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 package com.sun.star.lib.uno.helper;
25 import com.sun.star.uno.XWeak;
26 import com.sun.star.uno.XAdapter;
27 import com.sun.star.lang.XTypeProvider;
28 import com.sun.star.uno.Type;
29 import java.util.Vector;
30 import java.util.Map;
31 import java.util.Hashtable;
32 
33 
34 /** This class can be used as the base class for UNO components. It implements the capability
35  *  to be kept weak (com.sun.star.uno.XWeak) and it implements com.sun.star.lang.XTypeProvider
36  *  which is necessary for using the component with StarBasic.
37  */
38 public class WeakBase implements XWeak, XTypeProvider
39 {
40     private final boolean DEBUG= false;
41 
42     // Contains all WeakAdapter which have been created in this class
43     // They have to be notified when this object dies
44     private WeakAdapter m_adapter;
45 
46     protected static Map _mapImplementationIds= new Hashtable();
47     protected static Map _mapTypes= new Hashtable();
48 
49     /** Method of XWeak. The returned XAdapter implementation can be used to keap
50      * a weak reference to this object.
51      * @return a com.sun.star.uno.XAdapter implementation.
52      */
queryAdapter()53     synchronized public XAdapter queryAdapter()
54     {
55         if (m_adapter == null)
56             m_adapter= new WeakAdapter(this);
57         return m_adapter;
58     }
59 
60     /** Override of Object.finalize. When there are no references to this object anymore
61      * then the garbage collector calls this method. Thereby causing the adapter object
62      * to be notified. The adapter, in turn, notifies all listeners (com.sun.star.uno.XReference)
63      */
finalize()64     protected void finalize() throws java.lang.Throwable
65     {
66         if (m_adapter != null)
67             m_adapter.referentDying();
68         super.finalize();
69     }
70 
71     /** Method of XTypeProvider. It returns an array of Type objects which represent
72      * all implemented UNO interfaces of this object.
73      * @return Type objects of all implemented interfaces.
74      */
getTypes()75     public Type[] getTypes()
76     {
77         Type[] arTypes= (Type[]) _mapTypes.get( getClass());
78         if (arTypes == null)
79         {
80             Vector vec= new Vector();
81             Class currentClass= getClass();
82             do
83             {
84                 Class interfaces[]= currentClass.getInterfaces();
85                 for(int i = 0; i < interfaces.length; ++ i)
86                 {
87                     // Test if it is a UNO interface
88                     if (com.sun.star.uno.XInterface.class.isAssignableFrom((interfaces[i])))
89                         vec.add(new Type(interfaces[i]));
90                 }
91                 // get the superclass the currentClass inherits from
92                 currentClass= currentClass.getSuperclass();
93             } while (currentClass != null);
94 
95             Type types[]= new Type[vec.size()];
96             for( int i= 0; i < types.length; i++)
97                 types[i]= (Type) vec.elementAt(i);
98             _mapTypes.put(getClass(), types);
99             arTypes= types;
100         }
101         return arTypes;
102     }
103 
104     /** Method of XTypeProvider. It provides an identifier that represents the set of UNO
105      * interfaces implemented by this class. All instances of this class
106      * which run in the same Java Virtual Machine return the same array. (This only works as long
107      * the ClassLoader preserves the class even if no instance exist.)
108      *@return identifier as array of bytes
109      */
getImplementationId()110     public byte[] getImplementationId()
111     {
112         byte[] id= null;
113         synchronized (_mapImplementationIds)
114         {
115             id= (byte[]) _mapImplementationIds.get(getClass());
116 
117             if (id == null)
118             {
119                 int hash = hashCode();
120                 String sName= getClass().getName();
121                 byte[] arName= sName.getBytes();
122                 int nNameLength= arName.length;
123 
124                 id= new byte[ 4 + nNameLength];
125                 id[0]= (byte)(hash & 0xff);
126                 id[1]= (byte)((hash >>> 8) & 0xff);
127                 id[2]= (byte)((hash >>> 16) & 0xff);
128                 id[3]= (byte)((hash >>>24) & 0xff);
129 
130                 for (int i= 0; i < nNameLength; i++)
131                 {
132                     id[4 + i]= arName[i];
133                 }
134                 _mapImplementationIds.put(getClass(), id);
135             }
136         }
137         return id;
138     }
139 }
140