blob: 5905b141872ac8dbfc8097080f51298ceace1384 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
package com.sun.star.comp.helper;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.Any;
import com.sun.star.uno.XComponentContext;
import com.sun.star.lang.XMultiComponentFactory;
import com.sun.star.lang.XSingleComponentFactory;
import com.sun.star.lang.XComponent;
import com.sun.star.lang.XEventListener;
import com.sun.star.lang.EventObject;
import java.util.Hashtable;
import java.util.Enumeration;
import java.util.Vector;
//==================================================================================================
class Disposer implements XEventListener
{
private XComponent m_xComp;
//----------------------------------------------------------------------------------------------
Disposer( XComponent xComp )
{
m_xComp = xComp;
}
//______________________________________________________________________________________________
public void disposing( EventObject Source )
{
m_xComp.dispose();
}
}
/** Component context implementation.
*/
public class ComponentContext implements XComponentContext, XComponent
{
private static final boolean DEBUG = false;
private static final String SMGR_NAME = "/singletons/com.sun.star.lang.theServiceManager";
private static final String TDMGR_NAME = "/singletons/com.sun.star.reflection.theTypeDescriptionManager";
private Hashtable m_table;
private XComponentContext m_xDelegate;
private XMultiComponentFactory m_xSMgr;
private boolean m_bDisposeSMgr;
private Vector m_eventListener;
/** Ctor to create a component context passing a hashtable for values and a delegator
reference. Entries of the passed hashtable are either direct values or
ComponentContextEntry objects.
@param table
entries
@param xDelegate
if values are not found, request is delegated to this object
*/
public ComponentContext( Hashtable table, XComponentContext xDelegate )
{
m_eventListener = new Vector();
m_table = table;
m_xDelegate = xDelegate;
m_xSMgr = null;
m_bDisposeSMgr = false;
Object o = table.get( SMGR_NAME );
if (o != null)
{
if (o instanceof ComponentContextEntry)
{
o = ((ComponentContextEntry)o).m_value;
}
m_xSMgr = UnoRuntime.queryInterface(
XMultiComponentFactory.class, o );
}
if (m_xSMgr != null)
{
m_bDisposeSMgr = true;
}
else if (m_xDelegate != null)
{
m_xSMgr = m_xDelegate.getServiceManager();
}
// listen for delegate
XComponent xComp = UnoRuntime.queryInterface(
XComponent.class, m_xDelegate );
if (xComp != null)
{
xComp.addEventListener( new Disposer( this ) );
}
}
// XComponentContext impl
//______________________________________________________________________________________________
public Object getValueByName( String rName )
{
Object o = m_table.get( rName );
if (o != null)
{
if (o instanceof ComponentContextEntry)
{
ComponentContextEntry entry = (ComponentContextEntry)o;
if (entry.m_lateInit != null)
{
Object xInstance = null;
try
{
String serviceName = (String)entry.m_lateInit;
if (serviceName != null)
{
if (m_xSMgr != null)
{
xInstance = m_xSMgr.createInstanceWithContext( serviceName, this );
}
else
{
if (DEBUG)
System.err.println( "### no service manager instance for late init of singleton instance \"" + rName + "\"!" );
}
}
else
{
XSingleComponentFactory xCompFac =
UnoRuntime.queryInterface(
XSingleComponentFactory.class, entry.m_lateInit );
if (xCompFac != null)
{
xInstance = xCompFac.createInstanceWithContext( this );
}
else
{
if (DEBUG)
System.err.println( "### neither service name nor service factory given for late init of singleton instance \"" + rName + "\"!" );
}
}
}
catch (com.sun.star.uno.Exception exc)
{
if (DEBUG)
System.err.println( "### exception occured on late init of singleton instance \"" + rName + "\": " + exc.getMessage() );
}
if (xInstance != null)
{
synchronized (entry)
{
if (entry.m_lateInit != null)
{
entry.m_value = xInstance;
entry.m_lateInit = null;
}
else // inited in the meantime
{
// dispose fresh service instance
XComponent xComp = UnoRuntime.queryInterface(
XComponent.class, xInstance );
if (xComp != null)
{
xComp.dispose();
}
}
}
}
else
{
if (DEBUG)
System.err.println( "### failed late init of singleton instance \"" + rName + "\"!" );
}
}
return entry.m_value;
}
else // direct value in map
{
return o;
}
}
else if (m_xDelegate != null)
{
return m_xDelegate.getValueByName( rName );
}
else
{
return Any.VOID;
}
}
//______________________________________________________________________________________________
public XMultiComponentFactory getServiceManager()
{
return m_xSMgr;
}
// XComponent impl
//______________________________________________________________________________________________
public void dispose()
{
if (DEBUG)
System.err.print( "> disposing context " + this );
// fire events
EventObject evt = new EventObject( this );
Enumeration eventListener = m_eventListener.elements();
while (eventListener.hasMoreElements())
{
XEventListener listener = (XEventListener)eventListener.nextElement();
listener.disposing( evt );
}
m_eventListener.removeAllElements();
XComponent tdmgr = null;
// dispose values, then service manager, then typdescription manager
Enumeration keys = m_table.keys();
while (keys.hasMoreElements())
{
String name = (String)keys.nextElement();
if (! name.equals( SMGR_NAME ))
{
Object o = m_table.get( name );
if (o instanceof ComponentContextEntry)
{
o = ((ComponentContextEntry)o).m_value;
}
XComponent xComp = UnoRuntime.queryInterface( XComponent.class, o );
if (xComp != null)
{
if (name.equals( TDMGR_NAME ))
{
tdmgr = xComp;
}
else
{
xComp.dispose();
}
}
}
}
m_table.clear();
// smgr
if (m_bDisposeSMgr)
{
XComponent xComp = UnoRuntime.queryInterface(
XComponent.class, m_xSMgr );
if (xComp != null)
{
xComp.dispose();
}
}
m_xSMgr = null;
// tdmgr
if (tdmgr != null)
{
tdmgr.dispose();
}
if (DEBUG)
System.err.println( "... finished" );
}
//______________________________________________________________________________________________
public void addEventListener( XEventListener xListener )
{
if (xListener == null)
throw new com.sun.star.uno.RuntimeException( "Listener must not be null" );
if (m_eventListener.contains( xListener ))
throw new com.sun.star.uno.RuntimeException( "Listener already registred." );
m_eventListener.addElement( xListener );
}
//______________________________________________________________________________________________
public void removeEventListener( XEventListener xListener )
{
if (xListener == null)
throw new com.sun.star.uno.RuntimeException( "Listener must not be null" );
if (! m_eventListener.contains( xListener ))
throw new com.sun.star.uno.RuntimeException( "Listener is not registered." );
m_eventListener.removeElement( xListener );
}
}