1 23 24 29 30 package com.sun.jdo.api.persistence.model; 31 32 import java.io.*; 33 import java.util.*; 34 import java.lang.reflect.Modifier ; 35 36 import org.netbeans.modules.dbschema.migration.archiver.XMLInputStream; 37 import org.netbeans.modules.dbschema.migration.archiver.XMLOutputStream; 38 39 import org.netbeans.modules.dbschema.SchemaElement; 40 import com.sun.jdo.api.persistence.model.util.LogHelperModel; 41 import com.sun.jdo.api.persistence.model.util.ModelValidator; 42 import com.sun.jdo.api.persistence.model.jdo.*; 43 import com.sun.jdo.api.persistence.model.jdo.impl.*; 44 import com.sun.jdo.api.persistence.model.mapping.MappingClassElement; 45 import com.sun.jdo.api.persistence.model.mapping.MappingFieldElement; 46 import com.sun.jdo.api.persistence.model.mapping.impl.MappingClassElementImpl; 47 import com.sun.jdo.spi.persistence.utility.*; 48 import com.sun.jdo.spi.persistence.utility.logging.Logger; 49 50 62 63 68 public abstract class Model 69 { 70 71 public static final Model RUNTIME; 72 73 74 public static final Model ENHANCER; 75 76 78 public static final String [] EQUALS_ARGS = {"java.lang.Object"}; 80 83 public static final String [] NO_ARGS = new String [0]; 84 85 87 public static final String [] READ_OBJECT_ARGS = {"java.io.ObjectInputStream"}; 89 91 public static final String [] WRITE_OBJECT_ARGS = {"java.io.ObjectOutputStream"}; 93 96 private final Map _classes = new WeakValueHashMap(); 97 98 101 private final Set _nonPCClasses = new WeakHashSet(); 102 103 106 private static List _illegalPrefixes; 107 108 111 private static List _illegalClasses; 112 113 114 private static List _scoClasses; 115 116 117 private static List _mutableScoClasses; 118 119 120 private static List _collectionClasses; 121 122 123 public static final String messageBase = 124 "com.sun.jdo.api.persistence.model.Bundle"; 126 127 private static final ResourceBundle _messages = I18NHelper.loadBundle( 128 Model.class); 129 130 static 131 { 132 String prefixes[] = 133 {"java.awt", "java.applet", "javax.swing", "javax.ejb"}; String classes[] = {"java.lang.Throwable"}; String collectionClasses[] = { "java.util.Collection", "java.util.AbstractCollection", "java.util.Set", "java.util.AbstractSet", "java.util.HashSet", "com.sun.jdo.spi.persistence.support.sqlstore.sco.HashSet"}; String mutableScoClasses[] = {"java.util.Date", "com.sun.jdo.spi.persistence.support.sqlstore.sco.Date", "java.sql.Date", "com.sun.jdo.spi.persistence.support.sqlstore.sco.SqlDate", "java.sql.Time", "com.sun.jdo.spi.persistence.support.sqlstore.sco.SqlTime", "java.sql.Timestamp", "com.sun.jdo.spi.persistence.support.sqlstore.sco.SqlTimestamp"}; String scoClasses[] = {"java.lang.String", "java.lang.Character", "java.lang.Boolean", "java.lang.Long", "java.lang.Number", "java.lang.Byte", "java.lang.Short", "java.lang.Integer", "java.lang.Float", "java.lang.Double", "java.math.BigDecimal", "java.math.BigInteger"}; 157 _illegalPrefixes = Arrays.asList(prefixes); 158 _illegalClasses = Arrays.asList(classes); 159 _collectionClasses = Arrays.asList(collectionClasses); 160 _mutableScoClasses = new ArrayList(Arrays.asList(mutableScoClasses)); 161 _mutableScoClasses.addAll(_collectionClasses); 162 _scoClasses = new ArrayList(Arrays.asList(scoClasses)); 163 _scoClasses.addAll(_mutableScoClasses); 164 165 RUNTIME = NewModel(null, "com.sun.jdo.api.persistence.model.RuntimeModel"); ENHANCER = NewModel(null, "com.sun.jdo.api.persistence.model.EnhancerModel"); } 170 171 181 static protected Model NewModel (String testName, String modelName) { 182 Class DynamicClass = null; 183 Model model = null; 184 try { 185 if (testName != null) 186 Class.forName (testName); 188 DynamicClass = Class.forName (modelName); 189 if (DynamicClass != null) 190 model = (Model) DynamicClass.newInstance(); 191 } 192 catch (Exception e) { 193 } 195 return model; 196 } 197 199 protected static final ResourceBundle getMessages () 200 { 201 return _messages; 202 } 203 204 213 abstract protected BufferedInputStream getInputStreamForResource ( 214 String className, ClassLoader classLoader, String resourceName); 215 216 221 abstract public boolean isInterface (String className); 222 223 229 public boolean hasPersistentSuperclass (String className) 230 { 231 while ((className = getSuperclass(className)) != null) 232 { 233 if (isPersistent(className)) 234 return true; 235 } 236 237 return false; 238 } 239 240 246 abstract protected String findPenultimateSuperclass (String className); 247 248 253 abstract protected String getSuperclass (String className); 254 255 265 public PersistenceClassElement getPersistenceClass (String className) 266 { 267 return getPersistenceClass(className, null); 268 } 269 270 281 public PersistenceClassElement getPersistenceClass (String className, 282 ClassLoader classLoader) 283 { 284 return getPersistenceClass(getMappingClass(className, classLoader)); 285 } 286 287 294 protected PersistenceClassElement getPersistenceClass ( 295 MappingClassElement mappingClass) 296 { 297 return ((mappingClass == null) ? null : 298 ((MappingClassElementImpl)mappingClass).getPersistenceElement()); 299 } 300 301 308 public MappingClassElement getMappingClass (String className) 309 { 310 return getMappingClass(className, null); 311 } 312 313 322 public MappingClassElement getMappingClass (String className, 323 ClassLoader classLoader) 324 { 325 synchronized (this._classes) 333 { 334 MappingClassElement mappingClass = 335 (MappingClassElement)_classes.get(className); 336 337 if (mappingClass == null) 338 { 339 if (_nonPCClasses.contains(className)) 341 return null; 342 343 try 344 { 345 InputStream stream = getInputStreamForResource(className, 346 classLoader, getResourceNameWithExtension(className)); 347 348 if (stream != null) 349 { 350 if (stream.available() > 0) 354 { 355 XMLInputStream xmlInput = new XMLInputStream(stream, 356 getClass().getClassLoader()); 357 358 mappingClass = 359 (MappingClassElement)xmlInput.readObject(); 360 xmlInput.close(); 361 362 mappingClass.postUnarchive(); 365 366 _classes.put(className, mappingClass); 370 371 mappingClass.setModified(false); 375 getPersistenceClass(mappingClass). 376 setModified(false); 377 } 378 } 379 else 380 { 381 _nonPCClasses.add(className); 385 } 386 } 387 catch (ModelException e) 388 { 389 LogHelperModel.getLogger().log(Logger.WARNING, 391 e.getMessage()); 392 return null; 393 } 394 catch (Exception e) 395 { 396 LogHelperModel.getLogger().log(Logger.WARNING, 398 I18NHelper.getMessage(getMessages(), 399 "file.cannot_read", className, e.toString())); } } 402 403 return mappingClass; 404 } 405 } 406 407 410 public Map getMappingCache () 411 { 412 return Collections.unmodifiableMap(_classes); 413 } 414 415 420 public Map getClassLoaderCache () 421 { 422 return null; 423 } 424 425 431 public void removeResourcesFromCaches (ClassLoader classLoader) 432 { 433 } 435 436 445 protected void removeResourcesFromCaches (Collection classNames) 446 { 447 if (classNames == null) 448 return; 449 450 synchronized (this._classes) 451 { 452 for (Iterator i = classNames.iterator(); i.hasNext();) 453 { 454 String className = (String )i.next(); 455 MappingClassElement mapping = 456 (MappingClassElement)_classes.get(className); 457 458 if (mapping != null) 462 SchemaElement.removeFromCache(mapping.getDatabaseRoot()); 463 464 _classes.remove(className); 466 467 _nonPCClasses.remove(className); 469 } 470 } 471 } 472 473 478 public void removeFromCache (String className) 479 { 480 synchronized (this._classes) 481 { 482 _nonPCClasses.remove(className); 484 } 485 } 486 487 494 public void storeMappingClass (MappingClassElement mappingClass) 495 throws IOException 496 { 497 if (mappingClass != null) 498 { 499 String className = mappingClass.getName(); 500 OutputStream stream = ((className == null) ? null : 501 createFile(className, getFileName(className), 502 MappingClassElement.MAPPING_EXTENSION)); 503 504 storeMappingClass(mappingClass, stream); 505 } 506 } 507 508 516 public void storeMappingClass (MappingClassElement mappingClass, 517 OutputStream stream) throws IOException 518 { 519 if (mappingClass != null) 520 { 521 String className = mappingClass.getName(); 522 523 if (stream != null) 524 { 525 XMLOutputStream xmlOutput = new XMLOutputStream(stream); 526 527 try 528 { 529 mappingClass.preArchive(); xmlOutput.writeObject(mappingClass); 531 532 mappingClass.setModified(false); 535 getPersistenceClass(mappingClass).setModified(false); 536 } 537 catch (ModelException e) 538 { 539 LogHelperModel.getLogger().log(Logger.WARNING, 541 e.getMessage()); 542 } 543 finally 544 { 545 if (xmlOutput != null) 546 xmlOutput.close(); 547 548 unlockFile(stream, className); 549 } 550 return; 551 } 552 553 throw new IOException(I18NHelper.getMessage(getMessages(), 554 "file.cannot_save", className)); } 556 } 557 558 public void unlockFile (OutputStream stream, String className) 559 throws IOException 560 { 561 unlockFile(className); 562 563 if (stream != null) 564 stream.close(); 565 } 566 567 public void lockFile (String className) throws IOException {} 569 570 public void unlockFile (String className) {} 572 573 580 public void storeMappingClass (String className) throws IOException 581 { 582 MappingClassElement mappingClass = null; 583 584 synchronized (this._classes) 585 { 586 mappingClass = (MappingClassElement)_classes.get(className); 587 } 588 storeMappingClass(mappingClass); 589 } 590 591 599 public void updateKeyForClass (MappingClassElement mappingClass, 600 String oldName) 601 { 602 synchronized (this._classes) 605 { 606 if (oldName != null) 608 _classes.remove(oldName); 609 610 if (mappingClass != null) 612 { 613 String className = mappingClass.getName(); 614 615 _classes.put(className, mappingClass); 616 617 _nonPCClasses.remove(className); 620 } 621 } 622 } 623 624 631 public boolean isPersistent (String className) 632 { 633 return isPersistent(className, (ClassLoader )null); 634 } 635 636 637 645 public boolean isPersistent (String className, ClassLoader classLoader) 646 { 647 return (getPersistenceClass(className, classLoader) != null); 648 } 649 650 664 public boolean isPersistenceCapableAllowed (String className) 665 { 666 int modifier = getModifiersForClass(className); 667 668 if (!Modifier.isStatic(modifier) && !Modifier.isAbstract(modifier) && 669 !isInterface(className) && !hasPersistentSuperclass(className)) 670 { 671 String highestSuperclassName = findPenultimateSuperclass(className); 672 Iterator iterator = _illegalPrefixes.iterator(); 673 674 while (iterator.hasNext()) 675 { 676 String nextPrefix = iterator.next().toString(); 677 678 if (highestSuperclassName.startsWith(nextPrefix)) 679 return false; 680 } 681 682 iterator = _illegalClasses.iterator(); 683 while (iterator.hasNext()) 684 { 685 String nextClass = iterator.next().toString(); 686 687 if (highestSuperclassName.equals(nextClass)) 688 return false; 689 } 690 691 return true; 692 } 693 694 return false; 695 } 696 697 704 protected String getResourceNameWithExtension (String className) 705 { 706 return getResourceName(className) + "." + MappingClassElement.MAPPING_EXTENSION; 708 } 709 710 716 protected String getResourceName (String className) 717 { 718 return ((className != null) ? 719 className.replace('.', '/') : null); 720 } 721 722 730 protected String getFileNameWithExtension (String className) 731 { 732 return getFileName(className) + "." + MappingClassElement.MAPPING_EXTENSION; 734 } 735 736 742 protected String getFileName (String className) 743 { 744 return ((className != null) ? 745 className.replace('.', File.separatorChar) : null); 746 } 747 748 756 public void convertToPersistenceCapable (String className, 757 boolean flag) throws IOException 758 { 759 boolean classIsPersistent = isPersistent(className); 760 Exception conversionException = null; 761 762 if (flag && !classIsPersistent && 763 isPersistenceCapableAllowed(className)) 764 { 765 try 766 { 767 createSkeletonMappingClass(className); 770 } 771 catch (Exception e) 772 { 773 conversionException = e; 775 } 776 } 777 778 if ((!flag && classIsPersistent) || (conversionException != null)) 779 { 780 try 781 { 782 deleteFile(className, getFileNameWithExtension(className)); 784 785 synchronized (this._classes) 786 { 787 _classes.remove(className); 789 790 _nonPCClasses.add(className); 792 } 793 } 794 catch (Exception e) { 796 if (conversionException == null) 797 conversionException = e; 798 } 799 } 800 801 if (conversionException != null) { 803 if (conversionException instanceof RuntimeException ) 804 throw (RuntimeException )conversionException; 805 else if (conversionException instanceof IOException) 806 throw (IOException)conversionException; 807 } 808 } 809 810 815 public void convertToPersistenceCapable (String className) 816 throws IOException 817 { 818 convertToPersistenceCapable(className, true); 819 convertDefaultFields(className); 820 storeMappingClass(className); 821 } 822 823 830 private void createSkeletonMappingClass (String className) 831 { 832 PersistenceClassElement element = new PersistenceClassElement( 833 new PersistenceClassElementImpl(className)); 834 835 updateKeyForClass(new MappingClassElementImpl(element), null); 836 } 837 838 845 public void convertDefaultFields (String className) 846 { 847 convertFields(className, getFields(className)); 848 } 849 850 856 public void convertFields (String className, List fields) 857 { 858 PersistenceClassElement element = getPersistenceClass(className); 859 860 if (element != null) 861 { 862 Iterator iterator = fields.iterator(); 863 864 while (iterator.hasNext()) 867 { 868 String fieldName = (String )iterator.next(); 869 870 if (isPersistentAllowed(className, fieldName) && 871 shouldBePersistent(className, fieldName)) 872 { 873 addFieldElement(element, fieldName); 874 } 875 } 876 877 895 } 896 } 897 898 904 public boolean addFieldElement (PersistenceClassElement element, 905 String fieldName) 906 { 907 String fieldType = getFieldType(element.getName(), fieldName); 908 boolean isCollection = isCollection(fieldType); 909 910 try 911 { 912 if (isPersistent(fieldType) || isCollection) 914 { 915 RelationshipElement relationship = new RelationshipElement( 916 new RelationshipElementImpl(fieldName), element); 917 918 if (isCollection) 919 { 920 relationship.setCollectionClass( 921 getDefaultCollectionClass(fieldType)); 922 } 923 else relationship.setUpperBound(1); 925 926 element.addField(relationship); 927 } 928 else 929 { 930 element.addField(new PersistenceFieldElement(new 931 PersistenceFieldElementImpl(fieldName), element)); 932 } 933 934 return true; 935 } 936 catch (ModelException e) 937 {} 939 return false; 940 } 941 942 952 public void removeFieldElement (PersistenceFieldElement element) 953 throws ModelException 954 { 955 if (element != null) 956 { 957 if (element instanceof RelationshipElement) 958 { 959 ((RelationshipElement)element).setInverseRelationship(null, 960 this); 961 } 962 963 element.getDeclaringClass().removeField(element); 964 } 965 } 966 967 978 public String getRelatedClass (RelationshipElement element) 979 { 980 if (element != null) 981 { 982 String fieldType = getFieldType( 983 element.getDeclaringClass().getName(), element.getName()); 984 String relatedClass = (isCollection(fieldType) ? 985 element.getElementClass() : fieldType); 986 987 return (StringHelper.isEmpty(relatedClass) ? null : 988 relatedClass.trim()); 989 } 990 991 return null; 992 } 993 994 1002 public ArrayList getSupportedCollectionClasses (String className) 1003 { 1004 String supportedSet = "java.util.HashSet"; ArrayList returnList = new ArrayList(); 1008 1009 returnList.add(supportedSet); 1011 1024 return returnList; 1025 } 1026 1027 1036 public String getDefaultCollectionClass (String className) 1037 { 1038 String collectionClass = "java.util.HashSet"; 1040 1046 return collectionClass; 1047 } 1048 1049 1058 abstract protected BufferedOutputStream createFile (String className, 1059 String baseFileName, String extension) throws IOException; 1060 1061 1067 abstract protected void deleteFile (String className, String fileName) 1068 throws IOException; 1069 1070 1075 abstract public List getFields (String className); 1076 1077 1083 public List getAllFields (String className) 1084 { 1085 List returnList = new ArrayList(); 1086 1087 while (className != null) 1088 { 1089 returnList.addAll(getFields(className)); 1090 className = getSuperclass(className); 1091 } 1092 1093 return returnList; 1094 } 1095 1096 1100 public Object getClass (String className) 1101 { 1102 return getClass(className, null); 1103 } 1104 1105 1110 abstract public Object getClass (String className, ClassLoader classLoader); 1111 1112 1117 public boolean hasClass (String className) 1118 { 1119 return hasClass(className, null); 1120 } 1121 1122 1128 public boolean hasClass (String className, ClassLoader classLoader) 1129 { 1130 return (getClass(className, classLoader) != null); 1131 } 1132 1133 1143 abstract public boolean implementsInterface (Object classElement, 1144 String interfaceName); 1145 1146 1152 abstract public boolean hasConstructor (String className); 1153 1154 1164 abstract public Object getConstructor (String className, 1165 String [] argTypeNames); 1166 1167 1178 abstract public Object getMethod (String className, String methodName, 1179 String [] argTypeNames); 1180 1181 1194 public Object getInheritedMethod (String className, String methodName, 1195 String [] argTypeNames) 1196 { 1197 String superClass = getSuperclass(className); 1198 Object method = null; 1199 1200 while ((superClass != null) && ((method = 1201 getMethod(superClass, methodName, argTypeNames)) == null)) 1202 { 1203 superClass = getSuperclass(superClass); 1204 } 1205 1206 return method; 1207 } 1208 1209 1220 abstract public String getType (Object element); 1221 1222 1229 abstract public Object getField (String className, String fieldName); 1230 1231 1240 public Object getInheritedField (String className, String fieldName) 1241 { 1242 String superClass = getSuperclass(className); 1243 Object field = null; 1244 1245 while ((superClass != null) && 1246 ((field = getField(superClass, fieldName)) == null)) 1247 { 1248 superClass = getSuperclass(superClass); 1249 } 1250 1251 return field; 1252 } 1253 1254 1262 public boolean hasField (String className, String fieldName) 1263 { 1264 return (getField(className, fieldName) != null); 1265 } 1266 1267 1274 public String getFieldType (String className, String fieldName) 1275 { 1276 return getType(getField(className, fieldName)); 1277 } 1278 1279 1290 abstract public boolean isSerializable (Object fieldElement); 1291 1292 1301 public boolean isPrimitive (String className, String fieldName) 1302 { 1303 return isPrimitive(getFieldType(className, fieldName)); 1304 } 1305 1306 1313 protected boolean isPrimitive (String className) 1314 { 1315 return ((className != null) && 1316 JavaTypeHelper.getPrimitiveClass(className) != null); 1317 } 1318 1319 1328 abstract public boolean isArray (String className, String fieldName); 1329 1330 1339 public boolean isByteArray (String className, String fieldName) 1340 { 1341 return isByteArray(getFieldType(className, fieldName)); 1342 } 1343 1344 1350 protected boolean isByteArray (String className) 1351 { 1352 return ("byte[]".equals(className)); } 1354 1355 1361 public boolean isCollection (String className) 1362 { 1363 return _collectionClasses.contains(className); 1364 } 1365 1366 1377 public boolean isSecondClassObject (String className) 1378 { 1379 return _scoClasses.contains(className); 1380 } 1381 1382 1393 public boolean isMutableSecondClassObject (String className) 1394 { 1395 return _mutableScoClasses.contains(className); 1396 } 1397 1398 1412 abstract public String getDeclaringClass (Object memberElement); 1413 1414 1427 abstract public int getModifiers (Object memberElement); 1428 1429 1434 public int getModifiersForClass (String className) 1435 { 1436 return getModifiers(getClass(className)); 1437 } 1438 1439 1447 protected int getModifiers (String className, String fieldName) 1448 { 1449 return getModifiers(getField(className, fieldName)); 1450 } 1451 1452 1468 public boolean isPersistentAllowed (String className, String fieldName) 1469 { 1470 return isPersistentAllowed(className, null, fieldName); 1471 } 1472 1473 1488 public boolean isPersistentAllowed (String className, 1489 ClassLoader classLoader, String fieldName) 1490 { 1491 int modifier = getModifiers(className, fieldName); 1492 1493 if (!Modifier.isStatic(modifier) && !Modifier.isFinal(modifier)) 1494 { 1495 return isPersistentTypeAllowed( 1496 getFieldType(className, fieldName), classLoader); 1497 } 1498 1499 return false; 1500 } 1501 1502 1516 protected boolean isPersistentTypeAllowed (String className, 1517 ClassLoader classLoader) 1518 { 1519 return (isPrimitive(className) || isSecondClassObject(className) || 1520 isByteArray(className) || isPersistent(className, classLoader)); 1521 } 1522 1523 1533 public boolean shouldBePersistent (String className, String fieldName) 1534 { 1535 return !Modifier.isVolatile(getModifiers(className, fieldName)); 1536 } 1537 1538 1546 public PersistenceFieldElement getPersistenceField (String className, 1547 String fieldName) 1548 { 1549 return (hasField(className, fieldName) ? 1550 getPersistenceFieldInternal(className, fieldName) : null); 1551 } 1552 1553 1561 protected PersistenceFieldElement getPersistenceFieldInternal 1562 (String className, String fieldName) 1563 { 1564 PersistenceClassElement classElement = getPersistenceClass(className); 1565 1566 return ((classElement != null) ? 1567 classElement.getField(fieldName) : null); 1568 } 1569 1570 1578 public boolean isPersistent (String className, String fieldName) 1579 { 1580 PersistenceFieldElement fieldElement = 1581 getPersistenceField(className, fieldName); 1582 1583 if (fieldElement != null) 1584 { 1585 return (PersistenceFieldElement.PERSISTENT == 1586 fieldElement.getPersistenceType()); 1587 } 1588 1589 return false; 1590 } 1591 1592 1600 public boolean isKey (String className, String fieldName) 1601 { 1602 if (hasField(className, fieldName)) 1603 { 1604 PersistenceClassElement classElement = 1605 getPersistenceClass(className); 1606 1607 if (classElement != null) 1608 { 1609 String keyClass = classElement.getKeyClass(); 1610 1611 if (keyClass != null) 1612 return hasField(keyClass, fieldName); 1613 } 1614 } 1615 1616 return false; 1617 } 1618 1619 1629 public boolean isValidKeyType (String className, String fieldName) 1630 { 1631 String fieldType = getFieldType(className, fieldName); 1632 1633 if (fieldType == null) 1634 fieldType = getType(getInheritedField(className, fieldName)); 1635 1636 return (isPrimitive(fieldType) || 1637 (isSecondClassObject(fieldType) && !isCollection(fieldType))); 1638 } 1639 1640 1648 public boolean isDefaultFetchGroup (String className, String fieldName) 1649 { 1650 MappingClassElement mappingClass = getMappingClass(className); 1651 1652 try 1653 { 1654 return (MappingFieldElement.GROUP_DEFAULT == 1655 mappingClass.getField(fieldName).getFetchGroup()); 1656 } 1657 catch (Exception e) 1658 {} 1660 return false; 1661 } 1662 1663 1671 public boolean parse (String className) 1672 { 1673 return new ModelValidator(this, className, getMessages()).parseCheck(); 1674 } 1675 1676 1687 public Collection validate (String className, ResourceBundle bundle) 1688 { 1689 return validate(className, null, bundle); 1690 } 1691 1692 1704 public Collection validate (String className, ClassLoader classLoader, 1705 ResourceBundle bundle) 1706 { 1707 return new ModelValidator(this, className, classLoader, 1708 ((bundle == null) ? getMessages() : bundle)).fullValidationCheck(); 1709 } 1710 1711} 1712 1713 | Popular Tags |