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 23 24 package com.sun.star.uno; 25 26 import java.util.HashMap; 27 28 /** 29 * Represents the UNO built-in type <code>TYPE</code>. 30 * 31 * <p>The UNO type is not directly mapped to <code>java.lang.Class</code> for at 32 * least two reasons. For one, some UNO types (like <code>UNSIGNED 33 * SHORT</code>) do not have a matching Java class. For another, it can be 34 * necessary to describe a type which is unknown to the Java runtime system 35 * (for example, for delaying the need of a class, so that it is possible to 36 * generate it on the fly.) 37 * 38 * <p>A <code>Type</code> is uniquely determined by its type class (a 39 * <code>TypeClass</code>) and its type name (a <code>String</code>); these two 40 * will never be <code>null</code>. A <code>Type</code> may have an additional 41 * "z class" (a <code>java.lang.Class</code>), giving a Java class type that 42 * corresponds to the UNO type. Also, a <code>Type</code> can cache a type 43 * description (a <code>com.sun.star.uno.ITypeDescription</code>), which can be 44 * computed and set by <code>TypeDescription.getTypeDescription</code>. 45 */ 46 public class Type { 47 // The following private static members and static initializer must come 48 // first in the class definition, so that the class can be initialized 49 // sucessfully: 50 51 private static final String TYPE_NAME_VOID = "void"; 52 private static final String TYPE_NAME_BOOLEAN = "boolean"; 53 private static final String TYPE_NAME_BYTE = "byte"; 54 private static final String TYPE_NAME_SHORT = "short"; 55 private static final String TYPE_NAME_UNSIGNED_SHORT = "unsigned short"; 56 private static final String TYPE_NAME_LONG = "long"; 57 private static final String TYPE_NAME_UNSIGNED_LONG = "unsigned long"; 58 private static final String TYPE_NAME_HYPER = "hyper"; 59 private static final String TYPE_NAME_UNSIGNED_HYPER = "unsigned hyper"; 60 private static final String TYPE_NAME_FLOAT = "float"; 61 private static final String TYPE_NAME_DOUBLE = "double"; 62 private static final String TYPE_NAME_CHAR = "char"; 63 private static final String TYPE_NAME_STRING = "string"; 64 private static final String TYPE_NAME_TYPE = "type"; 65 private static final String TYPE_NAME_ANY = "any"; 66 67 // must be sorted same as TypeClass: 68 private static final String[] __typeClassToTypeName = new String[] { 69 TYPE_NAME_VOID, 70 TYPE_NAME_CHAR, 71 TYPE_NAME_BOOLEAN, 72 TYPE_NAME_BYTE, 73 TYPE_NAME_SHORT, 74 TYPE_NAME_UNSIGNED_SHORT, 75 TYPE_NAME_LONG, 76 TYPE_NAME_UNSIGNED_LONG, 77 TYPE_NAME_HYPER, 78 TYPE_NAME_UNSIGNED_HYPER, 79 TYPE_NAME_FLOAT, 80 TYPE_NAME_DOUBLE, 81 TYPE_NAME_STRING, 82 TYPE_NAME_TYPE, 83 TYPE_NAME_ANY 84 }; 85 86 private static final HashMap __javaClassToTypeClass = new HashMap(); 87 static { __javaClassToTypeClass.put( void.class, new TypeClass[] { TypeClass.VOID, TypeClass.VOID })88 __javaClassToTypeClass.put( 89 void.class, new TypeClass[] { TypeClass.VOID, TypeClass.VOID }); __javaClassToTypeClass.put( Void.class, new TypeClass[] { TypeClass.VOID, TypeClass.VOID })90 __javaClassToTypeClass.put( 91 Void.class, new TypeClass[] { TypeClass.VOID, TypeClass.VOID }); __javaClassToTypeClass.put( boolean.class, new TypeClass[] { TypeClass.BOOLEAN, TypeClass.BOOLEAN })92 __javaClassToTypeClass.put( 93 boolean.class, 94 new TypeClass[] { TypeClass.BOOLEAN, TypeClass.BOOLEAN }); __javaClassToTypeClass.put( Boolean.class, new TypeClass[] { TypeClass.BOOLEAN, TypeClass.BOOLEAN })95 __javaClassToTypeClass.put( 96 Boolean.class, 97 new TypeClass[] { TypeClass.BOOLEAN, TypeClass.BOOLEAN }); __javaClassToTypeClass.put( byte.class, new TypeClass[] { TypeClass.BYTE, TypeClass.BYTE })98 __javaClassToTypeClass.put( 99 byte.class, new TypeClass[] { TypeClass.BYTE, TypeClass.BYTE }); __javaClassToTypeClass.put( Byte.class, new TypeClass[] { TypeClass.BYTE, TypeClass.BYTE })100 __javaClassToTypeClass.put( 101 Byte.class, new TypeClass[] { TypeClass.BYTE, TypeClass.BYTE }); __javaClassToTypeClass.put( short.class, new TypeClass[] { TypeClass.SHORT, TypeClass.UNSIGNED_SHORT })102 __javaClassToTypeClass.put( 103 short.class, 104 new TypeClass[] { TypeClass.SHORT, TypeClass.UNSIGNED_SHORT }); __javaClassToTypeClass.put( Short.class, new TypeClass[] { TypeClass.SHORT, TypeClass.UNSIGNED_SHORT })105 __javaClassToTypeClass.put( 106 Short.class, 107 new TypeClass[] { TypeClass.SHORT, TypeClass.UNSIGNED_SHORT }); __javaClassToTypeClass.put( int.class, new TypeClass[] { TypeClass.LONG, TypeClass.UNSIGNED_LONG })108 __javaClassToTypeClass.put( 109 int.class, 110 new TypeClass[] { TypeClass.LONG, TypeClass.UNSIGNED_LONG }); __javaClassToTypeClass.put( Integer.class, new TypeClass[] { TypeClass.LONG, TypeClass.UNSIGNED_LONG })111 __javaClassToTypeClass.put( 112 Integer.class, 113 new TypeClass[] { TypeClass.LONG, TypeClass.UNSIGNED_LONG }); __javaClassToTypeClass.put( long.class, new TypeClass[] { TypeClass.HYPER, TypeClass.UNSIGNED_HYPER })114 __javaClassToTypeClass.put( 115 long.class, 116 new TypeClass[] { TypeClass.HYPER, TypeClass.UNSIGNED_HYPER }); __javaClassToTypeClass.put( Long.class, new TypeClass[] { TypeClass.HYPER, TypeClass.UNSIGNED_HYPER })117 __javaClassToTypeClass.put( 118 Long.class, 119 new TypeClass[] { TypeClass.HYPER, TypeClass.UNSIGNED_HYPER }); __javaClassToTypeClass.put( float.class, new TypeClass[] { TypeClass.FLOAT, TypeClass.FLOAT })120 __javaClassToTypeClass.put( 121 float.class, new TypeClass[] { TypeClass.FLOAT, TypeClass.FLOAT }); __javaClassToTypeClass.put( Float.class, new TypeClass[] { TypeClass.FLOAT, TypeClass.FLOAT })122 __javaClassToTypeClass.put( 123 Float.class, new TypeClass[] { TypeClass.FLOAT, TypeClass.FLOAT }); __javaClassToTypeClass.put( double.class, new TypeClass[] { TypeClass.DOUBLE, TypeClass.DOUBLE })124 __javaClassToTypeClass.put( 125 double.class, 126 new TypeClass[] { TypeClass.DOUBLE, TypeClass.DOUBLE }); __javaClassToTypeClass.put( Double.class, new TypeClass[] { TypeClass.DOUBLE, TypeClass.DOUBLE })127 __javaClassToTypeClass.put( 128 Double.class, 129 new TypeClass[] { TypeClass.DOUBLE, TypeClass.DOUBLE }); __javaClassToTypeClass.put( char.class, new TypeClass[] { TypeClass.CHAR, TypeClass.CHAR })130 __javaClassToTypeClass.put( 131 char.class, new TypeClass[] { TypeClass.CHAR, TypeClass.CHAR }); __javaClassToTypeClass.put( Character.class, new TypeClass[] { TypeClass.CHAR, TypeClass.CHAR })132 __javaClassToTypeClass.put( 133 Character.class, 134 new TypeClass[] { TypeClass.CHAR, TypeClass.CHAR }); __javaClassToTypeClass.put( String.class, new TypeClass[] { TypeClass.STRING, TypeClass.STRING })135 __javaClassToTypeClass.put( 136 String.class, 137 new TypeClass[] { TypeClass.STRING, TypeClass.STRING }); __javaClassToTypeClass.put( Type.class, new TypeClass[] { TypeClass.TYPE, TypeClass.TYPE })138 __javaClassToTypeClass.put( 139 Type.class, new TypeClass[] { TypeClass.TYPE, TypeClass.TYPE }); __javaClassToTypeClass.put( Any.class, new TypeClass[] { TypeClass.ANY, TypeClass.ANY })140 __javaClassToTypeClass.put( 141 Any.class, new TypeClass[] { TypeClass.ANY, TypeClass.ANY }); __javaClassToTypeClass.put( Object.class, new TypeClass[] { TypeClass.ANY, TypeClass.INTERFACE })142 __javaClassToTypeClass.put( 143 Object.class, 144 new TypeClass[] { TypeClass.ANY, TypeClass.INTERFACE }); 145 } 146 147 public static final Type VOID = new Type(void.class); 148 public static final Type CHAR = new Type(char.class); 149 public static final Type BOOLEAN = new Type(boolean.class); 150 public static final Type BYTE = new Type(byte.class); 151 public static final Type SHORT = new Type(short.class); 152 public static final Type UNSIGNED_SHORT = new Type( 153 TYPE_NAME_UNSIGNED_SHORT, TypeClass.UNSIGNED_SHORT); 154 public static final Type LONG = new Type(int.class); 155 public static final Type UNSIGNED_LONG = new Type( 156 TYPE_NAME_UNSIGNED_LONG, TypeClass.UNSIGNED_LONG); 157 public static final Type HYPER = new Type(long.class); 158 public static final Type UNSIGNED_HYPER = new Type( 159 TYPE_NAME_UNSIGNED_HYPER, TypeClass.UNSIGNED_HYPER); 160 public static final Type FLOAT = new Type(float.class); 161 public static final Type DOUBLE = new Type(double.class); 162 public static final Type STRING = new Type(String.class); 163 public static final Type TYPE = new Type(Type.class); 164 public static final Type ANY = new Type(Any.class); 165 166 /** 167 * Constructs a new <code>Type</code> which defaults to <code>VOID</code>. 168 */ Type()169 public Type() { 170 init(null, void.class, false, false); 171 } 172 173 /** 174 * Constructs a new <code>Type</code> with the given type class and type 175 * name. 176 * 177 * @param typeName the type name. Must not be <code>null</code>. 178 * @param typeClass the type class. Must not be <code>null</code>, and must 179 * match the <code>typeName</code> (for example, it is illegal to 180 * combine a <code>typeName</code> of <code>"void"</code> with a 181 * <code>typeClass</code> of <code>BOOLEAN</code>). 182 */ Type(String typeName, TypeClass typeClass)183 public Type(String typeName, TypeClass typeClass) { 184 _typeClass = typeClass; 185 _typeName = typeName; 186 } 187 188 /** 189 * Constructs a new <code>Type</code> from the given 190 * <code>java.lang.Class</code>. 191 * 192 * <p>This is equivalent to <code>Type(zClass, false)</code>.</p> 193 * 194 * @param zClass the Java class of this type. Must not be 195 * <code>null</code>. 196 */ Type(Class zClass)197 public Type(Class zClass) { 198 init(null, zClass, false, false); 199 } 200 201 /** 202 * Constructs a new <code>Type</code> from the given 203 * <code>java.lang.Class</code>, handling ambiguous cases. 204 * 205 * <p>In certain cases, one Java class corresponds to two UNO types (e.g., 206 * the Java class <code>short[].class</code> corresponds to both a sequence 207 * of <code>SHORT</code> and a sequence of <code>UNSIGNED SHORT</code> in 208 * UNO). In such ambiguous cases, the parameter <code>alternative</code> 209 * controls which UNO type is chosen:</p> 210 * <ul> 211 * <li>If the Java type is (an array type with element type) 212 * <code>short</code> or <code>java.lang.Short</code>: If 213 * <code>alternative</code> is <code>false</code>, the chosen UNO type is 214 * (a sequence type with element type) <code>SHORT</code>. If 215 * <code>alternative</code> is <code>true</code>, the chosen UNO type is 216 * (a sequence type with element type) <code>UNSIGNED SHORT</code>.</li> 217 * 218 * <li>If the Java type is (an array type with element type) 219 * <code>int</code> or <code>java.lang.Integer</code>: If 220 * <code>alternative</code> is <code>false</code>, the chosen UNO type is 221 * (a sequence type with element type) <code>LONG</code>. If 222 * <code>alternative</code> is <code>true</code>, the chosen UNO type is 223 * (a sequence type with element type) <code>UNSIGNED LONG</code>.</li> 224 * 225 * <li>If the Java type is (an array type with element type) 226 * <code>long</code> or <code>java.lang.Long</code>: If 227 * <code>alternative</code> is <code>false</code>, the chosen UNO type is 228 * (a sequence type with element type) <code>HYPER</code>. If 229 * <code>alternative</code> is <code>true</code>, the chosen UNO type is 230 * (a sequence type with element type) <code>UNSIGNED HYPER</code>.</li> 231 * 232 * <li>If the Java type is (an array type with element type) 233 * <code>java.lang.Object</code>: If <code>alternative</code> is 234 * <code>false</code>, the chosen UNO type is (a sequence type with 235 * element type) <code>ANY</code>. If <code>alternative</code> is 236 * <code>true</code>, the chosen UNO type is (a sequence type with element 237 * type) <code>com.sun.star.uno.XInterface</code>.</li> 238 * </ul> 239 * <p>In all other cases, the value of <code>alternative</code> is 240 * ignored.</p> 241 * 242 * <p>This constructor cannot be used to create <code>Type</code> instances 243 * that represent (sequences of) instantiated polymorphic struct types.</p> 244 * 245 * @param zClass the Java class of this type; must not be <code>null</code> 246 * @param alternative controls which UNO type to choose in case of 247 * ambiguities 248 * 249 * @since UDK 3.2.0 250 */ Type(Class zClass, boolean alternative)251 public Type(Class zClass, boolean alternative) { 252 init(null, zClass, alternative, false); 253 } 254 255 /** 256 * Constructs a new <code>Type</code> from the given type description. 257 * 258 * @param typeDescription a type description. Must not be 259 * <code>null</code>. 260 */ Type(ITypeDescription typeDescription)261 public Type(ITypeDescription typeDescription) { 262 _typeName = typeDescription.getTypeName(); 263 _typeClass = typeDescription.getTypeClass(); 264 _iTypeDescription = typeDescription; 265 } 266 267 /** 268 * Constructs a new <code>Type</code> with the given type name. 269 * 270 * @param typeName the name of this type; must not be <code>null</code>. 271 */ Type(String typeName)272 public Type(String typeName) { 273 if (typeName.startsWith("[]")) { 274 _typeName = typeName; 275 _typeClass = TypeClass.SEQUENCE; 276 return; 277 } 278 for (int i = 0; i < __typeClassToTypeName.length; ++i) { 279 if (__typeClassToTypeName[i].equals(typeName)) { 280 _typeName = typeName; 281 _typeClass = TypeClass.fromInt(i); 282 return; 283 } 284 } 285 int i = typeName.indexOf('<'); 286 try { 287 init( 288 typeName, 289 Class.forName(i < 0 ? typeName : typeName.substring(0, i)), 290 false, i >= 0); 291 } catch (ClassNotFoundException e) { 292 throw new RuntimeException(e.toString()); 293 } 294 } 295 296 /** 297 * Constructs a new <code>Type</code> with the given type class. 298 * 299 * @param typeClass the type class of this type; must not be 300 * <code>null</code>. Only type classes for simple types are allowed 301 * here. 302 * 303 * @throws IllegalArgumentException if the given <code>typeClass</code> is 304 * not simple (for example, a struct or an interface type). This 305 * constructor could not find out the type name in such a case. 306 */ Type(TypeClass typeClass)307 public Type(TypeClass typeClass) { 308 if(__isTypeClassPrimitive(typeClass)) { 309 _typeClass = typeClass; 310 _typeName = __typeClassToTypeName[typeClass.getValue()]; 311 } 312 else 313 throw new IllegalArgumentException(typeClass + " is not primitive"); 314 } 315 316 /** 317 * Gets the type class. 318 * 319 * @return the type class. Will never be <code>null</code>, but might be 320 * <code>UNKNOWN</code>. 321 */ getTypeClass()322 public TypeClass getTypeClass() { 323 return _typeClass; 324 } 325 326 /** 327 * Gets the type name. 328 * 329 * @return the type name; will never be <code>null</code> 330 */ getTypeName()331 public String getTypeName() { 332 return _typeName; 333 } 334 335 /** 336 * Gets the Java class. 337 * 338 * @return the type name; may be <code>null</code> in extreme situations 339 * (inconsistent <code>TypeClass</code>, error loading a class) 340 */ getZClass()341 public Class getZClass() { 342 synchronized (this) { 343 if (_class == null) { 344 _class = determineClass(); 345 } 346 } 347 return _class; 348 } 349 350 /** 351 * Gives the type description of this type. 352 * 353 * @return the type description; may be <code>null</code> 354 */ getTypeDescription()355 public ITypeDescription getTypeDescription() { 356 return _iTypeDescription; 357 } 358 359 /** 360 * Sets the type description for this type. 361 * 362 * @param typeDescription the type description 363 */ setTypeDescription(ITypeDescription typeDescription)364 public void setTypeDescription(ITypeDescription typeDescription) { 365 _iTypeDescription = typeDescription; 366 } 367 368 /** 369 * Determines whether this UNO type is a supertype of another UNO type. 370 * 371 * UNO only defines the following supertype relations: 372 * (1) A struct type t1 is a supertype of a struct type t2, if either t1 373 * and t2 are the same, or t1 is a direct or indirect parent of t2. 374 * (2) An exception type t1 is a supertype of an exception type t2, if 375 * either t1 and t2 are the same, or t1 is a direct or indirect parent 376 * of t2. 377 * (3) An interface type t1 is a supertype of an interface type t2, if 378 * either t1 and t2 are the same, or t1 is a direct or indirect parent 379 * of t2. 380 * 381 * Following the conventions of the Java UNO language binding, 382 * com.sun.star.uno.Exception is not considered a supertype of 383 * com.sun.star.uno.RuntimeException or any exception type derived from 384 * com.sun.star.uno.RuntimeException. 385 * 386 * @param type some Type 387 * @return true if this type is a supertype of the given type 388 * 389 * @since UDK 3.2.0 390 */ isSupertypeOf(Type type)391 public boolean isSupertypeOf(Type type) { 392 if (_typeClass != type._typeClass) { 393 return false; 394 } 395 switch (_typeClass.getValue()) { 396 case TypeClass.SEQUENCE_value: 397 case TypeClass.ENUM_value: 398 return _typeName.equals(type._typeName); 399 400 case TypeClass.STRUCT_value: 401 // This check exploits the fact that an instantiated polymorphic 402 // struct type may not be the direct base of a struct type: 403 if (_typeName.indexOf('<') >= 0 || type._typeName.indexOf('<') >= 0) 404 { 405 return _typeName.equals(type._typeName); 406 } 407 case TypeClass.EXCEPTION_value: 408 case TypeClass.INTERFACE_value: 409 Class c1 = getZClass(); 410 Class c2 = type.getZClass(); 411 return c1 != null && c2 != null && c1.isAssignableFrom(c2); 412 413 default: 414 return true; 415 } 416 } 417 418 // @see java.lang.Object#equals equals(Object obj)419 public boolean equals(Object obj) { 420 return obj instanceof Type 421 && _typeClass == ((Type) obj)._typeClass 422 && _typeName.equals(((Type) obj)._typeName); 423 } 424 425 // @see java.lang.Object#hashCode hashCode()426 public int hashCode() { 427 return _typeName.hashCode(); 428 } 429 430 // @see java.lang.Object#toString toString()431 public String toString() { 432 return "Type[" + _typeName + "]"; 433 } 434 init( String name, Class zClass, boolean alternative, boolean arguments)435 private void init( 436 String name, Class zClass, boolean alternative, boolean arguments) 437 { 438 TypeClass[] tc = (TypeClass[]) __javaClassToTypeClass.get(zClass); 439 if (tc != null) { 440 // tc only contains primitive type classes, except for 441 // TypeClass.INTERFACE, which stands for XInterface (the alternative 442 // interpretation of java.lang.Object): 443 _typeClass = tc[alternative ? 1 : 0]; 444 _typeName = _typeClass == TypeClass.INTERFACE 445 ? XInterface.class.getName() 446 : __typeClassToTypeName[_typeClass.getValue()]; 447 // do not assign _class from zClass, as _class should always be 448 // normalized (e.g., boolean.class instead of 449 // java.lang.Boolean.class); getZClass will later calculate the 450 // correct class when needed 451 } else if (zClass.isArray()) { 452 Type t = new Type(zClass.getComponentType(), alternative); 453 _typeClass = t.getTypeClass() != TypeClass.UNKNOWN 454 ? TypeClass.SEQUENCE : TypeClass.UNKNOWN; 455 _typeName = "[]" + t.getTypeName(); 456 // do not assign _class from zClass, as _class should always be 457 // normalized (e.g., boolean[].class instead of 458 // java.lang.Boolean[].class); getZClass will later calculate the 459 // correct class when needed 460 } else if (Enum.class.isAssignableFrom(zClass)) { 461 _typeClass = zClass != Enum.class 462 ? TypeClass.ENUM : TypeClass.UNKNOWN; 463 _typeName = zClass.getName(); 464 _class = zClass; 465 } else if (Throwable.class.isAssignableFrom(zClass)) { 466 _typeClass 467 = com.sun.star.uno.Exception.class.isAssignableFrom(zClass) 468 || com.sun.star.uno.RuntimeException.class.isAssignableFrom( 469 zClass) 470 ? TypeClass.EXCEPTION : TypeClass.UNKNOWN; 471 _typeName = zClass.getName(); 472 _class = zClass; 473 } else if (zClass.isInterface()) { 474 _typeClass = XInterface.class.isAssignableFrom(zClass) 475 ? TypeClass.INTERFACE : TypeClass.UNKNOWN; 476 _typeName = zClass.getName(); 477 _class = zClass; 478 } else if (XInterface.class.isAssignableFrom(zClass)) { 479 // This case is needed by code that uses this constructor to 480 // calculate the UNO type corresponding to a Java object: 481 _typeClass = TypeClass.INTERFACE; 482 _typeName = XInterface.class.getName(); 483 _class = XInterface.class; 484 } else { 485 // assert zClass != Object.class && !zClass.isPrimitive(); 486 _typeClass = TypeClass.STRUCT; 487 _typeName = name == null ? zClass.getName() : name; 488 _class = zClass; 489 } 490 if (arguments && _typeClass != TypeClass.STRUCT) { 491 throw new IllegalArgumentException( 492 zClass + " cannot have type arguments"); 493 } 494 } 495 determineClass()496 private Class determineClass() { 497 switch (_typeClass.getValue()) { 498 case TypeClass.VOID_value: 499 return _typeName.equals(TYPE_NAME_VOID) ? void.class : null; 500 501 case TypeClass.BOOLEAN_value: 502 return _typeName.equals(TYPE_NAME_BOOLEAN) ? boolean.class : null; 503 504 case TypeClass.BYTE_value: 505 return _typeName.equals(TYPE_NAME_BYTE) ? byte.class : null; 506 507 case TypeClass.SHORT_value: 508 return _typeName.equals(TYPE_NAME_SHORT) ? short.class : null; 509 510 case TypeClass.UNSIGNED_SHORT_value: 511 return _typeName.equals(TYPE_NAME_UNSIGNED_SHORT) 512 ? short.class : null; 513 514 case TypeClass.LONG_value: 515 return _typeName.equals(TYPE_NAME_LONG) ? int.class : null; 516 517 case TypeClass.UNSIGNED_LONG_value: 518 return _typeName.equals(TYPE_NAME_UNSIGNED_LONG) ? int.class : null; 519 520 case TypeClass.HYPER_value: 521 return _typeName.equals(TYPE_NAME_HYPER) ? long.class : null; 522 523 case TypeClass.UNSIGNED_HYPER_value: 524 return _typeName.equals(TYPE_NAME_UNSIGNED_HYPER) 525 ? long.class : null; 526 527 case TypeClass.FLOAT_value: 528 return _typeName.equals(TYPE_NAME_FLOAT) ? float.class : null; 529 530 case TypeClass.DOUBLE_value: 531 return _typeName.equals(TYPE_NAME_DOUBLE) ? double.class : null; 532 533 case TypeClass.CHAR_value: 534 return _typeName.equals(TYPE_NAME_CHAR) ? char.class : null; 535 536 case TypeClass.STRING_value: 537 return _typeName.equals(TYPE_NAME_STRING) ? String.class : null; 538 539 case TypeClass.TYPE_value: 540 return _typeName.equals(TYPE_NAME_TYPE) ? Type.class : null; 541 542 case TypeClass.ANY_value: 543 return _typeName.equals(TYPE_NAME_ANY) ? Object.class : null; 544 545 case TypeClass.SEQUENCE_value: 546 StringBuffer buf = new StringBuffer(); 547 int offset = 0; 548 for (; _typeName.startsWith("[]", offset); offset += "[]".length()) 549 { 550 buf.append('['); 551 } 552 if (buf.length() == 0) { 553 return null; 554 } 555 String base = _typeName.substring(offset); 556 if (base.equals(TYPE_NAME_VOID)) { 557 buf.append('V'); 558 } else if (base.equals(TYPE_NAME_BOOLEAN)) { 559 buf.append('Z'); 560 } else if (base.equals(TYPE_NAME_BYTE)) { 561 buf.append('B'); 562 } else if (base.equals(TYPE_NAME_SHORT) 563 || base.equals(TYPE_NAME_UNSIGNED_SHORT)) { 564 buf.append('S'); 565 } else if (base.equals(TYPE_NAME_LONG) 566 || base.equals(TYPE_NAME_UNSIGNED_LONG)) { 567 buf.append('I'); 568 } else if (base.equals(TYPE_NAME_HYPER) 569 || base.equals(TYPE_NAME_UNSIGNED_HYPER)) { 570 buf.append('J'); 571 } else if (base.equals(TYPE_NAME_FLOAT)) { 572 buf.append('F'); 573 } else if (base.equals(TYPE_NAME_DOUBLE)) { 574 buf.append('D'); 575 } else if (base.equals(TYPE_NAME_CHAR)) { 576 buf.append('C'); 577 } else if (base.equals(TYPE_NAME_STRING)) { 578 buf.append("Ljava.lang.String;"); 579 } else if (base.equals(TYPE_NAME_TYPE)) { 580 buf.append("Lcom.sun.star.uno.Type;"); 581 } else if (base.equals(TYPE_NAME_ANY)) { 582 buf.append("Ljava.lang.Object;"); 583 } else { 584 int args = base.indexOf('<'); 585 if (args >= 0) { 586 base = base.substring(0, args); 587 } 588 Class c; 589 try { 590 c = Class.forName(base); 591 } catch (ClassNotFoundException e) { 592 return null; 593 } 594 if (args < 0 && new Type(c).getTypeClass() == TypeClass.UNKNOWN) 595 { 596 return null; 597 } 598 buf.append('L'); 599 buf.append(base); 600 buf.append(';'); 601 } 602 try { 603 return Class.forName(buf.toString()); 604 } catch (ClassNotFoundException e) { 605 return null; 606 } 607 608 case TypeClass.ENUM_value: 609 case TypeClass.EXCEPTION_value: 610 case TypeClass.INTERFACE_value: 611 { 612 Class c; 613 try { 614 c = Class.forName(_typeName); 615 } catch (ClassNotFoundException e) { 616 return null; 617 } 618 return new Type(c).equals(this) ? c : null; 619 } 620 621 case TypeClass.STRUCT_value: 622 { 623 int args = _typeName.indexOf('<'); 624 Class c; 625 try { 626 c = Class.forName( 627 args < 0 ? _typeName : _typeName.substring(0, args)); 628 } catch (ClassNotFoundException e) { 629 return null; 630 } 631 return args >= 0 || new Type(c).equals(this) ? c : null; 632 } 633 634 default: 635 return null; 636 } 637 } 638 __isTypeClassPrimitive(TypeClass typeClass)639 private static boolean __isTypeClassPrimitive(TypeClass typeClass) { 640 return typeClass.getValue() < __typeClassToTypeName.length; 641 } 642 643 protected TypeClass _typeClass; // TODO should be final 644 protected String _typeName; // TODO should be final 645 646 protected Class _class; 647 protected ITypeDescription _iTypeDescription; 648 } 649