Altered ReferringObjectMetadataFactoryImpl to exclude bidirectional relationships...
[cdmlib.git] / cdmlib-persistence / src / main / java / eu / etaxonomy / cdm / persistence / hibernate / replace / impl / ReferringObjectMetadataFactoryImpl.java
1 package eu.etaxonomy.cdm.persistence.hibernate.replace.impl;
2
3 import java.lang.reflect.Field;
4 import java.lang.reflect.Modifier;
5 import java.util.HashMap;
6 import java.util.HashSet;
7 import java.util.Map;
8 import java.util.Set;
9
10 import javax.persistence.OneToMany;
11
12 import org.hibernate.MappingException;
13 import org.hibernate.SessionFactory;
14 import org.hibernate.engine.SessionFactoryImplementor;
15 import org.hibernate.impl.SessionFactoryImpl;
16 import org.hibernate.metadata.ClassMetadata;
17 import org.hibernate.type.AnyType;
18 import org.hibernate.type.AssociationType;
19 import org.hibernate.type.BagType;
20 import org.hibernate.type.CollectionType;
21 import org.hibernate.type.EntityType;
22 import org.hibernate.type.ListType;
23 import org.hibernate.type.MapType;
24 import org.hibernate.type.SetType;
25 import org.hibernate.type.Type;
26 import org.hibernate.validator.xml.PropertyType;
27 import org.springframework.beans.factory.annotation.Autowired;
28 import org.springframework.stereotype.Component;
29
30 import eu.etaxonomy.cdm.model.common.CdmBase;
31 import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
32 import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
33 import eu.etaxonomy.cdm.persistence.hibernate.replace.ReferringObjectMetadata;
34 import eu.etaxonomy.cdm.persistence.hibernate.replace.ReferringObjectMetadataFactory;
35
36 @Component
37 public class ReferringObjectMetadataFactoryImpl implements ReferringObjectMetadataFactory {
38
39 @Autowired
40 private SessionFactory sessionFactory;
41
42 private Map<Class<? extends CdmBase>, Set<ReferringObjectMetadata>> referringObjectMap = new HashMap<Class<? extends CdmBase>, Set<ReferringObjectMetadata>>();
43
44 public Set<ReferringObjectMetadata> get(Class<? extends CdmBase> toClass) {
45 if(!referringObjectMap.containsKey(toClass)) {
46 ClassMetadata toClassMetadata = sessionFactory.getClassMetadata(toClass);
47 Map<Class,Set<String>> bidirectionalRelationships = new HashMap<Class,Set<String>>();
48 for(String propertyName : toClassMetadata.getPropertyNames()) {
49 Type propertyType = toClassMetadata.getPropertyType(propertyName);
50 if(propertyType.isAssociationType() && !propertyType.isAnyType()) {
51 AssociationType associationType = (AssociationType)propertyType;
52
53 Field field = null;
54 try {
55 field = toClass.getDeclaredField(propertyName);
56 } catch(NoSuchFieldException nsfe) {
57 Class superClass = toClass.getSuperclass();
58 while(!superClass.equals(CdmBase.class)) {
59 try{
60 field = superClass.getDeclaredField(propertyName);
61 break;
62 } catch(NoSuchFieldException nsfe1) { }
63 superClass = superClass.getSuperclass();
64 }
65 if(field == null) {
66 // throw nsfe;
67 }
68 }
69 if(field != null) {
70 field.setAccessible(true);
71 if(field.isAnnotationPresent(OneToMany.class)){
72 OneToMany oneToMany = field.getAnnotation(OneToMany.class);
73 if(oneToMany.mappedBy() != null && oneToMany.mappedBy().length() > 0) {
74 String associatedEntityName = associationType.getAssociatedEntityName((SessionFactoryImpl) sessionFactory.getCurrentSession().getSessionFactory());
75 Class associatedEntity;
76 try {
77 associatedEntity = Class.forName(associatedEntityName);
78 if(!bidirectionalRelationships.containsKey(associatedEntity)) {
79 bidirectionalRelationships.put(associatedEntity, new HashSet<String>());
80 }
81 bidirectionalRelationships.get(associatedEntity).add(oneToMany.mappedBy());
82 } catch (ClassNotFoundException e) {
83 // TODO Auto-generated catch block
84 e.printStackTrace();
85 }
86 // System.out.println(oneToMany.mappedBy() + " " + associatedEntityName);
87 }
88 }
89 }
90 }
91 }
92
93 Map<Object,ClassMetadata> allClassMetadata = sessionFactory.getAllClassMetadata();
94 Set<ReferringObjectMetadata> referringObjectMetadata = new HashSet<ReferringObjectMetadata>();
95
96 for(Object fromClass : allClassMetadata.keySet()) {
97 String entityName = (String) fromClass;
98 if(!entityName.endsWith("_AUD")) {
99 try {
100 // System.out.println(entityName);
101 Class entityClass = Class.forName(entityName);
102 ClassMetadata classMetadata = allClassMetadata.get(entityName);
103
104 for(String propertyName : classMetadata.getPropertyNames()) {
105 if(bidirectionalRelationships.containsKey(entityClass) && bidirectionalRelationships.get(entityClass).contains(propertyName)) {
106 // System.out.println("Excluding " + entityClass.getName() + " " + propertyName);
107 } else {
108 Type propertyType = classMetadata.getPropertyType(propertyName);
109 if (propertyType.isAssociationType()){
110 // System.out.println(entityName+"."+propertyName);
111 AssociationType associationType = (AssociationType)propertyType;
112
113 if(!propertyType.isAnyType()) {
114 try {
115 String associatedEntityName = associationType.getAssociatedEntityName((SessionFactoryImpl) sessionFactory.getCurrentSession().getSessionFactory());
116 Class associatedClass = Class.forName(associatedEntityName);
117 if (associatedClass.isAssignableFrom(toClass)){
118
119 try {
120 if(associationType.isEntityType()) {
121
122 referringObjectMetadata.add(new ToOneReferringObjectMetadata(entityClass,propertyName, toClass));
123 // System.out.println(propertyName + " " + fromClass + " " + toClass);
124 } else if(associationType.isCollectionType()) {
125 CollectionType collectionType = (CollectionType)propertyType;
126
127 if(propertyType instanceof BagType || propertyType instanceof SetType) {
128 referringObjectMetadata.add(new SetReferringObjectMetadata(entityClass,propertyName, toClass));
129 // System.out.println(propertyName + " " + fromClass + " " + toClass);
130 } else if(propertyType instanceof ListType) {
131 referringObjectMetadata.add(new ListReferringObjectMetadata(entityClass,propertyName, toClass));
132 // System.out.println(propertyName + " " + fromClass + " " + toClass);
133 }
134 }
135 } catch(NoSuchFieldException nsfe) { }
136 }
137 } catch(MappingException me) { }
138 }
139 }
140 }
141 }
142
143 } catch (ClassNotFoundException e) {
144
145 }
146
147 }
148 }
149 referringObjectMap.put(toClass, referringObjectMetadata);
150 }
151
152 return referringObjectMap.get(toClass);
153 }
154
155 }