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 }