1*a5b190bfSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*a5b190bfSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*a5b190bfSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*a5b190bfSAndrew Rist  * distributed with this work for additional information
6*a5b190bfSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*a5b190bfSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*a5b190bfSAndrew Rist  * "License"); you may not use this file except in compliance
9*a5b190bfSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*a5b190bfSAndrew Rist  *
11*a5b190bfSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*a5b190bfSAndrew Rist  *
13*a5b190bfSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*a5b190bfSAndrew Rist  * software distributed under the License is distributed on an
15*a5b190bfSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*a5b190bfSAndrew Rist  * KIND, either express or implied.  See the License for the
17*a5b190bfSAndrew Rist  * specific language governing permissions and limitations
18*a5b190bfSAndrew Rist  * under the License.
19*a5b190bfSAndrew Rist  *
20*a5b190bfSAndrew Rist  *************************************************************/
21*a5b190bfSAndrew Rist 
22*a5b190bfSAndrew Rist 
23cdf0e10cSrcweir package com.sun.star.comp.helper;
24cdf0e10cSrcweir 
25cdf0e10cSrcweir import com.sun.star.uno.UnoRuntime;
26cdf0e10cSrcweir import com.sun.star.uno.Any;
27cdf0e10cSrcweir 
28cdf0e10cSrcweir import com.sun.star.uno.XComponentContext;
29cdf0e10cSrcweir import com.sun.star.lang.XMultiComponentFactory;
30cdf0e10cSrcweir import com.sun.star.lang.XSingleComponentFactory;
31cdf0e10cSrcweir import com.sun.star.lang.XComponent;
32cdf0e10cSrcweir import com.sun.star.lang.XEventListener;
33cdf0e10cSrcweir import com.sun.star.lang.EventObject;
34cdf0e10cSrcweir 
35cdf0e10cSrcweir import java.util.Hashtable;
36cdf0e10cSrcweir import java.util.Enumeration;
37cdf0e10cSrcweir import java.util.Vector;
38cdf0e10cSrcweir 
39cdf0e10cSrcweir 
40cdf0e10cSrcweir //==================================================================================================
41cdf0e10cSrcweir class Disposer implements XEventListener
42cdf0e10cSrcweir {
43cdf0e10cSrcweir     private XComponent m_xComp;
44cdf0e10cSrcweir 
45cdf0e10cSrcweir     //----------------------------------------------------------------------------------------------
Disposer( XComponent xComp )46cdf0e10cSrcweir     Disposer( XComponent xComp )
47cdf0e10cSrcweir     {
48cdf0e10cSrcweir         m_xComp = xComp;
49cdf0e10cSrcweir     }
50cdf0e10cSrcweir     //______________________________________________________________________________________________
disposing( EventObject Source )51cdf0e10cSrcweir     public void disposing( EventObject Source )
52cdf0e10cSrcweir     {
53cdf0e10cSrcweir         m_xComp.dispose();
54cdf0e10cSrcweir     }
55cdf0e10cSrcweir }
56cdf0e10cSrcweir 
57cdf0e10cSrcweir /** Component context implementation.
58cdf0e10cSrcweir */
59cdf0e10cSrcweir public class ComponentContext implements XComponentContext, XComponent
60cdf0e10cSrcweir {
61cdf0e10cSrcweir     private static final boolean DEBUG = false;
62cdf0e10cSrcweir     private static final String SMGR_NAME = "/singletons/com.sun.star.lang.theServiceManager";
63cdf0e10cSrcweir     private static final String TDMGR_NAME = "/singletons/com.sun.star.reflection.theTypeDescriptionManager";
64cdf0e10cSrcweir 
65cdf0e10cSrcweir     private Hashtable m_table;
66cdf0e10cSrcweir     private XComponentContext m_xDelegate;
67cdf0e10cSrcweir 
68cdf0e10cSrcweir     private XMultiComponentFactory m_xSMgr;
69cdf0e10cSrcweir     private boolean m_bDisposeSMgr;
70cdf0e10cSrcweir 
71cdf0e10cSrcweir     private Vector m_eventListener;
72cdf0e10cSrcweir 
73cdf0e10cSrcweir     /** Ctor to create a component context passing a hashtable for values and a delegator
74cdf0e10cSrcweir         reference. Entries of the passed hashtable are either direct values or
75cdf0e10cSrcweir         ComponentContextEntry objects.
76cdf0e10cSrcweir 
77cdf0e10cSrcweir         @param table
78cdf0e10cSrcweir                entries
79cdf0e10cSrcweir         @param xDelegate
80cdf0e10cSrcweir                if values are not found, request is delegated to this object
81cdf0e10cSrcweir     */
ComponentContext( Hashtable table, XComponentContext xDelegate )82cdf0e10cSrcweir     public ComponentContext( Hashtable table, XComponentContext xDelegate )
83cdf0e10cSrcweir     {
84cdf0e10cSrcweir         m_eventListener = new Vector();
85cdf0e10cSrcweir         m_table = table;
86cdf0e10cSrcweir         m_xDelegate = xDelegate;
87cdf0e10cSrcweir         m_xSMgr = null;
88cdf0e10cSrcweir         m_bDisposeSMgr = false;
89cdf0e10cSrcweir 
90cdf0e10cSrcweir         Object o = table.get( SMGR_NAME );
91cdf0e10cSrcweir         if (o != null)
92cdf0e10cSrcweir         {
93cdf0e10cSrcweir             if (o instanceof ComponentContextEntry)
94cdf0e10cSrcweir             {
95cdf0e10cSrcweir                 o = ((ComponentContextEntry)o).m_value;
96cdf0e10cSrcweir             }
97cdf0e10cSrcweir             m_xSMgr = UnoRuntime.queryInterface(
98cdf0e10cSrcweir                 XMultiComponentFactory.class, o );
99cdf0e10cSrcweir         }
100cdf0e10cSrcweir         if (m_xSMgr != null)
101cdf0e10cSrcweir         {
102cdf0e10cSrcweir             m_bDisposeSMgr = true;
103cdf0e10cSrcweir         }
104cdf0e10cSrcweir         else if (m_xDelegate != null)
105cdf0e10cSrcweir         {
106cdf0e10cSrcweir             m_xSMgr = m_xDelegate.getServiceManager();
107cdf0e10cSrcweir         }
108cdf0e10cSrcweir 
109cdf0e10cSrcweir         // listen for delegate
110cdf0e10cSrcweir         XComponent xComp = UnoRuntime.queryInterface(
111cdf0e10cSrcweir             XComponent.class, m_xDelegate );
112cdf0e10cSrcweir         if (xComp != null)
113cdf0e10cSrcweir         {
114cdf0e10cSrcweir             xComp.addEventListener( new Disposer( this ) );
115cdf0e10cSrcweir         }
116cdf0e10cSrcweir     }
117cdf0e10cSrcweir 
118cdf0e10cSrcweir     // XComponentContext impl
119cdf0e10cSrcweir     //______________________________________________________________________________________________
getValueByName( String rName )120cdf0e10cSrcweir     public Object getValueByName( String rName )
121cdf0e10cSrcweir     {
122cdf0e10cSrcweir         Object o = m_table.get( rName );
123cdf0e10cSrcweir         if (o != null)
124cdf0e10cSrcweir         {
125cdf0e10cSrcweir             if (o instanceof ComponentContextEntry)
126cdf0e10cSrcweir             {
127cdf0e10cSrcweir                 ComponentContextEntry entry = (ComponentContextEntry)o;
128cdf0e10cSrcweir                 if (entry.m_lateInit != null)
129cdf0e10cSrcweir                 {
130cdf0e10cSrcweir                     Object xInstance = null;
131cdf0e10cSrcweir 
132cdf0e10cSrcweir                     try
133cdf0e10cSrcweir                     {
134cdf0e10cSrcweir                         String serviceName = (String)entry.m_lateInit;
135cdf0e10cSrcweir                         if (serviceName != null)
136cdf0e10cSrcweir                         {
137cdf0e10cSrcweir                             if (m_xSMgr != null)
138cdf0e10cSrcweir                             {
139cdf0e10cSrcweir                                 xInstance = m_xSMgr.createInstanceWithContext( serviceName, this );
140cdf0e10cSrcweir                             }
141cdf0e10cSrcweir                             else
142cdf0e10cSrcweir                             {
143cdf0e10cSrcweir                                 if (DEBUG)
144cdf0e10cSrcweir                                     System.err.println( "### no service manager instance for late init of singleton instance \"" + rName + "\"!" );
145cdf0e10cSrcweir                             }
146cdf0e10cSrcweir                         }
147cdf0e10cSrcweir                         else
148cdf0e10cSrcweir                         {
149cdf0e10cSrcweir                             XSingleComponentFactory xCompFac =
150cdf0e10cSrcweir                                 UnoRuntime.queryInterface(
151cdf0e10cSrcweir                                     XSingleComponentFactory.class, entry.m_lateInit );
152cdf0e10cSrcweir                             if (xCompFac != null)
153cdf0e10cSrcweir                             {
154cdf0e10cSrcweir                                 xInstance = xCompFac.createInstanceWithContext( this );
155cdf0e10cSrcweir                             }
156cdf0e10cSrcweir                             else
157cdf0e10cSrcweir                             {
158cdf0e10cSrcweir                                 if (DEBUG)
159cdf0e10cSrcweir                                     System.err.println( "### neither service name nor service factory given for late init of singleton instance \"" + rName + "\"!" );
160cdf0e10cSrcweir                             }
161cdf0e10cSrcweir                         }
162cdf0e10cSrcweir                     }
163cdf0e10cSrcweir                     catch (com.sun.star.uno.Exception exc)
164cdf0e10cSrcweir                     {
165cdf0e10cSrcweir                         if (DEBUG)
166cdf0e10cSrcweir                             System.err.println( "### exception occured on late init of singleton instance \"" + rName + "\": " + exc.getMessage() );
167cdf0e10cSrcweir                     }
168cdf0e10cSrcweir 
169cdf0e10cSrcweir                     if (xInstance != null)
170cdf0e10cSrcweir                     {
171cdf0e10cSrcweir                         synchronized (entry)
172cdf0e10cSrcweir                         {
173cdf0e10cSrcweir                             if (entry.m_lateInit != null)
174cdf0e10cSrcweir                             {
175cdf0e10cSrcweir                                 entry.m_value = xInstance;
176cdf0e10cSrcweir                                 entry.m_lateInit = null;
177cdf0e10cSrcweir                             }
178cdf0e10cSrcweir                             else // inited in the meantime
179cdf0e10cSrcweir                             {
180cdf0e10cSrcweir                                 // dispose fresh service instance
181cdf0e10cSrcweir                                 XComponent xComp = UnoRuntime.queryInterface(
182cdf0e10cSrcweir                                     XComponent.class, xInstance );
183cdf0e10cSrcweir                                 if (xComp != null)
184cdf0e10cSrcweir                                 {
185cdf0e10cSrcweir                                     xComp.dispose();
186cdf0e10cSrcweir                                 }
187cdf0e10cSrcweir                             }
188cdf0e10cSrcweir                         }
189cdf0e10cSrcweir                     }
190cdf0e10cSrcweir                     else
191cdf0e10cSrcweir                     {
192cdf0e10cSrcweir                         if (DEBUG)
193cdf0e10cSrcweir                             System.err.println( "### failed late init of singleton instance \"" + rName + "\"!" );
194cdf0e10cSrcweir                     }
195cdf0e10cSrcweir                 }
196cdf0e10cSrcweir                 return entry.m_value;
197cdf0e10cSrcweir             }
198cdf0e10cSrcweir             else // direct value in map
199cdf0e10cSrcweir             {
200cdf0e10cSrcweir                 return o;
201cdf0e10cSrcweir             }
202cdf0e10cSrcweir         }
203cdf0e10cSrcweir         else if (m_xDelegate != null)
204cdf0e10cSrcweir         {
205cdf0e10cSrcweir             return m_xDelegate.getValueByName( rName );
206cdf0e10cSrcweir         }
207cdf0e10cSrcweir         else
208cdf0e10cSrcweir         {
209cdf0e10cSrcweir             return Any.VOID;
210cdf0e10cSrcweir         }
211cdf0e10cSrcweir     }
212cdf0e10cSrcweir     //______________________________________________________________________________________________
getServiceManager()213cdf0e10cSrcweir     public XMultiComponentFactory getServiceManager()
214cdf0e10cSrcweir     {
215cdf0e10cSrcweir         return m_xSMgr;
216cdf0e10cSrcweir     }
217cdf0e10cSrcweir 
218cdf0e10cSrcweir     // XComponent impl
219cdf0e10cSrcweir     //______________________________________________________________________________________________
dispose()220cdf0e10cSrcweir     public void dispose()
221cdf0e10cSrcweir     {
222cdf0e10cSrcweir         if (DEBUG)
223cdf0e10cSrcweir             System.err.print( "> disposing context " + this );
224cdf0e10cSrcweir 
225cdf0e10cSrcweir         // fire events
226cdf0e10cSrcweir         EventObject evt = new EventObject( this );
227cdf0e10cSrcweir         Enumeration eventListener = m_eventListener.elements();
228cdf0e10cSrcweir         while (eventListener.hasMoreElements())
229cdf0e10cSrcweir         {
230cdf0e10cSrcweir             XEventListener listener = (XEventListener)eventListener.nextElement();
231cdf0e10cSrcweir             listener.disposing( evt );
232cdf0e10cSrcweir         }
233cdf0e10cSrcweir         m_eventListener.removeAllElements();
234cdf0e10cSrcweir 
235cdf0e10cSrcweir         XComponent tdmgr = null;
236cdf0e10cSrcweir         // dispose values, then service manager, then typdescription manager
237cdf0e10cSrcweir         Enumeration keys = m_table.keys();
238cdf0e10cSrcweir         while (keys.hasMoreElements())
239cdf0e10cSrcweir         {
240cdf0e10cSrcweir             String name = (String)keys.nextElement();
241cdf0e10cSrcweir             if (! name.equals( SMGR_NAME ))
242cdf0e10cSrcweir             {
243cdf0e10cSrcweir                 Object o = m_table.get( name );
244cdf0e10cSrcweir                 if (o instanceof ComponentContextEntry)
245cdf0e10cSrcweir                 {
246cdf0e10cSrcweir                     o = ((ComponentContextEntry)o).m_value;
247cdf0e10cSrcweir                 }
248cdf0e10cSrcweir 
249cdf0e10cSrcweir                 XComponent xComp = UnoRuntime.queryInterface( XComponent.class, o );
250cdf0e10cSrcweir                 if (xComp != null)
251cdf0e10cSrcweir                 {
252cdf0e10cSrcweir                     if (name.equals( TDMGR_NAME ))
253cdf0e10cSrcweir                     {
254cdf0e10cSrcweir                         tdmgr = xComp;
255cdf0e10cSrcweir                     }
256cdf0e10cSrcweir                     else
257cdf0e10cSrcweir                     {
258cdf0e10cSrcweir                         xComp.dispose();
259cdf0e10cSrcweir                     }
260cdf0e10cSrcweir                 }
261cdf0e10cSrcweir             }
262cdf0e10cSrcweir         }
263cdf0e10cSrcweir         m_table.clear();
264cdf0e10cSrcweir 
265cdf0e10cSrcweir         // smgr
266cdf0e10cSrcweir         if (m_bDisposeSMgr)
267cdf0e10cSrcweir         {
268cdf0e10cSrcweir             XComponent xComp = UnoRuntime.queryInterface(
269cdf0e10cSrcweir                 XComponent.class, m_xSMgr );
270cdf0e10cSrcweir             if (xComp != null)
271cdf0e10cSrcweir             {
272cdf0e10cSrcweir                 xComp.dispose();
273cdf0e10cSrcweir             }
274cdf0e10cSrcweir         }
275cdf0e10cSrcweir         m_xSMgr = null;
276cdf0e10cSrcweir 
277cdf0e10cSrcweir         // tdmgr
278cdf0e10cSrcweir         if (tdmgr != null)
279cdf0e10cSrcweir         {
280cdf0e10cSrcweir             tdmgr.dispose();
281cdf0e10cSrcweir         }
282cdf0e10cSrcweir 
283cdf0e10cSrcweir         if (DEBUG)
284cdf0e10cSrcweir             System.err.println( "... finished" );
285cdf0e10cSrcweir     }
286cdf0e10cSrcweir     //______________________________________________________________________________________________
addEventListener( XEventListener xListener )287cdf0e10cSrcweir     public void addEventListener( XEventListener xListener )
288cdf0e10cSrcweir     {
289cdf0e10cSrcweir         if (xListener == null)
290cdf0e10cSrcweir         	throw new com.sun.star.uno.RuntimeException( "Listener must not be null" );
291cdf0e10cSrcweir   		if (m_eventListener.contains( xListener ))
292cdf0e10cSrcweir   			throw new com.sun.star.uno.RuntimeException( "Listener already registred." );
293cdf0e10cSrcweir 
294cdf0e10cSrcweir        	m_eventListener.addElement( xListener );
295cdf0e10cSrcweir     }
296cdf0e10cSrcweir     //______________________________________________________________________________________________
removeEventListener( XEventListener xListener )297cdf0e10cSrcweir     public void removeEventListener( XEventListener xListener )
298cdf0e10cSrcweir     {
299cdf0e10cSrcweir         if (xListener == null)
300cdf0e10cSrcweir         	throw new com.sun.star.uno.RuntimeException( "Listener must not be null" );
301cdf0e10cSrcweir   		if (! m_eventListener.contains( xListener ))
302cdf0e10cSrcweir   			throw new com.sun.star.uno.RuntimeException( "Listener is not registered." );
303cdf0e10cSrcweir 
304cdf0e10cSrcweir         m_eventListener.removeElement( xListener );
305cdf0e10cSrcweir     }
306cdf0e10cSrcweir }
307