001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.harmony.lang.reflect.implementation;
019:
020: import java.lang.reflect.WildcardType;
021: import java.lang.reflect.Type;
022: import java.lang.reflect.TypeVariable;
023: import java.lang.reflect.MalformedParameterizedTypeException;
024:
025: import org.apache.harmony.lang.reflect.parser.InterimWildcardType;
026: import org.apache.harmony.lang.reflect.parser.InterimClassType;
027: import org.apache.harmony.lang.reflect.support.AuxiliaryCreator;
028:
029: /**
030: * @author Serguei S. Zapreyev
031: * @version $Revision: 1.1.2.2 $
032: */
033: public final class WildcardTypeImpl implements WildcardType {
034: private final Object startPoint;
035: private Type[] lowerBounds;
036: private Type[] upperBounds;
037: private final InterimWildcardType wildCardTypeBillet;
038:
039: public WildcardTypeImpl(InterimWildcardType billet,
040: Object startPoint) {
041: this .upperBounds = null;
042: this .lowerBounds = null;
043: this .wildCardTypeBillet = billet;
044: this .startPoint = startPoint; // XXX: It seems to be a temporary decision to introduce startPoint
045: // It's not thought of finally. For example, it's not clear
046: // how can it influence on the WildcardTypeRepository.java
047: // ( "? extends TVAR" may be not equal to "? extends TVAR"
048: // because of first TVAR and second TVAR may be different type variables
049: // with the same name but I don't take it into account now in the repository algorithm
050: // I check there only the sugnatures equality :( .
051: }
052:
053: public boolean equals(Object other) {
054: //return super.equals(other);
055: if (!(other instanceof WildcardTypeImpl)) {
056: return false;
057: }
058: boolean res = true;
059: Type atl[] = (lowerBounds == null ? getLowerBounds()
060: : lowerBounds);
061: Type atl2[] = (((WildcardTypeImpl) other).lowerBounds == null ? ((WildcardTypeImpl) other)
062: .getLowerBounds()
063: : ((WildcardTypeImpl) other).lowerBounds);
064: if (atl.length != atl2.length) {
065: return false;
066: }
067: for (int i = 0; i < atl.length; i++) {
068: res = res && atl[i].equals(atl2[i]);
069: }
070: Type atu[] = (upperBounds == null ? getUpperBounds()
071: : upperBounds);
072: Type atu2[] = (((WildcardTypeImpl) other).upperBounds == null ? ((WildcardTypeImpl) other)
073: .getUpperBounds()
074: : ((WildcardTypeImpl) other).upperBounds);
075: if (atu.length != atu2.length) {
076: return false;
077: }
078: for (int i = 0; i < atu.length; i++) {
079: res = res && atu[i].equals(atu2[i]);
080: }
081: return res;
082: }
083:
084: public Type[] getLowerBounds() throws TypeNotPresentException,
085: MalformedParameterizedTypeException {
086: if (lowerBounds == null) {
087: if (wildCardTypeBillet.boundsType == false) {
088: int l = wildCardTypeBillet.bounds.length;
089: lowerBounds = new Type[l];
090: for (int i = 0; i < l; i++) {
091: // it can be InterimTypeVariable or InterimParameterizedType or InterimClassType.
092: // The MalformedParameterizedTypeException and TypeNotPresentException should be raised here if it needs.
093: try {
094: lowerBounds[i] = AuxiliaryCreator
095: .createTypeArg(
096: wildCardTypeBillet.bounds[i],
097: this .startPoint);
098: } catch (ClassNotFoundException e) {
099: throw new TypeNotPresentException(
100: ((InterimClassType) wildCardTypeBillet.bounds[i]).classTypeName
101: .substring(1).replace('/', '.'),
102: e); // ClassNotFoundException may appear here only for InterimClassType, see AuxiliaryCreator.createTypeArg.
103: }
104: }
105: } else {
106: lowerBounds = new Type[0];
107: }
108: }
109: return (Type[]) this .lowerBounds.clone();
110: }
111:
112: public Type[] getUpperBounds() throws TypeNotPresentException,
113: MalformedParameterizedTypeException {
114: if (upperBounds == null) {
115: if (wildCardTypeBillet.boundsType) {
116: int l = wildCardTypeBillet.bounds.length;
117: upperBounds = new Type[l];
118: for (int i = 0; i < l; i++) {
119: // it can be InterimTypeVariable or InterimParameterizedType or InterimClassType.
120: // The MalformedParameterizedTypeException and TypeNotPresentException should be raised here if it needs.
121: try {
122: upperBounds[i] = AuxiliaryCreator
123: .createTypeArg(
124: wildCardTypeBillet.bounds[i],
125: this .startPoint);
126: } catch (ClassNotFoundException e) {
127: throw new TypeNotPresentException(
128: ((InterimClassType) wildCardTypeBillet.bounds[i]).classTypeName
129: .substring(1).replace('/', '.'),
130: e); // ClassNotFoundException may appear here only for InterimClassType, see AuxiliaryCreator.createTypeArg.
131: }
132: }
133: } else {
134: upperBounds = new Type[1];
135: upperBounds[0] = (Type) Object.class;
136: }
137: }
138: return (Type[]) this .upperBounds.clone();
139: }
140:
141: public int hashCode() {
142: //return super.hashCode();
143: int res = 0;
144: Type atl[] = (lowerBounds == null ? getLowerBounds()
145: : lowerBounds);
146: for (int i = 0; i < atl.length; i++) {
147: res ^= atl[i].hashCode();
148: }
149: Type atu[] = (upperBounds == null ? getUpperBounds()
150: : upperBounds);
151: for (int i = 0; i < atu.length; i++) {
152: res ^= atu[i].hashCode();
153: }
154: return res;
155: }
156:
157: public String toString() {
158: // TODO: this body should be reimplemented effectively.
159: StringBuffer sb = new StringBuffer();
160: sb.append("?");
161: Type at[] = (lowerBounds == null ? getLowerBounds()
162: : lowerBounds);
163: if (at.length != 0) {
164: if (at[0] instanceof Class) {
165: sb.append(" super " + ((Class) at[0]).getName());
166: } else {
167: sb.append(" super " + ((TypeVariable) at[0]).getName());
168: }
169: return sb.toString();
170: }
171: at = (upperBounds == null ? getUpperBounds() : upperBounds);
172: if (at[0] instanceof Class) {
173: String ts = ((Class) at[0]).getName();
174: if (!ts.equals("java.lang.Object")) {
175: sb.append(" extends " + ts);
176: }
177: } else {
178: sb.append(" extends " + ((TypeVariable) at[0]).getName());
179: }
180: return sb.toString();
181: }
182: }
|