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