| /* |
| * 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; |
| } |
| |
| } |