1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: FactoryHelper.java,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 package com
.sun
.star
.comp
.loader
;
34 import java
.lang
.reflect
.Constructor
;
35 import java
.lang
.reflect
.Field
;
36 import java
.lang
.reflect
.InvocationTargetException
;
38 import com
.sun
.star
.uno
.XComponentContext
;
39 import com
.sun
.star
.lang
.XInitialization
;
40 import com
.sun
.star
.lang
.XMultiServiceFactory
;
41 import com
.sun
.star
.lang
.XServiceInfo
;
42 import com
.sun
.star
.lang
.XSingleServiceFactory
;
43 import com
.sun
.star
.lang
.XSingleComponentFactory
;
44 import com
.sun
.star
.lang
.XTypeProvider
;
46 import com
.sun
.star
.registry
.XRegistryKey
;
48 import com
.sun
.star
.uno
.UnoRuntime
;
49 import com
.sun
.star
.uno
.Type
;
53 * The purpose of this class to help component implementation.
54 * This class has default implementations for <code>getServiceFactory</code>
55 * and <code>writeRegistryServiceInfo</code>.
57 * @version $Revision: 1.9 $ $ $Date: 2008-04-11 11:10:09 $
59 * @see com.sun.star.lang.XMultiServiceFactory
60 * @see com.sun.star.lang.XServiceInfo
61 * @see com.sun.star.lang.XSingleServiceFactory
62 * @see com.sun.star.registry.XRegistryKey
65 public class FactoryHelper
{
67 private static final boolean DEBUG
= false;
69 static protected class Factory
70 implements XSingleServiceFactory
, XSingleComponentFactory
, XServiceInfo
,
72 protected static Class __objectArray
;
76 __objectArray
= Class
.forName("[Ljava.lang.Object;");
78 catch(ClassNotFoundException classNotFoundException
) {
79 System
.err
.println(FactoryHelper
.class.getName() + " exception occurred - " + classNotFoundException
);
83 // private static final boolean DEBUG = false;
85 protected XMultiServiceFactory _xMultiServiceFactory
;
86 protected XRegistryKey _xRegistryKey
;
88 protected Constructor _constructor
;
89 protected String _implName
;
90 protected String _serviceName
;
91 // keeps the Id for XTypeProvider
92 protected static Object _mutex
= new Object();
93 private static byte[] _implementationId
;
95 protected Factory(Class implClass
,
97 XMultiServiceFactory xMultiServiceFactory
,
98 XRegistryKey xRegistryKey
)
100 _xMultiServiceFactory
= xMultiServiceFactory
;
101 _xRegistryKey
= xRegistryKey
;
102 _implName
= implClass
.getName();
103 _serviceName
= serviceName
;
105 Constructor constructors
[] = implClass
.getConstructors();
106 for(int i
= 0; i
< constructors
.length
&& _constructor
== null; ++i
) {
107 Class parameters
[] = constructors
[i
].getParameterTypes();
109 if(parameters
.length
== 3
110 && parameters
[0].equals(XComponentContext
.class)
111 && parameters
[1].equals(XRegistryKey
.class)
112 && parameters
[2].equals(__objectArray
)) {
114 _constructor
= constructors
[i
];
116 else if(parameters
.length
== 2
117 && parameters
[0].equals(XComponentContext
.class)
118 && parameters
[1].equals(XRegistryKey
.class)) {
120 _constructor
= constructors
[i
];
122 else if(parameters
.length
== 2
123 && parameters
[0].equals(XComponentContext
.class)
124 && parameters
[1].equals(__objectArray
)) {
126 _constructor
= constructors
[i
];
128 else if(parameters
.length
== 1
129 && parameters
[0].equals(XComponentContext
.class)) {
131 _constructor
= constructors
[i
];
134 else if(parameters
.length
== 3
135 && parameters
[0].equals(XMultiServiceFactory
.class)
136 && parameters
[1].equals(XRegistryKey
.class)
137 && parameters
[2].equals(__objectArray
)) {
139 _constructor
= constructors
[i
];
141 else if(parameters
.length
== 2
142 && parameters
[0].equals(XMultiServiceFactory
.class)
143 && parameters
[1].equals(XRegistryKey
.class)) {
145 _constructor
= constructors
[i
];
147 else if(parameters
.length
== 2
148 && parameters
[0].equals(XMultiServiceFactory
.class)
149 && parameters
[1].equals(__objectArray
)) {
151 _constructor
= constructors
[i
];
153 else if(parameters
.length
== 1
154 && parameters
[0].equals(XMultiServiceFactory
.class)) {
156 _constructor
= constructors
[i
];
158 else if(parameters
.length
== 1
159 && parameters
[0].equals(__objectArray
)) {
161 _constructor
= constructors
[i
];
163 else if(parameters
.length
== 0) {
165 _constructor
= constructors
[i
];
169 if(_constructor
== null) // have not found a useable constructor
170 throw new com
.sun
.star
.uno
.RuntimeException(getClass().getName() + " can not find a useable constructor");
173 private final XMultiServiceFactory
getSMgr( XComponentContext xContext
)
175 if (xContext
!= null)
177 return UnoRuntime
.queryInterface(
178 XMultiServiceFactory
.class, xContext
.getServiceManager() );
182 return _xMultiServiceFactory
;
186 // XComponentContext impl
187 //______________________________________________________________________________________________
188 public Object
createInstanceWithContext(
189 XComponentContext xContext
)
190 throws com
.sun
.star
.uno
.Exception
196 args
= new Object
[] { xContext
, _xRegistryKey
, new Object
[ 0 ] };
199 args
= new Object
[] { xContext
, _xRegistryKey
};
202 args
= new Object
[] { xContext
, new Object
[ 0 ] };
205 args
= new Object
[] { xContext
};
208 args
= new Object
[] { getSMgr( xContext
), _xRegistryKey
, new Object
[ 0 ] };
211 args
= new Object
[] { getSMgr( xContext
), _xRegistryKey
};
214 args
= new Object
[] { getSMgr( xContext
), new Object
[ 0 ] };
217 args
= new Object
[] { getSMgr( xContext
) };
220 args
= new Object
[] { new Object
[ 0 ] };
223 args
= new Object
[ 0 ];
229 return _constructor
.newInstance( args
);
231 catch (InvocationTargetException invocationTargetException
)
233 Throwable targetException
= invocationTargetException
.getTargetException();
235 if (targetException
instanceof java
.lang
.RuntimeException
)
236 throw (java
.lang
.RuntimeException
)targetException
;
237 else if (targetException
instanceof com
.sun
.star
.uno
.Exception
)
238 throw (com
.sun
.star
.uno
.Exception
)targetException
;
239 else if (targetException
instanceof com
.sun
.star
.uno
.RuntimeException
)
240 throw (com
.sun
.star
.uno
.RuntimeException
)targetException
;
242 throw new com
.sun
.star
.uno
.Exception( targetException
.toString() );
244 catch (IllegalAccessException illegalAccessException
)
246 throw new com
.sun
.star
.uno
.Exception( illegalAccessException
.toString() );
248 catch (InstantiationException instantiationException
)
250 throw new com
.sun
.star
.uno
.Exception( instantiationException
.toString() );
253 //______________________________________________________________________________________________
254 public Object
createInstanceWithArgumentsAndContext(
255 Object rArguments
[], XComponentContext xContext
)
256 throws com
.sun
.star
.uno
.Exception
260 boolean bInitCall
= true;
264 args
= new Object
[] { xContext
, _xRegistryKey
, rArguments
};
268 args
= new Object
[] { xContext
, _xRegistryKey
};
271 args
= new Object
[] { xContext
, rArguments
};
275 args
= new Object
[] { xContext
};
278 args
= new Object
[] { getSMgr( xContext
), _xRegistryKey
, rArguments
};
282 args
= new Object
[] { getSMgr( xContext
), _xRegistryKey
};
285 args
= new Object
[] { getSMgr( xContext
), rArguments
};
289 args
= new Object
[] { getSMgr( xContext
) };
292 args
= new Object
[] { rArguments
};
296 args
= new Object
[ 0 ];
302 Object instance
= _constructor
.newInstance( args
);
305 XInitialization xInitialization
= UnoRuntime
.queryInterface(
306 XInitialization
.class, instance
);
307 if (xInitialization
!= null)
309 xInitialization
.initialize( rArguments
);
314 catch (InvocationTargetException invocationTargetException
)
316 Throwable targetException
= invocationTargetException
.getTargetException();
318 if (targetException
instanceof java
.lang
.RuntimeException
)
319 throw (java
.lang
.RuntimeException
)targetException
;
320 else if (targetException
instanceof com
.sun
.star
.uno
.Exception
)
321 throw (com
.sun
.star
.uno
.Exception
)targetException
;
322 else if (targetException
instanceof com
.sun
.star
.uno
.RuntimeException
)
323 throw (com
.sun
.star
.uno
.RuntimeException
)targetException
;
325 throw new com
.sun
.star
.uno
.Exception( targetException
.toString() );
327 catch (IllegalAccessException illegalAccessException
)
329 throw new com
.sun
.star
.uno
.Exception( illegalAccessException
.toString() );
331 catch (InstantiationException instantiationException
)
333 throw new com
.sun
.star
.uno
.Exception( instantiationException
.toString() );
338 * Creates an instance of the desired service.
340 * @return returns an instance of the desired service
341 * @see com.sun.star.lang.XSingleServiceFactory
343 public Object
createInstance()
344 throws com
.sun
.star
.uno
.Exception
,
345 com
.sun
.star
.uno
.RuntimeException
347 return createInstanceWithContext( null );
351 * Creates an instance of the desired service.
353 * @return returns an instance of the desired service
354 * @param args the args given to the constructor of the service
355 * @see com.sun.star.lang.XSingleServiceFactory
357 public Object
createInstanceWithArguments(Object
[] args
)
358 throws com
.sun
.star
.uno
.Exception
,
359 com
.sun
.star
.uno
.RuntimeException
361 return createInstanceWithArgumentsAndContext( args
, null );
365 * Gives the supported services
367 * @return returns an array of supported services
368 * @see com.sun.star.lang.XServiceInfo
370 public String
[] getSupportedServiceNames() throws com
.sun
.star
.uno
.RuntimeException
{
371 return new String
[]{_serviceName
};
375 * Gives the implementation name
377 * @return returns the implementation name
378 * @see com.sun.star.lang.XServiceInfo
380 public String
getImplementationName() throws com
.sun
.star
.uno
.RuntimeException
{
385 * Indicates if the given service is supported.
387 * @return returns true if the given service is supported
388 * @see com.sun.star.lang.XServiceInfo
390 public boolean supportsService(String serviceName
) throws com
.sun
.star
.uno
.RuntimeException
{
391 String services
[] = getSupportedServiceNames();
393 boolean found
= false;
395 for(int i
= 0; i
< services
.length
&& !found
; ++i
)
396 found
= services
[i
].equals(serviceName
);
402 public byte[] getImplementationId()
404 synchronized (_mutex
)
406 if (_implementationId
== null)
408 int hash
= hashCode();
409 String sName
= getClass().getName();
410 byte[] arName
= sName
.getBytes();
411 int nNameLength
= arName
.length
;
413 _implementationId
= new byte[ 4 + nNameLength
];
414 _implementationId
[0]= (byte)(hash
& 0xff);
415 _implementationId
[1]= (byte)((hash
>>> 8) & 0xff);
416 _implementationId
[2]= (byte)((hash
>>> 16) & 0xff);
417 _implementationId
[3]= (byte)((hash
>>>24) & 0xff);
419 for (int i
= 0; i
< nNameLength
; i
++)
421 _implementationId
[4 + i
]= arName
[i
];
425 return _implementationId
;
428 public com
.sun
.star
.uno
.Type
[] getTypes()
430 Type
[] t
= new Type
[] {
431 new Type(XSingleServiceFactory
.class),
432 new Type(XSingleComponentFactory
.class),
433 new Type(XServiceInfo
.class),
434 new Type(XTypeProvider
.class)
442 * Creates a factory for the given class.
444 * @deprecated as of UDK 1.0
446 * @return returns a factory
447 * @param implClass the implementing class
448 * @param multiFactory the given multi service factory (service manager)
449 * @param regKey the given registry key
450 * @see com.sun.star.lang.XServiceInfo
452 static public XSingleServiceFactory
getServiceFactory(Class implClass
,
453 XMultiServiceFactory multiFactory
,
456 XSingleServiceFactory xSingleServiceFactory
= null;
459 Field serviceName
= null;
462 serviceName
= implClass
.getField("__serviceName");
464 catch(NoSuchFieldException noSuchFieldExceptio
) {
465 serviceName
= implClass
.getField("serviceName"); // old style
468 xSingleServiceFactory
= new Factory(implClass
, (String
)serviceName
.get(null), multiFactory
, regKey
);
470 catch(NoSuchFieldException noSuchFieldException
) {
471 System
.err
.println("##### FactoryHelper.getServiceFactory - exception:" + noSuchFieldException
);
473 catch(IllegalAccessException illegalAccessException
) {
474 System
.err
.println("##### FactoryHelper.getServiceFactory - exception:" + illegalAccessException
);
477 return xSingleServiceFactory
;
481 * Creates a factory for the given class.
483 * @return returns a factory
484 * @param implClass the implementing class
485 * @param serviceName the service name of the implementing class
486 * @param multiFactory the given multi service factory (service manager)
487 * @param regKey the given registry key
488 * @see com.sun.star.lang.XServiceInfo
490 static public XSingleServiceFactory
getServiceFactory(Class implClass
,
492 XMultiServiceFactory multiFactory
,
495 return new Factory(implClass
, serviceName
, multiFactory
, regKey
);
498 /** Creates a factory for the given class.
500 @return returns a factory object
501 @param implClass the implementing class
503 static public Object
createComponentFactory( Class implClass
, String serviceName
)
505 return new Factory( implClass
, serviceName
, null, null );
509 * Writes the registration data into the registry key
512 * @param implName the name of the implementing class
513 * @param serviceName the service name
514 * @param regKey the given registry key
515 * @see com.sun.star.lang.XServiceInfo
517 static public boolean writeRegistryServiceInfo(String implName
, String serviceName
, XRegistryKey regKey
) {
518 boolean result
= false;
521 XRegistryKey newKey
= regKey
.createKey("/" + implName
+ "/UNO/SERVICES");
523 newKey
.createKey(serviceName
);
527 catch (Exception ex
) {
528 System
.err
.println(">>>Connection_Impl.writeRegistryServiceInfo " + ex
);
534 /** Writes the registration data into the registry key.
535 * Several services are supported.
537 * @param impl_name name of implementation
538 * @param supported_services supported services of implementation
539 * @param xKey registry key to write to
542 public static boolean writeRegistryServiceInfo(
543 String impl_name
, String supported_services
[], XRegistryKey xKey
)
547 XRegistryKey xNewKey
= xKey
.createKey( "/" + impl_name
+ "/UNO/SERVICES" );
548 for ( int nPos
= 0; nPos
< supported_services
.length
; ++nPos
)
550 xNewKey
.createKey( supported_services
[ nPos
] );
554 catch (com
.sun
.star
.registry
.InvalidRegistryException exc
)
559 "##### " + Factory
.class.getName() + ".writeRegistryServiceInfo -- exc: " +