blob: ab1cb834159aedc6b2ad05c4fb3c7a43d6414d6c [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.harmony.luni.internal.reflect;
import java.lang.reflect.Method;
import org.apache.harmony.luni.util.Msg;
class ProxyMethod {
Method method;
Class declaringClass;
Class[] commonExceptions;
ProxyMethod(Class declaringClass, Method method) {
this.declaringClass = declaringClass;
this.method = method;
this.commonExceptions = method.getExceptionTypes();
}
Class[] getCheckedExceptions() {
Class[] newExceptions = commonExceptions.clone();
int cLength = newExceptions.length;
for (int c = 0, cL = cLength; c < cL; c++) {
Class<?> ex = newExceptions[c];
if (Throwable.class == ex) {
// if Throwable is included then treat as if no exceptions are
// checked
return new Class[0];
}
if (Error.class.isAssignableFrom(ex) || RuntimeException.class.isAssignableFrom(ex)) {
newExceptions[c] = null;
cLength--;
}
}
// All errors & runtime exceptions are passed back without being wrapped
Class[] result = new Class[cLength + 2];
int index = 0;
result[index++] = Error.class;
result[index++] = RuntimeException.class;
for (Class<?> ex : newExceptions) {
if (ex != null) {
result[index++] = ex;
}
}
return result;
}
boolean matchMethod(Method otherMethod) {
if (!method.getName().equals(otherMethod.getName())) {
return false;
}
Class[] params1 = method.getParameterTypes();
Class[] params2 = otherMethod.getParameterTypes();
int p = params1.length;
if (p != params2.length) {
return false;
}
while (--p >= 0) {
if (params1[p] != params2[p]) {
return false;
}
}
Class<?> thisMethodReturnType = method.getReturnType();
Class<?> otherMethodReturnType = otherMethod.getReturnType();
if (!thisMethodReturnType.isAssignableFrom(otherMethodReturnType)) {
if (otherMethodReturnType.isAssignableFrom(thisMethodReturnType)) {
// substitute returnType of method with that of otherMethod
method = otherMethod;
} else {
throw new IllegalArgumentException(Msg.getString("K00f2",
method.getName()));
}
}
if (commonExceptions.length != 0) {
Class[] otherExceptions = otherMethod.getExceptionTypes();
if (otherExceptions.length == 0) {
commonExceptions = otherExceptions;
} else {
int cLength = commonExceptions.length;
nextException: for (int c = 0, cL = cLength, oL = otherExceptions.length; c < cL; c++) {
Class<?> cException = commonExceptions[c];
for (int o = 0; o < oL; o++) {
Class<?> oException = otherExceptions[o];
if (cException == oException) {
continue nextException;
}
if (oException.isAssignableFrom(cException)) {
continue nextException; // cException is a subclass
}
if (cException.isAssignableFrom(oException)) {
// oException is a subclass, keep it instead
commonExceptions[c] = cException = oException;
continue nextException;
}
}
commonExceptions[c] = null;
cLength--;
}
if (cLength != commonExceptions.length) {
Class[] newExceptions = new Class[cLength];
for (int i = 0, j = 0, length = commonExceptions.length; i < length; i++) {
Class<?> ex = commonExceptions[i];
if (ex != null) {
newExceptions[j++] = ex;
}
}
commonExceptions = newExceptions;
}
}
}
return true;
}
Class getDeclaringClass() {
return declaringClass;
}
}