xref: /AOO41X/main/cli_ure/source/ure/uno/util/WeakBase.cs (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir using System;
29*cdf0e10cSrcweir using System.Collections;
30*cdf0e10cSrcweir using unoidl.com.sun.star.uno;
31*cdf0e10cSrcweir using unoidl.com.sun.star.lang;
32*cdf0e10cSrcweir 
33*cdf0e10cSrcweir namespace uno.util
34*cdf0e10cSrcweir {
35*cdf0e10cSrcweir 
36*cdf0e10cSrcweir /** This class can be used as a base class for UNO objects.
37*cdf0e10cSrcweir     It implements the capability to be kept weakly
38*cdf0e10cSrcweir     (unoidl.com.sun.star.uno.XWeak) and it implements
39*cdf0e10cSrcweir     unoidl.com.sun.star.lang.XTypeProvider which is necessary for
40*cdf0e10cSrcweir     using the object from StarBasic.
41*cdf0e10cSrcweir */
42*cdf0e10cSrcweir public class WeakBase : XWeak, XTypeProvider
43*cdf0e10cSrcweir {
44*cdf0e10cSrcweir     // Contains all WeakAdapter which have been created in this class
45*cdf0e10cSrcweir     // They have to be notified when this object dies
46*cdf0e10cSrcweir     private WeakAdapter m_adapter = null;
47*cdf0e10cSrcweir 
48*cdf0e10cSrcweir     protected static Hashtable s_types = new Hashtable();
49*cdf0e10cSrcweir     protected static Hashtable s_impl_ids = new Hashtable();
50*cdf0e10cSrcweir 
51*cdf0e10cSrcweir     // XWeak impl
52*cdf0e10cSrcweir     /** The returned XAdapter implementation can be used to keap a
53*cdf0e10cSrcweir         weak reference to this object.
54*cdf0e10cSrcweir 
55*cdf0e10cSrcweir         @return a weak adapter
56*cdf0e10cSrcweir     */
57*cdf0e10cSrcweir     public XAdapter queryAdapter()
58*cdf0e10cSrcweir     {
59*cdf0e10cSrcweir         if (null == m_adapter)
60*cdf0e10cSrcweir         {
61*cdf0e10cSrcweir             lock (this)
62*cdf0e10cSrcweir             {
63*cdf0e10cSrcweir                 if (null == m_adapter)
64*cdf0e10cSrcweir                     m_adapter = new WeakAdapter( this );
65*cdf0e10cSrcweir             }
66*cdf0e10cSrcweir         }
67*cdf0e10cSrcweir         return m_adapter;
68*cdf0e10cSrcweir     }
69*cdf0e10cSrcweir 
70*cdf0e10cSrcweir     /** Overrides of Object.Finalize method.
71*cdf0e10cSrcweir         When there are no references to this object anymore, then the
72*cdf0e10cSrcweir         garbage collector calls this method, thereby causing the adapter
73*cdf0e10cSrcweir         object to be notified.  The adapter, in turn, notifies all
74*cdf0e10cSrcweir         listeners (unoidl.com.sun.star.uno.XReference).
75*cdf0e10cSrcweir     */
76*cdf0e10cSrcweir     ~WeakBase()
77*cdf0e10cSrcweir     {
78*cdf0e10cSrcweir         if (null != m_adapter)
79*cdf0e10cSrcweir             m_adapter.referentDying();
80*cdf0e10cSrcweir     }
81*cdf0e10cSrcweir 
82*cdf0e10cSrcweir     // XTypeProvider impl
83*cdf0e10cSrcweir 
84*cdf0e10cSrcweir     /** Returns an array of Type objects which represent all implemented
85*cdf0e10cSrcweir         UNO interfaces of this object.
86*cdf0e10cSrcweir 
87*cdf0e10cSrcweir        @return Type objects of all implemented interfaces.
88*cdf0e10cSrcweir     */
89*cdf0e10cSrcweir     public Type [] getTypes()
90*cdf0e10cSrcweir     {
91*cdf0e10cSrcweir         Type [] types;
92*cdf0e10cSrcweir         Type type = GetType();
93*cdf0e10cSrcweir         lock (s_types)
94*cdf0e10cSrcweir         {
95*cdf0e10cSrcweir             types = (Type []) s_types[ type ];
96*cdf0e10cSrcweir             if (null == types)
97*cdf0e10cSrcweir             {
98*cdf0e10cSrcweir                 Type [] interfaces = type.GetInterfaces();
99*cdf0e10cSrcweir                 ArrayList list = new ArrayList( interfaces.Length );
100*cdf0e10cSrcweir                 for ( Int32 pos = 0; pos < interfaces.Length; ++pos )
101*cdf0e10cSrcweir                 {
102*cdf0e10cSrcweir                     Type iface = interfaces[ pos ];
103*cdf0e10cSrcweir                     // xxx todo: as long as the bridge cannot introduce
104*cdf0e10cSrcweir                     // native CTS types into UNO on the fly
105*cdf0e10cSrcweir                     if (iface.FullName.StartsWith( "unoidl." ))
106*cdf0e10cSrcweir                     {
107*cdf0e10cSrcweir                         list.Add( iface );
108*cdf0e10cSrcweir                     }
109*cdf0e10cSrcweir                 }
110*cdf0e10cSrcweir                 Int32 len = list.Count;
111*cdf0e10cSrcweir                 Type [] ar = new Type [ len ];
112*cdf0e10cSrcweir                 for ( Int32 pos = 0; pos < len; ++pos )
113*cdf0e10cSrcweir                     ar[ pos ] = (Type) list[ pos ];
114*cdf0e10cSrcweir                 s_types[ type ] = ar;
115*cdf0e10cSrcweir                 types = ar;
116*cdf0e10cSrcweir             }
117*cdf0e10cSrcweir         }
118*cdf0e10cSrcweir         return types;
119*cdf0e10cSrcweir     }
120*cdf0e10cSrcweir 
121*cdf0e10cSrcweir     /** Provides an identifier that represents the set of UNO interfaces
122*cdf0e10cSrcweir         implemented by this class.  All instances of this class which run
123*cdf0e10cSrcweir         in the same CLR return the same array.
124*cdf0e10cSrcweir 
125*cdf0e10cSrcweir         @return identifier as array of bytes
126*cdf0e10cSrcweir     */
127*cdf0e10cSrcweir     public byte [] getImplementationId()
128*cdf0e10cSrcweir     {
129*cdf0e10cSrcweir         byte [] id;
130*cdf0e10cSrcweir         Type type = GetType();
131*cdf0e10cSrcweir         lock (s_impl_ids)
132*cdf0e10cSrcweir         {
133*cdf0e10cSrcweir             id = (byte []) s_impl_ids[ type ];
134*cdf0e10cSrcweir             if (null == id)
135*cdf0e10cSrcweir             {
136*cdf0e10cSrcweir                 Int32 hash = GetHashCode();
137*cdf0e10cSrcweir                 String name = type.FullName;
138*cdf0e10cSrcweir                 Int32 len= name.Length;
139*cdf0e10cSrcweir 
140*cdf0e10cSrcweir                 id = new byte[ 4 + (2 * len) ];
141*cdf0e10cSrcweir                 id[ 0 ]= (byte) (hash & 0xff);
142*cdf0e10cSrcweir                 id[ 1 ]= (byte) ((hash >> 8) & 0xff);
143*cdf0e10cSrcweir                 id[ 2 ]= (byte) ((hash >> 16) & 0xff);
144*cdf0e10cSrcweir                 id[ 3 ]= (byte) ((hash >> 24) & 0xff);
145*cdf0e10cSrcweir 
146*cdf0e10cSrcweir                 for ( Int32 pos = 0; pos < len; ++pos )
147*cdf0e10cSrcweir                 {
148*cdf0e10cSrcweir                     UInt16 c = Convert.ToUInt16( name[ pos ] );
149*cdf0e10cSrcweir                     id[ 4 + (2 * pos) ] = (byte) (c & 0xff);
150*cdf0e10cSrcweir                     id[ 4 + (2 * pos) +1 ] = (byte) ((c >> 8) & 0xff);
151*cdf0e10cSrcweir                 }
152*cdf0e10cSrcweir                 s_impl_ids[ type ] = id;
153*cdf0e10cSrcweir             }
154*cdf0e10cSrcweir         }
155*cdf0e10cSrcweir         return id;
156*cdf0e10cSrcweir     }
157*cdf0e10cSrcweir 
158*cdf0e10cSrcweir     // System.Object
159*cdf0e10cSrcweir     public override String ToString()
160*cdf0e10cSrcweir     {
161*cdf0e10cSrcweir         System.Text.StringBuilder buf =
162*cdf0e10cSrcweir             new System.Text.StringBuilder( base.ToString(), 256 );
163*cdf0e10cSrcweir         buf.Append( "\nUNO Object Implementation:\n\tImplementationId: " );
164*cdf0e10cSrcweir         buf.Append( getImplementationId() );
165*cdf0e10cSrcweir         buf.Append( "\n\tInterfaces: " );
166*cdf0e10cSrcweir         Type [] types = getTypes();
167*cdf0e10cSrcweir         for ( Int32 pos = 0; pos < types.Length; ++pos )
168*cdf0e10cSrcweir         {
169*cdf0e10cSrcweir             buf.Append( types[ pos ].FullName );
170*cdf0e10cSrcweir             if (pos < (types.Length -1))
171*cdf0e10cSrcweir                 buf.Append( ", " );
172*cdf0e10cSrcweir         }
173*cdf0e10cSrcweir         return buf.ToString();
174*cdf0e10cSrcweir     }
175*cdf0e10cSrcweir }
176*cdf0e10cSrcweir 
177*cdf0e10cSrcweir }
178*cdf0e10cSrcweir 
179