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 */ 360 @SuppressWarnings("unchecked") toObject(Class<T> clazz, Object object)361 static public <T> T toObject(Class<T> clazz, Object object) 362 throws com.sun.star.lang.IllegalArgumentException 363 { 364 return (T) toObject( new Type( clazz ), object ); 365 } 366 367 /** converts an array or an any containing an array into an array. 368 @param object the object to convert 369 @throws com.sun.star.lang.IllegalArgumentException in case no array is contained within object. 370 @return the array contained within the object 371 */ toArray( Object object)372 static public Object toArray( Object object) throws com.sun.star.lang.IllegalArgumentException { 373 return convertSimple( TypeClass.SEQUENCE, null, object); 374 } 375 376 /** 377 Examines the argument <em>object</em> if is correspond to the type in argument <em>what</em>. 378 <em>object</em> is either matched directly against the type or if it is an any then the 379 contained object is matched against the type. 380 */ containsType( TypeClass what, Object object)381 static private boolean containsType( TypeClass what, Object object){ 382 return (getType(object).getTypeClass().getValue() == what.getValue()); 383 } 384 385 static private final Type m_XInterface_type = new Type( XInterface.class ); 386 convertSimple( TypeClass destTClass, Type destType, Object object_ )387 static private Object convertSimple( TypeClass destTClass, Type destType, Object object_ ) 388 throws com.sun.star.lang.IllegalArgumentException 389 { 390 Object object; 391 Type type; 392 if (object_ instanceof Any) 393 { 394 // unbox 395 Any a = (Any)object_; 396 object = a.getObject(); 397 type = a.getType(); 398 // nested any 399 if (TypeClass.ANY_value == type.getTypeClass().getValue()) 400 return convertSimple( destTClass, destType, object ); 401 } 402 else 403 { 404 object = object_; 405 type = (null == object ? m_XInterface_type : new Type( object.getClass() )); 406 } 407 408 int tc = type.getTypeClass().getValue(); 409 int dest_tc = destTClass.getValue(); 410 411 if (null == object) 412 { 413 // special for interfaces 414 if (TypeClass.INTERFACE_value == tc && dest_tc == tc) 415 return null; 416 } 417 else 418 { 419 switch (dest_tc) 420 { 421 case TypeClass.CHAR_value: 422 if (tc == TypeClass.CHAR_value) 423 return object; 424 break; 425 case TypeClass.BOOLEAN_value: 426 if (tc == TypeClass.BOOLEAN_value) 427 return object; 428 break; 429 case TypeClass.BYTE_value: 430 if (tc == TypeClass.BYTE_value) 431 return object; 432 break; 433 case TypeClass.SHORT_value: 434 switch (tc) 435 { 436 case TypeClass.BYTE_value: 437 return Short.valueOf( ((Byte)object).byteValue() ); 438 case TypeClass.SHORT_value: 439 return object; 440 } 441 break; 442 case TypeClass.UNSIGNED_SHORT_value: 443 switch (tc) 444 { 445 case TypeClass.UNSIGNED_SHORT_value: 446 return object; 447 } 448 break; 449 case TypeClass.LONG_value: 450 switch (tc) 451 { 452 case TypeClass.BYTE_value: 453 return Integer.valueOf( ((Byte)object).byteValue() ); 454 case TypeClass.SHORT_value: 455 case TypeClass.UNSIGNED_SHORT_value: 456 return Integer.valueOf( ((Short)object).shortValue() ); 457 case TypeClass.LONG_value: 458 return object; 459 } 460 break; 461 case TypeClass.UNSIGNED_LONG_value: 462 switch (tc) 463 { 464 case TypeClass.UNSIGNED_SHORT_value: 465 return Integer.valueOf( ((Short)object).shortValue() ); 466 case TypeClass.UNSIGNED_LONG_value: 467 return object; 468 } 469 break; 470 case TypeClass.HYPER_value: 471 switch (tc) 472 { 473 case TypeClass.BYTE_value: 474 return Long.valueOf( ((Byte)object).byteValue() ); 475 case TypeClass.SHORT_value: 476 case TypeClass.UNSIGNED_SHORT_value: 477 return Long.valueOf( ((Short)object).shortValue() ); 478 case TypeClass.LONG_value: 479 case TypeClass.UNSIGNED_LONG_value: 480 return Long.valueOf( ((Integer)object).intValue() ); 481 case TypeClass.HYPER_value: 482 return object; 483 } 484 break; 485 case TypeClass.UNSIGNED_HYPER_value: 486 switch (tc) 487 { 488 case TypeClass.UNSIGNED_SHORT_value: 489 return Long.valueOf( ((Short)object).shortValue() ); 490 case TypeClass.UNSIGNED_LONG_value: 491 return Long.valueOf( ((Integer)object).intValue() ); 492 case TypeClass.UNSIGNED_HYPER_value: 493 return object; 494 } 495 break; 496 case TypeClass.FLOAT_value: 497 switch (tc) 498 { 499 case TypeClass.BYTE_value: 500 return Float.valueOf( ((Byte)object).byteValue() ); 501 case TypeClass.SHORT_value: 502 return Float.valueOf( ((Short)object).shortValue() ); 503 case TypeClass.FLOAT_value: 504 return object; 505 } 506 break; 507 case TypeClass.DOUBLE_value: 508 switch (tc) 509 { 510 case TypeClass.BYTE_value: 511 return Double.valueOf( ((Byte)object).byteValue() ); 512 case TypeClass.SHORT_value: 513 return Double.valueOf( ((Short)object).shortValue() ); 514 case TypeClass.LONG_value: 515 return Double.valueOf( ((Integer)object).intValue() ); 516 case TypeClass.FLOAT_value: 517 return Double.valueOf( ((Float)object).floatValue() ); 518 case TypeClass.DOUBLE_value: 519 return object; 520 } 521 break; 522 case TypeClass.ENUM_value: 523 if (tc == TypeClass.ENUM_value && 524 (null == destTClass || destType.equals( type ) /* optional destType */)) 525 { 526 return object; 527 } 528 break; 529 case TypeClass.STRING_value: 530 if (tc == TypeClass.STRING_value) 531 return object; 532 break; 533 case TypeClass.TYPE_value: 534 if (tc == TypeClass.TYPE_value) 535 return object; 536 break; 537 case TypeClass.INTERFACE_value: 538 // Because object is a class, not an interface, it is 539 // controversial what kind of Type "new Type(object.class)" 540 // above should return (UNKNOWN or INTERFACE), so that we should 541 // not check here for "tc == TypeClass.INTERFACE_value". 542 // Instead, we check whether object (indirectly) derives from 543 // XInterface: 544 if (object instanceof XInterface) 545 return UnoRuntime.queryInterface( destType, object ); 546 break; 547 case TypeClass.STRUCT_value: 548 case TypeClass.EXCEPTION_value: 549 if (destType.isSupertypeOf(type)) { 550 return object; 551 } 552 break; 553 case TypeClass.SEQUENCE_value: 554 if (tc == TypeClass.SEQUENCE_value && 555 (null == destType || destType.equals( type ) /* optional destType */)) 556 { 557 return object; 558 } 559 break; 560 } 561 } 562 throw new com.sun.star.lang.IllegalArgumentException( 563 "The Argument did not hold the proper type"); 564 } 565 } 566