1/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package signature.compare.model.subst;
18
19import java.util.Collections;
20import java.util.HashSet;
21import java.util.List;
22import java.util.Map;
23import java.util.Set;
24
25import signature.model.IAnnotation;
26import signature.model.IAnnotationField;
27import signature.model.IClassDefinition;
28import signature.model.IConstructor;
29import signature.model.IEnumConstant;
30import signature.model.IField;
31import signature.model.IMethod;
32import signature.model.ITypeReference;
33import signature.model.ITypeVariableDefinition;
34import signature.model.Kind;
35import signature.model.Modifier;
36import signature.model.impl.SigClassDefinition;
37
38public class ClassProjection implements IClassDefinition {
39
40    private final IClassDefinition original;
41    private final Map<ITypeVariableDefinition, ITypeReference> substitutions;
42
43    public ClassProjection(IClassDefinition original,
44            Map<ITypeVariableDefinition, ITypeReference> mapping) {
45        this.original = original;
46        this.substitutions = mapping;
47    }
48
49    public Set<IAnnotationField> getAnnotationFields() {
50        throw new UnsupportedOperationException();
51    }
52
53    public Set<IAnnotation> getAnnotations() {
54        throw new UnsupportedOperationException();
55    }
56
57    public Set<IConstructor> getConstructors() {
58        throw new UnsupportedOperationException();
59    }
60
61    public IClassDefinition getDeclaringClass() {
62        throw new UnsupportedOperationException();
63    }
64
65    public Set<IEnumConstant> getEnumConstants() {
66        throw new UnsupportedOperationException();
67    }
68
69    public Set<IField> getFields() {
70        throw new UnsupportedOperationException();
71    }
72
73    public Set<IClassDefinition> getInnerClasses() {
74        throw new UnsupportedOperationException();
75    }
76
77    Set<ITypeReference> interfaces = null;
78
79    public Set<ITypeReference> getInterfaces() {
80        if (interfaces == null) {
81            Set<ITypeReference> originalInterfaces = original.getInterfaces();
82            if (originalInterfaces == null) {
83                interfaces = Collections.emptySet();
84            } else {
85                interfaces = new HashSet<ITypeReference>();
86                for (ITypeReference interfaze : originalInterfaces) {
87                    interfaces.add(ViewpointAdapter.substitutedTypeReference(
88                            interfaze, substitutions));
89                }
90                interfaces = Collections.unmodifiableSet(interfaces);
91            }
92        }
93        return interfaces;
94    }
95
96    public Kind getKind() {
97        return original.getKind();
98    }
99
100
101    Set<IMethod> methods = null;
102
103    public Set<IMethod> getMethods() {
104        if (methods == null) {
105            Set<IMethod> originalMethods = original.getMethods();
106            if (originalMethods == null) {
107                methods = Collections.emptySet();
108            } else {
109                methods = new HashSet<IMethod>();
110                for (IMethod m : original.getMethods()) {
111                    methods.add(new MethodProjection(m, substitutions));
112                }
113                methods = Collections.unmodifiableSet(methods);
114            }
115        }
116        return methods;
117    }
118
119    public Set<Modifier> getModifiers() {
120        return original.getModifiers();
121    }
122
123    public String getName() {
124        return original.getName();
125    }
126
127    public List<String> getPackageFragments() {
128        return original.getPackageFragments();
129    }
130
131    public String getPackageName() {
132        return original.getPackageName();
133    }
134
135    public String getQualifiedName() {
136        return original.getQualifiedName();
137    }
138
139    private boolean superClassInit = false;
140    private ITypeReference superClass = null;
141
142    public ITypeReference getSuperClass() {
143        if (!superClassInit) {
144            ITypeReference originalSuperClass = original.getSuperClass();
145            if (originalSuperClass != null) {
146                superClass = ViewpointAdapter.substitutedTypeReference(original
147                        .getSuperClass(), substitutions);
148            }
149            superClassInit = true;
150        }
151        return superClass;
152    }
153
154    // Definitions of type variables are not substituted
155    public List<ITypeVariableDefinition> getTypeParameters() {
156        return original.getTypeParameters();
157    }
158
159    @Override
160    public int hashCode() {
161        return SigClassDefinition.hashCode(this);
162    }
163
164    @Override
165    public boolean equals(Object obj) {
166        return SigClassDefinition.equals(this, obj);
167    }
168
169    @Override
170    public String toString() {
171        return "(" + SigClassDefinition.toString(this) + " : " + substitutions
172                + " )";
173    }
174
175}
176