Added tiger classes of core bundle
This commit is contained in:
parent
4bc407fef8
commit
684a4f28c2
|
|
@ -23,6 +23,8 @@
|
|||
<dependency org="org.apache.commons" name="com.springsource.org.apache.commons.logging" rev="1.1.1" conf="compile->runtime" />
|
||||
<dependency org="org.apache.log4j" name="com.springsource.org.apache.log4j" rev="1.2.15" conf="optional->runtime" />
|
||||
<dependency org="org.apache.commons" name="com.springsource.org.apache.commons.collections" rev="3.2.0" conf="optional->compile" />
|
||||
<!--<dependency org="org.aspectj" name="com.springsource.org.aspectj.runtime" rev="1.6.2.RELEASE" conf="optional->compile" />-->
|
||||
<dependency org="org.aspectj" name="com.springsource.org.aspectj.weaver" rev="1.6.2.RELEASE" conf="optional->compile" />
|
||||
<!-- These should be replaced with the internal repackaging of ASM -->
|
||||
<dependency org="org.objectweb.asm" name="com.springsource.org.objectweb.asm" rev="2.2.3" conf="optional->compile" />
|
||||
<dependency org="org.objectweb.asm" name="com.springsource.org.objectweb.asm.commons" rev="2.2.3" conf="optional->compile" />
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.core.annotation;
|
||||
|
||||
import org.springframework.core.OrderComparator;
|
||||
import org.springframework.core.Ordered;
|
||||
|
||||
/**
|
||||
* {@link java.util.Comparator} implementation that checks
|
||||
* {@link org.springframework.core.Ordered} as well as the
|
||||
* {@link Order} annotation, with an order value provided by an
|
||||
* <code>Ordered</code> instance overriding a statically defined
|
||||
* annotation value (if any).
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.0.1
|
||||
* @see org.springframework.core.Ordered
|
||||
* @see Order
|
||||
*/
|
||||
public class AnnotationAwareOrderComparator extends OrderComparator {
|
||||
|
||||
protected int getOrder(Object obj) {
|
||||
if (obj instanceof Ordered) {
|
||||
return ((Ordered) obj).getOrder();
|
||||
}
|
||||
if (obj != null) {
|
||||
Order order = obj.getClass().getAnnotation(Order.class);
|
||||
if (order != null) {
|
||||
return order.value();
|
||||
}
|
||||
}
|
||||
return Ordered.LOWEST_PRECEDENCE;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,345 @@
|
|||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.core.annotation;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.core.BridgeMethodResolver;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* General utility methods for working with annotations, handling bridge methods
|
||||
* (which the compiler generates for generic declarations) as well as super
|
||||
* methods (for optional "annotation inheritance"). Note that none of
|
||||
* this is provided by the JDK's introspection facilities themselves.
|
||||
*
|
||||
* <p>As a general rule for runtime-retained annotations (e.g. for transaction
|
||||
* control, authorization or service exposure), always use the lookup methods on
|
||||
* this class (e.g., {@link #findAnnotation(Method, Class)},
|
||||
* {@link #getAnnotation(Method, Class)}, and {@link #getAnnotations(Method)})
|
||||
* instead of the plain annotation lookup methods in the JDK. You can still
|
||||
* explicitly choose between lookup on the given class level only
|
||||
* ({@link #getAnnotation(Method, Class)}) and lookup in the entire inheritance
|
||||
* hierarchy of the given method ({@link #findAnnotation(Method, Class)}).
|
||||
*
|
||||
* @author Rob Harrop
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
* @author Mark Fisher
|
||||
* @since 2.0
|
||||
* @see java.lang.reflect.Method#getAnnotations()
|
||||
* @see java.lang.reflect.Method#getAnnotation(Class)
|
||||
*/
|
||||
public abstract class AnnotationUtils {
|
||||
|
||||
/** The attribute name for annotations with a single element */
|
||||
static final String VALUE = "value";
|
||||
|
||||
|
||||
/**
|
||||
* Get all {@link Annotation Annotations} from the supplied {@link Method}.
|
||||
* <p>Correctly handles bridge {@link Method Methods} generated by the compiler.
|
||||
* @param method the method to look for annotations on
|
||||
* @return the annotations found
|
||||
* @see org.springframework.core.BridgeMethodResolver#findBridgedMethod(Method)
|
||||
*/
|
||||
public static Annotation[] getAnnotations(Method method) {
|
||||
return BridgeMethodResolver.findBridgedMethod(method).getAnnotations();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a single {@link Annotation} of <code>annotationType</code> from the
|
||||
* supplied {@link Method}.
|
||||
* <p>Correctly handles bridge {@link Method Methods} generated by the compiler.
|
||||
* @param method the method to look for annotations on
|
||||
* @param annotationType the annotation class to look for
|
||||
* @return the annotations found
|
||||
* @see org.springframework.core.BridgeMethodResolver#findBridgedMethod(Method)
|
||||
*/
|
||||
public static <A extends Annotation> A getAnnotation(Method method, Class<A> annotationType) {
|
||||
return BridgeMethodResolver.findBridgedMethod(method).getAnnotation(annotationType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a single {@link Annotation} of <code>annotationType</code> from the
|
||||
* supplied {@link Method}, traversing its super methods if no annotation
|
||||
* can be found on the given method itself.
|
||||
* <p>Annotations on methods are not inherited by default, so we need to handle
|
||||
* this explicitly. Tge
|
||||
* @param method the method to look for annotations on
|
||||
* @param annotationType the annotation class to look for
|
||||
* @return the annotation found, or <code>null</code> if none found
|
||||
*/
|
||||
public static <A extends Annotation> A findAnnotation(Method method, Class<A> annotationType) {
|
||||
A annotation = getAnnotation(method, annotationType);
|
||||
Class<?> cl = method.getDeclaringClass();
|
||||
while (annotation == null) {
|
||||
cl = cl.getSuperclass();
|
||||
if (cl == null || cl == Object.class) {
|
||||
break;
|
||||
}
|
||||
try {
|
||||
Method equivalentMethod = cl.getDeclaredMethod(method.getName(), method.getParameterTypes());
|
||||
annotation = getAnnotation(equivalentMethod, annotationType);
|
||||
}
|
||||
catch (NoSuchMethodException ex) {
|
||||
// We're done...
|
||||
}
|
||||
}
|
||||
return annotation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a single {@link Annotation} of <code>annotationType</code> from the
|
||||
* supplied {@link Class}, traversing its interfaces and super classes
|
||||
* if no annotation can be found on the given class itself.
|
||||
* <p>This method explicitly handles class-level annotations which are
|
||||
* not declared as {@link java.lang.annotation.Inherited inherited}
|
||||
* <i>as well as annotations on interfaces</i>.
|
||||
* <p>The algorithm operates as follows: Searches for an annotation on the given
|
||||
* class and returns it if found. Else searches all interfaces that the given
|
||||
* class declares, returning the annotation from the first matching candidate,
|
||||
* if any. Else proceeds with introspection of the superclass of the given class,
|
||||
* checking the superclass itself; if no annotation found there, proceeds with
|
||||
* the interfaces that the superclass declares. Recursing up through the entire
|
||||
* superclass hierarchy if no match is found.
|
||||
* @param clazz the class to look for annotations on
|
||||
* @param annotationType the annotation class to look for
|
||||
* @return the annotation found, or <code>null</code> if none found
|
||||
*/
|
||||
public static <A extends Annotation> A findAnnotation(Class<?> clazz, Class<A> annotationType) {
|
||||
Assert.notNull(clazz, "Class must not be null");
|
||||
A annotation = clazz.getAnnotation(annotationType);
|
||||
if (annotation != null) {
|
||||
return annotation;
|
||||
}
|
||||
for (Class<?> ifc : clazz.getInterfaces()) {
|
||||
annotation = findAnnotation(ifc, annotationType);
|
||||
if (annotation != null) {
|
||||
return annotation;
|
||||
}
|
||||
}
|
||||
Class superClass = clazz.getSuperclass();
|
||||
if (superClass == null || superClass == Object.class) {
|
||||
return null;
|
||||
}
|
||||
return findAnnotation(superClass, annotationType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the first {@link Class} in the inheritance hierarchy of the
|
||||
* specified <code>clazz</code> (including the specified
|
||||
* <code>clazz</code> itself) which declares an annotation for the
|
||||
* specified <code>annotationType</code>, or <code>null</code> if not
|
||||
* found. If the supplied <code>clazz</code> is <code>null</code>,
|
||||
* <code>null</code> will be returned.
|
||||
* <p>If the supplied <code>clazz</code> is an interface, only the interface
|
||||
* itself will be checked; the inheritance hierarchy for interfaces will not
|
||||
* be traversed.
|
||||
* <p>The standard {@link Class} API does not provide a mechanism for
|
||||
* determining which class in an inheritance hierarchy actually declares an
|
||||
* {@link Annotation}, so we need to handle this explicitly.
|
||||
* @param annotationType the Class object corresponding to the annotation type
|
||||
* @param clazz the Class object corresponding to the class on which to
|
||||
* check for the annotation, or <code>null</code>.
|
||||
* @return the first {@link Class} in the inheritance hierarchy of the
|
||||
* specified <code>clazz</code> which declares an annotation for the specified
|
||||
* <code>annotationType</code>, or <code>null</code> if not found.
|
||||
* @see Class#isAnnotationPresent(Class)
|
||||
* @see Class#getDeclaredAnnotations()
|
||||
*/
|
||||
public static Class<?> findAnnotationDeclaringClass(Class<? extends Annotation> annotationType, Class<?> clazz) {
|
||||
Assert.notNull(annotationType, "Annotation type must not be null");
|
||||
if (clazz == null || clazz.equals(Object.class)) {
|
||||
return null;
|
||||
}
|
||||
return (isAnnotationDeclaredLocally(annotationType, clazz)) ?
|
||||
clazz : findAnnotationDeclaringClass(annotationType, clazz.getSuperclass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether an annotation for the specified <code>annotationType</code>
|
||||
* is declared locally on the supplied <code>clazz</code>.
|
||||
* The supplied {@link Class} object may represent any type.
|
||||
* <p>Note: This method does <strong>not</strong> determine if the annotation
|
||||
* is {@link java.lang.annotation.Inherited inherited}. For greater clarity
|
||||
* regarding inherited annotations, consider using
|
||||
* {@link #isAnnotationInherited(Class, Class)} instead.
|
||||
* @param annotationType the Class object corresponding to the annotation type
|
||||
* @param clazz the Class object corresponding to the class on which to
|
||||
* check for the annotation
|
||||
* @return <code>true</code> if an annotation for the specified
|
||||
* <code>annotationType</code> is declared locally on the supplied <code>clazz</code>
|
||||
* @see Class#getDeclaredAnnotations()
|
||||
* @see #isAnnotationInherited(Class, Class)
|
||||
*/
|
||||
public static boolean isAnnotationDeclaredLocally(Class<? extends Annotation> annotationType, Class<?> clazz) {
|
||||
Assert.notNull(annotationType, "Annotation type must not be null");
|
||||
Assert.notNull(clazz, "Class must not be null");
|
||||
boolean declaredLocally = false;
|
||||
for (Annotation annotation : Arrays.asList(clazz.getDeclaredAnnotations())) {
|
||||
if (annotation.annotationType().equals(annotationType)) {
|
||||
declaredLocally = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return declaredLocally;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether an annotation for the specified <code>annotationType</code>
|
||||
* is present on the supplied <code>clazz</code> and is
|
||||
* {@link java.lang.annotation.Inherited inherited}
|
||||
* (i.e., not declared locally for the class).
|
||||
* <p>If the supplied <code>clazz</code> is an interface, only the interface
|
||||
* itself will be checked. In accord with standard meta-annotation
|
||||
* semantics, the inheritance hierarchy for interfaces will not be
|
||||
* traversed. See the {@link java.lang.annotation.Inherited JavaDoc} for the
|
||||
* @Inherited meta-annotation for further details regarding annotation
|
||||
* inheritance.
|
||||
* @param annotationType the Class object corresponding to the annotation type
|
||||
* @param clazz the Class object corresponding to the class on which to
|
||||
* check for the annotation
|
||||
* @return <code>true</code> if an annotation for the specified
|
||||
* <code>annotationType</code> is present on the supplied <code>clazz</code>
|
||||
* and is {@link java.lang.annotation.Inherited inherited}
|
||||
* @see Class#isAnnotationPresent(Class)
|
||||
* @see #isAnnotationDeclaredLocally(Class, Class)
|
||||
*/
|
||||
public static boolean isAnnotationInherited(Class<? extends Annotation> annotationType, Class<?> clazz) {
|
||||
Assert.notNull(annotationType, "Annotation type must not be null");
|
||||
Assert.notNull(clazz, "Class must not be null");
|
||||
return (clazz.isAnnotationPresent(annotationType) && !isAnnotationDeclaredLocally(annotationType, clazz));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the given annotation's attributes as a Map.
|
||||
* @param annotation the annotation to retrieve the attributes for
|
||||
* @return the Map of annotation attributes, with attribute names as keys
|
||||
* and corresponding attribute values as values
|
||||
*/
|
||||
public static Map<String, Object> getAnnotationAttributes(Annotation annotation) {
|
||||
Map<String, Object> attrs = new HashMap<String, Object>();
|
||||
Method[] methods = annotation.annotationType().getDeclaredMethods();
|
||||
for (int j = 0; j < methods.length; j++) {
|
||||
Method method = methods[j];
|
||||
if (method.getParameterTypes().length == 0 && method.getReturnType() != void.class) {
|
||||
try {
|
||||
attrs.put(method.getName(), method.invoke(annotation));
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException("Could not obtain annotation attribute values", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the <em>value</em> of the <code>"value"</code>
|
||||
* attribute of a single-element Annotation, given an annotation instance.
|
||||
* @param annotation the annotation instance from which to retrieve the value
|
||||
* @return the attribute value, or <code>null</code> if not found
|
||||
* @see #getValue(Annotation, String)
|
||||
*/
|
||||
public static Object getValue(Annotation annotation) {
|
||||
return getValue(annotation, VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the <em>value</em> of a named Annotation attribute, given an
|
||||
* annotation instance.
|
||||
* @see #getValue(Annotation)
|
||||
* @param annotation the annotation instance from which to retrieve the value
|
||||
* @param attributeName the name of the attribute value to retrieve
|
||||
* @return the attribute value, or <code>null</code> if not found
|
||||
*/
|
||||
public static Object getValue(Annotation annotation, String attributeName) {
|
||||
try {
|
||||
Method method = annotation.annotationType().getDeclaredMethod(attributeName, new Class[0]);
|
||||
return method.invoke(annotation);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the <em>default value</em> of the
|
||||
* <code>"value"</code> attribute of a single-element
|
||||
* Annotation, given an annotation instance.
|
||||
* @param annotation the annotation instance from which to retrieve
|
||||
* the default value
|
||||
* @return the default value, or <code>null</code> if not found
|
||||
* @see #getDefaultValue(Annotation, String)
|
||||
*/
|
||||
public static Object getDefaultValue(Annotation annotation) {
|
||||
return getDefaultValue(annotation, VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the <em>default value</em> of a named Annotation attribute,
|
||||
* given an annotation instance.
|
||||
* @param annotation the annotation instance from which to retrieve
|
||||
* the default value
|
||||
* @param attributeName the name of the attribute value to retrieve
|
||||
* @return the default value of the named attribute, or <code>null</code>
|
||||
* if not found.
|
||||
* @see #getDefaultValue(Class, String)
|
||||
*/
|
||||
public static Object getDefaultValue(Annotation annotation, String attributeName) {
|
||||
return getDefaultValue(annotation.annotationType(), attributeName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the <em>default value</em> of the
|
||||
* <code>"value"</code> attribute of a single-element
|
||||
* Annotation, given the {@link Class annotation type}.
|
||||
* @param annotationType the <em>annotation type</em> for which the
|
||||
* default value should be retrieved
|
||||
* @return the default value, or <code>null</code> if not found
|
||||
* @see #getDefaultValue(Class, String)
|
||||
*/
|
||||
public static Object getDefaultValue(Class<? extends Annotation> annotationType) {
|
||||
return getDefaultValue(annotationType, VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the <em>default value</em> of a named Annotation attribute,
|
||||
* given the {@link Class annotation type}.
|
||||
* @param annotationType the <em>annotation type</em> for which the
|
||||
* default value should be retrieved
|
||||
* @param attributeName the name of the attribute value to retrieve.
|
||||
* @return the default value of the named attribute, or <code>null</code>
|
||||
* if not found
|
||||
* @see #getDefaultValue(Annotation, String)
|
||||
*/
|
||||
public static Object getDefaultValue(Class<? extends Annotation> annotationType, String attributeName) {
|
||||
try {
|
||||
Method method = annotationType.getDeclaredMethod(attributeName, new Class[0]);
|
||||
return method.getDefaultValue();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.core.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.core.Ordered;
|
||||
|
||||
/**
|
||||
* Annotation to define ordering.
|
||||
*
|
||||
* <p>Value is optional, and represents order value as defined
|
||||
* in the Ordered interface. Lower values have higher priority.
|
||||
* Default value is <code>Integer.MAX_VALUE</code>, indicating lowest
|
||||
* priority (losing to any other specified order value).
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @since 2.0
|
||||
* @see org.springframework.core.Ordered
|
||||
* @see AnnotationAwareOrderComparator
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
|
||||
public @interface Order {
|
||||
|
||||
int value() default Ordered.LOWEST_PRECEDENCE;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<html>
|
||||
<body>
|
||||
|
||||
Core support package for Java 5 annotations.
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.core.type;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Interface that defines abstract access to the annotations of a specific
|
||||
* class, in a form that does not require that class to be loaded yet.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Mark Fisher
|
||||
* @since 2.5
|
||||
* @see StandardAnnotationMetadata
|
||||
* @see org.springframework.core.type.classreading.MetadataReader#getAnnotationMetadata()
|
||||
*/
|
||||
public interface AnnotationMetadata extends ClassMetadata {
|
||||
|
||||
/**
|
||||
* Return the names of all annotation types defined on the underlying class.
|
||||
* @return the annotation type names
|
||||
*/
|
||||
Set<String> getAnnotationTypes();
|
||||
|
||||
/**
|
||||
* Determine whether the underlying class has an annotation of the given
|
||||
* type defined.
|
||||
* @param annotationType the annotation type to look for
|
||||
* @return whether a matching annotation is defined
|
||||
*/
|
||||
boolean hasAnnotation(String annotationType);
|
||||
|
||||
/**
|
||||
* Return the names of all meta-annotation types defined on the
|
||||
* given annotation type of the underlying class.
|
||||
* @return the meta-annotation type names
|
||||
*/
|
||||
Set<String> getMetaAnnotationTypes(String annotationType);
|
||||
|
||||
/**
|
||||
* Determine whether the underlying class has an annotation that
|
||||
* is itself annotated with the meta-annotation of the given type.
|
||||
* @param metaAnnotationType the meta-annotation type to look for
|
||||
* @return whether a matching meta-annotation is defined
|
||||
*/
|
||||
boolean hasMetaAnnotation(String metaAnnotationType);
|
||||
|
||||
/**
|
||||
* Retrieve the attributes of the annotation of the given type,
|
||||
* if any (i.e. if defined on the underlying class).
|
||||
* @param annotationType the annotation type to look for
|
||||
* @return a Map of attributes, with the attribute name as key
|
||||
* (e.g. "value") and the defined attribute value as Map value.
|
||||
* This return value will be <code>null</code> if no matching
|
||||
* annotation is defined.
|
||||
*/
|
||||
Map<String, Object> getAnnotationAttributes(String annotationType);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.core.type;
|
||||
|
||||
/**
|
||||
* Interface that defines abstract metadata of a specific class,
|
||||
* in a form that does not require that class to be loaded yet.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.5
|
||||
* @see StandardClassMetadata
|
||||
* @see org.springframework.core.type.classreading.MetadataReader#getClassMetadata()
|
||||
* @see AnnotationMetadata
|
||||
*/
|
||||
public interface ClassMetadata {
|
||||
|
||||
/**
|
||||
* Return the name of the underlying class.
|
||||
*/
|
||||
String getClassName();
|
||||
|
||||
/**
|
||||
* Return whether the underlying class represents an interface.
|
||||
*/
|
||||
boolean isInterface();
|
||||
|
||||
/**
|
||||
* Return whether the underlying class is marked as abstract.
|
||||
*/
|
||||
boolean isAbstract();
|
||||
|
||||
/**
|
||||
* Return whether the underlying class represents a concrete class,
|
||||
* i.e. neither an interface nor an abstract class.
|
||||
*/
|
||||
boolean isConcrete();
|
||||
|
||||
/**
|
||||
* Determine whether the underlying class is independent,
|
||||
* i.e. whether it is a top-level class or a nested class
|
||||
* (static inner class) that can be constructed independent
|
||||
* from an enclosing class.
|
||||
*/
|
||||
boolean isIndependent();
|
||||
|
||||
/**
|
||||
* Return whether the underlying class has an enclosing class
|
||||
* (i.e. the underlying class is an inner/nested class or
|
||||
* a local class within a method).
|
||||
* <p>If this method returns <code>false</code>, then the
|
||||
* underlying class is a top-level class.
|
||||
*/
|
||||
boolean hasEnclosingClass();
|
||||
|
||||
/**
|
||||
* Return the name of the enclosing class of the underlying class,
|
||||
* or <code>null</code> if the underlying class is a top-level class.
|
||||
*/
|
||||
String getEnclosingClassName();
|
||||
|
||||
/**
|
||||
* Return whether the underlying class has a super class.
|
||||
*/
|
||||
boolean hasSuperClass();
|
||||
|
||||
/**
|
||||
* Return the name of the super class of the underlying class,
|
||||
* or <code>null</code> if there is no super class defined.
|
||||
*/
|
||||
String getSuperClassName();
|
||||
|
||||
/**
|
||||
* Return the name of all interfaces that the underlying class
|
||||
* implements, or an empty array if there are none.
|
||||
*/
|
||||
String[] getInterfaceNames();
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.core.type;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
|
||||
/**
|
||||
* {@link AnnotationMetadata} implementation that uses standard reflection
|
||||
* to introspect a given <code>Class</code>.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Mark Fisher
|
||||
* @since 2.5
|
||||
*/
|
||||
public class StandardAnnotationMetadata extends StandardClassMetadata implements AnnotationMetadata {
|
||||
|
||||
public StandardAnnotationMetadata(Class introspectedClass) {
|
||||
super(introspectedClass);
|
||||
}
|
||||
|
||||
|
||||
public Set<String> getAnnotationTypes() {
|
||||
Set<String> types = new HashSet<String>();
|
||||
Annotation[] anns = getIntrospectedClass().getAnnotations();
|
||||
for (int i = 0; i < anns.length; i++) {
|
||||
types.add(anns[i].annotationType().getName());
|
||||
}
|
||||
return types;
|
||||
}
|
||||
|
||||
public boolean hasAnnotation(String annotationType) {
|
||||
Annotation[] anns = getIntrospectedClass().getAnnotations();
|
||||
for (int i = 0; i < anns.length; i++) {
|
||||
if (anns[i].annotationType().getName().equals(annotationType)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Set<String> getMetaAnnotationTypes(String annotationType) {
|
||||
Annotation[] anns = getIntrospectedClass().getAnnotations();
|
||||
for (int i = 0; i < anns.length; i++) {
|
||||
if (anns[i].annotationType().getName().equals(annotationType)) {
|
||||
Set<String> types = new HashSet<String>();
|
||||
Annotation[] metaAnns = anns[i].annotationType().getAnnotations();
|
||||
for (Annotation meta : metaAnns) {
|
||||
types.add(meta.annotationType().getName());
|
||||
}
|
||||
return types;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean hasMetaAnnotation(String annotationType) {
|
||||
Annotation[] anns = getIntrospectedClass().getAnnotations();
|
||||
for (int i = 0; i < anns.length; i++) {
|
||||
Annotation[] metaAnns = anns[i].annotationType().getAnnotations();
|
||||
for (Annotation meta : metaAnns) {
|
||||
if (meta.annotationType().getName().equals(annotationType)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Map<String, Object> getAnnotationAttributes(String annotationType) {
|
||||
Annotation[] anns = getIntrospectedClass().getAnnotations();
|
||||
for (int i = 0; i < anns.length; i++) {
|
||||
Annotation ann = anns[i];
|
||||
if (ann.annotationType().getName().equals(annotationType)) {
|
||||
return AnnotationUtils.getAnnotationAttributes(ann);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.core.type;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
/**
|
||||
* {@link ClassMetadata} implementation that uses standard reflection
|
||||
* to introspect a given <code>Class</code>.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.5
|
||||
*/
|
||||
public class StandardClassMetadata implements ClassMetadata {
|
||||
|
||||
private final Class introspectedClass;
|
||||
|
||||
|
||||
public StandardClassMetadata(Class introspectedClass) {
|
||||
this.introspectedClass = introspectedClass;
|
||||
}
|
||||
|
||||
public final Class getIntrospectedClass() {
|
||||
return this.introspectedClass;
|
||||
}
|
||||
|
||||
|
||||
public String getClassName() {
|
||||
return getIntrospectedClass().getName();
|
||||
}
|
||||
|
||||
public boolean isInterface() {
|
||||
return getIntrospectedClass().isInterface();
|
||||
}
|
||||
|
||||
public boolean isAbstract() {
|
||||
return Modifier.isAbstract(getIntrospectedClass().getModifiers());
|
||||
}
|
||||
|
||||
public boolean isConcrete() {
|
||||
return !(isInterface() || isAbstract());
|
||||
}
|
||||
|
||||
public boolean isIndependent() {
|
||||
return (!hasEnclosingClass() ||
|
||||
(getIntrospectedClass().getDeclaringClass() != null &&
|
||||
Modifier.isStatic(getIntrospectedClass().getModifiers())));
|
||||
}
|
||||
|
||||
public boolean hasEnclosingClass() {
|
||||
return (getIntrospectedClass().getEnclosingClass() != null);
|
||||
}
|
||||
|
||||
public String getEnclosingClassName() {
|
||||
Class enclosingClass = getIntrospectedClass().getEnclosingClass();
|
||||
return (enclosingClass != null ? enclosingClass.getName() : null);
|
||||
}
|
||||
|
||||
public boolean hasSuperClass() {
|
||||
return (getIntrospectedClass().getSuperclass() != null);
|
||||
}
|
||||
|
||||
public String getSuperClassName() {
|
||||
Class superClass = getIntrospectedClass().getSuperclass();
|
||||
return (superClass != null ? superClass.getName() : null);
|
||||
}
|
||||
|
||||
public String[] getInterfaceNames() {
|
||||
Class[] ifcs = getIntrospectedClass().getInterfaces();
|
||||
String[] ifcNames = new String[ifcs.length];
|
||||
for (int i = 0; i < ifcs.length; i++) {
|
||||
ifcNames[i] = ifcs[i].getName();
|
||||
}
|
||||
return ifcNames;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.core.type.classreading;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.objectweb.asm.AnnotationVisitor;
|
||||
import org.objectweb.asm.Type;
|
||||
import org.objectweb.asm.commons.EmptyVisitor;
|
||||
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
|
||||
/**
|
||||
* ASM class visitor which looks for the class name and implemented types as
|
||||
* well as for the annotations defined on the class, exposing them through
|
||||
* the {@link org.springframework.core.type.AnnotationMetadata} interface.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Mark Fisher
|
||||
* @since 2.5
|
||||
*/
|
||||
class AnnotationMetadataReadingVisitor extends ClassMetadataReadingVisitor implements AnnotationMetadata {
|
||||
|
||||
private final Map<String, Map<String, Object>> attributesMap = new LinkedHashMap<String, Map<String, Object>>();
|
||||
|
||||
private final Map<String, Set<String>> metaAnnotationMap = new LinkedHashMap<String, Set<String>>();
|
||||
|
||||
|
||||
private final ClassLoader classLoader;
|
||||
|
||||
|
||||
public AnnotationMetadataReadingVisitor(ClassLoader classLoader) {
|
||||
this.classLoader = classLoader;
|
||||
}
|
||||
|
||||
|
||||
public AnnotationVisitor visitAnnotation(final String desc, boolean visible) {
|
||||
final String className = Type.getType(desc).getClassName();
|
||||
final Map<String, Object> attributes = new LinkedHashMap<String, Object>();
|
||||
return new EmptyVisitor() {
|
||||
public void visit(String name, Object value) {
|
||||
// Explicitly defined annotation attribute value.
|
||||
attributes.put(name, value);
|
||||
}
|
||||
public void visitEnd() {
|
||||
try {
|
||||
Class annotationClass = classLoader.loadClass(className);
|
||||
// Check declared default values of attributes in the annotation type.
|
||||
Method[] annotationAttributes = annotationClass.getMethods();
|
||||
for (int i = 0; i < annotationAttributes.length; i++) {
|
||||
Method annotationAttribute = annotationAttributes[i];
|
||||
String attributeName = annotationAttribute.getName();
|
||||
Object defaultValue = annotationAttribute.getDefaultValue();
|
||||
if (defaultValue != null && !attributes.containsKey(attributeName)) {
|
||||
attributes.put(attributeName, defaultValue);
|
||||
}
|
||||
}
|
||||
// Register annotations that the annotation type is annotated with.
|
||||
Annotation[] metaAnnotations = annotationClass.getAnnotations();
|
||||
Set<String> metaAnnotationTypeNames = new HashSet<String>();
|
||||
for (Annotation metaAnnotation : metaAnnotations) {
|
||||
metaAnnotationTypeNames.add(metaAnnotation.annotationType().getName());
|
||||
}
|
||||
metaAnnotationMap.put(className, metaAnnotationTypeNames);
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
// Class not found - can't determine meta-annotations.
|
||||
}
|
||||
attributesMap.put(className, attributes);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public Set<String> getAnnotationTypes() {
|
||||
return this.attributesMap.keySet();
|
||||
}
|
||||
|
||||
public boolean hasAnnotation(String annotationType) {
|
||||
return this.attributesMap.containsKey(annotationType);
|
||||
}
|
||||
|
||||
public Set<String> getMetaAnnotationTypes(String annotationType) {
|
||||
return this.metaAnnotationMap.get(annotationType);
|
||||
}
|
||||
|
||||
public boolean hasMetaAnnotation(String metaAnnotationType) {
|
||||
Collection<Set<String>> allMetaTypes = this.metaAnnotationMap.values();
|
||||
for (Set<String> metaTypes : allMetaTypes) {
|
||||
if (metaTypes.contains(metaAnnotationType)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Map<String, Object> getAnnotationAttributes(String annotationType) {
|
||||
return this.attributesMap.get(annotationType);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.core.type.classreading;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
|
||||
/**
|
||||
* Caching implementation of the {@link MetadataReaderFactory} interface,
|
||||
* caching an ASM {@link org.objectweb.asm.ClassReader} per Spring Resource handle
|
||||
* (i.e. per ".class" file).
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.5
|
||||
*/
|
||||
public class CachingMetadataReaderFactory extends SimpleMetadataReaderFactory {
|
||||
|
||||
private final Map<Resource, MetadataReader> classReaderCache = new HashMap<Resource, MetadataReader>();
|
||||
|
||||
|
||||
/**
|
||||
* Create a new CachingMetadataReaderFactory for the default class loader.
|
||||
*/
|
||||
public CachingMetadataReaderFactory() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new CachingMetadataReaderFactory for the given resource loader.
|
||||
* @param resourceLoader the Spring ResourceLoader to use
|
||||
* (also determines the ClassLoader to use)
|
||||
*/
|
||||
public CachingMetadataReaderFactory(ResourceLoader resourceLoader) {
|
||||
super(resourceLoader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new CachingMetadataReaderFactory for the given class loader.
|
||||
* @param classLoader the ClassLoader to use
|
||||
*/
|
||||
public CachingMetadataReaderFactory(ClassLoader classLoader) {
|
||||
super(classLoader);
|
||||
}
|
||||
|
||||
|
||||
public MetadataReader getMetadataReader(Resource resource) throws IOException {
|
||||
synchronized (this.classReaderCache) {
|
||||
MetadataReader metadataReader = this.classReaderCache.get(resource);
|
||||
if (metadataReader == null) {
|
||||
metadataReader = super.getMetadataReader(resource);
|
||||
this.classReaderCache.put(resource, metadataReader);
|
||||
}
|
||||
return metadataReader;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.core.type.classreading;
|
||||
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.commons.EmptyVisitor;
|
||||
|
||||
import org.springframework.core.type.ClassMetadata;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* ASM class visitor which looks only for the class name and implemented types,
|
||||
* exposing them through the {@link org.springframework.core.type.ClassMetadata}
|
||||
* interface.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Costin Leau
|
||||
* @author Mark Fisher
|
||||
* @author Ramnivas Laddad
|
||||
* @since 2.5
|
||||
*/
|
||||
class ClassMetadataReadingVisitor extends EmptyVisitor implements ClassMetadata {
|
||||
|
||||
private String className;
|
||||
|
||||
private boolean isInterface;
|
||||
|
||||
private boolean isAbstract;
|
||||
|
||||
private String enclosingClassName;
|
||||
|
||||
private boolean independentInnerClass;
|
||||
|
||||
private String superClassName;
|
||||
|
||||
private String[] interfaces;
|
||||
|
||||
|
||||
public void visit(int version, int access, String name, String signature, String supername, String[] interfaces) {
|
||||
this.className = ClassUtils.convertResourcePathToClassName(name);
|
||||
this.isInterface = ((access & Opcodes.ACC_INTERFACE) != 0);
|
||||
this.isAbstract = ((access & Opcodes.ACC_ABSTRACT) != 0);
|
||||
if (supername != null) {
|
||||
this.superClassName = ClassUtils.convertResourcePathToClassName(supername);
|
||||
}
|
||||
this.interfaces = new String[interfaces.length];
|
||||
for (int i = 0; i < interfaces.length; i++) {
|
||||
this.interfaces[i] = ClassUtils.convertResourcePathToClassName(interfaces[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public void visitOuterClass(String owner, String name, String desc) {
|
||||
this.enclosingClassName = ClassUtils.convertResourcePathToClassName(owner);
|
||||
}
|
||||
|
||||
public void visitInnerClass(String name, String outerName, String innerName, int access) {
|
||||
if (outerName != null && this.className.equals(ClassUtils.convertResourcePathToClassName(name))) {
|
||||
this.enclosingClassName = ClassUtils.convertResourcePathToClassName(outerName);
|
||||
this.independentInnerClass = ((access & Opcodes.ACC_STATIC) != 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public String getClassName() {
|
||||
return this.className;
|
||||
}
|
||||
|
||||
public boolean isInterface() {
|
||||
return this.isInterface;
|
||||
}
|
||||
|
||||
public boolean isAbstract() {
|
||||
return this.isAbstract;
|
||||
}
|
||||
|
||||
public boolean isConcrete() {
|
||||
return !(this.isInterface || this.isAbstract);
|
||||
}
|
||||
|
||||
public boolean isIndependent() {
|
||||
return (this.enclosingClassName == null || this.independentInnerClass);
|
||||
}
|
||||
|
||||
public boolean hasEnclosingClass() {
|
||||
return (this.enclosingClassName != null);
|
||||
}
|
||||
|
||||
public String getEnclosingClassName() {
|
||||
return this.enclosingClassName;
|
||||
}
|
||||
|
||||
public boolean hasSuperClass() {
|
||||
return (this.superClassName != null);
|
||||
}
|
||||
|
||||
public String getSuperClassName() {
|
||||
return this.superClassName;
|
||||
}
|
||||
|
||||
public String[] getInterfaceNames() {
|
||||
return this.interfaces;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.core.type.classreading;
|
||||
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.core.type.ClassMetadata;
|
||||
|
||||
/**
|
||||
* Simple facade for accessing class metadata,
|
||||
* as read by an ASM {@link org.objectweb.asm.ClassReader}.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.5
|
||||
*/
|
||||
public interface MetadataReader {
|
||||
|
||||
/**
|
||||
* Read basic class metadata for the underlying class.
|
||||
*/
|
||||
ClassMetadata getClassMetadata();
|
||||
|
||||
/**
|
||||
* Read full annotation metadata for the underlying class.
|
||||
*/
|
||||
AnnotationMetadata getAnnotationMetadata();
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.core.type.classreading;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.springframework.core.io.Resource;
|
||||
|
||||
/**
|
||||
* Factory interface for {@link MetadataReader} instances.
|
||||
* Allows for caching a MetadataReader per original resource.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.5
|
||||
* @see SimpleMetadataReaderFactory
|
||||
* @see CachingMetadataReaderFactory
|
||||
*/
|
||||
public interface MetadataReaderFactory {
|
||||
|
||||
/**
|
||||
* Obtain a MetadataReader for the given class name.
|
||||
* @param className the class name (to be resolved to a ".class" file)
|
||||
* @return a holder for the ClassReader instance (never <code>null</code>)
|
||||
* @throws IOException in case of I/O failure
|
||||
*/
|
||||
MetadataReader getMetadataReader(String className) throws IOException;
|
||||
|
||||
/**
|
||||
* Obtain a MetadataReader for the given resource.
|
||||
* @param resource the resource (pointing to a ".class" file)
|
||||
* @return a holder for the ClassReader instance (never <code>null</code>)
|
||||
* @throws IOException in case of I/O failure
|
||||
*/
|
||||
MetadataReader getMetadataReader(Resource resource) throws IOException;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.core.type.classreading;
|
||||
|
||||
import org.objectweb.asm.ClassReader;
|
||||
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.core.type.ClassMetadata;
|
||||
|
||||
/**
|
||||
* {@link MetadataReader} implementation based on an ASM
|
||||
* {@link org.objectweb.asm.ClassReader}.
|
||||
*
|
||||
* <p>Package-visible in order to allow for repackaging the ASM library
|
||||
* without effect on users of the <code>core.type</code> package.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.5
|
||||
*/
|
||||
class SimpleMetadataReader implements MetadataReader {
|
||||
|
||||
private final ClassReader classReader;
|
||||
|
||||
private final ClassLoader classLoader;
|
||||
|
||||
|
||||
public SimpleMetadataReader(ClassReader classReader, ClassLoader classLoader) {
|
||||
this.classReader = classReader;
|
||||
this.classLoader = classLoader;
|
||||
}
|
||||
|
||||
|
||||
public ClassMetadata getClassMetadata() {
|
||||
ClassMetadataReadingVisitor visitor = new ClassMetadataReadingVisitor();
|
||||
this.classReader.accept(visitor, true);
|
||||
return visitor;
|
||||
}
|
||||
|
||||
public AnnotationMetadata getAnnotationMetadata() {
|
||||
AnnotationMetadataReadingVisitor visitor = new AnnotationMetadataReadingVisitor(this.classLoader);
|
||||
this.classReader.accept(visitor, true);
|
||||
return visitor;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.core.type.classreading;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.objectweb.asm.ClassReader;
|
||||
|
||||
import org.springframework.core.io.DefaultResourceLoader;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* Simple implementation of the {@link MetadataReaderFactory} interface,
|
||||
* creating a new ASM {@link org.objectweb.asm.ClassReader} for every request.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.5
|
||||
*/
|
||||
public class SimpleMetadataReaderFactory implements MetadataReaderFactory {
|
||||
|
||||
private final ResourceLoader resourceLoader;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new SimpleMetadataReaderFactory for the default class loader.
|
||||
*/
|
||||
public SimpleMetadataReaderFactory() {
|
||||
this.resourceLoader = new DefaultResourceLoader();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new SimpleMetadataReaderFactory for the given resource loader.
|
||||
* @param resourceLoader the Spring ResourceLoader to use
|
||||
* (also determines the ClassLoader to use)
|
||||
*/
|
||||
public SimpleMetadataReaderFactory(ResourceLoader resourceLoader) {
|
||||
this.resourceLoader = (resourceLoader != null ? resourceLoader : new DefaultResourceLoader());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new SimpleMetadataReaderFactory for the given class loader.
|
||||
* @param classLoader the ClassLoader to use
|
||||
*/
|
||||
public SimpleMetadataReaderFactory(ClassLoader classLoader) {
|
||||
this.resourceLoader =
|
||||
(classLoader != null ? new DefaultResourceLoader(classLoader) : new DefaultResourceLoader());
|
||||
}
|
||||
|
||||
|
||||
public MetadataReader getMetadataReader(String className) throws IOException {
|
||||
String resourcePath = ResourceLoader.CLASSPATH_URL_PREFIX +
|
||||
ClassUtils.convertClassNameToResourcePath(className) + ClassUtils.CLASS_FILE_SUFFIX;
|
||||
return getMetadataReader(this.resourceLoader.getResource(resourcePath));
|
||||
}
|
||||
|
||||
public MetadataReader getMetadataReader(Resource resource) throws IOException {
|
||||
InputStream is = resource.getInputStream();
|
||||
try {
|
||||
return new SimpleMetadataReader(new ClassReader(is), this.resourceLoader.getClassLoader());
|
||||
}
|
||||
finally {
|
||||
is.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<html>
|
||||
<body>
|
||||
|
||||
Core support package for type introspection through ASM-based class reading.
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.core.type.filter;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.springframework.core.type.ClassMetadata;
|
||||
import org.springframework.core.type.classreading.MetadataReaderFactory;
|
||||
import org.springframework.core.type.classreading.MetadataReader;
|
||||
|
||||
/**
|
||||
* Type filter that exposes a
|
||||
* {@link org.springframework.core.type.ClassMetadata} object
|
||||
* to subclasses, for class testing purposes.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Costin Leau
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.5
|
||||
* @see #match(org.springframework.core.type.ClassMetadata)
|
||||
*/
|
||||
public abstract class AbstractClassTestingTypeFilter implements TypeFilter {
|
||||
|
||||
public final boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
|
||||
throws IOException {
|
||||
|
||||
return match(metadataReader.getClassMetadata());
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine a match based on the given ClassMetadata object.
|
||||
* @param metadata the ClassMetadata object
|
||||
* @return whether this filter matches on the specified type
|
||||
*/
|
||||
protected abstract boolean match(ClassMetadata metadata);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.core.type.filter;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.springframework.core.type.ClassMetadata;
|
||||
import org.springframework.core.type.classreading.MetadataReaderFactory;
|
||||
import org.springframework.core.type.classreading.MetadataReader;
|
||||
|
||||
/**
|
||||
* Type filter that is aware of traversing over hierarchy.
|
||||
*
|
||||
* <p>This filter is useful when matching needs to be made based on potentially the
|
||||
* whole class/interface hierarchy. The algorithm employed uses succeed-fast
|
||||
* strategy i.e. if at anytime a match is declared, no further processing is
|
||||
* carried out.
|
||||
*
|
||||
* @author Ramnivas Laddad
|
||||
* @author Mark Fisher
|
||||
* @since 2.5
|
||||
*/
|
||||
public abstract class AbstractTypeHierarchyTraversingFilter implements TypeFilter {
|
||||
|
||||
private final boolean considerInherited;
|
||||
|
||||
private final boolean considerInterfaces;
|
||||
|
||||
|
||||
protected AbstractTypeHierarchyTraversingFilter(boolean considerInherited, boolean considerInterfaces) {
|
||||
this.considerInherited = considerInherited;
|
||||
this.considerInterfaces = considerInterfaces;
|
||||
}
|
||||
|
||||
|
||||
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
|
||||
throws IOException {
|
||||
|
||||
// This method optimizes avoiding unnecessary creation of ClassReaders
|
||||
// as well as visiting over those readers.
|
||||
if (matchSelf(metadataReader)) {
|
||||
return true;
|
||||
}
|
||||
ClassMetadata metadata = metadataReader.getClassMetadata();
|
||||
if (matchClassName(metadata.getClassName())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!this.considerInherited) {
|
||||
return false;
|
||||
}
|
||||
if (metadata.hasSuperClass()) {
|
||||
// Optimization to avoid creating ClassReader for super class.
|
||||
Boolean superClassMatch = matchSuperClass(metadata.getSuperClassName());
|
||||
if (superClassMatch != null) {
|
||||
if (superClassMatch.booleanValue()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Need to read super class to determine a match...
|
||||
if (match(metadata.getSuperClassName(), metadataReaderFactory)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.considerInterfaces) {
|
||||
return false;
|
||||
}
|
||||
for (String ifc : metadata.getInterfaceNames()) {
|
||||
// Optimization to avoid creating ClassReader for super class
|
||||
Boolean interfaceMatch = matchInterface(ifc);
|
||||
if (interfaceMatch != null) {
|
||||
if (interfaceMatch.booleanValue()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Need to read interface to determine a match...
|
||||
if (match(ifc, metadataReaderFactory)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean match(String className, MetadataReaderFactory metadataReaderFactory) throws IOException {
|
||||
return match(metadataReaderFactory.getMetadataReader(className), metadataReaderFactory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this to match self characteristics alone. Typically,
|
||||
* the implementation will use a visitor to extract information
|
||||
* to perform matching.
|
||||
*/
|
||||
protected boolean matchSelf(MetadataReader metadataReader) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this to match on type name.
|
||||
*/
|
||||
protected boolean matchClassName(String className) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this to match on super type name.
|
||||
*/
|
||||
protected Boolean matchSuperClass(String superClassName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this to match on interface type name.
|
||||
*/
|
||||
protected Boolean matchInterface(String interfaceNames) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.core.type.filter;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.annotation.Inherited;
|
||||
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.core.type.classreading.MetadataReader;
|
||||
|
||||
/**
|
||||
* A simple filter which matches classes with a given annotation,
|
||||
* checking inherited annotations as well.
|
||||
*
|
||||
* <p>The matching logic mirrors that of <code>Class.isAnnotationPresent()</code>.
|
||||
*
|
||||
* @author Mark Fisher
|
||||
* @author Ramnivas Laddad
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.5
|
||||
*/
|
||||
public class AnnotationTypeFilter extends AbstractTypeHierarchyTraversingFilter {
|
||||
|
||||
private final Class<? extends Annotation> annotationType;
|
||||
|
||||
private final boolean considerMetaAnnotations;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new AnnotationTypeFilter for the given annotation type.
|
||||
* This filter will also match meta-annotations. To disable the
|
||||
* meta-annotation matching, use the constructor that accepts a
|
||||
* '<code>considerMetaAnnotations</code>' argument.
|
||||
* @param annotationType the annotation type to match
|
||||
*/
|
||||
public AnnotationTypeFilter(Class<? extends Annotation> annotationType) {
|
||||
this(annotationType, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new AnnotationTypeFilter for the given annotation type.
|
||||
* @param annotationType the annotation type to match
|
||||
* @param considerMetaAnnotations whether to also match on meta-annotations
|
||||
*/
|
||||
public AnnotationTypeFilter(Class<? extends Annotation> annotationType, boolean considerMetaAnnotations) {
|
||||
super(annotationType.isAnnotationPresent(Inherited.class), false);
|
||||
this.annotationType = annotationType;
|
||||
this.considerMetaAnnotations = considerMetaAnnotations;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected boolean matchSelf(MetadataReader metadataReader) {
|
||||
AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
|
||||
return metadata.hasAnnotation(this.annotationType.getName()) ||
|
||||
(this.considerMetaAnnotations && metadata.hasMetaAnnotation(this.annotationType.getName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Boolean matchSuperClass(String superClassName) {
|
||||
if (Object.class.getName().equals(superClassName)) {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
else if (superClassName.startsWith("java.")) {
|
||||
try {
|
||||
Class clazz = getClass().getClassLoader().loadClass(superClassName);
|
||||
return Boolean.valueOf(clazz.getAnnotation(this.annotationType) != null);
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
// Class not found - can't determine a match that way.
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.core.type.filter;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.aspectj.bridge.IMessageHandler;
|
||||
import org.aspectj.weaver.ResolvedType;
|
||||
import org.aspectj.weaver.World;
|
||||
import org.aspectj.weaver.bcel.BcelWorld;
|
||||
import org.aspectj.weaver.patterns.Bindings;
|
||||
import org.aspectj.weaver.patterns.FormalBinding;
|
||||
import org.aspectj.weaver.patterns.IScope;
|
||||
import org.aspectj.weaver.patterns.PatternParser;
|
||||
import org.aspectj.weaver.patterns.SimpleScope;
|
||||
import org.aspectj.weaver.patterns.TypePattern;
|
||||
|
||||
import org.springframework.core.type.classreading.MetadataReaderFactory;
|
||||
import org.springframework.core.type.classreading.MetadataReader;
|
||||
|
||||
/**
|
||||
* Type filter that uses AspectJ type pattern for matching.
|
||||
*
|
||||
* <p>A critical implementation details of this type filter is that it does not
|
||||
* load the class being examined to match with a type pattern.
|
||||
*
|
||||
* @author Ramnivas Laddad
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.5
|
||||
*/
|
||||
public class AspectJTypeFilter implements TypeFilter {
|
||||
|
||||
private final World world;
|
||||
|
||||
private final TypePattern typePattern;
|
||||
|
||||
|
||||
public AspectJTypeFilter(String typePatternExpression, ClassLoader classLoader) {
|
||||
this.world = new BcelWorld(classLoader, IMessageHandler.THROW, null);
|
||||
this.world.setBehaveInJava5Way(true);
|
||||
PatternParser patternParser = new PatternParser(typePatternExpression);
|
||||
TypePattern typePattern = patternParser.parseTypePattern();
|
||||
typePattern.resolve(this.world);
|
||||
IScope scope = new SimpleScope(this.world, new FormalBinding[0]);
|
||||
this.typePattern = typePattern.resolveBindings(scope, Bindings.NONE, false, false);
|
||||
}
|
||||
|
||||
|
||||
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
|
||||
throws IOException {
|
||||
|
||||
String className = metadataReader.getClassMetadata().getClassName();
|
||||
ResolvedType resolvedType = this.world.resolve(className);
|
||||
return this.typePattern.matchesStatically(resolvedType);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.core.type.filter;
|
||||
|
||||
/**
|
||||
* A simple filter which matches classes that are assignable to a given type.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Mark Fisher
|
||||
* @author Ramnivas Laddad
|
||||
* @since 2.5
|
||||
*/
|
||||
public class AssignableTypeFilter extends AbstractTypeHierarchyTraversingFilter {
|
||||
|
||||
private final Class targetType;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new AssignableTypeFilter for the given type.
|
||||
* @param targetType the type to match
|
||||
*/
|
||||
public AssignableTypeFilter(Class targetType) {
|
||||
super(true, true);
|
||||
this.targetType = targetType;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected boolean matchClassName(String className) {
|
||||
return this.targetType.getName().equals(className);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Boolean matchSuperClass(String superClassName) {
|
||||
return matchTargetType(superClassName);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Boolean matchInterface(String interfaceName) {
|
||||
return matchTargetType(interfaceName);
|
||||
}
|
||||
|
||||
protected Boolean matchTargetType(String typeName) {
|
||||
if (this.targetType.getName().equals(typeName)) {
|
||||
return true;
|
||||
}
|
||||
else if (Object.class.getName().equals(typeName)) {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
else if (typeName.startsWith("java.")) {
|
||||
try {
|
||||
Class clazz = getClass().getClassLoader().loadClass(typeName);
|
||||
return Boolean.valueOf(this.targetType.isAssignableFrom(clazz));
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
// Class not found - can't determine a match that way.
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.core.type.filter;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.springframework.core.type.ClassMetadata;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* A simple filter for matching a fully-qualified class name with a regex {@link Pattern}.
|
||||
*
|
||||
* @author Mark Fisher
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.5
|
||||
*/
|
||||
public class RegexPatternTypeFilter extends AbstractClassTestingTypeFilter {
|
||||
|
||||
private final Pattern pattern;
|
||||
|
||||
|
||||
public RegexPatternTypeFilter(Pattern pattern) {
|
||||
Assert.notNull(pattern, "Pattern must not be null");
|
||||
this.pattern = pattern;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected boolean match(ClassMetadata metadata) {
|
||||
return this.pattern.matcher(metadata.getClassName()).matches();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.core.type.filter;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.springframework.core.type.classreading.MetadataReader;
|
||||
import org.springframework.core.type.classreading.MetadataReaderFactory;
|
||||
|
||||
/**
|
||||
* Base interface for type filters using a
|
||||
* {@link org.springframework.core.type.classreading.MetadataReader}.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @author Juergen Hoeller
|
||||
* @author Mark Fisher
|
||||
* @since 2.5
|
||||
*/
|
||||
public interface TypeFilter {
|
||||
|
||||
/**
|
||||
* Determine whether this filter matches for the class described by
|
||||
* the given metadata.
|
||||
* @param metadataReader the metadata reader for the target class
|
||||
* @param metadataReaderFactory a factory for obtaining metadata readers
|
||||
* for other classes (such as superclasses and interfaces)
|
||||
* @return whether this filter matches
|
||||
* @throws IOException in case of I/O failure when reading metadata
|
||||
*/
|
||||
boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
|
||||
throws IOException;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<html>
|
||||
<body>
|
||||
|
||||
Core support package for type filtering (e.g. for classpath scanning).
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<html>
|
||||
<body>
|
||||
|
||||
Core support package for type introspection.
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -8,6 +8,7 @@ Import-Template:
|
|||
org.apache.commons.logging.*;version="[1.1.1, 2.0.0)",
|
||||
org.objectweb.asm.*;version="[2.2.3, 3.0.0)";resolution:=optional,
|
||||
org.apache.log4j.*;version="[1.2.15, 2.0.0)";resolution:=optional,
|
||||
org.aspectj.*;version="[1.5.4, 2.0.0)";resolution:=optional
|
||||
Unversioned-Imports:
|
||||
javax.xml.transform.*,
|
||||
org.w3c.dom.*,
|
||||
|
|
|
|||
Loading…
Reference in New Issue