KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > xdoclet > modules > ojb > model > ClassDescriptorDef


1 package xdoclet.modules.ojb.model;
2
3 /* Copyright 2004-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.util.*;
19
20 import xdoclet.modules.ojb.CommaListIterator;
21 import xdoclet.modules.ojb.LogHelper;
22 import xdoclet.modules.ojb.constraints.*;
23 import xjavadoc.XClass;
24
25 /**
26  * Definition of a class for the ojb repository file.
27  *
28  * @author <a HREF="mailto:tomdz@apache.org">Thomas Dudziak</a>
29  */

30 public class ClassDescriptorDef extends DefBase
31 {
32     /** The original class */
33     private XClass _origin;
34     /** The direct base types (available after this class has been processed */
35     private HashMap _directBaseTypes = new HashMap();
36     /** Sub class defs */
37     private ArrayList _extents = new ArrayList();
38     /** Fields */
39     private ArrayList _fields = new ArrayList();
40     /** References */
41     private ArrayList _references = new ArrayList();
42     /** Collections */
43     private ArrayList _collections = new ArrayList();
44     /** Nested objects */
45     private ArrayList _nested = new ArrayList();
46     /** Contains modifications to inherited fields/references/collections
47       * (key = name, value = Properties object with the modifications) */

48     private HashMap _modifications = new HashMap();
49     /** Index descriptors */
50     private ArrayList _indexDescriptors = new ArrayList();
51     /** The object cache */
52     private ObjectCacheDef _objectCache = null;
53     /** The procedures */
54     private SortedMap _procedures = new TreeMap();
55     /** The procedure arguments */
56     private HashMap _procedureArguments = new HashMap();
57     /** Whether this class descriptor has been processed */
58     private boolean _hasBeenProcessed = false;
59
60     /**
61      * Creates a new class definition object.
62      *
63      * @param origin The original class
64      */

65     public ClassDescriptorDef(XClass origin)
66     {
67         super(origin.getTransformedQualifiedName());
68         _origin = origin;
69     }
70
71     /**
72      * Returns the original class.
73      *
74      * @return The original XDoclet class object
75      */

76     public XClass getOriginalClass()
77     {
78         return _origin;
79     }
80
81     /**
82      * Returns the qualified name of this class as per Java spec.
83      *
84      * @return The qualified name
85      */

86     public String JavaDoc getQualifiedName()
87     {
88         return getName().replace('$', '.');
89     }
90
91     /**
92      * Returns the default table name for this class which is the unqualified class name.
93      *
94      * @return The default table name
95      */

96     public String JavaDoc getDefaultTableName()
97     {
98         String JavaDoc name = getName();
99         int lastDotPos = name.lastIndexOf('.');
100         int lastDollarPos = name.lastIndexOf('$');
101
102         return lastDollarPos > lastDotPos ? name.substring(lastDollarPos + 1) : name.substring(lastDotPos + 1);
103     }
104     
105     /**
106      * Determines whether this class descriptor has been processed.
107      *
108      * @return <code>true</code> if this class descriptor has been processed
109      */

110     boolean hasBeenProcessed()
111     {
112         return _hasBeenProcessed;
113     }
114     
115     /**
116      * Processes theis class (ensures that all base types are processed, copies their features to this class, and applies
117      * modifications (removes ignored features, changes declarations).
118      *
119      * @throws ConstraintException If a constraint has been violated
120      */

121     public void process() throws ConstraintException
122     {
123         ClassDescriptorDef otherClassDef;
124         
125         for (Iterator it = getDirectBaseTypes(); it.hasNext();)
126         {
127             otherClassDef = (ClassDescriptorDef)it.next();
128             if (!otherClassDef.hasBeenProcessed())
129             {
130                 otherClassDef.process();
131             }
132         }
133         for (Iterator it = getNested(); it.hasNext();)
134         {
135             otherClassDef = ((NestedDef)it.next()).getNestedType();
136             if (!otherClassDef.hasBeenProcessed())
137             {
138                 otherClassDef.process();
139             }
140         }
141         
142         ArrayList newFields = new ArrayList();
143         ArrayList newReferences = new ArrayList();
144         ArrayList newCollections = new ArrayList();
145         FieldDescriptorDef newFieldDef;
146         ReferenceDescriptorDef newRefDef;
147         CollectionDescriptorDef newCollDef;
148         
149         // adding base features
150
if (getBooleanProperty(PropertyHelper.OJB_PROPERTY_INCLUDE_INHERITED, true))
151         {
152             ArrayList baseTypes = new ArrayList();
153             DefBase featureDef;
154             
155             addRelevantBaseTypes(this, baseTypes);
156             for (Iterator it = baseTypes.iterator(); it.hasNext();)
157             {
158                 cloneInheritedFeatures((ClassDescriptorDef)it.next(), newFields, newReferences, newCollections);
159             }
160
161             for (Iterator it = newFields.iterator(); it.hasNext();)
162             {
163                 newFieldDef = (FieldDescriptorDef)it.next();
164                 featureDef = getFeature(newFieldDef.getName());
165                 if (featureDef != null)
166                 {
167                     if (!getBooleanProperty(PropertyHelper.OJB_PROPERTY_IGNORE, false))
168                     {
169                         // we have the implicit constraint that an anonymous field cannot redefine/be redefined
170
// except if it is ignored
171
if ("anonymous".equals(featureDef.getProperty(PropertyHelper.OJB_PROPERTY_ACCESS)))
172                         {
173                             throw new ConstraintException("The anonymous field "+featureDef.getName()+" in class "+getName()+" overrides an inherited field");
174                         }
175                         if ("anonymous".equals(newFieldDef.getProperty(PropertyHelper.OJB_PROPERTY_ACCESS)))
176                         {
177                             throw new ConstraintException("The inherited anonymous field "+newFieldDef.getName()+" is overriden in class "+getName());
178                         }
179                     }
180                     LogHelper.warn(true, ClassDescriptorDef.class, "process", "Class "+getName()+" redefines the inherited field "+newFieldDef.getName());
181                     it.remove();
182                 }
183             }
184             for (Iterator it = newReferences.iterator(); it.hasNext();)
185             {
186                 newRefDef = (ReferenceDescriptorDef)it.next();
187                 if ("super".equals(newRefDef.getName()))
188                 {
189                     // we don't inherit super-references
190
it.remove();
191                 }
192                 else if (hasFeature(newRefDef.getName()))
193                 {
194                     LogHelper.warn(true, ClassDescriptorDef.class, "process", "Class "+getName()+" redefines the inherited reference "+newRefDef.getName());
195                     it.remove();
196                 }
197             }
198             for (Iterator it = newCollections.iterator(); it.hasNext();)
199             {
200                 newCollDef = (CollectionDescriptorDef)it.next();
201                 if (hasFeature(newCollDef.getName()))
202                 {
203                     LogHelper.warn(true, ClassDescriptorDef.class, "process", "Class "+getName()+" redefines the inherited collection "+newCollDef.getName());
204                     it.remove();
205                 }
206             }
207         }
208         // adding nested features
209
for (Iterator it = getNested(); it.hasNext();)
210         {
211             cloneNestedFeatures((NestedDef)it.next(), newFields, newReferences, newCollections);
212         }
213         _fields.addAll(0, newFields);
214         _references.addAll(0, newReferences);
215         _collections.addAll(0, newCollections);
216         sortFields();
217         _hasBeenProcessed = true;
218     }
219
220     /**
221      * Sorts the fields.
222      */

223     private void sortFields()
224     {
225         HashMap fields = new HashMap();
226         ArrayList fieldsWithId = new ArrayList();
227         ArrayList fieldsWithoutId = new ArrayList();
228         FieldDescriptorDef fieldDef;
229
230         for (Iterator it = getFields(); it.hasNext(); )
231         {
232             fieldDef = (FieldDescriptorDef)it.next();
233             fields.put(fieldDef.getName(), fieldDef);
234             if (fieldDef.hasProperty(PropertyHelper.OJB_PROPERTY_ID))
235             {
236                 fieldsWithId.add(fieldDef.getName());
237             }
238             else
239             {
240                 fieldsWithoutId.add(fieldDef.getName());
241             }
242         }
243
244         Collections.sort(fieldsWithId, new FieldWithIdComparator(fields));
245
246         ArrayList result = new ArrayList();
247
248         for (Iterator it = fieldsWithId.iterator(); it.hasNext();)
249         {
250             result.add(getField((String JavaDoc)it.next()));
251         }
252         for (Iterator it = fieldsWithoutId.iterator(); it.hasNext();)
253         {
254             result.add(getField((String JavaDoc)it.next()));
255         }
256
257         _fields = result;
258     }
259     
260     /**
261      * Checks the constraints on this class.
262      *
263      * @param checkLevel The amount of checks to perform
264      * @exception ConstraintException If a constraint has been violated
265      */

266     public void checkConstraints(String JavaDoc checkLevel) throws ConstraintException
267     {
268         // now checking constraints
269
FieldDescriptorConstraints fieldConstraints = new FieldDescriptorConstraints();
270         ReferenceDescriptorConstraints refConstraints = new ReferenceDescriptorConstraints();
271         CollectionDescriptorConstraints collConstraints = new CollectionDescriptorConstraints();
272
273         for (Iterator it = getFields(); it.hasNext();)
274         {
275             fieldConstraints.check((FieldDescriptorDef)it.next(), checkLevel);
276         }
277         for (Iterator it = getReferences(); it.hasNext();)
278         {
279             refConstraints.check((ReferenceDescriptorDef)it.next(), checkLevel);
280         }
281         for (Iterator it = getCollections(); it.hasNext();)
282         {
283             collConstraints.check((CollectionDescriptorDef)it.next(), checkLevel);
284         }
285         new ClassDescriptorConstraints().check(this, checkLevel);
286     }
287
288     /**
289      * Adds all relevant base types (depending on their include-inherited setting) to the given list.
290      *
291      * @param curType The type to process
292      * @param baseTypes The list of basetypes
293      */

294     private void addRelevantBaseTypes(ClassDescriptorDef curType, ArrayList baseTypes)
295     {
296         ClassDescriptorDef baseDef;
297
298         for (Iterator it = curType.getDirectBaseTypes(); it.hasNext();)
299         {
300             baseDef = (ClassDescriptorDef)it.next();
301             if (!baseDef.getBooleanProperty(PropertyHelper.OJB_PROPERTY_INCLUDE_INHERITED, true))
302             {
303                 // the base type has include-inherited set to false which means that
304
// it does not include base features
305
// since we do want these base features, we have to traverse its base types
306
addRelevantBaseTypes(baseDef, baseTypes);
307             }
308             baseTypes.add(baseDef);
309         }
310     }
311
312     /**
313      * Determines whether the given list contains a descriptor with the same name.
314      *
315      * @param defs The list to search
316      * @param obj The object that is searched for
317      * @return <code>true</code> if the list contains a descriptor with the same name
318      */

319     private boolean contains(ArrayList defs, DefBase obj)
320     {
321         for (Iterator it = defs.iterator(); it.hasNext();)
322         {
323             if (obj.getName().equals(((DefBase)it.next()).getName()))
324             {
325                 return true;
326             }
327         }
328         return false;
329     }
330
331     /**
332      * Clones the features of the given base class (using modifications if available) and puts them into
333      * the given lists.
334      *
335      * @param baseDef The base class descriptor
336      * @param newFields Recieves the field copies
337      * @param newReferences Recieves the reference copies
338      * @param newCollections Recieves the collection copies
339      */

340     private void cloneInheritedFeatures(ClassDescriptorDef baseDef, ArrayList newFields, ArrayList newReferences, ArrayList newCollections)
341     {
342         FieldDescriptorDef copyFieldDef;
343         ReferenceDescriptorDef copyRefDef;
344         CollectionDescriptorDef copyCollDef;
345
346         // note that we also copy features with the ignore-property set to true
347
// they will be ignored later on
348
for (Iterator fieldIt = baseDef.getFields(); fieldIt.hasNext();)
349         {
350             copyFieldDef = cloneField((FieldDescriptorDef)fieldIt.next(), null);
351             if (!contains(newFields, copyFieldDef))
352             {
353                 copyFieldDef.setInherited();
354                 newFields.add(copyFieldDef);
355             }
356         }
357         for (Iterator refIt = baseDef.getReferences(); refIt.hasNext();)
358         {
359             copyRefDef = cloneReference((ReferenceDescriptorDef)refIt.next(), null);
360             if (!contains(newReferences, copyRefDef))
361             {
362                 copyRefDef.setInherited();
363                 newReferences.add(copyRefDef);
364             }
365         }
366         for (Iterator collIt = baseDef.getCollections(); collIt.hasNext();)
367         {
368             copyCollDef = cloneCollection((CollectionDescriptorDef)collIt.next(), null);
369             if (!contains(newCollections, copyCollDef))
370             {
371                 copyCollDef.setInherited();
372                 newCollections.add(copyCollDef);
373             }
374         }
375     }
376
377     /**
378      * Clones the features of the given nested object (using modifications if available) and puts them into
379      * the given lists.
380      *
381      * @param nestedDef The nested object
382      * @param newFields Recieves the field copies
383      * @param newReferences Recieves the reference copies
384      * @param newCollections Recieves the collection copies
385      */

386     private void cloneNestedFeatures(NestedDef nestedDef, ArrayList newFields, ArrayList newReferences, ArrayList newCollections)
387     {
388         ClassDescriptorDef nestedClassDef = nestedDef.getNestedType();
389         String JavaDoc prefix = nestedDef.getName()+"::";
390         FieldDescriptorDef copyFieldDef;
391         ReferenceDescriptorDef copyRefDef;
392         CollectionDescriptorDef copyCollDef;
393         StringBuffer JavaDoc newForeignkey;
394
395         for (Iterator fieldIt = nestedClassDef.getFields(); fieldIt.hasNext();)
396         {
397             copyFieldDef = cloneField((FieldDescriptorDef)fieldIt.next(), prefix);
398             if (!contains(newFields, copyFieldDef))
399             {
400                 copyFieldDef.setNested();
401                 newFields.add(copyFieldDef);
402             }
403         }
404         for (Iterator refIt = nestedClassDef.getReferences(); refIt.hasNext();)
405         {
406             copyRefDef = cloneReference((ReferenceDescriptorDef)refIt.next(), prefix);
407             if (contains(newReferences, copyRefDef))
408             {
409                 continue;
410             }
411             copyRefDef.setNested();
412
413             // we have to modify the foreignkey setting as it specifies a field of the same (nested) class
414
newForeignkey = new StringBuffer JavaDoc();
415
416             for (CommaListIterator it = new CommaListIterator(copyRefDef.getProperty(PropertyHelper.OJB_PROPERTY_FOREIGNKEY)); it.hasNext();)
417             {
418                 if (newForeignkey.length() > 0)
419                 {
420                     newForeignkey.append(",");
421                 }
422                 newForeignkey.append(prefix);
423                 newForeignkey.append(it.next());
424             }
425             copyRefDef.setProperty(PropertyHelper.OJB_PROPERTY_FOREIGNKEY, newForeignkey.toString());
426             newReferences.add(copyRefDef);
427         }
428         for (Iterator collIt = nestedClassDef.getCollections(); collIt.hasNext();)
429         {
430             copyCollDef = cloneCollection((CollectionDescriptorDef)collIt.next(), prefix);
431             if (!contains(newCollections, copyCollDef))
432             {
433                 copyCollDef.setNested();
434                 newCollections.add(copyCollDef);
435             }
436         }
437     }
438
439     /**
440      * Clones the given field.
441      *
442      * @param fieldDef The field descriptor
443      * @param prefix A prefix for the name
444      * @return The cloned field
445      */

446     private FieldDescriptorDef cloneField(FieldDescriptorDef fieldDef, String JavaDoc prefix)
447     {
448         FieldDescriptorDef copyFieldDef = new FieldDescriptorDef(fieldDef, prefix);
449
450         copyFieldDef.setOwner(this);
451         // we remove properties that are only relevant to the class the features are declared in
452
copyFieldDef.setProperty(PropertyHelper.OJB_PROPERTY_IGNORE, null);
453
454         Properties mod = getModification(copyFieldDef.getName());
455
456         if (mod != null)
457         {
458             if (!PropertyHelper.toBoolean(mod.getProperty(PropertyHelper.OJB_PROPERTY_IGNORE), false) &&
459                 hasFeature(copyFieldDef.getName()))
460             {
461                 LogHelper.warn(true,
462                                ClassDescriptorDef.class,
463                                "process",
464                                "Class "+getName()+" has a feature that has the same name as its included field "+
465                                copyFieldDef.getName()+" from class "+fieldDef.getOwner().getName());
466             }
467             copyFieldDef.applyModifications(mod);
468         }
469         return copyFieldDef;
470     }
471
472     /**
473      * Clones the given reference.
474      *
475      * @param refDef The reference descriptor
476      * @param prefix A prefix for the name
477      * @return The cloned reference
478      */

479     private ReferenceDescriptorDef cloneReference(ReferenceDescriptorDef refDef, String JavaDoc prefix)
480     {
481         ReferenceDescriptorDef copyRefDef = new ReferenceDescriptorDef(refDef, prefix);
482
483         copyRefDef.setOwner(this);
484         // we remove properties that are only relevant to the class the features are declared in
485
copyRefDef.setProperty(PropertyHelper.OJB_PROPERTY_IGNORE, null);
486         
487         Properties mod = getModification(copyRefDef.getName());
488
489         if (mod != null)
490         {
491             if (!PropertyHelper.toBoolean(mod.getProperty(PropertyHelper.OJB_PROPERTY_IGNORE), false) &&
492                 hasFeature(copyRefDef.getName()))
493             {
494                 LogHelper.warn(true,
495                                ClassDescriptorDef.class,
496                                "process",
497                                "Class "+getName()+" has a feature that has the same name as its included reference "+
498                                copyRefDef.getName()+" from class "+refDef.getOwner().getName());
499             }
500             copyRefDef.applyModifications(mod);
501         }
502         return copyRefDef;
503     }
504
505     /**
506      * Clones the given collection.
507      *
508      * @param collDef The collection descriptor
509      * @param prefix A prefix for the name
510      * @return The cloned collection
511      */

512     private CollectionDescriptorDef cloneCollection(CollectionDescriptorDef collDef, String JavaDoc prefix)
513     {
514         CollectionDescriptorDef copyCollDef = new CollectionDescriptorDef(collDef, prefix);
515
516         copyCollDef.setOwner(this);
517         // we remove properties that are only relevant to the class the features are declared in
518
copyCollDef.setProperty(PropertyHelper.OJB_PROPERTY_IGNORE, null);
519
520         Properties mod = getModification(copyCollDef.getName());
521
522         if (mod != null)
523         {
524             if (!PropertyHelper.toBoolean(mod.getProperty(PropertyHelper.OJB_PROPERTY_IGNORE), false) &&
525                 hasFeature(copyCollDef.getName()))
526             {
527                 LogHelper.warn(true,
528                                ClassDescriptorDef.class,
529                                "process",
530                                "Class "+getName()+" has a feature that has the same name as its included collection "+
531                                copyCollDef.getName()+" from class "+collDef.getOwner().getName());
532             }
533             copyCollDef.applyModifications(mod);
534         }
535         return copyCollDef;
536     }
537
538     /**
539      * Adds a direct base type.
540      *
541      * @param baseType The base type descriptor
542      */

543     public void addDirectBaseType(ClassDescriptorDef baseType)
544     {
545         _directBaseTypes.put(baseType.getName(), baseType);
546     }
547
548     /**
549      * Returns the direct base types.
550      *
551      * @return An iterator of the direct base types
552      */

553     public Iterator getDirectBaseTypes()
554     {
555         return _directBaseTypes.values().iterator();
556     }
557     
558     /**
559      * Returns all base types.
560      *
561      * @return An iterator of the base types
562      */

563     public Iterator getAllBaseTypes()
564     {
565         ArrayList baseTypes = new ArrayList();
566
567         baseTypes.addAll(_directBaseTypes.values());
568
569         for (int idx = baseTypes.size() - 1; idx >= 0; idx--)
570         {
571             ClassDescriptorDef curClassDef = (ClassDescriptorDef)baseTypes.get(idx);
572
573             for (Iterator it = curClassDef.getDirectBaseTypes(); it.hasNext();)
574             {
575                 ClassDescriptorDef curBaseTypeDef = (ClassDescriptorDef)it.next();
576
577                 if (!baseTypes.contains(curBaseTypeDef))
578                 {
579                     baseTypes.add(0, curBaseTypeDef);
580                     idx++;
581                 }
582             }
583         }
584         return baseTypes.iterator();
585     }
586
587     /**
588      * Adds a sub type.
589      *
590      * @param subType The sub type definition
591      */

592     public void addExtentClass(ClassDescriptorDef subType)
593     {
594         if (!_extents.contains(subType))
595         {
596             _extents.add(subType);
597         }
598     }
599
600     /**
601      * Returns an iterator of the extents of this class.
602      *
603      * @return The extents iterator
604      */

605     public Iterator getExtentClasses()
606     {
607         // we sort the extents prior to returning them
608
Collections.sort(_extents, new DefBaseComparator());
609         return _extents.iterator();
610     }
611
612     /**
613      * Returns an iterator of all direct and indirect extents of this class.
614      *
615      * @return The extents iterator
616      */

617     public Iterator getAllExtentClasses()
618     {
619         ArrayList subTypes = new ArrayList();
620
621         subTypes.addAll(_extents);
622
623         for (int idx = 0; idx < subTypes.size(); idx++)
624         {
625             ClassDescriptorDef curClassDef = (ClassDescriptorDef)subTypes.get(idx);
626
627             for (Iterator it = curClassDef.getExtentClasses(); it.hasNext();)
628             {
629                 ClassDescriptorDef curSubTypeDef = (ClassDescriptorDef)it.next();
630
631                 if (!subTypes.contains(curSubTypeDef))
632                 {
633                     subTypes.add(curSubTypeDef);
634                 }
635             }
636         }
637         return subTypes.iterator();
638     }
639
640     /**
641      * Determines whether this class can be instantiated, i.e. not an interface or abstract class.
642      *
643      * @return <code>true</code> if objects can be created of this class
644      */

645     public boolean canBeInstantiated()
646     {
647         return !_origin.isAbstract() && !_origin.isInterface();
648     }
649     
650     /**
651      * Determines whether this class has a feature (field, reference, collection) of the given name.
652      *
653      * @param name The name
654      * @return <code>true</code> if there is such a feature
655      */

656     public boolean hasFeature(String JavaDoc name)
657     {
658         return getFeature(name) != null;
659     }
660     
661     /**
662      * Returns the feature (field, reference, collection) of the given name.
663      *
664      * @param name The name
665      * @return The feature or <code>null</code> if there is no such feature in the current class
666      */

667     public DefBase getFeature(String JavaDoc name)
668     {
669         DefBase result = getField(name);
670
671         if (result == null)
672         {
673             result = getReference(name);
674         }
675         if (result == null)
676         {
677             result = getCollection(name);
678         }
679         return result;
680     }
681
682     /**
683      * Adds a field descriptor to this class.
684      *
685      * @param fieldDef The field descriptor
686      */

687     public void addField(FieldDescriptorDef fieldDef)
688     {
689         fieldDef.setOwner(this);
690         _fields.add(fieldDef);
691     }
692
693     /**
694      * Adds a clone of the given field descriptor to this class.
695      *
696      * @param fieldDef The field descriptor
697      */

698     public void addFieldClone(FieldDescriptorDef fieldDef)
699     {
700         _fields.add(cloneField(fieldDef, ""));
701     }
702
703     /**
704      * Returns the field definition with the specified name.
705      *
706      * @param name The name of the desired field
707      * @return The field definition or <code>null</code> if there is no such field
708      */

709     public FieldDescriptorDef getField(String JavaDoc name)
710     {
711         FieldDescriptorDef fieldDef = null;
712
713         for (Iterator it = _fields.iterator(); it.hasNext(); )
714         {
715             fieldDef = (FieldDescriptorDef)it.next();
716             if (fieldDef.getName().equals(name))
717             {
718                 return fieldDef;
719             }
720         }
721         return null;
722     }
723
724     /**
725      * Returns an iterator of the fields definitions.
726      *
727      * @return The field iterator
728      */

729     public Iterator getFields()
730     {
731         return _fields.iterator();
732     }
733
734     /**
735      * Returns the field descriptors given in the the field names list.
736      *
737      * @param fieldNames The field names, separated by commas
738      * @return The field descriptors in the order given by the field names
739      * @throws NoSuchFieldException If a field hasn't been found
740      */

741     public ArrayList getFields(String JavaDoc fieldNames) throws NoSuchFieldException JavaDoc
742     {
743         ArrayList result = new ArrayList();
744         FieldDescriptorDef fieldDef;
745         String JavaDoc name;
746
747         for (CommaListIterator it = new CommaListIterator(fieldNames); it.hasNext();)
748         {
749             name = it.getNext();
750             fieldDef = getField(name);
751             if (fieldDef == null)
752             {
753                 throw new NoSuchFieldException JavaDoc(name);
754             }
755             result.add(fieldDef);
756         }
757         return result;
758     }
759
760     /**
761      * Returns the primarykey fields.
762      *
763      * @return The field descriptors of the primarykey fields
764      */

765     public ArrayList getPrimaryKeys()
766     {
767         ArrayList result = new ArrayList();
768         FieldDescriptorDef fieldDef;
769
770         for (Iterator it = getFields(); it.hasNext();)
771         {
772             fieldDef = (FieldDescriptorDef)it.next();
773             if (fieldDef.getBooleanProperty(PropertyHelper.OJB_PROPERTY_PRIMARYKEY, false))
774             {
775                 result.add(fieldDef);
776             }
777         }
778         return result;
779     }
780     
781     /**
782      * Adds a reference descriptor to this class.
783      *
784      * @param refDef The reference descriptor
785      */

786     public void addReference(ReferenceDescriptorDef refDef)
787     {
788         refDef.setOwner(this);
789         _references.add(refDef);
790     }
791
792     /**
793      * Returns a reference definition of the given name if it exists.
794      *
795      * @param name The name of the reference
796      * @return The reference def or <code>null</code> if there is no such reference
797      */

798     public ReferenceDescriptorDef getReference(String JavaDoc name)
799     {
800         ReferenceDescriptorDef refDef;
801
802         for (Iterator it = _references.iterator(); it.hasNext(); )
803         {
804             refDef = (ReferenceDescriptorDef)it.next();
805             if (refDef.getName().equals(name))
806             {
807                 return refDef;
808             }
809         }
810         return null;
811     }
812
813     /**
814      * Returns an iterator of the reference definitionss.
815      *
816      * @return The iterator
817      */

818     public Iterator getReferences()
819     {
820         return _references.iterator();
821     }
822
823     /**
824      * Adds a collection descriptor to this class.
825      *
826      * @param collDef The collection descriptor
827      */

828     public void addCollection(CollectionDescriptorDef collDef)
829     {
830         collDef.setOwner(this);
831         _collections.add(collDef);
832     }
833
834     /**
835      * Returns the collection definition of the given name if it exists.
836      *
837      * @param name The name of the collection
838      * @return The collection definition or <code>null</code> if there is no such collection
839      */

840     public CollectionDescriptorDef getCollection(String JavaDoc name)
841     {
842         CollectionDescriptorDef collDef = null;
843
844         for (Iterator it = _collections.iterator(); it.hasNext(); )
845         {
846             collDef = (CollectionDescriptorDef)it.next();
847             if (collDef.getName().equals(name))
848             {
849                 return collDef;
850             }
851         }
852         return null;
853     }
854
855     /**
856      * Returns an iterator of the collection definitions.
857      *
858      * @return The collection iterator
859      */

860     public Iterator getCollections()
861     {
862         return _collections.iterator();
863     }
864
865     /**
866      * Adds a nested object to this class.
867      *
868      * @param nestedDef The nested object
869      */

870     public void addNested(NestedDef nestedDef)
871     {
872         nestedDef.setOwner(this);
873         _nested.add(nestedDef);
874     }
875
876     /**
877      * Returns the nested object definition with the specified name.
878      *
879      * @param name The name of the attribute of the nested object
880      * @return The nested object definition or <code>null</code> if there is no such nested object
881      */

882     public NestedDef getNested(String JavaDoc name)
883     {
884         NestedDef nestedDef = null;
885
886         for (Iterator it = _nested.iterator(); it.hasNext(); )
887         {
888             nestedDef = (NestedDef)it.next();
889             if (nestedDef.getName().equals(name))
890             {
891                 return nestedDef;
892             }
893         }
894         return null;
895     }
896
897     /**
898      * Returns an iterator of the nested object definitions.
899      *
900      * @return The nested object iterator
901      */

902     public Iterator getNested()
903     {
904         return _nested.iterator();
905     }
906
907     /**
908      * Adds an index descriptor definition to this class descriptor.
909      *
910      * @param indexDef The index descriptor definition
911      */

912     public void addIndexDescriptor(IndexDescriptorDef indexDef)
913     {
914         indexDef.setOwner(this);
915         _indexDescriptors.add(indexDef);
916     }
917
918     /**
919      * Returns the index descriptor definition of the given name if it exists.
920      *
921      * @param name The name of the index
922      * @return The index descriptor definition or <code>null</code> if there is no such index
923      */

924     public IndexDescriptorDef getIndexDescriptor(String JavaDoc name)
925     {
926         IndexDescriptorDef indexDef = null;
927
928         for (Iterator it = _indexDescriptors.iterator(); it.hasNext(); )
929         {
930             indexDef = (IndexDescriptorDef)it.next();
931             if (indexDef.getName().equals(name))
932             {
933                 return indexDef;
934             }
935         }
936         return null;
937     }
938
939     /**
940      * Returns an iterator of the index descriptor definitions.
941      *
942      * @return The index descriptor iterator
943      */

944     public Iterator getIndexDescriptors()
945     {
946         return _indexDescriptors.iterator();
947     }
948
949     /**
950      * Sets an object cache definition to an object cache of the given name (if necessary), and returns it.
951      *
952      * @param name The name of the object cache class
953      * @return The object cache definition
954      */

955     public ObjectCacheDef setObjectCache(String JavaDoc name)
956     {
957         if ((_objectCache == null) || !_objectCache.getName().equals(name))
958         {
959             _objectCache = new ObjectCacheDef(name);
960     
961             _objectCache.setOwner(this);
962         }
963         return _objectCache;
964     }
965
966     /**
967      * Returns the object cache definition.
968      *
969      * @return The object cache definition
970      */

971     public ObjectCacheDef getObjectCache()
972     {
973         return _objectCache;
974     }
975
976     /**
977      * Adds a procedure definition to this class descriptor.
978      *
979      * @param procDef The procedure definition
980      */

981     public void addProcedure(ProcedureDef procDef)
982     {
983         procDef.setOwner(this);
984         _procedures.put(procDef.getName(), procDef);
985     }
986
987     /**
988      * Returns the procedure definition of the given name if it exists.
989      *
990      * @param name The name of the procedure
991      * @return The procedure definition or <code>null</code> if there is no such procedure
992      */

993     public ProcedureDef getProcedure(String JavaDoc name)
994     {
995         return (ProcedureDef)_procedures.get(name);
996     }
997
998     /**
999      * Returns an iterator of the procedure definitions.
1000     *
1001     * @return The procedure iterator
1002     */

1003    public Iterator getProcedures()
1004    {
1005        return _procedures.values().iterator();
1006    }
1007    
1008    /**
1009     * Adds a procedure argument definition to this class descriptor.
1010     *
1011     * @param argDef The procedure argument definition
1012     */

1013    public void addProcedureArgument(ProcedureArgumentDef argDef)
1014    {
1015        argDef.setOwner(this);
1016        _procedureArguments.put(argDef.getName(), argDef);
1017    }
1018
1019    /**
1020     * Returns the procedure argument definition of the given name if it exists.
1021     *
1022     * @param name The name of the procedure argument
1023     * @return The procedure argument definition or <code>null</code> if there is no such argument
1024     */

1025    public ProcedureArgumentDef getProcedureArgument(String JavaDoc name)
1026    {
1027        return (ProcedureArgumentDef)_procedureArguments.get(name);
1028    }
1029
1030    /**
1031     * Returns an iterator of all procedure argument definitions.
1032     *
1033     * @return The procedure argument iterator
1034     */

1035    public Iterator getProcedureArguments()
1036    {
1037        return _procedureArguments.values().iterator();
1038    }
1039
1040    /**
1041     * Adds a modification for the given inherited field/reference/collection.
1042     *
1043     * @param name The name of the inherited field, reference or collection
1044     * @param mods The modified properties
1045     */

1046    public void addModification(String JavaDoc name, Properties mods)
1047    {
1048        _modifications.put(name, mods);
1049    }
1050
1051    /**
1052     * Returns an iterator of all field/reference/collection names for which modifications are stored in this class def.
1053     *
1054     * @return The iterator
1055     */

1056    public Iterator getModificationNames()
1057    {
1058        return _modifications.keySet().iterator();
1059    }
1060
1061    /**
1062     * Returns the modification for the inherited field/reference/collection with the given name.
1063     *
1064     * @param name The name of the inherited field, reference or collection
1065     * @return The modified properties or <code>null</code> if there are no modifications for it
1066     */

1067    public Properties getModification(String JavaDoc name)
1068    {
1069        return (Properties)_modifications.get(name);
1070    }
1071
1072    /* (non-Javadoc)
1073     * @see java.lang.Object#equals(java.lang.Object)
1074     */

1075    public boolean equals(Object JavaDoc other)
1076    {
1077        if ((other == null) || !(other instanceof ClassDescriptorDef))
1078        {
1079            return false;
1080        }
1081        return _origin == ((ClassDescriptorDef)other)._origin;
1082    }
1083
1084    /* (non-Javadoc)
1085     * @see java.lang.Object#hashCode()
1086     */

1087    public int hashCode()
1088    {
1089        return _origin.hashCode();
1090    }
1091}
1092
Popular Tags