1 2 12 package com.versant.core.metadata; 13 14 import com.versant.core.metadata.parser.*; 15 import com.versant.core.util.classhelper.ClassHelper; 16 import com.versant.core.common.BindingSupportImpl; 17 18 import javax.persistence.*; 19 import java.lang.reflect.*; 20 import java.lang.annotation.Annotation ; 21 import java.util.Map ; 22 import java.util.HashMap ; 23 import java.io.Serializable ; 24 25 30 public class EJBAnnotationProcessor implements JdoExtensionKeys, MetaDataPreProcessor { 31 private ClassLoader loader; 32 private MetaDataUtils mdutils; 33 private final Class [] EMPTY_CLASS_ARRAY; 34 35 public EJBAnnotationProcessor(ClassLoader loader, MetaDataUtils mdutils) { 36 this.loader = loader; 37 this.mdutils = mdutils; 38 EMPTY_CLASS_ARRAY = new Class [] {}; 39 } 40 41 public void process(JdoClass jdoClass) { 42 Class cls; 43 try { 44 cls = loadClass(jdoClass.getQName()); 45 } catch (ClassNotFoundException e) { 46 throw new RuntimeException (e); 47 } 48 49 if (!cls.isAnnotationPresent(javax.persistence.Entity.class)) return; 50 javax.persistence.Entity ea = (Entity) cls.getAnnotation(javax.persistence.Entity.class); 51 52 jdoClass.identityType = MDStatics.IDENTITY_TYPE_APPLICATION; 54 jdoClass.objectIdClasssRequired = false; 55 56 if (cls.isAnnotationPresent(javax.persistence.Table.class)) { 58 javax.persistence.Table ta = (Table) cls.getAnnotation(javax.persistence.Table.class); 59 JdoExtension ext = JdoExtension.find(JDBC_TABLE_NAME, jdoClass.elements); 60 if (ext == null) { 61 ext = new JdoExtension(); 62 ext.key = JDBC_TABLE_NAME; 63 ext.value = ta.name(); 64 jdoClass.addElement(ext); 65 } 66 } 67 68 doPCSuperClass(jdoClass, cls); 70 71 Map jdoFieldMap = createFieldMap(jdoClass); 73 74 final AccessibleMember accessibleMember = new AccessibleMember(); 75 if (ea.access() == AccessType.FIELD) { 76 Field[] fields = cls.getDeclaredFields(); 77 for (int i = 0; i < fields.length; i++) { 78 accessibleMember.init(fields[i], null); 79 bla(jdoFieldMap, jdoClass, accessibleMember); 80 } 81 } else { 82 Field[] fields = cls.getDeclaredFields(); 83 for (int i = 0; i < fields.length; i++) { 84 String s = fields[i].getName(); 85 char[] ca = s.toCharArray(); 86 ca[0] = Character.toUpperCase(ca[0]); 87 Method m = null; 88 try { 89 m = cls.getDeclaredMethod("get" + String.valueOf(ca), EMPTY_CLASS_ARRAY); 90 } catch (NoSuchMethodException e) { 91 try { 93 m = cls.getDeclaredMethod("is" + String.valueOf(ca), EMPTY_CLASS_ARRAY); 94 } catch (NoSuchMethodException e1) { 96 } 97 } 98 if (m == null) { 100 continue; 102 } 103 accessibleMember.init(fields[i], m); 104 bla(jdoFieldMap, jdoClass, accessibleMember); 105 } 106 } 107 } 108 109 private void bla(Map jdoFieldMap, JdoClass jdoClass, AccessibleMember property) { 110 if (property.isSynthetic()) return; 112 if (Modifier.isStatic(property.getModifiers())) return; 113 if (mdutils.isEnhancerAddedField(property.getName())) return; 114 116 JdoField jdoField = getJdoField(jdoFieldMap, property, jdoClass); 117 118 if (jdoField.persistenceModifier == 0 119 && property.isAnnotationPresent(Transient.class)) { 120 jdoField.persistenceModifier = MDStatics.PERSISTENCE_MODIFIER_NONE; 121 return; 122 } 123 124 processId(property, jdoField, jdoClass); 125 126 if (property.isAnnotationPresent(javax.persistence.Column.class)) { 127 javax.persistence.Column ca = property.getAnnotation(javax.persistence.Column.class); 128 if (isValid(ca.name())) { 129 jdoField.findCreate(JDBC_COLUMN, null, false). 130 findCreate(JDBC_COLUMN_NAME, ca.name(), false); 131 } 132 if (ca.scale() != 0) { 133 jdoField.findCreate(JDBC_COLUMN, null, false). 134 findCreate(JDBC_SCALE, "" + ca.scale(), false); 135 } 136 if (ca.length() != 255) { 137 jdoField.findCreate(JDBC_COLUMN, null, false). 138 findCreate(JDBC_LENGTH, "" + ca.length(), false); 139 } 140 141 if (ca.primaryKey()) jdoField.primaryKey = true; 142 } 143 144 if (property.isAnnotationPresent(Basic.class)) { 145 Basic basic = property.getAnnotation(Basic.class); 146 jdoField.defaultFetchGroup = (basic.fetch() == FetchType.EAGER) ? MDStatics.TRUE : MDStatics.FALSE; 147 } else if (property.isAnnotationPresent(OneToOne.class)) { 148 OneToOne oto = property.getAnnotation(OneToOne.class); 149 if (oto.cascade() != null) { 150 setCascadeType(oto.cascade(), jdoField); 151 } 152 if (!oto.optional()) jdoField.nullValue = MDStatics.NULL_VALUE_EXCEPTION; 153 jdoField.defaultFetchGroup = (oto.fetch() == FetchType.EAGER) ? MDStatics.TRUE : MDStatics.FALSE; 154 } else if (property.isAnnotationPresent(OneToMany.class)) { 155 OneToMany oto = property.getAnnotation(OneToMany.class); 156 if (oto.cascade() != null) { 157 setCascadeType(oto.cascade(), jdoField); 158 } 159 jdoField.defaultFetchGroup = (oto.fetch() == FetchType.EAGER) ? MDStatics.TRUE : MDStatics.FALSE; 160 161 JdoCollection col = jdoField.collection; 162 if (col == null) { 163 col = jdoField.collection = new JdoCollection(); 164 jdoField.collection.parent = jdoField; 165 } 166 167 if (!isValid(col.elementType) && isValid(oto.targetEntity())) { 168 col.elementType = oto.targetEntity(); 169 } 170 171 if (isValid(oto.mappedBy())) { 173 col.findCreate(INVERSE, oto.mappedBy(), false); 174 } 175 } else if (property.isAnnotationPresent(ManyToMany.class)) { 176 ManyToMany oto = property.getAnnotation(ManyToMany.class); 177 if (oto.cascade() != null) { 178 setCascadeType(oto.cascade(), jdoField); 179 } 180 jdoField.defaultFetchGroup = (oto.fetch() == FetchType.EAGER) ? MDStatics.TRUE : MDStatics.FALSE; 181 182 } else if (property.isAnnotationPresent(ManyToOne.class)) { 183 ManyToOne oto = property.getAnnotation(ManyToOne.class); 184 if (oto.cascade() != null) { 185 setCascadeType(oto.cascade(), jdoField); 186 } 187 jdoField.defaultFetchGroup = (oto.fetch() == FetchType.EAGER) ? MDStatics.TRUE : MDStatics.FALSE; 188 189 } else if (property.isAnnotationPresent(Serialized.class)) { 190 Serialized oto = property.getAnnotation(Serialized.class); 191 jdoField.defaultFetchGroup = (oto.fetch() == FetchType.EAGER) ? MDStatics.TRUE : MDStatics.FALSE; 192 jdoField.findCreate(EXTERNALIZER, "SERIALIZED", false); 193 } else if (property.isAnnotationPresent(Embedded.class)) { 194 jdoField.embedded = MDStatics.TRUE; 195 jdoField.defaultFetchGroup = MDStatics.FALSE; 196 } else if (property.isAnnotationPresent(Lob.class)) { 197 Lob lob = property.getAnnotation(Lob.class); 198 jdoField.defaultFetchGroup = (lob.fetch() == FetchType.EAGER) ? MDStatics.TRUE : MDStatics.FALSE; 199 } else if (property.isAnnotationPresent(Version.class)) { 200 jdoField.findCreate(JDBC_OPTIMISTIC_LOCKING, "version", false); 201 } else { 202 if (!mdutils.isPersistentModifiers(property.getModifiers())) { 203 jdoField.persistenceModifier = MDStatics.PERSISTENCE_MODIFIER_NONE; 204 } else if (mdutils.isBasicType(property.getType())) { 205 jdoField.defaultFetchGroup = MDStatics.TRUE; 206 } else if (property.getType().isAnnotationPresent(javax.persistence.Embeddable.class)) { 207 jdoField.embedded = MDStatics.TRUE; 208 jdoField.defaultFetchGroup = MDStatics.TRUE; 209 } else if (Serializable .class.isAssignableFrom(property.getType())) { 210 jdoField.findCreate(EXTERNALIZER, "SERIALIZED", false); 211 jdoField.defaultFetchGroup = MDStatics.TRUE; 212 } else if (java.sql.Blob .class.equals(property.getType()) 213 || java.sql.Clob .class.equals(property.getType())) { 214 jdoField.defaultFetchGroup = MDStatics.FALSE; 215 } 216 } 217 } 218 219 private void processId(AccessibleMember property, JdoField jdoField, JdoClass jdoClass) { 220 225 if (property.isAnnotationPresent(Id.class)) { 226 jdoField.primaryKey = true; 227 228 Id idAno = (Id) property.getAnnotation(Id.class); 229 JdoExtension keygenExt = JdoExtension.find(JDBC_KEY_GENERATOR, jdoClass.elements); 231 232 String generator = idAno.generator(); 233 if (idAno.generate() == GeneratorType.NONE) { 234 if (keygenExt != null) { 235 keygenExt.key = -1; 237 } 238 } else if (idAno.generate() == GeneratorType.SEQUENCE || 239 idAno.generate() == GeneratorType.IDENTITY) { 240 keygenExt = createKeyGen(jdoClass, keygenExt); 241 keygenExt.value = "AUTOINC"; 242 if (generator != null && generator.length() > 0) { 243 keygenExt.value = generator; 244 } 245 } else if (idAno.generate() == GeneratorType.AUTO) { 246 throw new RuntimeException ("NotImplemented"); 247 } else if (idAno.generate() == GeneratorType.TABLE) { 248 keygenExt = createKeyGen(jdoClass, keygenExt); 249 if (generator != null && generator.length() > 0) { 250 keygenExt.value = generator; 251 } else { 252 throw new RuntimeException ("Must ' '" + idAno.generate() + "'"); 253 } 254 } else { 255 throw new RuntimeException ("Unsupported GeneratorType '" + idAno.generate() + "'"); 256 } 257 } 258 } 259 260 private JdoField getJdoField(Map jdoFieldMap, Member field, JdoClass jdoClass) { 261 JdoField jdoField = (JdoField)jdoFieldMap.get(field.getName()); 262 if (jdoField == null) { 263 jdoField = new JdoField(); 264 jdoField.name = field.getName(); 265 jdoField.parent = jdoClass; 266 jdoClass.addElement(jdoField); 267 jdoFieldMap.put(jdoField.name, jdoField); 268 } 269 return jdoField; 270 } 271 272 private Map createFieldMap(JdoClass jdoClass) { 273 Map jdoFieldMap = new HashMap (); 274 if (jdoClass.elements != null) { 275 JdoElement[] elements = jdoClass.elements; 276 for (int i = 0; i < elements.length; i++) { 277 JdoElement element = elements[i]; 278 if (element instanceof JdoField) { 279 jdoFieldMap.put(((JdoField)element).name, element); 280 } 281 } 282 } 283 return jdoFieldMap; 284 } 285 286 private boolean isValid(String value) { 287 if (value == null || value.length() == 0) return false; 288 return true; 289 } 290 291 private void setCascadeType(CascadeType[] cct, JdoField jdoField) { 292 for (int j = 0; j < cct.length; j++) { 293 CascadeType cascadeType = cct[j]; 294 switch (cascadeType) { 295 case ALL: 296 jdoField.cascadeType = MDStatics.CASCADE_ALL; 297 break; 298 case MERGE: 299 jdoField.cascadeType += MDStatics.CASCADE_MERGE; 300 break; 301 case PERSIST: 302 jdoField.cascadeType += MDStatics.CASCADE_PERSIST; 303 break; 304 case REFRESH: 305 jdoField.cascadeType += MDStatics.CASCADE_REFRESH; 306 break; 307 case REMOVE: 308 jdoField.cascadeType += MDStatics.CASCADE_REMOVE; 309 break; 310 default: 311 throw BindingSupportImpl.getInstance().internal("unhandled CascadeType '" + cascadeType + "'"); 312 } 313 } 314 } 315 316 private JdoExtension createKeyGen(JdoClass jdoCls, JdoExtension keygenExt) { 317 if (keygenExt == null) { 318 keygenExt = new JdoExtension(); 319 keygenExt.key = JDBC_KEY_GENERATOR; 320 jdoCls.addElement(keygenExt); 321 } 322 return keygenExt; 323 } 324 325 private void doPCSuperClass(JdoClass jdoClass, Class subClass) { 326 Class superClass = subClass.getSuperclass(); 327 if (superClass == null) return; 328 329 String superClassName = jdoClass.getPCSuperClassQName(); 330 if (superClassName == null && superClass.isAnnotationPresent(javax.persistence.Entity.class)) { 331 jdoClass.pcSuperclass = superClass.getName(); 332 } 333 } 334 335 338 private Class loadClass(String name) throws ClassNotFoundException { 339 return ClassHelper.get().classForName(name, false, loader); 340 } 341 342 345 private class AccessibleMember extends AccessibleObject implements Member { 346 private Field field; 347 private Method method; 348 349 public void init(Field field, Method method) { 350 this.field = field; 351 this.method = method; 352 } 353 354 public Class getDeclaringClass() { 355 return field.getDeclaringClass(); 356 } 357 358 public int getModifiers() { 359 return field.getModifiers(); 360 } 361 362 public String getName() { 363 return field.getName(); 364 } 365 366 public boolean isSynthetic() { 367 return field.isSynthetic(); 368 } 369 370 public <T extends Annotation > T getAnnotation(Class <T> annotationClass) { 371 if (method == null) { 372 return field.getAnnotation(annotationClass); 373 } else { 374 return method.getAnnotation(annotationClass); 375 } 376 } 377 378 public Annotation [] getAnnotations() { 379 if (method == null) { 380 return field.getAnnotations(); 381 } else { 382 return method.getAnnotations(); 383 } 384 } 385 386 public Annotation [] getDeclaredAnnotations() { 387 if (method == null) { 388 return field.getDeclaredAnnotations(); 389 } else { 390 return method.getDeclaredAnnotations(); 391 } 392 } 393 394 395 public boolean isAccessible() { 396 if (method == null) { 397 return field.isAccessible(); 398 } else { 399 return method.isAccessible(); 400 } 401 } 402 403 public boolean isAnnotationPresent(Class <? extends Annotation > annotationClass) { 404 if (method == null) { 405 return field.isAnnotationPresent(annotationClass); 406 } else { 407 return method.isAnnotationPresent(annotationClass); 408 } 409 } 410 411 public void setAccessible(boolean flag) throws SecurityException { 412 if (method == null) { 413 field.setAccessible(flag); 414 } else { 415 method.setAccessible(flag); 416 } 417 } 418 419 public Class getType() { 420 return field.getType(); 421 } 422 423 } 424 } 425 | Popular Tags |