001: package org.conform.hibernate;
002:
003: import org.conform.*;
004: import org.hibernate.HibernateException;
005: import org.hibernate.SessionFactory;
006: import org.hibernate.engine.SessionFactoryImplementor;
007: import org.hibernate.metadata.ClassMetadata;
008: import org.hibernate.metadata.CollectionMetadata;
009: import org.hibernate.type.*;
010: import org.apache.commons.logging.LogFactory;
011:
012: import java.util.*;
013:
014: public class HibernateModifier implements Modifier {
015: private static org.apache.commons.logging.Log LOG = LogFactory
016: .getLog(Meta.class);
017:
018: SessionFactory sessionFactory;
019: BeanMetaProvider beanMetaProvider;
020: private Map allClassMetadata;
021:
022: public HibernateModifier() {
023: }
024:
025: public HibernateModifier(SessionFactory sessionFactory,
026: BeanMetaProvider beanMetaProvider) {
027: this .sessionFactory = sessionFactory;
028: this .beanMetaProvider = beanMetaProvider;
029: }
030:
031: public SessionFactory getSessionFactory() {
032: return sessionFactory;
033: }
034:
035: public void setSessionFactory(SessionFactory sessionFactory) {
036: this .sessionFactory = sessionFactory;
037: }
038:
039: public BeanMetaProvider getBeanMetaProvider() {
040: return beanMetaProvider;
041: }
042:
043: public void setBeanMetaProvider(BeanMetaProvider beanMetaProvider) {
044: this .beanMetaProvider = beanMetaProvider;
045: }
046:
047: public void modify(BeanMeta beanMeta) {
048: firstRun(beanMeta);
049: secondRun(beanMeta);
050: thirdRun(beanMeta);
051: }
052:
053: private void firstRun(BeanMeta beanMeta) {
054: try {
055: ClassMetadata metadata = sessionFactory
056: .getClassMetadata(beanMeta.getType());
057: if (metadata == null)
058: return;
059:
060: LOG.debug("metadata = " + metadata + " property = "
061: + beanMeta);
062:
063: String identifierPropertyName = metadata
064: .getIdentifierPropertyName();
065: beanMeta.getProperty(identifierPropertyName).setAttribute(
066: PropertyMeta.ATTRIBUTE_IDENTIFIER, Boolean.TRUE);
067:
068: String[] propertyNames = metadata.getPropertyNames();
069: Type[] propertyTypes = metadata.getPropertyTypes();
070: boolean[] propertyNullabilities = metadata
071: .getPropertyNullability();
072: for (int i = 0; i < propertyTypes.length; i++) {
073: String name = propertyNames[i];
074: Type type = propertyTypes[i];
075: boolean nullability = propertyNullabilities[i];
076:
077: PropertyMeta propertyMeta = beanMeta.getProperty(name);
078: if (propertyMeta == null)
079: continue;
080:
081: propertyMeta.setMandatory(!nullability);
082:
083: if (type.isCollectionType()) {
084: CollectionType collectionType = (CollectionType) type;
085: String role = collectionType.getRole();
086: CollectionMetadata meta = sessionFactory
087: .getCollectionMetadata(role);
088: LOG.trace("collection type = "
089: + meta.getElementType().getReturnedClass());
090:
091: BeanMeta relationBean = beanMetaProvider
092: .getBeanMeta(meta.getElementType()
093: .getReturnedClass());
094: propertyMeta
095: .setRelationType(PropertyMeta.ONE_TO_MANY_RELATION);
096: propertyMeta.setRelationBean(relationBean);
097:
098: LOG.trace("MAYBE one to many : " + beanMeta
099: + " to " + relationBean);
100: } else if (type.isEntityType()) {
101: EntityType entityType = (EntityType) type;
102: LOG.trace("entity type = "
103: + entityType.getReturnedClass());
104:
105: BeanMeta relationBean = beanMetaProvider
106: .getBeanMeta(entityType.getReturnedClass());
107: propertyMeta.setRelationBean(relationBean);
108: if (entityType.isOneToOne()) {
109: propertyMeta
110: .setRelationType(PropertyMeta.ONE_TO_ONE_RELATION);
111: LOG.trace("DEFINATELY one to one : " + beanMeta
112: + " to " + relationBean);
113: } else {
114: propertyMeta
115: .setRelationType(PropertyMeta.MANY_TO_ONE_RELATION);
116: LOG.trace("DEFINATELY many to one : "
117: + beanMeta + " to " + relationBean);
118: }
119: } else if (type.isComponentType()) {
120: ComponentType componentType = (ComponentType) type;
121: LOG.trace("component type = "
122: + componentType.getReturnedClass());
123:
124: if (Map.class.isAssignableFrom(componentType
125: .getReturnedClass())) {
126: System.out.println("dynamic component: "
127: + Arrays.asList(componentType
128: .getPropertyNames()));
129: } else {
130: BeanMeta relationBean = beanMetaProvider
131: .getBeanMeta(componentType
132: .getReturnedClass());
133: if (relationBean != null) {
134: propertyMeta
135: .setRelationType(PropertyMeta.ONE_TO_ONE_RELATION);
136: propertyMeta.setRelationBean(relationBean);
137: relationBean.setAttribute("value",
138: Boolean.TRUE);
139:
140: LOG.trace("DEFINATELY one to one : "
141: + beanMeta + " to " + relationBean);
142: }
143: }
144: } else if (type.isAssociationType()) {
145: AssociationType associationType = (AssociationType) type;
146: //associationType.getAssociatedEntityName();
147: }
148:
149: // TODO: consider the following
150: /*
151: if (!(type instanceof PrimitiveType))
152: propertyMeta.setMandatory(true);
153: */
154:
155: if (type instanceof StringType) {
156: StringType stringType = (StringType) type;
157: //propertyMeta.setAttribute(StringEditor.ATTRIBUTE_LENGTH, stringType.)
158: }
159: if (type instanceof CustomType) {
160: CustomType customType = (CustomType) type;
161: propertyMeta.setAttribute("hibernate.user.type",
162: customType.getReturnedClass());
163: }
164: }
165: } catch (HibernateException e) {
166: e.printStackTrace();
167: }
168: }
169:
170: private void secondRun(BeanMeta beanMeta) {
171: for (int i = 0; i < beanMeta.getProperties().length; i++) {
172: PropertyMeta property = beanMeta.getProperties()[i];
173:
174: if (property.getRelationType() == PropertyMeta.ONE_TO_ONE_RELATION)
175: mapXXXToOne(beanMeta, property);
176: else if (property.getRelationType() == PropertyMeta.ONE_TO_MANY_RELATION)
177: mapXXXToMany(beanMeta, property);
178: }
179: }
180:
181: private void mapXXXToMany(BeanMeta bean, PropertyMeta property) {
182: BeanMeta relationBean = property.getRelationBean();
183:
184: for (int i = 0; i < relationBean.getProperties().length; i++) {
185: PropertyMeta relationProperty = relationBean
186: .getProperties()[i];
187: if (relationProperty.getRelationBean() == bean) {
188: if (relationProperty.getRelationType() == PropertyMeta.ONE_TO_MANY_RELATION) {
189: mapManyToMany(property, relationProperty);
190: LOG.trace("DEFINATELY many to many : " + bean
191: + " to " + relationBean);
192: break;
193: } else if (relationProperty.getRelationType() == PropertyMeta.ONE_TO_ONE_RELATION) {
194: mapOneToMany(property, relationProperty);
195: LOG.trace("DEFINATELY one to many : " + bean
196: + " to " + relationBean);
197: break;
198: }
199: }
200: }
201: }
202:
203: private void mapManyToMany(PropertyMeta property,
204: PropertyMeta relationProperty) {
205: property.setRelationType(PropertyMeta.MANY_TO_MANY_RELATION);
206: property.setRelationProperty(relationProperty);
207: relationProperty
208: .setRelationType(PropertyMeta.MANY_TO_MANY_RELATION);
209: relationProperty.setRelationProperty(property);
210: }
211:
212: private void mapOneToMany(PropertyMeta property,
213: PropertyMeta relationProperty) {
214: property.setRelationType(PropertyMeta.ONE_TO_MANY_RELATION);
215: property.setRelationProperty(relationProperty);
216: relationProperty
217: .setRelationType(PropertyMeta.MANY_TO_ONE_RELATION);
218: relationProperty.setRelationProperty(property);
219: }
220:
221: private void mapXXXToOne(BeanMeta bean, PropertyMeta property) {
222: BeanMeta relationBean = property.getRelationBean();
223:
224: for (int i = 0; i < relationBean.getProperties().length; i++) {
225: PropertyMeta relationProperty = relationBean
226: .getProperties()[i];
227: if (relationProperty.getRelationBean() == bean) {
228: if (relationProperty.getRelationType() == PropertyMeta.ONE_TO_MANY_RELATION) {
229: mapManyToOne(property, relationProperty);
230: LOG.trace("DEFINATELY many to one : " + bean
231: + " to " + relationBean);
232: break;
233: } else if (relationProperty.getRelationType() == PropertyMeta.ONE_TO_ONE_RELATION) {
234: mapOneToOne(property, relationProperty);
235: LOG.trace("DEFINATELY one to one : " + bean
236: + " to " + relationBean);
237: break;
238: }
239: }
240: }
241: }
242:
243: private void mapManyToOne(PropertyMeta property,
244: PropertyMeta relationProperty) {
245: property.setRelationType(PropertyMeta.MANY_TO_ONE_RELATION);
246: property.setRelationProperty(relationProperty);
247: relationProperty
248: .setRelationType(PropertyMeta.ONE_TO_MANY_RELATION);
249: relationProperty.setRelationProperty(property);
250: }
251:
252: private void mapOneToOne(PropertyMeta property,
253: PropertyMeta relationProperty) {
254: property.setRelationType(PropertyMeta.ONE_TO_ONE_RELATION);
255: property.setRelationProperty(relationProperty);
256: relationProperty
257: .setRelationType(PropertyMeta.ONE_TO_ONE_RELATION);
258: relationProperty.setRelationProperty(property);
259: }
260:
261: // TODO: optimization: build a map: who ref's whom
262: private void thirdRun(BeanMeta beanMeta) {
263: String entityName = beanMeta.getClass().getName();
264:
265: Set<String> references = new HashSet<String>();
266:
267: for (Iterator<ClassMetadata> iterator = getAllClassMetadata()
268: .values().iterator(); iterator.hasNext();) {
269: ClassMetadata metadata = iterator.next();
270: for (Type type : metadata.getPropertyTypes()) {
271: if (!type.isEntityType())
272: continue;
273:
274: if (type instanceof ManyToOneType) {
275: ManyToOneType manyToOneType = (ManyToOneType) type;
276: if (manyToOneType.getAssociatedEntityName().equals(
277: entityName))
278: references.add(metadata.getEntityName());
279: } else if (type instanceof OneToOneType) {
280: OneToOneType oneToOneType = (OneToOneType) type;
281: if (oneToOneType.getAssociatedEntityName().equals(
282: entityName))
283: references.add(metadata.getEntityName());
284: } else if (type instanceof CollectionType) {
285: CollectionType collectionType = (CollectionType) type;
286: if (collectionType.getAssociatedEntityName(
287: (SessionFactoryImplementor) sessionFactory)
288: .equals(entityName))
289: references.add(metadata.getEntityName());
290: }
291: }
292: }
293:
294: if (references.size() > 0)
295: beanMeta.setAttribute("references", references);
296: }
297:
298: private Map getAllClassMetadata() {
299: if (allClassMetadata == null)
300: allClassMetadata = sessionFactory.getAllClassMetadata();
301: return allClassMetadata;
302: }
303: }
|