blob: 0b1dae4f1ce86dc23d83f672d65c66643cb0b1d5 [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.commons.weaver;
import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.weaver.model.ScanResult;
import org.apache.commons.weaver.model.WeavableClass;
import org.apache.commons.weaver.model.WeavableConstructor;
import org.apache.commons.weaver.model.WeavableConstructorParameter;
import org.apache.commons.weaver.model.WeavableField;
import org.apache.commons.weaver.model.WeavableMethod;
import org.apache.commons.weaver.model.WeavableMethodParameter;
import org.apache.commons.weaver.model.WeavablePackage;
import org.apache.xbean.finder.AnnotationFinder.ClassInfo;
import org.apache.xbean.finder.AnnotationFinder.FieldInfo;
import org.apache.xbean.finder.AnnotationFinder.Info;
import org.apache.xbean.finder.AnnotationFinder.MethodInfo;
import org.apache.xbean.finder.AnnotationFinder.PackageInfo;
import org.apache.xbean.finder.AnnotationFinder.ParameterInfo;
import org.apache.xbean.finder.Parameter;
/**
* Adds all classfile annotations to a ScanResult.
*/
class Inflater {
private class InfoMatcher {
final Class<? extends Info> type;
InfoMatcher(final Class<? extends Info> type) {
super();
this.type = type;
}
boolean test(final Info info) {
return type.isInstance(info);
}
}
private class MethodMatcher extends InfoMatcher {
final boolean isCtor;
MethodMatcher(final boolean isCtor) {
super(MethodInfo.class);
this.isCtor = isCtor;
}
@Override
boolean test(final Info info) {
return super.test(info) && ((MethodInfo) info).isConstructor() == isCtor;
}
}
private class ParameterMatcher extends InfoMatcher {
final boolean isCtor;
ParameterMatcher(final boolean isCtor) {
super(ParameterInfo.class);
this.isCtor = isCtor;
}
@Override
boolean test(final Info info) {
return super.test(info) && ((ParameterInfo) info).getDeclaringMethod().isConstructor() == isCtor;
}
}
final Map<PackageInfo, List<Annotation>> packageAnnotations;
final Map<ClassInfo, List<Annotation>> classAnnotations;
final Map<FieldInfo, List<Annotation>> fieldAnnotations;
final Map<MethodInfo, List<Annotation>> ctorAnnotations;
final Map<MethodInfo, List<Annotation>> methodAnnotations;
final Map<ParameterInfo, List<Annotation>> ctorParameterAnnotations;
final Map<ParameterInfo, List<Annotation>> methodParameterAnnotations;
Inflater(final Map<Info, List<Annotation>> annotationMap) {
super();
this.packageAnnotations = subMap(annotationMap, new InfoMatcher(PackageInfo.class));
this.classAnnotations = subMap(annotationMap, new InfoMatcher(ClassInfo.class));
this.fieldAnnotations = subMap(annotationMap, new InfoMatcher(FieldInfo.class));
this.ctorAnnotations = subMap(annotationMap, new MethodMatcher(true));
this.methodAnnotations = subMap(annotationMap, new MethodMatcher(false));
this.ctorParameterAnnotations = subMap(annotationMap, new ParameterMatcher(true));
this.methodParameterAnnotations = subMap(annotationMap, new ParameterMatcher(false));
}
static <I extends Info> Map<I, List<Annotation>> subMap(final Map<Info, List<Annotation>> source,
final InfoMatcher matcher) {
final HashMap<I, List<Annotation>> result = new HashMap<I, List<Annotation>>();
for (final Map.Entry<Info, List<Annotation>> entry : source.entrySet()) {
if (matcher.test(entry.getKey())) {
@SuppressWarnings("unchecked")
final I key = (I) entry.getKey();
result.put(key, entry.getValue());
}
}
return result;
}
ScanResult inflate(final ScanResult scanResult) {
for (final WeavablePackage pkg : scanResult.getPackages()) {
for (final Map.Entry<PackageInfo, List<Annotation>> entry : packageAnnotations.entrySet()) {
if (entry.getKey().getName().equals(pkg.getTarget().getName())) {
pkg.addAnnotations(entry.getValue());
}
}
for (final WeavableClass<?> cls : pkg.getClasses()) {
for (final Map.Entry<ClassInfo, List<Annotation>> entry : classAnnotations.entrySet()) {
if (entry.getKey().getName().equals(cls.getTarget().getName())) {
cls.addAnnotations(entry.getValue());
}
}
for (final WeavableField<?> fld : cls.getFields()) {
for (final Map.Entry<FieldInfo, List<Annotation>> entry : fieldAnnotations.entrySet()) {
try {
if (entry.getKey().get().equals(fld.getTarget())) {
fld.addAnnotations(entry.getValue());
}
} catch (final ClassNotFoundException cnfe) {
continue;
}
}
}
for (final WeavableConstructor<?> ctor : cls.getConstructors()) {
for (final Map.Entry<MethodInfo, List<Annotation>> entry : ctorAnnotations.entrySet()) {
try {
if (entry.getKey().get().equals(ctor.getTarget())) {
ctor.addAnnotations(entry.getValue());
}
} catch (final ClassNotFoundException cnfe) {
continue;
}
}
for (final WeavableConstructorParameter<?> param : ctor.getParameters()) {
for (final Map.Entry<ParameterInfo, List<Annotation>> entry : ctorParameterAnnotations
.entrySet()) {
try {
final Parameter<?> parameter = entry.getKey().get();
if (parameter.getDeclaringExecutable().equals(ctor.getTarget())
&& param.getTarget().intValue() == parameter.getIndex()) {
param.addAnnotations(entry.getValue());
}
} catch (final ClassNotFoundException cnfe) {
continue;
}
}
}
}
for (final WeavableMethod<?> methd : cls.getMethods()) {
for (final Map.Entry<MethodInfo, List<Annotation>> entry : methodAnnotations.entrySet()) {
try {
if (entry.getKey().get().equals(methd.getTarget())) {
methd.addAnnotations(entry.getValue());
}
} catch (final ClassNotFoundException cnfe) {
continue;
}
}
for (final WeavableMethodParameter<?> param : methd.getParameters()) {
for (final Map.Entry<ParameterInfo, List<Annotation>> entry : methodParameterAnnotations
.entrySet()) {
try {
final Parameter<?> parameter = entry.getKey().get();
if (parameter.getDeclaringExecutable().equals(methd.getTarget())
&& param.getTarget().intValue() == parameter.getIndex()) {
param.addAnnotations(entry.getValue());
}
} catch (final ClassNotFoundException cnfe) {
continue;
}
}
}
}
}
}
return scanResult;
}
}