KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > mx > mxbean > MXBeanUtils


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2006, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22 package org.jboss.mx.mxbean;
23
24 import java.lang.reflect.Array JavaDoc;
25 import java.lang.reflect.GenericArrayType JavaDoc;
26 import java.lang.reflect.InvocationHandler JavaDoc;
27 import java.lang.reflect.Method JavaDoc;
28 import java.lang.reflect.ParameterizedType JavaDoc;
29 import java.lang.reflect.Proxy JavaDoc;
30 import java.lang.reflect.Type JavaDoc;
31 import java.math.BigDecimal JavaDoc;
32 import java.math.BigInteger JavaDoc;
33 import java.util.Arrays JavaDoc;
34 import java.util.Collection JavaDoc;
35 import java.util.Collections JavaDoc;
36 import java.util.Date JavaDoc;
37 import java.util.HashMap JavaDoc;
38 import java.util.HashSet JavaDoc;
39 import java.util.Iterator JavaDoc;
40 import java.util.Map JavaDoc;
41 import java.util.Set JavaDoc;
42 import java.util.WeakHashMap JavaDoc;
43
44 import javax.management.DynamicMBean JavaDoc;
45 import javax.management.ObjectName JavaDoc;
46 import javax.management.openmbean.ArrayType JavaDoc;
47 import javax.management.openmbean.CompositeData JavaDoc;
48 import javax.management.openmbean.CompositeDataSupport JavaDoc;
49 import javax.management.openmbean.CompositeType JavaDoc;
50 import javax.management.openmbean.OpenType JavaDoc;
51 import javax.management.openmbean.SimpleType JavaDoc;
52 import javax.management.openmbean.TabularData JavaDoc;
53 import javax.management.openmbean.TabularDataSupport JavaDoc;
54 import javax.management.openmbean.TabularType JavaDoc;
55
56 import org.jboss.util.collection.WeakValueHashMap;
57
58 /**
59  * Utils.
60  *
61  * @author <a HREF="adrian@jboss.com">Adrian Brock</a>
62  * @version $Revision: 1.1 $
63  */

64 public class MXBeanUtils
65 {
66    /** A cache of methods to keys */
67    private static final Map JavaDoc<Method JavaDoc, String JavaDoc> compositeDataKeyCache = Collections.synchronizedMap(new WeakHashMap JavaDoc<Method JavaDoc, String JavaDoc>());
68
69    /** A cache of classes to key to getters */
70    private static final Map JavaDoc<Class JavaDoc, Map JavaDoc<String JavaDoc, Method JavaDoc>> compositeDataMethodCache = Collections.synchronizedMap(new WeakHashMap JavaDoc<Class JavaDoc, Map JavaDoc<String JavaDoc, Method JavaDoc>>());
71    
72    /** The map key */
73    public static final String JavaDoc MAP_KEY = "key";
74
75    /** The map value */
76    public static final String JavaDoc MAP_VALUE = "value";
77    
78    /** Map index names */
79    public static final String JavaDoc[] MAP_INDEX_NAMES = { MAP_KEY };
80    
81    /** Map item names */
82    public static final String JavaDoc[] MAP_ITEM_NAMES = { MAP_KEY, MAP_VALUE };
83    
84    /**
85     * Get the OpenType for a class
86     *
87     * @param type the type
88     * @return the open type
89     */

90    public static OpenType JavaDoc getOpenType(Type JavaDoc type)
91    {
92       if (type == null)
93          throw new IllegalArgumentException JavaDoc("Null type");
94
95       OpenType JavaDoc result = checkType(type);
96       if (result != null)
97          return result;
98       Class JavaDoc clazz = (Class JavaDoc) type;
99       return CompositeTypeMetaDataFactory.getCompositeType(clazz);
100    }
101
102    /**
103     * Get the SimpleType for a class
104     *
105     * @param type the type
106     * @return the open type
107     * @throws Exception for any error
108     */

109    public static SimpleType JavaDoc getSimpleType(Class JavaDoc type) throws Exception JavaDoc
110    {
111       SimpleType JavaDoc simpleType = checkSimpleType(type);
112       if (simpleType == null)
113          throw new IllegalArgumentException JavaDoc("Not a SimpleType: " + type.getName());
114       return simpleType;
115    }
116
117    /**
118     * Get the for a class that is not composite
119     *
120     * @param type the type
121     * @return the open type or null if composite
122     */

123    public static OpenType JavaDoc checkType(Type JavaDoc type)
124    {
125       OpenType JavaDoc result = checkSimpleType(type);
126       if (result != null)
127          return result;
128       result = checkEnum(type);
129       if (result != null)
130          return result;
131       result = checkArray(type);
132       if (result != null)
133          return result;
134       result = checkCollection(type);
135       if (result != null)
136          return result;
137       return checkMap(type);
138    }
139    
140    /**
141     * Create a composite data proxy
142     *
143     * @param <T> the interface type
144     * @param intf the interface type
145     * @param compositeData the composite data
146     * @return the proxy
147     */

148    public static <T> T createCompositeDataProxy(Class JavaDoc<T> intf, CompositeData JavaDoc compositeData)
149    {
150       if (intf == null)
151          throw new IllegalArgumentException JavaDoc("Null interface");
152       InvocationHandler JavaDoc handler = new CompositeDataInvocationHandler(compositeData);
153       Object JavaDoc object = Proxy.newProxyInstance(intf.getClassLoader(), new Class JavaDoc[] { intf }, handler);
154       return intf.cast(object);
155    }
156    
157    /**
158     * Construct some open data
159     *
160     * @param type the type
161     * @param value the value
162     * @param context the context
163     * @return the open data
164     * @throws Exception for any error
165     */

166    public static Object JavaDoc construct(Type JavaDoc type, Object JavaDoc value, Object JavaDoc context) throws Exception JavaDoc
167    {
168       OpenType JavaDoc openType = getOpenType(type);
169       return construct(openType, value, context);
170    }
171    
172    /**
173     * Construct some open data
174     *
175     * @param openType the open type
176     * @param value the value
177     * @param context the context
178     * @return the open data
179     * @throws Exception for any error
180     */

181    public static Object JavaDoc construct(OpenType JavaDoc openType, Object JavaDoc value, Object JavaDoc context) throws Exception JavaDoc
182    {
183       if (openType instanceof SimpleType JavaDoc)
184          return constructSimpleData(value);
185       if (openType.isArray())
186          return constructArrayData(openType, value, context);
187       if (openType instanceof TabularType JavaDoc)
188          return constructTabularData(openType, value, context);
189       return constructCompositeData(openType, value, context);
190    }
191    
192    /**
193     * Reconstruct a type from an object
194     *
195     * @param type the type
196     * @param value the value
197     * @param context for error reporting
198     * @return the object
199     * @throws Exception for any error
200     */

201    public static Object JavaDoc reconstruct(Type JavaDoc type, Object JavaDoc value, Object JavaDoc context) throws Exception JavaDoc
202    {
203       OpenType JavaDoc openType = MXBeanUtils.getOpenType(type);
204       return reconstruct(openType, type, value, context);
205    }
206    
207    /**
208     * Reconstruct a type from an object
209     *
210     * @param openType the open type
211     * @param type the type
212     * @param value the value
213     * @param context for error reporting
214     * @return the object
215     * @throws Exception for any error
216     */

217    public static Object JavaDoc reconstruct(OpenType JavaDoc openType, Type JavaDoc type, Object JavaDoc value, Object JavaDoc context) throws Exception JavaDoc
218    {
219       if (openType instanceof SimpleType JavaDoc)
220          return reconstructSimpleData(type, value, context);
221       if (openType.isArray())
222          return reconstructArrayData(openType, type, value, context);
223       if (openType instanceof TabularType JavaDoc)
224          return reconstructTabularData(openType, type, value, context);
225       return reconstructCompositeData(openType, type, value, context);
226    }
227
228    /**
229     * Get the SimpleType for a class
230     *
231     * @param type the type
232     * @return the simple type or null if not a simple type
233     */

234    public static SimpleType JavaDoc checkSimpleType(Type JavaDoc type)
235    {
236       if (BigDecimal JavaDoc.class.equals(type))
237          return SimpleType.BIGDECIMAL;
238       if (BigInteger JavaDoc.class.equals(type))
239          return SimpleType.BIGINTEGER;
240       if (Boolean JavaDoc.class.equals(type))
241          return SimpleType.BOOLEAN;
242       if (Boolean.TYPE.equals(type))
243          return SimpleType.BOOLEAN;
244       if (Byte JavaDoc.class.equals(type))
245          return SimpleType.BYTE;
246       if (Byte.TYPE.equals(type))
247          return SimpleType.BYTE;
248       if (Character JavaDoc.class.equals(type))
249          return SimpleType.CHARACTER;
250       if (Character.TYPE.equals(type))
251          return SimpleType.CHARACTER;
252       if (Date JavaDoc.class.equals(type))
253          return SimpleType.DATE;
254       if (Double JavaDoc.class.equals(type))
255          return SimpleType.DOUBLE;
256       if (Double.TYPE.equals(type))
257          return SimpleType.DOUBLE;
258       if (Float JavaDoc.class.equals(type))
259          return SimpleType.FLOAT;
260       if (Float.TYPE.equals(type))
261          return SimpleType.FLOAT;
262       if (Integer JavaDoc.class.equals(type))
263          return SimpleType.INTEGER;
264       if (Integer.TYPE.equals(type))
265          return SimpleType.INTEGER;
266       if (Long JavaDoc.class.equals(type))
267          return SimpleType.LONG;
268       if (Long.TYPE.equals(type))
269          return SimpleType.LONG;
270       if (ObjectName JavaDoc.class.equals(type))
271          return SimpleType.OBJECTNAME;
272       if (Short JavaDoc.class.equals(type))
273          return SimpleType.SHORT;
274       if (Short.TYPE.equals(type))
275          return SimpleType.SHORT;
276       if (String JavaDoc.class.equals(type))
277          return SimpleType.STRING;
278       if (Void JavaDoc.class.equals(type))
279          return SimpleType.VOID;
280       return null;
281    }
282
283    /**
284     * Get the simple type for an enum
285     *
286     * @param type the type
287     * @return return the enum type or null if it is not an enum
288     */

289    public static SimpleType JavaDoc checkEnum(Type JavaDoc type)
290    {
291       if (type instanceof Class JavaDoc == false)
292          return null;
293       Class JavaDoc clazz = (Class JavaDoc) type;
294       if (clazz.isEnum() || Enum JavaDoc.class.equals(clazz))
295          return SimpleType.STRING;
296       return null;
297    }
298
299    /**
300     * Construct a simple type open data
301     *
302     * @param value the value
303     * @return the simple type
304     */

305    public static Object JavaDoc constructSimpleData(Object JavaDoc value)
306    {
307       if (value != null && value instanceof Enum JavaDoc)
308       {
309          Enum JavaDoc enumeration = (Enum JavaDoc) value;
310          return enumeration.name();
311       }
312       return value;
313    }
314
315    /**
316     * Reconstruct a simple type open data
317     *
318     * @param type the type
319     * @param value the value
320     * @param context the context
321     * @return the simple type
322     */

323    @SuppressWarnings JavaDoc("unchecked")
324    private static Object JavaDoc reconstructSimpleData(Type JavaDoc type, Object JavaDoc value, Object JavaDoc context)
325    {
326       if (type instanceof Class JavaDoc)
327       {
328          if (value != null)
329          {
330             Class JavaDoc clazz = (Class JavaDoc) type;
331             if (clazz.isEnum() || Enum JavaDoc.class.equals(clazz))
332             {
333                String JavaDoc string = (String JavaDoc) value;
334                return Enum.valueOf(clazz, string);
335             }
336          }
337          else
338          {
339             Class JavaDoc clazz = (Class JavaDoc) type;
340             if (clazz.isPrimitive())
341                throw new IllegalArgumentException JavaDoc("Attempt to use null as a primitive for: " + context);
342             return null;
343          }
344       }
345       return value;
346    }
347
348    /**
349     * Get the array type for a class
350     *
351     * @param type the type
352     * @return return the array type or null if it is not an array
353     */

354    public static ArrayType JavaDoc checkArray(Type JavaDoc type)
355    {
356       if (type instanceof Class JavaDoc)
357       {
358          Class JavaDoc clazz = (Class JavaDoc) type;
359          if (clazz.isArray() == false)
360             return null;
361          int dimension = 1;
362          Class JavaDoc componentType = clazz.getComponentType();
363          while (componentType.isArray())
364          {
365             ++dimension;
366             componentType = componentType.getComponentType();
367          }
368          OpenType JavaDoc componentOpenType = getOpenType(componentType);
369          try
370          {
371             return new ArrayType JavaDoc(dimension, componentOpenType);
372          }
373          catch (RuntimeException JavaDoc e)
374          {
375             throw e;
376          }
377          catch (Exception JavaDoc e)
378          {
379             throw new RuntimeException JavaDoc(e);
380          }
381       }
382       if (type instanceof GenericArrayType JavaDoc)
383       {
384          GenericArrayType JavaDoc arrayType = (GenericArrayType JavaDoc) type;
385          int dimension = 1;
386          Type JavaDoc componentType = arrayType.getGenericComponentType();
387          while (componentType instanceof GenericArrayType JavaDoc)
388          {
389             ++dimension;
390             arrayType = (GenericArrayType JavaDoc) componentType;
391             componentType = arrayType.getGenericComponentType();
392          }
393          OpenType JavaDoc componentOpenType = getOpenType(componentType);
394          try
395          {
396             return new ArrayType JavaDoc(dimension, componentOpenType);
397          }
398          catch (RuntimeException JavaDoc e)
399          {
400             throw e;
401          }
402          catch (Exception JavaDoc e)
403          {
404             throw new RuntimeException JavaDoc(e);
405          }
406       }
407       return null;
408    }
409
410    /**
411     * Get the collection type for a class
412     *
413     * @param type the type
414     * @return return the array type or null if it is not a collection
415     */

416    public static ArrayType JavaDoc checkCollection(Type JavaDoc type)
417    {
418       if (type instanceof ParameterizedType JavaDoc == false)
419       {
420          if (type instanceof Class JavaDoc)
421             return checkCollectionClass((Class JavaDoc) type);
422          else
423             return null;
424       }
425       ParameterizedType JavaDoc parameterizedType = (ParameterizedType JavaDoc) type;
426       Type JavaDoc rawType = parameterizedType.getRawType();
427       if (rawType instanceof Class JavaDoc == false)
428          return null;
429       Class JavaDoc rawClass = (Class JavaDoc) rawType;
430       if (Collection JavaDoc.class.isAssignableFrom(rawClass) == false)
431          return null;
432       Type JavaDoc componentType = parameterizedType.getActualTypeArguments()[0];
433       OpenType JavaDoc componentOpenType = getOpenType(componentType);
434       try
435       {
436          return new ArrayType JavaDoc(1, componentOpenType);
437       }
438       catch (RuntimeException JavaDoc e)
439       {
440          throw e;
441       }
442       catch (Exception JavaDoc e)
443       {
444          throw new RuntimeException JavaDoc(e);
445       }
446    }
447
448    /**
449     * Get the collection type for a class
450     *
451     * @param clazz the class
452     * @return return the array type or null if it is not a collection
453     */

454    public static ArrayType JavaDoc checkCollectionClass(Class JavaDoc clazz)
455    {
456       if (Collection JavaDoc.class.isAssignableFrom(clazz) == false)
457          return null;
458       OpenType JavaDoc componentOpenType = getOpenType(Object JavaDoc.class);
459       try
460       {
461          return new ArrayType JavaDoc(1, componentOpenType);
462       }
463       catch (RuntimeException JavaDoc e)
464       {
465          throw e;
466       }
467       catch (Exception JavaDoc e)
468       {
469          throw new RuntimeException JavaDoc(e);
470       }
471    }
472
473    /**
474     * Construct an array type open data
475     *
476     * @param openType the open type
477     * @param value the value
478     * @param context the context
479     * @return the open data
480     * @throws Exception for any error
481     */

482    public static Object JavaDoc constructArrayData(OpenType JavaDoc openType, Object JavaDoc value, Object JavaDoc context) throws Exception JavaDoc
483    {
484       if (value == null)
485          return null;
486
487       ArrayType JavaDoc arrayType = (ArrayType JavaDoc) openType;
488       OpenType JavaDoc elementType = arrayType.getElementOpenType();
489       int dimension = arrayType.getDimension();
490
491       Class JavaDoc clazz = value.getClass();
492       if (clazz.isArray())
493       {
494          Object JavaDoc[] oldArray = (Object JavaDoc[]) value;
495          Class JavaDoc<?> componentType = Class.forName(arrayType.getClassName());
496          return constructArray(elementType, componentType.getComponentType(), dimension, oldArray, context);
497       }
498       if (value instanceof Collection JavaDoc)
499       {
500          Collection JavaDoc c = (Collection JavaDoc) value;
501          Object JavaDoc[] oldArray = c.toArray();
502          Class JavaDoc<?> componentType = Class.forName(arrayType.getClassName());
503          return constructArray(elementType, componentType.getComponentType(), dimension, oldArray, context);
504       }
505       throw new UnsupportedOperationException JavaDoc("Cannot construct array for: " + value);
506    }
507    
508    /**
509     * Construct an array of open data
510     *
511     * @param elementType the element type
512     * @param componentType the componentType
513     * @param dimension the dimension
514     * @param oldArray the old array
515     * @param context the context
516     * @return the array
517     * @throws Exception for any error
518     */

519    private static Object JavaDoc[] constructArray(OpenType JavaDoc elementType, Class JavaDoc<?> componentType, int dimension, Object JavaDoc[] oldArray, Object JavaDoc context) throws Exception JavaDoc
520    {
521       if (oldArray == null)
522          return null;
523       
524       Object JavaDoc[] newArray = (Object JavaDoc[]) Array.newInstance(componentType, oldArray.length);
525       if (dimension > 1)
526       {
527          for (int i = 0; i < oldArray.length; ++i)
528          {
529             Object JavaDoc[] nestedOld = (Object JavaDoc[]) oldArray[i];
530             newArray[i] = constructArray(elementType, componentType.getComponentType(), dimension-1, nestedOld, context);
531          }
532       }
533       else
534       {
535          if (Object JavaDoc.class.equals(componentType))
536          {
537             for (int i = 0; i < oldArray.length; ++i)
538                newArray[i] = oldArray[i];
539          }
540          else
541          {
542             for (int i = 0; i < oldArray.length; ++i)
543                newArray[i] = construct(elementType, oldArray[i], context);
544          }
545       }
546
547       return newArray;
548    }
549    
550    /**
551     * Reconstruct an array type
552     *
553     * @param openType the open type
554     * @param type the type
555     * @param value the value
556     * @param context the context
557     * @return the value
558     * @throws Exception for any error
559     */

560    public static Object JavaDoc reconstructArrayData(OpenType JavaDoc openType, Type JavaDoc type, Object JavaDoc value, Object JavaDoc context) throws Exception JavaDoc
561    {
562       if (value == null)
563          return null;
564
565       ArrayType JavaDoc arrayType = (ArrayType JavaDoc) getOpenType(type);
566       OpenType JavaDoc elementType = arrayType.getElementOpenType();
567       int dimension = arrayType.getDimension();
568       Object JavaDoc[] oldArray = (Object JavaDoc[]) value;
569       if (type instanceof Class JavaDoc)
570       {
571          Class JavaDoc clazz = (Class JavaDoc) type;
572          if (clazz.isArray())
573             return reconstructArray(elementType, clazz.getComponentType(), dimension, oldArray, context);
574          // TODO FIXME
575
// else if (Set.class.isAssignableFrom(clazz))
576
// return createSet(oldArray);
577
// else if (Collection.class.isAssignableFrom(clazz))
578
// return createCollection(oldArray);
579
}
580       else if (type instanceof ParameterizedType JavaDoc)
581       {
582          ParameterizedType JavaDoc parameterizedType = (ParameterizedType JavaDoc) type;
583          Type JavaDoc rawType = parameterizedType.getRawType();
584          if (rawType instanceof Class JavaDoc)
585          {
586             Class JavaDoc raw = (Class JavaDoc) rawType;
587             if (Set JavaDoc.class.isAssignableFrom(raw))
588                return createSet(oldArray);
589             else if (Collection JavaDoc.class.isAssignableFrom(raw))
590                return createCollection(oldArray);
591          }
592       }
593       throw new UnsupportedOperationException JavaDoc("Cannot convert array type: " + type);
594    }
595    
596    /**
597     * Reconstruct an array
598     *
599     * @param elementType the element type
600     * @param componentType the componentType
601     * @param dimension the dimension
602     * @param oldArray the old array of open data
603     * @param context the context
604     * @return the array
605     * @throws Exception for any error
606     */

607    private static Object JavaDoc[] reconstructArray(OpenType JavaDoc elementType, Class JavaDoc componentType, int dimension, Object JavaDoc[] oldArray, Object JavaDoc context) throws Exception JavaDoc
608    {
609       if (oldArray == null)
610          return null;
611       
612       Object JavaDoc[] newArray = (Object JavaDoc[]) Array.newInstance(componentType, oldArray.length);
613       if (dimension > 1)
614       {
615          for (int i = 0; i < oldArray.length; ++i)
616          {
617             Object JavaDoc[] nestedOld = (Object JavaDoc[]) oldArray[i];
618             newArray[i] = reconstructArray(elementType, componentType.getComponentType(), dimension-1, nestedOld, context);
619          }
620       }
621       else
622       {
623          for (int i = 0; i < oldArray.length; ++i)
624             newArray[i] = reconstruct(elementType, componentType, oldArray[i], context);
625       }
626
627       return newArray;
628    }
629
630    /**
631     * Create a collection
632     *
633     * @param array the array
634     * @return the collection
635     */

636    private static Collection JavaDoc createCollection(Object JavaDoc[] array)
637    {
638       return Arrays.asList(array);
639    }
640    
641    /**
642     * Create a set
643     *
644     * @param array the array
645     * @return the set
646     */

647    @SuppressWarnings JavaDoc("unchecked")
648    private static Set JavaDoc createSet(Object JavaDoc[] array)
649    {
650       HashSet JavaDoc result = new HashSet JavaDoc(array.length);
651       for (int i = 0; i < array.length; ++i)
652          result.add(array[i]);
653       return result;
654    }
655
656    /**
657     * Get the map type for a class
658     *
659     * @param type the type
660     * @return return the tabular type or null if it is not a collection
661     */

662    public static TabularType JavaDoc checkMap(Type JavaDoc type)
663    {
664       if (type instanceof ParameterizedType JavaDoc == false)
665       {
666          if (type instanceof Class JavaDoc)
667             return checkMapClass((Class JavaDoc) type);
668          else
669             return null;
670       }
671       ParameterizedType JavaDoc parameterizedType = (ParameterizedType JavaDoc) type;
672       Type JavaDoc rawType = parameterizedType.getRawType();
673       if (rawType instanceof Class JavaDoc == false)
674          return null;
675       Class JavaDoc rawClass = (Class JavaDoc) rawType;
676       if (Map JavaDoc.class.isAssignableFrom(rawClass) == false)
677          return null;
678       Type JavaDoc[] args = parameterizedType.getActualTypeArguments();
679       Type JavaDoc keyType = args[0];
680       Type JavaDoc valueType = args[1];
681       return createMapType(keyType, valueType);
682    }
683
684    /**
685     * Get the map type for a class
686     *
687     * @param clazz the class
688     * @return return the tabular type or null if it is not a collection
689     */

690    public static TabularType JavaDoc checkMapClass(Class JavaDoc clazz)
691    {
692       if (Map JavaDoc.class.isAssignableFrom(clazz) == false)
693          return null;
694       return createMapType(Object JavaDoc.class, Object JavaDoc.class);
695    }
696    
697    /**
698     * Create a map type
699     *
700     * @param keyType the key type
701     * @param valueType the value type
702     * @return the map type
703     */

704    public static TabularType JavaDoc createMapType(Type JavaDoc keyType, Type JavaDoc valueType)
705    {
706       String JavaDoc name = Map JavaDoc.class.getName();
707       OpenType JavaDoc[] itemTypes = { getOpenType(keyType), getOpenType(valueType) };
708       try
709       {
710          CompositeType JavaDoc entryType = createMapEntryType(itemTypes);
711          return new TabularType JavaDoc(name, name, entryType, MAP_INDEX_NAMES);
712       }
713       catch (RuntimeException JavaDoc e)
714       {
715          throw e;
716       }
717       catch (Exception JavaDoc e)
718       {
719          throw new RuntimeException JavaDoc(e);
720       }
721    }
722    
723    /**
724     * Create a map type
725     *
726     * @param itemTypes the item types
727     * @return the map entry type
728     */

729    private static CompositeType JavaDoc createMapEntryType(OpenType JavaDoc[] itemTypes)
730    {
731       String JavaDoc entryName = Map.Entry JavaDoc.class.getName();
732       try
733       {
734          return new CompositeType JavaDoc(entryName, entryName, MAP_ITEM_NAMES, MAP_ITEM_NAMES, itemTypes);
735       }
736       catch (RuntimeException JavaDoc e)
737       {
738          throw e;
739       }
740       catch (Exception JavaDoc e)
741       {
742          throw new RuntimeException JavaDoc(e);
743       }
744    }
745
746    /**
747     * Construct a tabular type open data
748     *
749     * @param openType the open type
750     * @param value the value
751     * @param context the context
752     * @return the open data
753     * @throws Exception for any error
754     */

755    @SuppressWarnings JavaDoc("unchecked")
756    public static Object JavaDoc constructTabularData(OpenType JavaDoc openType, Object JavaDoc value, Object JavaDoc context) throws Exception JavaDoc
757    {
758       if (value == null)
759          return null;
760
761       TabularType JavaDoc tabularType = (TabularType JavaDoc) openType;
762
763       if (value instanceof Map JavaDoc)
764       {
765          TabularDataSupport JavaDoc table = new TabularDataSupport JavaDoc(tabularType);
766          CompositeType JavaDoc entryType = tabularType.getRowType();
767          OpenType JavaDoc keyType = entryType.getType(MAP_KEY);
768          OpenType JavaDoc valueType = entryType.getType(MAP_VALUE);
769          
770          Map JavaDoc<Object JavaDoc, Object JavaDoc> m = (Map JavaDoc<Object JavaDoc, Object JavaDoc>) value;
771          for (Iterator JavaDoc<Map.Entry JavaDoc<Object JavaDoc, Object JavaDoc>> i = m.entrySet().iterator(); i.hasNext();)
772          {
773             Map.Entry JavaDoc<Object JavaDoc, Object JavaDoc> entry = i.next();
774             Object JavaDoc key = construct(keyType, entry.getKey(), context);
775             Object JavaDoc val = construct(valueType, entry.getValue(), context);
776             CompositeDataSupport JavaDoc data = new CompositeDataSupport JavaDoc(entryType, MXBeanUtils.MAP_ITEM_NAMES, new Object JavaDoc[] { key, val });
777             table.put(data);
778          }
779          return table;
780       }
781       throw new UnsupportedOperationException JavaDoc("Cannot construct map for: " + value);
782    }
783    
784    /**
785     * Reconstruct a tabular type
786     *
787     * @param openType the open type
788     * @param type the type
789     * @param value the value
790     * @param context the context
791     * @return the value
792     * @throws Exception for any error
793     */

794    public static Object JavaDoc reconstructTabularData(OpenType JavaDoc openType, Type JavaDoc type, Object JavaDoc value, Object JavaDoc context) throws Exception JavaDoc
795    {
796       if (value == null)
797          return null;
798
799       TabularType JavaDoc tabularType = (TabularType JavaDoc) getOpenType(type);
800       if (type instanceof Class JavaDoc)
801       {
802          // TODO FIXME
803
// Class clazz = (Class) type;
804
// if (Map.class.isAssignableFrom(clazz))
805
// return createMap(tabularType, Object.class, Object.class, value, context);
806
}
807       else if (type instanceof ParameterizedType JavaDoc)
808       {
809          ParameterizedType JavaDoc parameterizedType = (ParameterizedType JavaDoc) type;
810          Type JavaDoc rawType = parameterizedType.getRawType();
811          if (rawType instanceof Class JavaDoc)
812          {
813             Class JavaDoc raw = (Class JavaDoc) rawType;
814             if (Map JavaDoc.class.isAssignableFrom(raw))
815             {
816                Type JavaDoc keyType = parameterizedType.getActualTypeArguments()[0];
817                Type JavaDoc valueType = parameterizedType.getActualTypeArguments()[1];
818                return createMap(tabularType, keyType, valueType, value, context);
819             }
820          }
821       }
822       throw new UnsupportedOperationException JavaDoc("Cannot convert array type: " + type);
823    }
824
825    /**
826     * Create a map
827     *
828     * @param openType the open type
829     * @param keyType the key type
830     * @param valueType the value type
831     * @param value the value
832     * @param context the context
833     * @return the map
834     * @throws Exception for any problem
835     */

836    @SuppressWarnings JavaDoc("unchecked")
837    private static Map JavaDoc createMap(TabularType JavaDoc openType, Type JavaDoc keyType, Type JavaDoc valueType, Object JavaDoc value, Object JavaDoc context) throws Exception JavaDoc
838    {
839       if (value == null)
840          return null;
841       
842       Map JavaDoc<Object JavaDoc, Object JavaDoc> result = new HashMap JavaDoc<Object JavaDoc, Object JavaDoc>();
843       
844       TabularData JavaDoc table = (TabularData JavaDoc) value;
845       Collection JavaDoc<CompositeData JavaDoc> values = table.values();
846       for (CompositeData JavaDoc entry : values)
847       {
848          Object JavaDoc key = reconstruct(keyType, entry.get(MAP_KEY), context);
849          Object JavaDoc val = reconstruct(valueType, entry.get(MAP_VALUE), context);
850          result.put(key, val);
851       }
852       
853       return result;
854    }
855
856    /**
857     * Construct composite type open data
858     *
859     * @param openType the open type
860     * @param value the value
861     * @param context the context
862     * @return the open data
863     * @throws Exception for any error
864     */

865    @SuppressWarnings JavaDoc("unchecked")
866    public static Object JavaDoc constructCompositeData(OpenType JavaDoc openType, Object JavaDoc value, Object JavaDoc context) throws Exception JavaDoc
867    {
868       if (value == null)
869          return null;
870       
871       Class JavaDoc clazz = value.getClass();
872       
873       CompositeType JavaDoc compositeType = (CompositeType JavaDoc) openType;
874       Set JavaDoc<String JavaDoc> nameSet = compositeType.keySet();
875       String JavaDoc[] names = nameSet.toArray(new String JavaDoc[nameSet.size()]);
876       
877       Object JavaDoc[] values = new Object JavaDoc[names.length];
878       
879       for (int i = 0 ; i < names.length; ++i)
880       {
881          String JavaDoc name = names[i];
882          OpenType JavaDoc itemType = compositeType.getType(name);
883          Method JavaDoc method = getCompositeDataMethod(clazz, name, itemType == SimpleType.BOOLEAN);
884          Object JavaDoc itemValue = method.invoke(value, null);
885          values[i] = construct(itemType, itemValue, context);
886       }
887       return new CompositeDataSupport JavaDoc(compositeType, names, values);
888    }
889
890    /**
891     * Reconstruct a composite type
892     *
893     * @param openType the open type
894     * @param type the type
895     * @param value the value
896     * @param context the context
897     * @return the value
898     * @throws Exception for any error
899     */

900    public static Object JavaDoc reconstructCompositeData(OpenType JavaDoc openType, Type JavaDoc type, Object JavaDoc value, Object JavaDoc context) throws Exception JavaDoc
901    {
902       if (value == null)
903          return null;
904       
905       CompositeData JavaDoc compositeData = (CompositeData JavaDoc) value;
906       CompositeDataInvocationHandler handler = new CompositeDataInvocationHandler(compositeData);
907       Class JavaDoc clazz = (Class JavaDoc) type;
908       Class JavaDoc[] interfaces = null;
909       if (clazz.isInterface())
910          interfaces = new Class JavaDoc[] { clazz };
911       else
912          interfaces = clazz.getInterfaces();
913       return Proxy.newProxyInstance(clazz.getClassLoader(), interfaces, handler);
914    }
915    
916    /**
917     * Get the key for a composite data getter method
918     *
919     * @param method the method
920     * @return the key
921     */

922    public static String JavaDoc getCompositeDataKey(Method JavaDoc method)
923    {
924       String JavaDoc key = compositeDataKeyCache.get(method);
925       if (key != null)
926          return key;
927
928       StringBuilder JavaDoc fieldName = null;
929       
930       Class JavaDoc returnType = method.getReturnType();
931       Class JavaDoc[] paramTypes = method.getParameterTypes();
932       if (Void.TYPE.equals(returnType) == false && paramTypes.length == 0)
933       {
934          String JavaDoc name = method.getName();
935          if (name.startsWith("is") && name.length() > 2)
936          {
937             if (Boolean.TYPE.equals(returnType))
938             {
939                fieldName = new StringBuilder JavaDoc();
940                fieldName.append(Character.toLowerCase(name.charAt(2)));
941                if (name.length() > 3)
942                   fieldName.append(name.substring(3));
943             }
944          }
945          else if (name.startsWith("get") && name.length() > 3)
946          {
947             fieldName = new StringBuilder JavaDoc();
948             fieldName.append(Character.toLowerCase(name.charAt(3)));
949             if (name.length() > 4)
950                fieldName.append(name.substring(4));
951          }
952       }
953       
954       if (fieldName == null)
955          return null;
956       
957       String JavaDoc result = fieldName.toString();
958       compositeDataKeyCache.put(method, result);
959       return result;
960    }
961    
962    /**
963     * Get the key for a composite data getter method
964     *
965     * @param clazz the class
966     * @param key the key
967     * @param isBoolean whether it is boolean
968     * @return the method
969     * @throws Exception for any error
970     */

971    @SuppressWarnings JavaDoc("unchecked")
972    public static Method JavaDoc getCompositeDataMethod(Class JavaDoc clazz, String JavaDoc key, boolean isBoolean) throws Exception JavaDoc
973    {
974       Map JavaDoc<String JavaDoc, Method JavaDoc> cache = compositeDataMethodCache.get(clazz);
975       if (cache != null)
976       {
977          Method JavaDoc method = cache.get(key);
978          if (method != null)
979             return method;
980       }
981
982       StringBuilder JavaDoc name = new StringBuilder JavaDoc();
983       name.append(Character.toUpperCase(key.charAt(0)));
984       if (key.length() > 1)
985          name.append(key.substring(1));
986       Method JavaDoc method = null;
987       try
988       {
989          method = clazz.getMethod("get" + name, null);
990       }
991       catch (NoSuchMethodException JavaDoc e)
992       {
993          if (isBoolean)
994          {
995             try
996             {
997                method = clazz.getMethod("is" + name, null);
998             }
999             catch (NoSuchMethodException JavaDoc ignored)
1000            {
1001               throw e;
1002            }
1003         }
1004         else
1005         {
1006            throw e;
1007         }
1008      }
1009      
1010      if (cache == null)
1011      {
1012         cache = new WeakValueHashMap();
1013         compositeDataMethodCache.put(clazz, cache);
1014      }
1015      cache.put(key, method);
1016      return method;
1017   }
1018   
1019   /**
1020    * Create a new MXBean
1021    *
1022    * @param resource the resource
1023    * @param mxbeanInterface the interface
1024    * @return the MXBean
1025    */

1026   public static DynamicMBean JavaDoc createMXBean(Object JavaDoc resource, Class JavaDoc<?> mxbeanInterface)
1027   {
1028      try
1029      {
1030         return new MXBeanDelegate(resource, mxbeanInterface);
1031      }
1032      catch (RuntimeException JavaDoc e)
1033      {
1034         throw e;
1035      }
1036      catch (Exception JavaDoc e)
1037      {
1038         throw new RuntimeException JavaDoc("Error creating MXBean", e);
1039      }
1040   }
1041}
1042
Popular Tags