1 package net.sf.stitch.crud;
2
3 import java.lang.reflect.Field;
4 import java.lang.reflect.Method;
5 import java.lang.reflect.Modifier;
6 import java.util.Collection;
7 import java.util.Collections;
8 import java.util.LinkedHashMap;
9 import java.util.Map;
10
11 import javax.persistence.Entity;
12
13
14
15
16
17
18 public class CrudEntity
19 {
20
21 private final String entityClassName;
22
23 private final String entityShortName;
24
25 private final String entityPrefix;
26
27
28 private final String entityHome;
29
30 private final String entityQuery;
31
32
33 private final Map<String,CrudEntityProperty> entityFields;
34
35
36
37
38
39 public CrudEntity (final String entityClassName) throws ClassNotFoundException
40 {
41
42 final Class<?> entityClass = Class.forName(entityClassName);
43 if (!entityClass.isAnnotationPresent(Entity.class))
44 {
45 throw new IllegalArgumentException("CrudEntity may only be instantiated for a class annotated with @Entity");
46 }
47
48
49 this.entityClassName = entityClassName;
50 this.entityShortName = entityClassName.substring(entityClassName.lastIndexOf('.') + 1);
51 this.entityPrefix = Character.toLowerCase(entityShortName.charAt(0)) + entityShortName.substring(1);
52 this.entityFields = buildEntityFields(entityClass);
53
54
55 this.entityHome = this.entityPrefix + "Home";
56 this.entityQuery = this.entityPrefix + "List";
57 }
58
59 protected static boolean isGetter (final Method m)
60 {
61 return isBeanMethod(m, "get");
62 }
63
64 protected static boolean isSetter (final Method m)
65 {
66 return isBeanMethod(m, "set");
67 }
68
69 protected static boolean isBeanMethod (final Method m, final String prefix)
70 {
71 final String methodName = m.getName();
72 return methodName.startsWith(prefix)
73 && methodName.length() > prefix.length()
74 && Character.isUpperCase(methodName.charAt(prefix.length()));
75 }
76
77 protected static String fieldNameFromXetter (final String methodName)
78 {
79 return Character.toLowerCase(methodName.charAt(3)) + methodName.substring(4);
80 }
81
82 private Map<String,CrudEntityProperty> buildEntityFields (final Class<?> entityClass)
83 {
84 final Map<String,CrudEntityProperty> fieldMap = new LinkedHashMap<String,CrudEntityProperty>();
85
86
87 for (final Field f : entityClass.getDeclaredFields())
88 {
89 final int fieldModifiers = f.getModifiers();
90 if (!Modifier.isTransient(fieldModifiers))
91 {
92 final String name = f.getName();
93 fieldMap.put(name, new CrudEntityProperty(f));
94 }
95 }
96
97 for (final Method m : entityClass.getDeclaredMethods())
98 {
99 final int methodModifiers = m.getModifiers();
100 if (!Modifier.isStatic(methodModifiers))
101 {
102 if (isGetter(m))
103 {
104 final String fieldName = fieldNameFromXetter(m.getName());
105 final CrudEntityProperty prop = fieldMap.get(fieldName);
106 if (null != prop)
107 {
108 prop.setGetter(m);
109 }
110 }
111 else if (isSetter(m))
112 {
113 final String fieldName = fieldNameFromXetter(m.getName());
114 final CrudEntityProperty prop = fieldMap.get(fieldName);
115 if (null != prop)
116 {
117 prop.setSetter(m);
118 }
119 }
120 }
121 }
122
123 return fieldMap;
124 }
125
126
127
128
129 public String getEntityClassName ()
130 {
131 return this.entityClassName;
132 }
133
134
135
136
137 public String getEntityShortName ()
138 {
139 return this.entityShortName;
140 }
141
142
143
144
145 public String getEntityPrefix ()
146 {
147 return this.entityPrefix;
148 }
149
150
151
152
153 public String getEntityHome ()
154 {
155 return this.entityHome;
156 }
157
158
159
160
161 public String getEntityQuery ()
162 {
163 return this.entityQuery;
164 }
165
166
167
168
169 public Collection<CrudEntityProperty> getEntityFields ()
170 {
171 return Collections.unmodifiableCollection(this.entityFields.values());
172 }
173
174
175
176
177
178 public String getMessageKey ()
179 {
180 return entityClassName;
181 }
182 }