001 package org.tynamo.descriptor.annotation;
002
003 import ognl.Ognl;
004 import org.tynamo.descriptor.*;
005
006 import java.beans.Introspector;
007 import java.beans.PropertyDescriptor;
008 import java.lang.annotation.Annotation;
009 import java.lang.reflect.Field;
010 import java.lang.reflect.Method;
011 import java.util.Map;
012
013 /**
014 * Creates {@link InitialValueDescriptorExtension} and {@link PossibleValuesDescriptorExtension} extensions
015 * using the information retrieved from {@link InitialValue} and {@link PossibleValues} annotations.
016 */
017 public class OgnlAnnotationsDecorator implements DescriptorDecorator
018 {
019
020 /**
021 * It holds the Map of variables to put into the available namespace (scope) for OGNL expressions.
022 */
023 private Map context;
024
025 /**
026 * {@inheritDoc}
027 */
028 public TynamoClassDescriptor decorate(TynamoClassDescriptor descriptor)
029 {
030 decoratePropertyDescriptors(descriptor);
031 return descriptor;
032 }
033
034 private void decoratePropertyDescriptors(TynamoClassDescriptor descriptor)
035 {
036 for (TynamoPropertyDescriptor propertyDescriptor : descriptor.getPropertyDescriptors())
037 {
038 decoratePropertyDescriptor(propertyDescriptor);
039 // recursively decorate components
040 if (propertyDescriptor.isEmbedded())
041 {
042 decorate((EmbeddedDescriptor) propertyDescriptor);
043 }
044 }
045 }
046
047 private void decoratePropertyDescriptor(TynamoPropertyDescriptor propertyDescriptor)
048 {
049 try
050 {
051 Field propertyField = propertyDescriptor.getBeanType().getDeclaredField(propertyDescriptor.getName());
052 decorateFromAnnotations(propertyDescriptor, propertyField.getAnnotations());
053
054 } catch (Exception ex)
055 {
056 // don't care
057 }
058 try
059 {
060 PropertyDescriptor beanPropDescriptor = (PropertyDescriptor) Ognl.getValue("propertyDescriptors.{? name == '" + propertyDescriptor.getName() + "'}[0]",
061 Introspector.getBeanInfo(propertyDescriptor.getBeanType()));
062
063 Method readMethod = beanPropDescriptor.getReadMethod();
064 decorateFromAnnotations(propertyDescriptor, readMethod.getAnnotations());
065 }
066 catch (Exception ex)
067 {
068 // don't care
069 }
070 }
071
072 private void decorateFromAnnotations(Descriptor descriptor, Annotation[] annotations)
073 {
074 for (Annotation annotation : annotations)
075 {
076 if (annotation instanceof InitialValue)
077 {
078 InitialValueDescriptorExtension extension = new InitialValueDescriptorExtension(((InitialValue) annotation).value(), context);
079 descriptor.addExtension(InitialValueDescriptorExtension.class.getName(), extension);
080 } else if (annotation instanceof PossibleValues)
081 {
082 PossibleValuesDescriptorExtension extension = new PossibleValuesDescriptorExtension(((PossibleValues) annotation).value(), context);
083 descriptor.addExtension(PossibleValuesDescriptorExtension.class.getName(), extension);
084 }
085 }
086 }
087
088 /**
089 * sets the context value
090 *
091 * @param context
092 */
093 public void setContext(Map context)
094 {
095 this.context = context;
096 }
097 }