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