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