001 package org.tynamo.hibernate.services;
002
003 import org.apache.tapestry5.hibernate.HibernateConfigurer;
004 import org.apache.tapestry5.hibernate.HibernateSessionSource;
005 import org.apache.tapestry5.hibernate.HibernateTransactionDecorator;
006 import org.apache.tapestry5.ioc.Configuration;
007 import org.apache.tapestry5.ioc.MappedConfiguration;
008 import org.apache.tapestry5.ioc.OrderedConfiguration;
009 import org.apache.tapestry5.ioc.ServiceBinder;
010 import org.apache.tapestry5.ioc.annotations.InjectService;
011 import org.apache.tapestry5.ioc.annotations.Match;
012 import org.apache.tapestry5.ioc.annotations.Symbol;
013 import org.apache.tapestry5.services.BeanBlockContribution;
014 import org.apache.tapestry5.services.LibraryMapping;
015 import org.hibernate.mapping.PersistentClass;
016 import org.tynamo.VersionedModule;
017 import org.tynamo.descriptor.DescriptorDecorator;
018 import org.tynamo.descriptor.DescriptorFactory;
019 import org.tynamo.descriptor.annotation.AnnotationDecorator;
020 import org.tynamo.hibernate.TynamoHibernateSymbols;
021 import org.tynamo.hibernate.TynamoInterceptor;
022 import org.tynamo.hibernate.TynamoInterceptorConfigurer;
023 import org.tynamo.hibernate.validation.HibernateClassValidatorFactory;
024 import org.tynamo.hibernate.validation.HibernateValidationDelegate;
025 import org.tynamo.util.Pair;
026
027 import java.util.Iterator;
028
029 public class TynamoHibernateModule extends VersionedModule
030 {
031
032 public static void bind(ServiceBinder binder)
033 {
034 // Make bind() calls on the binder object to define most IoC services.
035 // Use service builder methods (example below) when the implementation
036 // is provided inline, or requires more initialization than simply
037 // invoking the constructor.
038
039 binder.bind(HibernatePersistenceService.class, HibernatePersistenceServiceImpl.class);
040 binder.bind(HibernateClassValidatorFactory.class, HibernateClassValidatorFactory.class);
041 binder.bind(HibernateValidationDelegate.class, HibernateValidationDelegate.class);
042 binder.bind(TynamoInterceptor.class);
043 binder.bind(HibernateConfigurer.class, TynamoInterceptorConfigurer.class).withId("TynamoInterceptorConfigurer");
044
045 }
046
047 /**
048 * Add our components and pages to the "trails" library.
049 */
050 public static void contributeComponentClassResolver(Configuration<LibraryMapping> configuration)
051 {
052 configuration.add(new LibraryMapping("tynamo-hibernate", "org.tynamo.hibernate"));
053 }
054
055 public static void contributeClasspathAssetAliasManager(MappedConfiguration<String, String> configuration)
056 {
057 configuration.add("tynamo-hibernate/" + version, "org/tynamo/hibernate");
058 }
059
060 public static void contributeValidationMessagesSource(OrderedConfiguration<String> configuration)
061 {
062 configuration.add("Tynamo", "ValidationMessages");
063 }
064
065 @Match("HibernatePersistenceService")
066 public static <T> T decorateTransactionally(HibernateTransactionDecorator decorator, Class<T> serviceInterface,
067 T delegate,
068 String serviceId)
069 {
070 return decorator.build(serviceInterface, delegate, serviceId);
071 }
072
073 /**
074 * Contributions to the DefaultDataTypeAnalyzer.
075 * <p/>
076 * DataTypeAnalyzer is a chain of command that can make match properties to data types based on property type or
077 * annotations on the property. In general, DefaultDataTypeAnalyzer is used, as that only needs to consider property
078 * type. DefaultDataTypeAnalyzer matches property types to data types, based on a search up the inheritance path.
079 */
080 public static void contributeDefaultDataTypeAnalyzer(MappedConfiguration<Class, String> configuration)
081 {
082
083 }
084
085 /**
086 * Contribution to the BeanBlockSource service to tell the BeanEditForm component about the editors. When the
087 * BeanEditForm sees a property of type BigDecimal, it will map that to datatype "currency" and from there to the
088 * currency block of the AppPropertyEditBlocks page of the application.
089 */
090 public static void contributeBeanBlockSource(Configuration<BeanBlockContribution> configuration)
091 {
092
093 }
094
095 public static void contributeDescriptorFactory(OrderedConfiguration<DescriptorDecorator> configuration,
096 HibernateDescriptorDecorator hibernateDescriptorDecorator)
097 {
098 configuration.add("Hibernate", hibernateDescriptorDecorator);
099 configuration.add("Annotation", new AnnotationDecorator());
100 }
101
102 @SuppressWarnings("unchecked")
103 public static void contributeDescriptorService(Configuration<Class> configuration,
104 HibernateSessionSource hibernateSessionSource)
105 {
106
107 org.hibernate.cfg.Configuration config = hibernateSessionSource.getConfiguration();
108 Iterator<PersistentClass> mappings = config.getClassMappings();
109 while (mappings.hasNext())
110 {
111 final PersistentClass persistentClass = mappings.next();
112 final Class entityClass = persistentClass.getMappedClass();
113
114 if (entityClass != null)
115 {
116 configuration.add(entityClass);
117 }
118 }
119 }
120
121 public static void contributeTynamoDataTypeAnalyzer(OrderedConfiguration<Pair> configuration)
122 {
123
124 addPairToOrderedConfiguration(configuration, "hidden", "hidden");
125 addPairToOrderedConfiguration(configuration, "readOnly", "readOnly");
126 addPairToOrderedConfiguration(configuration, "richText", "fckEditor");
127 // addPairToOrderedConfiguration(configuration, "name.toLowerCase().endsWith('password')", "passwordEditor"); //USE @DataType("password")
128 // addPairToOrderedConfiguration(configuration, "string and !large and !identifier", "stringEditor"); //managed by Tapestry
129 addPairToOrderedConfiguration(configuration, "string and large and !identifier", "longtext");
130 addPairToOrderedConfiguration(configuration, "date", "dateEditor");
131 // addPairToOrderedConfiguration(configuration, "numeric and !identifier", "numberEditor"); //managed by Tapestry
132 addPairToOrderedConfiguration(configuration, "identifier && generated", "readOnly");
133 addPairToOrderedConfiguration(configuration, "identifier && not(generated) && string", "identifierEditor");
134 // addPairToOrderedConfiguration(configuration, "identifier && objectReference", "objectReferenceIdentifierEditor");
135 // addPairToOrderedConfiguration(configuration, "boolean", "booleanEditor"); //managed by Tapestry
136 // addPairToOrderedConfiguration(configuration, "supportsExtension('org.tynamo.descriptor.extension.EnumReferenceDescriptor')", "enumEditor"); //managed by Tapestry
137 addPairToOrderedConfiguration(configuration, "supportsExtension('org.tynamo.descriptor.extension.BlobDescriptorExtension')", "blob");
138
139 addPairToOrderedConfiguration(configuration, "objectReference", "single-valued-association" /* (aka: ManyToOne) */);
140 addPairToOrderedConfiguration(configuration, "collection && not(childRelationship)", "many-valued-association" /* (aka: ManyToMany) */);
141 addPairToOrderedConfiguration(configuration, "collection && childRelationship", "composition");
142 addPairToOrderedConfiguration(configuration, "name == 'id'", "readOnly");
143 addPairToOrderedConfiguration(configuration, "embedded", "embedded");
144 }
145
146 private static void addPairToOrderedConfiguration(OrderedConfiguration<Pair> configuration, String key, String value)
147 {
148 configuration.add(key, new Pair<String, String>(key, value));
149 }
150
151
152 public static void contributePropertyDescriptorFactory(Configuration<String> configuration)
153 {
154 configuration.add("exclude.*");
155 configuration.add("class");
156 }
157
158 public static void contributeMethodDescriptorFactory(Configuration<String> configuration)
159 {
160 configuration.add("shouldExclude");
161 configuration.add("set.*");
162 configuration.add("get.*");
163 configuration.add("is.*");
164 configuration.add("equals");
165 configuration.add("wait");
166 configuration.add("toString");
167 configuration.add("notify.*");
168 configuration.add("hashCode");
169 }
170
171 public static HibernateDescriptorDecorator buildHibernateDescriptorDecorator(
172 HibernateSessionSource hibernateSessionSource,
173 DescriptorFactory descriptorFactory,
174 @Symbol(TynamoHibernateSymbols.LARGE_COLUMN_LENGTH)
175 final int largeColumnLength,
176 @Symbol(TynamoHibernateSymbols.IGNORE_NON_HIBERNATE_TYPES)
177 final boolean ignoreNonHibernateTypes)
178 {
179 return new HibernateDescriptorDecorator(hibernateSessionSource, descriptorFactory, largeColumnLength, ignoreNonHibernateTypes);
180 }
181
182 public static void contributeFactoryDefaults(MappedConfiguration<String, String> configuration)
183 {
184 configuration.add(TynamoHibernateSymbols.LARGE_COLUMN_LENGTH, "100");
185 configuration.add(TynamoHibernateSymbols.IGNORE_NON_HIBERNATE_TYPES, "false");
186 }
187
188
189 /**
190 * Adds the following configurers:
191 * <dl>
192 * <dt>TynamoInterceptorConfigurer
193 * <dd>add the TynamoInterceptor to the hibernate configuration
194 */
195 public static void contributeHibernateSessionSource(OrderedConfiguration<HibernateConfigurer> config,
196 @InjectService("TynamoInterceptorConfigurer")
197 HibernateConfigurer trailsInterceptorConfigurer)
198 {
199 config.add("TynamoInterceptorConfigurer", trailsInterceptorConfigurer);
200 }
201
202
203 /**
204 * We don't need this just yet, and it gives an error under Tapestry 5.1.0.2
205 *
206 * [INFO] [talledLocalContainer] java.lang.IllegalArgumentException:
207 * Contribution org.tynamo.hibernate.services.TynamoHibernateModule.contributeTynamoEntityPackageManager(Configuration, HibernateEntityPackageManager)
208 * (at TynamoHibernateModule.java:145) is for service 'TynamoEntityPackageManager', which does not exist.
209 *
210 public static void contributeTynamoEntityPackageManager(Configuration<String> configuration, HibernateEntityPackageManager packageManager)
211 {
212 for (String packageName : packageManager.getPackageNames())
213 {
214 configuration.add(packageName);
215 }
216 }
217 */
218
219
220 /*
221 public static void contributeFieldValidatorSource(MappedConfiguration<String, Validator> configuration) {
222 configuration.add("int", new ValidateInt());
223 }
224 */
225
226 }