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    }