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