001    package org.tynamo.services;
002    
003    import org.tynamo.internal.services.TynamoBeanModelSourceImpl;
004    import org.apache.tapestry5.ioc.Configuration;
005    import org.apache.tapestry5.ioc.MappedConfiguration;
006    import org.apache.tapestry5.ioc.OrderedConfiguration;
007    import org.apache.tapestry5.ioc.ServiceBinder;
008    import org.apache.tapestry5.ioc.annotations.InjectService;
009    import org.apache.tapestry5.ioc.annotations.Local;
010    import org.apache.tapestry5.ioc.services.CoercionTuple;
011    import org.apache.tapestry5.ioc.services.PropertyAccess;
012    import org.apache.tapestry5.services.*;
013    import org.tynamo.VersionedModule;
014    import org.tynamo.blob.BlobManager;
015    import org.tynamo.blob.DefaultBlobManager;
016    import org.tynamo.builder.BuilderDirector;
017    import org.tynamo.descriptor.decorators.TapestryDecorator;
018    import org.tynamo.descriptor.decorators.TynamoDecorator;
019    import org.tynamo.descriptor.decorators.DescriptorDecorator;
020    import org.tynamo.descriptor.factories.*;
021    import org.tynamo.util.Pair;
022    
023    public class TynamoCoreModule extends VersionedModule
024    {
025    
026            public final static String PROPERTY_DISPLAY_BLOCKS = "tynamo/PropertyDisplayBlocks";
027            public final static String PROPERTY_EDIT_BLOCKS = "tynamo/PropertyEditBlocks";
028    
029            public static void bind(ServiceBinder binder)
030            {
031                    // Make bind() calls on the binder object to define most IoC services.
032                    // Use service builder methods (example below) when the implementation
033                    // is provided inline, or requires more initialization than simply
034                    // invoking the constructor.
035    
036                    binder.bind(BuilderDirector.class, BuilderDirector.class);
037                    binder.bind(DescriptorFactory.class, ReflectionDescriptorFactory.class);
038                    binder.bind(PropertyDescriptorFactory.class, PropertyDescriptorFactoryImpl.class);
039                    binder.bind(MethodDescriptorFactory.class, MethodDescriptorFactoryImpl.class);
040                    binder.bind(EntityCoercerService.class, EntityCoercerServiceImpl.class);
041                    binder.bind(DescriptorService.class, DescriptorServiceImpl.class);
042                    binder.bind(TynamoDataTypeAnalyzer.class, TynamoDataTypeAnalyzer.class);
043    
044                    binder.bind(BlobManager.class, DefaultBlobManager.class).withId("DefaultBlobManager");
045    
046                    binder.bind(BeanModelSource.class, TynamoBeanModelSourceImpl.class).withId("TynamoBeanModelSourceImpl");
047    
048            }
049    
050            public static void contributeServiceOverride(MappedConfiguration<Class, Object> configuration,
051                                                         @Local BeanModelSource beanModelSource)
052            {
053                    configuration.add(BeanModelSource.class, beanModelSource);
054            }
055    
056            /**
057             * Add our components and pages to the "Tynamo" library.
058             */
059            public static void contributeComponentClassResolver(Configuration<LibraryMapping> configuration)
060            {
061                    configuration.add(new LibraryMapping("tynamo", "org.tynamo"));
062            }
063    
064            public static void contributeClasspathAssetAliasManager(MappedConfiguration<String, String> configuration)
065            {
066                    configuration.add("tynamo-" + version, "org/tynamo");
067            }
068    
069    
070            /**
071             * Contribution to the BeanBlockSource service to tell the BeanEditForm component about the editors.
072             */
073            public static void contributeBeanBlockSource(Configuration<BeanBlockContribution> configuration)
074            {
075                    configuration.add(new BeanBlockContribution("enum", PROPERTY_EDIT_BLOCKS, "select", true)); // overrides Tapestry's enum
076    
077                    configuration.add(new BeanBlockContribution("nonVisual", PROPERTY_EDIT_BLOCKS, "nonVisual", true));
078    //              configuration.add(new BeanBlockContribution("dateEditor", PROPERTY_EDIT_BLOCKS, "date", true));
079    //              configuration.add(new BeanBlockContribution("fckEditor", PROPERTY_EDIT_BLOCKS, "fckEditor", true));
080                    configuration.add(new BeanBlockContribution("readOnly", PROPERTY_EDIT_BLOCKS, "readOnly", true));
081                    configuration.add(new BeanBlockContribution("single-valued-association", PROPERTY_EDIT_BLOCKS, "select", true));
082                    configuration.add(new BeanBlockContribution("identifierEditor", PROPERTY_EDIT_BLOCKS, "identifierEditor", true));
083                    configuration.add(new BeanBlockContribution("many-valued-association", PROPERTY_EDIT_BLOCKS, "palette", true));
084                    configuration.add(new BeanBlockContribution("composition", PROPERTY_EDIT_BLOCKS, "nonVisual", true));
085                    configuration.add(new BeanBlockContribution("embedded", PROPERTY_EDIT_BLOCKS, "embedded", true));
086                    configuration.add(new BeanBlockContribution("blob", PROPERTY_EDIT_BLOCKS, "blob", true));
087    
088                    configuration.add(new BeanBlockContribution("nonVisual", PROPERTY_DISPLAY_BLOCKS, "nonVisual", false));
089                    configuration.add(new BeanBlockContribution("single-valued-association", PROPERTY_DISPLAY_BLOCKS, "showPageLink", false));
090                    configuration.add(new BeanBlockContribution("many-valued-association", PROPERTY_DISPLAY_BLOCKS, "showPageLinks", false));
091                    configuration.add(new BeanBlockContribution("composition", PROPERTY_DISPLAY_BLOCKS, "composition", false));
092                    configuration.add(new BeanBlockContribution("blob", PROPERTY_DISPLAY_BLOCKS, "download", false));
093            }
094    
095            public static void contributeDataTypeAnalyzer(OrderedConfiguration<DataTypeAnalyzer> configuration,
096                                                          @InjectService("TynamoDataTypeAnalyzer")
097                                                          DataTypeAnalyzer tynamoDataTypeAnalyzer)
098            {
099                    configuration.add("Tynamo", tynamoDataTypeAnalyzer, "before:Default");
100            }
101    
102            /**
103             * Contributes a set of standard type coercions to the {@link org.apache.tapestry5.ioc.services.TypeCoercer} service:
104             * <ul>
105             * <li>Class to String</li>
106             * <li>String to Double</li>
107             * </ul>
108             */
109            @SuppressWarnings("unchecked")
110            public static void contributeTypeCoercer(final Configuration<CoercionTuple> configuration,
111                                                     @InjectService("EntityCoercerService")
112                                                     EntityCoercerService entityCoercerService)
113            {
114                    configuration.add(new CoercionTuple<Class, String>(Class.class, String.class, new ClassToStringCoercion(entityCoercerService)));
115                    configuration.add(new CoercionTuple<String, Class>(String.class, Class.class, new StringToClassCoercion(entityCoercerService)));
116            }
117    
118            public static void contributeDescriptorFactory(OrderedConfiguration<DescriptorDecorator> configuration,
119                                                           PropertyAccess propertyAccess)
120            {
121                    configuration.add("TynamoDecorator", new TynamoDecorator());
122                    configuration.add("TapestryDecorator", new TapestryDecorator(propertyAccess));
123            }
124    
125            public static void contributeTynamoDataTypeAnalyzer(OrderedConfiguration<Pair> configuration)
126            {
127    
128                    addPairToOrderedConfiguration(configuration, "nonVisual", "nonVisual");
129                    addPairToOrderedConfiguration(configuration, "readOnly", "readOnly");
130    //              addPairToOrderedConfiguration(configuration, "richText", "fckEditor");
131    //              addPairToOrderedConfiguration(configuration, "name.toLowerCase().endsWith('password')", "passwordEditor"); //USE @DataType("password")
132    //              addPairToOrderedConfiguration(configuration, "string and !large and !identifier", "stringEditor"); //managed by Tapestry
133                    addPairToOrderedConfiguration(configuration, "string and large and !identifier", "longtext");
134    //              addPairToOrderedConfiguration(configuration, "date", "dateEditor");
135    //              addPairToOrderedConfiguration(configuration, "numeric and !identifier", "numberEditor"); //managed by Tapestry
136                    addPairToOrderedConfiguration(configuration, "identifier && generated", "readOnly");
137                    addPairToOrderedConfiguration(configuration, "identifier && not(generated) && string", "identifierEditor");
138    //              addPairToOrderedConfiguration(configuration, "identifier && objectReference", "objectReferenceIdentifierEditor");
139    //              addPairToOrderedConfiguration(configuration, "boolean", "booleanEditor"); //managed by Tapestry
140                    addPairToOrderedConfiguration(configuration, "supportsExtension('org.tynamo.descriptor.extension.EnumReferenceDescriptor')", "enum"); // overrides Tapestry's enum
141                    addPairToOrderedConfiguration(configuration, "supportsExtension('org.tynamo.descriptor.extension.BlobDescriptorExtension')", "blob");
142    
143                    addPairToOrderedConfiguration(configuration, "objectReference", "single-valued-association" /* (aka: ManyToOne) */);
144                    addPairToOrderedConfiguration(configuration, "collection && not(childRelationship)", "many-valued-association" /* (aka: ManyToMany) */);
145                    addPairToOrderedConfiguration(configuration, "collection && childRelationship", "composition");
146                    addPairToOrderedConfiguration(configuration, "name == 'id'", "readOnly");
147                    addPairToOrderedConfiguration(configuration, "embedded", "embedded");
148            }
149    
150            private static void addPairToOrderedConfiguration(OrderedConfiguration<Pair> configuration, String key, String value)
151            {
152                    configuration.add(key, new Pair<String, String>(key, value));
153            }
154    
155            public static void contributePropertyDescriptorFactory(Configuration<String> configuration)
156            {
157                    configuration.add("exclude.*");
158                    configuration.add("class");
159            }
160    
161            public static void contributeMethodDescriptorFactory(Configuration<String> configuration)
162            {
163                    configuration.add("shouldExclude");
164                    configuration.add("set.*");
165                    configuration.add("get.*");
166                    configuration.add("is.*");
167                    configuration.add("equals");
168                    configuration.add("wait");
169                    configuration.add("toString");
170                    configuration.add("notify.*");
171                    configuration.add("hashCode");
172            }
173    
174    
175    }