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 <