1*a046d00fSAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*a046d00fSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*a046d00fSAndrew Rist * or more contributor license agreements. See the NOTICE file 5*a046d00fSAndrew Rist * distributed with this work for additional information 6*a046d00fSAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*a046d00fSAndrew Rist * to you under the Apache License, Version 2.0 (the 8*a046d00fSAndrew Rist * "License"); you may not use this file except in compliance 9*a046d00fSAndrew Rist * with the License. You may obtain a copy of the License at 10*a046d00fSAndrew Rist * 11*a046d00fSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12*a046d00fSAndrew Rist * 13*a046d00fSAndrew Rist * Unless required by applicable law or agreed to in writing, 14*a046d00fSAndrew Rist * software distributed under the License is distributed on an 15*a046d00fSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*a046d00fSAndrew Rist * KIND, either express or implied. See the License for the 17*a046d00fSAndrew Rist * specific language governing permissions and limitations 18*a046d00fSAndrew Rist * under the License. 19*a046d00fSAndrew Rist * 20*a046d00fSAndrew Rist *************************************************************/ 21*a046d00fSAndrew Rist 22*a046d00fSAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir package com.sun.star.uno; 25cdf0e10cSrcweir 26cdf0e10cSrcweir import java.io.IOException; 27cdf0e10cSrcweir import java.lang.reflect.Array; 28cdf0e10cSrcweir import java.lang.reflect.Constructor; 29cdf0e10cSrcweir import java.util.ArrayList; 30cdf0e10cSrcweir import java.util.Iterator; 31cdf0e10cSrcweir import com.sun.star.lib.uno.typedesc.TypeDescription; 32cdf0e10cSrcweir import com.sun.star.lib.util.WeakMap; 33cdf0e10cSrcweir 34cdf0e10cSrcweir /** 35cdf0e10cSrcweir * The central class needed for implementing or using UNO components in Java. 36cdf0e10cSrcweir * 37cdf0e10cSrcweir * <p>The methods <code>queryInterface</code> and <code>areSame</code> delegate 38cdf0e10cSrcweir * calls to the implementing objects and are used instead of casts, 39cdf0e10cSrcweir * <code>instanceof</code>, <code>==</code>, and <code>equals</code>.<p> 40cdf0e10cSrcweir * 41cdf0e10cSrcweir * <p>For historic reasons, this class is not <code>final</code>, and has a 42cdf0e10cSrcweir * <code>public</code> constructor. These artifacts are considered mistakes, 43cdf0e10cSrcweir * which might be corrected in a future version of this class, so client code 44cdf0e10cSrcweir * should not rely on them.</p> 45cdf0e10cSrcweir * 46cdf0e10cSrcweir * @see com.sun.star.uno.IBridge 47cdf0e10cSrcweir * @see com.sun.star.uno.IEnvironment 48cdf0e10cSrcweir * @see com.sun.star.uno.IQueryInterface 49cdf0e10cSrcweir */ 50cdf0e10cSrcweir public class UnoRuntime { 51cdf0e10cSrcweir /** 52cdf0e10cSrcweir * @deprecated As of UDK 3.2.0, do not create instances of this class. 53cdf0e10cSrcweir * It is considered a historic mistake to have a <code>public</code> 54cdf0e10cSrcweir * constructor for this class, which only has <code>static</code> members. 55cdf0e10cSrcweir * Also, this class might be changed to become <code>final</code> in a 56cdf0e10cSrcweir * future version. 57cdf0e10cSrcweir */ 58cdf0e10cSrcweir public UnoRuntime() {} 59cdf0e10cSrcweir 60cdf0e10cSrcweir /** 61cdf0e10cSrcweir * Generates a world wide unique identifier string. 62cdf0e10cSrcweir * 63cdf0e10cSrcweir * <p>It is guaranteed that every invocation of this method generates a new 64cdf0e10cSrcweir * ID, which is unique within the VM. The quality of “world wide 65cdf0e10cSrcweir * unique” will depend on the actual implementation, you should look 66cdf0e10cSrcweir * at the source to determine if it meets your requirements.</p> 67cdf0e10cSrcweir * 68cdf0e10cSrcweir * @return a unique <code>String</code> 69cdf0e10cSrcweir */ 70cdf0e10cSrcweir public static String getUniqueKey() { 71cdf0e10cSrcweir synchronized (uniqueKeyLock) { 72cdf0e10cSrcweir if (uniqueKeyCount == Long.MAX_VALUE) { 73cdf0e10cSrcweir long time; 74cdf0e10cSrcweir for (time = System.currentTimeMillis(); time == uniqueKeyTime;) 75cdf0e10cSrcweir { 76cdf0e10cSrcweir // Conservatively sleep for 100 millisecond to wait for 77cdf0e10cSrcweir // System.currentTimeMillis() to change: 78cdf0e10cSrcweir try { 79cdf0e10cSrcweir Thread.sleep(100); 80cdf0e10cSrcweir } catch (InterruptedException e) { 81cdf0e10cSrcweir Thread.currentThread().interrupt(); 82cdf0e10cSrcweir } 83cdf0e10cSrcweir } 84cdf0e10cSrcweir uniqueKeyTime = time; 85cdf0e10cSrcweir uniqueKeyCount = Long.MIN_VALUE; 86cdf0e10cSrcweir } 87cdf0e10cSrcweir return uniqueKeyHostPrefix + Long.toString(uniqueKeyTime, 16) + ":" 88cdf0e10cSrcweir + Long.toString(uniqueKeyCount++, 16); 89cdf0e10cSrcweir } 90cdf0e10cSrcweir } 91cdf0e10cSrcweir 92cdf0e10cSrcweir /** 93cdf0e10cSrcweir * Generates a world wide unique object identifier (OID) for the given 94cdf0e10cSrcweir * Java object. 95cdf0e10cSrcweir * 96cdf0e10cSrcweir * <p>It is guaranteed that subsequent calls to this method with the same 97cdf0e10cSrcweir * Java object will give the same ID.</p> 98cdf0e10cSrcweir * 99cdf0e10cSrcweir * <p>This method is generally of little use for client code. It should be 100cdf0e10cSrcweir * considered a mistake that this method is published at all.</p> 101cdf0e10cSrcweir * 102cdf0e10cSrcweir * @param object any object for which a OID shall be generated; must not be 103cdf0e10cSrcweir * <code>null</code> 104cdf0e10cSrcweir * @return the generated OID 105cdf0e10cSrcweir * @see com.sun.star.uno.IQueryInterface#getOid 106cdf0e10cSrcweir */ 107cdf0e10cSrcweir public static String generateOid(Object object) { 108cdf0e10cSrcweir String oid = null; 109cdf0e10cSrcweir if (object instanceof IQueryInterface) { 110cdf0e10cSrcweir oid = ((IQueryInterface) object).getOid(); 111cdf0e10cSrcweir } 112cdf0e10cSrcweir return oid == null ? object.hashCode() + oidSuffix : oid; 113cdf0e10cSrcweir } 114cdf0e10cSrcweir 115cdf0e10cSrcweir /** 116cdf0e10cSrcweir * Queries the given UNO object for the given UNO interface type. 117cdf0e10cSrcweir * 118cdf0e10cSrcweir * <p>This method returns <code>null</code> in case the given UNO object 119cdf0e10cSrcweir * does not support the given UNO interface type (or is itself 120cdf0e10cSrcweir * <code>null</code>). Otherwise, a reference to a Java object implementing 121cdf0e10cSrcweir * the Java interface type corresponding to the given UNO interface is 122cdf0e10cSrcweir * returned. In the latter case, it is unspecified whether the returned 123cdf0e10cSrcweir * Java object is the same as the given object, or is another facet of that 124cdf0e10cSrcweir * UNO object.</p> 125cdf0e10cSrcweir * 126cdf0e10cSrcweir * @param type the requested UNO interface type; must be a <code>Type</code> 127cdf0e10cSrcweir * object representing a UNO interface type 128cdf0e10cSrcweir * @param object a reference to any Java object representing (a facet of) a 129cdf0e10cSrcweir * UNO object; may be <code>null</code> 130cdf0e10cSrcweir * @return a reference to the requested UNO interface type if available, 131cdf0e10cSrcweir * otherwise <code>null</code> 132cdf0e10cSrcweir * @see com.sun.star.uno.IQueryInterface#queryInterface 133cdf0e10cSrcweir */ 134cdf0e10cSrcweir public static Object queryInterface(Type type, Object object) { 135cdf0e10cSrcweir // Gracefully handle those situations where the passed in UNO object is 136cdf0e10cSrcweir // wrapped in an Any. Strictly speaking, such a situation constitutes a 137cdf0e10cSrcweir // bug, but it is anticipated that such situations will arise quite 138cdf0e10cSrcweir // often in practice (especially since UNO Anys containing an XInterface 139cdf0e10cSrcweir // reference are not wrapped in a Java Any, but UNO Anys containing any 140cdf0e10cSrcweir // other interface reference are wrapped in a Java Any, which can lead 141cdf0e10cSrcweir // to confusion). 142cdf0e10cSrcweir if (object instanceof Any) { 143cdf0e10cSrcweir Any a = (Any) object; 144cdf0e10cSrcweir if (a.getType().getTypeClass() == TypeClass.INTERFACE) { 145cdf0e10cSrcweir object = a.getObject(); 146cdf0e10cSrcweir } 147cdf0e10cSrcweir } 148cdf0e10cSrcweir if (object instanceof IQueryInterface) { 149cdf0e10cSrcweir object = ((IQueryInterface) object).queryInterface(type); 150cdf0e10cSrcweir if (object instanceof Any) { 151cdf0e10cSrcweir Any a = (Any) object; 152cdf0e10cSrcweir object = a.getType().getTypeClass() == TypeClass.INTERFACE 153cdf0e10cSrcweir ? a.getObject() : null; 154cdf0e10cSrcweir } 155cdf0e10cSrcweir } 156cdf0e10cSrcweir // Ensure that the object implements the requested interface type: 157cdf0e10cSrcweir Class c = type.getZClass(); 158cdf0e10cSrcweir if (c == null || !c.isInstance(object)) { 159cdf0e10cSrcweir object = null; 160cdf0e10cSrcweir } 161cdf0e10cSrcweir return object; 162cdf0e10cSrcweir } 163cdf0e10cSrcweir 164cdf0e10cSrcweir /** 165cdf0e10cSrcweir * Queries the given UNO object for the given Java class (which must 166cdf0e10cSrcweir * represent a UNO interface type). 167cdf0e10cSrcweir * 168cdf0e10cSrcweir * @param ifc a Java class representing a UNO interface type 169cdf0e10cSrcweir * @param object a reference to any Java object representing (a facet of) a 170cdf0e10cSrcweir * UNO object; may be <code>null</code> 171cdf0e10cSrcweir * @return a reference to the requested UNO interface type if available, 172cdf0e10cSrcweir * otherwise <code>null</code> 173cdf0e10cSrcweir * @see #queryInterface(Type, Object) 174cdf0e10cSrcweir */ 175cdf0e10cSrcweir @SuppressWarnings("unchecked") 176cdf0e10cSrcweir public static <T> T queryInterface(Class<T> zInterface, Object object) { 177cdf0e10cSrcweir return (T) queryInterface(new Type(zInterface), object); 178cdf0e10cSrcweir } 179cdf0e10cSrcweir 180cdf0e10cSrcweir /** 181cdf0e10cSrcweir Tests two UNO <code>ANY</code> values for equality. 182cdf0e10cSrcweir 183cdf0e10cSrcweir <p>Two UNO values are <dfn>equal</dfn> if and only if they are of the 184cdf0e10cSrcweir same UNO type <var>t</var>, and they meet the following condition, 185cdf0e10cSrcweir depending on <var>t</var>:</p> 186cdf0e10cSrcweir <ul> 187cdf0e10cSrcweir <li>If <var>t</var> is a primitive type, then both values must denote 188cdf0e10cSrcweir the same element of the set of values of <var>t</var>.</li> 189cdf0e10cSrcweir 190cdf0e10cSrcweir <li>If <var>t</var> is a structured type, then both values must 191cdf0e10cSrcweir recursively contain corresponding values that are equal.</li> 192cdf0e10cSrcweir 193cdf0e10cSrcweir <li>If <var>t</var> is an interface type, then the two values must be 194cdf0e10cSrcweir either both null references, or both references to the same UNO 195cdf0e10cSrcweir object.</li> 196cdf0e10cSrcweir </ul> 197cdf0e10cSrcweir 198cdf0e10cSrcweir @param any1 a Java value representing a UNO <code>ANY</code> value. 199cdf0e10cSrcweir 200cdf0e10cSrcweir @param any2 a Java value representing a UNO <code>ANY</code> value. 201cdf0e10cSrcweir 202cdf0e10cSrcweir @return <code>true</code> if and only if the two arguments represent 203cdf0e10cSrcweir equal UNO values. 204cdf0e10cSrcweir */ 205cdf0e10cSrcweir public static boolean areSame(Object any1, Object any2) { 206cdf0e10cSrcweir Any a1 = Any.complete(any1); 207cdf0e10cSrcweir Any a2 = Any.complete(any2); 208cdf0e10cSrcweir Type t = a1.getType(); 209cdf0e10cSrcweir if (!a2.getType().equals(t)) { 210cdf0e10cSrcweir return false; 211cdf0e10cSrcweir } 212cdf0e10cSrcweir Object v1 = a1.getObject(); 213cdf0e10cSrcweir Object v2 = a2.getObject(); 214cdf0e10cSrcweir switch (t.getTypeClass().getValue()) { 215cdf0e10cSrcweir case TypeClass.VOID_value: 216cdf0e10cSrcweir return true; 217cdf0e10cSrcweir case TypeClass.BOOLEAN_value: 218cdf0e10cSrcweir case TypeClass.BYTE_value: 219cdf0e10cSrcweir case TypeClass.SHORT_value: 220cdf0e10cSrcweir case TypeClass.UNSIGNED_SHORT_value: 221cdf0e10cSrcweir case TypeClass.LONG_value: 222cdf0e10cSrcweir case TypeClass.UNSIGNED_LONG_value: 223cdf0e10cSrcweir case TypeClass.HYPER_value: 224cdf0e10cSrcweir case TypeClass.UNSIGNED_HYPER_value: 225cdf0e10cSrcweir case TypeClass.FLOAT_value: 226cdf0e10cSrcweir case TypeClass.DOUBLE_value: 227cdf0e10cSrcweir case TypeClass.CHAR_value: 228cdf0e10cSrcweir case TypeClass.STRING_value: 229cdf0e10cSrcweir case TypeClass.TYPE_value: 230cdf0e10cSrcweir return v1.equals(v2); 231cdf0e10cSrcweir case TypeClass.SEQUENCE_value: 232cdf0e10cSrcweir int n = Array.getLength(v1); 233cdf0e10cSrcweir if (n != Array.getLength(v2)) { 234cdf0e10cSrcweir return false; 235cdf0e10cSrcweir } 236cdf0e10cSrcweir for (int i = 0; i < n; ++i) { 237cdf0e10cSrcweir // Recursively using areSame on Java values that are (boxed) 238cdf0e10cSrcweir // elements of Java arrays representing UNO sequence values, 239cdf0e10cSrcweir // instead of on Java values that are representations of UNO ANY 240cdf0e10cSrcweir // values, works by chance: 241cdf0e10cSrcweir if (!areSame(Array.get(v1, i), Array.get(v2, i))) { 242cdf0e10cSrcweir return false; 243cdf0e10cSrcweir } 244cdf0e10cSrcweir } 245cdf0e10cSrcweir return true; 246cdf0e10cSrcweir case TypeClass.ENUM_value: 247cdf0e10cSrcweir return v1 == v2; 248cdf0e10cSrcweir case TypeClass.STRUCT_value: 249cdf0e10cSrcweir case TypeClass.EXCEPTION_value: 250cdf0e10cSrcweir IFieldDescription[] fs; 251cdf0e10cSrcweir try { 252cdf0e10cSrcweir fs = TypeDescription.getTypeDescription(t). 253cdf0e10cSrcweir getFieldDescriptions(); 254cdf0e10cSrcweir } catch (ClassNotFoundException e) { 255cdf0e10cSrcweir throw new java.lang.RuntimeException(e.toString()); 256cdf0e10cSrcweir } 257cdf0e10cSrcweir for (int i = 0; i< fs.length; ++i) { 258cdf0e10cSrcweir Type ft = new Type(fs[i].getTypeDescription()); 259cdf0e10cSrcweir try { 260cdf0e10cSrcweir // Recursively using areSame on Java values that are (boxed) 261cdf0e10cSrcweir // fields of Java classes representing UNO struct or 262cdf0e10cSrcweir // exception values, instead of on Java values that are 263cdf0e10cSrcweir // representations of UNO ANY values, works by chance: 264cdf0e10cSrcweir if (!areSame( 265cdf0e10cSrcweir completeValue(ft, fs[i].getField().get(v1)), 266cdf0e10cSrcweir completeValue(ft, fs[i].getField().get(v2)))) 267cdf0e10cSrcweir { 268cdf0e10cSrcweir return false; 269cdf0e10cSrcweir } 270cdf0e10cSrcweir } catch (IllegalAccessException e) { 271cdf0e10cSrcweir throw new java.lang.RuntimeException(e.toString()); 272cdf0e10cSrcweir } 273cdf0e10cSrcweir } 274cdf0e10cSrcweir return true; 275cdf0e10cSrcweir case TypeClass.INTERFACE_value: 276cdf0e10cSrcweir return v1 == v2 277cdf0e10cSrcweir || (v1 instanceof IQueryInterface 278cdf0e10cSrcweir && ((IQueryInterface) v1).isSame(v2)) 279cdf0e10cSrcweir || (v2 instanceof IQueryInterface 280cdf0e10cSrcweir && ((IQueryInterface) v2).isSame(v1)); 281cdf0e10cSrcweir default: 282cdf0e10cSrcweir throw new java.lang.RuntimeException( 283cdf0e10cSrcweir "com.sun.star.uno.Any has bad com.sun.star.uno.TypeClass"); 284cdf0e10cSrcweir } 285cdf0e10cSrcweir } 286cdf0e10cSrcweir 287cdf0e10cSrcweir /** 288cdf0e10cSrcweir Complete a UNO value (make sure it is no invalid <code>null</code> 289cdf0e10cSrcweir value). 290cdf0e10cSrcweir 291cdf0e10cSrcweir <p>This is useful for members of parameterized type of instantiated 292cdf0e10cSrcweir polymorphic struct types, as <code>null</code> is a valid value there 293cdf0e10cSrcweir (and only there, for all types except <code>ANY</code> and interface 294cdf0e10cSrcweir types).</p> 295cdf0e10cSrcweir 296cdf0e10cSrcweir @param type a non-void, non-exception UNO type. 297cdf0e10cSrcweir 298cdf0e10cSrcweir @param value a Java value representing a UNO value of the given UNO type, 299cdf0e10cSrcweir or <code>null</code>. 300cdf0e10cSrcweir 301cdf0e10cSrcweir @return the given value, or the neutral value of the given type, if the 302cdf0e10cSrcweir given value was an invalid <code>null</code> value. 303cdf0e10cSrcweir 304cdf0e10cSrcweir @since UDK 3.2.3 305cdf0e10cSrcweir */ 306cdf0e10cSrcweir public static final Object completeValue(Type type, Object value) { 307cdf0e10cSrcweir if (value != null) { 308cdf0e10cSrcweir return value; 309cdf0e10cSrcweir } 310cdf0e10cSrcweir switch (type.getTypeClass().getValue()) { 311cdf0e10cSrcweir case TypeClass.BOOLEAN_value: 312cdf0e10cSrcweir return Boolean.FALSE; 313cdf0e10cSrcweir case TypeClass.BYTE_value: 314cdf0e10cSrcweir return new Byte((byte) 0); 315cdf0e10cSrcweir case TypeClass.SHORT_value: 316cdf0e10cSrcweir case TypeClass.UNSIGNED_SHORT_value: 317cdf0e10cSrcweir return new Short((short) 0); 318cdf0e10cSrcweir case TypeClass.LONG_value: 319cdf0e10cSrcweir case TypeClass.UNSIGNED_LONG_value: 320cdf0e10cSrcweir return new Integer(0); 321cdf0e10cSrcweir case TypeClass.HYPER_value: 322cdf0e10cSrcweir case TypeClass.UNSIGNED_HYPER_value: 323cdf0e10cSrcweir return new Long(0L); 324cdf0e10cSrcweir case TypeClass.FLOAT_value: 325cdf0e10cSrcweir return new Float(0.0f); 326cdf0e10cSrcweir case TypeClass.DOUBLE_value: 327cdf0e10cSrcweir return new Double(0.0); 328cdf0e10cSrcweir case TypeClass.CHAR_value: 329cdf0e10cSrcweir return new Character('\u0000'); 330cdf0e10cSrcweir case TypeClass.STRING_value: 331cdf0e10cSrcweir return ""; 332cdf0e10cSrcweir case TypeClass.TYPE_value: 333cdf0e10cSrcweir return Type.VOID; 334cdf0e10cSrcweir case TypeClass.ANY_value: 335cdf0e10cSrcweir case TypeClass.INTERFACE_value: 336cdf0e10cSrcweir return null; 337cdf0e10cSrcweir case TypeClass.SEQUENCE_value: 338cdf0e10cSrcweir return Array.newInstance(type.getZClass().getComponentType(), 0); 339cdf0e10cSrcweir case TypeClass.STRUCT_value: 340cdf0e10cSrcweir try { 341cdf0e10cSrcweir return type.getZClass().getConstructor(null).newInstance(null); 342cdf0e10cSrcweir } catch (java.lang.RuntimeException e) { 343cdf0e10cSrcweir throw e; 344cdf0e10cSrcweir } catch (java.lang.Exception e) { 345cdf0e10cSrcweir throw new java.lang.RuntimeException(e.toString()); 346cdf0e10cSrcweir } 347cdf0e10cSrcweir case TypeClass.ENUM_value: 348cdf0e10cSrcweir try { 349cdf0e10cSrcweir return type.getZClass().getMethod("getDefault", null).invoke( 350cdf0e10cSrcweir null, null); 351cdf0e10cSrcweir } catch (java.lang.RuntimeException e) { 352cdf0e10cSrcweir throw e; 353cdf0e10cSrcweir } catch (java.lang.Exception e) { 354cdf0e10cSrcweir throw new java.lang.RuntimeException(e.toString()); 355cdf0e10cSrcweir } 356cdf0e10cSrcweir default: 357cdf0e10cSrcweir throw new IllegalArgumentException( 358cdf0e10cSrcweir "com.sun.star.uno.UnoRuntime.completeValue called with bad" 359cdf0e10cSrcweir + " com.sun.star.uno.Type"); 360cdf0e10cSrcweir } 361cdf0e10cSrcweir } 362cdf0e10cSrcweir 363cdf0e10cSrcweir /** 364cdf0e10cSrcweir * Gets the current context of the current thread, or <code>null</code> if 365cdf0e10cSrcweir * no context has been set for the current thread. 366cdf0e10cSrcweir * 367cdf0e10cSrcweir * <p>The current context is thread local, which means that this method 368cdf0e10cSrcweir * returns the context that was last set for this thread.</p> 369cdf0e10cSrcweir * 370cdf0e10cSrcweir * @return the current context of the current thread, or <code>null</code> 371cdf0e10cSrcweir * if no context has been set for the current thread 372cdf0e10cSrcweir */ 373cdf0e10cSrcweir public static XCurrentContext getCurrentContext() { 374cdf0e10cSrcweir return (XCurrentContext) currentContext.get(); 375cdf0e10cSrcweir } 376cdf0e10cSrcweir 377cdf0e10cSrcweir /** 378cdf0e10cSrcweir * Sets the current context for the current thread. 379cdf0e10cSrcweir * 380cdf0e10cSrcweir * <p>The current context is thread local. To support a stacking behaviour, 381cdf0e10cSrcweir * every function that sets the current context should reset it to the 382cdf0e10cSrcweir * original value when exiting (for example, within a <code>finally</code> 383cdf0e10cSrcweir * block).</p> 384cdf0e10cSrcweir * 385cdf0e10cSrcweir * @param context the context to be set; if <code>null</code>, any 386cdf0e10cSrcweir * previously set context will be removed 387cdf0e10cSrcweir */ 388cdf0e10cSrcweir public static void setCurrentContext(XCurrentContext context) { 389cdf0e10cSrcweir // optimize this by using Java 1.5 ThreadLocal.remove if context == null 390cdf0e10cSrcweir currentContext.set(context); 391cdf0e10cSrcweir } 392cdf0e10cSrcweir 393cdf0e10cSrcweir /** 394cdf0e10cSrcweir * Retrieves an environment of type <code>name</code> with context 395cdf0e10cSrcweir * <code>context</code>. 396cdf0e10cSrcweir * 397cdf0e10cSrcweir * <p>Environments are held weakly by this class. If the requested 398cdf0e10cSrcweir * environment already exists, this methods simply returns it. Otherwise, 399cdf0e10cSrcweir * this method looks for it under 400cdf0e10cSrcweir * <code>com.sun.star.lib.uno.environments.<var>name</var>.<!-- 401cdf0e10cSrcweir * --><var>name</var>_environment</code>.</p> 402cdf0e10cSrcweir * 403cdf0e10cSrcweir * @param name the name of the environment 404cdf0e10cSrcweir * @param context the context of the environment 405cdf0e10cSrcweir * @see com.sun.star.uno.IEnvironment 406cdf0e10cSrcweir * 407cdf0e10cSrcweir * @deprecated As of UDK 3.2.0, this method is deprecated, without 408cdf0e10cSrcweir * offering a replacement. 409cdf0e10cSrcweir */ 410cdf0e10cSrcweir public static IEnvironment getEnvironment(String name, Object context) 411cdf0e10cSrcweir throws java.lang.Exception 412cdf0e10cSrcweir { 413cdf0e10cSrcweir synchronized (environments) { 414cdf0e10cSrcweir IEnvironment env = (IEnvironment) WeakMap.getValue( 415cdf0e10cSrcweir environments.get(name + context)); 416cdf0e10cSrcweir if (env == null) { 417cdf0e10cSrcweir Class c = Class.forName( 418cdf0e10cSrcweir "com.sun.star.lib.uno.environments." + name + "." + name 419cdf0e10cSrcweir + "_environment"); 420cdf0e10cSrcweir Constructor ctor = c.getConstructor( 421cdf0e10cSrcweir new Class[] { Object.class }); 422cdf0e10cSrcweir env = (IEnvironment) ctor.newInstance(new Object[] { context }); 423cdf0e10cSrcweir environments.put(name + context, env); 424cdf0e10cSrcweir } 425cdf0e10cSrcweir return env; 426cdf0e10cSrcweir } 427cdf0e10cSrcweir } 428cdf0e10cSrcweir 429cdf0e10cSrcweir /** 430cdf0e10cSrcweir * Gets a bridge from environment <code>from</code> to environment 431cdf0e10cSrcweir * <code>to</code>. 432cdf0e10cSrcweir * 433cdf0e10cSrcweir * <p>Creates a new bridge, if the requested bridge does not yet exist, and 434cdf0e10cSrcweir * hands the arguments to the bridge.</p> 435cdf0e10cSrcweir * 436cdf0e10cSrcweir * <p>If the requested bridge does not exist, it is searched for in package 437cdf0e10cSrcweir * <code>com.sun.star.lib.uno.bridges.<var>from</var>_<var>to</var>;</code> 438cdf0e10cSrcweir * and the root classpath as 439cdf0e10cSrcweir * <code><var>from</var>_<var>to</var>_bridge</code>.</p> 440cdf0e10cSrcweir * 441cdf0e10cSrcweir * @param from the source environment 442cdf0e10cSrcweir * @param to the target environment 443cdf0e10cSrcweir * @param args the initial arguments for the bridge 444cdf0e10cSrcweir * @return the requested bridge 445cdf0e10cSrcweir * @see #getBridgeByName 446cdf0e10cSrcweir * @see com.sun.star.uno.IBridge 447cdf0e10cSrcweir * @see com.sun.star.uno.IEnvironment 448cdf0e10cSrcweir * 449cdf0e10cSrcweir * @deprecated As of UDK 3.2.0, this method is deprecated, without 450cdf0e10cSrcweir * offering a replacement. 451cdf0e10cSrcweir */ 452cdf0e10cSrcweir public static IBridge getBridge( 453cdf0e10cSrcweir IEnvironment from, IEnvironment to, Object[] args) 454cdf0e10cSrcweir throws java.lang.Exception 455cdf0e10cSrcweir { 456cdf0e10cSrcweir synchronized (bridges) { 457cdf0e10cSrcweir String name = from.getName() + "_" + to.getName(); 458cdf0e10cSrcweir String hashName = from.getName() + from.getContext() + "_" 459cdf0e10cSrcweir + to.getName() + to.getContext(); 460cdf0e10cSrcweir IBridge bridge = (IBridge) WeakMap.getValue(bridges.get(hashName)); 461cdf0e10cSrcweir if(bridge == null) { 462cdf0e10cSrcweir Class zClass = null; 463cdf0e10cSrcweir String className = name + "_bridge"; 464cdf0e10cSrcweir try { 465cdf0e10cSrcweir zClass = Class.forName(className); 466cdf0e10cSrcweir } catch (ClassNotFoundException e) { 467cdf0e10cSrcweir className = "com.sun.star.lib.uno.bridges." + name + "." 468cdf0e10cSrcweir + className; 469cdf0e10cSrcweir zClass = Class.forName(className); 470cdf0e10cSrcweir } 471cdf0e10cSrcweir Class[] signature = { 472cdf0e10cSrcweir IEnvironment.class, IEnvironment.class, args.getClass() }; 473cdf0e10cSrcweir Constructor constructor = zClass.getConstructor(signature); 474cdf0e10cSrcweir Object[] iargs = { from, to, args }; 475cdf0e10cSrcweir bridge = (IBridge) constructor.newInstance(iargs); 476cdf0e10cSrcweir bridges.put(hashName, bridge); 477cdf0e10cSrcweir } 478cdf0e10cSrcweir return bridge; 479cdf0e10cSrcweir } 480cdf0e10cSrcweir } 481cdf0e10cSrcweir 482cdf0e10cSrcweir /** 483cdf0e10cSrcweir * Gets a bridge from environment <code>from</code> to environment 484cdf0e10cSrcweir * <code>to</code>. 485cdf0e10cSrcweir * 486cdf0e10cSrcweir * <p>Creates a new bridge, if the requested bridge does not yet exist, and 487cdf0e10cSrcweir * hands the arguments to the bridge.</p> 488cdf0e10cSrcweir * 489cdf0e10cSrcweir * <p>If the requested bridge does not exist, it is searched for in package 490cdf0e10cSrcweir * <code>com.sun.star.lib.uno.bridges.<var>from</var>_<var>to</var>;</code> 491cdf0e10cSrcweir * and the root classpath as 492cdf0e10cSrcweir * <code><var>from</var>_<var>to</var>_bridge</code>. The used environments 493cdf0e10cSrcweir * are retrieved through <code>getEnvironment</code>.</p> 494cdf0e10cSrcweir * 495cdf0e10cSrcweir * @param from the name of the source environment 496cdf0e10cSrcweir * @param fromContext the context for the source environment 497cdf0e10cSrcweir * @param to the name of the target environment 498cdf0e10cSrcweir * @param toContext the context for the target environment 499cdf0e10cSrcweir * @param args the initial arguments for the bridge 500cdf0e10cSrcweir * @return the requested bridge 501cdf0e10cSrcweir * @see #getBridge 502cdf0e10cSrcweir * @see #getEnvironment 503cdf0e10cSrcweir * @see com.sun.star.uno.IBridge 504cdf0e10cSrcweir * @see com.sun.star.uno.IEnvironment 505cdf0e10cSrcweir * 506cdf0e10cSrcweir * @deprecated As of UDK 3.2.0, this method is deprecated, without 507cdf0e10cSrcweir * offering a replacement. 508cdf0e10cSrcweir */ 509cdf0e10cSrcweir public static IBridge getBridgeByName( 510cdf0e10cSrcweir String from, Object fromContext, String to, Object toContext, 511cdf0e10cSrcweir Object[] args) throws java.lang.Exception 512cdf0e10cSrcweir { 513cdf0e10cSrcweir return getBridge( 514cdf0e10cSrcweir getEnvironment(from, fromContext), getEnvironment(to, toContext), 515cdf0e10cSrcweir args); 516cdf0e10cSrcweir } 517cdf0e10cSrcweir 518cdf0e10cSrcweir /** 519cdf0e10cSrcweir * Returns an array of all active bridges. 520cdf0e10cSrcweir * 521cdf0e10cSrcweir * @return an array of <code>IBridge</code> objects 522cdf0e10cSrcweir * @see com.sun.star.uno.IBridge 523cdf0e10cSrcweir * 524cdf0e10cSrcweir * @deprecated As of UDK 3.2.0, this method is deprecated, without 525cdf0e10cSrcweir * offering a replacement. 526cdf0e10cSrcweir */ 527cdf0e10cSrcweir public static IBridge[] getBridges() { 528cdf0e10cSrcweir ArrayList l = new ArrayList(); 529cdf0e10cSrcweir synchronized (bridges) { 530cdf0e10cSrcweir for (Iterator i = bridges.values().iterator(); i.hasNext();) { 531cdf0e10cSrcweir Object o = WeakMap.getValue(i.next()); 532cdf0e10cSrcweir if (o != null) { 533cdf0e10cSrcweir l.add(o); 534cdf0e10cSrcweir } 535cdf0e10cSrcweir } 536cdf0e10cSrcweir } 537cdf0e10cSrcweir return (IBridge[]) l.toArray(new IBridge[l.size()]); 538cdf0e10cSrcweir } 539cdf0e10cSrcweir 540cdf0e10cSrcweir /** 541cdf0e10cSrcweir * Gets a mapping from environment <code>from</code> to environment 542cdf0e10cSrcweir * <code>to</code>. 543cdf0e10cSrcweir * 544cdf0e10cSrcweir * <p>Mappings are like bridges, except that with mappings one can only map 545cdf0e10cSrcweir * in one direction. Mappings are here for compatibility with the binary 546cdf0e10cSrcweir * UNO API. Mappings are implemented as wrappers around bridges.</p> 547cdf0e10cSrcweir * 548cdf0e10cSrcweir * @param from the source environment 549cdf0e10cSrcweir * @param to the target environment 550cdf0e10cSrcweir * @return the requested mapping 551cdf0e10cSrcweir * @see com.sun.star.uno.IEnvironment 552cdf0e10cSrcweir * @see com.sun.star.uno.IMapping 553cdf0e10cSrcweir * 554cdf0e10cSrcweir * @deprecated As of UDK 3.2.0, this method is deprecated, without 555cdf0e10cSrcweir * offering a replacement. 556cdf0e10cSrcweir */ 557cdf0e10cSrcweir public static IMapping getMapping(IEnvironment from, IEnvironment to) 558cdf0e10cSrcweir throws java.lang.Exception 559cdf0e10cSrcweir { 560cdf0e10cSrcweir IBridge bridge; 561cdf0e10cSrcweir try { 562cdf0e10cSrcweir bridge = getBridge(from, to, null); 563cdf0e10cSrcweir } 564cdf0e10cSrcweir catch (ClassNotFoundException e) { 565cdf0e10cSrcweir bridge = new BridgeTurner(getBridge(to, from, null)); 566cdf0e10cSrcweir } 567cdf0e10cSrcweir return new MappingWrapper(bridge); 568cdf0e10cSrcweir } 569cdf0e10cSrcweir 570cdf0e10cSrcweir /** 571cdf0e10cSrcweir * Gets a mapping from environment <code>from</code> to environment 572cdf0e10cSrcweir * <code>to</code>. 573cdf0e10cSrcweir * 574cdf0e10cSrcweir * <p>The used environments are retrieved through 575cdf0e10cSrcweir * <code>getEnvironment</code>.</p> 576cdf0e10cSrcweir * 577cdf0e10cSrcweir * @param from the name of the source environment 578cdf0e10cSrcweir * @param to the name of the target environment 579cdf0e10cSrcweir * @return the requested mapping 580cdf0e10cSrcweir * @see #getEnvironment 581cdf0e10cSrcweir * @see #getMapping 582cdf0e10cSrcweir * @see com.sun.star.uno.IMapping 583cdf0e10cSrcweir * 584cdf0e10cSrcweir * @deprecated As of UDK 3.2.0, this method is deprecated, without 585cdf0e10cSrcweir * offering a replacement. 586cdf0e10cSrcweir */ 587cdf0e10cSrcweir public static IMapping getMappingByName(String from, String to) 588cdf0e10cSrcweir throws java.lang.Exception 589cdf0e10cSrcweir { 590cdf0e10cSrcweir return getMapping(getEnvironment(from, null), getEnvironment(to, null)); 591cdf0e10cSrcweir } 592cdf0e10cSrcweir 593cdf0e10cSrcweir /** 594cdf0e10cSrcweir * Resets this <code>UnoRuntime</code> to its initial state. 595cdf0e10cSrcweir * 596cdf0e10cSrcweir * <p>Releases all references to bridges and environments.</p> 597cdf0e10cSrcweir * 598cdf0e10cSrcweir * @deprecated As of UDK 3.2.0, this method is deprecated, without 599cdf0e10cSrcweir * offering a replacement. 600cdf0e10cSrcweir */ 601cdf0e10cSrcweir static public boolean reset() { 602cdf0e10cSrcweir synchronized (bridges) { 603cdf0e10cSrcweir for (Iterator i = bridges.values().iterator(); i.hasNext();) { 604cdf0e10cSrcweir IBridge b = (IBridge) WeakMap.getValue(i.next()); 605cdf0e10cSrcweir if (b != null) { 606cdf0e10cSrcweir // The following call to dispose was originally made to 607cdf0e10cSrcweir // com.sun.star.lib.sandbox.Disposable.dispose, which cannot 608cdf0e10cSrcweir // throw an InterruptedException or IOException: 609cdf0e10cSrcweir try { 610cdf0e10cSrcweir b.dispose(); 611cdf0e10cSrcweir } catch (InterruptedException e) { 612cdf0e10cSrcweir Thread.currentThread().interrupted(); 613cdf0e10cSrcweir throw new RuntimeException( 614cdf0e10cSrcweir "Unexpected exception in UnoRuntime.reset: " + e); 615cdf0e10cSrcweir } catch (IOException e) { 616cdf0e10cSrcweir throw new RuntimeException( 617cdf0e10cSrcweir "Unexpected exception in UnoRuntime.reset: " + e); 618cdf0e10cSrcweir } 619cdf0e10cSrcweir } 620cdf0e10cSrcweir } 621cdf0e10cSrcweir bridges.clear(); 622cdf0e10cSrcweir } 623cdf0e10cSrcweir environments.clear(); 624cdf0e10cSrcweir return bridges.isEmpty() && environments.isEmpty(); 625cdf0e10cSrcweir } 626cdf0e10cSrcweir 627cdf0e10cSrcweir /** 628cdf0e10cSrcweir * @deprecated As of UDK 3.2.0, do not use this internal field. 629cdf0e10cSrcweir */ 630cdf0e10cSrcweir static public final boolean DEBUG = false; 631cdf0e10cSrcweir 632cdf0e10cSrcweir private static final class BridgeTurner implements IBridge { 633cdf0e10cSrcweir public BridgeTurner(IBridge bridge) { 634cdf0e10cSrcweir this.bridge = bridge; 635cdf0e10cSrcweir } 636cdf0e10cSrcweir 637cdf0e10cSrcweir public Object mapInterfaceTo(Object object, Type type) { 638cdf0e10cSrcweir return bridge.mapInterfaceFrom(object, type); 639cdf0e10cSrcweir } 640cdf0e10cSrcweir 641cdf0e10cSrcweir public Object mapInterfaceFrom(Object object, Type type) { 642cdf0e10cSrcweir return bridge.mapInterfaceTo(object, type); 643cdf0e10cSrcweir } 644cdf0e10cSrcweir 645cdf0e10cSrcweir public IEnvironment getSourceEnvironment() { 646cdf0e10cSrcweir return bridge.getTargetEnvironment(); 647cdf0e10cSrcweir } 648cdf0e10cSrcweir 649cdf0e10cSrcweir public IEnvironment getTargetEnvironment() { 650cdf0e10cSrcweir return bridge.getSourceEnvironment(); 651cdf0e10cSrcweir } 652cdf0e10cSrcweir 653cdf0e10cSrcweir public void acquire() { 654cdf0e10cSrcweir bridge.acquire(); 655cdf0e10cSrcweir } 656cdf0e10cSrcweir 657cdf0e10cSrcweir public void release() { 658cdf0e10cSrcweir bridge.release(); 659cdf0e10cSrcweir } 660cdf0e10cSrcweir 661cdf0e10cSrcweir public void dispose() throws InterruptedException, IOException { 662cdf0e10cSrcweir bridge.dispose(); 663cdf0e10cSrcweir } 664cdf0e10cSrcweir 665cdf0e10cSrcweir private final IBridge bridge; 666cdf0e10cSrcweir } 667cdf0e10cSrcweir 668cdf0e10cSrcweir private static final class MappingWrapper implements IMapping { 669cdf0e10cSrcweir public MappingWrapper(IBridge bridge) { 670cdf0e10cSrcweir this.bridge = bridge; 671cdf0e10cSrcweir } 672cdf0e10cSrcweir 673cdf0e10cSrcweir public Object mapInterface(Object object, Type type) { 674cdf0e10cSrcweir return bridge.mapInterfaceTo(object, type); 675cdf0e10cSrcweir } 676cdf0e10cSrcweir 677cdf0e10cSrcweir private final IBridge bridge; 678cdf0e10cSrcweir } 679cdf0e10cSrcweir 680cdf0e10cSrcweir private static final String uniqueKeyHostPrefix 681cdf0e10cSrcweir = Integer.toString(new Object().hashCode(), 16) + ":"; 682cdf0e10cSrcweir private static final Object uniqueKeyLock = new Object(); 683cdf0e10cSrcweir private static long uniqueKeyTime = System.currentTimeMillis(); 684cdf0e10cSrcweir private static long uniqueKeyCount = Long.MIN_VALUE; 685cdf0e10cSrcweir 686cdf0e10cSrcweir private static final String oidSuffix = ";java[];" + getUniqueKey(); 687cdf0e10cSrcweir 688cdf0e10cSrcweir private static final ThreadLocal currentContext = new ThreadLocal(); 689cdf0e10cSrcweir 690cdf0e10cSrcweir private static final WeakMap environments = new WeakMap(); 691cdf0e10cSrcweir private static final WeakMap bridges = new WeakMap(); 692cdf0e10cSrcweir } 693