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