KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > jofti > introspect > JavaBeanClassIntrospector


1 /*
2  * ObjectInspector.java
3  *
4  * Created on 11 May 2003, 18:59
5  */

6
7 package com.jofti.introspect;
8
9 import java.io.File JavaDoc;
10 import java.io.ObjectStreamField JavaDoc;
11 import java.lang.reflect.Array JavaDoc;
12 import java.lang.reflect.InvocationTargetException JavaDoc;
13 import java.lang.reflect.Method JavaDoc;
14 import java.nio.ByteBuffer JavaDoc;
15 import java.nio.CharBuffer JavaDoc;
16 import java.nio.DoubleBuffer JavaDoc;
17 import java.nio.FloatBuffer JavaDoc;
18 import java.nio.IntBuffer JavaDoc;
19 import java.nio.LongBuffer JavaDoc;
20 import java.nio.ShortBuffer JavaDoc;
21 import java.nio.charset.Charset JavaDoc;
22 import java.sql.Timestamp JavaDoc;
23 import java.text.CollationKey JavaDoc;
24 import java.util.ArrayList JavaDoc;
25 import java.util.Collection JavaDoc;
26 import java.util.HashMap JavaDoc;
27 import java.util.HashSet JavaDoc;
28 import java.util.Iterator JavaDoc;
29 import java.util.List JavaDoc;
30 import java.util.Map JavaDoc;
31 import java.util.Set JavaDoc;
32
33 import org.apache.commons.logging.Log;
34 import org.apache.commons.logging.LogFactory;
35
36 import com.jofti.btree.ValueObject;
37 import com.jofti.config.IndexConfig;
38 import com.jofti.exception.JoftiException;
39 import com.jofti.exception.PropertyNotIndexedException;
40 import com.jofti.model.ComparableBoolean;
41 import com.jofti.model.ParsedObject;
42 import com.jofti.util.ReflectionUtil;
43
44 import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap;
45
46
47 /**
48  * A JavaBean idiom compliant introspector. This means that Objects have to implement thet getter/setter
49  * metaphor in order to be correctly interrogated.</p>
50  *
51  * The general usage of the parsing is package.Class.property. This value needs to be specified int he config file
52  * in this format and the introspector will use this mechanism to navigate to the correct property. </p>
53  * @author xenephon (xenephon@jofti.com)
54  */

55 public class JavaBeanClassIntrospector implements ClassIntrospector
56 {
57     
58     private static Log log = LogFactory.getLog(JavaBeanClassIntrospector.class);
59
60
61     private static final String JavaDoc METHOD_PREFIX = "get";
62     
63     private static final Class JavaDoc[] noArgs = new Class JavaDoc[]{};
64     
65     private static final int KEY_DIMENSION_VALUE = -1;
66     
67     private static int keyDimensionCount = KEY_DIMENSION_VALUE;
68     
69     private static final String JavaDoc NULL_ATTRIBUTE = "NULL METHOD";
70     
71     private static final String JavaDoc ARRAY_ATTRIBUTE = "[element]";
72     
73     
74     private static Method JavaDoc ARRAY_METHOD = null;
75     
76     private static Method JavaDoc COLLECTIONS_METHOD = null;
77     
78     private static Method JavaDoc NULL_METHOD = null;
79     
80     private static final Set JavaDoc defaultClasses = new HashSet JavaDoc();
81     
82     static {
83             defaultClasses.add( java.lang.String JavaDoc.class);
84             defaultClasses.add( java.lang.Integer JavaDoc.class);
85             defaultClasses.add( java.lang.Double JavaDoc.class);
86             defaultClasses.add( java.lang.Float JavaDoc.class);
87             defaultClasses.add( java.lang.Long JavaDoc.class);
88             defaultClasses.add( java.lang.Short JavaDoc.class);
89             defaultClasses.add( java.lang.Byte JavaDoc.class);
90             defaultClasses.add( java.lang.Character JavaDoc.class);
91             defaultClasses.add(java.math.BigInteger JavaDoc.class);
92             defaultClasses.add(java.math.BigDecimal JavaDoc.class);
93             defaultClasses.add(java.util.Date JavaDoc.class);
94             defaultClasses.add(Timestamp JavaDoc.class);
95             defaultClasses.add(java.net.URI JavaDoc.class);
96             defaultClasses.add(ComparableBoolean.class);
97
98             defaultClasses.add( java.lang.String JavaDoc[].class);
99             defaultClasses.add( java.lang.Integer JavaDoc[].class);
100             defaultClasses.add( java.lang.Double JavaDoc[].class);
101             defaultClasses.add( java.lang.Float JavaDoc[].class);
102             defaultClasses.add( java.lang.Long JavaDoc[].class);
103             defaultClasses.add( java.lang.Short JavaDoc[].class);
104             defaultClasses.add( java.lang.Byte JavaDoc[].class);
105             defaultClasses.add( java.lang.Character JavaDoc[].class);
106             defaultClasses.add(java.math.BigInteger JavaDoc[].class);
107             defaultClasses.add(java.math.BigDecimal JavaDoc[].class);
108             defaultClasses.add(java.util.Date JavaDoc[].class);
109             defaultClasses.add(Timestamp JavaDoc[].class);
110             defaultClasses.add(java.net.URI JavaDoc[].class);
111             defaultClasses.add(ComparableBoolean[].class);
112             defaultClasses.add(java.lang.Boolean JavaDoc[].class);
113             defaultClasses.add(int[].class);
114             defaultClasses.add(long[].class);
115             defaultClasses.add(short[].class);
116             defaultClasses.add(byte[].class);
117             defaultClasses.add(boolean[].class);
118             defaultClasses.add(char[].class);
119             defaultClasses.add(float[].class);
120             defaultClasses.add(double[].class);
121         }
122     
123     private static final Set JavaDoc excludedComparableClasses = new HashSet JavaDoc();
124     
125     static {
126         excludedComparableClasses.add( ByteBuffer JavaDoc.class);
127         excludedComparableClasses.add( CharBuffer JavaDoc.class);
128         excludedComparableClasses.add( Charset JavaDoc.class);
129         excludedComparableClasses.add( CollationKey JavaDoc.class);
130         excludedComparableClasses.add( DoubleBuffer JavaDoc.class);
131         excludedComparableClasses.add( File JavaDoc.class);
132         excludedComparableClasses.add( FloatBuffer JavaDoc.class);
133         excludedComparableClasses.add( IntBuffer JavaDoc.class);
134         excludedComparableClasses.add( LongBuffer JavaDoc.class);
135         excludedComparableClasses.add( ObjectStreamField JavaDoc.class);
136         excludedComparableClasses.add( ShortBuffer JavaDoc.class);
137         
138 }
139     
140     
141     static {
142         try{
143             ARRAY_METHOD = JavaBeanClassIntrospector.class.getDeclaredMethod("arrayMethod",
144                     new Class JavaDoc[]{});
145             
146             COLLECTIONS_METHOD = JavaBeanClassIntrospector.class.getDeclaredMethod("collectionsMethod",
147                     new Class JavaDoc[]{});
148             
149             NULL_METHOD = JavaBeanClassIntrospector.class.getDeclaredMethod("nullMethod",
150                     new Class JavaDoc[]{});
151         }catch (Exception JavaDoc e){
152             
153         }
154     }
155     
156     private void arrayMethod(){
157         
158     }
159     
160     private void nullMethod(){
161         
162     }
163     
164     private void collectionsMethod(){
165         
166     }
167
168    private Set JavaDoc primitiveSet = java.util.Collections.unmodifiableSet(defaultClasses);
169    
170     Map JavaDoc dimensionMap = new ConcurrentHashMap();
171     
172     Map JavaDoc interfaceMap = new ConcurrentHashMap();
173     
174     Map JavaDoc concreteMap = new ConcurrentHashMap();
175     
176     Map JavaDoc keyDimensionMap = new ConcurrentHashMap();
177   
178     
179     private ClassUtils utils = new ClassUtils();
180     
181     /* (non-Javadoc)
182      * @see com.jofti.introspect.ClassIntrospector#parseConfig(com.jofti.config.IndexConfig)
183      */

184     public void parseConfig(IndexConfig config) throws JoftiException {
185
186         Map JavaDoc configMap = config.getIndexMappings();
187         // check if we have a config map
188
if (configMap == null) {
189             return;
190         }
191
192         // starts at 0
193
int dimensionCount = 0;
194
195         // look through mappings to construct methods
196
for (Iterator JavaDoc it = configMap.keySet().iterator(); it.hasNext();) {
197             // what class are we dealing with
198
String JavaDoc className = (String JavaDoc) it.next();
199             Class JavaDoc clazz = null;
200
201             // see if the JVM knows about the class
202
try {
203                 clazz = ReflectionUtil.classForName(className);
204             } catch (Exception JavaDoc e) {
205                 log.info("No class found for " + className);
206                 throw new JoftiException(e);
207             }
208
209             // set up the parsed Object
210
ParsedObject parsedObject = new ParsedObject();
211
212             parsedObject.setClassValue(clazz);
213             Map JavaDoc classMap = new ConcurrentHashMap();
214             Map JavaDoc methodMap = new ConcurrentHashMap();
215             Map JavaDoc dimensionClassMap = new ConcurrentHashMap();
216             Map JavaDoc fieldMethodMap = new ConcurrentHashMap();
217             
218             parsedObject.setFieldValues(classMap);
219             parsedObject.setMethodValues(methodMap);
220             parsedObject.setDimensionClassMappings(dimensionClassMap);
221             parsedObject.setFieldMethods(fieldMethodMap);
222
223             // we need to look at proxy or interface stuff here
224
List JavaDoc properties = (List JavaDoc) configMap.get(className);
225             if (clazz.isInterface()) {
226                 parsedObject.setInterface(true);
227             }
228             // now we get the map of attributes to index
229

230             dimensionCount = parseAttribtes(dimensionCount, clazz, classMap,
231                     methodMap, dimensionClassMap, fieldMethodMap,properties);
232
233             dimensionMap.put(clazz, parsedObject);
234
235         }
236
237         parseBuiltInClasses(dimensionCount);
238     }
239
240     /**
241      * @param dimensionCount
242      * @param clazz
243      * @param classMap
244      * @param methodMap
245      * @param dimensionClassMap
246      * @param attributes
247      * @return
248      * @throws JoftiException
249      */

250     
251     
252     
253     private int parseAttribtes(int dimensionCount, Class JavaDoc clazz, Map JavaDoc classMap, Map JavaDoc methodMap, Map JavaDoc dimensionClassMap, Map JavaDoc fieldMethodMap, List JavaDoc attributes) throws JoftiException
254     {
255         
256         
257         if (attributes != null){
258             
259         
260          int size = attributes.size();
261             Iterator JavaDoc attribIterator = attributes.iterator();
262             for (int i=0;i<size;i++) {
263                 String JavaDoc attribute = (String JavaDoc)attribIterator.next();
264                 
265                     Object JavaDoc[] methods = getMethodArray(clazz, attribute);
266                     if (methods == null || methods.length ==0){
267                         throw new JoftiException("No getter method found for attribute " + attribute + " in class " + clazz);
268                     } else{
269                         
270                         
271                             Class JavaDoc returnType = null;
272                             if (methods[methods.length-1] == ARRAY_METHOD){
273                         
274                                 throw new JoftiException("terminating value cannot be an array type");
275                             }else if (methods[methods.length-1] instanceof Method JavaDoc){
276                                 returnType = ((Method JavaDoc)methods[methods.length-1]).getReturnType();
277                             }else{
278                                 // must contain the return value as an object
279
returnType = (Class JavaDoc)methods[methods.length-1];
280                             }
281                         
282                         
283                         // see if method type is a primitive we can change
284
if (returnType.isPrimitive() || returnType == Boolean JavaDoc.class){
285                             returnType = boxPrimitive(returnType);
286                         }
287                         
288                         // see if the final value from method array is comparable
289

290                         if (Comparable JavaDoc.class.isAssignableFrom(returnType) && !excludedComparableClasses.contains(returnType) ){
291                             Integer JavaDoc dimension = new Integer JavaDoc(dimensionCount);
292                             classMap.put(attribute,dimension);
293                             methodMap.put(methods,dimension );
294                             dimensionClassMap.put(dimension,returnType);
295                             fieldMethodMap.put(attribute,methods);
296                             dimensionCount++;
297                         } else{
298                             throw new JoftiException("Attribute " + attribute + " is not Comparable in class " +clazz + " or is an excluded Comparable type");
299                         }
300                     
301                     }
302             }
303             
304         }
305         return dimensionCount;
306     }
307
308     /**
309      * @param clazz
310      * @param attribute
311      * @return
312      */

313     public Object JavaDoc[] getMethodsForAttribute(Class JavaDoc clazz,String JavaDoc attribute) throws JoftiException{
314         
315         Object JavaDoc[] results =null;
316         
317     // first see if we already have the field
318
ParsedObject obj = (ParsedObject)dimensionMap.get(clazz);
319         if (obj != null){
320             // see if it one we have already specified
321
Map JavaDoc fieldMethods = obj.getFieldMethods();
322             // we have a parsed class
323

324             // see if it is a primitive class and value is value
325
if (fieldMethods.containsKey(NULL_ATTRIBUTE)){
326                  if ("value".equalsIgnoreCase(attribute)){
327                     return (Object JavaDoc[])fieldMethods.get(NULL_ATTRIBUTE);
328                  }else{
329                     throw new JoftiException("Attribute "+ attribute + " is not allowed for Class "+ clazz + " can only have attribute VALUE or must be a whole object ");
330                  }
331             }
332             results = (Object JavaDoc[])fieldMethods.get(attribute);
333             
334             if (results == null){
335                 
336                 // oj lets see if it is a primitive so it must have
337
// a null method
338

339                 results = getMethodArray(clazz,attribute);
340             }
341             return results;
342         }else{
343             results = getMethodArray(clazz,attribute);
344         }
345         return results;
346     }
347     
348     private Object JavaDoc[] getMethodArray(Class JavaDoc clazz, String JavaDoc attribute)throws JoftiException {
349         Object JavaDoc[] methods =null;
350         try {
351             methods = preProcessAttribute(attribute);
352             methods =constructMethodArray(methods, clazz);
353             
354         } catch (JoftiException e){
355             log.warn("No getter method found for attribute " + attribute + ": " + e);
356             throw new JoftiException("No getter method found for attribute " + attribute +" on " + clazz,e);
357         }
358         return methods;
359     }
360
361     /**
362      * @param dimensionCount
363      */

364     private void parseBuiltInClasses(int dimensionCount)
365     {
366         // now parse in the default classes
367
for (Iterator JavaDoc it = defaultClasses.iterator();it.hasNext();){
368             
369                 ParsedObject parsedObject = new ParsedObject();
370                 Class JavaDoc temp = (Class JavaDoc)it.next();
371                 parsedObject.setClassValue(temp);
372                 Map JavaDoc classMap = new HashMap JavaDoc();
373                 Map JavaDoc methodMap = new HashMap JavaDoc();
374                 Map JavaDoc fieldMethodMap = new HashMap JavaDoc();
375                 
376                 parsedObject.setFieldValues(classMap);
377                 parsedObject.setMethodValues(methodMap);
378                 parsedObject.setFieldMethods(fieldMethodMap);
379                 
380                 Integer JavaDoc dimension = new Integer JavaDoc(dimensionCount);
381                 String JavaDoc attribute =null;
382                 
383                 Object JavaDoc[] meth =null;
384                 if (temp.isArray()){
385                     meth = new Object JavaDoc[2];
386                     meth[0]=ARRAY_METHOD;
387                     meth[1]=temp.getComponentType();
388                     attribute= ARRAY_ATTRIBUTE;
389                 }else{
390                     meth = new Object JavaDoc[1];
391                     meth[0]=NULL_METHOD;
392                     attribute = NULL_ATTRIBUTE;
393                 }
394                 
395                 methodMap.put(meth,dimension);
396                 classMap.put(attribute,dimension);
397                 fieldMethodMap.put(attribute,meth);
398
399      
400             dimensionCount++;
401             dimensionMap.put(temp,parsedObject);
402         }
403     }
404     
405     public Class JavaDoc boxPrimitive(Class JavaDoc clazz){
406         if (clazz == Integer.TYPE){
407             return Integer JavaDoc.class;
408         }else if (clazz == Double.TYPE){
409             return Double JavaDoc.class;
410         }else if (clazz == Long.TYPE){
411             return Long JavaDoc.class;
412         }else if (clazz == Float.TYPE){
413             return Float JavaDoc.class;
414         }else if (clazz == Short.TYPE){
415             return Short JavaDoc.class;
416         }else if (clazz == Byte.TYPE){
417             return Byte JavaDoc.class;
418         }else if (clazz == Character.TYPE){
419             return Character JavaDoc.class;
420         }else{
421             return ComparableBoolean.class;
422         }
423     }
424     
425     /* (non-Javadoc)
426      * @see com.jofti.introspect.ClassIntrospector#getClassForAttribute(java.lang.Class, java.lang.String)
427      */

428     public Class JavaDoc getClassForAttribute(Class JavaDoc className, String JavaDoc attribute) throws JoftiException{
429         
430         ParsedObject obj = (ParsedObject)dimensionMap.get(className);
431         if (obj != null){
432             Object JavaDoc returnObj =null;
433             // first see if it has the null method
434
if ( (returnObj= obj.getFieldValues().get(NULL_ATTRIBUTE)) != null){
435                 // we should return the dimension ofr the primitive class itself
436
if (attribute != null && !"value".equalsIgnoreCase(attribute)){
437                     throw new JoftiException ("Only field value 'VALUE' can be used for class "+ className);
438                 }
439                 return className;
440             } else if ( (returnObj= obj.getFieldValues().get(ARRAY_ATTRIBUTE)) != null){
441                 // we should return the dimension ofr the primitive class itself
442
if (attribute.equalsIgnoreCase(ARRAY_ATTRIBUTE)){
443                         return className;
444                     }else{
445                         throw new PropertyNotIndexedException(" property "+ attribute + " cannot refer to an element in "+ className + " use "+ ARRAY_ATTRIBUTE);
446                         
447                     }
448                 
449             }else {
450                 try {
451                     return (Class JavaDoc) obj.getDimensionClassMappings().get(obj.getFieldValues().get(attribute));
452                 } catch (Throwable JavaDoc e){
453                     throw new PropertyNotIndexedException(" property "+ attribute + " not indexed in " + className);
454                 }
455             }
456         }else{
457             throw new PropertyNotIndexedException(" class "+ className + " not in index");
458         }
459     }
460     
461     
462     private Object JavaDoc[] preProcessAttribute(String JavaDoc attribute) throws JoftiException{
463         List JavaDoc tempList = new ArrayList JavaDoc();
464         int startFragment =0;
465         int endFragment =0;
466         boolean inArray=false;
467         if (attribute.length() ==1){
468             return new Object JavaDoc[]{attribute};
469         }
470         for (int i=0;i<attribute.length();i++){
471             if (attribute.charAt(i)=='['){
472                 inArray = true;
473                 startFragment =i;
474             }else if (attribute.charAt(i)==']'){
475                 
476                 endFragment =i;
477             }else if ( i ==attribute.length()-1){
478                 endFragment =i;
479             }
480             else if (! inArray){
481                 if (attribute.charAt(i)=='.'){
482                     endFragment = i;
483                 }
484             }else {
485                 
486             }
487             if (endFragment > startFragment ){
488                 // we should extract the string
489
if (inArray || i== attribute.length()-1){
490                     endFragment = endFragment+1;
491                 }
492                 String JavaDoc temp = attribute.substring(startFragment,endFragment);
493                 if (temp.startsWith(".")){
494                     temp = temp.substring(1);
495                 }
496
497                 tempList.add(temp);
498                 startFragment = endFragment;
499                 inArray =false;
500             }
501         }
502         return tempList.toArray();
503         
504     }
505     
506     private Object JavaDoc[] constructMethodArray(Object JavaDoc[] attributes,
507             Class JavaDoc originalClass) throws JoftiException {
508         
509         List JavaDoc methods = new ArrayList JavaDoc();
510
511         try {
512             // we have an array thing
513

514             
515             
516             Method JavaDoc tempMethod = null;
517             int j= attributes.length;
518             int k=0;
519             for (int i = 0; i < j; i++) {
520                 
521                 if (originalClass.isArray() && attributes[i].equals("[element]")){
522                     
523                     // check that the component type is not an object
524
if (originalClass.getComponentType().equals(Object JavaDoc.class)){
525                         throw new JoftiException("Types to be indexed in an Object array must be specified");
526                     }
527                     
528                     // add in the extra method that signifies an array
529
// make sure that element is the attribute
530

531                     methods.add(ARRAY_METHOD);
532                     
533                     // increment j
534

535                     originalClass = originalClass.getComponentType();
536                     methods.add(originalClass);
537                     
538                 }else if (originalClass.isArray()){
539                     // we have to get they type out of it
540
String JavaDoc tempClass = ((String JavaDoc)attributes[i]).substring(1,((String JavaDoc)attributes[i]).length()-1);
541                     methods.add(ARRAY_METHOD);
542                     Class JavaDoc elementClass =null;
543                     try{
544                         elementClass = ReflectionUtil.classForName(tempClass);
545                     } catch (Exception JavaDoc e){
546                         throw new JoftiException(e);
547                     }
548                     
549                     if (originalClass.getComponentType().isAssignableFrom(elementClass) ){
550                         originalClass = elementClass;
551                         
552                         methods.add(originalClass);
553                         
554                     }else{
555                         throw new JoftiException("element type "+ elementClass + " is not assignable to " + originalClass.getComponentType());
556                     }
557                     
558                 } else if (originalClass.isAssignableFrom(Collection JavaDoc.class) && attributes[i].equals("[element]")){
559                     
560                     // check that the component type is not an object
561
if (originalClass.getComponentType() == null || originalClass.getComponentType().equals(Object JavaDoc.class)){
562                         throw new JoftiException("Types to be indexed in a Collection must be specified by Type");
563                     }
564                     
565                     
566                 }else if (Collection JavaDoc.class.isAssignableFrom(originalClass)){
567                     
568                     String JavaDoc tempClass = ((String JavaDoc)attributes[i]).substring(1,((String JavaDoc)attributes[i]).length()-1);
569                     methods.add(COLLECTIONS_METHOD);
570                     Class JavaDoc elementClass =null;
571                     try{
572                         elementClass = ReflectionUtil.classForName(tempClass);
573                     } catch (Exception JavaDoc e){
574                         throw new JoftiException(e);
575                     }
576                     
577                     methods.add(elementClass);
578                     originalClass = elementClass;
579                 }else{
580                     
581                     
582                 
583                 
584                     tempMethod = getMethod(originalClass,(String JavaDoc)attributes[i],noArgs);
585         
586                     methods.add( tempMethod);
587                     originalClass = tempMethod.getReturnType();
588                     
589                 }
590                 
591             }
592
593         } catch (NoSuchMethodException JavaDoc nme) {
594             throw new JoftiException(nme);
595         }
596             
597
598             
599             
600             return methods.toArray();
601     }
602    
603     private Method JavaDoc getMethod(Class JavaDoc originalClass, String JavaDoc attribute, Class JavaDoc[] args) throws NoSuchMethodException JavaDoc
604     {
605             StringBuffer JavaDoc buf = new StringBuffer JavaDoc(attribute);
606             buf.setCharAt(0, Character.toUpperCase(buf.charAt(0)));
607             buf.insert(0, METHOD_PREFIX);
608             return originalClass.getMethod(buf.toString(), args);
609
610     }
611     
612
613     /* (non-Javadoc)
614      * @see com.jofti.introspect.ClassIntrospector#getDimension(java.lang.String, java.lang.String)
615      */

616     
617     public int getDimension(String JavaDoc className, String JavaDoc propertyName) throws JoftiException {
618         Class JavaDoc clazz = null;
619         
620         try {
621             clazz = ReflectionUtil.classForName(className);
622         } catch (Exception JavaDoc e){
623             log.info("No class found for " + className);
624             throw new JoftiException(e);
625         }
626         return getDimension(clazz, propertyName);
627     }
628     public int getDimension(Class JavaDoc clazz, String JavaDoc propertyName) throws JoftiException {
629
630         int temp =0;
631         ParsedObject obj = (ParsedObject)dimensionMap.get(clazz);
632         if (obj != null){
633             Object JavaDoc returnObj =null;
634             // first see if it has the null method
635
if ( (returnObj= obj.getFieldValues().get(NULL_ATTRIBUTE)) != null){
636                 // we should return the dimension ofr the primitive class itself
637
temp = ((Integer JavaDoc)returnObj).intValue();
638             } else if ( (returnObj= obj.getFieldValues().get(ARRAY_ATTRIBUTE)) != null){
639                 // we should return the dimension ofr the array class itself
640
temp = ((Integer JavaDoc)returnObj).intValue();
641             } else {
642                 try {
643                     temp = ((Integer JavaDoc)obj.getFieldValues().get(propertyName)).intValue();
644                 } catch (Throwable JavaDoc e){
645                     throw new PropertyNotIndexedException("no dimension found for property "+ propertyName);
646                 }
647             }
648         }else{
649             throw new PropertyNotIndexedException("no dimension found for class "+ clazz);
650         }
651         return temp;
652     }
653
654     /* (non-Javadoc)
655      * @see com.jofti.introspect.ClassIntrospector#getKeyDimension()
656      */

657     public int getKeyDimension() {
658         
659         return KEY_DIMENSION_VALUE;
660     }
661     
662     public synchronized int getKeyDimension(Class JavaDoc className) {
663         
664         Integer JavaDoc temp = (Integer JavaDoc)keyDimensionMap.get(className);
665         if (temp == null){
666             temp = new Integer JavaDoc(keyDimensionCount--);
667             keyDimensionMap.put(className, temp);
668         }
669         return temp.intValue();
670     }
671
672     /* (non-Javadoc)
673      * @see com.jofti.introspect.ClassIntrospector#getAttributeValues()
674      */

675     public Map JavaDoc getAttributeValues(Object JavaDoc obj) throws JoftiException {
676
677
678          if (obj == null){
679             return new HashMap JavaDoc(1);
680          }
681          
682          
683          obj =utils.wrapObject(obj);
684          
685          Class JavaDoc objClass = obj.getClass();
686          List JavaDoc parsedList = getParsedObjectsForClass(objClass);
687          
688          //
689
if (parsedList.size() >0){
690              return getValuesFromParsedObjects(obj,parsedList);
691          } else{
692
693              if (log.isDebugEnabled()){
694                  log.debug("no mapping found for class "+ objClass);
695              }
696             return new HashMap JavaDoc(1);
697          }
698     }
699
700     public List JavaDoc getParsedObjectsForClass(Class JavaDoc clazz){
701         List JavaDoc temp = new ArrayList JavaDoc();
702         
703         // first get the interfaces
704
Class JavaDoc[] interfaceArray = (Class JavaDoc[])interfaceMap.get(clazz);
705         if (interfaceArray == null){
706             interfaceArray = utils.getInterfaces(clazz);
707             // we can't cache proxy xlasses as they might change
708
if (!java.lang.reflect.Proxy.isProxyClass(clazz)){
709                 interfaceMap.put(clazz,interfaceArray);
710             }
711         }
712         temp = getParsedClassesForArray(interfaceArray,temp);
713         
714         // if not a proxy then do the concrete classes
715
if (!java.lang.reflect.Proxy.isProxyClass(clazz)){
716             Class JavaDoc[] concreteArray = (Class JavaDoc[])concreteMap.get(clazz);
717             if (concreteArray == null){
718                 concreteArray = utils.getClasses(clazz);
719                 concreteMap.put(clazz,concreteArray);
720             }
721             temp = getParsedClassesForArray(concreteArray,temp);
722         }
723         return temp;
724         
725     }
726     
727     private List JavaDoc getParsedClassesForArray(Class JavaDoc[] array, List JavaDoc temp){
728         for (int i=0;i<array.length;i++){
729             // get all the parsedObjects that match
730
ParsedObject parsedObj = (ParsedObject)dimensionMap.get(array[i]);
731             if (parsedObj != null){
732                 temp.add(parsedObj);
733             }
734         }
735         return temp;
736     }
737     
738      private Map JavaDoc getValuesFromParsedObjects(Object JavaDoc obj,List JavaDoc parsedObjects){
739          Map JavaDoc temp = new HashMap JavaDoc(2);
740          
741          for (int i=0;i<parsedObjects.size();i++){
742              ParsedObject parsedObj = (ParsedObject)parsedObjects.get(i);
743              temp = getValuesFromParsedObject(temp,obj,parsedObj);
744          }
745          return temp;
746      
747      }
748     
749       public Map JavaDoc getResultValuesFromObject(Map JavaDoc temp, Object JavaDoc obj,Map JavaDoc methodMap){
750         int size = methodMap.size();
751         Iterator JavaDoc it = methodMap.entrySet().iterator();
752            for (int j=0;j<size;j++) {
753             Object JavaDoc tempObj = obj;
754             // loop through the objects and index the value
755
// turn this into a queue
756
Map.Entry JavaDoc entry = (Map.Entry JavaDoc)it.next();
757             Object JavaDoc[] methods = (Object JavaDoc[])entry.getValue();
758             if (methods ==null){
759                 
760                 temp.put(entry.getKey(),tempObj);
761             } else {
762                 List JavaDoc results = new ArrayList JavaDoc();
763                 try {
764                     tempObj = processMethodArray(tempObj, methods);
765                     
766                     
767                     if (tempObj != null){
768                        
769                         temp.put(entry.getKey(),tempObj);
770                     }else{
771                         temp.put(entry.getKey(),null);
772                     }
773                 } catch (Exception JavaDoc e){
774                     throw new IllegalArgumentException JavaDoc(e.getMessage());
775                     
776                 }
777             }
778                 
779         }
780            return temp;
781         
782       }
783     private Map JavaDoc getValuesFromParsedObject(Map JavaDoc temp, Object JavaDoc obj,ParsedObject parsedObj){
784         
785         Set JavaDoc tempSet = parsedObj.getMethodValues().entrySet();
786         int size = tempSet.size();
787         Iterator JavaDoc it = tempSet.iterator();
788         for (int j=0;j<size;j++) {
789                 Object JavaDoc tempObj = obj;
790                 // loop through the objects and index the value
791
// turn this into a queue
792
Map.Entry JavaDoc entry = (Map.Entry JavaDoc)it.next();
793                 Object JavaDoc[] methods = (Object JavaDoc[])entry.getKey();
794                 if (methods ==null){
795                     
796                     temp.put(entry.getValue(),utils.wrapObject(tempObj));
797                 } else {
798                     List JavaDoc results = new ArrayList JavaDoc();
799                     try {
800                         tempObj = processMethodArray(tempObj, methods);
801                         
802                         
803                         if (tempObj != null){
804                            
805                             temp.put(entry.getValue(),utils.wrapObject(tempObj));
806                         }else{
807                             temp.put(entry.getValue(),ValueObject.MIN_COMAPARBLE_VALUE);
808                         }
809                     } catch (Exception JavaDoc e){
810                         throw new IllegalArgumentException JavaDoc(e.getMessage());
811                         
812                     }
813                 }
814                     
815             }
816             return temp;
817     }
818     
819     public Object JavaDoc getResultFromMethods(Object JavaDoc obj, Object JavaDoc[] methods) throws JoftiException{
820         Object JavaDoc retVal =null;
821         try {
822             retVal = processMethodArray(obj, methods);
823         }catch (Exception JavaDoc e){
824             throw new JoftiException(e);
825         }
826         return retVal;
827         
828     }
829     
830     /**
831      * @param tempObj
832      * @param methods
833      * @return
834      * @throws IllegalAccessException
835      * @throws InvocationTargetException
836      */

837     private Object JavaDoc processMethodArray(Object JavaDoc tempObj, Object JavaDoc[] methods) throws IllegalAccessException JavaDoc, InvocationTargetException JavaDoc {
838         for (int i =0;i <methods.length;i++){
839             if (tempObj == null){
840                 break;
841             }
842             if (methods[i] == ARRAY_METHOD){
843                 // we need to get the values
844
tempObj = getRealArrayValues(tempObj,(Class JavaDoc)methods[i+1]);
845             }else if (methods[i] == NULL_METHOD){
846                 // we need to use the actual value
847
// we do not need to do anything here
848
}else if (tempObj.getClass().isArray() && methods[i] instanceof Method JavaDoc){
849                 //apply the method to each object
850
tempObj = applyMethodsToArray(tempObj,(Method JavaDoc)methods[i]);
851             }else if (tempObj.getClass().isArray() && methods[i] instanceof Class JavaDoc){
852                 // get the values out of the array
853
tempObj = getArrayValues(tempObj,(Class JavaDoc)methods[i] );
854             }else if (methods[i] == COLLECTIONS_METHOD){
855                 // we need to get the values
856
tempObj = getRealCollectionValues((Collection JavaDoc)tempObj,(Class JavaDoc)methods[i+1]);
857             } else if (Collection JavaDoc.class.isAssignableFrom(tempObj.getClass()) && methods[i] instanceof Method JavaDoc){
858                 //apply the method to each object
859
tempObj = applyMethodsToCollection((Collection JavaDoc)tempObj,(Method JavaDoc)methods[i]);
860             }else if (Collection JavaDoc.class.isAssignableFrom(tempObj.getClass()) && methods[i] instanceof Class JavaDoc){
861                 // get the values out of the array
862
tempObj = getCollectionValues((Collection JavaDoc)tempObj,(Class JavaDoc)methods[i] );
863             }else {
864             
865                 tempObj = ((Method JavaDoc)methods[i]).invoke(tempObj,noArgs);
866             }
867         }
868         //tempObject = method.invoke(obj,noArgs);
869
return tempObj;
870     }
871
872     private Object JavaDoc[] applyMethodsToArray( Object JavaDoc array, Method JavaDoc meth){
873        
874         int size = Array.getLength(array);
875         List JavaDoc res = new ArrayList JavaDoc();
876         for (int i=0;i<size;i++){
877             
878             Object JavaDoc temp = Array.get(array,i);
879            
880             if (temp != null ){
881                 
882                 try {
883                 temp= meth.invoke(temp,noArgs);
884                 } catch (IllegalArgumentException JavaDoc e) {
885                     
886                     log.warn(e);
887                 } catch (IllegalAccessException JavaDoc e) {
888                     
889                     log.warn(e);
890                 } catch (InvocationTargetException JavaDoc e) {
891                     log.warn(e);
892                 }
893                 
894             }
895             if (temp != null){
896                 res.add(temp);
897             }
898         }
899         if (res.size() == 0){
900             return null;
901         }else{
902             return res.toArray();
903         }
904
905     }
906     
907     private Object JavaDoc[] applyMethodsToCollection( Collection JavaDoc col, Method JavaDoc meth){
908            
909         
910         List JavaDoc res = new ArrayList JavaDoc();
911         
912         int size = col.size();
913         Iterator JavaDoc it = col.iterator();
914         for (int i=0;i<size;i++) {
915             
916             Object JavaDoc temp = it.next();
917            
918             if (temp != null ){
919                 
920                 try {
921                 temp= meth.invoke(temp,noArgs);
922                 } catch (IllegalArgumentException JavaDoc e) {
923                     log.warn(e);
924                 } catch (IllegalAccessException JavaDoc e) {
925                     log.warn(e);
926                 
927                 } catch (InvocationTargetException JavaDoc e) {
928                     log.warn(e);
929                 }
930                 
931             }
932             if (temp != null){
933                 res.add(temp);
934             }
935         }
936         if (res.size() == 0){
937             return null;
938         }else{
939             return res.toArray();
940         }
941
942     }
943     private Object JavaDoc[] getArrayValues( Object JavaDoc array, Class JavaDoc type){
944            
945             int size = Array.getLength(array);
946             List JavaDoc res = new ArrayList JavaDoc();
947             for (int i=0;i<size;i++){
948                 
949                 Object JavaDoc temp = Array.get(array,i);
950                 if (type.isPrimitive() ){
951                        res.add(utils.wrapObject(temp));
952                    }else
953                 if (temp != null && (type.isAssignableFrom(temp.getClass()) ||type.isAssignableFrom(utils.wrapObject(temp.getClass()).getClass())) ){
954                     res.add(utils.wrapObject(temp));
955                 }
956             }
957             if (res.size() == 0){
958                 return null;
959             }else{
960                 return res.toArray();
961             }
962
963         }
964     
965     private Object JavaDoc[] getCollectionValues( Collection JavaDoc col, Class JavaDoc type){
966            
967
968         List JavaDoc res = new ArrayList JavaDoc();
969         int size = col.size();
970         Iterator JavaDoc it = col.iterator();
971         for (int i=0;i<size;i++) {
972             
973             Object JavaDoc temp = it.next();
974
975             if (temp != null && (type.isAssignableFrom(temp.getClass()) ||type.isAssignableFrom(utils.wrapObject(temp.getClass()).getClass())) ){
976                 res.add(utils.wrapObject(temp));
977             }
978         }
979         if (res.size() == 0){
980             return null;
981         }else{
982             return res.toArray();
983         }
984
985     }
986
987     private Object JavaDoc[] getRealCollectionValues( Collection JavaDoc col, Class JavaDoc type){
988            
989
990         List JavaDoc res = new ArrayList JavaDoc();
991         
992         int size = col.size();
993         Iterator JavaDoc it = col.iterator();
994         for (int i=0;i<size;i++) {
995             
996             Object JavaDoc temp = it.next();
997            
998             if (temp != null && (type.isAssignableFrom(temp.getClass()) ||type.isAssignableFrom(utils.wrapObject(temp.getClass()).getClass())) ){
999                 res.add(temp);
1000            }
1001        }
1002        if (res.size() == 0){
1003            return null;
1004        }else{
1005            return res.toArray();
1006        }
1007
1008    }
1009    
1010    
1011    
1012    private Object JavaDoc[] getRealArrayValues( Object JavaDoc array, Class JavaDoc type){
1013           
1014            int size = Array.getLength(array);
1015            List JavaDoc res = new ArrayList JavaDoc();
1016            for (int i=0;i<size;i++){
1017                
1018                Object JavaDoc temp = Array.get(array,i);
1019               if (array.getClass().getComponentType().isPrimitive()){
1020                   res.add(temp);
1021               }else
1022                if (temp != null && (type.isAssignableFrom(temp.getClass()) ||type.isAssignableFrom(utils.wrapObject(temp.getClass()).getClass())) ){
1023                    res.add(temp);
1024                }
1025            }
1026            if (res.size() == 0){
1027                return null;
1028            }else{
1029                return res.toArray();
1030            }
1031
1032        }
1033    /* (non-Javadoc)
1034     * @see com.jofti.introspect.ClassIntrospector#getKeyDimensions()
1035     */

1036    public Map JavaDoc getKeyDimensions() {
1037        return keyDimensionMap;
1038    }
1039
1040
1041    /* (non-Javadoc)
1042     * @see com.jofti.introspect.ClassIntrospector#getPrimitiveClasses()
1043     */

1044    public Set JavaDoc getPrimitiveClasses() {
1045        return primitiveSet;
1046    }
1047
1048
1049
1050    public Map JavaDoc getDimensions() {
1051
1052        return dimensionMap;
1053    }
1054    
1055
1056
1057}
1058
Popular Tags