All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.milyn.annotation.AnnotatedMethodImpl Maven / Gradle / Ivy

The newest version!
// Copyright 2007 Fusionsoft, Inc. All rights reserved.
// Use is subject to license terms.
package org.milyn.annotation;

/** The standard implementation for the annotated method.
 *
 * Note: This class is a modified version of the original Fusionsoft Annotation
 * library. See: {@link http://www.fusionsoft-online.com/articles-java-annotations.php}
 *
 * @author Vladimir Ovchinnikov
 * @author [email protected]
 * @version 1.1
 */
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

class AnnotatedMethodImpl implements AnnotatedMethod {

	private final AnnotatedClass annotatedClass;

	private final Method method;

	private Map, Annotation> classToAnnotationMap;

	private Annotation[] annotations;

	private Annotation[][] parameterAnnotations;

	AnnotatedMethodImpl(final AnnotatedClass annotatedClass, final Method method) {
		super();
		this.annotatedClass = annotatedClass;
		this.method = method;
	}

	private Map, Annotation> getAllAnnotationMap(){
		if (classToAnnotationMap == null) {
			classToAnnotationMap = getAllAnnotationMapCalculated();
		}
		return classToAnnotationMap;
	}

	private Map, Annotation> getAllAnnotationMapCalculated(){
		final HashMap, Annotation> result = new HashMap, Annotation>();

		final Class superClass = getAnnotatedClass().getTheClass().getSuperclass();
		// Get the superclass's overriden method annotations
		if (superClass != null) {
			fillAnnotationsForOneMethod(result,
					AnnotationManager.getAnnotatedClass(
							superClass)
							.getAnnotatedMethod(getMethod().getName(),
									getMethod().getParameterTypes()));
		}

		// Get the superinterfaces' overriden method annotations
		for (final Class c : getAnnotatedClass().getTheClass().getInterfaces()){
			fillAnnotationsForOneMethod(result,
					AnnotationManager.getAnnotatedClass(c)
					.getAnnotatedMethod(getMethod().getName(),
							getMethod().getParameterTypes()));
		}

		// Get its own annotations. They have preference to inherited annotations.
		for (final Annotation annotation : getMethod().getDeclaredAnnotations()) {
			result.put(annotation.getClass().getInterfaces()[0], annotation);
		}

		return result;
	}

	/**
	 * @param result is the map of classes to annotations to fill
	 * @param annotatedMethod the method to get annotations. Does nothing
	 * if the annotated method is null.
	 */
	private void fillAnnotationsForOneMethod(final HashMap, Annotation> result,
			final AnnotatedMethod annotatedMethod) {

		if (annotatedMethod == null) {
			return;
		}

		addAnnotations(result, annotatedMethod.getAllAnnotations());
	}

	/**
	 * @param result map of classes to annotations
	 * @param annotations to add to the result
	 */
	private void addAnnotations(final Map, Annotation> result,
			final Annotation[] annotations) {

		for (final Annotation annotation : annotations) {
			if (annotation == null) {
				continue;
			}

			result.put(annotation.getClass().getInterfaces()[0], annotation); /*It means to take the last annotation*/

//			if (result.containsKey(annotation.getClass().getInterfaces()[0]))
//				result.put(annotation.getClass().getInterfaces()[0],
//						null /*it means not to take the annotation at all*/);
//			else
//				result.put(annotation.getClass().getInterfaces()[0], annotation);

		}
	}

	public Annotation[] getAllAnnotations() {
		if (annotations == null) {
			annotations = getAllAnnotationsCalculated();
		}
		return annotations;
	}

	private Annotation[] getAllAnnotationsCalculated() {
		final Collection values = getAllAnnotationMap().values();
		return values.toArray(new Annotation[0]);
	}


	public AnnotatedClass getAnnotatedClass() {
		return annotatedClass;
	}

	@SuppressWarnings("unchecked")
	public  T getAnnotation(final Class annotationClass) {
		return (T) getAllAnnotationMap().get(annotationClass);
	}

	public Method getMethod() {
		return method;
	}

	/*
	 * (non-Javadoc)
	 * @see com.fusionsoft.annotation.AnnotatedMethod#isAnnotationPresent(java.lang.Class)
	 */
	public boolean isAnnotationPresent(
			final Class annotationClass) {

		return getAnnotation(annotationClass) != null;
	}

	/**
	 * @param result is the map of classes to annotations to fill
	 * @param annotatedMethod the method to get annotations. Does nothing
	 * if the annotated method is null.
	 */
	@SuppressWarnings("unused")
	private void fillAnnotationsForParameters(final Map, Annotation>[] result,
			final Annotation[][] paramAnnotations) {

		for (int i = 0; i < paramAnnotations.length; i++) {
			final Annotation[] annontations = paramAnnotations[i];

			Map, Annotation> map = result[i];
			if (map == null) {
				map = new HashMap, Annotation>();
				result[i] = map;
			}

			addAnnotations(map, annontations);
		}
	}


	/**
	 * Process the parameter annotations
	 *
	 * @return
	 */
	private Annotation[][] getParameterAnnotationsCalculated(){

		@SuppressWarnings("unchecked")
		final Map, Annotation>[] mapResult = new Map[method.getParameterAnnotations().length];

		final Class superClass = getAnnotatedClass().getTheClass().getSuperclass();
		if (superClass != null) {

			final AnnotatedClass aClass = AnnotationManager.getAnnotatedClass(superClass);
			final AnnotatedMethod aMethod = aClass.getAnnotatedMethod(getMethod().getName(), getMethod().getParameterTypes());

			if(aMethod != null) {
				final Annotation[][] paramAnnotations = aMethod.getParameterAnnotations();

				fillAnnotationsForParameters(mapResult, paramAnnotations);
			}

		}

		// Get the superinterfaces' overriden method annotations
		for (final Class c : getAnnotatedClass().getTheClass().getInterfaces()){

			final AnnotatedClass aClass = AnnotationManager.getAnnotatedClass(c);
			final AnnotatedMethod aMethod = aClass.getAnnotatedMethod(getMethod().getName(), getMethod().getParameterTypes());

			if(aMethod != null) {
				final Annotation[][] paramAnnotations = aMethod.getParameterAnnotations();

				fillAnnotationsForParameters(mapResult, paramAnnotations);
			}
		}

		// Get its own annotations. They have preference to inherited annotations.
		fillAnnotationsForParameters(mapResult, method.getParameterAnnotations());

		final Annotation[][] result = new Annotation[mapResult.length][];
		final Annotation[] arrayTemplate = new Annotation[0];
		for(int i = 0; i < mapResult.length; i++) {

			result[i] = mapResult[i].values().toArray(arrayTemplate);

		}

		return result;
	}

	/* (non-Javadoc)
	 * @see com.fusionsoft.annotation.AnnotatedMethod#getParameterAnnotations()
	 */
	public Annotation[][] getParameterAnnotations() {
		if(parameterAnnotations == null) {
			parameterAnnotations = getParameterAnnotationsCalculated();
		}
		return parameterAnnotations;
	}



}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy