KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jac > core > rtti > CollectionItem


1 /*
2   Copyright (C) 2003 Renaud Pawlak <renaud@aopsys.com>,
3                      Laurent Martelli <laurent@aopsys.com>
4   
5   This program is free software; you can redistribute it and/or modify
6   it under the terms of the GNU Lesser General Public License as
7   published by the Free Software Foundation; either version 2 of the
8   License, or (at your option) any later version.
9
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13   GNU Lesser General Public License for more details.
14
15   You should have received a copy of the GNU Lesser General Public License
16   along with this program; if not, write to the Free Software
17   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */

18
19 package org.objectweb.jac.core.rtti;
20
21 import java.lang.reflect.Array JavaDoc;
22 import java.lang.reflect.Field JavaDoc;
23 import java.lang.reflect.InvocationTargetException JavaDoc;
24 import java.util.Arrays JavaDoc;
25 import java.util.Collection JavaDoc;
26 import java.util.List JavaDoc;
27 import java.util.Map JavaDoc;
28 import java.util.Vector JavaDoc;
29 import org.apache.log4j.Logger;
30 import org.objectweb.jac.util.WrappedThrowableException;
31 import java.util.ArrayList JavaDoc;
32
33 /**
34  * This class defines a meta item that corresponds to a
35  * <code>java.lang.reflect.Field</code> meta element that is of an
36  * array, a collection, or a map type.<p>
37  *
38  * @see java.util.Collection
39  * @see java.util.Map
40  * @see java.util.Arrays
41  * @see java.lang.reflect.Field
42  *
43  * @author Renaud Pawlak
44  * @author Laurent Martelli
45  */

46
47 public class CollectionItem extends FieldItem {
48
49     static Logger logger = Logger.getLogger("rtti.collection");
50  
51     protected ClassItem componentType;
52
53     /**
54      * Default contructor to create a new collection item object.<p>
55      *
56      * @param delegate the <code>java.lang.reflect.Field</code> actual
57      * meta item */

58
59     /**
60      * Creates a CollectionItem for a real field
61      * @param delegate the field the collection corresponds to
62      * @param parent the class the collection belongs to
63      */

64     public CollectionItem(Field JavaDoc delegate, ClassItem parent)
65         throws InvalidDelegateException
66     {
67         super(delegate,parent);
68         type = delegate.getType();
69         if (!RttiAC.isCollectionType(type)) {
70             throw new InvalidDelegateException(delegate,"not a collection type");
71         }
72     }
73
74     /**
75      * Creates a CollectionItem for an expression field.
76      * @param name the expression
77      * @param path the list of FieldItem the expression is made of
78      * @param parent the class the collection belongs to
79      */

80     public CollectionItem(String JavaDoc name, List JavaDoc path, ClassItem parent)
81         throws InvalidDelegateException
82     {
83         super(name,path,parent);
84         if (!RttiAC.isCollectionType(type)) {
85             throw new InvalidDelegateException(parent.getName()+"."+name,"Not a collection type");
86         }
87     }
88
89     /**
90      * Creates a CollectionItem for a calculated field.
91      * @param name the name of the collection
92      * @param getter the getter of the calculated collection
93      * @param parent the class the collection belongs to
94      */

95     public CollectionItem(String JavaDoc name, MethodItem getter, ClassItem parent) {
96         super(name,getter,parent);
97     }
98
99     MethodItem[] addingMethods = MethodItem.emptyArray;
100    
101     /**
102      * Gets the method items that access this collection for adding.<p>
103      *
104      * @return value of addingMethods.
105      * @see #hasAdder()
106      */

107
108     public MethodItem[] getAddingMethods() {
109         ((ClassItem)parent).buildFieldInfo();
110         return addingMethods;
111     }
112
113     /**
114      * Returns true if the collection has at least one adding method.
115      * @see #getAddingMethods()
116      */

117     public boolean hasAdder() {
118         ((ClassItem)parent).buildFieldInfo();
119         return addingMethods.length>0;
120     }
121    
122     MethodItem adder;
123     /**
124      * Returns <em>the</em> adder of the collection, or null if it has
125      * no adder.
126      */

127     public MethodItem getAdder() {
128         ((ClassItem)parent).buildFieldInfo();
129         if (adder!=null)
130             return adder;
131         else if (addingMethods.length>0)
132             return addingMethods[0];
133         else if (isExpression)
134             return ((CollectionItem)getPathTop()).getAdder();
135         else
136             return null;
137     }
138     /**
139      * Sets <em>the</em> adder of the collection.
140      * @param adder the adder
141      */

142     public void setAdder(MethodItem adder) {
143         this.adder = adder;
144     }
145
146     /**
147      * Sets the methods that access this collection for adding.<p>
148      *
149      * @param addingMethods value to assign to addingMethods.
150      */

151
152     public void setAddingMethods( MethodItem[] addingMethods ) {
153         this.addingMethods = addingMethods;
154     }
155
156     /**
157      * Adds a new adding method for this field.<p>
158      *
159      * @param addingMethod the method to add
160      */

161
162     public void addAddingMethod(MethodItem addingMethod) {
163         if (addingMethods.length == 0) {
164             addingMethods = new MethodItem[] { addingMethod };
165         } else {
166             MethodItem[] tmp = new MethodItem[addingMethods.length + 1];
167             System.arraycopy(addingMethods, 0, tmp, 0, addingMethods.length);
168             tmp[addingMethods.length] = addingMethod;
169             addingMethods = tmp;
170             if (getLongName().startsWith("org.objectweb.jac."))
171                 logger.debug("Adders for "+getLongName()+": "+Arrays.asList(tmp));
172             else
173                 logger.warn("Adders for "+getLongName()+": "+Arrays.asList(tmp));
174         }
175     }
176
177     /**
178      * Returns the actual collection item. In the case of an expression
179      * field, this is the last element of the path, otherwise it is the
180      * field itself.
181      */

182     public CollectionItem getCollection() {
183         if (isExpression) {
184             return (CollectionItem)getPathTop();
185         } else {
186             return this;
187         }
188     }
189
190     /**
191      * Returns the type of the objects contained in this collection.
192      * @return the type of objects in this collection or null if it is
193      * undefined.
194      */

195     public ClassItem getComponentType() {
196         ((ClassItem)parent).buildFieldInfo();
197         if (componentType!=null)
198             return componentType;
199         if (isArray()) {
200             componentType = ClassRepository.get().getClass(getType().getComponentType());
201         } else {
202
203             if (isExpression) {
204                 componentType = ((CollectionItem)getPathTop()).getComponentType();
205             } else {
206                 MethodItem adder = getAdder();
207                 if (adder!=null && adder.getParameterCount()>0) {
208                     if (isMap()) {
209                         if (isIndex())
210                             componentType = adder.getParameterTypeItem(
211                                 adder.getParameterCount()-1);
212                         else {
213                             componentType =
214                                 ClassRepository.get().getClass(
215                                     "java.util.Map$Entry");
216                         }
217                     } else {
218                         if (adder.getParameterCount()==1)
219                             componentType = adder.getParameterTypeItem(0);
220                         else if (adder.getParameterCount()==2) {
221                             int itemArg = adder.getCollectionItemArgument();
222                             if (itemArg!=-1)
223                                 componentType = adder.getParameterTypeItem(itemArg);
224                         }
225                         if (componentType==null)
226                             logger.warn(
227                                 "Cannot determine component type of "+getName()+
228                                 " from adder "+adder.getFullName());
229                     }
230                 }
231             }
232         }
233
234         if (componentType==null) {
235             if (!isMap() || isIndex())
236                 logger.warn("Component type of "+this+" is null");
237             if (adder==null && !isCalculated())
238                 logger.warn("no adder fo "+this+" "+getParent());
239         }
240         return componentType;
241     }
242
243     /**
244      * Sets the component type of the collection.
245      * @param componentType the component type
246      */

247     public void setComponentType(ClassItem componentType) {
248         this.componentType = componentType;
249     }
250
251     public boolean isAddingMethod(MethodItem method) {
252         ((ClassItem)parent).buildFieldInfo();
253         return Arrays.asList(addingMethods).contains(method);
254     }
255
256     /**
257      * Adds an item to the collection, using the adder method if it has one.
258      * @param substance object on which to add
259      * @param value object to add to the collection
260      */

261     public final void addThroughAdder(Object JavaDoc substance, Object JavaDoc value) {
262         logger.debug("addThroughAdder "+substance+"."+getName()+","+value);
263         MethodItem adder = getAdder();
264         if (adder!=null) {
265             try {
266                 //Log.trace("rtti.field",this+": invoking "+adders[i]);
267
adder.invoke(substance,new Object JavaDoc[] { value });
268                 return;
269             } catch (WrappedThrowableException e) {
270                 Throwable JavaDoc target = e.getWrappedThrowable();
271                 if (target instanceof InvocationTargetException JavaDoc)
272                     throw e;
273                 else
274                     logger.error("addThroughAdder "+substance+"."+getName()+","+value,e);
275             }
276         }
277
278         logger.warn("No adder for collection " + this);
279         add(substance,value,null);
280     }
281
282
283     public final void putThroughAdder(Object JavaDoc substance, Object JavaDoc value, Object JavaDoc key) {
284         logger.debug("putThroughAdder "+substance+"."+getName()+","+key+"->"+value);
285         MethodItem adder = getAdder();
286         if (adder!=null) {
287             try {
288                 //Log.trace("rtti.field",this+": invoking "+adders[i]);
289
if (adder.getParameterCount()==2)
290                     adder.invoke(substance,new Object JavaDoc[] { key, value });
291                 else if (adder.getParameterCount()==1)
292                     adder.invoke(substance,new Object JavaDoc[] { value });
293                 else
294                     throw new RuntimeException JavaDoc("putThroughAdder("+substance+","+value+","+key+
295                                                ") :Wrong number off parameters for adder "+adder);
296                 return;
297             } catch (WrappedThrowableException e) {
298                 Throwable JavaDoc target = e.getWrappedThrowable();
299                 if (target instanceof InvocationTargetException JavaDoc)
300                     throw e;
301                 else
302                     logger.error("putThroughAdder "+substance+"."+getName()+","+value,e);
303             }
304         }
305
306         logger.warn("No adder for collection " + this);
307         add(substance,value,key);
308     }
309
310     MethodItem[] removingMethods = MethodItem.emptyArray;
311    
312     /**
313      * Gets the methods that access this collection for removing.<p>
314      *
315      * @return value of removingMethods.
316      */

317
318     public MethodItem[] getRemovingMethods() {
319         ((ClassItem)parent).buildFieldInfo();
320         return removingMethods;
321     }
322    
323     /**
324      * Returns true if the collection has at least one removing method.
325      * @see #getRemovingMethods()
326      */

327     public boolean hasRemover() {
328         ((ClassItem)parent).buildFieldInfo();
329         return removingMethods.length>0;
330     }
331
332     MethodItem remover;
333     /**
334      * Returns <em>the</em> remover of the collection, or null if it has
335      * no remover.
336      */

337     public MethodItem getRemover() {
338         ((ClassItem)parent).buildFieldInfo();
339         if (remover!=null)
340             return remover;
341         else if (removingMethods.length>0)
342             return removingMethods[0];
343         else if (isExpression)
344             return ((CollectionItem)getPathTop()).getRemover();
345         else
346             return null;
347     }
348
349     /**
350      * Sets <em>the</em> remover of the collection.
351      * @param remover the remover
352      */

353     public void setRemover(MethodItem remover) {
354         this.remover = remover;
355     }
356
357     /**
358      * Sets the methods that access this collection for removing.<p>
359      *
360      * @param removingMethods value to assign to removingMethods.
361      */

362
363     public void setRemovingMethods( MethodItem[] removingMethods ) {
364         this.removingMethods = removingMethods;
365     }
366
367     /**
368      * Adds a new removing method for this field.<p>
369      *
370      * @param removingMethod the method to add
371      */

372
373     public void addRemovingMethod( MethodItem removingMethod ) {
374         if (removingMethods == null) {
375             removingMethods = new MethodItem[] { removingMethod };
376         } else {
377             MethodItem[] tmp = new MethodItem[removingMethods.length + 1];
378             System.arraycopy(removingMethods, 0, tmp, 0, removingMethods.length);
379             tmp[removingMethods.length] = removingMethod;
380             removingMethods = tmp;
381         }
382     }
383
384     public boolean isRemovingMethod(MethodItem method) {
385         ((ClassItem)parent).buildFieldInfo();
386         return Arrays.asList(removingMethods).contains(method);
387     }
388
389     /**
390      * Clears all the methods that has been set to be removers or
391      * adders for this collection item.
392      *
393      * @see #addAddingMethod(MethodItem)
394      * @see #setAddingMethods(MethodItem[])
395      * @see MethodItem#removeAddedCollection(CollectionItem)
396      * @see #addRemovingMethod(MethodItem)
397      * @see #setRemovingMethods(MethodItem[])
398      * @see MethodItem#removeRemovedCollection(CollectionItem) */

399
400     public void clearMethods() {
401         super.clearMethods();
402         if (removingMethods != null) {
403             for (int i=0; i<removingMethods.length; i++) {
404                 removingMethods[i].removeRemovedCollection(this);
405             }
406             removingMethods = null;
407         }
408         if (addingMethods != null) {
409             for (int i=0; i<addingMethods.length; i++) {
410                 addingMethods[i].removeAddedCollection(this);
411             }
412             addingMethods = null;
413         }
414     }
415
416     /**
417      * Clears the collection on the given object.<p>
418      *
419      * For maps and collections, it delegates to the <code>clear</code>
420      * method. For array, it resets the adding index so that added
421      * elements will crush existing ones.<p>
422      *
423      * @param substance the object where to clean the collection
424      */

425
426     public void clear(Object JavaDoc substance) {
427         logger.debug(this+".clear("+substance+")");
428         Field JavaDoc f = (Field JavaDoc) delegate;
429
430         try {
431             Object JavaDoc collection = f.get(substance);
432             logger.debug("collection="+System.identityHashCode(collection));
433             if (collection!=null) {
434                 logger.debug("type="+collection.getClass().getName());
435                 if (collection instanceof Collection JavaDoc) {
436                     ((Collection JavaDoc)collection).clear();
437                 } else if (collection instanceof Map JavaDoc) {
438                     ((Map JavaDoc)collection).clear();
439                 } else if (getType().isArray()) {
440                     f.set(substance, Array.newInstance(getType().getComponentType(),0));
441                 }
442             }
443         } catch (Exception JavaDoc e) {
444             logger.error("clear failed for "+this+" on "+substance,e);
445         }
446     }
447
448     /**
449      * Tells if this collection is actually an array.<p>
450      *
451      * @return true if an array
452      */

453
454     public boolean isArray() {
455         return getType()!=null && getType().isArray();
456     }
457
458     /**
459      * Gets the collection object represented by this collection
460      * item.
461      *
462      * <p>It returns a <code>java.util.Collection</code> representation of
463      * the actual collection (i.e. either a <code>Collection</code>, a
464      * <code>Map</code>, or an array).
465      *
466      * <p>The programmer should rather use the methods that gets the
467      * actual collection by using the accessor for this collection if
468      * any since it allows possible aspects applications if needed.
469      *
470      * @return the actual object collection representation
471      * @see #getActualCollectionThroughAccessor(Object)
472      * @see #toCollection(Object) */

473
474     public Collection JavaDoc getActualCollection(Object JavaDoc substance) {
475         Object JavaDoc value = null;
476
477         try {
478             value = ((Field JavaDoc)delegate).get(substance);
479         } catch (Exception JavaDoc e) {
480             logger.error("getActualCollection("+getName()+") failed",e);
481             return null;
482         }
483         return toCollection(value);
484     }
485
486     /**
487      * Gets the collection object represented by this collection item
488      * by using the accessor defined in the class containing this
489      * collection if any.
490      *
491      * <p>Use this method to be sure that all the aspects will be
492      * applied to the substance when the collection is retrieved.
493      *
494      * <p>It returns a <code>java.util.Collection</code> representation of
495      * the actual collection (i.e. either a <code>Collection</code>, a
496      * <code>Map</code>, or an array).
497      *
498      * @return the actual object collection representation
499      * @see #getActualCollection(Object)
500      * @see #toCollection(Object)
501      */

502     public Collection JavaDoc getActualCollectionThroughAccessor(Object JavaDoc substance) {
503         Object JavaDoc value = getThroughAccessor(substance);
504         return value!=null ? toCollection(value) : new ArrayList JavaDoc();
505     }
506
507     /**
508      * A useful method to convert any kind of collection to a
509      * <code>java.util.Collection</code> compatible instance.
510      *
511      * <p>Supported converted value types are
512      * <code>java.util.Collection</code>, <code>java.util.Map</code>,
513      * and Java arrays.
514      *
515      * @param value an object of one of the supported types
516      * @return the collection compliant converted value */

517
518     public Collection JavaDoc toCollection(Object JavaDoc value) {
519         if (value == null) return null;
520
521         if (value instanceof Collection JavaDoc) {
522             return (Collection JavaDoc)value;
523         } else if (value instanceof Map JavaDoc) {
524             if (isIndex())
525                 return ((Map JavaDoc)value).values();
526             else
527                 return ((Map JavaDoc)value).entrySet();
528         } else if (value.getClass().isArray()) {
529             if (value.getClass().getComponentType()==Object JavaDoc.class) {
530                 return Arrays.asList( (Object JavaDoc[]) value );
531             } else {
532                 int length = Array.getLength(value);
533                 Vector JavaDoc result = new Vector JavaDoc(length);
534                 for (int i=0; i<length; i++) {
535                     result.add(Array.get(value,i));
536                 }
537                 return result;
538             }
539         }
540         return null;
541     }
542
543     /**
544      * Adds an item to the collection.<p>
545      *
546      * The <code>extraInfos</code> param must represent a key if the
547      * collection is an hastable. If the collection is a
548      * <code>java.util</code> collection or if it is an array, the
549      * extra informations can be null (in this case, the new item is
550      * added at the end of the collection), and they can be not
551      * null. In this case, it must be an <code>Integer</code> instance
552      * that represents the index of the new item within the
553      * collection (must be a list in this case).<p>
554      *
555      * @param substance the collection where to add the new item
556      * @param newItem the item to add
557      * @param extraInfos this optional parameter must be used when the
558      * collection need some other information when adding a item to it
559      * as, for instance the key for a map or the index for a list
560      */

561     public void add(Object JavaDoc substance, Object JavaDoc newItem, Object JavaDoc extraInfos) {
562
563         Field JavaDoc f = (Field JavaDoc) delegate;
564
565         try {
566             if (isSet() || isList()) {
567                 // Set and List
568
if ( extraInfos == null ) {
569                     ((Collection JavaDoc)f.get(substance)).add(newItem);
570                 } else {
571                     ((List JavaDoc)f.get(substance)).add(
572                         ((Integer JavaDoc)extraInfos).intValue(), newItem);
573                 }
574             } else if (isMap()) {
575                 // Map
576
((Map JavaDoc)f.get(substance)).put(extraInfos, newItem);
577             } else if (isArray()) {
578                 // Arrays
579
// THIS IS BUGGED !!!
580
if (extraInfos == null) {
581                     Object JavaDoc oldArray = f.get(substance);
582                     int index = 0;
583                     if (oldArray != null) {
584                         index = Array.getLength(oldArray);
585                     }
586                     Object JavaDoc newArray;
587                     f.set( substance,
588                            newArray = Array.newInstance(
589                                getType().getComponentType(), index+1 ) );
590
591                     if (oldArray != null) {
592                         for(int i=0; i<index; i++) {
593                             Array.set(newArray, i, Array.get(oldArray, i));
594                         }
595                     }
596                
597                     Array.set(newArray, index, newItem);
598
599                 } else {
600                     ((Object JavaDoc[])f.get(substance))[((Integer JavaDoc)extraInfos).intValue()] = newItem;
601                     //arrayAddingIndex = ((Integer)extraInfos).intValue() + 1;
602
}
603             }
604         } catch ( Exception JavaDoc e ) {
605             logger.error("add "+substance+"."+getName()+" "+newItem+","+extraInfos,e);
606         }
607     }
608
609     /**
610      * Removes an item from the collection, using the remover method if it has one.
611      * @param substance object on which to remove
612      * @param item object to remove from the collection
613      */

614     public void removeThroughRemover(Object JavaDoc substance, Object JavaDoc item) {
615         ((ClassItem)parent).buildFieldInfo();
616         MethodItem remover = getRemover();
617         if (remover!=null) {
618             remover.invoke(substance,new Object JavaDoc[] {item});
619         } else {
620             logger.warn("No remover for collection "+this);
621             remove(substance,item,null);
622         }
623     }
624
625     /**
626      * Removes an item from the collection.<p>
627      *
628      * The <code>extraInfos</code> param must represent a key if the
629      * collection is an hastable. If the collection is a
630      * <code>java.util</code> collection or if it is an array, the
631      * extra informations can be null (in this case, the new item is
632      * added at the end of the collection), and they can be not
633      * null. In this case, it must be an <code>Integer</code> instance
634      * that represents the index of the new item within the
635      * collection (must be a list in this case).<p>
636      *
637      * @param substance the collection where to remove the new item
638      * @param item the item to remove (can be null if extra infos are
639      * not null)
640      * @param extraInfos this optional parameter must be used when the
641      * collection need some other information when adding a item to it
642      * as, for instance the key for a map, or the index in a list */

643
644     public void remove(Object JavaDoc substance, Object JavaDoc item, Object JavaDoc extraInfos) {
645         Field JavaDoc f = (Field JavaDoc)delegate;
646
647         try {
648       
649             if (Collection JavaDoc.class.isAssignableFrom(getType())) {
650                 // Set and List
651
if (extraInfos == null) {
652                     ((Collection JavaDoc)f.get(substance)).remove(item);
653                 } else {
654                     int index = ((Integer JavaDoc)extraInfos).intValue();
655                     ((List JavaDoc)f.get(substance)).remove(index);
656                 }
657             } else if (Map JavaDoc.class.isAssignableFrom(getType())) {
658                 // Map
659
((Map JavaDoc)f.get(substance)).remove(extraInfos);
660             } else if (getType().isArray()) {
661                 // Arrays
662
// THIS IS BUGGED !!!
663
if (extraInfos == null) {
664                     Object JavaDoc oldArray = f.get(substance);
665                     int index = 0;
666                     if (oldArray != null) {
667                         index = Array.getLength(oldArray);
668                     }
669                     Object JavaDoc newArray;
670                     f.set( substance,
671                            newArray = Array.newInstance(
672                                getType().getComponentType(), index-1 ) );
673
674                     if (oldArray != null) {
675                         for( int i=0; i<index; i++) {
676                             Array.set(newArray, i, Array.get(oldArray,i));
677                         }
678                     }
679                
680                     //Array.set( newArray, index, newItem );
681

682                 } else {
683                     //((Object[])f.get( substance ))[((Integer)extraInfos).intValue()] = item;
684
//arrayAddingIndex = ((Integer)extraInfos).intValue() + 1;
685
}
686             }
687         } catch (Exception JavaDoc e) {
688             logger.error("remove "+substance+"."+getName()+" "+item+","+extraInfos,e);
689         }
690       
691     }
692
693     /**
694      * Tells wether an object's collection contains an given object
695      * @param substance
696      * @param object the object to search
697      * @return true if substance.collection.contains(object)
698      */

699     public boolean contains(Object JavaDoc substance, Object JavaDoc object) {
700         if (!isArray()) {
701             Collection JavaDoc collection = (Collection JavaDoc)getThroughAccessor(substance);
702             return collection.contains(object);
703         } else {
704             throw new RuntimeException JavaDoc(
705                 "CollectionItem.contains(substance,object) is not implemented for arrays");
706         }
707     }
708
709     public Object JavaDoc getMap(Object JavaDoc substance, Object JavaDoc key) {
710         if (!isMap()) {
711             throw new RuntimeException JavaDoc("Cannot call getMap() on "+this);
712         }
713         try {
714             return getMap(substance).get(key);
715         } catch(IllegalAccessException JavaDoc e) {
716             logger.error("getMap "+substance+"."+getName()+" "+key,e);
717         }
718         return null;
719     }
720
721     protected Map JavaDoc getMap(Object JavaDoc substance) throws IllegalAccessException JavaDoc {
722         return (Map JavaDoc)((Field JavaDoc)delegate).get(substance);
723     }
724
725     /**
726      * Tells if this collection item is compliant with a
727      * <code>java.util.List</code> interface.
728      *
729      * @return true if compliant */

730
731     public boolean isList() {
732         return List JavaDoc.class.isAssignableFrom(getType());
733     }
734    
735     /**
736      * Tells if this collection item is compliant with a
737      * <code>java.util.Map</code> interface.
738      *
739      * @return true if compliant */

740
741     public boolean isMap() {
742         return Map JavaDoc.class.isAssignableFrom(getType());
743     }
744    
745     public boolean isIndex() {
746         return RttiAC.isIndex(this);
747     }
748
749     /**
750      * Tells if this collection item is compliant with a
751      * <code>java.util.Set</code> interface.
752      *
753      * @return true if compliant */

754
755     public boolean isSet() {
756         return java.util.Set JavaDoc.class.isAssignableFrom(getType());
757     }
758    
759     /**
760      * Always returns false for collections (maybe not very
761      * semantically clear).
762      *
763      * @return false */

764
765     public boolean isPrimitive() {
766         return false;
767     }
768
769     /**
770      * Always returns false for collections (maybe not very
771      * semantically clear).
772      *
773      * @return false */

774
775     public boolean isReference() {
776         return false;
777     }
778
779     public FieldItem clone(ClassItem parent) {
780         CollectionItem clone = null;
781         try {
782             if (isCalculated)
783                 clone = new CollectionItem(name,getter,parent);
784             else
785                 clone = new CollectionItem((Field JavaDoc)delegate,parent);
786             clone.setAdder(adder);
787             clone.setRemover(remover);
788         } catch(Exception JavaDoc e) {
789             logger.error("Failed to clone collection "+this);
790         }
791         return clone;
792     }
793
794     public static final CollectionItem[] emptyArray = new CollectionItem[0];
795 }
796
Popular Tags