001 /*
002 * Licensed under the Apache License, Version 2.0 (the "License");
003 * you may not use this file except in compliance with the License.
004 * You may obtain a copy of the License at
005 *
006 * http://www.apache.org/licenses/LICENSE-2.0
007 *
008 * Unless required by applicable law or agreed to in writing, software
009 * distributed under the License is distributed on an "AS IS" BASIS,
010 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
011 * See the License for the specific language governing permissions and
012 * limitations under the License.
013 */
014 package org.apache.commons.classscan.bcel;
015
016 import java.util.Set;
017
018 import org.apache.bcel.classfile.Method;
019 import org.apache.bcel.classfile.ParameterAnnotationEntry;
020 import org.apache.bcel.generic.Type;
021 import org.apache.commons.classscan.model.MetaAnnotation;
022 import org.apache.commons.classscan.model.MetaParameter;
023 import org.apache.commons.classscan.model.MetaType;
024 import org.apache.commons.classscan.spi.model.SpiMetaClassLoader;
025 import org.apache.commons.classscan.spi.model.SpiMetaMethod;
026 import org.apache.commons.classscan.spi.model.SpiMetaParameter;
027 import org.apache.commons.classscan.util.ResolveSet;
028
029 public class BcelMethod implements SpiMetaMethod {
030
031 private final String methodName;
032 private final boolean isStatic;
033 private final AnnotationMap annotations;
034 private MetaType returnType;
035 private String returnTypeDescriptor;
036 private final ResolveSet<SpiMetaParameter> paramTypes;
037
038 public BcelMethod(Method method) {
039 methodName = method.getName();
040 isStatic = method.isStatic();
041 annotations = AnnotationMap.createAnnotations(method.getAnnotationEntries());
042 returnTypeDescriptor = method.getReturnType().getSignature();
043 paramTypes = createParameters(method);
044 }
045
046 @Override
047 public boolean resolve(SpiMetaClassLoader classLoader) {
048 returnType = classLoader.resolveTypeForDescriptor(returnTypeDescriptor);
049 if(returnType==null) {
050 return false;
051 }
052 returnTypeDescriptor = null;
053
054 return annotations.resolve(classLoader)
055 && paramTypes.resolve(classLoader);
056 }
057
058 @Override
059 public String getName() {
060 return methodName;
061 }
062
063 @Override
064 public Set<? extends MetaAnnotation> getAnnotations() {
065 return annotations;
066 }
067
068 @Override
069 public MetaAnnotation getAnnotation(String annotationName) {
070 return annotations.getValue(annotationName);
071 }
072
073 @Override
074 public boolean isStatic() {
075 return isStatic;
076 }
077
078 @Override
079 public MetaType getType() {
080 return returnType;
081 }
082
083 @Override
084 public Set<? extends MetaParameter> getParameters() {
085 return paramTypes;
086 }
087
088 private ResolveSet<SpiMetaParameter> createParameters(Method method) {
089 final Type[] types = method.getArgumentTypes();
090 if (types.length == 0) {
091 return ResolveSet.emptyResolveSet();
092 }
093
094 final ParameterAnnotationEntry[] parameterAnnotations = method.getParameterAnnotationEntries();
095 SpiMetaParameter[] metaParameterArray = new SpiMetaParameter[types.length];
096 for (int i = 0; i < metaParameterArray.length; ++i) {
097 // there may be less annotations than parameters
098 ParameterAnnotationEntry arg = i < parameterAnnotations.length ? parameterAnnotations[i] : null;
099 metaParameterArray[i] = new BcelParameter(types[i], arg);
100 }
101
102 ResolveSet<SpiMetaParameter> parameters = new ResolveSet<SpiMetaParameter>(metaParameterArray);
103 return parameters;
104 }
105 }