1e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom/*
2e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom * Copyright (C) 2008 The Android Open Source Project
3e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom *
4e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom * Licensed under the Apache License, Version 2.0 (the "License");
5e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom * you may not use this file except in compliance with the License.
6e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom * You may obtain a copy of the License at
7e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom *
8e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom *      http://www.apache.org/licenses/LICENSE-2.0
9e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom *
10e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom * Unless required by applicable law or agreed to in writing, software
11e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom * distributed under the License is distributed on an "AS IS" BASIS,
12e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom * See the License for the specific language governing permissions and
14e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom * limitations under the License.
15e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom */
16e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom
17e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrompackage libcore.reflect;
18e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom
19e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstromimport java.lang.reflect.ParameterizedType;
20e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstromimport java.lang.reflect.Type;
2165326f8cdeac2d85e5f714c4a01fb81a084d02f7Piotr Jastrzebskiimport java.util.Arrays;
2265326f8cdeac2d85e5f714c4a01fb81a084d02f7Piotr Jastrzebskiimport java.util.Objects;
23e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom
24e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrompublic final class ParameterizedTypeImpl implements ParameterizedType {
25e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom    private final ListOfTypes args;
26e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom    private final ParameterizedTypeImpl ownerType0; // Potentially unresolved.
2765326f8cdeac2d85e5f714c4a01fb81a084d02f7Piotr Jastrzebski    private Type ownerTypeRes; // Potentially unresolved.
2865326f8cdeac2d85e5f714c4a01fb81a084d02f7Piotr Jastrzebski    private Class rawType; // Potentially unresolved.
29e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom    private final String rawTypeName;
3065326f8cdeac2d85e5f714c4a01fb81a084d02f7Piotr Jastrzebski    private final ClassLoader loader;
31e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom
32e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom    public ParameterizedTypeImpl(ParameterizedTypeImpl ownerType, String rawTypeName,
33e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom            ListOfTypes args, ClassLoader loader) {
3465326f8cdeac2d85e5f714c4a01fb81a084d02f7Piotr Jastrzebski        if (args == null) {
3565326f8cdeac2d85e5f714c4a01fb81a084d02f7Piotr Jastrzebski            throw new NullPointerException();
3665326f8cdeac2d85e5f714c4a01fb81a084d02f7Piotr Jastrzebski        }
37e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom        this.ownerType0 = ownerType;
38e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom        this.rawTypeName = rawTypeName;
39e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom        this.args = args;
40e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom        this.loader = loader;
41e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom    }
42e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom
43e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom
44e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom    public Type[] getActualTypeArguments() {
45e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom        return args.getResolvedTypes().clone();
46e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom    }
47e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom
48e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom    public Type getOwnerType() {
49e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom        if (ownerTypeRes == null) {
50e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom            if (ownerType0 != null) {
51e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom                ownerTypeRes = ownerType0.getResolvedType();
52e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom            } else {
53e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom                ownerTypeRes = getRawType().getDeclaringClass();
54e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom            }
55e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom        }
56e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom        return ownerTypeRes;
57e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom    }
58e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom
59e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom    public Class getRawType() {
60e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom        if (rawType == null) {
61e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom            // Here the actual loading of the class has to be performed and the
62e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom            // Exceptions have to be re-thrown TypeNotPresent...
63e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom            // How to deal with member (nested) classes?
64e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom            try {
65e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom                rawType = Class.forName(rawTypeName, false, loader);
66e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom            } catch (ClassNotFoundException e) {
67e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom                throw new TypeNotPresentException(rawTypeName, e);
68e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom            }
69e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom        }
70e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom        return rawType;
71e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom    }
72e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom
73e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom
74e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom    Type getResolvedType() {
75e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom        if (args.getResolvedTypes().length == 0) {
76e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom            return getRawType();
77e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom        } else {
78e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom            return this;
79e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom        }
80e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom    }
81e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom
82e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom    @Override
8365326f8cdeac2d85e5f714c4a01fb81a084d02f7Piotr Jastrzebski    public boolean equals(Object o) {
8465326f8cdeac2d85e5f714c4a01fb81a084d02f7Piotr Jastrzebski        if (!(o instanceof ParameterizedType)) {
8565326f8cdeac2d85e5f714c4a01fb81a084d02f7Piotr Jastrzebski            return false;
8665326f8cdeac2d85e5f714c4a01fb81a084d02f7Piotr Jastrzebski        }
8765326f8cdeac2d85e5f714c4a01fb81a084d02f7Piotr Jastrzebski        ParameterizedType that = (ParameterizedType) o;
8865326f8cdeac2d85e5f714c4a01fb81a084d02f7Piotr Jastrzebski        return Objects.equals(getRawType(), that.getRawType()) &&
8965326f8cdeac2d85e5f714c4a01fb81a084d02f7Piotr Jastrzebski                Objects.equals(getOwnerType(), that.getOwnerType()) &&
9065326f8cdeac2d85e5f714c4a01fb81a084d02f7Piotr Jastrzebski                Arrays.equals(args.getResolvedTypes(), that.getActualTypeArguments());
9165326f8cdeac2d85e5f714c4a01fb81a084d02f7Piotr Jastrzebski    }
9265326f8cdeac2d85e5f714c4a01fb81a084d02f7Piotr Jastrzebski
9365326f8cdeac2d85e5f714c4a01fb81a084d02f7Piotr Jastrzebski    @Override
9465326f8cdeac2d85e5f714c4a01fb81a084d02f7Piotr Jastrzebski    public int hashCode() {
9565326f8cdeac2d85e5f714c4a01fb81a084d02f7Piotr Jastrzebski        return 31 * (31 * Objects.hashCode(getRawType()) + Objects.hashCode(getOwnerType())) +
9665326f8cdeac2d85e5f714c4a01fb81a084d02f7Piotr Jastrzebski            Arrays.hashCode(args.getResolvedTypes());
9765326f8cdeac2d85e5f714c4a01fb81a084d02f7Piotr Jastrzebski    }
9865326f8cdeac2d85e5f714c4a01fb81a084d02f7Piotr Jastrzebski
9965326f8cdeac2d85e5f714c4a01fb81a084d02f7Piotr Jastrzebski    @Override
100e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom    public String toString() {
101e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom        StringBuilder sb = new StringBuilder();
102e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom        sb.append(rawTypeName);
103e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom        if (args.length() > 0) {
104e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom            sb.append("<").append(args).append(">");
105e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom        }
106e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom        return sb.toString();
107e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom    }
108e96f94f57430bf3060581c816cc3a148adbe91a4Brian Carlstrom}
109