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