/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ 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 getServiceFactory * and writeRegistryServiceInfo.

* * @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 protected static class Factory implements XSingleServiceFactory, XSingleComponentFactory, XServiceInfo, XTypeProvider { protected XMultiServiceFactory _xMultiServiceFactory; protected XRegistryKey _xRegistryKey; protected int _nCode; protected Constructor _constructor; protected String _implName; protected String _serviceName; 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(Object[].class)) { _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(Object[].class)) { _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(Object[].class)) { _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(Object[].class)) { _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(Object[].class)) { _nCode = 8; _constructor = constructors[i]; } else if(parameters.length == 0) { _nCode = 9; _constructor = constructors[i]; } } if(_constructor == null) // have not found a usable constructor throw new com.sun.star.uno.RuntimeException(getClass().getName() + " can not find a usable 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.getCause(); 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 ); } catch (IllegalAccessException illegalAccessException) { throw new com.sun.star.uno.Exception( illegalAccessException ); } catch (InstantiationException instantiationException) { throw new com.sun.star.uno.Exception( instantiationException ); } } 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.getCause(); 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 ); } catch (IllegalAccessException illegalAccessException) { throw new com.sun.star.uno.Exception( illegalAccessException ); } catch (InstantiationException instantiationException) { throw new com.sun.star.uno.Exception( instantiationException ); } } /** * Creates an instance of the desired service. * * @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. * * @param args the args given to the constructor of the service. * @return returns an instance of the desired 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. * * @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. * * @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. * * @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() { return new byte[0]; } //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. * * @param implClass the implementing class. * @param multiFactory the given multi service factory (service manager). * @param regKey the given registry key. * @return returns a factory. * * @see com.sun.star.lang.XServiceInfo * @deprecated as of UDK 1.0 */ @Deprecated public static XSingleServiceFactory getServiceFactory(Class implClass, XMultiServiceFactory multiFactory, XRegistryKey regKey) { XSingleServiceFactory xSingleServiceFactory = null; try { Field serviceName ; 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. * * @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. * * @return returns a factory. * @see com.sun.star.lang.XServiceInfo */ public static XSingleServiceFactory getServiceFactory(Class implClass, String serviceName, XMultiServiceFactory multiFactory, XRegistryKey regKey) { return new Factory(implClass, serviceName, multiFactory, regKey); } /** * Creates a factory for the given class. * * @param implClass the implementing class. * @return returns a factory object. */ public static Object createComponentFactory( Class implClass, String serviceName ) { return new Factory( implClass, serviceName, null, null ); } /** * Writes the registration data into the registry key. * * @param implName the name of the implementing class. * @param serviceName the service name. * @param regKey the given registry key. * @return success. * * @see com.sun.star.lang.XServiceInfo */ public static 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; } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */