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 24 package com.sun.star.comp.loader; 25 26 27 import java.lang.reflect.Constructor; 28 import java.lang.reflect.Field; 29 import java.lang.reflect.InvocationTargetException; 30 31 import com.sun.star.uno.XComponentContext; 32 import com.sun.star.lang.XInitialization; 33 import com.sun.star.lang.XMultiServiceFactory; 34 import com.sun.star.lang.XServiceInfo; 35 import com.sun.star.lang.XSingleServiceFactory; 36 import com.sun.star.lang.XSingleComponentFactory; 37 import com.sun.star.lang.XTypeProvider; 38 39 import com.sun.star.registry.XRegistryKey; 40 41 import com.sun.star.uno.UnoRuntime; 42 import com.sun.star.uno.Type; 43 44 45 /** 46 * The purpose of this class to help component implementation. 47 * This class has default implementations for <code>getServiceFactory</code> 48 * and <code>writeRegistryServiceInfo</code>. 49 * <p> 50 * @version $Revision: 1.9 $ $ $Date: 2008-04-11 11:10:09 $ 51 * @author Kay Ramme 52 * @see com.sun.star.lang.XMultiServiceFactory 53 * @see com.sun.star.lang.XServiceInfo 54 * @see com.sun.star.lang.XSingleServiceFactory 55 * @see com.sun.star.registry.XRegistryKey 56 * @since UDK1.0 57 */ 58 public class FactoryHelper { 59 60 private static final boolean DEBUG = false; 61 // the factory 62 static protected class Factory 63 implements XSingleServiceFactory, XSingleComponentFactory, XServiceInfo, 64 XTypeProvider { 65 protected static Class __objectArray; 66 67 static { 68 try { 69 __objectArray = Class.forName("[Ljava.lang.Object;"); 70 } 71 catch(ClassNotFoundException classNotFoundException) { 72 System.err.println(FactoryHelper.class.getName() + " exception occurred - " + classNotFoundException); 73 } 74 } 75 76 // private static final boolean DEBUG = false; 77 78 protected XMultiServiceFactory _xMultiServiceFactory; 79 protected XRegistryKey _xRegistryKey; 80 protected int _nCode; 81 protected Constructor _constructor; 82 protected String _implName; 83 protected String _serviceName; 84 // keeps the Id for XTypeProvider 85 protected static Object _mutex= new Object(); 86 private static byte[] _implementationId; 87 Factory(Class implClass, String serviceName, XMultiServiceFactory xMultiServiceFactory, XRegistryKey xRegistryKey)88 protected Factory(Class implClass, 89 String serviceName, 90 XMultiServiceFactory xMultiServiceFactory, 91 XRegistryKey xRegistryKey) 92 { 93 _xMultiServiceFactory = xMultiServiceFactory; 94 _xRegistryKey = xRegistryKey; 95 _implName = implClass.getName(); 96 _serviceName = serviceName; 97 98 Constructor constructors[] = implClass.getConstructors(); 99 for(int i = 0; i < constructors.length && _constructor == null; ++i) { 100 Class parameters[] = constructors[i].getParameterTypes(); 101 102 if(parameters.length == 3 103 && parameters[0].equals(XComponentContext.class) 104 && parameters[1].equals(XRegistryKey.class) 105 && parameters[2].equals(__objectArray)) { 106 _nCode = 0; 107 _constructor = constructors[i]; 108 } 109 else if(parameters.length == 2 110 && parameters[0].equals(XComponentContext.class) 111 && parameters[1].equals(XRegistryKey.class)) { 112 _nCode = 1; 113 _constructor = constructors[i]; 114 } 115 else if(parameters.length == 2 116 && parameters[0].equals(XComponentContext.class) 117 && parameters[1].equals(__objectArray)) { 118 _nCode = 2; 119 _constructor = constructors[i]; 120 } 121 else if(parameters.length == 1 122 && parameters[0].equals(XComponentContext.class)) { 123 _nCode = 3; 124 _constructor = constructors[i]; 125 } 126 // depr 127 else if(parameters.length == 3 128 && parameters[0].equals(XMultiServiceFactory.class) 129 && parameters[1].equals(XRegistryKey.class) 130 && parameters[2].equals(__objectArray)) { 131 _nCode = 4; 132 _constructor = constructors[i]; 133 } 134 else if(parameters.length == 2 135 && parameters[0].equals(XMultiServiceFactory.class) 136 && parameters[1].equals(XRegistryKey.class)) { 137 _nCode = 5; 138 _constructor = constructors[i]; 139 } 140 else if(parameters.length == 2 141 && parameters[0].equals(XMultiServiceFactory.class) 142 && parameters[1].equals(__objectArray)) { 143 _nCode = 6; 144 _constructor = constructors[i]; 145 } 146 else if(parameters.length == 1 147 && parameters[0].equals(XMultiServiceFactory.class)) { 148 _nCode = 7; 149 _constructor = constructors[i]; 150 } 151 else if(parameters.length == 1 152 && parameters[0].equals(__objectArray)) { 153 _nCode = 8; 154 _constructor = constructors[i]; 155 } 156 else if(parameters.length == 0) { 157 _nCode = 9; 158 _constructor = constructors[i]; 159 } 160 } 161 162 if(_constructor == null) // have not found a useable constructor 163 throw new com.sun.star.uno.RuntimeException(getClass().getName() + " can not find a useable constructor"); 164 } 165 getSMgr( XComponentContext xContext )166 private final XMultiServiceFactory getSMgr( XComponentContext xContext ) 167 { 168 if (xContext != null) 169 { 170 return UnoRuntime.queryInterface( 171 XMultiServiceFactory.class, xContext.getServiceManager() ); 172 } 173 else 174 { 175 return _xMultiServiceFactory; 176 } 177 } 178 179 // XComponentContext impl 180 //______________________________________________________________________________________________ createInstanceWithContext( XComponentContext xContext )181 public Object createInstanceWithContext( 182 XComponentContext xContext ) 183 throws com.sun.star.uno.Exception 184 { 185 Object args[]; 186 switch (_nCode) 187 { 188 case 0: 189 args = new Object [] { xContext, _xRegistryKey, new Object[ 0 ] }; 190 break; 191 case 1: 192 args = new Object [] { xContext, _xRegistryKey }; 193 break; 194 case 2: 195 args = new Object [] { xContext, new Object[ 0 ] }; 196 break; 197 case 3: 198 args = new Object [] { xContext }; 199 break; 200 case 4: 201 args = new Object [] { getSMgr( xContext ), _xRegistryKey, new Object[ 0 ] }; 202 break; 203 case 5: 204 args = new Object [] { getSMgr( xContext ), _xRegistryKey }; 205 break; 206 case 6: 207 args = new Object [] { getSMgr( xContext ), new Object[ 0 ] }; 208 break; 209 case 7: 210 args = new Object [] { getSMgr( xContext ) }; 211 break; 212 case 8: 213 args = new Object [] { new Object[ 0 ] }; 214 break; 215 default: 216 args = new Object [ 0 ]; 217 break; 218 } 219 220 try 221 { 222 return _constructor.newInstance( args ); 223 } 224 catch (InvocationTargetException invocationTargetException) 225 { 226 Throwable targetException = invocationTargetException.getTargetException(); 227 228 if (targetException instanceof java.lang.RuntimeException) 229 throw (java.lang.RuntimeException)targetException; 230 else if (targetException instanceof com.sun.star.uno.Exception) 231 throw (com.sun.star.uno.Exception)targetException; 232 else if (targetException instanceof com.sun.star.uno.RuntimeException) 233 throw (com.sun.star.uno.RuntimeException)targetException; 234 else 235 throw new com.sun.star.uno.Exception( targetException.toString() ); 236 } 237 catch (IllegalAccessException illegalAccessException) 238 { 239 throw new com.sun.star.uno.Exception( illegalAccessException.toString() ); 240 } 241 catch (InstantiationException instantiationException) 242 { 243 throw new com.sun.star.uno.Exception( instantiationException.toString() ); 244 } 245 } 246 //______________________________________________________________________________________________ createInstanceWithArgumentsAndContext( Object rArguments[], XComponentContext xContext )247 public Object createInstanceWithArgumentsAndContext( 248 Object rArguments[], XComponentContext xContext ) 249 throws com.sun.star.uno.Exception 250 { 251 Object args[]; 252 253 boolean bInitCall = true; 254 switch (_nCode) 255 { 256 case 0: 257 args = new Object [] { xContext, _xRegistryKey, rArguments }; 258 bInitCall = false; 259 break; 260 case 1: 261 args = new Object [] { xContext, _xRegistryKey }; 262 break; 263 case 2: 264 args = new Object [] { xContext, rArguments }; 265 bInitCall = false; 266 break; 267 case 3: 268 args = new Object [] { xContext }; 269 break; 270 case 4: 271 args = new Object [] { getSMgr( xContext ), _xRegistryKey, rArguments }; 272 bInitCall = false; 273 break; 274 case 5: 275 args = new Object [] { getSMgr( xContext ), _xRegistryKey }; 276 break; 277 case 6: 278 args = new Object [] { getSMgr( xContext ), rArguments }; 279 bInitCall = false; 280 break; 281 case 7: 282 args = new Object [] { getSMgr( xContext ) }; 283 break; 284 case 8: 285 args = new Object [] { rArguments }; 286 bInitCall = false; 287 break; 288 default: 289 args = new Object [ 0 ]; 290 break; 291 } 292 293 try 294 { 295 Object instance = _constructor.newInstance( args ); 296 if (bInitCall) 297 { 298 XInitialization xInitialization = UnoRuntime.queryInterface( 299 XInitialization.class, instance ); 300 if (xInitialization != null) 301 { 302 xInitialization.initialize( rArguments ); 303 } 304 } 305 return instance; 306 } 307 catch (InvocationTargetException invocationTargetException) 308 { 309 Throwable targetException = invocationTargetException.getTargetException(); 310 311 if (targetException instanceof java.lang.RuntimeException) 312 throw (java.lang.RuntimeException)targetException; 313 else if (targetException instanceof com.sun.star.uno.Exception) 314 throw (com.sun.star.uno.Exception)targetException; 315 else if (targetException instanceof com.sun.star.uno.RuntimeException) 316 throw (com.sun.star.uno.RuntimeException)targetException; 317 else 318 throw new com.sun.star.uno.Exception( targetException.toString() ); 319 } 320 catch (IllegalAccessException illegalAccessException) 321 { 322 throw new com.sun.star.uno.Exception( illegalAccessException.toString() ); 323 } 324 catch (InstantiationException instantiationException) 325 { 326 throw new com.sun.star.uno.Exception( instantiationException.toString() ); 327 } 328 } 329 330 /** 331 * Creates an instance of the desired service. 332 * <p> 333 * @return returns an instance of the desired service 334 * @see com.sun.star.lang.XSingleServiceFactory 335 */ createInstance()336 public Object createInstance() 337 throws com.sun.star.uno.Exception, 338 com.sun.star.uno.RuntimeException 339 { 340 return createInstanceWithContext( null ); 341 } 342 343 /** 344 * Creates an instance of the desired service. 345 * <p> 346 * @return returns an instance of the desired service 347 * @param args the args given to the constructor of the service 348 * @see com.sun.star.lang.XSingleServiceFactory 349 */ createInstanceWithArguments(Object[] args)350 public Object createInstanceWithArguments(Object[] args) 351 throws com.sun.star.uno.Exception, 352 com.sun.star.uno.RuntimeException 353 { 354 return createInstanceWithArgumentsAndContext( args, null ); 355 } 356 357 /** 358 * Gives the supported services 359 * <p> 360 * @return returns an array of supported services 361 * @see com.sun.star.lang.XServiceInfo 362 */ getSupportedServiceNames()363 public String[] getSupportedServiceNames() throws com.sun.star.uno.RuntimeException { 364 return new String[]{_serviceName}; 365 } 366 367 /** 368 * Gives the implementation name 369 * <p> 370 * @return returns the implementation name 371 * @see com.sun.star.lang.XServiceInfo 372 */ getImplementationName()373 public String getImplementationName() throws com.sun.star.uno.RuntimeException { 374 return _implName; 375 } 376 377 /** 378 * Indicates if the given service is supported. 379 * <p> 380 * @return returns true if the given service is supported 381 * @see com.sun.star.lang.XServiceInfo 382 */ supportsService(String serviceName)383 public boolean supportsService(String serviceName) throws com.sun.star.uno.RuntimeException { 384 String services[] = getSupportedServiceNames(); 385 386 boolean found = false; 387 388 for(int i = 0; i < services.length && !found; ++i) 389 found = services[i].equals(serviceName); 390 391 return found; 392 } 393 394 //XTypeProvider getImplementationId()395 public byte[] getImplementationId() 396 { 397 synchronized (_mutex) 398 { 399 if (_implementationId == null) 400 { 401 int hash = hashCode(); 402 String sName= getClass().getName(); 403 byte[] arName= sName.getBytes(); 404 int nNameLength= arName.length; 405 406 _implementationId= new byte[ 4 + nNameLength]; 407 _implementationId[0]= (byte)(hash & 0xff); 408 _implementationId[1]= (byte)((hash >>> 8) & 0xff); 409 _implementationId[2]= (byte)((hash >>> 16) & 0xff); 410 _implementationId[3]= (byte)((hash >>>24) & 0xff); 411 412 System.arraycopy(arName, 0, _implementationId, 4, nNameLength); 413 } 414 } 415 return _implementationId; 416 } 417 //XTypeProvider getTypes()418 public com.sun.star.uno.Type[] getTypes() 419 { 420 Type[] t = new Type[] { 421 new Type(XSingleServiceFactory.class), 422 new Type(XSingleComponentFactory.class), 423 new Type(XServiceInfo.class), 424 new Type(XTypeProvider.class) 425 }; 426 return t; 427 } 428 429 } 430 431 /** 432 * Creates a factory for the given class. 433 * <p> 434 * @deprecated as of UDK 1.0 435 * <p> 436 * @return returns a factory 437 * @param implClass the implementing class 438 * @param multiFactory the given multi service factory (service manager) 439 * @param regKey the given registry key 440 * @see com.sun.star.lang.XServiceInfo 441 */ getServiceFactory(Class implClass, XMultiServiceFactory multiFactory, XRegistryKey regKey)442 static public XSingleServiceFactory getServiceFactory(Class implClass, 443 XMultiServiceFactory multiFactory, 444 XRegistryKey regKey) 445 { 446 XSingleServiceFactory xSingleServiceFactory = null; 447 448 try { 449 Field serviceName ; 450 451 try { 452 serviceName = implClass.getField("__serviceName"); 453 } 454 catch(NoSuchFieldException noSuchFieldExceptio) { 455 serviceName = implClass.getField("serviceName"); // old style 456 } 457 458 xSingleServiceFactory = new Factory(implClass, (String)serviceName.get(null), multiFactory, regKey); 459 } 460 catch(NoSuchFieldException noSuchFieldException) { 461 System.err.println("##### FactoryHelper.getServiceFactory - exception:" + noSuchFieldException); 462 } 463 catch(IllegalAccessException illegalAccessException) { 464 System.err.println("##### FactoryHelper.getServiceFactory - exception:" + illegalAccessException); 465 } 466 467 return xSingleServiceFactory; 468 } 469 470 /** 471 * Creates a factory for the given class. 472 * <p> 473 * @return returns a factory 474 * @param implClass the implementing class 475 * @param serviceName the service name of the implementing class 476 * @param multiFactory the given multi service factory (service manager) 477 * @param regKey the given registry key 478 * @see com.sun.star.lang.XServiceInfo 479 */ getServiceFactory(Class implClass, String serviceName, XMultiServiceFactory multiFactory, XRegistryKey regKey)480 static public XSingleServiceFactory getServiceFactory(Class implClass, 481 String serviceName, 482 XMultiServiceFactory multiFactory, 483 XRegistryKey regKey) 484 { 485 return new Factory(implClass, serviceName, multiFactory, regKey); 486 } 487 488 /** Creates a factory for the given class. 489 490 @return returns a factory object 491 @param implClass the implementing class 492 */ createComponentFactory( Class implClass, String serviceName )493 static public Object createComponentFactory( Class implClass, String serviceName ) 494 { 495 return new Factory( implClass, serviceName, null, null ); 496 } 497 498 /** 499 * Writes the registration data into the registry key 500 * <p> 501 * @return success 502 * @param implName the name of the implementing class 503 * @param serviceName the service name 504 * @param regKey the given registry key 505 * @see com.sun.star.lang.XServiceInfo 506 */ writeRegistryServiceInfo(String implName, String serviceName, XRegistryKey regKey)507 static public boolean writeRegistryServiceInfo(String implName, String serviceName, XRegistryKey regKey) { 508 boolean result = false; 509 510 try { 511 XRegistryKey newKey = regKey.createKey("/" + implName + "/UNO/SERVICES"); 512 513 newKey.createKey(serviceName); 514 515 result = true; 516 } 517 catch (Exception ex) { 518 System.err.println(">>>Connection_Impl.writeRegistryServiceInfo " + ex); 519 } 520 521 return result; 522 } 523 524 /** Writes the registration data into the registry key. 525 * Several services are supported. 526 * 527 * @param impl_name name of implementation 528 * @param supported_services supported services of implementation 529 * @param xKey registry key to write to 530 * @return success 531 */ writeRegistryServiceInfo( String impl_name, String supported_services [], XRegistryKey xKey )532 public static boolean writeRegistryServiceInfo( 533 String impl_name, String supported_services [], XRegistryKey xKey ) 534 { 535 try 536 { 537 XRegistryKey xNewKey = xKey.createKey( "/" + impl_name + "/UNO/SERVICES" ); 538 for ( int nPos = 0; nPos < supported_services.length; ++nPos ) 539 { 540 xNewKey.createKey( supported_services[ nPos ] ); 541 } 542 return true; 543 } 544 catch (com.sun.star.registry.InvalidRegistryException exc) 545 { 546 if (DEBUG) 547 { 548 System.err.println( 549 "##### " + Factory.class.getName() + ".writeRegistryServiceInfo -- exc: " + 550 exc.toString() ); 551 } 552 } 553 return false; 554 } 555 556 } 557 558