diff options
Diffstat (limited to 'jurt/com/sun/star/comp/loader/FactoryHelper.java')
-rw-r--r-- | jurt/com/sun/star/comp/loader/FactoryHelper.java | 564 |
1 files changed, 564 insertions, 0 deletions
diff --git a/jurt/com/sun/star/comp/loader/FactoryHelper.java b/jurt/com/sun/star/comp/loader/FactoryHelper.java new file mode 100644 index 000000000000..29b484631670 --- /dev/null +++ b/jurt/com/sun/star/comp/loader/FactoryHelper.java @@ -0,0 +1,564 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package com.sun.star.comp.loader; + + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; + +import com.sun.star.uno.XComponentContext; +import com.sun.star.lang.XInitialization; +import com.sun.star.lang.XMultiServiceFactory; +import com.sun.star.lang.XServiceInfo; +import com.sun.star.lang.XSingleServiceFactory; +import com.sun.star.lang.XSingleComponentFactory; +import com.sun.star.lang.XTypeProvider; + +import com.sun.star.registry.XRegistryKey; + +import com.sun.star.uno.UnoRuntime; +import com.sun.star.uno.Type; + + +/** + * The purpose of this class to help component implementation. + * This class has default implementations for <code>getServiceFactory</code> + * and <code>writeRegistryServiceInfo</code>. + * <p> + * @version $Revision: 1.9 $ $ $Date: 2008-04-11 11:10:09 $ + * @author Kay Ramme + * @see com.sun.star.lang.XMultiServiceFactory + * @see com.sun.star.lang.XServiceInfo + * @see com.sun.star.lang.XSingleServiceFactory + * @see com.sun.star.registry.XRegistryKey + * @since UDK1.0 + */ +public class FactoryHelper { + + private static final boolean DEBUG = false; + // the factory + static protected class Factory + implements XSingleServiceFactory, XSingleComponentFactory, XServiceInfo, + XTypeProvider { + protected static Class __objectArray; + + static { + try { + __objectArray = Class.forName("[Ljava.lang.Object;"); + } + catch(ClassNotFoundException classNotFoundException) { + System.err.println(FactoryHelper.class.getName() + " exception occurred - " + classNotFoundException); + } + } + +// private static final boolean DEBUG = false; + + protected XMultiServiceFactory _xMultiServiceFactory; + protected XRegistryKey _xRegistryKey; + protected int _nCode; + protected Constructor _constructor; + protected String _implName; + protected String _serviceName; + // keeps the Id for XTypeProvider + protected static Object _mutex= new Object(); + private static byte[] _implementationId; + + protected Factory(Class implClass, + String serviceName, + XMultiServiceFactory xMultiServiceFactory, + XRegistryKey xRegistryKey) + { + _xMultiServiceFactory = xMultiServiceFactory; + _xRegistryKey = xRegistryKey; + _implName = implClass.getName(); + _serviceName = serviceName; + + Constructor constructors[] = implClass.getConstructors(); + for(int i = 0; i < constructors.length && _constructor == null; ++i) { + Class parameters[] = constructors[i].getParameterTypes(); + + if(parameters.length == 3 + && parameters[0].equals(XComponentContext.class) + && parameters[1].equals(XRegistryKey.class) + && parameters[2].equals(__objectArray)) { + _nCode = 0; + _constructor = constructors[i]; + } + else if(parameters.length == 2 + && parameters[0].equals(XComponentContext.class) + && parameters[1].equals(XRegistryKey.class)) { + _nCode = 1; + _constructor = constructors[i]; + } + else if(parameters.length == 2 + && parameters[0].equals(XComponentContext.class) + && parameters[1].equals(__objectArray)) { + _nCode = 2; + _constructor = constructors[i]; + } + else if(parameters.length == 1 + && parameters[0].equals(XComponentContext.class)) { + _nCode = 3; + _constructor = constructors[i]; + } + // depr + else if(parameters.length == 3 + && parameters[0].equals(XMultiServiceFactory.class) + && parameters[1].equals(XRegistryKey.class) + && parameters[2].equals(__objectArray)) { + _nCode = 4; + _constructor = constructors[i]; + } + else if(parameters.length == 2 + && parameters[0].equals(XMultiServiceFactory.class) + && parameters[1].equals(XRegistryKey.class)) { + _nCode = 5; + _constructor = constructors[i]; + } + else if(parameters.length == 2 + && parameters[0].equals(XMultiServiceFactory.class) + && parameters[1].equals(__objectArray)) { + _nCode = 6; + _constructor = constructors[i]; + } + else if(parameters.length == 1 + && parameters[0].equals(XMultiServiceFactory.class)) { + _nCode = 7; + _constructor = constructors[i]; + } + else if(parameters.length == 1 + && parameters[0].equals(__objectArray)) { + _nCode = 8; + _constructor = constructors[i]; + } + else if(parameters.length == 0) { + _nCode = 9; + _constructor = constructors[i]; + } + } + + if(_constructor == null) // have not found a useable constructor + throw new com.sun.star.uno.RuntimeException(getClass().getName() + " can not find a useable constructor"); + } + + private final XMultiServiceFactory getSMgr( XComponentContext xContext ) + { + if (xContext != null) + { + return UnoRuntime.queryInterface( + XMultiServiceFactory.class, xContext.getServiceManager() ); + } + else + { + return _xMultiServiceFactory; + } + } + + // XComponentContext impl + //______________________________________________________________________________________________ + public Object createInstanceWithContext( + XComponentContext xContext ) + throws com.sun.star.uno.Exception + { + Object args[]; + switch (_nCode) + { + case 0: + args = new Object [] { xContext, _xRegistryKey, new Object[ 0 ] }; + break; + case 1: + args = new Object [] { xContext, _xRegistryKey }; + break; + case 2: + args = new Object [] { xContext, new Object[ 0 ] }; + break; + case 3: + args = new Object [] { xContext }; + break; + case 4: + args = new Object [] { getSMgr( xContext ), _xRegistryKey, new Object[ 0 ] }; + break; + case 5: + args = new Object [] { getSMgr( xContext ), _xRegistryKey }; + break; + case 6: + args = new Object [] { getSMgr( xContext ), new Object[ 0 ] }; + break; + case 7: + args = new Object [] { getSMgr( xContext ) }; + break; + case 8: + args = new Object [] { new Object[ 0 ] }; + break; + default: + args = new Object [ 0 ]; + break; + } + + try + { + return _constructor.newInstance( args ); + } + catch (InvocationTargetException invocationTargetException) + { + Throwable targetException = invocationTargetException.getTargetException(); + + if (targetException instanceof java.lang.RuntimeException) + throw (java.lang.RuntimeException)targetException; + else if (targetException instanceof com.sun.star.uno.Exception) + throw (com.sun.star.uno.Exception)targetException; + else if (targetException instanceof com.sun.star.uno.RuntimeException) + throw (com.sun.star.uno.RuntimeException)targetException; + else + throw new com.sun.star.uno.Exception( targetException.toString() ); + } + catch (IllegalAccessException illegalAccessException) + { + throw new com.sun.star.uno.Exception( illegalAccessException.toString() ); + } + catch (InstantiationException instantiationException) + { + throw new com.sun.star.uno.Exception( instantiationException.toString() ); + } + } + //______________________________________________________________________________________________ + public Object createInstanceWithArgumentsAndContext( + Object rArguments[], XComponentContext xContext ) + throws com.sun.star.uno.Exception + { + Object args[]; + + boolean bInitCall = true; + switch (_nCode) + { + case 0: + args = new Object [] { xContext, _xRegistryKey, rArguments }; + bInitCall = false; + break; + case 1: + args = new Object [] { xContext, _xRegistryKey }; + break; + case 2: + args = new Object [] { xContext, rArguments }; + bInitCall = false; + break; + case 3: + args = new Object [] { xContext }; + break; + case 4: + args = new Object [] { getSMgr( xContext ), _xRegistryKey, rArguments }; + bInitCall = false; + break; + case 5: + args = new Object [] { getSMgr( xContext ), _xRegistryKey }; + break; + case 6: + args = new Object [] { getSMgr( xContext ), rArguments }; + bInitCall = false; + break; + case 7: + args = new Object [] { getSMgr( xContext ) }; + break; + case 8: + args = new Object [] { rArguments }; + bInitCall = false; + break; + default: + args = new Object [ 0 ]; + break; + } + + try + { + Object instance = _constructor.newInstance( args ); + if (bInitCall) + { + XInitialization xInitialization = UnoRuntime.queryInterface( + XInitialization.class, instance ); + if (xInitialization != null) + { + xInitialization.initialize( rArguments ); + } + } + return instance; + } + catch (InvocationTargetException invocationTargetException) + { + Throwable targetException = invocationTargetException.getTargetException(); + + if (targetException instanceof java.lang.RuntimeException) + throw (java.lang.RuntimeException)targetException; + else if (targetException instanceof com.sun.star.uno.Exception) + throw (com.sun.star.uno.Exception)targetException; + else if (targetException instanceof com.sun.star.uno.RuntimeException) + throw (com.sun.star.uno.RuntimeException)targetException; + else + throw new com.sun.star.uno.Exception( targetException.toString() ); + } + catch (IllegalAccessException illegalAccessException) + { + throw new com.sun.star.uno.Exception( illegalAccessException.toString() ); + } + catch (InstantiationException instantiationException) + { + throw new com.sun.star.uno.Exception( instantiationException.toString() ); + } + } + + /** + * Creates an instance of the desired service. + * <p> + * @return returns an instance of the desired service + * @see com.sun.star.lang.XSingleServiceFactory + */ + public Object createInstance() + throws com.sun.star.uno.Exception, + com.sun.star.uno.RuntimeException + { + return createInstanceWithContext( null ); + } + + /** + * Creates an instance of the desired service. + * <p> + * @return returns an instance of the desired service + * @param args the args given to the constructor of the service + * @see com.sun.star.lang.XSingleServiceFactory + */ + public Object createInstanceWithArguments(Object[] args) + throws com.sun.star.uno.Exception, + com.sun.star.uno.RuntimeException + { + return createInstanceWithArgumentsAndContext( args, null ); + } + + /** + * Gives the supported services + * <p> + * @return returns an array of supported services + * @see com.sun.star.lang.XServiceInfo + */ + public String[] getSupportedServiceNames() throws com.sun.star.uno.RuntimeException { + return new String[]{_serviceName}; + } + + /** + * Gives the implementation name + * <p> + * @return returns the implementation name + * @see com.sun.star.lang.XServiceInfo + */ + public String getImplementationName() throws com.sun.star.uno.RuntimeException { + return _implName; + } + + /** + * Indicates if the given service is supported. + * <p> + * @return returns true if the given service is supported + * @see com.sun.star.lang.XServiceInfo + */ + public boolean supportsService(String serviceName) throws com.sun.star.uno.RuntimeException { + String services[] = getSupportedServiceNames(); + + boolean found = false; + + for(int i = 0; i < services.length && !found; ++i) + found = services[i].equals(serviceName); + + return found; + } + + //XTypeProvider + public byte[] getImplementationId() + { + synchronized (_mutex) + { + if (_implementationId == null) + { + int hash = hashCode(); + String sName= getClass().getName(); + byte[] arName= sName.getBytes(); + int nNameLength= arName.length; + + _implementationId= new byte[ 4 + nNameLength]; + _implementationId[0]= (byte)(hash & 0xff); + _implementationId[1]= (byte)((hash >>> 8) & 0xff); + _implementationId[2]= (byte)((hash >>> 16) & 0xff); + _implementationId[3]= (byte)((hash >>>24) & 0xff); + + for (int i= 0; i < nNameLength; i++) + { + _implementationId[4 + i]= arName[i]; + } + } + } + return _implementationId; + } + //XTypeProvider + public com.sun.star.uno.Type[] getTypes() + { + Type[] t = new Type[] { + new Type(XSingleServiceFactory.class), + new Type(XSingleComponentFactory.class), + new Type(XServiceInfo.class), + new Type(XTypeProvider.class) + }; + return t; + } + + } + + /** + * Creates a factory for the given class. + * <p> + * @deprecated as of UDK 1.0 + * <p> + * @return returns a factory + * @param implClass the implementing class + * @param multiFactory the given multi service factory (service manager) + * @param regKey the given registry key + * @see com.sun.star.lang.XServiceInfo + */ + static public XSingleServiceFactory getServiceFactory(Class implClass, + XMultiServiceFactory multiFactory, + XRegistryKey regKey) + { + XSingleServiceFactory xSingleServiceFactory = null; + + try { + Field serviceName = null; + + try { + serviceName = implClass.getField("__serviceName"); + } + catch(NoSuchFieldException noSuchFieldExceptio) { + serviceName = implClass.getField("serviceName"); // old style + } + + xSingleServiceFactory = new Factory(implClass, (String)serviceName.get(null), multiFactory, regKey); + } + catch(NoSuchFieldException noSuchFieldException) { + System.err.println("##### FactoryHelper.getServiceFactory - exception:" + noSuchFieldException); + } + catch(IllegalAccessException illegalAccessException) { + System.err.println("##### FactoryHelper.getServiceFactory - exception:" + illegalAccessException); + } + + return xSingleServiceFactory; + } + + /** + * Creates a factory for the given class. + * <p> + * @return returns a factory + * @param implClass the implementing class + * @param serviceName the service name of the implementing class + * @param multiFactory the given multi service factory (service manager) + * @param regKey the given registry key + * @see com.sun.star.lang.XServiceInfo + */ + static public XSingleServiceFactory getServiceFactory(Class implClass, + String serviceName, + XMultiServiceFactory multiFactory, + XRegistryKey regKey) + { + return new Factory(implClass, serviceName, multiFactory, regKey); + } + + /** Creates a factory for the given class. + + @return returns a factory object + @param implClass the implementing class + */ + static public Object createComponentFactory( Class implClass, String serviceName ) + { + return new Factory( implClass, serviceName, null, null ); + } + + /** + * Writes the registration data into the registry key + * <p> + * @return success + * @param implName the name of the implementing class + * @param serviceName the service name + * @param regKey the given registry key + * @see com.sun.star.lang.XServiceInfo + */ + static public boolean writeRegistryServiceInfo(String implName, String serviceName, XRegistryKey regKey) { + boolean result = false; + + try { + XRegistryKey newKey = regKey.createKey("/" + implName + "/UNO/SERVICES"); + + newKey.createKey(serviceName); + + result = true; + } + catch (Exception ex) { + System.err.println(">>>Connection_Impl.writeRegistryServiceInfo " + ex); + } + + return result; + } + + /** Writes the registration data into the registry key. + * Several services are supported. + * + * @param impl_name name of implementation + * @param supported_services supported services of implementation + * @param xKey registry key to write to + * @return success + */ + public static boolean writeRegistryServiceInfo( + String impl_name, String supported_services [], XRegistryKey xKey ) + { + try + { + XRegistryKey xNewKey = xKey.createKey( "/" + impl_name + "/UNO/SERVICES" ); + for ( int nPos = 0; nPos < supported_services.length; ++nPos ) + { + xNewKey.createKey( supported_services[ nPos ] ); + } + return true; + } + catch (com.sun.star.registry.InvalidRegistryException exc) + { + if (DEBUG) + { + System.err.println( + "##### " + Factory.class.getName() + ".writeRegistryServiceInfo -- exc: " + + exc.toString() ); + } + } + return false; + } + +} + |