/* * This code is distributed under The GNU Lesser General Public License (LGPLv3) * Please visit GNU site for LGPLv3 http://www.gnu.org/copyleft/lesser.html * * Copyright Denis Pavlov 2009 * Web: http://www.genericdtoassembler.org * SVN: https://svn.code.sf.net/p/geda-genericdto/code/trunk/ * SVN (mirror): http://geda-genericdto.googlecode.com/svn/trunk/ */ package com.inspiresoftware.lib.dto.geda.assembler.annotations.impl; import com.inspiresoftware.lib.dto.geda.annotations.*; import com.inspiresoftware.lib.dto.geda.assembler.annotations.AnnotationProxy; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.lang.reflect.Proxy; import java.util.HashMap; import java.util.Map; /** * Annotation proxy factory that hides some of the complexity by providing static * wrappers for same classloader annotations and reflection proxies for external * class loaders. * * @since 3.0.0 * * User: denispavlov * Date: 13-02-21 * Time: 11:41 AM */ public final class AnnotationProxies { private static final AnnotationProxy NULL = new NullAnnotationProxy(); private AnnotationProxies() { // no instance } /** * Some annotations are proxied. This method attempt to detect this. * * @param annotation annotation or proxy * * @return annotation class */ private static Class getAnnotationTrueClass(Annotation annotation) { if (annotation instanceof Proxy) { return annotation.getClass().getInterfaces()[0]; } return annotation.getClass(); } /** * Get @Dto proxy for this class. * * @param clazz class to discover @Dto annotation for * * @return annotation proxy (never null) */ public static AnnotationProxy getClassAnnotationProxy(Class clazz) { for (final Annotation annotation : clazz.getDeclaredAnnotations()) { if (annotation instanceof Dto) { return new LocalClassLoaderDtoAnnotationProxy((Dto) annotation); } else if ("com.inspiresoftware.lib.dto.geda.annotations.Dto" .equals(getAnnotationTrueClass(annotation).getCanonicalName())) { return new ReflectionAnnotationProxy(annotation, "value"); } } return NULL; } private static final Map<String, String[]> REFLECTIVE_PROPERTIES = new HashMap<String, String[]>(); static { REFLECTIVE_PROPERTIES.put( "com.inspiresoftware.lib.dto.geda.annotations.DtoField", new String[] { "value", "converter", "readOnly", "entityBeanKeys", "dtoBeanKey" } ); REFLECTIVE_PROPERTIES.put( "com.inspiresoftware.lib.dto.geda.annotations.DtoParent", new String[] { "value", "retriever" } ); REFLECTIVE_PROPERTIES.put( "com.inspiresoftware.lib.dto.geda.annotations.DtoVirtualField", new String[] { "converter", "readOnly", "entityBeanKeys", "dtoBeanKey" } ); REFLECTIVE_PROPERTIES.put( "com.inspiresoftware.lib.dto.geda.annotations.DtoCollection", new String[] { "value", "readOnly", "entityCollectionClass", "entityCollectionClassKey", "dtoCollectionClass", "dtoCollectionClassKey", "entityBeanKeys", "dtoBeanKey", "entityGenericType", "entityGenericTypeKey", "dtoToEntityMatcher", "dtoToEntityMatcherKey" } ); REFLECTIVE_PROPERTIES.put( "com.inspiresoftware.lib.dto.geda.annotations.DtoMap", new String[] { "value", "readOnly", "entityMapOrCollectionClass", "entityMapOrCollectionClassKey", "dtoMapClass", "dtoMapClassKey", "entityBeanKeys", "dtoBeanKey", "entityGenericType", "entityGenericTypeKey", "entityCollectionMapKey", "useEntityMapKey", "dtoToEntityMatcher", "dtoToEntityMatcherKey" } ); } /** * Get @DtoField (+@DtoParent), @DtoVirtualField, @DtoCollection, @DtoMap proxy for this field. * * @param field field to discover annotation for * * @return annotation proxy map (never null) */ public static Map<String, AnnotationProxy> getFieldAnnotationProxy(Field field) { final Map<String, AnnotationProxy> anns = new HashMap<String, AnnotationProxy>(); for (final Annotation annotation : field.getDeclaredAnnotations()) { if (annotation instanceof DtoField) { anns.put("DtoField", new LocalClassLoaderDtoFieldAnnotationProxy((DtoField) annotation)); } else if (annotation instanceof DtoParent) { anns.put("DtoParent", new LocalClassLoaderDtoParentAnnotationProxy((DtoParent) annotation)); } else if (annotation instanceof DtoVirtualField) { anns.put("DtoVirtualField", new LocalClassLoaderDtoVirtualFieldAnnotationProxy((DtoVirtualField) annotation)); } else if (annotation instanceof DtoCollection) { anns.put("DtoCollection", new LocalClassLoaderDtoCollectionAnnotationProxy((DtoCollection) annotation)); } else if (annotation instanceof DtoMap) { anns.put("DtoMap", new LocalClassLoaderDtoMapAnnotationProxy((DtoMap) annotation)); } else { final Class annClass = getAnnotationTrueClass(annotation); final String[] properties = REFLECTIVE_PROPERTIES.get(annClass.getCanonicalName()); if (properties != null) { anns.put(annClass.getSimpleName(), new ReflectionAnnotationProxy(annotation,properties)); } } } return anns; } }