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