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 using System; 25 using System.Collections; 26 using unoidl.com.sun.star.uno; 27 using unoidl.com.sun.star.lang; 28 29 namespace uno.util 30 { 31 32 /** This class can be used as a base class for UNO objects. 33 It implements the capability to be kept weakly 34 (unoidl.com.sun.star.uno.XWeak) and it implements 35 unoidl.com.sun.star.lang.XTypeProvider which is necessary for 36 using the object from StarBasic. 37 */ 38 public class WeakBase : XWeak, XTypeProvider 39 { 40 // Contains all WeakAdapter which have been created in this class 41 // They have to be notified when this object dies 42 private WeakAdapter m_adapter = null; 43 44 protected static Hashtable s_types = new Hashtable(); 45 protected static Hashtable s_impl_ids = new Hashtable(); 46 47 // XWeak impl 48 /** The returned XAdapter implementation can be used to keap a 49 weak reference to this object. 50 51 @return a weak adapter 52 */ queryAdapter()53 public XAdapter queryAdapter() 54 { 55 if (null == m_adapter) 56 { 57 lock (this) 58 { 59 if (null == m_adapter) 60 m_adapter = new WeakAdapter( this ); 61 } 62 } 63 return m_adapter; 64 } 65 66 /** Overrides of Object.Finalize method. 67 When there are no references to this object anymore, then the 68 garbage collector calls this method, thereby causing the adapter 69 object to be notified. The adapter, in turn, notifies all 70 listeners (unoidl.com.sun.star.uno.XReference). 71 */ ~WeakBase()72 ~WeakBase() 73 { 74 if (null != m_adapter) 75 m_adapter.referentDying(); 76 } 77 78 // XTypeProvider impl 79 80 /** Returns an array of Type objects which represent all implemented 81 UNO interfaces of this object. 82 83 @return Type objects of all implemented interfaces. 84 */ getTypes()85 public Type [] getTypes() 86 { 87 Type [] types; 88 Type type = GetType(); 89 lock (s_types) 90 { 91 types = (Type []) s_types[ type ]; 92 if (null == types) 93 { 94 Type [] interfaces = type.GetInterfaces(); 95 ArrayList list = new ArrayList( interfaces.Length ); 96 for ( Int32 pos = 0; pos < interfaces.Length; ++pos ) 97 { 98 Type iface = interfaces[ pos ]; 99 // xxx todo: as long as the bridge cannot introduce 100 // native CTS types into UNO on the fly 101 if (iface.FullName.StartsWith( "unoidl." )) 102 { 103 list.Add( iface ); 104 } 105 } 106 Int32 len = list.Count; 107 Type [] ar = new Type [ len ]; 108 for ( Int32 pos = 0; pos < len; ++pos ) 109 ar[ pos ] = (Type) list[ pos ]; 110 s_types[ type ] = ar; 111 types = ar; 112 } 113 } 114 return types; 115 } 116 117 /** Provides an identifier that represents the set of UNO interfaces 118 implemented by this class. All instances of this class which run 119 in the same CLR return the same array. 120 121 @return identifier as array of bytes 122 */ getImplementationId()123 public byte [] getImplementationId() 124 { 125 byte [] id; 126 Type type = GetType(); 127 lock (s_impl_ids) 128 { 129 id = (byte []) s_impl_ids[ type ]; 130 if (null == id) 131 { 132 Int32 hash = GetHashCode(); 133 String name = type.FullName; 134 Int32 len= name.Length; 135 136 id = new byte[ 4 + (2 * len) ]; 137 id[ 0 ]= (byte) (hash & 0xff); 138 id[ 1 ]= (byte) ((hash >> 8) & 0xff); 139 id[ 2 ]= (byte) ((hash >> 16) & 0xff); 140 id[ 3 ]= (byte) ((hash >> 24) & 0xff); 141 142 for ( Int32 pos = 0; pos < len; ++pos ) 143 { 144 UInt16 c = Convert.ToUInt16( name[ pos ] ); 145 id[ 4 + (2 * pos) ] = (byte) (c & 0xff); 146 id[ 4 + (2 * pos) +1 ] = (byte) ((c >> 8) & 0xff); 147 } 148 s_impl_ids[ type ] = id; 149 } 150 } 151 return id; 152 } 153 154 // System.Object ToString()155 public override String ToString() 156 { 157 System.Text.StringBuilder buf = 158 new System.Text.StringBuilder( base.ToString(), 256 ); 159 buf.Append( "\nUNO Object Implementation:\n\tImplementationId: " ); 160 buf.Append( getImplementationId() ); 161 buf.Append( "\n\tInterfaces: " ); 162 Type [] types = getTypes(); 163 for ( Int32 pos = 0; pos < types.Length; ++pos ) 164 { 165 buf.Append( types[ pos ].FullName ); 166 if (pos < (types.Length -1)) 167 buf.Append( ", " ); 168 } 169 return buf.ToString(); 170 } 171 } 172 173 } 174 175