diff options
Diffstat (limited to 'ridljar/com/sun/star/comp/helper/ComponentContext.java')
-rw-r--r-- | ridljar/com/sun/star/comp/helper/ComponentContext.java | 308 |
1 files changed, 308 insertions, 0 deletions
diff --git a/ridljar/com/sun/star/comp/helper/ComponentContext.java b/ridljar/com/sun/star/comp/helper/ComponentContext.java new file mode 100644 index 000000000..34649d563 --- /dev/null +++ b/ridljar/com/sun/star/comp/helper/ComponentContext.java @@ -0,0 +1,308 @@ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ +package com.sun.star.comp.helper; + +import com.sun.star.uno.UnoRuntime; +import com.sun.star.uno.Any; + +import com.sun.star.uno.DeploymentException; +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.ArrayList; +import java.util.Hashtable; +import java.util.Map; + + + +class Disposer implements XEventListener +{ + private final 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 Map<String,Object> m_table; + private XComponentContext m_xDelegate; + + private XMultiComponentFactory m_xSMgr; + private boolean m_bDisposeSMgr; + + private ArrayList<XEventListener> m_eventListener; + + public ComponentContext( Hashtable<String,Object> table, XComponentContext xDelegate ) + { + this((Map<String,Object>) table, xDelegate); + } + + /** 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( Map<String,Object> table, XComponentContext xDelegate ) + { + m_eventListener = new ArrayList<XEventListener>(); + 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 (m_xDelegate != null) + { + return m_xDelegate.getValueByName( rName ); + } + else + { + return Any.VOID; + } + } + + if (!(o instanceof ComponentContextEntry)) + { + // direct value in map + return o; + } + + ComponentContextEntry entry = (ComponentContextEntry)o; + if (entry.m_lateInit == null) + { + return entry.m_value; + } + + 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 occurred 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; + } + + public XMultiComponentFactory getServiceManager() + { + if (m_xSMgr == null) + { + throw new DeploymentException( + "null component context service manager" ); + } + return m_xSMgr; + } + + // XComponent impl + + public void dispose() + { + if (DEBUG) + System.err.print( "> disposing context " + this ); + + // fire events + EventObject evt = new EventObject( this ); + for (XEventListener listener : m_eventListener) + { + listener.disposing( evt ); + } + m_eventListener.clear(); + + XComponent tdmgr = null; + // dispose values, then service manager, then typedescription manager + for (Map.Entry<String, Object> entry : m_table.entrySet()) + { + String name = entry.getKey(); + if (! name.equals( SMGR_NAME )) + { + Object o = entry.getValue(); + 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 registered." ); + + m_eventListener.add( 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.remove( xListener ); + } +} |