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