1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski  *
3*b1cdbd2cSJim Jagielski  * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski  * or more contributor license agreements.  See the NOTICE file
5*b1cdbd2cSJim Jagielski  * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski  * regarding copyright ownership.  The ASF licenses this file
7*b1cdbd2cSJim Jagielski  * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski  * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski  * with the License.  You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski  *
11*b1cdbd2cSJim Jagielski  *   http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski  *
13*b1cdbd2cSJim Jagielski  * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski  * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski  * KIND, either express or implied.  See the License for the
17*b1cdbd2cSJim Jagielski  * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski  * under the License.
19*b1cdbd2cSJim Jagielski  *
20*b1cdbd2cSJim Jagielski  *************************************************************/
21*b1cdbd2cSJim Jagielski 
22*b1cdbd2cSJim Jagielski 
23*b1cdbd2cSJim Jagielski 
24*b1cdbd2cSJim Jagielski using System;
25*b1cdbd2cSJim Jagielski using System.Collections;
26*b1cdbd2cSJim Jagielski using unoidl.com.sun.star.uno;
27*b1cdbd2cSJim Jagielski using unoidl.com.sun.star.lang;
28*b1cdbd2cSJim Jagielski 
29*b1cdbd2cSJim Jagielski namespace uno.util
30*b1cdbd2cSJim Jagielski {
31*b1cdbd2cSJim Jagielski 
32*b1cdbd2cSJim Jagielski /** This class can be used as a base class for UNO objects.
33*b1cdbd2cSJim Jagielski     It implements the capability to be kept weakly
34*b1cdbd2cSJim Jagielski     (unoidl.com.sun.star.uno.XWeak) and it implements
35*b1cdbd2cSJim Jagielski     unoidl.com.sun.star.lang.XTypeProvider which is necessary for
36*b1cdbd2cSJim Jagielski     using the object from StarBasic.
37*b1cdbd2cSJim Jagielski */
38*b1cdbd2cSJim Jagielski public class WeakBase : XWeak, XTypeProvider
39*b1cdbd2cSJim Jagielski {
40*b1cdbd2cSJim Jagielski     // Contains all WeakAdapter which have been created in this class
41*b1cdbd2cSJim Jagielski     // They have to be notified when this object dies
42*b1cdbd2cSJim Jagielski     private WeakAdapter m_adapter = null;
43*b1cdbd2cSJim Jagielski 
44*b1cdbd2cSJim Jagielski     protected static Hashtable s_types = new Hashtable();
45*b1cdbd2cSJim Jagielski     protected static Hashtable s_impl_ids = new Hashtable();
46*b1cdbd2cSJim Jagielski 
47*b1cdbd2cSJim Jagielski     // XWeak impl
48*b1cdbd2cSJim Jagielski     /** The returned XAdapter implementation can be used to keap a
49*b1cdbd2cSJim Jagielski         weak reference to this object.
50*b1cdbd2cSJim Jagielski 
51*b1cdbd2cSJim Jagielski         @return a weak adapter
52*b1cdbd2cSJim Jagielski     */
queryAdapter()53*b1cdbd2cSJim Jagielski     public XAdapter queryAdapter()
54*b1cdbd2cSJim Jagielski     {
55*b1cdbd2cSJim Jagielski         if (null == m_adapter)
56*b1cdbd2cSJim Jagielski         {
57*b1cdbd2cSJim Jagielski             lock (this)
58*b1cdbd2cSJim Jagielski             {
59*b1cdbd2cSJim Jagielski                 if (null == m_adapter)
60*b1cdbd2cSJim Jagielski                     m_adapter = new WeakAdapter( this );
61*b1cdbd2cSJim Jagielski             }
62*b1cdbd2cSJim Jagielski         }
63*b1cdbd2cSJim Jagielski         return m_adapter;
64*b1cdbd2cSJim Jagielski     }
65*b1cdbd2cSJim Jagielski 
66*b1cdbd2cSJim Jagielski     /** Overrides of Object.Finalize method.
67*b1cdbd2cSJim Jagielski         When there are no references to this object anymore, then the
68*b1cdbd2cSJim Jagielski         garbage collector calls this method, thereby causing the adapter
69*b1cdbd2cSJim Jagielski         object to be notified.  The adapter, in turn, notifies all
70*b1cdbd2cSJim Jagielski         listeners (unoidl.com.sun.star.uno.XReference).
71*b1cdbd2cSJim Jagielski     */
~WeakBase()72*b1cdbd2cSJim Jagielski     ~WeakBase()
73*b1cdbd2cSJim Jagielski     {
74*b1cdbd2cSJim Jagielski         if (null != m_adapter)
75*b1cdbd2cSJim Jagielski             m_adapter.referentDying();
76*b1cdbd2cSJim Jagielski     }
77*b1cdbd2cSJim Jagielski 
78*b1cdbd2cSJim Jagielski     // XTypeProvider impl
79*b1cdbd2cSJim Jagielski 
80*b1cdbd2cSJim Jagielski     /** Returns an array of Type objects which represent all implemented
81*b1cdbd2cSJim Jagielski         UNO interfaces of this object.
82*b1cdbd2cSJim Jagielski 
83*b1cdbd2cSJim Jagielski        @return Type objects of all implemented interfaces.
84*b1cdbd2cSJim Jagielski     */
getTypes()85*b1cdbd2cSJim Jagielski     public Type [] getTypes()
86*b1cdbd2cSJim Jagielski     {
87*b1cdbd2cSJim Jagielski         Type [] types;
88*b1cdbd2cSJim Jagielski         Type type = GetType();
89*b1cdbd2cSJim Jagielski         lock (s_types)
90*b1cdbd2cSJim Jagielski         {
91*b1cdbd2cSJim Jagielski             types = (Type []) s_types[ type ];
92*b1cdbd2cSJim Jagielski             if (null == types)
93*b1cdbd2cSJim Jagielski             {
94*b1cdbd2cSJim Jagielski                 Type [] interfaces = type.GetInterfaces();
95*b1cdbd2cSJim Jagielski                 ArrayList list = new ArrayList( interfaces.Length );
96*b1cdbd2cSJim Jagielski                 for ( Int32 pos = 0; pos < interfaces.Length; ++pos )
97*b1cdbd2cSJim Jagielski                 {
98*b1cdbd2cSJim Jagielski                     Type iface = interfaces[ pos ];
99*b1cdbd2cSJim Jagielski                     // xxx todo: as long as the bridge cannot introduce
100*b1cdbd2cSJim Jagielski                     // native CTS types into UNO on the fly
101*b1cdbd2cSJim Jagielski                     if (iface.FullName.StartsWith( "unoidl." ))
102*b1cdbd2cSJim Jagielski                     {
103*b1cdbd2cSJim Jagielski                         list.Add( iface );
104*b1cdbd2cSJim Jagielski                     }
105*b1cdbd2cSJim Jagielski                 }
106*b1cdbd2cSJim Jagielski                 Int32 len = list.Count;
107*b1cdbd2cSJim Jagielski                 Type [] ar = new Type [ len ];
108*b1cdbd2cSJim Jagielski                 for ( Int32 pos = 0; pos < len; ++pos )
109*b1cdbd2cSJim Jagielski                     ar[ pos ] = (Type) list[ pos ];
110*b1cdbd2cSJim Jagielski                 s_types[ type ] = ar;
111*b1cdbd2cSJim Jagielski                 types = ar;
112*b1cdbd2cSJim Jagielski             }
113*b1cdbd2cSJim Jagielski         }
114*b1cdbd2cSJim Jagielski         return types;
115*b1cdbd2cSJim Jagielski     }
116*b1cdbd2cSJim Jagielski 
117*b1cdbd2cSJim Jagielski     /** Provides an identifier that represents the set of UNO interfaces
118*b1cdbd2cSJim Jagielski         implemented by this class.  All instances of this class which run
119*b1cdbd2cSJim Jagielski         in the same CLR return the same array.
120*b1cdbd2cSJim Jagielski 
121*b1cdbd2cSJim Jagielski         @return identifier as array of bytes
122*b1cdbd2cSJim Jagielski     */
getImplementationId()123*b1cdbd2cSJim Jagielski     public byte [] getImplementationId()
124*b1cdbd2cSJim Jagielski     {
125*b1cdbd2cSJim Jagielski         byte [] id;
126*b1cdbd2cSJim Jagielski         Type type = GetType();
127*b1cdbd2cSJim Jagielski         lock (s_impl_ids)
128*b1cdbd2cSJim Jagielski         {
129*b1cdbd2cSJim Jagielski             id = (byte []) s_impl_ids[ type ];
130*b1cdbd2cSJim Jagielski             if (null == id)
131*b1cdbd2cSJim Jagielski             {
132*b1cdbd2cSJim Jagielski                 Int32 hash = GetHashCode();
133*b1cdbd2cSJim Jagielski                 String name = type.FullName;
134*b1cdbd2cSJim Jagielski                 Int32 len= name.Length;
135*b1cdbd2cSJim Jagielski 
136*b1cdbd2cSJim Jagielski                 id = new byte[ 4 + (2 * len) ];
137*b1cdbd2cSJim Jagielski                 id[ 0 ]= (byte) (hash & 0xff);
138*b1cdbd2cSJim Jagielski                 id[ 1 ]= (byte) ((hash >> 8) & 0xff);
139*b1cdbd2cSJim Jagielski                 id[ 2 ]= (byte) ((hash >> 16) & 0xff);
140*b1cdbd2cSJim Jagielski                 id[ 3 ]= (byte) ((hash >> 24) & 0xff);
141*b1cdbd2cSJim Jagielski 
142*b1cdbd2cSJim Jagielski                 for ( Int32 pos = 0; pos < len; ++pos )
143*b1cdbd2cSJim Jagielski                 {
144*b1cdbd2cSJim Jagielski                     UInt16 c = Convert.ToUInt16( name[ pos ] );
145*b1cdbd2cSJim Jagielski                     id[ 4 + (2 * pos) ] = (byte) (c & 0xff);
146*b1cdbd2cSJim Jagielski                     id[ 4 + (2 * pos) +1 ] = (byte) ((c >> 8) & 0xff);
147*b1cdbd2cSJim Jagielski                 }
148*b1cdbd2cSJim Jagielski                 s_impl_ids[ type ] = id;
149*b1cdbd2cSJim Jagielski             }
150*b1cdbd2cSJim Jagielski         }
151*b1cdbd2cSJim Jagielski         return id;
152*b1cdbd2cSJim Jagielski     }
153*b1cdbd2cSJim Jagielski 
154*b1cdbd2cSJim Jagielski     // System.Object
ToString()155*b1cdbd2cSJim Jagielski     public override String ToString()
156*b1cdbd2cSJim Jagielski     {
157*b1cdbd2cSJim Jagielski         System.Text.StringBuilder buf =
158*b1cdbd2cSJim Jagielski             new System.Text.StringBuilder( base.ToString(), 256 );
159*b1cdbd2cSJim Jagielski         buf.Append( "\nUNO Object Implementation:\n\tImplementationId: " );
160*b1cdbd2cSJim Jagielski         buf.Append( getImplementationId() );
161*b1cdbd2cSJim Jagielski         buf.Append( "\n\tInterfaces: " );
162*b1cdbd2cSJim Jagielski         Type [] types = getTypes();
163*b1cdbd2cSJim Jagielski         for ( Int32 pos = 0; pos < types.Length; ++pos )
164*b1cdbd2cSJim Jagielski         {
165*b1cdbd2cSJim Jagielski             buf.Append( types[ pos ].FullName );
166*b1cdbd2cSJim Jagielski             if (pos < (types.Length -1))
167*b1cdbd2cSJim Jagielski                 buf.Append( ", " );
168*b1cdbd2cSJim Jagielski         }
169*b1cdbd2cSJim Jagielski         return buf.ToString();
170*b1cdbd2cSJim Jagielski     }
171*b1cdbd2cSJim Jagielski }
172*b1cdbd2cSJim Jagielski 
173*b1cdbd2cSJim Jagielski }
174*b1cdbd2cSJim Jagielski 
175