1 21 package oracle.toplink.essentials.internal.ejb.cmp3.metadata; 22 23 import java.lang.annotation.Annotation ; 24 25 import java.lang.reflect.AnnotatedElement ; 26 import java.lang.reflect.Field ; 27 import java.lang.reflect.Method ; 28 import java.lang.reflect.ParameterizedType ; 29 import java.lang.reflect.Type ; 30 31 import java.security.AccessController ; 32 import java.security.PrivilegedActionException ; 33 34 import java.util.ArrayList ; 35 import java.util.Collection ; 36 import java.util.HashMap ; 37 import java.util.HashSet ; 38 import java.util.Hashtable ; 39 import java.util.List ; 40 import java.util.Map ; 41 import java.util.Set ; 42 import java.util.Vector ; 43 44 import javax.persistence.Embeddable; 45 import javax.persistence.Embedded; 46 import javax.persistence.EmbeddedId; 47 import javax.persistence.ManyToMany; 48 import javax.persistence.ManyToOne; 49 import javax.persistence.OneToMany; 50 import javax.persistence.OneToOne; 51 52 import oracle.toplink.essentials.descriptors.ClassDescriptor; 53 54 import oracle.toplink.essentials.exceptions.ValidationException; 55 56 import oracle.toplink.essentials.internal.ejb.cmp3.metadata.accessors.MetadataAccessor; 57 import oracle.toplink.essentials.internal.ejb.cmp3.metadata.accessors.objects.MetadataAccessibleObject; 58 import oracle.toplink.essentials.internal.ejb.cmp3.metadata.listeners.MetadataEntityListener; 59 60 import oracle.toplink.essentials.internal.helper.Helper; 61 62 import oracle.toplink.essentials.internal.security.PrivilegedAccessHelper; 63 import oracle.toplink.essentials.internal.security.PrivilegedClassForName; 64 import oracle.toplink.essentials.internal.security.PrivilegedGetDeclaredFields; 65 import oracle.toplink.essentials.internal.security.PrivilegedGetDeclaredMethods; 66 import oracle.toplink.essentials.internal.security.PrivilegedGetField; 67 import oracle.toplink.essentials.internal.security.PrivilegedGetMethod; 68 import oracle.toplink.essentials.internal.security.PrivilegedGetMethods; 69 70 import oracle.toplink.essentials.sessions.Project; 71 72 78 public class MetadataHelper { 79 public static final String IS_PROPERTY_METHOD_PREFIX = "is"; 80 public static final String GET_PROPERTY_METHOD_PREFIX = "get"; 81 public static final String SET_PROPERTY_METHOD_PREFIX = "set"; 82 public static final String SET_IS_PROPERTY_METHOD_PREFIX = "setIs"; 83 private static final int POSITION_AFTER_IS_PREFIX = IS_PROPERTY_METHOD_PREFIX.length(); 84 private static final int POSITION_AFTER_GET_PREFIX = GET_PROPERTY_METHOD_PREFIX.length(); 85 86 public static final String PERSISTENCE_PACKAGE_PREFIX = "javax.persistence"; 87 88 98 public static ClassDescriptor findDescriptor(Project project, Class cls) { 99 for (ClassDescriptor descriptor : (Vector <ClassDescriptor>) project.getOrderedDescriptors()) { 100 if (descriptor.getJavaClassName().equals(cls.getName())){ 101 return descriptor; 102 } 103 } 104 105 return null; 106 } 107 108 114 public static <T extends Annotation > T getAnnotation(Class annotation, AnnotatedElement annotatedElement) { 115 return (T) annotatedElement.getAnnotation(annotation); 116 } 117 118 123 public static <T extends Annotation > T getAnnotation(Class annotation, AnnotatedElement annotatedElement, MetadataDescriptor descriptor) { 124 if (descriptor.ignoreAnnotations()) { 127 return null; 128 } else { 129 return (T) getAnnotation(annotation, annotatedElement); 130 } 131 } 132 133 137 public static <T extends Annotation > T getAnnotation(Class annotation, MetadataAccessor accessor) { 138 return (T) getAnnotation(annotation, accessor.getAnnotatedElement(), accessor.getDescriptor()); 139 } 140 141 145 public static <T extends Annotation > T getAnnotation(Class annotation, MetadataDescriptor descriptor) { 146 return (T) getAnnotation(annotation, descriptor.getJavaClass(), descriptor); 147 } 148 149 155 public static String getAttributeNameFromMethodName(String methodName) { 156 String leadingChar = ""; 157 String restOfName = methodName; 158 159 if (methodName.startsWith(GET_PROPERTY_METHOD_PREFIX)) { 160 leadingChar = methodName.substring(POSITION_AFTER_GET_PREFIX, POSITION_AFTER_GET_PREFIX + 1); 161 restOfName = methodName.substring(POSITION_AFTER_GET_PREFIX + 1); 162 } else if (methodName.startsWith(IS_PROPERTY_METHOD_PREFIX)){ 163 leadingChar = methodName.substring(POSITION_AFTER_IS_PREFIX, POSITION_AFTER_IS_PREFIX + 1); 164 restOfName = methodName.substring(POSITION_AFTER_IS_PREFIX + 1); 165 } 166 167 return leadingChar.toLowerCase().concat(restOfName); 168 } 169 170 174 public static Method [] getCandidateCallbackMethodsForDefaultListener(MetadataEntityListener listener) { 175 return getCandidateCallbackMethodsForEntityListener(listener); 176 } 177 178 182 public static Method [] getCandidateCallbackMethodsForEntityClass(Class entityClass) { 183 return getDeclaredMethods(entityClass); 184 } 185 186 192 public static Method [] getCandidateCallbackMethodsForEntityListener(MetadataEntityListener listener) { 193 HashSet candidateMethods = new HashSet (); 194 Class listenerClass = listener.getListenerClass(); 195 196 Method [] declaredMethods = getDeclaredMethods(listenerClass); 198 for (int i = 0; i < declaredMethods.length; i++) { 199 candidateMethods.add(declaredMethods[i]); 200 } 201 202 Method [] methods = getMethods(listenerClass); 204 for (int i = 0; i < methods.length; i++) { 205 if (candidateMethods.contains(methods[i])) { 206 continue; 207 } 208 209 candidateMethods.add(methods[i]); 210 } 211 212 return (Method []) candidateMethods.toArray(new Method [candidateMethods.size()]); 213 } 214 215 221 public static Method [] getCandidateCallbackMethodsForMappedSuperclass(Class mappedSuperclass, Class entityClass) { 222 ArrayList candidateMethods = new ArrayList (); 223 Method [] allMethods = getMethods(entityClass); 224 Method [] declaredMethods = getDeclaredMethods(mappedSuperclass); 225 226 for (int i = 0; i < declaredMethods.length; i++) { 227 Method method = getMethodForName(allMethods, declaredMethods[i].getName()); 228 229 if (method != null) { 230 candidateMethods.add(method); 231 } 232 } 233 234 return (Method []) candidateMethods.toArray(new Method [candidateMethods.size()]); 235 } 236 237 241 public static Class getClassForName(String classname, ClassLoader classLoader) { 242 try { 243 if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){ 244 try { 245 return(Class )AccessController.doPrivileged(new PrivilegedClassForName(classname, true, classLoader)); 246 } catch (PrivilegedActionException exception) { 247 throw ValidationException.unableToLoadClass(classname, exception.getException()); } 248 } else { 249 return oracle.toplink.essentials.internal.security.PrivilegedAccessHelper.getClassForName(classname, true, classLoader); 250 } 251 } catch (ClassNotFoundException exception) { 252 throw ValidationException.unableToLoadClass(classname, exception); 253 } 254 } 255 256 259 public static int getDeclaredAnnotationsCount(AnnotatedElement annotatedElement, MetadataDescriptor descriptor) { 260 if (descriptor.ignoreAnnotations()) { 261 return 0; 262 } else { 263 int count = 0; 265 266 for (Annotation annotation : annotatedElement.getDeclaredAnnotations()) { 267 if (annotation.annotationType().getName().startsWith(PERSISTENCE_PACKAGE_PREFIX)) { 268 count++; 269 } 270 } 271 272 return count; 273 } 274 } 275 276 282 public static Method [] getDeclaredMethods(Class cls) { 283 if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){ 284 try { 285 return(Method [])AccessController.doPrivileged(new PrivilegedGetDeclaredMethods(cls)); 286 } catch (PrivilegedActionException exception) { 287 return null; 289 } 290 } else { 291 return oracle.toplink.essentials.internal.security.PrivilegedAccessHelper.getDeclaredMethods(cls); 292 } 293 } 294 295 299 public static Class getDiscriminatorType(String discriminatorType) { 300 if (discriminatorType.equals(MetadataConstants.CHAR)) { 301 return Character .class; 302 } else if (discriminatorType.equals(MetadataConstants.STRING)) { 303 return String .class; 304 } else if (discriminatorType.equals(MetadataConstants.INTEGER)) { 305 return Integer .class; 306 } else { 307 return null; 309 } 310 } 311 312 316 public static Class getFieldClassification(String temporalType) { 317 if (temporalType.equals(MetadataConstants.DATE)) { 318 return java.sql.Date .class; 319 } else if (temporalType.equals(MetadataConstants.TIME)) { 320 return java.sql.Time .class; 321 } else if (temporalType.equals(MetadataConstants.TIMESTAMP)) { 322 return java.sql.Timestamp .class; 323 } else { 324 return null; 326 } 327 } 328 329 333 public static Field getFieldForName(String fieldName, Class javaClass) { 334 Field field = null; 335 336 try { 337 if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){ 338 try { 339 field = (Field )AccessController.doPrivileged(new PrivilegedGetField(javaClass, fieldName, false)); 340 } catch (PrivilegedActionException exception) { 341 return null; 342 } 343 } else { 344 field = PrivilegedAccessHelper.getField(javaClass, fieldName, false); 345 } 346 } catch (NoSuchFieldException nsfex) { 347 return null; 348 } 349 350 return field; 351 } 352 353 358 public static Field [] getFields(Class cls) { 359 if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){ 360 try { 361 return (Field [])AccessController.doPrivileged(new PrivilegedGetDeclaredFields(cls)); 362 } catch (PrivilegedActionException exception) { 363 return null; 365 } 366 } else { 367 return PrivilegedAccessHelper.getDeclaredFields(cls); 368 } 369 } 370 371 376 public static String getFullyQualifiedTableName(String tableName, String catalog, String schema) { 377 if (! catalog.equals("")) { 379 tableName = catalog + "." + tableName; 380 } 381 382 if (! schema.equals("")) { 384 tableName = schema + "." + tableName; 385 } 386 387 return tableName; 388 } 389 390 395 public static String getFullyQualifiedTableName(String name, String defaultName, String catalog, String schema) { 396 String tableName = name; 398 if (tableName.equals("")) { 399 tableName = defaultName; 400 } 401 402 return getFullyQualifiedTableName(tableName, catalog, schema); 403 } 404 405 409 public static Type getGenericReturnType(Method method) { 410 return method.getGenericReturnType(); 412 } 413 414 418 public static Type getGenericType(Field field) { 419 return field.getGenericType(); 421 } 422 423 428 protected static Method getMethod(String methodName, Class cls, Class [] params) { 429 try { 430 if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){ 431 try { 432 return (Method )AccessController.doPrivileged(new PrivilegedGetMethod(cls, methodName, params, true)); 433 } catch (PrivilegedActionException exception) { 434 return null; 435 } 436 } else { 437 return PrivilegedAccessHelper.getMethod(cls, methodName, params, true); 438 } 439 } catch (NoSuchMethodException e1) { 440 return null; 441 } 442 } 443 444 448 public static Method getMethodForName(Method [] methods, String methodName) { 449 for (int i = 0; i < methods.length; i++) { 450 Method method = methods[i]; 451 452 if (method.getName().equals(methodName)) { 453 return method; 454 } 455 } 456 457 return null; 458 } 459 460 464 public static Method getMethodForPropertyName(String propertyName, Class cls) { 465 Method method; 466 467 String leadingChar = String.valueOf(propertyName.charAt(0)).toUpperCase(); 468 String restOfName = propertyName.substring(1); 469 470 method = getMethod(GET_PROPERTY_METHOD_PREFIX.concat(leadingChar).concat(restOfName), cls, new Class []{}); 472 473 if (method == null) { 474 method = getMethod(IS_PROPERTY_METHOD_PREFIX.concat(leadingChar).concat(restOfName), cls, new Class []{}); 476 } 477 478 return method; 479 } 480 481 487 public static Method [] getMethods(Class cls) { 488 if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){ 489 try { 490 return (Method [])AccessController.doPrivileged(new PrivilegedGetMethods(cls)); 491 } catch (PrivilegedActionException exception) { 492 return null; 493 } 494 } else { 495 return PrivilegedAccessHelper.getMethods(cls); 496 } 497 } 498 499 503 public static Class getRawClassFromGeneric(Type type) { 504 return (Class )(((ParameterizedType ) type).getRawType()); 505 } 506 507 512 public static Class getReferenceClass(Class defaultReferenceClass, Class targetEntity) { 513 if (targetEntity == void.class) { 514 return defaultReferenceClass; 515 } 516 517 return targetEntity; 518 } 519 520 526 public static Class getReturnTypeFromGeneric(Type type) { 527 ParameterizedType pType = (ParameterizedType ) type; 528 529 if (java.util.Map .class.isAssignableFrom((Class ) pType.getRawType())) { 530 return (Class ) pType.getActualTypeArguments()[1]; 531 } 532 533 return (Class ) pType.getActualTypeArguments()[0]; 534 } 535 536 541 public static Method getSetMethod(Method method, Class cls) { 542 String getMethodName = method.getName(); 543 Class [] params = new Class [] { method.getReturnType() }; 544 545 if (getMethodName.startsWith(GET_PROPERTY_METHOD_PREFIX)) { 546 return getMethod(SET_PROPERTY_METHOD_PREFIX + getMethodName.substring(3), cls, params); 548 } 549 550 Method setMethod = getMethod(SET_PROPERTY_METHOD_PREFIX + getMethodName.substring(2), cls, params); 553 554 if (setMethod == null) { 555 return getMethod(SET_IS_PROPERTY_METHOD_PREFIX + getMethodName.substring(2), cls, params); 557 } 558 559 return setMethod; 560 } 561 562 565 public static boolean havePersistenceAnnotationsDefined(AnnotatedElement [] annotatedElements) { 566 for (AnnotatedElement annotatedElement : annotatedElements) { 567 for (Annotation annotation : annotatedElement.getDeclaredAnnotations()) { 568 if (annotation.annotationType().getName().startsWith(PERSISTENCE_PACKAGE_PREFIX)) { 569 return true; 570 } 571 } 572 } 573 574 return false; 575 } 576 577 584 public static boolean isAnnotationNotPresent(Class annotation, AnnotatedElement annotatedElement) { 585 return ! annotatedElement.isAnnotationPresent(annotation); 586 } 587 588 593 public static boolean isAnnotationPresent(Class annotation, AnnotatedElement annotatedElement) { 594 return annotatedElement.isAnnotationPresent(annotation); 595 } 596 597 602 public static boolean isAnnotationPresent(Class annotation, AnnotatedElement annotatedElement, MetadataDescriptor descriptor) { 603 if (descriptor.ignoreAnnotations()) { 606 return false; 607 } else { 608 return isAnnotationPresent(annotation, annotatedElement); 609 } 610 } 611 612 617 public static boolean isAnnotationPresent(Class annotation, MetadataDescriptor descriptor) { 618 return isAnnotationPresent(annotation, descriptor.getJavaClass(), descriptor); 619 } 620 621 627 public static boolean isEmbedded(MetadataAccessibleObject accessibleObject, MetadataDescriptor descriptor) { 628 AnnotatedElement annotatedElement = accessibleObject.getAnnotatedElement(); 629 630 if (isAnnotationNotPresent(Embedded.class, annotatedElement) && isAnnotationNotPresent(EmbeddedId.class, annotatedElement)) { 631 return (isAnnotationPresent(Embeddable.class, accessibleObject.getReferenceClass())); 632 } else { 633 return isAnnotationPresent(Embedded.class, annotatedElement, descriptor); 636 } 637 } 638 639 645 public static boolean isEmbeddedId(MetadataAccessibleObject accessibleObject, MetadataDescriptor descriptor) { 646 return isAnnotationPresent(EmbeddedId.class, accessibleObject.getAnnotatedElement(), descriptor); 647 } 648 649 653 public static boolean isGenericCollectionType(Type type) { 654 return (type instanceof ParameterizedType ); 655 } 656 657 661 public static boolean isManyToMany(MetadataAccessibleObject accessibleObject, MetadataDescriptor descriptor) { 662 Class rawClass = accessibleObject.getRawClass(); 663 AnnotatedElement annotatedElement = accessibleObject.getAnnotatedElement(); 664 665 if (isAnnotationPresent(ManyToMany.class, annotatedElement, descriptor)) { 666 if (MetadataHelper.isSupportedCollectionClass(rawClass)) { 667 return true; 668 } else { 669 throw ValidationException.invalidCollectionTypeForRelationship(rawClass, annotatedElement); 670 } 671 } 672 673 return false; 674 } 675 676 680 public static boolean isManyToOne(MetadataAccessibleObject annotatedAccessor, MetadataDescriptor descriptor) { 681 return isAnnotationPresent(ManyToOne.class, annotatedAccessor.getAnnotatedElement(), descriptor); 682 } 683 684 688 public static boolean isOneToMany(MetadataAccessibleObject annotatedAccessor, MetadataLogger logger, MetadataDescriptor descriptor) { 689 Class rawClass = annotatedAccessor.getRawClass(); 690 AnnotatedElement annotatedElement = annotatedAccessor.getAnnotatedElement(); 691 692 if (isAnnotationNotPresent(OneToMany.class, annotatedElement)) { 693 if (MetadataHelper.isGenericCollectionType(annotatedAccessor.getRelationType()) && MetadataHelper.isSupportedCollectionClass(rawClass)) { 694 logger.logConfigMessage(MetadataLogger.ONE_TO_MANY_MAPPING, annotatedElement); 695 return true; 696 } 697 } else { 698 if (isAnnotationPresent(OneToMany.class, annotatedElement, descriptor)) { 701 if (MetadataHelper.isSupportedCollectionClass(rawClass)) { 702 return true; 703 } else { 704 throw ValidationException.invalidCollectionTypeForRelationship(rawClass, annotatedElement); 705 } 706 } 707 } 708 709 return false; 710 } 711 712 716 public static boolean isOneToOne(MetadataAccessibleObject accessibleObject, MetadataProject project, MetadataLogger logger, MetadataDescriptor descriptor) { 717 Class referenceClass = accessibleObject.getReferenceClass(); 718 AnnotatedElement annotatedElement = accessibleObject.getAnnotatedElement(); 719 720 if (isAnnotationNotPresent(OneToOne.class, annotatedElement)) { 721 if (project.containsDescriptor(referenceClass) && ! isEmbedded(accessibleObject, descriptor)) { 722 logger.logConfigMessage(MetadataLogger.ONE_TO_ONE_MAPPING, annotatedElement); 723 return true; 724 } else { 725 return false; 726 } 727 } else { 728 return isAnnotationPresent(OneToOne.class, annotatedElement, descriptor); 731 } 732 } 733 734 738 public static boolean isPrimitiveWrapperClass(Class cls) { 739 return cls.equals(Long .class) || 740 cls.equals(Short .class) || 741 cls.equals(Float .class) || 742 cls.equals(Byte .class) || 743 cls.equals(Double .class) || 744 cls.equals(Number .class) || 745 cls.equals(Boolean .class) || 746 cls.equals(Integer .class) || 747 cls.equals(Character .class) || 748 cls.equals(java.math.BigInteger .class) || 749 cls.equals(java.math.BigDecimal .class); 750 } 751 752 757 public static boolean isSupportedCollectionClass(Class cls) { 758 return cls == Collection .class || 759 cls == Set .class || 760 cls == List .class || 761 cls == Map .class; 762 } 763 764 768 public static boolean isValidAttributeName(String attributeName, Class javaClass) { 769 Field attributes[] = getFields(javaClass); 770 771 for (int i = 0; i < attributes.length; i++) { 772 if (attributes[i].getName().equals(attributeName)) { 773 return true; 774 } 775 } 776 777 return false; 778 } 779 780 784 public static boolean isValidBlobType(Class cls) { 785 return cls.equals(byte[].class) || 786 cls.equals(Byte [].class) || 787 cls.equals(java.sql.Blob .class) || 788 Helper.classImplementsInterface(cls, java.io.Serializable .class); 789 } 790 791 795 public static boolean isValidClobType(Class cls) { 796 return cls.equals(char[].class) || 797 cls.equals(String .class) || 798 cls.equals(Character [].class) || 799 cls.equals(java.sql.Clob .class); 800 } 801 802 806 public static boolean isValidEnumeratedType(Class cls) { 807 return cls.isEnum(); 808 } 809 810 814 public static boolean isValidLobType(Class cls) { 815 return isValidClobType(cls) || isValidBlobType(cls); 816 } 817 818 821 public static boolean isValidPersistenceMethodName(String methodName) { 822 return methodName.startsWith(GET_PROPERTY_METHOD_PREFIX) || methodName.startsWith(IS_PROPERTY_METHOD_PREFIX); 823 } 824 825 829 public static boolean isValidSerializedType(Class cls) { 830 if (cls.isPrimitive()) { 831 return false; 832 } 833 834 if (isPrimitiveWrapperClass(cls)) { 835 return false; 836 } 837 838 if (isValidLobType(cls)) { 839 return false; 840 } 841 842 if (isValidTemporalType(cls)) { 843 return false; 844 } 845 846 return true; 847 } 848 849 854 public static boolean isValidTemporalType(Class cls) { 855 return (cls.equals(java.util.Date .class) || 856 cls.equals(java.util.Calendar .class) || 857 cls.equals(java.util.GregorianCalendar .class)); 858 } 859 860 864 public static boolean isValidTimstampVersionLockingType(Class cls) { 865 return (cls.equals(java.sql.Timestamp .class)); 866 } 867 868 872 public static boolean isValidVersionLockingType(Class cls) { 873 return (cls.equals(int.class) || 874 cls.equals(Integer .class) || 875 cls.equals(short.class) || 876 cls.equals(Short .class) || 877 cls.equals(long.class) || 878 cls.equals(Long .class)); 879 } 880 881 887 public static boolean shouldIgnoreAnnotations(Class cls, HashMap <Class , MetadataDescriptor> metadataDescriptors) { 888 MetadataDescriptor descriptor = metadataDescriptors.get(cls); 889 890 if (descriptor != null) { 891 return descriptor.ignoreAnnotations(); 892 } else { 893 return false; 894 } 895 } 896 } 897 | Popular Tags |