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.luni.internal.reflect;
019:
020: import java.lang.reflect.Method;
021:
022: import org.apache.harmony.luni.util.Msg;
023:
024: class ProxyMethod {
025: Method method;
026: Class declaringClass;
027:
028: Class[] commonExceptions;
029:
030: ProxyMethod(Class declaringClass, Method method) {
031: this .declaringClass = declaringClass;
032: this .method = method;
033: this .commonExceptions = method.getExceptionTypes();
034: }
035:
036: Class[] getCheckedExceptions() {
037: Class[] newExceptions = commonExceptions.clone();
038: int cLength = newExceptions.length;
039: for (int c = 0, cL = cLength; c < cL; c++) {
040: Class<?> ex = newExceptions[c];
041: if (Throwable.class == ex) {
042: // if Throwable is included then treat as if no exceptions are
043: // checked
044: return new Class[0];
045: }
046: if (Error.class.isAssignableFrom(ex)
047: || RuntimeException.class.isAssignableFrom(ex)) {
048: newExceptions[c] = null;
049: cLength--;
050: }
051: }
052:
053: // All errors & runtime exceptions are passed back without being wrapped
054: Class[] result = new Class[cLength + 2];
055: int index = 0;
056: result[index++] = Error.class;
057: result[index++] = RuntimeException.class;
058: for (Class<?> ex : newExceptions) {
059: if (ex != null) {
060: result[index++] = ex;
061: }
062: }
063: return result;
064: }
065:
066: boolean matchMethod(Method otherMethod) {
067: if (!method.getName().equals(otherMethod.getName())) {
068: return false;
069: }
070:
071: Class[] params1 = method.getParameterTypes();
072: Class[] params2 = otherMethod.getParameterTypes();
073: int p = params1.length;
074: if (p != params2.length) {
075: return false;
076: }
077: while (--p >= 0) {
078: if (params1[p] != params2[p]) {
079: return false;
080: }
081: }
082:
083: Class<?> this MethodReturnType = method.getReturnType();
084: Class<?> otherMethodReturnType = otherMethod.getReturnType();
085: if (!this MethodReturnType
086: .isAssignableFrom(otherMethodReturnType)) {
087: if (otherMethodReturnType
088: .isAssignableFrom(this MethodReturnType)) {
089: // substitute returnType of method with that of otherMethod
090: method = otherMethod;
091: } else {
092: throw new IllegalArgumentException(Msg.getString(
093: "K00f2", method.getName()));
094: }
095: }
096:
097: if (commonExceptions.length != 0) {
098: Class[] otherExceptions = otherMethod.getExceptionTypes();
099: if (otherExceptions.length == 0) {
100: commonExceptions = otherExceptions;
101: } else {
102: int cLength = commonExceptions.length;
103: nextException: for (int c = 0, cL = cLength, oL = otherExceptions.length; c < cL; c++) {
104: Class<?> cException = commonExceptions[c];
105: for (int o = 0; o < oL; o++) {
106: Class<?> oException = otherExceptions[o];
107: if (cException == oException) {
108: continue nextException;
109: }
110: if (oException.isAssignableFrom(cException)) {
111: continue nextException; // cException is a subclass
112: }
113: if (cException.isAssignableFrom(oException)) {
114: // oException is a subclass, keep it instead
115: commonExceptions[c] = cException = oException;
116: continue nextException;
117: }
118: }
119: commonExceptions[c] = null;
120: cLength--;
121: }
122: if (cLength != commonExceptions.length) {
123: Class[] newExceptions = new Class[cLength];
124: for (int i = 0, j = 0, length = commonExceptions.length; i < length; i++) {
125: Class<?> ex = commonExceptions[i];
126: if (ex != null) {
127: newExceptions[j++] = ex;
128: }
129: }
130: commonExceptions = newExceptions;
131: }
132: }
133: }
134: return true;
135: }
136:
137: Class getDeclaringClass() {
138: return declaringClass;
139: }
140:
141: }
|