KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > ojb > broker > metadata > ClassDescriptor


1 package org.apache.ojb.broker.metadata;
2
3 /* Copyright 2002-2005 The Apache Software Foundation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 import java.io.Serializable JavaDoc;
19 import java.lang.reflect.Constructor JavaDoc;
20 import java.lang.reflect.Method JavaDoc;
21 import java.lang.reflect.Modifier JavaDoc;
22 import java.sql.Timestamp JavaDoc;
23 import java.util.ArrayList JavaDoc;
24 import java.util.Arrays JavaDoc;
25 import java.util.Collection JavaDoc;
26 import java.util.Collections JavaDoc;
27 import java.util.HashMap JavaDoc;
28 import java.util.Iterator JavaDoc;
29 import java.util.List JavaDoc;
30 import java.util.Map JavaDoc;
31 import java.util.Vector JavaDoc;
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 /**
53  * A ClassDescriptor contains all information for mapping objects of a
54  * given class to database tables.
55  * <br>
56  * Note: Be careful when use ClassDescriptor variables or caching
57  * ClassDescriptor instances, because instances could become invalid
58  * during runtime (see {@link MetadataManager}).
59  *
60  * @author <a HREF="mailto:thma@apache.org">Thomas Mahler<a>
61  * @version $Id: ClassDescriptor.java,v 1.88.2.21 2005/12/21 22:26:10 tomdz Exp $
62  */

63 public final class ClassDescriptor extends DescriptorBase
64     implements Serializable JavaDoc, XmlCapable, IsolationLevels
65 {
66     private String JavaDoc persistentFieldClassName;
67
68     private static final long serialVersionUID = -5212253607374173965L;
69
70     public static final String JavaDoc DYNAMIC_STR = "dynamic";
71     public static final String JavaDoc OJB_CONCRETE_CLASS = "ojbConcreteClass";
72     private static final Class JavaDoc[] NO_PARAMS = {};
73
74     //---------------------------------------------------------------
75
/**
76      * The descriptor for the insert procedure/function.
77      */

78     private InsertProcedureDescriptor insertProcedure;
79
80     //---------------------------------------------------------------
81
/**
82      * The descriptor for the update procedure/function.
83      */

84     private UpdateProcedureDescriptor updateProcedure;
85
86     //---------------------------------------------------------------
87
/**
88      * The descriptor for the delete procedure/function.
89      */

90     private DeleteProcedureDescriptor deleteProcedure;
91
92     //---------------------------------------------------------------
93
// transient fields, to make this class serializable we have to declare
94
// some transient fields and some associated string fields to reinitialze
95
// transient fields after serialization
96
//---------------------------------------------------------------
97
/**
98      * optional method to be invoked after instance fields are initialized
99      */

100     private transient Method JavaDoc initializationMethod;
101     private String JavaDoc initializationMethodName;
102
103     private transient Method JavaDoc factoryMethod;
104     private String JavaDoc factoryMethodName;
105     /**
106      * whether we have already tried to look up the zero
107      * argument constructor. Transient declared, because
108      * {@link Constructor} is transient and we need to
109      * reinitialize constructor after serialization.
110      */

111     private transient boolean alreadyLookedupZeroArguments = false;
112     /**
113      * the zero argument constructor for this class
114      */

115     private transient Constructor JavaDoc zeroArgumentConstructor = null;
116
117     /**
118      * used to signal use of ojbConcreteClass field
119      */

120     private transient boolean ojbConcreteFieldCheckDone = false;
121     private transient FieldDescriptor ojbConcreteClassField;
122     /**
123      * We have to bound {@link org.apache.ojb.broker.accesslayer.StatementsForClassIF}
124      * instance to this class, because metadata may change.
125      */

126     private transient StatementsForClassIF statementsForClass;
127     //---------------------------------------------------------------
128
// end transient fields
129
//---------------------------------------------------------------
130

131     private DescriptorRepository m_repository;
132     /**
133      * optional class.method to be invoked to create object instance. Both
134      * of these must be present for this function to be successful.
135      */

136     private Class JavaDoc factoryClass;
137     private int useIdentityColumn = 0;
138
139     private String JavaDoc baseClass = null;
140     /**
141      * transaction isolation level specified for this class, used in the ODMG server
142      */

143     private int m_IsolationLevel;
144     /**
145      * the SQL SCHEMA of the underlying table of this class
146      */

147     private String JavaDoc schema = null;
148     /**
149      * the described class
150      */

151     private Class JavaDoc m_Class = null;
152     /**
153      * whether the described class is abstract
154      */

155     private boolean isAbstract = false;
156     /**
157      * the table name used to store the scalar attributes of this class
158      */

159     private String JavaDoc m_TableName = null;
160 // private Vector superPersistentFieldDescriptors = null;
161
/**
162      * the RowReader for this class
163      */

164     private RowReader m_rowReader = null;
165 /*
166 arminw:
167 TODO: this feature doesn't work, so remove/reuse this in future
168 */

169     /**
170      * the class that this class extends
171      */

172     private String JavaDoc superClass;
173     /**
174      * reference column for the superclass
175      */

176     private int superClassFieldRef;
177     /**
178      * does the described class represent an interface?
179      */

180     private boolean m_isInterface = false;
181     /**
182      * the proxy class for the described class, may be null
183      */

184     private Class JavaDoc proxyClass = null;
185     /**
186      * the proxy class name for the described class, may be null
187      */

188     private String JavaDoc proxyClassName = null;
189     /**
190      * if false do not accept implicit locks on this class
191      */

192     private boolean acceptLocks = true;
193     /**
194      * if true instances of this class are always refreshed
195      * even if they are already in the cache.
196      * false by default.
197      */

198     private boolean alwaysRefresh = false;
199     private int m_ProxyPrefetchingLimit = 50;
200     /**
201      * optional, ObjectCacheDescriptor for representing class
202      */

203     private ObjectCacheDescriptor objectCacheDescriptor;
204     /**
205      * the vector of indices used in DDL generation.
206      */

207     private Vector JavaDoc indexes = new Vector JavaDoc();
208
209     //-----------------------------------------------------------------
210
//-----------------------------------------------------------------
211
// !!! the following arrays and maps have take care of metadata changes!!!
212
//-----------------------------------------------------------------
213
//-----------------------------------------------------------------
214
private FieldDescriptor m_autoIncrementField = null;
215     /**
216      * the FieldDescriptors for the primitive attributes
217      */

218     private FieldDescriptor[] m_FieldDescriptions = null;
219     /**
220      * the descriptors for collection attributes
221      */

222     private Vector JavaDoc m_CollectionDescriptors = new Vector JavaDoc();
223     /**
224      * the descriptor for 1-1 reference attributes
225      */

226     private Vector JavaDoc m_ObjectReferenceDescriptors = new Vector JavaDoc();
227     /**
228      * the non-primary key FieldDescriptors
229      */

230     private FieldDescriptor[] m_nonPkFieldDescriptors = null;
231     /**
232      * the primary key FieldDescriptors
233      */

234     private FieldDescriptor[] m_PkFieldDescriptors = null;
235     /**
236      * the read/write FieldDescriptors BRJ
237      */

238     private FieldDescriptor[] m_RwFieldDescriptors = null;
239     private FieldDescriptor[] m_RwNonPkFieldDescriptors = null;
240     /**
241      * the optimistic lockingFieldDescriptors BRJ
242      */

243     private FieldDescriptor[] m_lockingFieldDescriptors = null;
244     /**
245      * the list of classes in the extent of this class. can be empty
246      */

247     private Vector JavaDoc extentClasses = new Vector JavaDoc();
248     /**
249      * the list of class names in the extent of this class. can be empty
250      */

251     private Vector JavaDoc extentClassNames = new Vector JavaDoc();
252     private Map JavaDoc m_fieldDescriptorNameMap = null;
253     private Map JavaDoc m_collectionDescriptorNameMap = null;
254     private Map JavaDoc m_objectReferenceDescriptorsNameMap = null;
255
256     // BRJ: ClassDescriptor referenced by 'super' ObjectReferenceDescriptor
257
private ClassDescriptor m_superCld = null;
258     private boolean m_superCldSet = false;
259
260     //-----------------------------------------------------------------
261
//-----------------------------------------------------------------
262
// END of cached metadata information
263
//-----------------------------------------------------------------
264
//-----------------------------------------------------------------
265

266
267     //---------------------------------------------------------------
268
/**
269      * Constructor declaration
270      */

271     public ClassDescriptor(DescriptorRepository pRepository)
272     {
273         m_repository = pRepository;
274         m_IsolationLevel = pRepository.getDefaultIsolationLevel();
275     }
276
277
278     //---------------------------------------------------------------
279
// method declarations
280
//---------------------------------------------------------------
281
public String JavaDoc getBaseClass()
282     {
283         return baseClass;
284     }
285     public void setBaseClass(String JavaDoc baseClass)
286     {
287         this.baseClass = baseClass;
288         // first deregister
289
getRepository().deregisterSuperClassMultipleJoinedTables(this);
290         // register classes using mapping of classes to multiple joined tables
291
getRepository().registerSuperClassMultipleJoinedTables(this);
292     }
293
294 // /**
295
// * @deprecated no longer needed map class on multi joined table
296
// */
297
// public void setSuperPersistentFieldDescriptors(Vector superPersistentFieldDescriptors)
298
// {
299
// this.superPersistentFieldDescriptors = superPersistentFieldDescriptors;
300
// }
301
//
302
// /**
303
// * @deprecated no longer needed map class on multi joined table
304
// */
305
// public Vector getSuperPersistentFieldDescriptors()
306
// {
307
// return superPersistentFieldDescriptors;
308
// }
309

310     /**
311      * Returns the appropriate {@link ObjectCacheDescriptor}
312      * or <code>null</code> if not specified.
313      */

314     public ObjectCacheDescriptor getObjectCacheDescriptor()
315     {
316         return objectCacheDescriptor;
317     }
318
319     /**
320      * Sets the {@link ObjectCacheDescriptor} for representing class.
321      */

322     public void setObjectCacheDescriptor(ObjectCacheDescriptor objectCacheDescriptor)
323     {
324         this.objectCacheDescriptor = objectCacheDescriptor;
325     }
326
327
328     /**
329      * sets the row reader class for this descriptor
330      */

331     public void setRowReader(RowReader newReader)
332     {
333         m_rowReader = newReader;
334     }
335
336     /**
337      * Returns the {@link org.apache.ojb.broker.accesslayer.RowReader}
338      * for this descriptor.
339      */

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 JavaDoc rrClass = config.getClass("RowReaderDefaultClass", RowReaderDefaultImpl.class);
347
348             setRowReader(rrClass.getName());
349         }
350         return m_rowReader;
351     }
352
353     /**
354      * sets the row reader class name for thie class descriptor
355      */

356     public void setRowReader(String JavaDoc newReaderClassName)
357     {
358         try
359         {
360             m_rowReader =
361                 (RowReader) ClassHelper.newInstance(
362                     newReaderClassName,
363                     ClassDescriptor.class,
364                     this);
365         }
366         catch (Exception JavaDoc e)
367         {
368             throw new MetadataException("Instantiating of current set RowReader failed", e);
369         }
370     }
371
372     public String JavaDoc getRowReaderClassName()
373     {
374         return m_rowReader != null ? m_rowReader.getClass().getName() : null;
375     }
376
377     /**
378      * returns the name of the described class
379      * @return String name of the described class
380      */

381     public String JavaDoc getClassNameOfObject()
382     {
383         return m_Class != null ? m_Class.getName() : null;
384     }
385
386     /**
387      * returns the class object of the described class
388      * @return Class the described class
389      */

390     public Class JavaDoc getClassOfObject()
391     {
392         return m_Class;
393     }
394
395     /**
396      * sets the class object described by this descriptor.
397      * @param c the class to describe
398      */

399     public void setClassOfObject(Class JavaDoc c)
400     {
401         m_Class = c;
402         isAbstract = Modifier.isAbstract(m_Class.getModifiers());
403         // TODO : Shouldn't the HashMap in DescriptorRepository be updated as well?
404
}
405
406     /**
407      * adds a FIELDDESCRIPTOR to this ClassDescriptor.
408      * @param fld
409      */

410     public void addFieldDescriptor(FieldDescriptor fld)
411     {
412         fld.setClassDescriptor(this); // BRJ
413
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             // 2. Sort fields according to their getOrder() Property
426
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 JavaDoc list = new ArrayList JavaDoc(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     /**
456      * Returns all defined {@link CollectionDescriptor} for
457      * this class descriptor.
458      */

459     public Vector JavaDoc getCollectionDescriptors()
460     {
461         return m_CollectionDescriptors;
462     }
463
464     /**
465      * Add a {@link CollectionDescriptor}.
466      */

467     public void addCollectionDescriptor(CollectionDescriptor cod)
468     {
469         m_CollectionDescriptors.add(cod);
470         cod.setClassDescriptor(this); // BRJ
471

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     /**
482      * Returns all defined {@link ObjectReferenceDescriptor}.
483      */

484     public Vector JavaDoc getObjectReferenceDescriptors()
485     {
486         return m_ObjectReferenceDescriptors;
487     }
488
489     /**
490      * Add a {@link ObjectReferenceDescriptor}.
491      */

492     public void addObjectReferenceDescriptor(ObjectReferenceDescriptor ord)
493     {
494         m_ObjectReferenceDescriptors.add(ord);
495         ord.setClassDescriptor(this); // BRJ
496

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     /**
507      * Get an ObjectReferenceDescriptor by name BRJ
508      * @param name
509      * @return ObjectReferenceDescriptor or null
510      */

511     public ObjectReferenceDescriptor getObjectReferenceDescriptorByName(String JavaDoc name)
512     {
513         ObjectReferenceDescriptor ord = (ObjectReferenceDescriptor)
514             getObjectReferenceDescriptorsNameMap().get(name);
515
516         //
517
// BRJ: if the ReferenceDescriptor is not found
518
// look in the ClassDescriptor referenced by 'super' for it
519
//
520
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 JavaDoc getObjectReferenceDescriptorsNameMap()
532     {
533         if (m_objectReferenceDescriptorsNameMap == null)
534         {
535             HashMap JavaDoc nameMap = new HashMap JavaDoc();
536
537             Vector JavaDoc 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     /**
550      * Get an CollectionDescriptor by name BRJ
551      * @param name
552      * @return CollectionDescriptor or null
553      */

554     public CollectionDescriptor getCollectionDescriptorByName(String JavaDoc name)
555     {
556         if (name == null)
557         {
558             return null;
559         }
560
561         CollectionDescriptor cod = (CollectionDescriptor) getCollectionDescriptorNameMap().get(name);
562
563         //
564
// BRJ: if the CollectionDescriptor is not found
565
// look in the ClassDescriptor referenced by 'super' for it
566
//
567
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 JavaDoc getCollectionDescriptorNameMap()
580     {
581         if (m_collectionDescriptorNameMap == null)
582         {
583             HashMap JavaDoc nameMap = new HashMap JavaDoc();
584
585             Vector JavaDoc 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     /**
598      * Answers the ClassDescriptor referenced by 'super' ReferenceDescriptor.
599      * @return ClassDescriptor or null
600      */

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     /**
621      * add an Extent class to the current descriptor
622      * @param newExtendClass
623      * @deprecated use {@link #addExtentClass(String newExtentClass)} instead
624      */

625     public void addExtentClassName(Class JavaDoc newExtendClass)
626     {
627         addExtentClass(newExtendClass);
628     }
629
630     /**
631      * add an Extent class to the current descriptor
632      * @param newExtendClass
633      */

634     public void addExtentClass(Class JavaDoc newExtendClass)
635     {
636         extentClasses.add(newExtendClass);
637         this.addExtentClass(newExtendClass.getName());
638     }
639
640     /**
641      * add an Extent class to the current descriptor
642      * @param newExtentClassName name of the class to add
643      */

644     public void addExtentClass(String JavaDoc newExtentClassName)
645     {
646         extentClassNames.add(newExtentClassName);
647         if(m_repository != null) m_repository.addExtent(newExtentClassName, this);
648     }
649
650     public void removeExtentClass(String JavaDoc extentClassName)
651     {
652         extentClassNames.remove(extentClassName);
653         if(m_repository != null) m_repository.removeExtent(extentClassName);
654     }
655
656     /**
657      * return all classes in this extent.
658      * Creation date: (02.02.2001 17:49:11)
659      * @return java.util.Vector
660      */

661     public synchronized Vector JavaDoc getExtentClasses()
662     {
663         if (extentClassNames.size() != extentClasses.size())
664         {
665             extentClasses.clear();
666             for (Iterator JavaDoc iter = extentClassNames.iterator(); iter.hasNext();)
667             {
668                 String JavaDoc classname = (String JavaDoc) iter.next();
669                 Class JavaDoc extentClass;
670                 try
671                 {
672                     extentClass = ClassHelper.getClass(classname);
673                 }
674                 catch (ClassNotFoundException JavaDoc 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     /**
690      * Return the names of all classes in this extent
691      * @return java.util.Vector a Vector containing the fully qualified names
692      * of all classes in this extent
693      */

694     public synchronized Vector JavaDoc getExtentClassNames()
695     {
696         return this.extentClassNames;
697     }
698
699     /**
700      * Insert the method's description here.
701      * Creation date: (02.02.2001 17:49:11)
702      * @return boolean
703      */

704     public boolean isExtent()
705     {
706         return (getExtentClassNames().size() > 0);
707     }
708
709     /**
710      * Insert the method's description here.
711      * Creation date: (26.01.2001 09:20:09)
712      * @return java.lang.Class
713      */

714     public synchronized Class JavaDoc getProxyClass()
715     {
716         if ((proxyClass == null) && (proxyClassName != null))
717         {
718             if (isDynamicProxy())
719             {
720                 /**
721                  * AClute: Return the same class back if it is dynamic. This signifies
722                  * that this class become the base to a generated sub-class, regadless
723                  * of which Proxy implementation is used
724                  */

725                 return getClassOfObject();
726             }
727             else
728             {
729                 try
730                 {
731                     proxyClass = ClassHelper.getClass(proxyClassName);
732                 }
733                 catch (ClassNotFoundException JavaDoc 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     /**
748      * Sets the proxy class to be used.
749      * @param newProxyClass java.lang.Class
750      */

751     public void setProxyClass(Class JavaDoc 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     /**
765      * Sets the name of the proxy class to be used.
766      * using "dynamic" instead of a real classname
767      * will result in usage of dynamic proxies.
768      * @param newProxyClassName the classname or "dynamic"
769      */

770     public void setProxyClassName(String JavaDoc newProxyClassName)
771     {
772         proxyClassName = newProxyClassName;
773     }
774
775     /**
776      * Get the name of the proxy class. This method doesn't try to access
777      * the real class, so it can be called even if the class doesn't exist.
778      */

779     public String JavaDoc getProxyClassName()
780     {
781         return proxyClassName;
782     }
783
784     /**
785      * Returns array of all FieldDescriptors.
786      */

787     public FieldDescriptor[] getFieldDescriptions()
788     {
789         return m_FieldDescriptions;
790     }
791
792     /**
793      * Returns the matching {@link FieldDescriptor}.
794      */

795     public FieldDescriptor getFieldDescriptorByIndex(int index)
796     {
797         return m_FieldDescriptions[index - 1];
798     }
799
800     /**
801      * Returns the matching {@link FieldDescriptor} - only fields
802      * of the current class will be scanned, to include fields defined
803      * the the super-classes too, use method {@link #getFieldDescriptor(boolean)}.
804      */

805     public FieldDescriptor getFieldDescriptorByName(String JavaDoc name)
806     {
807         if (name == null || m_FieldDescriptions == null)
808         {
809             return null;
810         }
811
812         if (m_fieldDescriptorNameMap == null)
813         {
814             HashMap JavaDoc nameMap = new HashMap JavaDoc();
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     /**
830      * return the FieldDescriptor for the Attribute referenced in the path<br>
831      * the path may contain simple attribut names, functions and path expressions
832      * using relationships <br>
833      * ie: name, avg(price), adress.street
834      * @param aPath the path to the attribute
835      * @param pathHints a Map containing the class to be used for a segment or <em>null</em>
836      * if no segment was used.
837      * @return the FieldDescriptor or null (ie: for m:n queries)
838      */

839     public FieldDescriptor getFieldDescriptorForPath(String JavaDoc aPath, Map JavaDoc pathHints)
840     {
841         ArrayList JavaDoc desc = getAttributeDescriptorsForPath(aPath, pathHints);
842         FieldDescriptor fld = null;
843         Object JavaDoc 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     /**
857      * return the FieldDescriptor for the Attribute referenced in the path<br>
858      * the path may contain simple attribut names, functions and path expressions
859      * using relationships <br>
860      * ie: name, avg(price), adress.street
861      * @param aPath the path to the attribute
862      * @return the FieldDescriptor or null (ie: for m:n queries)
863      */

864     public FieldDescriptor getFieldDescriptorForPath(String JavaDoc aPath)
865     {
866         return getFieldDescriptorForPath(aPath, null);
867     }
868 /*
869 arminw:
870 TODO: this feature doesn't work, so remove this in future
871 */

872     /**
873      *
874      * @return this classes FieldDescriptor's as well as it's parents and so on and so on
875      */

876     public FieldDescriptor[] getFieldDescriptorsInHeirarchy()
877     {
878         if (superClass == null)
879         {
880             return getFieldDescriptions();
881         }
882         ClassDescriptor cldSuper = getRepository().getDescriptorFor(superClass);
883         return appendFieldDescriptorArrays(
884             getFieldDescriptions(),
885             cldSuper.getFieldDescriptorsInHeirarchy());
886     }
887
888     private FieldDescriptor[] appendFieldDescriptorArrays(
889         FieldDescriptor[] fieldDescriptions,
890         FieldDescriptor[] fieldDescriptorsInHeirarchy)
891     {
892         // take the 2 arrays and add them into one
893
int size = fieldDescriptions.length + fieldDescriptorsInHeirarchy.length;
894         FieldDescriptor[] newArray = new FieldDescriptor[size];
895         System.arraycopy(fieldDescriptions, 0, newArray, 0, fieldDescriptions.length);
896         System.arraycopy(fieldDescriptorsInHeirarchy, 0, newArray, fieldDescriptions.length, fieldDescriptorsInHeirarchy.length);
897         return newArray;
898     }
899
900     /**
901      * Returns the first found autoincrement field
902      * defined in this class descriptor. Use carefully
903      * when multiple autoincrement field were defined.
904      * @deprecated does not make sense because it's possible to
905      * define more than one autoincrement field. Alternative
906      * see {@link #getAutoIncrementFields}
907      */

908     public FieldDescriptor getAutoIncrementField()
909     {
910         if (m_autoIncrementField == null)
911         {
912             FieldDescriptor[] fds = getPkFields();
913
914             for (int i = 0; i < fds.length; i++)
915             {
916                 FieldDescriptor fd = fds[i];
917                 if (fd.isAutoIncrement())
918                 {
919                     m_autoIncrementField = fd;
920                     break;
921                 }
922             }
923         }
924         if (m_autoIncrementField == null)
925         {
926             LoggerFactory.getDefaultLogger().warn(
927                 this.getClass().getName()
928                     + ": "
929                     + "Could not find autoincrement attribute for class: "
930                     + this.getClassNameOfObject());
931         }
932         return m_autoIncrementField;
933     }
934
935     public FieldDescriptor[] getAutoIncrementFields()
936     {
937         ArrayList JavaDoc result = new ArrayList JavaDoc();
938         for (int i = 0; i < m_FieldDescriptions.length; i++)
939         {
940             FieldDescriptor field = m_FieldDescriptions[i];
941             if(field.isAutoIncrement()) result.add(field);
942         }
943         return (FieldDescriptor[]) result.toArray(new FieldDescriptor[result.size()]);
944     }
945
946     /**
947      * returns an Array with an Objects CURRENT locking VALUES , BRJ
948      * @throws PersistenceBrokerException if there is an erros accessing o field values
949      */

950     public ValueContainer[] getCurrentLockingValues(Object JavaDoc o) throws PersistenceBrokerException
951     {
952         FieldDescriptor[] fields = getLockingFields();
953         ValueContainer[] result = new ValueContainer[fields.length];
954         for (int i = 0; i < result.length; i++)
955         {
956             result[i] = new ValueContainer(fields[i].getPersistentField().get(o), fields[i].getJdbcType());
957         }
958         return result;
959     }
960
961     /**
962      * updates the values for locking fields , BRJ
963      * handles int, long, Timestamp
964      * respects updateLock so locking field are only updated when updateLock is true
965      * @throws PersistenceBrokerException if there is an erros accessing obj field values
966      */

967     public void updateLockingValues(Object JavaDoc obj) throws PersistenceBrokerException
968     {
969         FieldDescriptor[] fields = getLockingFields();
970         for (int i = 0; i < fields.length; i++)
971         {
972             FieldDescriptor fmd = fields[i];
973             if (fmd.isUpdateLock())
974             {
975                 PersistentField f = fmd.getPersistentField();
976                 Object JavaDoc cv = f.get(obj);
977                 // int
978
if ((f.getType() == int.class) || (f.getType() == Integer JavaDoc.class))
979                 {
980                     int newCv = 0;
981                     if (cv != null)
982                     {
983                         newCv = ((Number JavaDoc) cv).intValue();
984                     }
985                     newCv++;
986                     f.set(obj, new Integer JavaDoc(newCv));
987                 }
988                 // long
989
else if ((f.getType() == long.class) || (f.getType() == Long JavaDoc.class))
990                 {
991                     long newCv = 0;
992                     if (cv != null)
993                     {
994                         newCv = ((Number JavaDoc) cv).longValue();
995                     }
996                     newCv++;
997                     f.set(obj, new Long JavaDoc(newCv));
998                 }
999                 // Timestamp
1000
else if (f.getType() == Timestamp JavaDoc.class)
1001                {
1002                    long newCv = System.currentTimeMillis();
1003                    f.set(obj, new Timestamp JavaDoc(newCv));
1004                }
1005            }
1006        }
1007    }
1008
1009    /**
1010     * return an array of NONPK-FieldDescription sorted ascending
1011     * according to the field-descriptions getOrder() property
1012     */

1013    public FieldDescriptor[] getNonPkFields()
1014    {
1015        if (m_nonPkFieldDescriptors == null)
1016        {
1017            // 1. collect all Primary Key fields from Field list
1018
Vector JavaDoc vec = new Vector JavaDoc();
1019            for (int i = 0; i < m_FieldDescriptions.length; i++)
1020            {
1021                FieldDescriptor fd = m_FieldDescriptions[i];
1022                if (!fd.isPrimaryKey())
1023                {
1024                    vec.add(fd);
1025                }
1026            }
1027            // 2. Sort fields according to their getOrder() Property
1028
Collections.sort(vec, FieldDescriptor.getComparator());
1029            m_nonPkFieldDescriptors =
1030                (FieldDescriptor[]) vec.toArray(new FieldDescriptor[vec.size()]);
1031        }
1032        return m_nonPkFieldDescriptors;
1033    }
1034
1035    /**
1036     * Return an array of PK FieldDescription sorted ascending
1037     * according to the field-descriptions getOrder() property
1038     */

1039    public FieldDescriptor[] getPkFields()
1040    {
1041        if (m_PkFieldDescriptors == null)
1042        {
1043            // 1. collect all Primary Key fields from Field list
1044
Vector JavaDoc vec = new Vector JavaDoc();
1045            // 1.a if descriptor describes an interface: take PK fields from an implementors ClassDescriptor
1046
if (m_isInterface)
1047            {
1048                if (getExtentClasses().size() == 0)
1049                {
1050                    throw new PersistenceBrokerException(
1051                        "No Implementors declared for interface "
1052                            + this.getClassOfObject().getName());
1053                }
1054                Class JavaDoc implementor = (Class JavaDoc) getExtentClasses().get(0);
1055                ClassDescriptor implCld = this.getRepository().getDescriptorFor(implementor);
1056                m_PkFieldDescriptors = implCld.getPkFields();
1057            }
1058            else
1059            {
1060                FieldDescriptor[] fields;
1061                // 1.b if not an interface The classdescriptor must have FieldDescriptors
1062
fields = getFieldDescriptions();
1063                // now collect all PK fields
1064
for (int i = 0; i < fields.length; i++)
1065                {
1066                    FieldDescriptor fd = fields[i];
1067                    if (fd.isPrimaryKey())
1068                    {
1069                        vec.add(fd);
1070                    }
1071                }
1072                // 2. Sort fields according to their getOrder() Property
1073
Collections.sort(vec, FieldDescriptor.getComparator());
1074                m_PkFieldDescriptors = (FieldDescriptor[]) vec.toArray(new FieldDescriptor[vec.size()]);
1075            }
1076        }
1077        return m_PkFieldDescriptors;
1078    }
1079
1080    /**
1081     * Returns array of read/write non pk FieldDescriptors.
1082     */

1083    public FieldDescriptor[] getNonPkRwFields()
1084    {
1085        if (m_RwNonPkFieldDescriptors == null)
1086        {
1087            FieldDescriptor[] fields = getNonPkFields();
1088            Collection JavaDoc rwFields = new ArrayList JavaDoc();
1089
1090            for (int i = 0; i < fields.length; i++)
1091            {
1092                FieldDescriptor fd = fields[i];
1093                if (!fd.isAccessReadOnly())
1094                {
1095                    rwFields.add(fd);
1096                }
1097            }
1098            m_RwNonPkFieldDescriptors =
1099                (FieldDescriptor[]) rwFields.toArray(new FieldDescriptor[rwFields.size()]);
1100        }
1101        return m_RwNonPkFieldDescriptors;
1102    }
1103
1104    /**
1105     * Returns array of read/write FieldDescriptors.
1106     */

1107    public FieldDescriptor[] getAllRwFields()
1108    {
1109        if (m_RwFieldDescriptors == null)
1110        {
1111            FieldDescriptor[] fields = getFieldDescriptions();
1112            Collection JavaDoc rwFields = new ArrayList JavaDoc();
1113
1114            for (int i = 0; i < fields.length; i++)
1115            {
1116                FieldDescriptor fd = fields[i];
1117                /*
1118                arminw: if locking is enabled and the increment of locking
1119                values is done by the database, the field is read-only
1120                */

1121                if(fd.isAccessReadOnly() || (fd.isLocking() && !fd.isUpdateLock()))
1122                {
1123                    continue;
1124                }
1125                rwFields.add(fd);
1126            }
1127            m_RwFieldDescriptors =
1128                (FieldDescriptor[]) rwFields.toArray(new FieldDescriptor[rwFields.size()]);
1129        }
1130
1131        return m_RwFieldDescriptors;
1132    }
1133
1134    /**
1135     * return an array of FieldDescription for optimistic locking sorted ascending
1136     * according to the field-descriptions getOrder() property
1137     */

1138    public FieldDescriptor[] getLockingFields()
1139    {
1140        if (m_lockingFieldDescriptors == null)
1141        {
1142            // 1. collect all Primary Key fields from Field list
1143
Vector JavaDoc vec = new Vector JavaDoc();
1144            for (int i = 0; i < m_FieldDescriptions.length; i++)
1145            {
1146                FieldDescriptor fd = m_FieldDescriptions[i];
1147                if (fd.isLocking())
1148                {
1149                    vec.add(fd);
1150                }
1151            }
1152            // 2. Sort fields according to their getOrder() Property
1153
Collections.sort(vec, FieldDescriptor.getComparator());
1154            m_lockingFieldDescriptors =
1155                (FieldDescriptor[]) vec.toArray(new FieldDescriptor[vec.size()]);
1156        }
1157        return m_lockingFieldDescriptors;
1158    }
1159
1160    /**
1161     * return true if optimistic locking is used
1162     */

1163    public boolean isLocking()
1164    {
1165        return getLockingFields().length > 0;
1166    }
1167
1168    /**
1169     * return all AttributeDescriptors for the path<br>
1170     * ie: partner.addresses.street returns a Collection of 3 AttributeDescriptors
1171     * (ObjectReferenceDescriptor, CollectionDescriptor, FieldDescriptor)<br>
1172     * ie: partner.addresses returns a Collection of 2 AttributeDescriptors
1173     * (ObjectReferenceDescriptor, CollectionDescriptor)
1174     * @param aPath the cleaned path to the attribute
1175     * @return ArrayList of AttributeDescriptors
1176     */

1177    public ArrayList JavaDoc getAttributeDescriptorsForPath(String JavaDoc aPath)
1178    {
1179        return getAttributeDescriptorsForPath(aPath, new HashMap JavaDoc());
1180    }
1181
1182    /**
1183     * return all AttributeDescriptors for the path<br>
1184     * ie: partner.addresses.street returns a Collection of 3 AttributeDescriptors
1185     * (ObjectReferenceDescriptor, CollectionDescriptor, FieldDescriptor)<br>
1186     * ie: partner.addresses returns a Collection of 2 AttributeDescriptors
1187     * (ObjectReferenceDescriptor, CollectionDescriptor)
1188     * @param aPath the cleaned path to the attribute
1189     * @param pathHints a Map containing the class to be used for a segment or <em>null</em>
1190     * if no segment was used.
1191     * @return ArrayList of AttributeDescriptors
1192     */

1193    public ArrayList JavaDoc getAttributeDescriptorsForPath(String JavaDoc aPath, Map JavaDoc pathHints)
1194    {
1195        return getAttributeDescriptorsForCleanPath(SqlHelper.cleanPath(aPath), pathHints);
1196    }
1197
1198    /**
1199     * return all AttributeDescriptors for the path<br>
1200     * ie: partner.addresses.street returns a Collection of 3 AttributeDescriptors
1201     * (ObjectReferenceDescriptor, CollectionDescriptor, FieldDescriptor)<br>
1202     * ie: partner.addresses returns a Collection of 2 AttributeDescriptors
1203     * (ObjectReferenceDescriptor, CollectionDescriptor)
1204     * @param aPath the cleaned path to the attribute
1205     * @param pathHints a Map containing the class to be used for a segment or <em>null</em>
1206     * if no segment is used.
1207     * @return ArrayList of AttributeDescriptors
1208     */

1209    private ArrayList JavaDoc getAttributeDescriptorsForCleanPath(String JavaDoc aPath, Map JavaDoc pathHints)
1210    {
1211        ArrayList JavaDoc result = new ArrayList JavaDoc();
1212        ClassDescriptor cld = this;
1213        ObjectReferenceDescriptor ord;
1214        FieldDescriptor fld;
1215        String JavaDoc currPath = aPath;
1216        String JavaDoc segment;
1217        StringBuffer JavaDoc processedSegment = new StringBuffer JavaDoc();
1218        int sepPos;
1219        Class JavaDoc itemClass;
1220
1221        while (currPath.length() > 0)
1222        {
1223            sepPos = currPath.indexOf(".");
1224            if (sepPos >= 0)
1225            {
1226                segment = currPath.substring(0, sepPos);
1227                currPath = currPath.substring(sepPos + 1);
1228            }
1229            else
1230            {
1231                segment = currPath;
1232                currPath = "";
1233            }
1234
1235            if (processedSegment.length() > 0)
1236            {
1237                processedSegment.append(".");
1238            }
1239            processedSegment.append(segment);
1240
1241            // look for 1:1 or n:1 Relationship
1242
ord = cld.getObjectReferenceDescriptorByName(segment);
1243            if (ord == null)
1244            {
1245                // look for 1:n or m:n Relationship
1246
ord = cld.getCollectionDescriptorByName(segment);
1247            }
1248
1249            if (ord != null)
1250            {
1251                // BRJ : look for hints for the processed segment
1252
// ie: ref pointng to ClassA and ref.ref pointing to ClassC
1253
List JavaDoc hintClasses = pathHints != null ? (List JavaDoc) pathHints.get(processedSegment.toString()) : null;
1254                if (hintClasses != null && hintClasses.get(0) != null)
1255                {
1256                    itemClass = (Class JavaDoc) hintClasses.get(0);
1257                }
1258                else
1259                {
1260                    itemClass = ord.getItemClass();
1261                }
1262
1263                cld = cld.getRepository().getDescriptorFor(itemClass);
1264                result.add(ord);
1265            }
1266            else
1267            {
1268                // look for Field
1269
fld = cld.getFieldDescriptorByName(segment);
1270                if (fld != null)
1271                {
1272                    result.add(fld);
1273                }
1274            }
1275        }
1276
1277        return result;
1278    }
1279
1280    /**
1281     * returns the zero argument constructor for the class represented by this class descriptor
1282     * or null if a zero argument constructor does not exist. If the zero argument constructor
1283     * for this class is not public it is made accessible before being returned.
1284     */

1285    public Constructor JavaDoc getZeroArgumentConstructor()
1286    {
1287        if (zeroArgumentConstructor == null && !alreadyLookedupZeroArguments)
1288        {
1289            try
1290            {
1291                zeroArgumentConstructor = getClassOfObject().getConstructor(NO_PARAMS);
1292            }
1293            catch (NoSuchMethodException JavaDoc e)
1294            {
1295                //no public zero argument constructor available let's try for a private/protected one
1296
try
1297                {
1298                    zeroArgumentConstructor = getClassOfObject().getDeclaredConstructor(NO_PARAMS);
1299
1300                    //we found one, now let's make it accessible
1301
zeroArgumentConstructor.setAccessible(true);
1302                }
1303                catch (NoSuchMethodException JavaDoc e2)
1304                {
1305                    //out of options, log the fact and let the method return null
1306
LoggerFactory.getDefaultLogger().warn(
1307                        this.getClass().getName()
1308                            + ": "
1309                            + "No zero argument constructor defined for "
1310                            + this.getClassOfObject());
1311                }
1312            }
1313
1314            alreadyLookedupZeroArguments = true;
1315        }
1316
1317        return zeroArgumentConstructor;
1318    }
1319
1320    /*
1321     * @see XmlCapable#toXML()
1322     */

1323    public String JavaDoc toXML()
1324    {
1325        RepositoryTags tags = RepositoryTags.getInstance();
1326        String JavaDoc eol = System.getProperty("line.separator");
1327
1328        // comment on class
1329
StringBuffer JavaDoc result = new StringBuffer JavaDoc(1024);
1330        result.append( eol);
1331        result.append( " <!-- Mapping for Class ");
1332        result.append( this.getClassNameOfObject());
1333        result.append( " -->");
1334        result.append( eol );
1335
1336        // opening tag and attributes
1337
result.append( " ");
1338        result.append( tags.getOpeningTagNonClosingById(CLASS_DESCRIPTOR));
1339        result.append( eol );
1340
1341        // class
1342
result.append( " ");
1343        result.append( tags.getAttribute(CLASS_NAME, this.getClassNameOfObject()));
1344        result.append( eol );
1345
1346        // isolation level is optional
1347
if (null != getRepository())
1348        {
1349            if (getIsolationLevel() != this.getRepository().getDefaultIsolationLevel())
1350            {
1351                result.append( " ");
1352                result.append( tags.getAttribute(ISOLATION_LEVEL, this.isolationLevelXml()) );
1353                result.append( eol );
1354            }
1355        }
1356
1357        Class JavaDoc theProxyClass = null;
1358        try
1359        {
1360            theProxyClass = this.getProxyClass();
1361        }
1362        catch (Throwable JavaDoc t)
1363        {
1364            // Ignore this exception, just try to get the Class object of the
1365
// proxy class in order to be able to decide, whether the class
1366
// is a dynamic proxy or not.
1367
}
1368
1369        // proxy is optional
1370
if (theProxyClass != null)
1371    {
1372        if (isDynamicProxy()) // tomdz: What about VirtualProxy ?
1373
{
1374            result.append( " ");
1375                result.append( tags.getAttribute(CLASS_PROXY, DYNAMIC_STR));
1376                result.append( eol );
1377            }
1378            else
1379        {
1380                result.append( " ");
1381            result.append( tags.getAttribute(CLASS_PROXY, this.getProxyClassName()));
1382            result.append( eol );
1383            }
1384            result.append( " ");
1385        result.append( tags.getAttribute(PROXY_PREFETCHING_LIMIT, "" + this.getProxyPrefetchingLimit()));
1386        result.append( eol );
1387    }
1388
1389        // schema is optional
1390
if (this.getSchema() != null)
1391        {
1392            result.append( " ");
1393            result.append( tags.getAttribute(SCHEMA_NAME, this.getSchema()));
1394            result.append( eol );
1395        }
1396
1397        // table name
1398
if (this.getTableName() != null)
1399        {
1400            result.append(" ");
1401            result.append( tags.getAttribute(TABLE_NAME, this.getTableName()));
1402            result.append( eol );
1403        }
1404
1405        // rowreader is optional
1406
if (this.getRowReaderClassName() != null)
1407        {
1408            result.append( " ");
1409            result.append( tags.getAttribute(ROW_READER, this.getRowReaderClassName()));
1410            result.append( eol );
1411        }
1412
1413        //accept-locks is optional, enabled by default
1414
if (!this.acceptLocks)
1415        {
1416            result.append( " ");
1417            result.append( tags.getAttribute(ACCEPT_LOCKS, "false"));
1418            result.append( eol );
1419        }
1420        // sequence manager attribute not yet implemented
1421

1422        // initialization method is optional
1423
if (this.getInitializationMethod() != null)
1424        {
1425            result.append( " ");
1426            result.append( tags.getAttribute(INITIALIZATION_METHOD, this.getInitializationMethod().getName()));
1427            result.append( eol );
1428        }
1429
1430        // factory class is optional
1431
if (this.getFactoryClass() != null)
1432        {
1433            result.append( " ");
1434            result.append( tags.getAttribute(FACTORY_CLASS, this.getFactoryClass().getName()) );
1435            result.append( eol );
1436        }
1437
1438        // factory method is optional
1439
if (this.getFactoryMethod() != null)
1440        {
1441            result.append( " ");
1442            result.append( tags.getAttribute(FACTORY_METHOD, this.getFactoryMethod().getName()) );
1443            result.append( eol );
1444        }
1445
1446        //reference refresh is optional, disabled by default
1447
if (isAlwaysRefresh())
1448        {
1449            result.append( " ");
1450            result.append( tags.getAttribute(REFRESH, "true"));
1451            result.append( eol );
1452        }
1453
1454        result.append( " >");
1455        result.append( eol );
1456
1457        // end of attributes
1458

1459        // begin of elements
1460
if (isInterface())
1461        {
1462            // extent-class
1463
for (int i = 0; i < getExtentClassNames().size(); i++)
1464            {
1465                result.append( " ");
1466                result.append( tags.getOpeningTagNonClosingById(CLASS_EXTENT));
1467                result.append( " " );
1468                result.append( tags.getAttribute(CLASS_REF, getExtentClassNames().get(i).toString()) );
1469                result.append( " />");
1470                result.append( eol );
1471            }
1472        }
1473        else
1474        {
1475            // class extent is optional
1476
if (isExtent())
1477            {
1478                for (int i = 0; i < getExtentClassNames().size(); i++)
1479                {
1480                    result.append( " ");
1481                    result.append( tags.getOpeningTagNonClosingById(CLASS_EXTENT));
1482                    result.append( " " );
1483                    result.append( tags.getAttribute(CLASS_REF, getExtentClassNames().get(i).toString()) );
1484                    result.append( " />");
1485                    result.append( eol );
1486                }
1487            }
1488
1489            // write all FieldDescriptors
1490
FieldDescriptor[] fields = getFieldDescriptions();
1491            for (int i = 0; i < fields.length; i++)
1492            {
1493                result.append( fields[i].toXML() );
1494            }
1495
1496            // write optional ReferenceDescriptors
1497
Vector JavaDoc refs = getObjectReferenceDescriptors();
1498            for (int i = 0; i < refs.size(); i++)
1499            {
1500                result.append( ((ObjectReferenceDescriptor) refs.get(i)).toXML() );
1501            }
1502
1503            // write optional CollectionDescriptors
1504
Vector JavaDoc cols = getCollectionDescriptors();
1505            for (int i = 0; i < cols.size(); i++)
1506            {
1507                result.append( ((CollectionDescriptor) cols.get(i)).toXML() );
1508            }
1509
1510            // write optional IndexDescriptors
1511
for (int i = 0; i < indexes.size(); i++)
1512            {
1513                IndexDescriptor indexDescriptor = (IndexDescriptor) indexes.elementAt(i);
1514                result.append( indexDescriptor.toXML() );
1515            }
1516
1517            // Write out the procedures
1518
if (this.getInsertProcedure() != null)
1519            {
1520                result.append( this.getInsertProcedure().toXML() );
1521            }
1522            if (this.getUpdateProcedure() != null)
1523            {
1524                result.append( this.getUpdateProcedure().toXML() );
1525            }
1526            if (this.getDeleteProcedure() != null)
1527            {
1528                result.append( this.getDeleteProcedure().toXML() );
1529            }
1530        }
1531        result.append( " ");
1532        result.append( tags.getClosingTagById(CLASS_DESCRIPTOR) );
1533        return result.toString();
1534    }
1535
1536    private String JavaDoc isolationLevelXml()
1537    {
1538        switch (this.getIsolationLevel())
1539        {
1540            case (IL_OPTIMISTIC) :
1541                {
1542                    return LITERAL_IL_OPTIMISTIC;
1543                }
1544            case (IL_READ_COMMITTED) :
1545                {
1546                    return LITERAL_IL_READ_COMMITTED;
1547                }
1548            case (IL_READ_UNCOMMITTED) :
1549                {
1550                    return LITERAL_IL_READ_UNCOMMITTED;
1551                }
1552            case (IL_REPEATABLE_READ) :
1553                {
1554                    return LITERAL_IL_REPEATABLE_READ;
1555                }
1556            case (IL_SERIALIZABLE) :
1557                {
1558                    return LITERAL_IL_SERIALIZABLE;
1559                }
1560            default :
1561                {
1562                    return LITERAL_IL_READ_UNCOMMITTED;
1563                }
1564        }
1565    }
1566/*
1567arminw:
1568TODO: this feature doesn't work, so remove this in future
1569*/

1570    /**
1571     * Set name of the super class.
1572     */

1573    public void setSuperClass(String JavaDoc classname)
1574    {
1575        this.superClass = classname;
1576    }
1577
1578    /**
1579     * Return the super class or <code>null</code>
1580     * if not declared in repository file.
1581     */

1582    public String JavaDoc getSuperClass()
1583    {
1584        return superClass;
1585    }
1586
1587    /**
1588     * TODO drop this method?
1589     */

1590    public void setSuperClassFieldRef(int fieldId)
1591    {
1592        this.superClassFieldRef = fieldId;
1593    }
1594
1595    /**
1596     * TODO drop this method?
1597     */

1598    public int getSuperClassFieldRef()
1599    {
1600        return superClassFieldRef;
1601    }
1602
1603    /**
1604     * Return true, if the described class is
1605     * an interface.
1606     */

1607    public boolean isInterface()
1608    {
1609        return m_isInterface;
1610    }
1611
1612    /**
1613     * Set <code>true</code> if described class is
1614     * a interface.
1615     */

1616    public void setIsInterface(boolean newIsInterface)
1617    {
1618        m_isInterface = newIsInterface;
1619    }
1620
1621    /**
1622     * @return boolean true if the mapped class is abstract
1623     */

1624    public boolean isAbstract()
1625    {
1626        return isAbstract;
1627    }
1628
1629    /**
1630     * Returns acceptLocks.
1631     * @return boolean
1632     */

1633    public boolean isAcceptLocks()
1634    {
1635        return acceptLocks;
1636    }
1637
1638    /**
1639     * Sets acceptLocks.
1640     * @param acceptLocks The m_acceptLocks to set
1641     */

1642    public void setAcceptLocks(boolean acceptLocks)
1643    {
1644        this.acceptLocks = acceptLocks;
1645    }
1646
1647    /**
1648     * Gets the IndexDescriptors used for DDL generation.
1649     */

1650    public Vector JavaDoc getIndexes()
1651    {
1652        return indexes;
1653    }
1654
1655    /**
1656     * Sets the IndexDescriptors used for DDL generation.
1657     */

1658    public void setIndexes(Vector JavaDoc indexes)
1659    {
1660        this.indexes = indexes;
1661    }
1662
1663    /**
1664     * Gets the repository.
1665     * @return Returns a DescriptorRepository
1666     */

1667    public DescriptorRepository getRepository()
1668    {
1669        return m_repository;
1670    }
1671
1672    /**
1673     * Sets the repository.
1674     * @param repository The repository to set
1675     */

1676    public void setRepository(DescriptorRepository repository)
1677    {
1678        m_repository = repository;
1679    }
1680
1681    /**
1682     * returns the transaction isolation level to be used for this class. Used only in the ODMG server
1683     */

1684    public int getIsolationLevel()
1685    {
1686        return m_IsolationLevel;
1687    }
1688
1689    /**
1690     * Method declaration
1691     * @param isoLevel
1692     */

1693    public void setIsolationLevel(int isoLevel)
1694    {
1695        m_IsolationLevel = isoLevel;
1696    }
1697
1698    /**
1699     * Method declaration
1700     * @return table name
1701     */

1702    private String JavaDoc getTableName()
1703    {
1704        return m_TableName;
1705    }
1706
1707    /**
1708     * Method declaration
1709     * @param str
1710     */

1711    public void setTableName(String JavaDoc str)
1712    {
1713        m_TableName = str;
1714    }
1715
1716    /**
1717     * Answer Table name including schema BRJ
1718     */

1719    public String JavaDoc getFullTableName()
1720    {
1721        if (getSchema() != null)
1722            return getSchema() + "." + getTableName();
1723        else
1724            return getTableName();
1725    }
1726
1727    /**
1728     * Gets the schema.
1729     * @return Returns a String
1730     */

1731    public String JavaDoc getSchema()
1732    {
1733        return schema;
1734    }
1735
1736    /**
1737     * Sets the schema.
1738     * @param schema The schema to set
1739     */

1740    public void setSchema(String JavaDoc schema)
1741    {
1742        this.schema = schema;
1743    }
1744
1745    /**
1746     * Return a string representation of this class.
1747     */

1748    public String JavaDoc toString()
1749    {
1750        ToStringBuilder buf = new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE);
1751        return buf
1752            .append("classNameOfObject", getClassNameOfObject())
1753            .append("tableName", getTableName())
1754            .append("schema", getSchema())
1755            .append("isInterface", isInterface())
1756            .append("extendClassNames", getExtentClassNames().toString())
1757            //.append("[fieldDescriptions:")
1758
.append(getFieldDescriptions())
1759            //.append("]")
1760
.toString();
1761    }
1762
1763    /**
1764     * sets the initialization method for this descriptor
1765     */

1766    private synchronized void setInitializationMethod(Method JavaDoc newMethod)
1767    {
1768        if (newMethod != null)
1769        {
1770            // make sure it's a no argument method
1771
if (newMethod.getParameterTypes().length > 0)
1772            {
1773                throw new MetadataException(
1774                    "Initialization methods must be zero argument methods: "
1775                        + newMethod.getClass().getName()
1776                        + "."
1777                        + newMethod.getName());
1778            }
1779
1780            // make it accessible if it's not already
1781
if (!newMethod.isAccessible())
1782            {
1783                newMethod.setAccessible(true);
1784            }
1785        }
1786        this.initializationMethod = newMethod;
1787    }
1788
1789    /**
1790     * sets the initialization method for this descriptor by name
1791     */

1792    public synchronized void setInitializationMethod(String JavaDoc newMethodName)
1793    {
1794        Method JavaDoc newMethod = null;
1795        if (newMethodName != null)
1796        {
1797            initializationMethodName = newMethodName;
1798            try
1799            {
1800                // see if we have a publicly accessible method by the name
1801
newMethod = getClassOfObject().getMethod(newMethodName, NO_PARAMS);
1802            }
1803            catch (NoSuchMethodException JavaDoc e)
1804            {
1805                try
1806                {
1807                    // no publicly accessible method, see if there is a private/protected one
1808
newMethod = getClassOfObject().getDeclaredMethod(newMethodName, NO_PARAMS);
1809                }
1810                catch (NoSuchMethodException JavaDoc e2)
1811                {
1812                    // there is no such method available
1813
throw new MetadataException(
1814                        "Invalid initialization method, there is not"
1815                            + " a zero argument method named "
1816                            + newMethodName
1817                            + " on class "
1818                            + getClassOfObject().getName()
1819                            + ".");
1820                }
1821            }
1822        }
1823        setInitializationMethod(newMethod);
1824    }
1825
1826    /**
1827     * Returns the initialization method for this descriptor or null if no
1828     * initialization method is defined.
1829     */

1830    public synchronized Method JavaDoc getInitializationMethod()
1831    {
1832        if(this.initializationMethod == null)
1833        {
1834            setInitializationMethod(initializationMethodName);
1835        }
1836        return initializationMethod;
1837    }
1838
1839    /**
1840     * if true instances of this class are always refreshed
1841     * even if they are already in the cache.
1842     * @return boolean
1843     */

1844    public boolean isAlwaysRefresh()
1845    {
1846        return alwaysRefresh;
1847    }
1848
1849    /**
1850     * Sets the alwaysRefresh parameter.
1851     * @param alwaysRefresh The value to set
1852     */

1853    public void setAlwaysRefresh(boolean alwaysRefresh)
1854    {
1855        this.alwaysRefresh = alwaysRefresh;
1856    }
1857
1858    public int getProxyPrefetchingLimit()
1859    {
1860        return m_ProxyPrefetchingLimit;
1861    }
1862
1863    public void setProxyPrefetchingLimit(int proxyPrefetchingLimit)
1864    {
1865        m_ProxyPrefetchingLimit = proxyPrefetchingLimit;
1866    }
1867
1868    /**
1869     * Return factory class.
1870     */

1871    public synchronized Class JavaDoc getFactoryClass()
1872    {
1873        return this.factoryClass;
1874    }
1875
1876    /**
1877     * Return factory method.
1878     */

1879    public synchronized Method JavaDoc getFactoryMethod()
1880    {
1881        if(factoryMethod == null && factoryMethodName != null)
1882        {
1883            setFactoryMethod(factoryMethodName);
1884        }
1885        return this.factoryMethod;
1886    }
1887
1888    /**
1889     * Set the object factory for class described by this
1890     * descriptor.
1891     * @see #setFactoryMethod
1892     */

1893    public synchronized void setFactoryClass(Class JavaDoc newClass)
1894    {
1895        this.factoryClass = newClass;
1896    }
1897
1898    /**
1899     * @see #setFactoryClass
1900     */

1901    public void setFactoryClass(String JavaDoc newClass)
1902    {
1903        if (null != newClass)
1904        {
1905            try
1906            {
1907                Class JavaDoc clazz = ClassHelper.getClass(newClass);
1908                setFactoryClass(clazz);
1909            }
1910            catch (Exception JavaDoc e)
1911            {
1912                // there is no such method available
1913
throw new MetadataException("Invalid factory class: " + newClass + ".");
1914            }
1915        }
1916        else
1917        {
1918            setFactoryClass((Class JavaDoc) null);
1919        }
1920    }
1921
1922    /**
1923     * Specify the method to instantiate objects
1924     * represented by this descriptor.
1925     * @see #setFactoryClass
1926     */

1927    private synchronized void setFactoryMethod(Method JavaDoc newMethod)
1928    {
1929        if (newMethod != null)
1930        {
1931            // make sure it's a no argument method
1932
if (newMethod.getParameterTypes().length > 0)
1933            {
1934                throw new MetadataException(
1935                    "Factory methods must be zero argument methods: "
1936                        + newMethod.getClass().getName()
1937                        + "."
1938                        + newMethod.getName());
1939            }
1940
1941            // make it accessible if it's not already
1942
if (!newMethod.isAccessible())
1943            {
1944                newMethod.setAccessible(true);
1945            }
1946        }
1947
1948        this.factoryMethod = newMethod;
1949    }
1950
1951    /**
1952     * sets the initialization method for this descriptor by name
1953     */

1954    public synchronized void setFactoryMethod(String JavaDoc factoryMethodName)
1955    {
1956        Method JavaDoc newMethod = null;
1957        this.factoryMethodName = factoryMethodName;
1958
1959        if (factoryMethodName != null)
1960        {
1961            try
1962            {
1963                // see if we have a publicly accessible method by the name
1964
newMethod = getFactoryClass().getMethod(factoryMethodName, NO_PARAMS);
1965            }
1966            catch (NoSuchMethodException JavaDoc e)
1967            {
1968                try
1969                {
1970                    // no publicly accessible method, see if there is a private/protected one
1971
newMethod = getFactoryClass().getDeclaredMethod(factoryMethodName, NO_PARAMS);
1972                }
1973                catch (NoSuchMethodException JavaDoc e2)
1974                {
1975                    // there is no such method available
1976
throw new MetadataException(
1977                        "Invalid factory method, there is not"
1978                            + " a zero argument method named "
1979                            + factoryMethodName
1980                            + " on class "
1981                            + getFactoryClass().getName()
1982                            + ".");
1983                }
1984            }
1985        }
1986        setFactoryMethod(newMethod);
1987    }
1988
1989    //---------------------------------------------------------------
1990
/**
1991     * Change the descriptor for the insert procedure/function.
1992     *
1993     * @param newValue the new value.
1994     */

1995    public void setInsertProcedure(InsertProcedureDescriptor newValue)
1996    {
1997        this.insertProcedure = newValue;
1998    }
1999
2000    //---------------------------------------------------------------
2001
/**
2002     * Retrieve the descriptor for the insert procedure/function.
2003     *
2004     * @return The current value
2005     */

2006    public InsertProcedureDescriptor getInsertProcedure()
2007    {
2008        return this.insertProcedure;
2009    }
2010
2011    //---------------------------------------------------------------
2012
/**
2013     * Change the descriptor for the update procedure/function.
2014     *
2015     * @param newValue the new value.
2016     */

2017    public void setUpdateProcedure(UpdateProcedureDescriptor newValue)
2018    {
2019        this.updateProcedure = newValue;
2020    }
2021
2022    //---------------------------------------------------------------
2023
/**
2024     * Retrieve the descriptor for the update procedure/function.
2025     *
2026     * @return The current value
2027     */

2028    public UpdateProcedureDescriptor getUpdateProcedure()
2029    {
2030        return this.updateProcedure;
2031    }
2032
2033    //---------------------------------------------------------------
2034
/**
2035     * Change the descriptor for the delete procedure/function.
2036     *
2037     * @param newValue the new value.
2038     */

2039    public void setDeleteProcedure(DeleteProcedureDescriptor newValue)
2040    {
2041        this.deleteProcedure = newValue;
2042    }
2043
2044    //---------------------------------------------------------------
2045
/**
2046     * Retrieve the descriptor for the delete procedure/function.
2047     *
2048     * @return The current value
2049     */

2050    public DeleteProcedureDescriptor getDeleteProcedure()
2051    {
2052        return this.deleteProcedure;
2053    }
2054
2055    /**
2056     * Returns the ojbConcreteClass field or <code>null</code> if none defined.
2057     */

2058    public FieldDescriptor getOjbConcreteClassField()
2059    {
2060        // if not checked before
2061
if(!ojbConcreteFieldCheckDone)
2062        {
2063            ojbConcreteClassField = getFieldDescriptorByName(OJB_CONCRETE_CLASS);
2064            ojbConcreteFieldCheckDone = true;
2065        }
2066        return ojbConcreteClassField;
2067    }
2068
2069    public StatementsForClassIF getStatementsForClass(ConnectionManagerIF conMan)
2070    {
2071        if(statementsForClass == null)
2072        {
2073           statementsForClass = StatementsForClassFactory.getInstance().
2074                   getStatementsForClass(conMan.getConnectionDescriptor(), this);
2075        }
2076        return statementsForClass;
2077    }
2078
2079
2080    /**
2081     * Optional! Set the {@link org.apache.ojb.broker.metadata.fieldaccess.PersistentField}
2082     * implementation class used by this class.
2083     * @param pfClassName The full qualified class name of the
2084     * {@link org.apache.ojb.broker.metadata.fieldaccess.PersistentField}.
2085     */

2086    public void setPersistentFieldClassName(String JavaDoc pfClassName)
2087    {
2088        this.persistentFieldClassName = pfClassName;
2089    }
2090
2091
2092    /**
2093     * Get the used {@link org.apache.ojb.broker.metadata.fieldaccess.PersistentField}
2094     * implementation name.
2095     */

2096    public String JavaDoc getPersistentFieldClassName()
2097    {
2098        return persistentFieldClassName;
2099    }
2100
2101    /**
2102     * Returns <em>true</em> if an DB Identity column field based sequence
2103     * manager was used. In that cases we will find an autoincrement field with
2104     * read-only access and return true, otherwise false.
2105     */

2106     public boolean useIdentityColumnField()
2107     {
2108         if(useIdentityColumn == 0)
2109         {
2110             useIdentityColumn = -1;
2111             FieldDescriptor[] pkFields = getPkFields();
2112             for (int i = 0; i < pkFields.length; i++)
2113             {
2114                 // to find the identity column we search for a autoincrement
2115
// read-only field
2116
if (pkFields[i].isAutoIncrement() && pkFields[i].isAccessReadOnly())
2117                {
2118                    useIdentityColumn = 1;
2119                    break;
2120                }
2121             }
2122         }
2123        return useIdentityColumn == 1;
2124     }
2125
2126    /**
2127     * Returns all defined {@link ObjectReferenceDescriptor}.
2128     *
2129     * @param withInherited If <em>true</em> inherited super class references will be included.
2130     */

2131    public List JavaDoc getObjectReferenceDescriptors(boolean withInherited)
2132    {
2133        if(withInherited && getSuperClassDescriptor() != null)
2134        {
2135            List JavaDoc result = new ArrayList JavaDoc(m_ObjectReferenceDescriptors);
2136            result.addAll(getSuperClassDescriptor().getObjectReferenceDescriptors(true));
2137            return result;
2138        }
2139        else
2140        {
2141            return m_ObjectReferenceDescriptors;
2142        }
2143    }
2144
2145    /**
2146     * Returns all defined {@link CollectionDescriptor} for
2147     * this class descriptor.
2148     *
2149     * @param withInherited If <em>true</em> inherited super class references will be included.
2150     */

2151    public List JavaDoc getCollectionDescriptors(boolean withInherited)
2152    {
2153        if(withInherited && getSuperClassDescriptor() != null)
2154        {
2155            List JavaDoc result = new ArrayList JavaDoc(m_CollectionDescriptors);
2156            result.addAll(getSuperClassDescriptor().getCollectionDescriptors(true));
2157            return result;
2158        }
2159        else
2160        {
2161            return m_CollectionDescriptors;
2162        }
2163    }
2164
2165    /**
2166     * Return an array of all {@link FieldDescriptor} for this represented class, if
2167     * parameter <em>withInherited</em> is <em>true</em> all inherited descriptor
2168     * of declared super classes are included.
2169     *
2170     * @param withInherited If <em>true</em> inherited super class fields will be included.
2171     */

2172    public FieldDescriptor[] getFieldDescriptor(boolean withInherited)
2173    {
2174        if(withInherited && getSuperClassDescriptor() != null)
2175        {
2176            /*
2177            arminw: only return no-PK fields, because all PK fields are declared
2178            in sub-class too.
2179            */

2180            FieldDescriptor[] superFlds = getSuperClassDescriptor().getFieldDescriptorNonPk(true);
2181            if(m_FieldDescriptions == null)
2182            {
2183                m_FieldDescriptions = new FieldDescriptor[0];
2184            }
2185            FieldDescriptor[] result = new FieldDescriptor[m_FieldDescriptions.length + superFlds.length];
2186            System.arraycopy(m_FieldDescriptions, 0, result, 0, m_FieldDescriptions.length);
2187            System.arraycopy(superFlds, 0, result, m_FieldDescriptions.length, superFlds.length);
2188            // System.out.println("all fields: " + ArrayUtils.toString(result));
2189
return result;
2190        }
2191        else
2192        {
2193            return m_FieldDescriptions;
2194        }
2195    }
2196
2197    /**
2198     * Return an array of NON-PK {@link FieldDescriptor}, if parameter <em>withInherited</em>
2199     * is <em>true</em> all inherited descriptor of declared super classes are included.
2200     *
2201     * @param withInherited If <em>true</em> inherited super class fields will be included.
2202     */

2203    public FieldDescriptor[] getFieldDescriptorNonPk(boolean withInherited)
2204    {
2205        if(withInherited && getSuperClassDescriptor() != null)
2206        {
2207            FieldDescriptor[] flds = getNonPkFields();
2208            FieldDescriptor[] superFlds = getSuperClassDescriptor().getFieldDescriptorNonPk(true);
2209            FieldDescriptor[] result = new FieldDescriptor[flds.length + superFlds.length];
2210            System.arraycopy(flds, 0, result, 0, flds.length);
2211            System.arraycopy(superFlds, 0, result, flds.length, superFlds.length);
2212            return result;
2213        }
2214        else
2215        {
2216            return getNonPkFields();
2217        }
2218    }
2219
2220    /**
2221     * Returns the {@link SuperReferenceDescriptor} of this class or <em>null</em>
2222     * if none was used.
2223     *
2224     * @return The reference descriptor for the <em>super</em>-reference or <em>null</em>
2225     * if not exists.
2226     */

2227    public SuperReferenceDescriptor getSuperReference()
2228    {
2229        return (SuperReferenceDescriptor) getObjectReferenceDescriptorByName(SuperReferenceDescriptor.SUPER_FIELD_INTERNAL_NAME);
2230    }
2231}
2232
Popular Tags