| 1 package org.apache.ojb.broker.metadata; 2 3 17 18 import java.io.Serializable ; 19 import java.lang.reflect.Constructor ; 20 import java.lang.reflect.Method ; 21 import java.lang.reflect.Modifier ; 22 import java.sql.Timestamp ; 23 import java.util.ArrayList ; 24 import java.util.Arrays ; 25 import java.util.Collection ; 26 import java.util.Collections ; 27 import java.util.HashMap ; 28 import java.util.Iterator ; 29 import java.util.List ; 30 import java.util.Map ; 31 import java.util.Vector ; 32 33 import org.apache.commons.lang.builder.ToStringBuilder; 34 import org.apache.commons.lang.builder.ToStringStyle; 35 import org.apache.ojb.broker.PersistenceBrokerException; 36 import org.apache.ojb.broker.accesslayer.ConnectionManagerIF; 37 import org.apache.ojb.broker.accesslayer.RowReader; 38 import org.apache.ojb.broker.accesslayer.RowReaderDefaultImpl; 39 import org.apache.ojb.broker.accesslayer.StatementsForClassFactory; 40 import org.apache.ojb.broker.accesslayer.StatementsForClassIF; 41 import org.apache.ojb.broker.core.ValueContainer; 42 import org.apache.ojb.broker.locking.IsolationLevels; 43 import org.apache.ojb.broker.metadata.fieldaccess.PersistentField; 44 import org.apache.ojb.broker.util.ClassHelper; 45 import org.apache.ojb.broker.util.SqlHelper; 46 import org.apache.ojb.broker.util.configuration.Configuration; 47 import org.apache.ojb.broker.util.configuration.Configurator; 48 import org.apache.ojb.broker.util.configuration.impl.OjbConfigurator; 49 import org.apache.ojb.broker.util.logging.LoggerFactory; 50 51 52 63 public final class ClassDescriptor extends DescriptorBase 64 implements Serializable , XmlCapable, IsolationLevels 65 { 66 private String persistentFieldClassName; 67 68 private static final long serialVersionUID = -5212253607374173965L; 69 70 public static final String DYNAMIC_STR = "dynamic"; 71 public static final String OJB_CONCRETE_CLASS = "ojbConcreteClass"; 72 private static final Class [] NO_PARAMS = {}; 73 74 78 private InsertProcedureDescriptor insertProcedure; 79 80 84 private UpdateProcedureDescriptor updateProcedure; 85 86 90 private DeleteProcedureDescriptor deleteProcedure; 91 92 100 private transient Method initializationMethod; 101 private String initializationMethodName; 102 103 private transient Method factoryMethod; 104 private String factoryMethodName; 105 111 private transient boolean alreadyLookedupZeroArguments = false; 112 115 private transient Constructor zeroArgumentConstructor = null; 116 117 120 private transient boolean ojbConcreteFieldCheckDone = false; 121 private transient FieldDescriptor ojbConcreteClassField; 122 126 private transient StatementsForClassIF statementsForClass; 127 131 private DescriptorRepository m_repository; 132 136 private Class factoryClass; 137 private int useIdentityColumn = 0; 138 139 private String baseClass = null; 140 143 private int m_IsolationLevel; 144 147 private String schema = null; 148 151 private Class m_Class = null; 152 155 private boolean isAbstract = false; 156 159 private String m_TableName = null; 160 164 private RowReader m_rowReader = null; 165 169 172 private String superClass; 173 176 private int superClassFieldRef; 177 180 private boolean m_isInterface = false; 181 184 private Class proxyClass = null; 185 188 private String proxyClassName = null; 189 192 private boolean acceptLocks = true; 193 198 private boolean alwaysRefresh = false; 199 private int m_ProxyPrefetchingLimit = 50; 200 203 private ObjectCacheDescriptor objectCacheDescriptor; 204 207 private Vector indexes = new Vector (); 208 209 private FieldDescriptor m_autoIncrementField = null; 215 218 private FieldDescriptor[] m_FieldDescriptions = null; 219 222 private Vector m_CollectionDescriptors = new Vector (); 223 226 private Vector m_ObjectReferenceDescriptors = new Vector (); 227 230 private FieldDescriptor[] m_nonPkFieldDescriptors = null; 231 234 private FieldDescriptor[] m_PkFieldDescriptors = null; 235 238 private FieldDescriptor[] m_RwFieldDescriptors = null; 239 private FieldDescriptor[] m_RwNonPkFieldDescriptors = null; 240 243 private FieldDescriptor[] m_lockingFieldDescriptors = null; 244 247 private Vector extentClasses = new Vector (); 248 251 private Vector extentClassNames = new Vector (); 252 private Map m_fieldDescriptorNameMap = null; 253 private Map m_collectionDescriptorNameMap = null; 254 private Map m_objectReferenceDescriptorsNameMap = null; 255 256 private ClassDescriptor m_superCld = null; 258 private boolean m_superCldSet = false; 259 260 266 267 271 public ClassDescriptor(DescriptorRepository pRepository) 272 { 273 m_repository = pRepository; 274 m_IsolationLevel = pRepository.getDefaultIsolationLevel(); 275 } 276 277 278 public String getBaseClass() 282 { 283 return baseClass; 284 } 285 public void setBaseClass(String baseClass) 286 { 287 this.baseClass = baseClass; 288 getRepository().deregisterSuperClassMultipleJoinedTables(this); 290 getRepository().registerSuperClassMultipleJoinedTables(this); 292 } 293 294 310 314 public ObjectCacheDescriptor getObjectCacheDescriptor() 315 { 316 return objectCacheDescriptor; 317 } 318 319 322 public void setObjectCacheDescriptor(ObjectCacheDescriptor objectCacheDescriptor) 323 { 324 this.objectCacheDescriptor = objectCacheDescriptor; 325 } 326 327 328 331 public void setRowReader(RowReader newReader) 332 { 333 m_rowReader = newReader; 334 } 335 336 340 public synchronized RowReader getRowReader() 341 { 342 if (m_rowReader == null) 343 { 344 Configurator configurator = OjbConfigurator.getInstance(); 345 Configuration config = configurator.getConfigurationFor(null); 346 Class rrClass = config.getClass("RowReaderDefaultClass", RowReaderDefaultImpl.class); 347 348 setRowReader(rrClass.getName()); 349 } 350 return m_rowReader; 351 } 352 353 356 public void setRowReader(String newReaderClassName) 357 { 358 try 359 { 360 m_rowReader = 361 (RowReader) ClassHelper.newInstance( 362 newReaderClassName, 363 ClassDescriptor.class, 364 this); 365 } 366 catch (Exception e) 367 { 368 throw new MetadataException("Instantiating of current set RowReader failed", e); 369 } 370 } 371 372 public String getRowReaderClassName() 373 { 374 return m_rowReader != null ? m_rowReader.getClass().getName() : null; 375 } 376 377 381 public String getClassNameOfObject() 382 { 383 return m_Class != null ? m_Class.getName() : null; 384 } 385 386 390 public Class getClassOfObject() 391 { 392 return m_Class; 393 } 394 395 399 public void setClassOfObject(Class c) 400 { 401 m_Class = c; 402 isAbstract = Modifier.isAbstract(m_Class.getModifiers()); 403 } 405 406 410 public void addFieldDescriptor(FieldDescriptor fld) 411 { 412 fld.setClassDescriptor(this); if (m_FieldDescriptions == null) 414 { 415 m_FieldDescriptions = new FieldDescriptor[1]; 416 m_FieldDescriptions[0] = fld; 417 } 418 else 419 { 420 int size = m_FieldDescriptions.length; 421 FieldDescriptor[] tmpArray = new FieldDescriptor[size + 1]; 422 System.arraycopy(m_FieldDescriptions, 0, tmpArray, 0, size); 423 tmpArray[size] = fld; 424 m_FieldDescriptions = tmpArray; 425 Arrays.sort(m_FieldDescriptions, FieldDescriptor.getComparator()); 427 } 428 429 m_fieldDescriptorNameMap = null; 430 m_PkFieldDescriptors = null; 431 m_nonPkFieldDescriptors = null; 432 m_lockingFieldDescriptors = null; 433 m_RwFieldDescriptors = null; 434 m_RwNonPkFieldDescriptors = null; 435 } 436 437 public boolean removeFieldDescriptor(FieldDescriptor fld) 438 { 439 boolean result = false; 440 if(m_FieldDescriptions == null) return result; 441 442 List list = new ArrayList (Arrays.asList(m_FieldDescriptions)); 443 result = list.remove(fld); 444 m_FieldDescriptions = (FieldDescriptor[]) list.toArray(new FieldDescriptor[list.size()]); 445 446 m_fieldDescriptorNameMap = null; 447 m_PkFieldDescriptors = null; 448 m_nonPkFieldDescriptors = null; 449 m_lockingFieldDescriptors = null; 450 m_RwFieldDescriptors = null; 451 m_RwNonPkFieldDescriptors = null; 452 return result; 453 } 454 455 459 public Vector getCollectionDescriptors() 460 { 461 return m_CollectionDescriptors; 462 } 463 464 467 public void addCollectionDescriptor(CollectionDescriptor cod) 468 { 469 m_CollectionDescriptors.add(cod); 470 cod.setClassDescriptor(this); 472 m_collectionDescriptorNameMap = null; 473 } 474 475 public void removeCollectionDescriptor(CollectionDescriptor cod) 476 { 477 m_CollectionDescriptors.remove(cod); 478 m_collectionDescriptorNameMap = null; 479 } 480 481 484 public Vector getObjectReferenceDescriptors() 485 { 486 return m_ObjectReferenceDescriptors; 487 } 488 489 492 public void addObjectReferenceDescriptor(ObjectReferenceDescriptor ord) 493 { 494 m_ObjectReferenceDescriptors.add(ord); 495 ord.setClassDescriptor(this); 497 m_objectReferenceDescriptorsNameMap = null; 498 } 499 500 public void removeObjectReferenceDescriptor(ObjectReferenceDescriptor ord) 501 { 502 m_ObjectReferenceDescriptors.remove(ord); 503 m_objectReferenceDescriptorsNameMap = null; 504 } 505 506 511 public ObjectReferenceDescriptor getObjectReferenceDescriptorByName(String name) 512 { 513 ObjectReferenceDescriptor ord = (ObjectReferenceDescriptor) 514 getObjectReferenceDescriptorsNameMap().get(name); 515 516 if (ord == null) 521 { 522 ClassDescriptor superCld = getSuperClassDescriptor(); 523 if (superCld != null) 524 { 525 ord = superCld.getObjectReferenceDescriptorByName(name); 526 } 527 } 528 return ord; 529 } 530 531 private Map getObjectReferenceDescriptorsNameMap() 532 { 533 if (m_objectReferenceDescriptorsNameMap == null) 534 { 535 HashMap nameMap = new HashMap (); 536 537 Vector descriptors = getObjectReferenceDescriptors(); 538 for (int i = descriptors.size() - 1; i >= 0; i--) 539 { 540 ObjectReferenceDescriptor ord = (ObjectReferenceDescriptor) descriptors.get(i); 541 nameMap.put(ord.getAttributeName(), ord); 542 } 543 m_objectReferenceDescriptorsNameMap = nameMap; 544 } 545 546 return m_objectReferenceDescriptorsNameMap; 547 } 548 549 554 public CollectionDescriptor getCollectionDescriptorByName(String name) 555 { 556 if (name == null) 557 { 558 return null; 559 } 560 561 CollectionDescriptor cod = (CollectionDescriptor) getCollectionDescriptorNameMap().get(name); 562 563 if (cod == null) 568 { 569 ClassDescriptor superCld = getSuperClassDescriptor(); 570 if (superCld != null) 571 { 572 cod = superCld.getCollectionDescriptorByName(name); 573 } 574 } 575 576 return cod; 577 } 578 579 private Map getCollectionDescriptorNameMap() 580 { 581 if (m_collectionDescriptorNameMap == null) 582 { 583 HashMap nameMap = new HashMap (); 584 585 Vector descriptors = getCollectionDescriptors(); 586 for (int i = descriptors.size() - 1; i >= 0; i--) 587 { 588 CollectionDescriptor cod = (CollectionDescriptor) descriptors.get(i); 589 nameMap.put(cod.getAttributeName(), cod); 590 } 591 m_collectionDescriptorNameMap = nameMap; 592 } 593 594 return m_collectionDescriptorNameMap; 595 } 596 597 601 public ClassDescriptor getSuperClassDescriptor() 602 { 603 if (!m_superCldSet) 604 { 605 if(getBaseClass() != null) 606 { 607 m_superCld = getRepository().getDescriptorFor(getBaseClass()); 608 if(m_superCld.isAbstract() || m_superCld.isInterface()) 609 { 610 throw new MetadataException("Super class mapping only work for real class, but declared super class" + 611 " is an interface or is abstract. Declared class: " + m_superCld.getClassNameOfObject()); 612 } 613 } 614 m_superCldSet = true; 615 } 616 617 return m_superCld; 618 } 619 620 625 public void addExtentClassName(Class newExtendClass) 626 { 627 addExtentClass(newExtendClass); 628 } 629 630 634 public void addExtentClass(Class newExtendClass) 635 { 636 extentClasses.add(newExtendClass); 637 this.addExtentClass(newExtendClass.getName()); 638 } 639 640 644 public void addExtentClass(String newExtentClassName) 645 { 646 extentClassNames.add(newExtentClassName); 647 if(m_repository != null) m_repository.addExtent(newExtentClassName, this); 648 } 649 650 public void removeExtentClass(String extentClassName) 651 { 652 extentClassNames.remove(extentClassName); 653 if(m_repository != null) m_repository.removeExtent(extentClassName); 654 } 655 656 661 public synchronized Vector getExtentClasses() 662 { 663 if (extentClassNames.size() != extentClasses.size()) 664 { 665 extentClasses.clear(); 666 for (Iterator iter = extentClassNames.iterator(); iter.hasNext();) 667 { 668 String classname = (String ) iter.next(); 669 Class extentClass; 670 try 671 { 672 extentClass = ClassHelper.getClass(classname); 673 } 674 catch (ClassNotFoundException e) 675 { 676 throw new MetadataException( 677 "Unable to load class [" 678 + classname 679 + "]. Make sure it is available on the classpath.", 680 e); 681 } 682 extentClasses.add(extentClass); 683 } 684 } 685 return extentClasses; 686 } 687 688 689 694 public synchronized Vector getExtentClassNames() 695 { 696 return this.extentClassNames; 697 } 698 699 704 public boolean isExtent() 705 { 706 return (getExtentClassNames().size() > 0); 707 } 708 709 714 public synchronized Class getProxyClass() 715 { 716 if ((proxyClass == null) && (proxyClassName != null)) 717 { 718 if (isDynamicProxy()) 719 { 720 725 return getClassOfObject(); 726 } 727 else 728 { 729 try 730 { 731 proxyClass = ClassHelper.getClass(proxyClassName); 732 } 733 catch (ClassNotFoundException e) 734 { 735 throw new MetadataException(e); 736 } 737 } 738 } 739 return proxyClass; 740 } 741 742 public boolean isDynamicProxy() 743 { 744 return DYNAMIC_STR.equalsIgnoreCase(proxyClassName); 745 } 746 747 751 public void setProxyClass(Class newProxyClass) 752 { 753 proxyClass = newProxyClass; 754 if (proxyClass == null) 755 { 756 setProxyClassName(null); 757 } 758 else 759 { 760 proxyClassName = proxyClass.getName(); 761 } 762 } 763 764 770 public void setProxyClassName(String newProxyClassName) 771 { 772 proxyClassName = newProxyClassName; 773 } 774 775 779 public String getProxyClassName() 780 { 781 return proxyClassName; 782 } 783 784 787 public FieldDescriptor[] getFieldDescriptions() 788 { 789 return m_FieldDescriptions; 790 } 791 792 795 public FieldDescriptor getFieldDescriptorByIndex(int index) 796 { 797 return m_FieldDescriptions[index - 1]; 798 } 799 800 805 public FieldDescriptor getFieldDescriptorByName(String name) 806 { 807 if (name == null || m_FieldDescriptions == null) 808 { 809 return null; 810 } 811 812 if (m_fieldDescriptorNameMap == null) 813 { 814 HashMap nameMap = new HashMap (); 815 816 FieldDescriptor[] descriptors = getFieldDescriptions(); 817 for (int i = descriptors.length - 1; i >= 0; i--) 818 { 819 FieldDescriptor fld = descriptors[i]; 820 nameMap.put(fld.getPersistentField().getName(), fld); 821 } 822 823 m_fieldDescriptorNameMap = nameMap; 824 } 825 826 return (FieldDescriptor) m_fieldDescriptorNameMap.get(name); 827 } 828 829 839 public FieldDescriptor getFieldDescriptorForPath(String aPath, Map pathHints) 840 { 841 ArrayList desc = getAttributeDescriptorsForPath(aPath, pathHints); 842 FieldDescriptor fld = null; 843 Object temp; 844 845 if (!desc.isEmpty()) 846 { 847 temp = desc.get(desc.size() - 1); 848 if (temp instanceof FieldDescriptor) 849 { 850 fld = (FieldDescriptor) temp; 851 } 852 } 853 return fld; 854 } 855 856 864 public FieldDescriptor getFieldDescriptorForPath(String aPath) 865 { 866 return getFieldDescriptorForPath(aPath, null); 867 } 868 872 |