diff options
Diffstat (limited to 'jurt/com/sun/star/comp/loader')
-rw-r--r-- | jurt/com/sun/star/comp/loader/FactoryHelper.java | 564 | ||||
-rw-r--r-- | jurt/com/sun/star/comp/loader/JavaLoader.java | 483 | ||||
-rw-r--r-- | jurt/com/sun/star/comp/loader/JavaLoaderFactory.java | 104 | ||||
-rw-r--r-- | jurt/com/sun/star/comp/loader/RegistrationClassFinder.java | 133 | ||||
-rw-r--r-- | jurt/com/sun/star/comp/loader/makefile.mk | 47 |
5 files changed, 1331 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; + } + +} + diff --git a/jurt/com/sun/star/comp/loader/JavaLoader.java b/jurt/com/sun/star/comp/loader/JavaLoader.java new file mode 100644 index 000000000000..47723b208497 --- /dev/null +++ b/jurt/com/sun/star/comp/loader/JavaLoader.java @@ -0,0 +1,483 @@ +/************************************************************************* + * + * 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.Method; + +import java.lang.reflect.InvocationTargetException; + +import java.net.URLDecoder; + +import com.sun.star.loader.CannotActivateFactoryException; +import com.sun.star.loader.XImplementationLoader; + +import com.sun.star.registry.CannotRegisterImplementationException; +import com.sun.star.registry.XRegistryKey; + +import com.sun.star.lang.XSingleComponentFactory; +import com.sun.star.lang.XSingleServiceFactory; +import com.sun.star.lang.XMultiServiceFactory; +import com.sun.star.lang.XServiceInfo; +import com.sun.star.lang.XInitialization; + +import com.sun.star.uno.XComponentContext; +import com.sun.star.beans.XPropertySet; +import com.sun.star.util.XMacroExpander; + +import com.sun.star.uno.Type; +import com.sun.star.uno.UnoRuntime; + +import com.sun.star.lib.util.StringHelper; + +import com.sun.star.uno.AnyConverter; + + +/** + * The <code>JavaLoader</code> class provides the functionality of the <code>com.sun.star.loader.Java</code> + * service. Therefor the <code>JavaLoader</code> activates external UNO components which are implemented in Java. + * The loader is used by the <code>ServiceManger</code>. + * <p> + * @version $Revision: 1.16 $ $ $Date: 2008-04-11 11:10:31 $ + * @author Markus Herzog + * @see com.sun.star.loader.XImplementationLoader + * @see com.sun.star.loader.Java + * @see com.sun.star.comp.servicemanager.ServiceManager + * @see com.sun.star.lang.ServiceManager + * @since UDK1.0 + */ +public class JavaLoader implements XImplementationLoader, + XServiceInfo, + XInitialization +{ + private static final boolean DEBUG = false; + + private static final void DEBUG(String dbg) { + if (DEBUG) System.err.println( dbg ); + } + + private static String[] supportedServices = { + "com.sun.star.loader.Java" + }; + + protected XMultiServiceFactory multiServiceFactory = null; + + private XMacroExpander m_xMacroExpander = null; + private static final String EXPAND_PROTOCOL_PREFIX = "vnd.sun.star.expand:"; + + /** Expands macrofied url using the macro expander singleton. + */ + private String expand_url( String url ) throws RuntimeException + { + if (url != null && url.startsWith( EXPAND_PROTOCOL_PREFIX )) + { + try + { + if (m_xMacroExpander == null) + { + XPropertySet xProps = + UnoRuntime.queryInterface( + XPropertySet.class, multiServiceFactory ); + if (xProps == null) + { + throw new com.sun.star.uno.RuntimeException( + "service manager does not support XPropertySet!", + this ); + } + XComponentContext xContext = (XComponentContext) + AnyConverter.toObject( + new Type( XComponentContext.class ), + xProps.getPropertyValue( "DefaultContext" ) ); + m_xMacroExpander = (XMacroExpander)AnyConverter.toObject( + new Type( XMacroExpander.class ), + xContext.getValueByName( + "/singletons/com.sun.star.util.theMacroExpander" ) + ); + } + // decode uric class chars + String macro = URLDecoder.decode( + StringHelper.replace( + url.substring( EXPAND_PROTOCOL_PREFIX.length() ), + '+', "%2B" ) ); + // expand macro string + String ret = m_xMacroExpander.expandMacros( macro ); + if (DEBUG) + { + System.err.println( + "JavaLoader.expand_url(): " + url + " => " + + macro + " => " + ret ); + } + return ret; + } + catch (com.sun.star.uno.Exception exc) + { + throw new com.sun.star.uno.RuntimeException( + exc.getMessage(), this ); + } + catch (java.lang.Exception exc) + { + throw new com.sun.star.uno.RuntimeException( + exc.getMessage(), this ); + } + } + return url; + } + + /** default constructor + */ + + /** + * Creates a new instance of the <code>JavaLoader</code> class. + * <p> + * @return new instance + */ + public JavaLoader() {} + + /** + * Creates a new <code>JavaLoader</code> object. The specified <code>com.sun.star.lang.XMultiServiceFactory</code> + * is the <code>ServiceManager</code> service which can be deliviert to all components the <code>JavaLoader</code> is + * loading. + * To set the <code>MultiServiceFactory</code> you can use the <code>com.sun.star.lang.XInitialization</code> interface, either. + * <p> + * @return new instance + * @param factory the <code>ServiceManager</code> + * @see com.sun.star.lang.ServiceManager + * @see com.sun.star.lang.ServiceManager + * @see com.sun.star.lang.XInitialization + */ + public JavaLoader(XMultiServiceFactory factory) { + multiServiceFactory = factory; + } + + /** + * Unlike the original intention, the method could be called every time a new + * <code>com.sun.star.lang.XMultiServiceFactory</code> should be set at the loader. + * <p> + * @param args - the first parameter (args[0]) specifices the <code>ServiceManager</code> + * @see com.sun.star.lang.XInitialization + * @see com.sun.star.lang.ServiceManager + */ + public void initialize( java.lang.Object[] args ) + throws com.sun.star.uno.Exception, + com.sun.star.uno.RuntimeException + { + if (args.length == 0) throw new com.sun.star.lang.IllegalArgumentException("No arguments specified"); + + try { + multiServiceFactory = (XMultiServiceFactory) AnyConverter.toObject( + new Type(XMultiServiceFactory.class), args[0]); + } + catch (ClassCastException castEx) { + throw new com.sun.star.lang.IllegalArgumentException( + "The argument must be an instance of XMultiServiceFactory"); + } + } + + /** + * Supplies the implementation name of the component. + * <p> + * @return the implementation name - here the class name + * @see com.sun.star.lang.XServiceInfo + */ + public String getImplementationName() + throws com.sun.star.uno.RuntimeException + { + return getClass().getName(); + } + + /** + * Verifies if a given service is supported by the component. + * <p> + * @return true,if service is suported - otherwise false + * @param serviceName the name of the service that should be checked + * @see com.sun.star.lang.XServiceInfo + */ + public boolean supportsService(String serviceName) + throws com.sun.star.uno.RuntimeException + { + for ( int i = 0; i < supportedServices.length; i++ ) { + if ( supportedServices[i].equals(serviceName) ) + return true; + } + return false; + } + + /** + * Supplies a list of all service names supported by the component + * <p> + * @return a String array with all supported services + * @see com.sun.star.lang.XServiceInfo + */ + public String[] getSupportedServiceNames() + throws com.sun.star.uno.RuntimeException + { + return supportedServices; + } + + /** + * Provides a components factory. + * The <code>JavaLoader</code> tries to load the class first. If a loacation URL is given the + * RegistrationClassFinder is used to load the class. Otherwise the class is loaded thru the Class.forName + * method. + * To get the factory the inspects the class for the optional static member functions __getServiceFactory resp. + * getServiceFactory (DEPRECATED). + * If the function can not be found a default factory @see ComponentFactoryWrapper will be created. + * <p> + * @return the factory for the component (@see com.sun.star.lang.XSingleServiceFactory) + * @param implementationName the implementation (class) name of the component + * @param implementationLoaderUrl the URL of the implementation loader. Not used. + * @param locationUrl points to an archive (JAR file) which contains a component + * @param xKey + * @see com.sun.star.lang.XImplementationLoader + * @see com.sun.star.com.loader.RegistrationClassFinder + */ + public java.lang.Object activate( String implementationName, + String implementationLoaderUrl, + String locationUrl, + XRegistryKey xKey ) + throws CannotActivateFactoryException, + com.sun.star.uno.RuntimeException + { + locationUrl = expand_url( locationUrl ); + + Object returnObject = null; + Class clazz = null; + + DEBUG("try to get factory for " + implementationName); + + // first we must get the class of the implementation + // 1. If a location URL is given it is assumed that this points to a JAR file. + // The components class name is stored in the manifest file. + // 2. If only the implementation name is given, the class is loaded with the + // Class.forName() method. This is a hack to load bootstrap components. + // Normally a string must no be null. + try { + if ( locationUrl != null ) { + // 1. + clazz = RegistrationClassFinder.find( locationUrl ); + } + else { + // 2. + clazz = Class.forName( implementationName ); + } + } + catch (java.net.MalformedURLException e) { + CannotActivateFactoryException cae = new CannotActivateFactoryException( + "Can not activate factory because " + e.toString() ); + cae.fillInStackTrace(); + throw cae; + } + catch (java.io.IOException e) { + CannotActivateFactoryException cae = new CannotActivateFactoryException( + "Can not activate factory because " + e.toString() ); + cae.fillInStackTrace(); + throw cae; + } + catch (java.lang.ClassNotFoundException e) { + CannotActivateFactoryException cae = new CannotActivateFactoryException( + "Can not activate factory because " + e.toString() ); + cae.fillInStackTrace(); + throw cae; + } + + if (null == clazz) + { + CannotActivateFactoryException cae = + new CannotActivateFactoryException( + "Cannot determine activation class!" ); + cae.fillInStackTrace(); + throw cae; + } + + Class[] paramTypes = {String.class, XMultiServiceFactory.class, XRegistryKey.class}; + Object[] params = { implementationName, multiServiceFactory, xKey }; + + // try to get factory from implemetation class + // latest style: use the public static method __getComponentFactory + // - new style: use the public static method __getServiceFactory + // - old style: use the public static method getServiceFactory ( DEPRECATED ) + + Method compfac_method = null; + try + { + compfac_method = clazz.getMethod( + "__getComponentFactory", new Class [] { String.class } ); + } + catch ( NoSuchMethodException noSuchMethodEx) {} + catch ( SecurityException secEx) {} + + Method method = null; + if (null == compfac_method) + { + try { + method = clazz.getMethod("__getServiceFactory", paramTypes); + } + catch ( NoSuchMethodException noSuchMethodEx) { + method = null; + } + catch ( SecurityException secEx) { + method = null; + } + } + + try { + if (null != compfac_method) + { + Object ret = compfac_method.invoke( clazz, new Object [] { implementationName } ); + if (null == ret || !(ret instanceof XSingleComponentFactory)) + { + throw new CannotActivateFactoryException( + "No factory object for " + implementationName ); + } + return (XSingleComponentFactory)ret; + } + else + { + if ( method == null ) { + method = clazz.getMethod("getServiceFactory", paramTypes); + } + + Object oRet = method.invoke(clazz, params); + + if ( (oRet != null) && (oRet instanceof XSingleServiceFactory) ) { + returnObject = (XSingleServiceFactory) oRet; + } + } + } + catch ( NoSuchMethodException e) { + throw new CannotActivateFactoryException("Can not activate the factory for " + + implementationName + " because " + e.toString() ); + } + catch ( SecurityException e) { + throw new CannotActivateFactoryException("Can not activate the factory for " + + implementationName + " because " + e.toString() ); + } + catch ( IllegalAccessException e ) { + throw new CannotActivateFactoryException("Can not activate the factory for " + + implementationName + " because " + e.toString() ); + } + catch ( IllegalArgumentException e ) { + throw new CannotActivateFactoryException("Can not activate the factory for " + + implementationName + " because " + e.toString() ); + } + catch ( InvocationTargetException e ) { + throw new CannotActivateFactoryException("Can not activate the factory for " + + implementationName + " because " + e.getTargetException().toString() ); + } + + return returnObject; + } + + /** + * Registers the component in a registry under a given root key. If the component supports the optional + * methods __writeRegistryServiceInfo, writeRegistryServiceInfo (DEPRECATED), the call is delegated to that + * method. Otherwise a default registration will be accomplished. + * <p> + * @return true if registration is successfully - otherwise false + * @param regKey the root key under that the component should be registred. + * @param implementationLoaderUrl specifies the loader, the component is loaded by. + * @param locationUrl points to an archive (JAR file) which contains a component + * @see ComponentFactoryWrapper + */ + public boolean writeRegistryInfo( XRegistryKey regKey, + String implementationLoaderUrl, + String locationUrl ) + throws CannotRegisterImplementationException, + com.sun.star.uno.RuntimeException + { + locationUrl = expand_url( locationUrl ); + + boolean success = false; + + try { + + Class clazz = RegistrationClassFinder.find(locationUrl); + if (null == clazz) + { + throw new CannotRegisterImplementationException( + "Cannot determine registration class!" ); + } + + Class[] paramTypes = { XRegistryKey.class }; + Object[] params = { regKey }; + + Method method = clazz.getMethod("__writeRegistryServiceInfo", paramTypes); + Object oRet = method.invoke(clazz, params); + + if ( (oRet != null) && (oRet instanceof Boolean) ) + success = ((Boolean) oRet).booleanValue(); + } + catch (Exception e) { + throw new CannotRegisterImplementationException( e.getMessage()); + } + + return success; + } + + /** + * Supplies the factory for the <code>JavaLoader</code> + * <p> + * @return the factory for the <code>JavaLoader</code> + * @param implName the name of the desired component + * @param multiFactory the <code>ServiceManager</code> is delivered to the factory + * @param regKey not used - can be null + */ + public static XSingleServiceFactory getServiceFactory( String implName, + XMultiServiceFactory multiFactory, + XRegistryKey regKey) + { + if ( implName.equals(JavaLoader.class.getName()) ) + return new JavaLoaderFactory( multiFactory ); + + return null; + } + + /** + * Registers the <code>JavaLoader</code> at the registry. + * <p> + * @return true if registration succseeded - otherwise false + * @param regKey root key under which the <code>JavaLoader</code> should be regidstered + */ + public static boolean writeRegistryServiceInfo(XRegistryKey regKey) { + boolean result = false; + + try { + XRegistryKey newKey = regKey.createKey("/" + JavaLoader.class.getName() + "/UNO/SERVICE"); + + for (int i=0; i<supportedServices.length; i++) + newKey.createKey(supportedServices[i]); + + result = true; + } + catch (Exception ex) { + if (DEBUG) System.err.println(">>>JavaLoader.writeRegistryServiceInfo " + ex); + } + + return result; + } +} + diff --git a/jurt/com/sun/star/comp/loader/JavaLoaderFactory.java b/jurt/com/sun/star/comp/loader/JavaLoaderFactory.java new file mode 100644 index 000000000000..22981f2081e3 --- /dev/null +++ b/jurt/com/sun/star/comp/loader/JavaLoaderFactory.java @@ -0,0 +1,104 @@ +/************************************************************************* + * + * 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 com.sun.star.lang.XSingleServiceFactory; +import com.sun.star.lang.XMultiServiceFactory; +import com.sun.star.lang.XServiceInfo; + + +public class JavaLoaderFactory implements XSingleServiceFactory, XServiceInfo { + + private static String[] supportedServices = { + "com.sun.star.loader.Java", + "com.sun.star.loader.Java2" + }; + + private static final boolean DEBUG = false; + + private static final void DEBUG(String dbg) { + if (DEBUG) + System.err.println(" >>> JavaLoaderFactory - " + dbg); + } + + protected XMultiServiceFactory multiServiceFactory = null; + + /** default constructor + */ +// public JavaLoaderFactory() {} + + public JavaLoaderFactory(XMultiServiceFactory factory) { + multiServiceFactory = factory; + } + + public java.lang.Object createInstance() + throws com.sun.star.uno.Exception, + com.sun.star.uno.RuntimeException + { + return new JavaLoader(multiServiceFactory); + } + + public java.lang.Object createInstanceWithArguments( java.lang.Object[] args ) + throws com.sun.star.uno.Exception, + com.sun.star.uno.RuntimeException + { + JavaLoader loader = new JavaLoader(); + loader.initialize(args); + + return loader; + } + + /** implements the XServiceInfo interface + */ + public String getImplementationName() + throws com.sun.star.uno.RuntimeException + { + return JavaLoader.class.getName(); + } + + /** implements the XServiceInfo interface + */ + public boolean supportsService(String serviceName) + throws com.sun.star.uno.RuntimeException + { + for ( int i = 0; i < supportedServices.length; i++ ) { + if ( supportedServices[i].equals(serviceName) ) + return true; + } + return false; + } + + /** implements the XServiceInfo interface + */ + public String[] getSupportedServiceNames() + throws com.sun.star.uno.RuntimeException + { + return supportedServices; + } +} + diff --git a/jurt/com/sun/star/comp/loader/RegistrationClassFinder.java b/jurt/com/sun/star/comp/loader/RegistrationClassFinder.java new file mode 100644 index 000000000000..3a40daab866b --- /dev/null +++ b/jurt/com/sun/star/comp/loader/RegistrationClassFinder.java @@ -0,0 +1,133 @@ +/************************************************************************* + * + * 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 com.sun.star.lib.unoloader.UnoClassLoader; +import com.sun.star.lib.util.WeakMap; +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.StringTokenizer; +import java.util.jar.Attributes; + +final class RegistrationClassFinder { + public static Class find(String locationUrl) + throws ClassNotFoundException, IOException + { + synchronized (map) { + Class c = (Class) WeakMap.getValue(map.get(locationUrl)); + if (c != null) { + return c; + } + } + URL url = new URL(locationUrl); + checkAccess(url); + Attributes attr = UnoClassLoader.getJarMainAttributes(url); + String name = attr == null + ? null : attr.getValue("RegistrationClassName"); + if (name == null) { + return null; + } + ClassLoader cl1 = RegistrationClassFinder.class.getClassLoader(); + ClassLoader cl2; + if (cl1 instanceof UnoClassLoader) { + cl2 = ((UnoClassLoader) cl1).getClassLoader(url, attr); + } else { + cl2 = URLClassLoader.newInstance(new URL[] { url }, cl1); + } + Class c = cl2.loadClass(name); + synchronized (map) { + Class c2 = (Class) WeakMap.getValue(map.get(locationUrl)); + if (c2 != null) { + return c2; + } + map.put(locationUrl, c); + } + return c; + } + + private RegistrationClassFinder() {} // do not instantiate + + private static void checkAccess(URL url) throws ClassNotFoundException { + // The system property com.sun.star.comp.loader.CPLD_ACCESSPATH was + // introduced as a hack to restrict which UNO components can be + // instantiated. It seems to be unused nowadays, and should probably be + // replaced by the native Java security features, anyway. + if (accessPath != null) { + if (!url.getProtocol().equals("file")) { + throw new ClassNotFoundException( + "Access restriction: <" + url + "> is not a file URL"); + } + String p; + try { + p = new File(url.getFile()).getCanonicalPath(); + } catch (IOException e) { + throw new ClassNotFoundException( + "Access restriction: <" + url + "> is bad: " + e); + } + for (int i = 0; i < accessPath.length; ++i) { + String p2 = accessPath[i]; + if (p.startsWith(p2) && p.length() > p2.length() + && (p2.charAt(p2.length() - 1) == File.separatorChar + || p.charAt(p2.length()) == File.separatorChar)) + { + return; + } + } + throw new ClassNotFoundException( + "Access restriction: <" + url + "> is restricted"); + } + } + + private static final WeakMap map = new WeakMap(); + + private static final String[] accessPath; + static { + String[] ap = null; + String p = System.getProperty( + "com.sun.star.comp.loader.CPLD_ACCESSPATH"); + if (p != null) { + StringTokenizer t = new StringTokenizer(p, ";"); + ap = new String[t.countTokens()]; + int i = 0; + while (t.hasMoreTokens()) { + try { + ap[i] = new File(t.nextToken()).getCanonicalPath(); + ++i; + } catch (IOException e) {} + } + if (i != ap.length) { + String[] ap2 = new String[i]; + System.arraycopy(ap, 0, ap2, 0, i); + ap = ap2; + } + } + accessPath = ap; + } +} diff --git a/jurt/com/sun/star/comp/loader/makefile.mk b/jurt/com/sun/star/comp/loader/makefile.mk new file mode 100644 index 000000000000..849509995ab5 --- /dev/null +++ b/jurt/com/sun/star/comp/loader/makefile.mk @@ -0,0 +1,47 @@ +#************************************************************************* +# +# 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. +# +#************************************************************************* + +PRJ = ..$/..$/..$/..$/.. +PRJNAME = jurt +PACKAGE = com$/sun$/star$/comp$/loader +TARGET = com_sun_star_comp_loader + +# --- Settings ----------------------------------------------------- + +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +JAVAFILES = \ + FactoryHelper.java \ + JavaLoader.java \ + JavaLoaderFactory.java \ + RegistrationClassFinder.java + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk |