1:
37:
38: package ;
39:
40: import ;
41: import ;
42: import ;
43: import ;
44:
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50: import ;
51: import ;
52:
53: import ;
54: import ;
55:
56: import ;
57: import ;
58: import ;
59: import ;
60: import ;
61: import ;
62: import ;
63: import ;
64: import ;
65: import ;
66: import ;
67: import ;
68:
69:
76: public final class Translator
77: {
78:
79:
89: public static final Object[] fromJava(Object[] jtypes, Method method)
90: throws Throwable
91: {
92: Type[] gtypes = method.getGenericParameterTypes();
93: Object[] otypes = new Object[jtypes.length];
94: for (int a = 0; a < jtypes.length; ++a)
95: otypes[a] = fromJava(jtypes[a], (Class<?>) gtypes[a]);
96: return otypes;
97: }
98:
99:
109: public static final Object fromJava(Object jtype, Type type)
110: throws Throwable
111: {
112: if (jtype == null)
113: return null;
114: Class<?> jclass = jtype.getClass();
115: if (OpenType.ALLOWED_CLASSNAMES_LIST.contains(jclass.getName()))
116: return jtype;
117: if (jclass.isArray())
118: {
119: Class<?> ctype = jclass.getComponentType();
120: if (ctype.isPrimitive())
121: return jtype;
122: if (OpenType.ALLOWED_CLASSNAMES_LIST.contains(ctype.getName()))
123: return jtype;
124: Object[] elems = (Object[]) jtype;
125: Object[] celems = new Object[elems.length];
126: for (int a = 0; a < elems.length; ++a)
127: celems[a] = fromJava(elems[a], elems[a].getClass());
128: return makeArraySpecific(celems);
129: }
130: String tName = getTypeName(type);
131: if (jtype instanceof List || jtype instanceof Set ||
132: jtype instanceof SortedSet)
133: {
134: String elemType = tName.substring(tName.indexOf("<") + 1,
135: tName.indexOf(">")).trim();
136: if (jtype instanceof SortedSet)
137: {
138: Class<?> elemClass = Class.forName(elemType);
139: if (!Comparable.class.isAssignableFrom(elemClass))
140: throw new IllegalArgumentException(jtype + " has a " +
141: "non-comparable element " +
142: "type, " + elemClass);
143: if (((SortedSet) jtype).comparator() != null)
144: throw new IllegalArgumentException(jtype + " does not " +
145: "use natural ordering.");
146: }
147: List elems = (List) jtype;
148: Object[] celems = new Object[elems.size()];
149: for (int a = 0; a < elems.size(); ++a)
150: {
151: Object elem = elems.get(a);
152: celems[a] = fromJava(elem, elem.getClass());
153: }
154: return makeArraySpecific(celems);
155: }
156: if (jtype instanceof Enum)
157: return ((Enum) jtype).name();
158: if (jtype instanceof Map || jtype instanceof SortedMap)
159: {
160: int lparam = tName.indexOf("<");
161: int comma = tName.indexOf(",", lparam);
162: int rparam = tName.indexOf(">", comma);
163: String key = tName.substring(lparam + 1, comma).trim();
164: String value = tName.substring(comma + 1, rparam).trim();
165: String typeName = null;
166: if (jtype instanceof Map)
167: typeName = "java.util.Map" + tName.substring(lparam);
168: else
169: {
170: Class<?> keyClass = Class.forName(key);
171: if (!Comparable.class.isAssignableFrom(keyClass))
172: throw new IllegalArgumentException(jtype + " has a " +
173: "non-comparable element " +
174: "type, " + keyClass);
175: if (((SortedMap) jtype).comparator() != null)
176: throw new IllegalArgumentException(jtype + " does not " +
177: "use natural ordering.");
178: typeName = "java.util.SortedMap" + tName.substring(lparam);
179: }
180: OpenType k = translate(key).getOpenType();
181: OpenType v = translate(value).getOpenType();
182: CompositeType rowType = new CompositeType(typeName, typeName,
183: new String[] { "key", "value" },
184: new String[] { "Map key", "Map value"},
185: new OpenType[] {k,v});
186: TabularType tabType = new TabularType(typeName, typeName, rowType,
187: new String[]{"key"});
188: TabularData data = new TabularDataSupport(tabType);
189: for (Map.Entry entry : (Set<Map.Entry>) ((Map) jtype).entrySet())
190: {
191: try
192: {
193: data.put(new CompositeDataSupport(rowType,
194: new String[] {
195: "key",
196: "value"
197: },
198: new Object[] {
199: entry.getKey(),
200: entry.getValue()
201: }));
202: }
203: catch (OpenDataException e)
204: {
205: throw (InternalError) (new InternalError("A problem occurred " +
206: "converting the map " +
207: "to a composite data " +
208: "structure.").initCause(e));
209: }
210: }
211: return data;
212: }
213: if (JMX.isMXBeanInterface(jclass))
214: {
215: try
216: {
217: MBeanServerInvocationHandler ih = (MBeanServerInvocationHandler)
218: Proxy.getInvocationHandler(jtype);
219: return ih.getObjectName();
220: }
221: catch (IllegalArgumentException e)
222: {
223: throw new IllegalArgumentException("For a MXBean to be translated " +
224: "to an open type, it must be a " +
225: "proxy.", e);
226: }
227: catch (ClassCastException e)
228: {
229: throw new IllegalArgumentException("For a MXBean to be translated " +
230: "to an open type, it must have a " +
231: "MBeanServerInvocationHandler.", e);
232: }
233: }
234:
235: throw new IllegalArgumentException("The type, " + jtype +
236: ", is not convertible.");
237: }
238:
239:
249: public static final Object toJava(Object otype, Method method)
250: throws Throwable
251: {
252: Class<?> returnType = method.getReturnType();
253: if (returnType.isEnum())
254: {
255: String ename = (String) otype;
256: Enum[] constants = (Enum[]) returnType.getEnumConstants();
257: for (Enum c : constants)
258: if (c.name().equals(ename))
259: return c;
260: }
261: if (List.class.isAssignableFrom(returnType))
262: {
263: Object[] elems = (Object[]) otype;
264: List l = new ArrayList(elems.length);
265: for (Object elem : elems)
266: l.add(elem);
267: return l;
268: }
269: if (Map.class.isAssignableFrom(returnType))
270: {
271: TabularData data = (TabularData) otype;
272: Map m = new HashMap(data.size());
273: for (Object val : data.values())
274: {
275: CompositeData vals = (CompositeData) val;
276: m.put(vals.get("key"), vals.get("value"));
277: }
278: return m;
279: }
280: try
281: {
282: Method m = returnType.getMethod("from",
283: new Class[]
284: { CompositeData.class });
285: return m.invoke(null, (CompositeData) otype);
286: }
287: catch (NoSuchMethodException e)
288: {
289:
291: }
292: return otype;
293: }
294:
295:
305: private static final Object[] makeArraySpecific(Object[] arr)
306: {
307: Object[] rcelems = (Object[]) Array.newInstance(arr[0].getClass(),
308: arr.length);
309: System.arraycopy(arr, 0, rcelems, 0, arr.length);
310: return rcelems;
311: }
312:
313:
324: public static final OpenMBeanParameterInfo translate(String type)
325: throws OpenDataException
326: {
327: if (type.equals("boolean") || type.equals(Boolean.class.getName()))
328: return new OpenMBeanParameterInfoSupport("TransParam",
329: "Translated parameter",
330: SimpleType.BOOLEAN,
331: null,
332: new Boolean[] {
333: Boolean.TRUE,
334: Boolean.FALSE
335: });
336: if (type.equals("byte") || type.equals(Byte.class.getName()))
337: return new OpenMBeanParameterInfoSupport("TransParam",
338: "Translated parameter",
339: SimpleType.BYTE,
340: null,
341: Byte.valueOf(Byte.MIN_VALUE),
342: Byte.valueOf(Byte.MAX_VALUE));
343: if (type.equals("char") || type.equals(Character.class.getName()))
344: return new OpenMBeanParameterInfoSupport("TransParam",
345: "Translated parameter",
346: SimpleType.CHARACTER,
347: null,
348: Character.valueOf(Character.MIN_VALUE),
349: Character.valueOf(Character.MAX_VALUE));
350: if (type.equals("double") || type.equals(Double.class.getName()))
351: return new OpenMBeanParameterInfoSupport("TransParam",
352: "Translated parameter",
353: SimpleType.DOUBLE,
354: null,
355: Double.valueOf(Double.MIN_VALUE),
356: Double.valueOf(Double.MAX_VALUE));
357: if (type.equals("float") || type.equals(Float.class.getName()))
358: return new OpenMBeanParameterInfoSupport("TransParam",
359: "Translated parameter",
360: SimpleType.FLOAT,
361: null,
362: Float.valueOf(Float.MIN_VALUE),
363: Float.valueOf(Float.MAX_VALUE));
364: if (type.equals("int") || type.equals(Integer.class.getName()))
365: return new OpenMBeanParameterInfoSupport("TransParam",
366: "Translated parameter",
367: SimpleType.INTEGER,
368: null,
369: Integer.valueOf(Integer.MIN_VALUE),
370: Integer.valueOf(Integer.MAX_VALUE));
371: if (type.equals("long") || type.equals(Long.class.getName()))
372: return new OpenMBeanParameterInfoSupport("TransParam",
373: "Translated parameter",
374: SimpleType.LONG,
375: null,
376: Long.valueOf(Long.MIN_VALUE),
377: Long.valueOf(Long.MAX_VALUE));
378: if (type.equals("short") || type.equals(Short.class.getName()))
379: return new OpenMBeanParameterInfoSupport("TransParam",
380: "Translated parameter",
381: SimpleType.SHORT,
382: null,
383: Short.valueOf(Short.MIN_VALUE),
384: Short.valueOf(Short.MAX_VALUE));
385: if (type.equals(String.class.getName()))
386: return new OpenMBeanParameterInfoSupport("TransParam",
387: "Translated parameter",
388: SimpleType.STRING);
389: if (type.equals("void"))
390: return new OpenMBeanParameterInfoSupport("TransParam",
391: "Translated parameter",
392: SimpleType.VOID);
393: if (type.startsWith("java.util.Map"))
394: {
395: int lparam = type.indexOf("<");
396: int comma = type.indexOf(",", lparam);
397: int rparam = type.indexOf(">", comma);
398: String key = type.substring(lparam + 1, comma).trim();
399: OpenType k = translate(key).getOpenType();
400: OpenType v = translate(type.substring(comma + 1, rparam).trim()).getOpenType();
401: CompositeType ctype = new CompositeType(Map.class.getName(), Map.class.getName(),
402: new String[] { "key", "value" },
403: new String[] { "Map key", "Map value"},
404: new OpenType[] { k, v});
405: TabularType ttype = new TabularType(key, key, ctype,
406: new String[] { "key" });
407: return new OpenMBeanParameterInfoSupport("TransParam",
408: "Translated parameter",
409: ttype);
410: }
411: if (type.startsWith("java.util.List"))
412: {
413: int lparam = type.indexOf("<");
414: int rparam = type.indexOf(">");
415: OpenType e = translate(type.substring(lparam + 1, rparam).trim()).getOpenType();
416: return new OpenMBeanParameterInfoSupport("TransParam",
417: "Translated parameter",
418: new ArrayType(1, e)
419: );
420: }
421: Class c;
422: try
423: {
424: c = Class.forName(type);
425: }
426: catch (ClassNotFoundException e)
427: {
428: throw (InternalError)
429: (new InternalError("The class for a type used in a management bean " +
430: "could not be loaded.").initCause(e));
431: }
432: if (c.isEnum())
433: {
434: Object[] values = c.getEnumConstants();
435: String[] names = new String[values.length];
436: for (int a = 0; a < values.length; ++a)
437: names[a] = values[a].toString();
438: return new OpenMBeanParameterInfoSupport("TransParam",
439: "Translated parameter",
440: SimpleType.STRING,
441: null, names);
442: }
443: try
444: {
445: c.getMethod("from", new Class[] { CompositeData.class });
446: Method[] methods = c.getDeclaredMethods();
447: List<String> names = new ArrayList<String>();
448: List<OpenType> types = new ArrayList<OpenType>();
449: for (int a = 0; a < methods.length; ++a)
450: {
451: String name = methods[a].getName();
452: if (name.startsWith("get"))
453: {
454: names.add(name.substring(3));
455: types.add(getTypeFromClass(methods[a].getReturnType()));
456: }
457: }
458: String[] fields = names.toArray(new String[names.size()]);
459: CompositeType ctype = new CompositeType(c.getName(), c.getName(),
460: fields, fields,
461: types.toArray(new OpenType[types.size()]));
462: return new OpenMBeanParameterInfoSupport("TransParam",
463: "Translated parameter",
464: ctype);
465: }
466: catch (NoSuchMethodException e)
467: {
468:
469: }
470: if (c.isArray())
471: {
472: int depth;
473: for (depth = 0; c.getName().charAt(depth) == '['; ++depth)
474: ;
475: OpenType ot = getTypeFromClass(c.getComponentType());
476: return new OpenMBeanParameterInfoSupport("TransParam",
477: "Translated parameter",
478: new ArrayType(depth, ot)
479: );
480: }
481: throw new InternalError("The type used does not have an open type translation.");
482: }
483:
484:
492: private static final OpenType getTypeFromClass(Class c)
493: throws OpenDataException
494: {
495: return Translator.translate(c.getName()).getOpenType();
496: }
497:
498:
520: private static final String getTypeName(Type type)
521: {
522: if (type instanceof Class)
523: {
524: Class<?> c = (Class<?>) type;
525: if (c.isArray())
526: {
527: StringBuilder b =
528: new StringBuilder(c.getComponentType().getName());
529: String normName = c.getName();
530: for (int a = 0; a < normName.length(); ++a)
531: {
532: if (normName.charAt(a) == '[')
533: b.append("[]");
534: else
535: break;
536: }
537: return b.toString();
538: }
539: return c.getName();
540: }
541: return type.toString();
542: }
543:
544: }