1 /* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 package com
.sun
.star
.comp
.loader
;
22 import java
.lang
.reflect
.Constructor
;
23 import java
.lang
.reflect
.Field
;
24 import java
.lang
.reflect
.InvocationTargetException
;
26 import com
.sun
.star
.uno
.XComponentContext
;
27 import com
.sun
.star
.lang
.XInitialization
;
28 import com
.sun
.star
.lang
.XMultiServiceFactory
;
29 import com
.sun
.star
.lang
.XServiceInfo
;
30 import com
.sun
.star
.lang
.XSingleServiceFactory
;
31 import com
.sun
.star
.lang
.XSingleComponentFactory
;
32 import com
.sun
.star
.lang
.XTypeProvider
;
33 import com
.sun
.star
.registry
.XRegistryKey
;
34 import com
.sun
.star
.uno
.UnoRuntime
;
35 import com
.sun
.star
.uno
.Type
;
39 * The purpose of this class to help component implementation.
41 * <p>This class has default implementations for <code>getServiceFactory</code>
42 * and <code>writeRegistryServiceInfo</code>.</p>
44 * @see com.sun.star.lang.XMultiServiceFactory
45 * @see com.sun.star.lang.XServiceInfo
46 * @see com.sun.star.lang.XSingleServiceFactory
47 * @see com.sun.star.registry.XRegistryKey
50 public class FactoryHelper
{
52 private static final boolean DEBUG
= false;
54 protected static class Factory
55 implements XSingleServiceFactory
, XSingleComponentFactory
, XServiceInfo
,
58 protected XMultiServiceFactory _xMultiServiceFactory
;
59 protected XRegistryKey _xRegistryKey
;
61 protected Constructor
<?
> _constructor
;
62 protected String _implName
;
63 protected String _serviceName
;
65 protected Factory(Class
<?
> implClass
,
67 XMultiServiceFactory xMultiServiceFactory
,
68 XRegistryKey xRegistryKey
)
70 _xMultiServiceFactory
= xMultiServiceFactory
;
71 _xRegistryKey
= xRegistryKey
;
72 _implName
= implClass
.getName();
73 _serviceName
= serviceName
;
75 Constructor
<?
> constructors
[] = implClass
.getConstructors();
76 for(int i
= 0; i
< constructors
.length
&& _constructor
== null; ++i
) {
77 Class
<?
> parameters
[] = constructors
[i
].getParameterTypes();
79 if(parameters
.length
== 3
80 && parameters
[0].equals(XComponentContext
.class)
81 && parameters
[1].equals(XRegistryKey
.class)
82 && parameters
[2].equals(Object
[].class)) {
84 _constructor
= constructors
[i
];
86 else if(parameters
.length
== 2
87 && parameters
[0].equals(XComponentContext
.class)
88 && parameters
[1].equals(XRegistryKey
.class)) {
90 _constructor
= constructors
[i
];
92 else if(parameters
.length
== 2
93 && parameters
[0].equals(XComponentContext
.class)
94 && parameters
[1].equals(Object
[].class)) {
96 _constructor
= constructors
[i
];
98 else if(parameters
.length
== 1
99 && parameters
[0].equals(XComponentContext
.class)) {
101 _constructor
= constructors
[i
];
104 else if(parameters
.length
== 3
105 && parameters
[0].equals(XMultiServiceFactory
.class)
106 && parameters
[1].equals(XRegistryKey
.class)
107 && parameters
[2].equals(Object
[].class)) {
109 _constructor
= constructors
[i
];
111 else if(parameters
.length
== 2
112 && parameters
[0].equals(XMultiServiceFactory
.class)
113 && parameters
[1].equals(XRegistryKey
.class)) {
115 _constructor
= constructors
[i
];
117 else if(parameters
.length
== 2
118 && parameters
[0].equals(XMultiServiceFactory
.class)
119 && parameters
[1].equals(Object
[].class)) {
121 _constructor
= constructors
[i
];
123 else if(parameters
.length
== 1
124 && parameters
[0].equals(XMultiServiceFactory
.class)) {
126 _constructor
= constructors
[i
];
128 else if(parameters
.length
== 1
129 && parameters
[0].equals(Object
[].class)) {
131 _constructor
= constructors
[i
];
133 else if(parameters
.length
== 0) {
135 _constructor
= constructors
[i
];
139 if(_constructor
== null) // have not found a usable constructor
140 throw new com
.sun
.star
.uno
.RuntimeException(getClass().getName() + " can not find a usable constructor");
143 private final XMultiServiceFactory
getSMgr( XComponentContext xContext
)
145 if (xContext
!= null)
147 return UnoRuntime
.queryInterface(
148 XMultiServiceFactory
.class, xContext
.getServiceManager() );
152 return _xMultiServiceFactory
;
156 // XComponentContext impl
158 public Object
createInstanceWithContext(
159 XComponentContext xContext
)
160 throws com
.sun
.star
.uno
.Exception
166 args
= new Object
[] { xContext
, _xRegistryKey
, new Object
[ 0 ] };
169 args
= new Object
[] { xContext
, _xRegistryKey
};
172 args
= new Object
[] { xContext
, new Object
[ 0 ] };
175 args
= new Object
[] { xContext
};
178 args
= new Object
[] { getSMgr( xContext
), _xRegistryKey
, new Object
[ 0 ] };
181 args
= new Object
[] { getSMgr( xContext
), _xRegistryKey
};
184 args
= new Object
[] { getSMgr( xContext
), new Object
[ 0 ] };
187 args
= new Object
[] { getSMgr( xContext
) };
190 args
= new Object
[] { new Object
[ 0 ] };
193 args
= new Object
[ 0 ];
198 return _constructor
.newInstance( args
);
199 } catch (InvocationTargetException invocationTargetException
) {
200 Throwable targetException
= invocationTargetException
.getCause();
202 if (targetException
instanceof java
.lang
.RuntimeException
)
203 throw (java
.lang
.RuntimeException
)targetException
;
204 else if (targetException
instanceof com
.sun
.star
.uno
.Exception
)
205 throw (com
.sun
.star
.uno
.Exception
)targetException
;
206 else if (targetException
instanceof com
.sun
.star
.uno
.RuntimeException
)
207 throw (com
.sun
.star
.uno
.RuntimeException
)targetException
;
209 throw new com
.sun
.star
.uno
.Exception( targetException
);
210 } catch (IllegalAccessException illegalAccessException
) {
211 throw new com
.sun
.star
.uno
.Exception( illegalAccessException
);
212 } catch (InstantiationException instantiationException
) {
213 throw new com
.sun
.star
.uno
.Exception( instantiationException
);
217 public Object
createInstanceWithArgumentsAndContext(
218 Object rArguments
[], XComponentContext xContext
)
219 throws com
.sun
.star
.uno
.Exception
223 boolean bInitCall
= true;
227 args
= new Object
[] { xContext
, _xRegistryKey
, rArguments
};
231 args
= new Object
[] { xContext
, _xRegistryKey
};
234 args
= new Object
[] { xContext
, rArguments
};
238 args
= new Object
[] { xContext
};
241 args
= new Object
[] { getSMgr( xContext
), _xRegistryKey
, rArguments
};
245 args
= new Object
[] { getSMgr( xContext
), _xRegistryKey
};
248 args
= new Object
[] { getSMgr( xContext
), rArguments
};
252 args
= new Object
[] { getSMgr( xContext
) };
255 args
= new Object
[] { rArguments
};
259 args
= new Object
[ 0 ];
264 Object instance
= _constructor
.newInstance( args
);
267 XInitialization xInitialization
= UnoRuntime
.queryInterface(
268 XInitialization
.class, instance
);
269 if (xInitialization
!= null)
271 xInitialization
.initialize( rArguments
);
275 } catch (InvocationTargetException invocationTargetException
) {
276 Throwable targetException
= invocationTargetException
.getCause();
278 if (targetException
instanceof java
.lang
.RuntimeException
)
279 throw (java
.lang
.RuntimeException
)targetException
;
280 else if (targetException
instanceof com
.sun
.star
.uno
.Exception
)
281 throw (com
.sun
.star
.uno
.Exception
)targetException
;
282 else if (targetException
instanceof com
.sun
.star
.uno
.RuntimeException
)
283 throw (com
.sun
.star
.uno
.RuntimeException
)targetException
;
285 throw new com
.sun
.star
.uno
.Exception( targetException
);
286 } catch (IllegalAccessException illegalAccessException
) {
287 throw new com
.sun
.star
.uno
.Exception( illegalAccessException
);
288 } catch (InstantiationException instantiationException
) {
289 throw new com
.sun
.star
.uno
.Exception( instantiationException
);
294 * Creates an instance of the desired service.
296 * @return returns an instance of the desired service.
297 * @see com.sun.star.lang.XSingleServiceFactory
299 public Object
createInstance()
300 throws com
.sun
.star
.uno
.Exception
,
301 com
.sun
.star
.uno
.RuntimeException
303 return createInstanceWithContext( null );
307 * Creates an instance of the desired service.
309 * @param args the args given to the constructor of the service.
310 * @return returns an instance of the desired service.
312 * @see com.sun.star.lang.XSingleServiceFactory
314 public Object
createInstanceWithArguments(Object
[] args
)
315 throws com
.sun
.star
.uno
.Exception
,
316 com
.sun
.star
.uno
.RuntimeException
318 return createInstanceWithArgumentsAndContext( args
, null );
322 * Gives the supported services.
324 * @return returns an array of supported services.
325 * @see com.sun.star.lang.XServiceInfo
327 public String
[] getSupportedServiceNames() throws com
.sun
.star
.uno
.RuntimeException
{
328 return new String
[]{_serviceName
};
332 * Gives the implementation name.
334 * @return returns the implementation name.
335 * @see com.sun.star.lang.XServiceInfo
337 public String
getImplementationName() throws com
.sun
.star
.uno
.RuntimeException
{
342 * Indicates if the given service is supported.
344 * @return returns true if the given service is supported.
345 * @see com.sun.star.lang.XServiceInfo
347 public boolean supportsService(String serviceName
) throws com
.sun
.star
.uno
.RuntimeException
{
348 String services
[] = getSupportedServiceNames();
350 boolean found
= false;
352 for(int i
= 0; i
< services
.length
&& !found
; ++i
)
353 found
= services
[i
].equals(serviceName
);
359 public byte[] getImplementationId()
364 public com
.sun
.star
.uno
.Type
[] getTypes()
366 Type
[] t
= new Type
[] {
367 new Type(XSingleServiceFactory
.class),
368 new Type(XSingleComponentFactory
.class),
369 new Type(XServiceInfo
.class),
370 new Type(XTypeProvider
.class)
378 * Creates a factory for the given class.
380 * @param implClass the implementing class.
381 * @param multiFactory the given multi service factory (service manager).
382 * @param regKey the given registry key.
383 * @return returns a factory.
385 * @see com.sun.star.lang.XServiceInfo
386 * @deprecated as of UDK 1.0
389 public static XSingleServiceFactory
getServiceFactory(Class
<?
> implClass
,
390 XMultiServiceFactory multiFactory
,
393 XSingleServiceFactory xSingleServiceFactory
= null;
399 serviceName
= implClass
.getField("__serviceName");
400 } catch(NoSuchFieldException noSuchFieldExceptio
) {
401 serviceName
= implClass
.getField("serviceName"); // old style
404 xSingleServiceFactory
= new Factory(implClass
, (String
)serviceName
.get(null), multiFactory
, regKey
);
405 } catch(NoSuchFieldException noSuchFieldException
) {
406 System
.err
.println("##### FactoryHelper.getServiceFactory - exception:" + noSuchFieldException
);
407 } catch(IllegalAccessException illegalAccessException
) {
408 System
.err
.println("##### FactoryHelper.getServiceFactory - exception:" + illegalAccessException
);
411 return xSingleServiceFactory
;
415 * Creates a factory for the given class.
417 * @param implClass the implementing class.
418 * @param serviceName the service name of the implementing class.
419 * @param multiFactory the given multi service factory (service manager).
420 * @param regKey the given registry key.
422 * @return returns a factory.
423 * @see com.sun.star.lang.XServiceInfo
425 public static XSingleServiceFactory
getServiceFactory(Class
<?
> implClass
,
427 XMultiServiceFactory multiFactory
,
430 return new Factory(implClass
, serviceName
, multiFactory
, regKey
);
434 * Creates a factory for the given class.
436 * @param implClass the implementing class.
437 * @return returns a factory object.
439 public static Object
createComponentFactory( Class
<?
> implClass
, String serviceName
)
441 return new Factory( implClass
, serviceName
, null, null );
445 * Writes the registration data into the registry key.
447 * @param implName the name of the implementing class.
448 * @param serviceName the service name.
449 * @param regKey the given registry key.
452 * @see com.sun.star.lang.XServiceInfo
454 public static boolean writeRegistryServiceInfo(String implName
, String serviceName
, XRegistryKey regKey
) {
455 boolean result
= false;
458 XRegistryKey newKey
= regKey
.createKey("/" + implName
+ "/UNO/SERVICES");
460 newKey
.createKey(serviceName
);
464 catch (Exception ex
) {
465 System
.err
.println(">>>Connection_Impl.writeRegistryServiceInfo " + ex
);
472 * Writes the registration data into the registry key.
474 * <p>Several services are supported.</p>
476 * @param impl_name name of implementation.
477 * @param supported_services supported services of implementation.
478 * @param xKey registry key to write to.
481 public static boolean writeRegistryServiceInfo(
482 String impl_name
, String supported_services
[], XRegistryKey xKey
)
485 XRegistryKey xNewKey
= xKey
.createKey( "/" + impl_name
+ "/UNO/SERVICES" );
486 for ( int nPos
= 0; nPos
< supported_services
.length
; ++nPos
) {
487 xNewKey
.createKey( supported_services
[ nPos
] );
490 } catch (com
.sun
.star
.registry
.InvalidRegistryException exc
) {
493 "##### " + Factory
.class.getName() + ".writeRegistryServiceInfo -- exc: " +
502 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */