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