xref: /aoo41x/main/jurt/com/sun/star/uno/AnyConverter.java (revision cdf0e10c)
1 package com.sun.star.uno;
2 
3 /** This class provides static methods which aim at exploring the contents of an
4  * Any and extracting its value. All public methods take an Object argument that
5  * either is the immediate object, such as Boolean, Type, interface implementation,
6  * or an Any that contains an object. <br>The methods which extract the value do a
7  * widening conversion. See the method comments for the respective conversions.
8  */
9 public class AnyConverter
10 {
11     /** Determines the type of an any object.
12 
13         @param object any object
14         @return type object
15     */
16     static public Type getType( Object object )
17     {
18         Type t;
19         if (null == object)
20         {
21             t = m_XInterface_type;
22         }
23         else if (object instanceof Any)
24         {
25             t = ((Any)object).getType();
26             // nested any
27             if (TypeClass.ANY_value == t.getTypeClass().getValue())
28                 return getType( ((Any)object).getObject() );
29         }
30         else
31         {
32             t = new Type( object.getClass() );
33         }
34         return t;
35     }
36 
37     /** checks if the any contains the idl type <code>void</code>.
38         @param object the object to check
39         @return true when the any is void, false otherwise
40      */
41 	static public boolean isVoid(Object object){
42 		return containsType(TypeClass.VOID, object);
43 	}
44 
45     /** checks if the any contains a value of the idl type <code>char</code>.
46         @param object the object to check
47         @return true when the any contains a char, false otherwise.
48      */
49 	static public boolean isChar(Object object){
50 		return containsType(TypeClass.CHAR, object);
51 	}
52 
53     /** checks if the any contains a value of the idl type <code>boolean</code>.
54         @param object the object to check
55         @return true when the any contains a boolean, false otherwise.
56      */
57 	static public boolean isBoolean(Object object){
58 		return containsType(TypeClass.BOOLEAN, object);
59 	}
60 
61     /** checks if the any contains a value of the idl type <code>byte</code>.
62         @param object the object to check
63         @return true when the any contains a byte, false otherwise.
64      */
65 	static public boolean isByte(Object object){
66 		return containsType(TypeClass.BYTE, object);
67 	}
68 
69     /** checks if the any contains a value of the idl type <code>short</code>.
70         @param object the object to check
71         @return true when the any contains a short, false otherwise.
72      */
73 	static public boolean isShort(Object object){
74 		return containsType(TypeClass.SHORT, object);
75 	}
76 
77     /** checks if the any contains a value of the idl type <code>long</code> (which maps to a java-int).
78         @param object the object to check
79         @return true when the any contains a int, false otherwise.
80      */
81 	static public boolean isInt(Object object){
82 		return containsType(TypeClass.LONG, object);
83 	}
84 
85     /** checks if the any contains a value of the idl type <code>hyper</code> (which maps to a java-long).
86         @param object the object to check
87         @return true when the any contains a long, false otherwise.
88      */
89 	static public boolean isLong(Object object){
90 		return containsType(TypeClass.HYPER, object);
91 	}
92 
93     /** checks if the any contains a value of the idl type <code>float</code>.
94         @param object the object to check
95         @return true when the any contains a float, false otherwise.
96      */
97 	static public boolean isFloat(Object object){
98 		return containsType(TypeClass.FLOAT, object);
99 	}
100 
101     /** checks if the any contains a value of the idl type <code>double</code>.
102         @param object the object to check
103         @return true when the any contains a double, false otherwise.
104      */
105 	static public boolean isDouble(Object object){
106 		return containsType(TypeClass.DOUBLE, object);
107 	}
108 
109     /** checks if the any contains a value of the idl type <code>string</code>.
110         @param object the object to check
111         @return true when the any contains a string, false otherwise.
112      */
113 	static public boolean isString(Object object){
114 		return containsType(TypeClass.STRING, object);
115 	}
116 
117     /** checks if the any contains a value of the idl type <code>enum</code>.
118         @param object the object to check
119         @return true if the any contains an enum, false otherwise
120      */
121 	static public boolean isEnum(Object object)
122     {
123 		return containsType(TypeClass.ENUM, object);
124 	}
125 
126     /** checks if the any contains a value of the idl type <code>type</code>.
127         @param object the object to check
128         @return true when the any contains a type, false otherwise.
129      */
130 	static public boolean isType(Object object){
131 		return containsType(TypeClass.TYPE, object);
132 	}
133 
134     /** checks if the any contains an interface, struct, exception, sequence or enum.
135         If <em>object</em> is an any with an interface type, then true is also returned if
136         the any contains a null reference. This is because interfaces are allowed to have
137         a null value contrary to other UNO types.
138         @param object the object to check
139         @return true if the any contains an object
140      */
141 	static public boolean isObject(Object object)
142     {
143         int tc = getType(object).getTypeClass().getValue();
144         return (TypeClass.INTERFACE_value == tc ||
145                 TypeClass.STRUCT_value == tc ||
146                 TypeClass.EXCEPTION_value == tc ||
147                 TypeClass.SEQUENCE_value == tc ||
148                 TypeClass.ENUM_value == tc);
149 	}
150 
151     /** checks if the any contains UNO idl sequence value (meaning a java array
152         containing elements which are values of UNO idl types).
153         @param object the object to check
154         @return true when the any contains an object which implements interfaces, false otherwise.
155      */
156 	static public boolean isArray(Object object){
157 		return containsType(TypeClass.SEQUENCE, object);
158 	}
159 
160 	/** converts an Char object or an Any object containing a Char object into a simple char.
161         @param object the object to convert
162         @return the char contained within the object
163         @throws com.sun.star.lang.IllegalArgumentException in case no char is contained within object
164         @see #isChar
165     */
166 	static public char toChar(Object object) throws  com.sun.star.lang.IllegalArgumentException{
167 		Character ret= (Character)convertSimple(TypeClass.CHAR, null, object);
168 		return ret.charValue();
169 	}
170 
171 	/** converts an Boolean object or an Any object containing a Boolean object into a simple boolean.
172         @param object the object to convert
173         @return the boolean contained within the object
174         @throws com.sun.star.lang.IllegalArgumentException in case no boolean is contained within object
175         @see #isBoolean
176     */
177 	static public boolean toBoolean(Object object) throws  com.sun.star.lang.IllegalArgumentException{
178 		Boolean ret= (Boolean)convertSimple(TypeClass.BOOLEAN, null, object);
179 		return ret.booleanValue();
180 	}
181 
182 	/** converts an Byte object or an Any object containing a Byte object into a simple byte.
183         @param object the object to convert
184         @return the boolean contained within the object
185         @throws com.sun.star.lang.IllegalArgumentException in case no byte is contained within object
186         @see #isBoolean
187     */
188 	static public byte toByte(Object object) throws   com.sun.star.lang.IllegalArgumentException{
189 		Byte ret= (Byte)convertSimple(TypeClass.BYTE, null, object);
190 		return ret.byteValue();
191 	}
192 
193     /** converts a number object into a simple short and allows widening conversions.
194         Allowed argument types are Byte, Short or Any containing these types.
195         @param object the object to convert
196         @throws com.sun.star.lang.IllegalArgumentException in case no short or byte is contained within object
197         @return the short contained within the object
198      */
199 	static public short toShort(Object object) throws   com.sun.star.lang.IllegalArgumentException{
200 		Short ret= (Short)convertSimple(TypeClass.SHORT, null, object);
201 		return ret.shortValue();
202 	}
203     /** converts a number object into an idl unsigned short and allows widening conversions.
204         Allowed argument types are Anies containing idl unsigned short values.
205         @param object the object to convert
206         @throws com.sun.star.lang.IllegalArgumentException
207                 in case no idl unsigned short is contained within Any
208         @return an (unsigned) short
209      */
210 	static public short toUnsignedShort(Object object)
211         throws com.sun.star.lang.IllegalArgumentException
212     {
213 		Short ret= (Short)convertSimple(TypeClass.UNSIGNED_SHORT, null, object);
214 		return ret.shortValue();
215 	}
216 
217     /** converts a number object into a simple int and allows widening conversions.
218         Allowed argument types are Byte, Short, Integer or Any containing these types.
219         @param object the object to convert
220         @throws com.sun.star.lang.IllegalArgumentException in case no short, byte or int is contained within object.
221         @return the int contained within the object
222      */
223 	static public int toInt(Object object) throws  com.sun.star.lang.IllegalArgumentException{
224 		Integer ret= (Integer) convertSimple( TypeClass.LONG, null, object);
225 		return ret.intValue();
226 	}
227     /** converts a number object into an idl unsigned long and allows widening conversions.
228         Allowed argument types are Anies containing idl unsigned short or unsigned long values.
229         @param object the object to convert
230         @throws com.sun.star.lang.IllegalArgumentException
231                 in case no idl unsigned short nor unsigned long is contained within Any
232         @return an (unsigned) int
233      */
234 	static public int toUnsignedInt(Object object)
235         throws  com.sun.star.lang.IllegalArgumentException
236     {
237 		Integer ret = (Integer)convertSimple(TypeClass.UNSIGNED_LONG, null, object);
238 		return ret.intValue();
239 	}
240 
241     /** converts a number object into a simple long and allows widening conversions.
242         Allowed argument types are Byte, Short, Integer, Long or Any containing these types.
243         @param object the object to convert
244         @throws com.sun.star.lang.IllegalArgumentException in case no short, byte, int or long
245                 is contained within object.
246         @return the long contained within the object
247      */
248 	static public long toLong(Object object) throws   com.sun.star.lang.IllegalArgumentException{
249 		Long ret= (Long) convertSimple( TypeClass.HYPER, null, object);
250 		return ret.longValue();
251 	}
252     /** converts a number object into an idl unsigned hyper and allows widening conversions.
253         Allowed argument types are Anies containing idl unsigned short, unsigned long or
254         unsigned hyper values.
255         @param object the object to convert
256         @throws com.sun.star.lang.IllegalArgumentException
257                 in case no idl unsigned short, nor unsigned long nor unsigned hyper
258                 is contained within object.
259         @return an (unsigned) long
260      */
261 	static public long toUnsignedLong(Object object)
262         throws com.sun.star.lang.IllegalArgumentException
263     {
264 		Long ret = (Long)convertSimple(TypeClass.UNSIGNED_HYPER, null, object);
265 		return ret.longValue();
266 	}
267 
268     /** converts a number object into a simple float and allows widening conversions.
269         Allowed argument types are Byte, Short, Float or Any containing these types.
270         @param object the object to convert
271         @throws com.sun.star.lang.IllegalArgumentException in case no byte, short or float
272                 is contained within object.
273         @return the float contained within the object
274      */
275 	static public float toFloat(Object object) throws com.sun.star.lang.IllegalArgumentException{
276 		Float ret= (Float) convertSimple( TypeClass.FLOAT,null, object);
277 		return ret.floatValue();
278 	}
279 
280     /** converts a number object into a simple double and allows widening conversions.
281         Allowed argument types are Byte, Short, Int, Float, Double or Any containing these types.
282         @param object the object to convert
283         @throws com.sun.star.lang.IllegalArgumentException in case no byte, short, int, float
284                 or double is contained within object.
285         @return the double contained within the object
286      */
287 	static public double toDouble(Object object) throws com.sun.star.lang.IllegalArgumentException {
288 		Double ret= (Double) convertSimple( TypeClass.DOUBLE, null, object);
289 		return ret.doubleValue();
290 	}
291 
292     /** converts a string or an any containing a string into a string.
293         @param object the object to convert
294         @throws com.sun.star.lang.IllegalArgumentException in case no string is contained within object.
295         @return the string contained within the object
296      */
297 	static public String toString(Object object) throws com.sun.star.lang.IllegalArgumentException {
298 		return (String) convertSimple( TypeClass.STRING, null, object);
299 	}
300 
301     /** converts a Type or an any containing a Type into a Type.
302         @param object the object to convert
303         @throws com.sun.star.lang.IllegalArgumentException in case no type is contained within object.
304         @return the type contained within the object
305      */
306 	static public Type toType(Object object) throws com.sun.star.lang.IllegalArgumentException {
307 		return (Type) convertSimple( TypeClass.TYPE, null, object);
308 	}
309 
310     /** converts a UNO object (struct, exception, sequence, enum or interface) or an Any containing
311      *  these types into an UNO object of a specified destination type.
312      *  For interfaces, the argument <em>object</em> is queried for the interface specified
313      *  by the <em>type</em> argument. That query (UnoRuntime.queryInterface) might return null,
314      *  if the interface is not implemented or a null-ref or a VOID any is given.
315      *
316      *  @param type type of the returned value
317      *  @param object the object that is to be converted
318      *  @return destination object
319      *  @throws com.sun.star.lang.IllegalArgumentException
320      *          in case conversion is not possible
321      */
322 	static public Object toObject(Type type, Object object)
323 		throws com.sun.star.lang.IllegalArgumentException
324     {
325 		return convertSimple( type.getTypeClass(), type, object );
326 	}
327     /** converts a UNO object (struct, exception, sequence, enum or interface) or an Any containing
328      *  these types into an UNO object of a specified destination type.
329      *  For interfaces, the argument <em>object</em> is queried for the interface specified
330      *  by the <em>type</em> argument. That query (UnoRuntime.queryInterface) might return null,
331      *  if the interface is not implemented or a null-ref or a VOID any is given.
332      *
333      *  @param clazz class of the returned value
334      *  @param object the object that is to be converted
335      *  @return destination object
336      *  @throws com.sun.star.lang.IllegalArgumentException
337      *          in case conversion is not possible
338      */
339 	static public Object toObject(Class clazz, Object object)
340 		throws com.sun.star.lang.IllegalArgumentException
341     {
342         return toObject( new Type( clazz ), object );
343 	}
344 
345     /** converts an array or an any containing an array into an array.
346         @param object the object to convert
347         @throws com.sun.star.lang.IllegalArgumentException in case no array is contained within object.
348         @return the array contained within the object
349      */
350 	static public Object toArray( Object object) throws com.sun.star.lang.IllegalArgumentException {
351 		return convertSimple( TypeClass.SEQUENCE, null, object);
352 	}
353 
354 	/**
355 	   Examines the argument <em>object</em> if is correspond to the type in argument <em>what</em>.
356 	   <em>object</em> is either matched directly against the type or if it is an any then the
357 	   contained object is matched against the type.
358 	*/
359 	static private boolean containsType( TypeClass what, Object object){
360         return (getType(object).getTypeClass().getValue() == what.getValue());
361 	}
362 
363     static private final Type m_XInterface_type = new Type( XInterface.class );
364 
365 	static private Object convertSimple( TypeClass destTClass, Type destType, Object object_ )
366 		throws com.sun.star.lang.IllegalArgumentException
367     {
368 		Object object;
369         Type type;
370         if (object_ instanceof Any)
371         {
372             // unbox
373             Any a = (Any)object_;
374             object = a.getObject();
375             type = a.getType();
376             // nested any
377             if (TypeClass.ANY_value == type.getTypeClass().getValue())
378                 return convertSimple( destTClass, destType, object );
379         }
380         else
381         {
382             object = object_;
383             type = (null == object ? m_XInterface_type : new Type( object.getClass() ));
384         }
385 
386         int tc = type.getTypeClass().getValue();
387         int dest_tc = destTClass.getValue();
388 
389         if (null == object)
390         {
391             // special for interfaces
392             if (TypeClass.INTERFACE_value == tc && dest_tc == tc)
393                 return null;
394         }
395         else
396         {
397             switch (dest_tc)
398             {
399             case TypeClass.CHAR_value:
400                 if (tc == TypeClass.CHAR_value)
401                     return object;
402                 break;
403             case TypeClass.BOOLEAN_value:
404                 if (tc == TypeClass.BOOLEAN_value)
405                     return object;
406                 break;
407             case TypeClass.BYTE_value:
408                 if (tc == TypeClass.BYTE_value)
409                     return object;
410                 break;
411             case TypeClass.SHORT_value:
412                 switch (tc)
413                 {
414                 case TypeClass.BYTE_value:
415                     return new Short( ((Byte)object).byteValue() );
416                 case TypeClass.SHORT_value:
417                     return object;
418                 }
419                 break;
420             case TypeClass.UNSIGNED_SHORT_value:
421                 switch (tc)
422                 {
423                 case TypeClass.UNSIGNED_SHORT_value:
424                     return object;
425                 }
426                 break;
427             case TypeClass.LONG_value:
428                 switch (tc)
429                 {
430                 case TypeClass.BYTE_value:
431                     return new Integer( ((Byte)object).byteValue() );
432                 case TypeClass.SHORT_value:
433                 case TypeClass.UNSIGNED_SHORT_value:
434                     return new Integer( ((Short)object).shortValue() );
435                 case TypeClass.LONG_value:
436                     return object;
437                 }
438                 break;
439             case TypeClass.UNSIGNED_LONG_value:
440                 switch (tc)
441                 {
442                 case TypeClass.UNSIGNED_SHORT_value:
443                     return new Integer( ((Short)object).shortValue() );
444                 case TypeClass.UNSIGNED_LONG_value:
445                     return object;
446                 }
447                 break;
448             case TypeClass.HYPER_value:
449                 switch (tc)
450                 {
451                 case TypeClass.BYTE_value:
452                     return new Long( ((Byte)object).byteValue() );
453                 case TypeClass.SHORT_value:
454                 case TypeClass.UNSIGNED_SHORT_value:
455                     return new Long( ((Short)object).shortValue() );
456                 case TypeClass.LONG_value:
457                 case TypeClass.UNSIGNED_LONG_value:
458                     return new Long( ((Integer)object).intValue() );
459                 case TypeClass.HYPER_value:
460                     return object;
461                 }
462                 break;
463             case TypeClass.UNSIGNED_HYPER_value:
464                 switch (tc)
465                 {
466                 case TypeClass.UNSIGNED_SHORT_value:
467                     return new Long( ((Short)object).shortValue() );
468                 case TypeClass.UNSIGNED_LONG_value:
469                     return new Long( ((Integer)object).intValue() );
470                 case TypeClass.UNSIGNED_HYPER_value:
471                     return object;
472                 }
473                 break;
474             case TypeClass.FLOAT_value:
475                 switch (tc)
476                 {
477                 case TypeClass.BYTE_value:
478                     return new Float( ((Byte)object).byteValue() );
479                 case TypeClass.SHORT_value:
480                     return new Float( ((Short)object).shortValue() );
481                 case TypeClass.FLOAT_value:
482                     return object;
483                 }
484                 break;
485             case TypeClass.DOUBLE_value:
486                 switch (tc)
487                 {
488                 case TypeClass.BYTE_value:
489                     return new Double( ((Byte)object).byteValue() );
490                 case TypeClass.SHORT_value:
491                     return new Double( ((Short)object).shortValue() );
492                 case TypeClass.LONG_value:
493                     return new Double( ((Integer)object).intValue() );
494                 case TypeClass.FLOAT_value:
495                     return new Double( ((Float)object).floatValue() );
496                 case TypeClass.DOUBLE_value:
497                     return object;
498                 }
499                 break;
500             case TypeClass.ENUM_value:
501                 if (tc == TypeClass.ENUM_value &&
502                     (null == destTClass || destType.equals( type ) /* optional destType */))
503                 {
504                     return object;
505                 }
506                 break;
507             case TypeClass.STRING_value:
508                 if (tc == TypeClass.STRING_value)
509                     return object;
510                 break;
511             case TypeClass.TYPE_value:
512                 if (tc == TypeClass.TYPE_value)
513                     return object;
514                 break;
515             case TypeClass.INTERFACE_value:
516                 // Because object is a class, not an interface, it is
517                 // controversial what kind of Type "new Type(object.class)"
518                 // above should return (UNKNOWN or INTERFACE), so that we should
519                 // not check here for "tc == TypeClass.INTERFACE_value".
520                 // Instead, we check whether object (indirectly) derives from
521                 // XInterface:
522                 if (object instanceof XInterface)
523                     return UnoRuntime.queryInterface( destType, object );
524                 break;
525             case TypeClass.STRUCT_value:
526             case TypeClass.EXCEPTION_value:
527                 if (destType.isSupertypeOf(type)) {
528                     return object;
529                 }
530                 break;
531             case TypeClass.SEQUENCE_value:
532                 if (tc == TypeClass.SEQUENCE_value &&
533                     (null == destType || destType.equals( type ) /* optional destType */))
534                 {
535                     return object;
536                 }
537                 break;
538             }
539         }
540 		throw new com.sun.star.lang.IllegalArgumentException(
541 			"The Argument did not hold the proper type");
542 	}
543 }
544