1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package ch.elca.el4j.util.objectwrapper.impl;
18
19 import java.lang.annotation.Annotation;
20 import java.lang.reflect.InvocationTargetException;
21 import java.lang.reflect.Method;
22 import java.util.Collection;
23 import java.util.LinkedList;
24 import java.util.List;
25 import java.util.Locale;
26
27 import javax.persistence.ManyToMany;
28 import javax.persistence.OneToMany;
29 import javax.persistence.OneToOne;
30
31 import org.hibernate.EntityMode;
32 import org.hibernate.SessionFactory;
33 import org.hibernate.metadata.ClassMetadata;
34 import org.hibernate.type.Type;
35
36 import ch.elca.el4j.util.objectwrapper.ObjectWrapperRTException;
37 import ch.elca.el4j.util.objectwrapper.interfaces.Linked;
38
39
40
41
42
43
44
45
46 public class LinkedHibernateImpl extends AbstractWrapper implements Linked {
47
48
49
50
51 private static List<Class<?extends Annotation>> s_candidates
52 = new LinkedList<Class<?extends Annotation>>();
53
54
55
56
57 static {
58 s_candidates.add(OneToMany.class);
59 s_candidates.add(OneToOne.class);
60 s_candidates.add(ManyToMany.class);
61 }
62
63
64 private final SessionFactory m_sessionFactory;
65
66
67 private ClassMetadata m_meta;
68
69
70 private List<String> m_simple;
71
72
73 private List<String> m_collections;
74
75
76
77
78
79 public LinkedHibernateImpl(SessionFactory sessionFactory) {
80 m_sessionFactory = sessionFactory;
81 }
82
83
84 @Override
85 public void create() {
86 m_meta = m_sessionFactory.getClassMetadata(m_target.getClass());
87 if (m_meta == null) {
88 throw new ObjectWrapperRTException("Failed to create hibernate metadata.");
89 }
90 m_simple = new LinkedList<String>();
91 m_collections = new LinkedList<String>();
92
93 for (String property : m_meta.getPropertyNames()) {
94 if (isInverse(m_target.getClass(), property)) {
95 continue;
96 }
97
98 Type type = m_meta.getPropertyType(property);
99 if (type.isCollectionType()) {
100 m_collections.add(property);
101 } else if (type.isAssociationType()) {
102 m_simple.add(property);
103 }
104 }
105 }
106
107
108
109
110
111
112
113
114 private boolean isInverse(Class<?> cls, String property) {
115
116 String methodName = "get" + property.substring(0, 1)
117 .toUpperCase(Locale.getDefault()) + property.substring(1);
118 Method method;
119 try {
120 method = cls.getMethod(methodName);
121 } catch (NoSuchMethodException e) {
122 try {
123 methodName = "is" + methodName.substring("get".length());
124 method = cls.getMethod(methodName);
125 } catch (NoSuchMethodException ex) {
126 throw new ObjectWrapperRTException("No getter for " + property
127 + " in " + cls, ex);
128 }
129 }
130
131
132 boolean inverse = false;
133
134 OUTER:
135 for (Annotation a : method.getAnnotations()) {
136 for (Class<? extends Annotation> candidate : s_candidates) {
137 if (candidate.isAssignableFrom(a.getClass())
138 && isInverseAnnotation(a)) {
139 inverse = true;
140 break OUTER;
141 }
142 }
143 }
144
145 return inverse;
146 }
147
148
149
150
151
152
153
154 private boolean isInverseAnnotation(Annotation ann) {
155 String str;
156 try {
157 Method mappedBy = ann.getClass().getMethod("mappedBy");
158 str = (String) mappedBy.invoke(ann);
159 } catch (NoSuchMethodException e) {
160 throw new ObjectWrapperRTException("Missing mappedBy in " + ann, e);
161 } catch (IllegalAccessException e) {
162 throw new ObjectWrapperRTException(e);
163 } catch (InvocationTargetException e) {
164 throw new ObjectWrapperRTException(e);
165 }
166 return !"".equals(str);
167 }
168
169
170 public Object[] getAllLinked() {
171 List<Object> objects = new LinkedList<Object>();
172 for (String simple : m_simple) {
173 Object obj = getlinkByName(simple);
174 if (obj != null) {
175 objects.add(obj);
176 }
177 }
178 for (String collectionName : m_collections) {
179 Collection<?> collection = getCollectionLinkByName(collectionName);
180 for (Object obj : collection) {
181 if (obj != null) {
182 objects.add(obj);
183 }
184 }
185 }
186 return objects.toArray();
187 }
188
189
190 public Collection<?> getCollectionLinkByName(String name) {
191 return (Collection<?>) m_meta.getPropertyValue(m_target, name, EntityMode.POJO);
192 }
193
194
195 public String[] getCollectionLinkNames() {
196 return m_collections.toArray(new String[m_collections.size()]);
197 }
198
199
200 public String[] getLinkNames() {
201 return m_simple.toArray(new String[m_simple.size()]);
202 }
203
204
205 public Object getlinkByName(String linkName) {
206 return m_meta.getPropertyValue(m_target, linkName, EntityMode.POJO);
207 }
208 }