diff options
Diffstat (limited to 'jurt')
116 files changed, 17414 insertions, 0 deletions
diff --git a/jurt/com/sun/star/comp/bridgefactory/BridgeFactory.java b/jurt/com/sun/star/comp/bridgefactory/BridgeFactory.java new file mode 100644 index 000000000000..a444f1813c3d --- /dev/null +++ b/jurt/com/sun/star/comp/bridgefactory/BridgeFactory.java @@ -0,0 +1,228 @@ +/************************************************************************* + * + * 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.bridgefactory; + +import java.math.BigInteger; +import java.util.Vector; + + +import com.sun.star.bridge.BridgeExistsException; +import com.sun.star.bridge.XBridge; +import com.sun.star.bridge.XBridgeFactory; +import com.sun.star.bridge.XInstanceProvider; + +import com.sun.star.comp.loader.FactoryHelper; + +import com.sun.star.connection.XConnection; + +import com.sun.star.lang.XMultiServiceFactory; +import com.sun.star.lang.XSingleServiceFactory; + +import com.sun.star.registry.XRegistryKey; + +import com.sun.star.uno.IBridge; +import com.sun.star.uno.UnoRuntime; + + +/** + * The BridgeFactory class implements the <code>XBridgeFactory</code> Interface. + * It wrapps the <code>UnoRuntime#getBridgeByName</code>method and delivers a + * XBridge component. + * <p> + * This component is only usable for remote bridges. + * <p> + * @version $Revision: 1.11 $ $ $Date: 2008-04-11 11:07:51 $ + * @author Kay Ramme + * @see com.sun.star.uno.UnoRuntime + * @since UDK1.0 + */ +public class BridgeFactory implements XBridgeFactory/*, XEventListener*/ { + static private final boolean DEBUG = false; + + /** + * The name of the service, the <code>JavaLoader</code> acceses this through reflection. + */ + public final static String __serviceName = "com.sun.star.bridge.BridgeFactory"; + + /** + * Gives a factory for creating the service. + * This method is called by the <code>JavaLoader</code> + * <p> + * @return returns a <code>XSingleServiceFactory</code> for creating the component + * @param implName the name of the implementation for which a service is desired + * @param multiFactory the service manager to be uses if needed + * @param regKey the registryKey + * @see com.sun.star.comp.loader.JavaLoader + */ + public static XSingleServiceFactory __getServiceFactory(String implName, + XMultiServiceFactory multiFactory, + XRegistryKey regKey) + { + XSingleServiceFactory xSingleServiceFactory = null; + + if (implName.equals(BridgeFactory.class.getName()) ) + xSingleServiceFactory = FactoryHelper.getServiceFactory(BridgeFactory.class, + multiFactory, + regKey); + + return xSingleServiceFactory; + } + + /** + * Writes the service information into the given registry key. + * This method is called by the <code>JavaLoader</code> + * <p> + * @return returns true if the operation succeeded + * @param regKey the registryKey + * @see com.sun.star.comp.loader.JavaLoader + */ + public static boolean __writeRegistryServiceInfo(XRegistryKey regKey) { + return FactoryHelper.writeRegistryServiceInfo(BridgeFactory.class.getName(), __serviceName, regKey); + } + + /** + * Creates a remote bridge and memorizes it under <code>sName</code>. + * <p> + * @return the bridge + * @param sName the name to memorize the bridge + * @param sProtocol the protocol the bridge should use + * @param anInstanceProvider the instance provider + * @see com.sun.star.bridge.XBridgeFactory + */ + public XBridge createBridge(String sName, String sProtocol, XConnection aConnection, XInstanceProvider anInstanceProvider) throws + BridgeExistsException, + com.sun.star.lang.IllegalArgumentException, + com.sun.star.uno.RuntimeException + { + boolean hasName = sName.length() != 0; + Object context = hasName ? (Object) sName : (Object) new UniqueToken(); + // UnoRuntime.getBridgeByName internally uses context.toString() to + // distinguish bridges, so the result of + // new UniqueToken().toString() might clash with an explicit + // sName.toString(), but the UnoRuntime bridge management is + // obsolete anyway and should be removed + + // do not create a new bridge, if one already exists + if (hasName) { + IBridge iBridges[] = UnoRuntime.getBridges(); + for(int i = 0; i < iBridges.length; ++ i) { + XBridge xBridge = UnoRuntime.queryInterface(XBridge.class, iBridges[i]); + + if(xBridge != null) { + if(xBridge.getName().equals(sName)) + throw new BridgeExistsException(sName + " already exists"); + } + } + } + + XBridge xBridge = null; + + try { + IBridge iBridge = UnoRuntime.getBridgeByName("java", context, "remote", context, hasName ? new Object[]{sProtocol, aConnection, anInstanceProvider, sName} : new Object[]{sProtocol, aConnection, anInstanceProvider}); + + xBridge = UnoRuntime.queryInterface(XBridge.class, iBridge); + } + catch(Exception exception) { + throw new com.sun.star.lang.IllegalArgumentException(exception.getMessage()); + } + + if(DEBUG) System.err.println("##### " + getClass().getName() + ".createBridge:" + sName + " " + sProtocol + " " + aConnection + " " + anInstanceProvider + " " + xBridge); + + return xBridge; + } + + /** + * Gets a remote bridge which must already exist. + * <p> + * @return the bridge + * @param sName the name of the bridge + * @see com.sun.star.bridge.XBridgeFactory + */ + public XBridge getBridge(String sName) throws com.sun.star.uno.RuntimeException { + XBridge xBridge = null; + + IBridge iBridges[] = UnoRuntime.getBridges(); + for(int i = 0; i < iBridges.length; ++ i) { + xBridge = UnoRuntime.queryInterface(XBridge.class, iBridges[i]); + + if(xBridge != null) { + if(xBridge.getName().equals(sName)) + break; + + else + xBridge = null; + } + } + + + if(DEBUG) System.err.println("##### " + getClass().getName() + ".getBridge:" + sName + " " + xBridge); + + return xBridge; + } + + /** + * Gives all created bridges + * <p> + * @return the bridges + * @see com.sun.star.bridge.XBridgeFactory + */ + public synchronized XBridge[] getExistingBridges() throws com.sun.star.uno.RuntimeException { + Vector vector = new Vector(); + + IBridge iBridges[] = UnoRuntime.getBridges(); + for(int i = 0; i < iBridges.length; ++ i) { + XBridge xBridge = UnoRuntime.queryInterface(XBridge.class, iBridges[i]); + + if(xBridge != null) + vector.addElement(xBridge); + } + + XBridge xBridges[]= new XBridge[vector.size()]; + for(int i = 0; i < vector.size(); ++ i) + xBridges[i] = (XBridge)vector.elementAt(i); + + return xBridges; + } + + private static final class UniqueToken { + public UniqueToken() { + synchronized (UniqueToken.class) { + token = counter.toString(); + counter = counter.add(BigInteger.ONE); + } + } + + public String toString() { + return token; + } + + private final String token; + private static BigInteger counter = BigInteger.ZERO; + } +} + diff --git a/jurt/com/sun/star/comp/bridgefactory/makefile.mk b/jurt/com/sun/star/comp/bridgefactory/makefile.mk new file mode 100644 index 000000000000..fa1c7345e9a1 --- /dev/null +++ b/jurt/com/sun/star/comp/bridgefactory/makefile.mk @@ -0,0 +1,43 @@ +#************************************************************************* +# +# 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$/bridgefactory +TARGET = com_sun_star_comp_bridgefactory + +# --- Settings ----------------------------------------------------- + +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +JAVAFILES = BridgeFactory.java + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/jurt/com/sun/star/comp/connections/Acceptor.java b/jurt/com/sun/star/comp/connections/Acceptor.java new file mode 100644 index 000000000000..3df51e735a1c --- /dev/null +++ b/jurt/com/sun/star/comp/connections/Acceptor.java @@ -0,0 +1,170 @@ +/************************************************************************* + * + * 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.connections; + +import com.sun.star.comp.loader.FactoryHelper; +import com.sun.star.connection.AlreadyAcceptingException; +import com.sun.star.connection.ConnectionSetupException; +import com.sun.star.connection.XAcceptor; +import com.sun.star.connection.XConnection; +import com.sun.star.lang.XMultiServiceFactory; +import com.sun.star.lang.XSingleServiceFactory; +import com.sun.star.registry.XRegistryKey; + +/** + * A component that implements the <code>XAcceptor</code> interface. + * + * <p>The <code>Acceptor</code> is a general component, that uses less general + * components (like <code>com.sun.star.connection.socketAcceptor</code>) to + * implement its functionality.</p> + * + * @see com.sun.star.connections.XAcceptor + * @see com.sun.star.connections.XConnection + * @see com.sun.star.connections.XConnector + * @see com.sun.star.loader.JavaLoader + * + * @since UDK 1.0 + */ +public final class Acceptor implements XAcceptor { + /** + * The name of the service. + * + * <p>The <code>JavaLoader</code> acceses this through reflection.</p> + * + * @see com.sun.star.comp.loader.JavaLoader + */ + public static final String __serviceName + = "com.sun.star.connection.Acceptor"; + + /** + * Returns a factory for creating the service. + * + * <p>This method is called by the <code>JavaLoader</code>.</p> + * + * @param implName the name of the implementation for which a service is + * requested. + * @param multiFactory the service manager to be used (if needed). + * @param regKey the registry key. + * @return an <code>XSingleServiceFactory</code> for creating the component. + * + * @see com.sun.star.comp.loader.JavaLoader + */ + public static XSingleServiceFactory __getServiceFactory( + String implName, XMultiServiceFactory multiFactory, XRegistryKey regKey) + { + return implName.equals(Acceptor.class.getName()) + ? FactoryHelper.getServiceFactory(Acceptor.class, __serviceName, + multiFactory, regKey) + : null; + } + + /** + * Writes the service information into the given registry key. + * + * <p>This method is called by the <code>JavaLoader</code>.</p> + * + * @param regKey the registry key. + * @return <code>true</code> if the operation succeeded. + * + * @see com.sun.star.comp.loader.JavaLoader + */ + public static boolean __writeRegistryServiceInfo(XRegistryKey regKey) { + return FactoryHelper.writeRegistryServiceInfo(Acceptor.class.getName(), + __serviceName, regKey); + } + + /** + * Constructs a new <code>Acceptor</code> that uses the given service + * factory to create a specific <code>XAcceptor</code>. + * + * @param serviceFactory the service factory to use. + */ + public Acceptor(XMultiServiceFactory serviceFactory) { + this.serviceFactory = serviceFactory; + } + + /** + * Accepts a connection request via the given connection type. + * + * <p>This call blocks until a connection has been established.</p> + * + * <p>The connection description has the following format: + * <code><var>type</var></code><!-- + * -->*(<code><var>key</var>=<var>value</var></code>). + * The specific <code>XAcceptor</code> implementation is instantiated + * through the service factory as + * <code>com.sun.star.connection.<var>type</var>Acceptor</code> (with + * <code><var>type</var></code> in lower case).</p> + * + * @param connectionDescription the description of the connection. + * @return an <code>XConnection</code> to the client. + * + * @see com.sun.star.connections.XConnection + * @see com.sun.star.connections.XConnector + */ + public XConnection accept(String connectionDescription) throws + AlreadyAcceptingException, ConnectionSetupException, + com.sun.star.lang.IllegalArgumentException + { + if (DEBUG) { + System.err.println("##### " + getClass().getName() + ".accept(" + + connectionDescription + ")"); + } + XAcceptor acc; + synchronized (this) { + if (acceptor == null) { + acceptor = (XAcceptor) Implementation.getConnectionService( + serviceFactory, connectionDescription, XAcceptor.class, + "Acceptor"); + acceptingDescription = connectionDescription; + } else if (!connectionDescription.equals(acceptingDescription)) { + throw new AlreadyAcceptingException(acceptingDescription + + " vs. " + + connectionDescription); + } + acc = acceptor; + } + return acc.accept(connectionDescription); + } + + // see com.sun.star.connection.XAcceptor#stopAccepting + public void stopAccepting() { + XAcceptor acc; + synchronized (this) { + acc = acceptor; + } + acc.stopAccepting(); + } + + private static final boolean DEBUG = false; + + private final XMultiServiceFactory serviceFactory; + + private XAcceptor acceptor = null; + private String acceptingDescription; +} diff --git a/jurt/com/sun/star/comp/connections/Connector.java b/jurt/com/sun/star/comp/connections/Connector.java new file mode 100644 index 000000000000..c02db5c52b8b --- /dev/null +++ b/jurt/com/sun/star/comp/connections/Connector.java @@ -0,0 +1,151 @@ +/************************************************************************* + * + * 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.connections; + +import com.sun.star.comp.loader.FactoryHelper; +import com.sun.star.connection.ConnectionSetupException; +import com.sun.star.connection.NoConnectException; +import com.sun.star.connection.XConnection; +import com.sun.star.connection.XConnector; +import com.sun.star.lang.XMultiServiceFactory; +import com.sun.star.lang.XSingleServiceFactory; +import com.sun.star.registry.XRegistryKey; + +/** + * A component that implements the <code>XConnector</code> interface. + * + * <p>The <code>Connector</code> is a general component, that uses less general + * components (like <code>com.sun.star.connection.socketConnector</code>) to + * implement its functionality.</p> + * + * @see com.sun.star.connections.XAcceptor + * @see com.sun.star.connections.XConnection + * @see com.sun.star.connections.XConnector + * @see com.sun.star.loader.JavaLoader + * + * @since UDK 1.0 + */ +public class Connector implements XConnector { + /** + * The name of the service. + * + * <p>The <code>JavaLoader</code> acceses this through reflection.</p> + * + * @see com.sun.star.comp.loader.JavaLoader + */ + public static final String __serviceName + = "com.sun.star.connection.Connector"; + + /** + * Returns a factory for creating the service. + * + * <p>This method is called by the <code>JavaLoader</code>.</p> + * + * @param implName the name of the implementation for which a service is + * requested. + * @param multiFactory the service manager to be used (if needed). + * @param regKey the registry key. + * @return an <code>XSingleServiceFactory</code> for creating the component. + * + * @see com.sun.star.comp.loader.JavaLoader + */ + public static XSingleServiceFactory __getServiceFactory( + String implName, XMultiServiceFactory multiFactory, XRegistryKey regKey) + { + return implName.equals(Connector.class.getName()) + ? FactoryHelper.getServiceFactory(Connector.class, __serviceName, + multiFactory, regKey) + : null; + } + + /** + * Writes the service information into the given registry key. + * + * <p>This method is called by the <code>JavaLoader</code>.</p> + * + * @param regKey the registry key. + * @return <code>true</code> if the operation succeeded. + * + * @see com.sun.star.comp.loader.JavaLoader + */ + public static boolean __writeRegistryServiceInfo(XRegistryKey regKey) { + return FactoryHelper.writeRegistryServiceInfo(Connector.class.getName(), + __serviceName, regKey); + } + + /** + * Constructs a new <code>Connector</code> that uses the given service + * factory to create a specific <code>XConnector</code>. + * + * @param serviceFactory the service factory to use. + */ + public Connector(XMultiServiceFactory serviceFactory) { + this.serviceFactory = serviceFactory; + } + + /** + * Connects via the given connection type to a waiting server. + * + * <p>The connection description has the following format: + * <code><var>type</var></code><!-- + * -->*(<code><var>key</var>=<var>value</var></code>). + * The specific <code>XConnector</code> implementation is instantiated + * through the service factory as + * <code>com.sun.star.connection.<var>type</var>Connector</code> (with + * <code><var>type</var></code> in lower case).</p> + * + * @param connectionDescription the description of the connection. + * @return an <code>XConnection</code> to the server. + * + * @see com.sun.star.connections.XAcceptor + * @see com.sun.star.connections.XConnection + */ + public synchronized XConnection connect(String connectionDescription) + throws NoConnectException, ConnectionSetupException + { + if (DEBUG) { + System.err.println("##### " + getClass().getName() + ".connect(" + + connectionDescription + ")"); + } + if (connected) { + throw new ConnectionSetupException("already connected"); + } + XConnection con + = ((XConnector) Implementation.getConnectionService( + serviceFactory, connectionDescription, XConnector.class, + "Connector")).connect(connectionDescription); + connected = true; + return con; + } + + private static final boolean DEBUG = false; + + private final XMultiServiceFactory serviceFactory; + + private boolean connected = false; +} diff --git a/jurt/com/sun/star/comp/connections/ConstantInstanceProvider.java b/jurt/com/sun/star/comp/connections/ConstantInstanceProvider.java new file mode 100644 index 000000000000..f63eeadf10d8 --- /dev/null +++ b/jurt/com/sun/star/comp/connections/ConstantInstanceProvider.java @@ -0,0 +1,139 @@ +/************************************************************************* + * + * 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.connections; + +import com.sun.star.bridge.XInstanceProvider; + +import com.sun.star.lang.XMultiServiceFactory; +import com.sun.star.lang.XSingleServiceFactory; + +import com.sun.star.registry.XRegistryKey; + +import com.sun.star.comp.loader.FactoryHelper; + + +/** + * The <code>ConstantInstanceProvider</code> is a component + * that implements the <code>XInstanceProvider</code> Interface. + * <p> + * @version $Revision: 1.3 $ $ $Date: 2008-04-11 11:08:55 $ + * @author Kay Ramme + * @see com.sun.star.bridge.XBridge + * @see com.sun.star.bridge.XBridgeFactory + * @see com.sun.star.bridge.XInstanceProvider + * @see com.sun.star.loader.JavaLoader + * @since UDK1.0 + */ +public class ConstantInstanceProvider implements XInstanceProvider { + /** + * When set to true, enables various debugging output. + */ + static public final boolean DEBUG = false; + + /** + * The name of the service, the <code>JavaLoader</code> acceses this through reflection. + */ + static private final String __serviceName = "com.sun.star.comp.connection.InstanceProvider"; + + /** + * Gives a factory for creating the service. + * This method is called by the <code>JavaLoader</code> + * <p> + * @return returns a <code>XSingleServiceFactory</code> for creating the component + * @param implName the name of the implementation for which a service is desired + * @param multiFactory the service manager to be uses if needed + * @param regKey the registryKey + * @see com.sun.star.comp.loader.JavaLoader + */ + public static XSingleServiceFactory __getServiceFactory(String implName, + XMultiServiceFactory multiFactory, + XRegistryKey regKey) + { + XSingleServiceFactory xSingleServiceFactory = null; + + if (implName.equals(ConstantInstanceProvider.class.getName()) ) + xSingleServiceFactory = FactoryHelper.getServiceFactory(ConstantInstanceProvider.class, + __serviceName, + multiFactory, + regKey); + + return xSingleServiceFactory; + } + + /** + * Writes the service information into the given registry key. + * This method is called by the <code>JavaLoader</code> + * <p> + * @return returns true if the operation succeeded + * @param regKey the registryKey + * @see com.sun.star.comp.loader.JavaLoader + */ + public static boolean __writeRegistryServiceInfo(XRegistryKey regKey) { + return FactoryHelper.writeRegistryServiceInfo(ConstantInstanceProvider.class.getName(), __serviceName, regKey); + } + + + + protected XMultiServiceFactory _serviceManager; + protected String _serviceName; + protected Object _instance; + + + public void setInstance(String serviceName) throws com.sun.star.uno.Exception { + _instance = _serviceManager.createInstance(serviceName); + _serviceName = serviceName; + } + + /** + * Constructs a new <code>ConstantInstanceProvider</code>. + * Uses the provided ServiceManager as the provided instance. + * <p> + * @param serviceName the provided service manager + */ + public ConstantInstanceProvider(XMultiServiceFactory serviceManager) { + _serviceManager = serviceManager; + + _serviceName = "SERVICEMANAGER"; + _instance = serviceManager; + } + + /** + * Gives an object for the passed instance name. + * <p> + * @return the desired instance + * @param sInstanceName the name of the desired instance + */ + public Object getInstance(String sInstanceName) throws com.sun.star.container.NoSuchElementException, com.sun.star.uno.RuntimeException { + Object result = sInstanceName.equals(_serviceName) ? _instance : null; + + if(DEBUG) System.err.println("##### " + getClass().getName() + ".getInstance(" + sInstanceName + "):" + result); + + return result; + } +} + diff --git a/jurt/com/sun/star/comp/connections/Implementation.java b/jurt/com/sun/star/comp/connections/Implementation.java new file mode 100644 index 000000000000..466ea9741766 --- /dev/null +++ b/jurt/com/sun/star/comp/connections/Implementation.java @@ -0,0 +1,101 @@ +/************************************************************************* + * + * 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.connections; + +import com.sun.star.connection.ConnectionSetupException; +import com.sun.star.lang.XMultiServiceFactory; +import com.sun.star.uno.UnoRuntime; + +/** + * Helper class for <code>Acceptor</code> and <code>Connector</code>. + */ +final class Implementation { + /** + * Instantiate a service for a given connection type. + * + * @param factory the service factory used to instantiate the requested + * service. + * @param description has the following format: + * <code><var>type</var></code><!-- + * -->*(<code><var>key</var>=<var>value</var></code>). + * The specific service implementation is instantiated through the + * service factory as + * <code>com.sun.star.connection.<var>type</var>service<var></var><!-- + * --></code> + * (with <code><var>type</var></code> in lower case, and + * <code><var>service</var></code> either <code>Acceptor</code> or + * <code>Connector</code>).</p> + * @param serviceClass the IDL interface type for which to query the + * requested service. + * @param serviceType must be either <code>Acceptor</code> or + * <code>Connector</code>. + * @return an instance of the requested service. Never returns + * <code>null</code>. + * @throws ConnectionSetupException if the requested service can not be + * found, or cannot be instantiated. + */ + public static Object getConnectionService(XMultiServiceFactory factory, + String description, + Class serviceClass, + String serviceType) + throws ConnectionSetupException + { + int i = description.indexOf(','); + String type + = (i < 0 ? description : description.substring(0, i)).toLowerCase(); + Object service = null; + try { + service = UnoRuntime.queryInterface( + serviceClass, + factory.createInstance("com.sun.star.connection." + type + + serviceType)); + } catch (RuntimeException e) { + throw e; + } catch (com.sun.star.uno.Exception e) { + } + if (service == null) { + // As a fallback, also try to instantiate the service from the + // com.sun.star.lib.connections package structure: + try { + service + = Class.forName("com.sun.star.lib.connections." + type + + "." + type + serviceType).newInstance(); + } catch (ClassNotFoundException e) { + } catch (IllegalAccessException e) { + } catch (InstantiationException e) { + } + } + if (service == null) { + throw new ConnectionSetupException("no " + serviceType + " for " + + type); + } + return service; + } + + private Implementation() {} // do not instantiate +} diff --git a/jurt/com/sun/star/comp/connections/PipedConnection.java b/jurt/com/sun/star/comp/connections/PipedConnection.java new file mode 100644 index 000000000000..630adf4e223b --- /dev/null +++ b/jurt/com/sun/star/comp/connections/PipedConnection.java @@ -0,0 +1,283 @@ +/************************************************************************* + * + * 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.connections; + + +import com.sun.star.comp.loader.FactoryHelper; + +import com.sun.star.connection.XConnection; + +import com.sun.star.lang.XMultiServiceFactory; +import com.sun.star.lang.XSingleServiceFactory; + +import com.sun.star.registry.XRegistryKey; + +/** + * The PipedConnection is a component that implements the + * <code>XConnection</code> Interface. + * It is useful for <code>Thread</code> communication + * in one Process. + * <p> + * @version $Revision: 1.3 $ $ $Date: 2008-04-11 11:09:30 $ + * @author Kay Ramme + * @see com.sun.star.connections.XConnection + * @see com.sun.star.loader.JavaLoader + * @since UDK1.0 + */ +public class PipedConnection implements XConnection { + /** + * When set to true, enables various debugging output. + */ + public static final boolean DEBUG = false; + + /** + * The name of the service, the <code>JavaLoader</code> acceses this through reflection. + */ + static private final String __serviceName = "com.sun.star.connection.PipedConnection"; + + /** + * Gives a factory for creating the service. + * This method is called by the <code>JavaLoader</code> + * <p> + * @return returns a <code>XSingleServiceFactory</code> for creating the component + * @param implName the name of the implementation for which a service is desired + * @param multiFactory the service manager to be uses if needed + * @param regKey the registryKey + * @see com.sun.star.comp.loader.JavaLoader + */ + public static XSingleServiceFactory __getServiceFactory(String implName, + XMultiServiceFactory multiFactory, + XRegistryKey regKey) + { + XSingleServiceFactory xSingleServiceFactory = null; + + if (implName.equals(PipedConnection.class.getName()) ) + xSingleServiceFactory = FactoryHelper.getServiceFactory(PipedConnection.class, + __serviceName, + multiFactory, + regKey); + + return xSingleServiceFactory; + } + + /** + * Writes the service information into the given registry key. + * This method is called by the <code>JavaLoader</code> + * <p> + * @return returns true if the operation succeeded + * @param regKey the registryKey + * @see com.sun.star.comp.loader.JavaLoader + */ + public static boolean __writeRegistryServiceInfo(XRegistryKey regKey) { + return FactoryHelper.writeRegistryServiceInfo(PipedConnection.class.getName(), __serviceName, regKey); + } + + + /** + * The amount of time in milliseconds, to wait to + * see check the buffers. + */ + protected static final int __waitTime = 10000; + + protected byte _buffer[] = new byte[4096]; + protected int _in, + _out; + protected boolean _closed; + protected PipedConnection _otherSide; + + /** + * Constructs a new <code>PipedConnection</code>, sees if there + * is an other side, which it should be connected to. + * <p> + * @param args Another side could be in index 0. + */ + public PipedConnection(Object args[]) throws com.sun.star.uno.RuntimeException { + if (DEBUG) System.err.println("##### " + getClass().getName() + " - instantiated"); + + _otherSide = (args.length == 1) ? (PipedConnection)args[0] : null; + if(_otherSide != null) { + if(_otherSide == this) + throw new RuntimeException("can not connect to myself"); + + _otherSide._otherSide = this; + } + } + + /** + * This is a private method, used to cummunicate + * internal in the pipe. + */ + private synchronized void receive(byte aData[]) throws com.sun.star.io.IOException { + int bytesWritten = 0; + + if(DEBUG) System.err.println("##### PipedConnection.receive - bytes:" + aData.length + " at:" + _out); + + while(bytesWritten < aData.length) { + // wait until it is not full anymore + while(_out == (_in - 1) || (_in == 0 && _out == _buffer.length - 1)) { + try { + notify(); // the buffer is full, signal it + + wait(__waitTime); + } + catch(InterruptedException interruptedException) { + throw new com.sun.star.io.IOException(interruptedException.toString()); + } + } + + if(_closed) throw new com.sun.star.io.IOException("connection has been closed"); + + int bytes = 0; + + if(_out < _in) { + bytes = Math.min(aData.length - bytesWritten, _in - _out - 1); + + System.arraycopy(aData, bytesWritten, _buffer, _out, bytes); + } + else { + if(_in > 0){ + bytes = Math.min(aData.length - bytesWritten, _buffer.length - _out); + } + else { + bytes = Math.min(aData.length - bytesWritten, _buffer.length - _out - 1); + } + + System.arraycopy(aData, bytesWritten, _buffer, _out, bytes); + } + + bytesWritten += bytes; + _out += bytes; + if(_out >= _buffer.length) + _out = 0; + } + } + + /** + * Read the required number of bytes. + * <p> + * @return the number of bytes read + * @param aReadBytes the outparameter, where the bytes have to be placed + * @param nBytesToRead the number of bytes to read + * @see com.sun.star.connections.XConnection#read + */ + public synchronized int read(/*OUT*/byte[][] aReadBytes, int nBytesToRead) throws com.sun.star.io.IOException, com.sun.star.uno.RuntimeException { + aReadBytes[0] = new byte[nBytesToRead]; + + if(DEBUG) System.err.println("##### PipedConnection.read - bytes:" + nBytesToRead + " at:" + _in); + + // loop while not all bytes read or when closed but there is still data + while(nBytesToRead > 0 && (_in != _out || !_closed)) { + while(_in == _out && !_closed) { + try { + notify(); // the buffer is empty, signal it + + wait(__waitTime); // we wait for data or for the pipe to be closed + } + catch(InterruptedException interruptedException) { + throw new com.sun.star.io.IOException(interruptedException.toString()); + } + } + + if(_in < _out) { + int bytes = Math.min(nBytesToRead, _out - _in); + + System.arraycopy(_buffer, _in, aReadBytes[0], aReadBytes[0].length - nBytesToRead, bytes); + + nBytesToRead -= bytes; + _in += bytes; + } + else if(_in > _out) { + int bytes = Math.min(nBytesToRead, _buffer.length - _in); + + System.arraycopy(_buffer, _in, aReadBytes[0], aReadBytes[0].length - nBytesToRead, bytes); + + nBytesToRead -= bytes; + _in += bytes; + if(_in >= _buffer.length) + _in = 0; + } + } + + if(nBytesToRead > 0) { // not all bytes read + byte tmp[] = new byte[aReadBytes[0].length - nBytesToRead]; + System.arraycopy(aReadBytes[0], 0, tmp, 0, tmp.length); + + aReadBytes[0] = tmp; + } + + return aReadBytes[0].length; + } + + /** + * Write bytes. + * <p> + * @param aData the bytes to write + * @see com.sun.star.connections.XConnection#write + */ + public void write(byte aData[]) throws com.sun.star.io.IOException, com.sun.star.uno.RuntimeException { + _otherSide.receive(aData); + } + + /** + * Flushes the buffer, notifies if necessary the other side that new data has arrived. + * <p> + * @see com.sun.star.connections.XConnection#flush + */ + public void flush() throws com.sun.star.io.IOException, com.sun.star.uno.RuntimeException { + synchronized(_otherSide) { + _otherSide.notify(); + } + } + + /** + * Closes the pipe. + * <p> + * @see com.sun.star.connections.XConnection#closed + */ + public synchronized void close() throws com.sun.star.io.IOException, com.sun.star.uno.RuntimeException { + if(!_closed) { + _closed = true; + + _otherSide.close(); + + notify(); + } + } + + /** + * Gives a description of this pipe. + * <p> + * @return the description + * @see com.sun.star.connections.XConnection#getDescription + */ + public String getDescription() throws com.sun.star.uno.RuntimeException { + return getClass().getName(); + } + +} + diff --git a/jurt/com/sun/star/comp/connections/makefile.mk b/jurt/com/sun/star/comp/connections/makefile.mk new file mode 100644 index 000000000000..99141108c7d9 --- /dev/null +++ b/jurt/com/sun/star/comp/connections/makefile.mk @@ -0,0 +1,43 @@ +#************************************************************************* +# +# 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 +TARGET = com_sun_star_comp_connections + +PACKAGE = com$/sun$/star$/comp$/connections + +.INCLUDE: $(PRJ)$/util$/makefile.pmk + +JAVAFILES = \ + Acceptor.java \ + Connector.java \ + ConstantInstanceProvider.java \ + Implementation.java \ + PipedConnection.java + +.INCLUDE: target.mk 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 diff --git a/jurt/com/sun/star/comp/servicemanager/ServiceManager.java b/jurt/com/sun/star/comp/servicemanager/ServiceManager.java new file mode 100644 index 000000000000..3d672c6dfddf --- /dev/null +++ b/jurt/com/sun/star/comp/servicemanager/ServiceManager.java @@ -0,0 +1,926 @@ +/************************************************************************* + * + * 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.servicemanager; + +import com.sun.star.uno.UnoRuntime; +import com.sun.star.uno.XComponentContext; + +import com.sun.star.container.XSet; +import com.sun.star.container.XContentEnumerationAccess; +import com.sun.star.container.XEnumeration; + +import com.sun.star.lang.XComponent; +import com.sun.star.lang.XEventListener; +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.XMultiComponentFactory; + +import com.sun.star.registry.XRegistryKey; +import com.sun.star.registry.XSimpleRegistry; + +import com.sun.star.loader.XImplementationLoader; + +import java.lang.reflect.InvocationTargetException; + +/** + * The <code>ServiceManager</code> class is an implmentation of the <code>ServiceManager</code>the central class needed for + * implementing or using UNO components in Java. + * <p> + * The Methods <code>queryInterface</code> and <code>isSame</code> delegate + * calls to the implementing objects and are used instead of casts + * and identity comparisons. + * <p> + * @version $Revision: 1.10 $ $ $Date: 2008-04-11 11:11:46 $ + * @author Markus Herzog + * @see com.sun.star.lang.XMultiServiceFactory + * @see com.sun.star.container.XSet + * @see com.sun.star.container.XContentEnumerationAccess + * @see com.sun.star.lang.XComponent + * @see com.sun.star.lang.XServiceInfo + * @see com.sun.star.lang.XInitialization + * @since UDK1.0 + */ +public class ServiceManager implements XMultiServiceFactory, + XMultiComponentFactory, + XSet, + XContentEnumerationAccess, + XComponent, + XServiceInfo, + XInitialization +{ + private static final boolean DEBUG = false; + + private static final void DEBUG (String dbg) { + if (DEBUG) System.err.println( dbg ); + } + + private static com.sun.star.uno.Type UNO_TYPE = null; + + XImplementationLoader loader = null; + + static String[] supportedServiceNames = { + "com.sun.star.lang.MultiServiceFactory", + "com.sun.star.lang.ServiceManager" + }; + + java.util.Vector eventListener; + java.util.Hashtable factoriesByImplNames; + java.util.Hashtable factoriesByServiceNames; // keys: + + private com.sun.star.uno.XComponentContext m_xDefaultContext; + + /** + * Creates a new instance of the <code>ServiceManager</code>. + */ + public ServiceManager() { + eventListener = new java.util.Vector(); + factoriesByImplNames = new java.util.Hashtable(); + factoriesByServiceNames = new java.util.Hashtable(); + m_xDefaultContext = null; + } + /** + * Creates a new instance of the <code>ServiceManager</code>. + */ + public ServiceManager( XComponentContext xContext ) { + eventListener = new java.util.Vector(); + factoriesByImplNames = new java.util.Hashtable(); + factoriesByServiceNames = new java.util.Hashtable(); + m_xDefaultContext = xContext; + } + + /** + * Returns the service factory for the <code>ServiceManager</code>. If the given implementation name + * does not equal to the <code>ServiceManagers</code> class name null will be returned. + * <p> + * @return the factory for the <code>ServiceManager</code>. + * @param implName the implementation name of the of the service. + * Must be equal to <code>com.sun.star.comp.servicemanager.ServicManager</code> + * @param multiFactory refernce of the <code>MultiServiceFactory</code>. This parameter will be ignored. + * @param regKey the root key of the registry. This parameter will be ignored. + */ + public static XSingleServiceFactory getServiceFactory( String implName, + XMultiServiceFactory multiFactory, + XRegistryKey regKey) + { + if ( implName.equals(ServiceManager.class.getName()) ) + return new ServiceManagerFactory(); + + return null; + } + + + /** + * Supplies a Java component loader. The loader component must be enlisted at the <code>ServiceManager</code> before. + * <p> + * @return a new instance of the Java component loader + * @see com.sun.star.loader.Java + */ + private XImplementationLoader getLoader() + throws com.sun.star.uno.Exception, + com.sun.star.uno.RuntimeException + { + Object[] param = { this }; + DEBUG("make loader"); + Object loaderObj = createInstanceWithArgumentsAndContext( + "com.sun.star.loader.Java", param, m_xDefaultContext ); + + if (loaderObj == null) + throw new com.sun.star.uno.Exception("Can get an instance of com.sun.star.loader.Java"); + + return UnoRuntime.queryInterface( XImplementationLoader.class, loaderObj ); + } + + /** + * Registers a list of components given by their class names. + * <p> + * @param newImpls list of the components that should be registered, given by their class names. + * If any exception occured during the registration, the process will be canceled. + * @see com.sun.star.container.XSet + */ + private void xaddFactories( String[] newImpls ) + throws com.sun.star.uno.Exception + { + for (int i=0; i<newImpls.length; i++) { + DEBUG ("try to add " + newImpls[i] ); + Object newFactory = null; + + try { + if (loader == null) + loader = getLoader(); + + newFactory = loader.activate( newImpls[i], null, null, null ); + } + catch (com.sun.star.uno.Exception e) { + +//****************************** BEGIN DEPRECATED ****************************************** + + try { + // try to get the class of the implementation + Class clazz = Class.forName( newImpls[i] ); + + Class[] methodClassParam = { String.class, XMultiServiceFactory.class, XRegistryKey.class }; + java.lang.reflect.Method getFactoryMeth = null; + try { + getFactoryMeth = clazz.getMethod("__getServiceFactory", methodClassParam); + } + catch (NoSuchMethodException noSuchMethodEx) { + getFactoryMeth = null; + } + catch (SecurityException securityExc) { + getFactoryMeth = null; + } + + if (getFactoryMeth == null) + getFactoryMeth = clazz.getMethod("getServiceFactory", methodClassParam); + + Object[] methodParams = { newImpls[i], this, null }; + newFactory = getFactoryMeth.invoke( clazz, methodParams ); + } + catch (NoSuchMethodException ex) {} + catch (SecurityException ex) {} + catch (ClassNotFoundException ex) {} + catch (IllegalAccessException ex) {} + catch (IllegalArgumentException ex) {} + catch (InvocationTargetException ex) {} + +//****************************** END DEPRECATED ****************************************** + } + + if ( newFactory == null ) + throw new com.sun.star.loader.CannotActivateFactoryException("Can not get factory for " + newImpls[i]); + + insert( newFactory ); + } // end of for ... + } + + /** + * The method is used to add components to the <code>ServiceManager</code>. The first argument indicates a <code>SimpleRegistry</code>. + * The components which should be added will be searched under the <i>Implementations</i> key in the registry. + * <p> + * @param args the first argument ( args[0] ) specifices the SimpleRegistry object + * @see com.sun.star.lang.XInitialization + * @see com.sun.star.lang.RegistryServiceManager + * @see com.sun.star.lang.XSimpleRegistry + */ + public void initialize( Object args[] ) + throws com.sun.star.uno.Exception, + com.sun.star.uno.RuntimeException { + XSimpleRegistry xSimpleRegistry = null; + try { + xSimpleRegistry = (XSimpleRegistry) args[0]; + if (xSimpleRegistry != null) + { + XRegistryKey rootkey = xSimpleRegistry.getRootKey(); + + XRegistryKey implkey_xRegistryKey = rootkey.openKey("Implementations"); + if(implkey_xRegistryKey != null) { + XRegistryKey xRegistryKeys[] = implkey_xRegistryKey.openKeys(); + + for(int i = 0; i < xRegistryKeys.length; ++ i) { + xaddFactories(new String[]{xRegistryKeys[i].getStringValue()}); + } + } + } + + if (args.length > 1) + { + m_xDefaultContext = (XComponentContext)args[ 1 ]; + } + } + catch (ArrayIndexOutOfBoundsException e) + { + throw new com.sun.star.lang.IllegalArgumentException("Argument must not be null."); + } + } + + /** + * Creates a new instance of a specified service. Therefor the associated factory of the service is + * looked up and used to instanciate a new component. + * <p> + * @return newly created component + * @param serviceSpecifier indicates the service or component name + * @see com.sun.star.lang.XMultiServiceFactory + */ + public java.lang.Object createInstance( String serviceSpecifier ) + throws com.sun.star.uno.Exception, + com.sun.star.uno.RuntimeException + { + return createInstanceWithContext( serviceSpecifier, m_xDefaultContext ); + } + + /** + * Creates a new instance of a specified service with the given parameters. + * Therefor the associated factory of the service is looked up and used to instanciate a new component. + * <p> + * @return newly created component + * @param serviceSpecifier indicates the service or component name + * @see com.sun.star.lang.XMultiServiceFactory + */ + public java.lang.Object createInstanceWithArguments( + String serviceSpecifier, Object[] args ) + throws com.sun.star.uno.Exception, com.sun.star.uno.RuntimeException + { + if (DEBUG) { + System.err.println("createInstanceWithArguments:" ); + + for (int i=0; i<args.length; i++) + System.err.print(" "+ args[i]); + + System.err.println(); + } + + return createInstanceWithArgumentsAndContext( serviceSpecifier, args, m_xDefaultContext ); + } + + /** + * Look up the factory for a given service or implementation name. + * First the requested service name is search in the list of avaible services. If it can not be found + * the name is looked up in the the implementation list. + * <p> + * @return the factory of the service / implementation + * @param serviceSpecifier indicates the service or implementation name + * @see com.sun.star.lang.XMultiServiceFactory + */ + private Object queryServiceFactory(String serviceName) + throws com.sun.star.uno.Exception, + com.sun.star.uno.RuntimeException + { + DEBUG("queryServiceFactory for name " + serviceName ); + Object factory = null; + + if ( factoriesByServiceNames.containsKey( serviceName ) ) { + java.util.Vector aviableFact = (java.util.Vector) factoriesByServiceNames.get( serviceName ); + + DEBUG(""); + DEBUG("aviable factories for " + serviceName +" "+ aviableFact); + DEBUG(""); + + if ( !aviableFact.isEmpty() ) + factory = aviableFact.lastElement(); + + } else // not found in list of services - now try the implementations + factory = factoriesByImplNames.get( serviceName ); // return null if none is aviable + + if (DEBUG) { + if (factory == null) System.err.println("service not registered"); + else + System.err.println("service found:" + factory + " " + UnoRuntime.queryInterface(XSingleServiceFactory.class, factory)); + } + + if (factory == null) + throw new com.sun.star.uno.Exception("Query for service factory for " + serviceName + " failed."); + + return factory; + } + + /** + * Supplies a list of all avialable services names. + * <p> + * @return list of Strings of all service names + * @see com.sun.star.container.XContentEnumerationAccess + */ + public String[] getAvailableServiceNames() + throws com.sun.star.uno.RuntimeException + { + int i = 0; + String[] availableServiceNames = new String[factoriesByServiceNames.size()]; + + java.util.Enumeration keys = factoriesByServiceNames.keys(); + + while (keys.hasMoreElements()) + availableServiceNames[i++] = (String) keys.nextElement(); + + return availableServiceNames; + } + + // XMultiComponentFactory implementation + + /** Create a service instance with given context. + + @param rServiceSpecifier service name + @param xContext context + @return service instance + */ + public java.lang.Object createInstanceWithContext( + String rServiceSpecifier, + com.sun.star.uno.XComponentContext xContext ) + throws com.sun.star.uno.Exception + { + Object fac = queryServiceFactory( rServiceSpecifier ); + if (fac != null) + { + XSingleComponentFactory xCompFac = UnoRuntime.queryInterface( + XSingleComponentFactory.class, fac ); + if (xCompFac != null) + { + return xCompFac.createInstanceWithContext( xContext ); + } + else + { + XSingleServiceFactory xServiceFac = UnoRuntime.queryInterface( + XSingleServiceFactory.class, fac ); + if (xServiceFac != null) + { + if (DEBUG) + System.err.println( "### ignoring context raising service \"" + rServiceSpecifier + "\"!" ); + return xServiceFac.createInstance(); + } + else + { + throw new com.sun.star.uno.Exception( + "retrieved service factory object for \"" + rServiceSpecifier + + "\" does not export XSingleComponentFactory nor XSingleServiceFactory!" ); + } + } + } + return null; + } + /** Create a service instance with given context and arguments. + + @param rServiceSpecifier service name + @param rArguments arguments + @param xContext context + @return service instance + */ + public java.lang.Object createInstanceWithArgumentsAndContext( + String rServiceSpecifier, + java.lang.Object[] rArguments, + com.sun.star.uno.XComponentContext xContext ) + throws com.sun.star.uno.Exception + { + Object fac = queryServiceFactory( rServiceSpecifier ); + if (fac != null) + { + XSingleComponentFactory xCompFac = UnoRuntime.queryInterface( + XSingleComponentFactory.class, fac ); + if (xCompFac != null) + { + return xCompFac.createInstanceWithArgumentsAndContext( rArguments, xContext ); + } + else + { + XSingleServiceFactory xServiceFac = UnoRuntime.queryInterface( + XSingleServiceFactory.class, fac ); + if (xServiceFac != null) + { + if (DEBUG) + System.err.println( "### ignoring context raising service \"" + rServiceSpecifier + "\"!" ); + return xServiceFac.createInstanceWithArguments( rArguments ); + } + else + { + throw new com.sun.star.uno.Exception( + "retrieved service factory object for \"" + rServiceSpecifier + + "\" does not export XSingleComponentFactory nor XSingleServiceFactory!" ); + } + } + } + return null; + } +// public String[] getAvailableServiceNames(); + + /** + * Removes all listeners from the <code>ServiceManager</code> and clears the list of the services. + * <p> + * @see com.sun.star.lang.XComponent + */ + public void dispose() + throws com.sun.star.uno.RuntimeException + { + if (eventListener != null) { + java.util.Enumeration enumer = eventListener.elements(); + + while (enumer.hasMoreElements()) { + XEventListener listener = (XEventListener) enumer.nextElement(); + listener.disposing(new com.sun.star.lang.EventObject(this)); + } + } + + eventListener.removeAllElements(); + factoriesByServiceNames.clear(); + factoriesByImplNames.clear(); + } + + /** + * Adds a new <code>EventListener</code>. The listener is notified when a + * service is added (removed) to (from) the <code>ServiceManager</code>. + * If the listener is already registred a + * <code>com.sun.star.uno.RuntimeException</code> will be thrown. + * <p> + * @param xListener the new listener which should been added. + * @see com.sun.star.lang.XComponent + */ + public void addEventListener( XEventListener xListener ) + throws com.sun.star.uno.RuntimeException + { + if (xListener == null) + throw new com.sun.star.uno.RuntimeException("Listener must not be null"); + + if ( eventListener.contains(xListener) ) + throw new com.sun.star.uno.RuntimeException("Listener already registred."); + + eventListener.addElement(xListener); + } + + /** + * Removes a <code>EventListener</code> from the <code>ServiceManager</code>. + * If the listener is not registered a <code>com.sun.star.uno.RuntimeException</code> + * will be thrown. + * <p> + * @param xListener the new listener which should been removed. + * @see com.sun.star.lang.XComponent + */ + public void removeEventListener( XEventListener xListener ) + throws com.sun.star.uno.RuntimeException + { + if (xListener == null) + throw new com.sun.star.uno.RuntimeException("Listener must not be null"); + + if ( !eventListener.contains(xListener) ) + throw new com.sun.star.uno.RuntimeException("Listener is not registered."); + + eventListener.removeElement(xListener); + } + + /** + * Checks if a component is registered at the <code>ServiceManager</code>. The given object argument must + * provide a <code>XServiceInfo</code> interface. + * <p> + * @return true if the component is registred otherwise false. + * @param object object which provides a <code>XServiceInfo</code> interface. + * @see com.sun.star.container.XSet + * @see com.sun.star.lang.XServiceInfo + */ + public boolean has( Object object ) + throws com.sun.star.uno.RuntimeException + { + if (object == null) + throw new com.sun.star.uno.RuntimeException("The parameter must not been null"); + + XServiceInfo xServiceInfo = UnoRuntime.queryInterface(XServiceInfo.class, object); + + if (xServiceInfo != null) { + return UnoRuntime.areSame(factoriesByImplNames.get(xServiceInfo.getImplementationName()), object); + } + + return false; + } + + /** + * Adds a <code>SingleServiceFactory</code> to the <code>ServiceManager</code>. + * <p> + * @param object factory which should be added. + * @see com.sun.star.container.XSet + * @see com.sun.star.lang.XSingleServiceFactory + */ + public void insert( Object object ) + throws com.sun.star.lang.IllegalArgumentException, + com.sun.star.container.ElementExistException, + com.sun.star.uno.RuntimeException + { + if (object == null) throw new com.sun.star.lang.IllegalArgumentException(); + + XServiceInfo xServiceInfo = + UnoRuntime.queryInterface(XServiceInfo.class, object); + + if (xServiceInfo == null) + throw new com.sun.star.lang.IllegalArgumentException( + "The given object does not implement the XServiceInfo interface." + ); + + if ( factoriesByImplNames.containsKey( xServiceInfo.getImplementationName() ) ) { + throw new com.sun.star.container.ElementExistException( + xServiceInfo.getImplementationName() + " already registred" + ); + } + + DEBUG("add factory " + object.toString() + " for " + xServiceInfo.getImplementationName()); + factoriesByImplNames.put( xServiceInfo.getImplementationName(), object ); + + + String[] serviceNames = xServiceInfo.getSupportedServiceNames(); + java.util.Vector vec = null; + + for (int i=0; i<serviceNames.length; i++) { + if ( !factoriesByServiceNames.containsKey( serviceNames[i] ) ) { + DEBUG("> no registered services found under " + serviceNames[i] + ": adding..." ); + factoriesByServiceNames.put(serviceNames[i], new java.util.Vector()); + } + + vec = (java.util.Vector) factoriesByServiceNames.get( serviceNames[i] ); + + if ( vec.contains( object ) ) + System.err.println("The implementation " + xServiceInfo.getImplementationName() + + " already registered for the service " + serviceNames[i] + " - ignoring!"); + else + vec.addElement(object); + } + } + + /** + * Removes a <code>SingleServiceFactory</code> from the <code>ServiceManager</code>. + * <p> + * @param object factory which should be removed. + * @see com.sun.star.container.XSet + * @see com.sun.star.lang.XSingleServiceFactory + */ + public void remove( Object object ) + throws com.sun.star.lang.IllegalArgumentException, + com.sun.star.container.NoSuchElementException, + com.sun.star.uno.RuntimeException + { + if (object == null) + throw new com.sun.star.lang.IllegalArgumentException( + "The given object must not be null." + ); + + XServiceInfo xServiceInfo = + UnoRuntime.queryInterface(XServiceInfo.class, object); + + if (xServiceInfo == null) + throw new com.sun.star.lang.IllegalArgumentException( + "The given object does not implement the XServiceInfo interface." + ); + + XSingleServiceFactory xSingleServiceFactory = + UnoRuntime.queryInterface(XSingleServiceFactory.class, object); + + if (xSingleServiceFactory == null) + throw new com.sun.star.lang.IllegalArgumentException( + "The given object does not implement the XSingleServiceFactory interface." + ); + + if ( factoriesByImplNames.remove( xServiceInfo.getImplementationName() ) == null ) + throw new com.sun.star.container.NoSuchElementException( + xServiceInfo.getImplementationName() + + " is not registered as an implementation." + ); + + String[] serviceNames = xServiceInfo.getSupportedServiceNames(); + + for ( int i=0; i<serviceNames.length; i++ ) { + if ( factoriesByServiceNames.containsKey( serviceNames[i] ) ) { + java.util.Vector vec = (java.util.Vector) factoriesByServiceNames.get(serviceNames[i]); + + if ( !vec.removeElement(object) ) + System.err.println("The implementation " + xServiceInfo.getImplementationName() + + " is not registered for the service " + serviceNames[i] + " - ignoring!"); + + if ( vec.isEmpty() ) // remove the vector if no implementations aviable for the service + factoriesByServiceNames.remove( serviceNames[i] ); + } + } + } + + /** + * Provides an enumeration of all registred services. + * <p> + * @return an enumeration of all avialable services. + * @see com.sun.star.conatiner.XEnumerationAccess + */ + public XEnumeration createEnumeration() + throws com.sun.star.uno.RuntimeException + { + return new ServiceEnumerationImpl( factoriesByImplNames.elements() ); + } + + /** + * Provides the UNO type of the <code>ServiceManager</code> + * <p> + * @return the UNO type of the <code>ServiceManager</code>. + * @see com.sun.star.container.XElementAccess + * @see com.sun.star.uno.TypeClass + */ + public com.sun.star.uno.Type getElementType() + throws com.sun.star.uno.RuntimeException + { + if ( UNO_TYPE == null ) + UNO_TYPE = new com.sun.star.uno.Type(ServiceManager.class); + + return UNO_TYPE; + } + + /** + * Checks if the any componets are registered. + * <p> + * @return true - if the list of the registred components is not empty - otherwise false. + * @see com.sun.star.container.XElementAccess + */ + public boolean hasElements() { + return ! factoriesByImplNames.isEmpty(); + } + + /** + * Provides an enumeration of of all factorys for a specified service. + * <p> + * @return an enumeration for service name. + * @param serviceName name of the requested service + * @see com.sun.star.container.XContentEnumerationAccess + */ + public XEnumeration createContentEnumeration( String serviceName ) + throws com.sun.star.uno.RuntimeException + { + XEnumeration enumer = null; + + java.util.Vector serviceList = (java.util.Vector) factoriesByServiceNames.get(serviceName); + + if (serviceList != null) + enumer = new ServiceEnumerationImpl( serviceList.elements() ); + else + enumer = new ServiceEnumerationImpl(); + + return enumer; + } + + /** + * Returns the implementation name of the <code>ServiceManager</code> component. + * <p> + * @return the class name of the <code>ServiceManager</code>. + * @see com.sun.star.lang.XServiceInfo + */ + public String getImplementationName() + throws com.sun.star.uno.RuntimeException + { + return getClass().getName(); + } + + /** + * Checks if the <code>ServiceManager</code> supports a service. + * <p> + * @return true if the service is supported - otherwise false. + * @param serviceName service name which 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<supportedServiceNames.length; i++) + if (supportedServiceNames[i].equals( serviceName )) return true; + + if (getImplementationName().equals( serviceName )) return true; + + return false; + } + + /** + * Supplies list of all supported services. + * <p> + * @return a list of all supported service names. + * @see com.sun.star.lang.XServiceInfo + */ + public String[] getSupportedServiceNames() + throws com.sun.star.uno.RuntimeException + { + return supportedServiceNames; + } + + /** + * The <code>ServiceEnumerationImpl</code> class provides an + * implementation of the @see com.sun.star.container.XEnumeration interface. + * It is a inner wrapper for a java.util.Enumeration object. + * <p> + * @version $Revision: 1.10 $ $ $Date: 2008-04-11 11:11:46 $ + * @author Markus Herzog + * @see com.sun.star.lang.XSingleServiceFactory + * @see com.sun.star.lang.XServiceInfo + * @since UDK1.0 + */ + class ServiceEnumerationImpl implements XEnumeration { + java.util.Enumeration enumeration = null; + + /** + * Constructs a new empty instance. + */ + public ServiceEnumerationImpl() { + } + + /** + * Constructs a new instance with a given enumeration. + * <p> + * @param enumer is the enumeration which should been wrapped. + * @see com.sun.star.container.XEnumeration + */ + public ServiceEnumerationImpl(java.util.Enumeration enumer) { + enumeration = enumer; + } + + /** + * Checks if the enumeration contains more elements. + * <p> + * @return true if more elements are available - otherwise false. + * @see com.sun.star.container.XEnumeration + */ + public boolean hasMoreElements() + throws com.sun.star.uno.RuntimeException + { + if (enumeration != null) + return enumeration.hasMoreElements(); + + return false; + } + + /** + * Returns the next element of the enumeration. If no further elements + * available a com.sun.star.container.NoSuchElementException exception will be thrown. + * <p> + * @return the next element. + * @see com.sun.star.container.XEnumeration + */ + public Object nextElement() + throws com.sun.star.container.NoSuchElementException, + com.sun.star.lang.WrappedTargetException, + com.sun.star.uno.RuntimeException + { + if (enumeration == null) + throw new com.sun.star.container.NoSuchElementException(); + + try { + return enumeration.nextElement(); + } catch (java.util.NoSuchElementException e) { + com.sun.star.container.NoSuchElementException ex = + new com.sun.star.container.NoSuchElementException(); + ex.fillInStackTrace(); + + throw ex; + } + } + } +} +/** + * The <code>ServiceManagerFactory</code> is the factory class for the + * <code>ServiceManager</code>. As all factories it implments the + * com.sun.star.lang.XSingleServiceFactory and the com.sun.star.lang.XServiceInfo + * interfaces. + * <p> + * @version $Revision: 1.10 $ $ $Date: 2008-04-11 11:11:46 $ + * @author Markus Herzog + * @see com.sun.star.lang.XSingleServiceFactory + * @see com.sun.star.lang.XServiceInfo + * @since UDK1.0 +*/ +class ServiceManagerFactory implements XServiceInfo, XSingleComponentFactory, XSingleServiceFactory +{ + /** + * Creates a new instance of the <code>ServiceManagerFactory</code>. + */ + public ServiceManagerFactory() { + } + + /** + * Supplies the implementation name of the <code>ServiceManager</code>. + * <p> + * @return <code>ServiceManager</code> class name. + * @see com.sun.star.lang.XServiceInfo + */ + public String getImplementationName() + throws com.sun.star.uno.RuntimeException + { + return ServiceManager.class.getName(); + } + + /** + * Checks wether or not a service is supported. + * <p> + * @return true - if the service is supported, 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<ServiceManager.supportedServiceNames.length; i++ ) + if ( ServiceManager.supportedServiceNames[i].equals(serviceName) ) return true; + + if ( getImplementationName().equals(serviceName) ) return true; + + return false; + } + + /** + * Returns all service names which are supported by <code>ServiceManager</code>. + * <p> + * @return a list aof all supported service names. + * @see com.sun.star.lang.XServiceInfo + */ + public String[] getSupportedServiceNames() + throws com.sun.star.uno.RuntimeException + { + return ServiceManager.supportedServiceNames; + } + + /** + * Creates a new instance of the <code>ServiceManager</code>. + * <p> + * @return newly created <code>ServiceManager</code> object. + * @see com.sun.star.lang.XSingleServiceFactory + */ + public java.lang.Object createInstance() + throws com.sun.star.uno.Exception, + com.sun.star.uno.RuntimeException + { + return new ServiceManager(); + } + + /** + * Creates a new instance of the <code>ServiceManager</code> with arguments. + * At this time it always throws a com.sun.star.lang.NoSuchMethodException + * because there is no the <code>ServiceManager</code> has no constructor with + * arguments. + * <p> + * @return null - allways throws an exception + * @param aArguments arguments for new instance. + * @see com.sun.star.lang.XSingleServiceFactory + */ + public java.lang.Object createInstanceWithArguments( java.lang.Object[] aArguments ) + throws com.sun.star.uno.Exception, + com.sun.star.uno.RuntimeException + { + throw new com.sun.star.lang.NoSuchMethodException("Constructor with arguments is not supported."); + } + + // XSingleComponentFactory impl + //______________________________________________________________________________________________ + public Object createInstanceWithContext( XComponentContext xContext ) + throws com.sun.star.uno.Exception, com.sun.star.uno.RuntimeException + { + return new ServiceManager( xContext ); + } + //______________________________________________________________________________________________ + public Object createInstanceWithArgumentsAndContext( + Object aArguments [], XComponentContext xContext ) + throws com.sun.star.uno.Exception, com.sun.star.uno.RuntimeException + { + throw new com.sun.star.lang.NoSuchMethodException( + "ServiceManagerFactory.createInstanceWithArgumentsAndContext() not impl!" ); + } +} + + diff --git a/jurt/com/sun/star/comp/servicemanager/makefile.mk b/jurt/com/sun/star/comp/servicemanager/makefile.mk new file mode 100644 index 000000000000..46fae35b5902 --- /dev/null +++ b/jurt/com/sun/star/comp/servicemanager/makefile.mk @@ -0,0 +1,43 @@ +#************************************************************************* +# +# 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$/servicemanager +TARGET = com_sun_star_comp_servicemanager + +# --- Settings ----------------------------------------------------- + +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +JAVAFILES = ServiceManager.java + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/jurt/com/sun/star/comp/urlresolver/UrlResolver.java b/jurt/com/sun/star/comp/urlresolver/UrlResolver.java new file mode 100644 index 000000000000..3509dfb303f2 --- /dev/null +++ b/jurt/com/sun/star/comp/urlresolver/UrlResolver.java @@ -0,0 +1,171 @@ +/************************************************************************* + * + * 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.urlresolver; + + +import com.sun.star.bridge.XBridge; +import com.sun.star.bridge.XBridgeFactory; +import com.sun.star.bridge.XUnoUrlResolver; + +import com.sun.star.comp.loader.FactoryHelper; + +import com.sun.star.connection.ConnectionSetupException; +import com.sun.star.connection.NoConnectException; +import com.sun.star.connection.XConnection; +import com.sun.star.connection.XConnector; + +import com.sun.star.lang.IllegalArgumentException; +import com.sun.star.lang.XMultiServiceFactory; +import com.sun.star.lang.XSingleServiceFactory; + +import com.sun.star.registry.XRegistryKey; + +import com.sun.star.uno.UnoRuntime; + + +/** + * This component gives a factory for an <code>UnoUrlResolver</code> service. + * <p> + * @version $Revision: 1.6 $ $ $Date: 2008-04-11 11:12:25 $ + * @author Kay Ramme + * @see com.sun.star.brige.XBrideFactory + * @see com.sun.star.connection.Connector + * @since UDK1.0 + */ +public class UrlResolver { + static private final boolean DEBUG = false; + + + static public class _UrlResolver implements XUnoUrlResolver { + static private final String __serviceName = "com.sun.star.bridge.UnoUrlResolver"; + + private XMultiServiceFactory _xMultiServiceFactory; + + public _UrlResolver(XMultiServiceFactory xMultiServiceFactory) { + _xMultiServiceFactory = xMultiServiceFactory; + } + + public Object resolve(/*IN*/String dcp) throws NoConnectException, ConnectionSetupException, IllegalArgumentException, com.sun.star.uno.RuntimeException { + String conDcp = null; + String protDcp = null; + String rootOid = null; + + if(dcp.indexOf(';') == -1) {// use old style + conDcp = dcp; + protDcp = "iiop"; + rootOid = "classic_uno"; + } + else { // new style + int index = dcp.indexOf(':'); + String url = dcp.substring(0, index).trim(); + dcp = dcp.substring(index + 1).trim(); + + index = dcp.indexOf(';'); + conDcp = dcp.substring(0, index).trim(); + dcp = dcp.substring(index + 1).trim(); + + index = dcp.indexOf(';'); + protDcp = dcp.substring(0, index).trim(); + dcp = dcp.substring(index + 1).trim(); + + rootOid = dcp.trim().trim(); + } + + Object rootObject = null; + XBridgeFactory xBridgeFactory= null; + try { + xBridgeFactory = UnoRuntime.queryInterface(XBridgeFactory.class, + _xMultiServiceFactory.createInstance("com.sun.star.bridge.BridgeFactory")); + } catch (com.sun.star.uno.Exception e) { + throw new com.sun.star.uno.RuntimeException(e.getMessage()); + } + XBridge xBridge = xBridgeFactory.getBridge(conDcp + ";" + protDcp); + + if(xBridge == null) { + Object connector= null; + try { + connector = _xMultiServiceFactory.createInstance("com.sun.star.connection.Connector"); + } catch (com.sun.star.uno.Exception e) { + throw new com.sun.star.uno.RuntimeException(e.getMessage()); + } + + XConnector connector_xConnector = UnoRuntime.queryInterface(XConnector.class, connector); + + // connect to the server + XConnection xConnection = connector_xConnector.connect(conDcp); + try { + xBridge = xBridgeFactory.createBridge(conDcp + ";" + protDcp, protDcp, xConnection, null); + } catch (com.sun.star.bridge.BridgeExistsException e) { + throw new com.sun.star.uno.RuntimeException(e.getMessage()); + } + } + rootObject = xBridge.getInstance(rootOid); + return rootObject; + } + } + + + /** + * Gives a factory for creating the service. + * This method is called by the <code>JavaLoader</code> + * <p> + * @return returns a <code>XSingleServiceFactory</code> for creating the component + * @param implName the name of the implementation for which a service is desired + * @param multiFactory the service manager to be uses if needed + * @param regKey the registryKey + * @see com.sun.star.comp.loader.JavaLoader + */ + public static XSingleServiceFactory __getServiceFactory(String implName, + XMultiServiceFactory multiFactory, + XRegistryKey regKey) + { + XSingleServiceFactory xSingleServiceFactory = null; + + if (implName.equals(UrlResolver.class.getName()) ) + xSingleServiceFactory = FactoryHelper.getServiceFactory(_UrlResolver.class, + _UrlResolver.__serviceName, + multiFactory, + regKey); + + return xSingleServiceFactory; + } + + /** + * Writes the service information into the given registry key. + * This method is called by the <code>JavaLoader</code> + * <p> + * @return returns true if the operation succeeded + * @param regKey the registryKey + * @see com.sun.star.comp.loader.JavaLoader + */ + public static boolean __writeRegistryServiceInfo(XRegistryKey regKey) { + return FactoryHelper.writeRegistryServiceInfo(_UrlResolver.class.getName(), _UrlResolver.__serviceName, regKey); + } + +} + diff --git a/jurt/com/sun/star/comp/urlresolver/makefile.mk b/jurt/com/sun/star/comp/urlresolver/makefile.mk new file mode 100644 index 000000000000..20f4dd78c33e --- /dev/null +++ b/jurt/com/sun/star/comp/urlresolver/makefile.mk @@ -0,0 +1,43 @@ +#************************************************************************* +# +# 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$/urlresolver +TARGET = com_sun_star_comp_urlresolver + +# --- Settings ----------------------------------------------------- + +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# Files -------------------------------------------------------- + +JAVAFILES = UrlResolver.java + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/jurt/com/sun/star/lib/connections/pipe/PipeConnection.java b/jurt/com/sun/star/lib/connections/pipe/PipeConnection.java new file mode 100644 index 000000000000..997b9d1c76ee --- /dev/null +++ b/jurt/com/sun/star/lib/connections/pipe/PipeConnection.java @@ -0,0 +1,254 @@ +/************************************************************************* + * + * 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.lib.connections.pipe; + +import java.io.IOException; + +import java.util.StringTokenizer; +import java.util.Enumeration; +import java.util.Vector; + +import com.sun.star.lib.util.NativeLibraryLoader; + +import com.sun.star.io.XStreamListener; + +import com.sun.star.connection.XConnection; +import com.sun.star.connection.XConnectionBroadcaster; + +/** + * The PipeConnection implements the <code>XConnection</code> interface + * and is uses by the <code>PipeConnector</code> and the <code>PipeAcceptor</code>. + * This class is not part of the provided <code>api</code>. + * <p> + * @version $Revision: 1.7 $ $ $Date: 2008-04-11 11:13:00 $ + * @author Kay Ramme + * @see com.sun.star.comp.connections.PipeAcceptor + * @see com.sun.star.comp.connections.PipeConnector + * @see com.sun.star.connections.XConnection + * @since UDK1.0 + */ +public class PipeConnection implements XConnection, XConnectionBroadcaster { + /** + * When set to true, enables various debugging output. + */ + static public final boolean DEBUG = false; + + static { + // preload shared libraries whichs import lips are linked to jpipe + if ( System.getProperty( "os.name" ).startsWith( "Windows" ) ) + { + try { + NativeLibraryLoader.loadLibrary(PipeConnection.class.getClassLoader(), "msvcr71"); + } catch (Throwable e){} // loading twice would fail + + try { + NativeLibraryLoader.loadLibrary(PipeConnection.class.getClassLoader(), "msvcr70"); + } catch (Throwable e){} // loading twice would fail + + try { + NativeLibraryLoader.loadLibrary(PipeConnection.class.getClassLoader(), "uwinapi"); + } catch (Throwable e){} // loading twice would fail + + try { + NativeLibraryLoader.loadLibrary(PipeConnection.class.getClassLoader(), "sal3"); + } catch (Throwable e){} // loading twice would fail + } + + // load shared library for JNI code + try { + NativeLibraryLoader.loadLibrary(PipeConnection.class.getClassLoader(), "jpipe"); + } catch (Throwable e){} // loading twice would fail + } + + protected String _aDescription; + protected long _nPipeHandle; + protected Vector _aListeners; + protected boolean _bFirstRead; + + /** + * Constructs a new <code>PipeConnection</code>. + * <p> + * @param description the description of the connection + * @param pipe the pipe of the connection + */ + public PipeConnection(String description) + throws IOException + { + if (DEBUG) System.err.println("##### " + getClass().getName() + " - instantiated " + description ); + + _aListeners = new Vector(); + _bFirstRead = true; + + // get pipe name from pipe descriptor + String aPipeName = null; + StringTokenizer aTokenizer = new StringTokenizer( description, "," ); + if ( aTokenizer.hasMoreTokens() ) + { + String aConnType = aTokenizer.nextToken(); + if ( !aConnType.equals( "pipe" ) ) + throw new RuntimeException( "invalid pipe descriptor: does not start with 'pipe,'" ); + + String aPipeNameParam = aTokenizer.nextToken(); + if ( !aPipeNameParam.substring( 0, 5 ).equals( "name=" ) ) + throw new RuntimeException( "invalid pipe descriptor: no 'name=' parameter found" ); + aPipeName = aPipeNameParam.substring( 5 ); + } + else + throw new RuntimeException( "invalid or empty pipe descriptor" ); + + // create the pipe + try + { createJNI( aPipeName ); } + catch ( java.lang.NullPointerException aNPE ) + { throw new IOException( aNPE.getMessage() ); } + catch ( com.sun.star.io.IOException aIOE ) + { throw new IOException( aIOE.getMessage() ); } + catch ( java.lang.Exception aE ) + { throw new IOException( aE.getMessage() ); } + } + + public void addStreamListener(XStreamListener aListener ) throws com.sun.star.uno.RuntimeException { + _aListeners.addElement(aListener); + } + + public void removeStreamListener(XStreamListener aListener ) throws com.sun.star.uno.RuntimeException { + _aListeners.removeElement(aListener); + } + + private void notifyListeners_open() { + Enumeration elements = _aListeners.elements(); + while(elements.hasMoreElements()) { + XStreamListener xStreamListener = (XStreamListener)elements.nextElement(); + xStreamListener.started(); + } + } + + private void notifyListeners_close() { + Enumeration elements = _aListeners.elements(); + while(elements.hasMoreElements()) { + XStreamListener xStreamListener = (XStreamListener)elements.nextElement(); + xStreamListener.closed(); + } + } + + private void notifyListeners_error(com.sun.star.uno.Exception exception) { + Enumeration elements = _aListeners.elements(); + while(elements.hasMoreElements()) { + XStreamListener xStreamListener = (XStreamListener)elements.nextElement(); + xStreamListener.error(exception); + } + } + + // JNI implementation to create the pipe + private native int createJNI( String name ) + throws com.sun.star.io.IOException, com.sun.star.uno.RuntimeException; + + // JNI implementation to read from the pipe + private native int readJNI(/*OUT*/byte[][] bytes, int nBytesToRead) + throws com.sun.star.io.IOException, com.sun.star.uno.RuntimeException; + + // JNI implementation to write to the pipe + private native void writeJNI(byte aData[]) + throws com.sun.star.io.IOException, com.sun.star.uno.RuntimeException; + + // JNI implementation to flush the pipe + private native void flushJNI() + throws com.sun.star.io.IOException, com.sun.star.uno.RuntimeException; + + // JNI implementation to close the pipe + private native void closeJNI() + throws com.sun.star.io.IOException, com.sun.star.uno.RuntimeException; + + /** + * Read the required number of bytes. + * <p> + * @return the number of bytes read + * @param aReadBytes the outparameter, where the bytes have to be placed + * @param nBytesToRead the number of bytes to read + * @see com.sun.star.connections.XConnection#read + */ + public int read(/*OUT*/byte[][] bytes, int nBytesToRead) + throws com.sun.star.io.IOException, com.sun.star.uno.RuntimeException + { + if(_bFirstRead) { + _bFirstRead = false; + + notifyListeners_open(); + } + + return readJNI( bytes, nBytesToRead ); + } + + /** + * Write bytes. + * <p> + * @param aData the bytes to write + * @see com.sun.star.connections.XConnection#write + */ + public void write(byte aData[]) + throws com.sun.star.io.IOException, com.sun.star.uno.RuntimeException + { + writeJNI( aData ); + } + + /** + * Flushes the buffer. + * <p> + * @see com.sun.star.connections.XConnection#flush + */ + public void flush() + throws com.sun.star.io.IOException, com.sun.star.uno.RuntimeException + { + flushJNI(); + } + + /** + * Closes the connection. + * <p> + * @see com.sun.star.connections.XConnection#close + */ + public void close() + throws com.sun.star.io.IOException, com.sun.star.uno.RuntimeException + { + if (DEBUG) System.out.print( "PipeConnection::close() " ); + closeJNI(); + notifyListeners_close(); + if (DEBUG) System.out.println( "done" ); + } + + /** + * Gives a description of the connection. + * <p> + * @return the description + * @see com.sun.star.connections.XConnection#getDescription + */ + public String getDescription() throws com.sun.star.uno.RuntimeException { + return _aDescription; + } + +} + diff --git a/jurt/com/sun/star/lib/connections/pipe/makefile.mk b/jurt/com/sun/star/lib/connections/pipe/makefile.mk new file mode 100644 index 000000000000..d90bc63bc891 --- /dev/null +++ b/jurt/com/sun/star/lib/connections/pipe/makefile.mk @@ -0,0 +1,41 @@ +#************************************************************************* +# +# 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 +TARGET = com_sun_star_connections_pipe + +PACKAGE = com$/sun$/star$/lib$/connections$/pipe + +.INCLUDE: $(PRJ)$/util$/makefile.pmk + +JAVAFILES = \ + PipeConnection.java \ + pipeAcceptor.java \ + pipeConnector.java + +.INCLUDE: target.mk diff --git a/jurt/com/sun/star/lib/connections/pipe/pipeAcceptor.java b/jurt/com/sun/star/lib/connections/pipe/pipeAcceptor.java new file mode 100644 index 000000000000..4c5bf7f1c979 --- /dev/null +++ b/jurt/com/sun/star/lib/connections/pipe/pipeAcceptor.java @@ -0,0 +1,146 @@ +/************************************************************************* + * + * 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.lib.connections.pipe; + +import com.sun.star.comp.loader.FactoryHelper; +import com.sun.star.connection.AlreadyAcceptingException; +import com.sun.star.connection.ConnectionSetupException; +import com.sun.star.connection.XAcceptor; +import com.sun.star.connection.XConnection; +import com.sun.star.lang.XMultiServiceFactory; +import com.sun.star.lang.XSingleServiceFactory; +import com.sun.star.registry.XRegistryKey; + +/** + * A component that implements the <code>XAcceptor</code> interface. + * + * <p>The <code>pipeAcceptor</code> is a specialized component that uses TCP + * pipes for communication. The <code>pipeAcceptor</code> is generally used + * by the <code>com.sun.star.connection.Acceptor</code> service.</p> + * + * @see com.sun.star.connections.XAcceptor + * @see com.sun.star.connections.XConnection + * @see com.sun.star.connections.XConnector + * @see com.sun.star.loader.JavaLoader + * + * @since UDK 1.0 + */ +public final class pipeAcceptor implements XAcceptor { + /** + * The name of the service. + * + * <p>The <code>JavaLoader</code> acceses this through reflection.</p> + * + * @see com.sun.star.comp.loader.JavaLoader + */ + public static final String __serviceName + = "com.sun.star.connection.pipeAcceptor"; + + /** + * Returns a factory for creating the service. + * + * <p>This method is called by the <code>JavaLoader</code>.</p> + * + * @param implName the name of the implementation for which a service is + * requested. + * @param multiFactory the service manager to be used (if needed). + * @param regKey the registry key. + * @return an <code>XSingleServiceFactory</code> for creating the component. + * + * @see com.sun.star.comp.loader.JavaLoader + */ + public static XSingleServiceFactory __getServiceFactory( + String implName, XMultiServiceFactory multiFactory, XRegistryKey regKey) + { + return implName.equals(pipeAcceptor.class.getName()) + ? FactoryHelper.getServiceFactory( + pipeAcceptor.class, __serviceName, multiFactory, regKey) + : null; + } + + /** + * Writes the service information into the given registry key. + * + * <p>This method is called by the <code>JavaLoader</code>.</p> + * + * @param regKey the registry key. + * @return <code>true</code> if the operation succeeded. + * + * @see com.sun.star.comp.loader.JavaLoader + */ + public static boolean __writeRegistryServiceInfo(XRegistryKey regKey) { + return FactoryHelper.writeRegistryServiceInfo( + pipeAcceptor.class.getName(), __serviceName, regKey); + } + + /** + * Accepts a connection request via the described pipe. + * + * <p>This call blocks until a connection has been established.</p> + * + * <p>The connection description has the following format: + * <code><var>type</var></code><!-- + * -->*(<code><var>key</var>=<var>value</var></code>), + * where <code><var>type</var></code> should be <code>pipe</code> + * (ignoring case). Supported keys (ignoring case) currently are + * <dl> + * <dt><code>host</code> + * <dd>The name or address of the accepting interface (defaults to + * <code>0</code>, meaning any interface). + * <dt><code>port</code> + * <dd>The TCP port number to accept on (defaults to <code>6001</code>). + * <dt><code>backlog</code> + * <dd>The maximum length of the acceptor's queue (defaults to + * <code>50</code>). + * <dt><code>tcpnodelay</code> + * <dd>A flag (<code>0</code>/<code>1</code>) enabling or disabling Nagle's + * algorithm on the resulting connection. + * </dl></p> + * + * @param connectionDescription the description of the connection. + * @return an <code>XConnection</code> to the client. + * + * @see com.sun.star.connections.XConnection + * @see com.sun.star.connections.XConnector + */ + public XConnection accept(String connectionDescription) throws + AlreadyAcceptingException, ConnectionSetupException, + com.sun.star.lang.IllegalArgumentException + { + throw new java.lang.NoSuchMethodError( "pipeAcceptor not fully implemented yet" ); + + //try { return new PipeConnection( connectionDescription ); } + //catch ( java.io.IOException e ) { return null; } + } + + // see com.sun.star.connection.XAcceptor#stopAccepting + public void stopAccepting() { + } + + private static final boolean DEBUG = false; +} diff --git a/jurt/com/sun/star/lib/connections/pipe/pipeConnector.java b/jurt/com/sun/star/lib/connections/pipe/pipeConnector.java new file mode 100644 index 000000000000..9c0c412ec2bc --- /dev/null +++ b/jurt/com/sun/star/lib/connections/pipe/pipeConnector.java @@ -0,0 +1,142 @@ +/************************************************************************* + * + * 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.lib.connections.pipe; + +import com.sun.star.comp.loader.FactoryHelper; +import com.sun.star.connection.ConnectionSetupException; +import com.sun.star.connection.NoConnectException; +import com.sun.star.connection.XConnection; +import com.sun.star.connection.XConnector; +import com.sun.star.lang.XMultiServiceFactory; +import com.sun.star.lang.XSingleServiceFactory; +import com.sun.star.registry.XRegistryKey; + +/** + * A component that implements the <code>XConnector</code> interface. + * + * <p>The <code>pipeConnector</code> is a specialized component that uses TCP + * pipes for communication. The <code>pipeConnector</code> is generally + * used by the <code>com.sun.star.connection.Connector</code> service.</p> + * + * @see com.sun.star.connections.XAcceptor + * @see com.sun.star.connections.XConnection + * @see com.sun.star.connections.XConnector + * @see com.sun.star.loader.JavaLoader + * + * @since UDK 1.0 + */ +public final class pipeConnector implements XConnector { + /** + * The name of the service. + * + * <p>The <code>JavaLoader</code> acceses this through reflection.</p> + * + * @see com.sun.star.comp.loader.JavaLoader + */ + public static final String __serviceName = "com.sun.star.connection.pipeConnector"; + + /** + * Returns a factory for creating the service. + * + * <p>This method is called by the <code>JavaLoader</code>.</p> + * + * @param implName the name of the implementation for which a service is + * requested. + * @param multiFactory the service manager to be used (if needed). + * @param regKey the registry key. + * @return an <code>XSingleServiceFactory</code> for creating the component. + * + * @see com.sun.star.comp.loader.JavaLoader + */ + public static XSingleServiceFactory __getServiceFactory( + String implName, XMultiServiceFactory multiFactory, XRegistryKey regKey) + { + return implName.equals(pipeConnector.class.getName()) + ? FactoryHelper.getServiceFactory(pipeConnector.class, + __serviceName, multiFactory, + regKey) + : null; + } + + /** + * Writes the service information into the given registry key. + * + * <p>This method is called by the <code>JavaLoader</code>.</p> + * + * @param regKey the registry key. + * @return <code>true</code> if the operation succeeded. + * + * @see com.sun.star.comp.loader.JavaLoader + */ + public static boolean __writeRegistryServiceInfo(XRegistryKey regKey) { + return FactoryHelper.writeRegistryServiceInfo( + pipeConnector.class.getName(), __serviceName, regKey); + } + + /** + * Connects via the described pipe to a waiting server. + * + * <p>The connection description has the following format: + * <code><var>type</var></code><!-- + * -->*(<code><var>key</var>=<var>value</var></code>), + * where <code><var>type</var></code> should be <code>pipe</code> + * (ignoring case). Supported keys (ignoring case) currently are + * <dl> + * <dt><code>host</code> + * <dd>The name or address of the server. Must be present. + * <dt><code>port</code> + * <dd>The TCP port number of the server (defaults to <code>6001</code>). + * <dt><code>tcpnodelay</code> + * <dd>A flag (<code>0</code>/<code>1</code>) enabling or disabling Nagle's + * algorithm on the resulting connection. + * </dl></p> + * + * @param connectionDescription the description of the connection. + * @return an <code>XConnection</code> to the server. + * + * @see com.sun.star.connections.XAcceptor + * @see com.sun.star.connections.XConnection + */ + public synchronized XConnection connect(String connectionDescription) + throws NoConnectException, ConnectionSetupException + { + if (bConnected) { + throw new ConnectionSetupException("alread connected"); + } + + try + { + XConnection xConn = new PipeConnection( connectionDescription ); + bConnected = true; + return xConn; + } + catch ( java.io.IOException e ) { throw new NoConnectException(); } + } + + private boolean bConnected = false; +} diff --git a/jurt/com/sun/star/lib/connections/socket/ConnectionDescriptor.java b/jurt/com/sun/star/lib/connections/socket/ConnectionDescriptor.java new file mode 100644 index 000000000000..c38faed73e41 --- /dev/null +++ b/jurt/com/sun/star/lib/connections/socket/ConnectionDescriptor.java @@ -0,0 +1,107 @@ +/************************************************************************* + * + * 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.lib.connections.socket; + +/** + * Helper class for <code>socketAcceptor</code> and + * <code>socketConnector</code>. + * + * <p>FIXME: Once those classes have been moved from <code>jurt</code> to + * <code>javaunohelper</code>, they should use + * <code>com.sun.star.lib.uno.helper.UnoUrl</code> either instead of this class + * or underneath this class.</p> + */ +final class ConnectionDescriptor { + public ConnectionDescriptor(String description) + throws com.sun.star.lang.IllegalArgumentException { + for (int i = description.indexOf(','); i >= 0;) { + int j = description.indexOf(',', i + 1); + int k = j < 0 ? description.length() : j; + int l = description.indexOf('=', i + 1); + if (l < 0 || l >= k) { + throw new com.sun.star.lang.IllegalArgumentException( + "parameter lacks '='"); + } + String key = description.substring(i + 1, l); + String value = description.substring(l + 1, k); + if (key.equalsIgnoreCase("host")) { + host = value; + } else if (key.equalsIgnoreCase("port")) { + try { + port = Integer.valueOf(value).intValue(); + } catch (NumberFormatException e) { + throw new com.sun.star.lang.IllegalArgumentException( + e.toString()); + } + if (port < 0 || port > 65535) { + throw new com.sun.star.lang.IllegalArgumentException( + "port parameter must have value between 0 and 65535," + + " inclusive"); + } + } else if (key.equalsIgnoreCase("backlog")) { + try { + backlog = Integer.valueOf(value).intValue(); + } catch (NumberFormatException e) { + throw new com.sun.star.lang.IllegalArgumentException( + e.toString()); + } + } else if (key.equalsIgnoreCase("tcpnodelay")) { + if (value.equals("0")) { + tcpNoDelay = Boolean.FALSE; + } else if (value.equals("1")) { + tcpNoDelay = Boolean.TRUE; + } else { + throw new com.sun.star.lang.IllegalArgumentException( + "tcpnodelay parameter must have 0/1 value"); + } + } + i = j; + } + } + + public String getHost() { + return host; + } + + public int getPort() { + return port; + } + + public int getBacklog() { + return backlog; + } + + public Boolean getTcpNoDelay() { + return tcpNoDelay; + } + + private String host = null; + private int port = 6001; + private int backlog = 50; + private Boolean tcpNoDelay = null; +} diff --git a/jurt/com/sun/star/lib/connections/socket/SocketConnection.java b/jurt/com/sun/star/lib/connections/socket/SocketConnection.java new file mode 100644 index 000000000000..8512bdb49fe1 --- /dev/null +++ b/jurt/com/sun/star/lib/connections/socket/SocketConnection.java @@ -0,0 +1,252 @@ +/************************************************************************* + * + * 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.lib.connections.socket; + + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.InputStream; +import java.io.IOException; +import java.io.OutputStream; + +import java.net.Socket; + +import java.util.Enumeration; +import java.util.Vector; + + +import com.sun.star.io.XStreamListener; + +import com.sun.star.connection.XConnection; +import com.sun.star.connection.XConnectionBroadcaster; + +/** + * The SocketConnection implements the <code>XConnection</code> interface + * and is uses by the <code>SocketConnector</code> and the <code>SocketAcceptor</code>. + * This class is not part of the provided <code>api</code>. + * <p> + * @version $Revision: 1.6 $ $ $Date: 2008-04-11 11:14:31 $ + * @author Kay Ramme + * @see com.sun.star.comp.connections.SocketAcceptor + * @see com.sun.star.comp.connections.SocketConnector + * @see com.sun.star.connections.XConnection + * @since UDK1.0 + */ +public class SocketConnection implements XConnection, XConnectionBroadcaster { + /** + * When set to true, enables various debugging output. + */ + static public final boolean DEBUG = false; + + protected String _description; + protected Socket _socket; + protected InputStream _inputStream; + protected OutputStream _outputStream; + protected Vector _listeners; + protected boolean _firstRead; + + /** + * Constructs a new <code>SocketConnection</code>. + * <p> + * @param description the description of the connection + * @param socket the socket of the connection + */ + public SocketConnection(String description, Socket socket) throws IOException { + if (DEBUG) System.err.println("##### " + getClass().getName() + " - instantiated " + description + " " + socket); + + _description = description + + ",localHost=" + socket.getLocalAddress().getHostName() + + ",localPort=" + socket.getLocalPort() + + ",peerHost=" + socket.getInetAddress().getHostName() + + ",peerPort=" + socket.getPort(); + + _socket = socket; + _inputStream = new BufferedInputStream(socket.getInputStream()); + _outputStream = new BufferedOutputStream(socket.getOutputStream()); + + _listeners = new Vector(); + _firstRead = true; + } + + + + + public void addStreamListener(XStreamListener aListener ) throws com.sun.star.uno.RuntimeException { + _listeners.addElement(aListener); + } + + public void removeStreamListener(XStreamListener aListener ) throws com.sun.star.uno.RuntimeException { + _listeners.removeElement(aListener); + } + + private void notifyListeners_open() { + Enumeration elements = _listeners.elements(); + while(elements.hasMoreElements()) { + XStreamListener xStreamListener = (XStreamListener)elements.nextElement(); + xStreamListener.started(); + } + } + + private void notifyListeners_close() { + Enumeration elements = _listeners.elements(); + while(elements.hasMoreElements()) { + XStreamListener xStreamListener = (XStreamListener)elements.nextElement(); + xStreamListener.closed(); + } + } + + private void notifyListeners_error(com.sun.star.uno.Exception exception) { + Enumeration elements = _listeners.elements(); + while(elements.hasMoreElements()) { + XStreamListener xStreamListener = (XStreamListener)elements.nextElement(); + xStreamListener.error(exception); + } + } + + + /** + * Read the required number of bytes. + * <p> + * @return the number of bytes read + * @param aReadBytes the outparameter, where the bytes have to be placed + * @param nBytesToRead the number of bytes to read + * @see com.sun.star.connections.XConnection#read + */ + public int read(/*OUT*/byte[][] bytes, int nBytesToRead) throws com.sun.star.io.IOException, com.sun.star.uno.RuntimeException { + if(_firstRead) { + _firstRead = false; + + notifyListeners_open(); + } + + String errMessage = null; + + int read_bytes = 0; + bytes[0] = new byte[nBytesToRead]; + + try { + int count = 0; + + do { + count = _inputStream.read(bytes[0], read_bytes, nBytesToRead - read_bytes); + if(count == -1) + errMessage = "EOF reached - " + getDescription(); + + read_bytes += count; + } + while(read_bytes >= 0 && read_bytes < nBytesToRead && count >= 0); + } + catch(IOException ioException) { + if(DEBUG) { + System.err.println("##### " + getClass().getName() + ".read - exception occurred:" + ioException); + ioException.printStackTrace(); + } + + errMessage = ioException.toString(); + } + + if(errMessage != null) { + com.sun.star.io.IOException unoIOException = new com.sun.star.io.IOException(errMessage); + notifyListeners_error(unoIOException); + + throw unoIOException; + } + + if (DEBUG) System.err.println("##### " + getClass().getName() + " - read byte:" + read_bytes + " " + bytes[0]); + + return read_bytes; + } + + /** + * Write bytes. + * <p> + * @param aData the bytes to write + * @see com.sun.star.connections.XConnection#write + */ + public void write(byte aData[]) throws com.sun.star.io.IOException, com.sun.star.uno.RuntimeException { + try { + _outputStream.write(aData); + } + catch(IOException ioException) { + com.sun.star.io.IOException unoIOException = new com.sun.star.io.IOException(ioException.toString()); + notifyListeners_error(unoIOException); + + throw unoIOException; + } + + if (DEBUG) System.err.println("##### " + getClass().getName() + " - written bytes:" + aData + " " + aData.length); + } + + /** + * Flushes the buffer. + * <p> + * @see com.sun.star.connections.XConnection#flush + */ + public void flush() throws com.sun.star.io.IOException, com.sun.star.uno.RuntimeException { + try { + _outputStream.flush(); + } + catch(IOException ioException) { + com.sun.star.io.IOException unoIOException = new com.sun.star.io.IOException(ioException.toString()); + notifyListeners_error(unoIOException); + + throw unoIOException; + } + } + + /** + * Closes the connection. + * <p> + * @see com.sun.star.connections.XConnection#close + */ + public void close() throws com.sun.star.io.IOException, com.sun.star.uno.RuntimeException { + try { + _socket.close(); + } + catch(IOException ioException) { + com.sun.star.io.IOException unoIOException = new com.sun.star.io.IOException(ioException.toString()); + notifyListeners_error(unoIOException); + + throw unoIOException; + } + if (DEBUG) System.err.println("##### " + getClass().getName() + " - socket closed"); + + notifyListeners_close(); + } + + /** + * Gives a description of the connection. + * <p> + * @return the description + * @see com.sun.star.connections.XConnection#getDescription + */ + public String getDescription() throws com.sun.star.uno.RuntimeException { + return _description; + } + +} + diff --git a/jurt/com/sun/star/lib/connections/socket/makefile.mk b/jurt/com/sun/star/lib/connections/socket/makefile.mk new file mode 100644 index 000000000000..a1e437abb605 --- /dev/null +++ b/jurt/com/sun/star/lib/connections/socket/makefile.mk @@ -0,0 +1,42 @@ +#************************************************************************* +# +# 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 +TARGET = com_sun_star_connections_socket + +PACKAGE = com$/sun$/star$/lib$/connections$/socket + +.INCLUDE: $(PRJ)$/util$/makefile.pmk + +JAVAFILES = \ + ConnectionDescriptor.java \ + SocketConnection.java \ + socketAcceptor.java \ + socketConnector.java + +.INCLUDE: target.mk diff --git a/jurt/com/sun/star/lib/connections/socket/socketAcceptor.java b/jurt/com/sun/star/lib/connections/socket/socketAcceptor.java new file mode 100644 index 000000000000..f2119225f029 --- /dev/null +++ b/jurt/com/sun/star/lib/connections/socket/socketAcceptor.java @@ -0,0 +1,207 @@ +/************************************************************************* + * + * 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.lib.connections.socket; + +import com.sun.star.comp.loader.FactoryHelper; +import com.sun.star.connection.AlreadyAcceptingException; +import com.sun.star.connection.ConnectionSetupException; +import com.sun.star.connection.XAcceptor; +import com.sun.star.connection.XConnection; +import com.sun.star.lang.XMultiServiceFactory; +import com.sun.star.lang.XSingleServiceFactory; +import com.sun.star.registry.XRegistryKey; +import java.io.IOException; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.net.Socket; + +/** + * A component that implements the <code>XAcceptor</code> interface. + * + * <p>The <code>socketAcceptor</code> is a specialized component that uses TCP + * sockets for communication. The <code>socketAcceptor</code> is generally used + * by the <code>com.sun.star.connection.Acceptor</code> service.</p> + * + * @see com.sun.star.connections.XAcceptor + * @see com.sun.star.connections.XConnection + * @see com.sun.star.connections.XConnector + * @see com.sun.star.loader.JavaLoader + * + * @since UDK 1.0 + */ +public final class socketAcceptor implements XAcceptor { + /** + * The name of the service. + * + * <p>The <code>JavaLoader</code> acceses this through reflection.</p> + * + * @see com.sun.star.comp.loader.JavaLoader + */ + public static final String __serviceName + = "com.sun.star.connection.socketAcceptor"; + + /** + * Returns a factory for creating the service. + * + * <p>This method is called by the <code>JavaLoader</code>.</p> + * + * @param implName the name of the implementation for which a service is + * requested. + * @param multiFactory the service manager to be used (if needed). + * @param regKey the registry key. + * @return an <code>XSingleServiceFactory</code> for creating the component. + * + * @see com.sun.star.comp.loader.JavaLoader + */ + public static XSingleServiceFactory __getServiceFactory( + String implName, XMultiServiceFactory multiFactory, XRegistryKey regKey) + { + return implName.equals(socketAcceptor.class.getName()) + ? FactoryHelper.getServiceFactory(socketAcceptor.class, + __serviceName, multiFactory, + regKey) + : null; + } + + /** + * Writes the service information into the given registry key. + * + * <p>This method is called by the <code>JavaLoader</code>.</p> + * + * @param regKey the registry key. + * @return <code>true</code> if the operation succeeded. + * + * @see com.sun.star.comp.loader.JavaLoader + */ + public static boolean __writeRegistryServiceInfo(XRegistryKey regKey) { + return FactoryHelper.writeRegistryServiceInfo( + socketAcceptor.class.getName(), __serviceName, regKey); + } + + /** + * Accepts a connection request via the described socket. + * + * <p>This call blocks until a connection has been established.</p> + * + * <p>The connection description has the following format: + * <code><var>type</var></code><!-- + * -->*(<code><var>key</var>=<var>value</var></code>), + * where <code><var>type</var></code> should be <code>socket</code> + * (ignoring case). Supported keys (ignoring case) currently are + * <dl> + * <dt><code>host</code> + * <dd>The name or address of the accepting interface (defaults to + * <code>0</code>, meaning any interface). + * <dt><code>port</code> + * <dd>The TCP port number to accept on (defaults to <code>6001</code>). + * <dt><code>backlog</code> + * <dd>The maximum length of the acceptor's queue (defaults to + * <code>50</code>). + * <dt><code>tcpnodelay</code> + * <dd>A flag (<code>0</code>/<code>1</code>) enabling or disabling Nagle's + * algorithm on the resulting connection. + * </dl></p> + * + * @param connectionDescription the description of the connection. + * @return an <code>XConnection</code> to the client. + * + * @see com.sun.star.connections.XConnection + * @see com.sun.star.connections.XConnector + */ + public XConnection accept(String connectionDescription) throws + AlreadyAcceptingException, ConnectionSetupException, + com.sun.star.lang.IllegalArgumentException + { + ServerSocket serv; + synchronized (this) { + if (server == null) { + ConnectionDescriptor desc + = new ConnectionDescriptor(connectionDescription); + String host = desc.getHost(); + if (host.equals("0")) { + host = null; + } + if (DEBUG) { + System.err.println("##### " + getClass().getName() + + ".accept: creating ServerSocket " + + desc.getPort() + ", " + + desc.getBacklog() + ", " + host); + } + try { + server = new ServerSocket(desc.getPort(), desc.getBacklog(), + host == null ? null + : InetAddress.getByName(host)); + } catch (IOException e) { + throw new ConnectionSetupException(e.toString()); + } + acceptingDescription = connectionDescription; + tcpNoDelay = desc.getTcpNoDelay(); + } else if (!connectionDescription.equals(acceptingDescription)) { + throw new AlreadyAcceptingException(acceptingDescription + + " vs. " + + connectionDescription); + } + serv = server; + } + Socket socket; + try { + socket = serv.accept(); + if (DEBUG) { + System.err.println("##### " + getClass().getName() + + ".accept: accepted " + socket); + } + if (tcpNoDelay != null) { + socket.setTcpNoDelay(tcpNoDelay.booleanValue()); + } + return new SocketConnection(acceptingDescription, socket); + } + catch(IOException e) { + throw new ConnectionSetupException(e.toString()); + } + } + + // see com.sun.star.connection.XAcceptor#stopAccepting + public void stopAccepting() { + ServerSocket serv; + synchronized (this) { + serv = server; + } + try { + serv.close(); + } + catch (IOException e) { + throw new com.sun.star.uno.RuntimeException(e.toString()); + } + } + + private static final boolean DEBUG = false; + + private ServerSocket server = null; + private String acceptingDescription; + private Boolean tcpNoDelay; +} diff --git a/jurt/com/sun/star/lib/connections/socket/socketConnector.java b/jurt/com/sun/star/lib/connections/socket/socketConnector.java new file mode 100644 index 000000000000..f85a5ac41bd0 --- /dev/null +++ b/jurt/com/sun/star/lib/connections/socket/socketConnector.java @@ -0,0 +1,181 @@ +/************************************************************************* + * + * 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.lib.connections.socket; + +import com.sun.star.comp.loader.FactoryHelper; +import com.sun.star.connection.ConnectionSetupException; +import com.sun.star.connection.NoConnectException; +import com.sun.star.connection.XConnection; +import com.sun.star.connection.XConnector; +import com.sun.star.lang.XMultiServiceFactory; +import com.sun.star.lang.XSingleServiceFactory; +import com.sun.star.registry.XRegistryKey; +import java.io.IOException; +import java.net.InetAddress; +import java.net.Socket; +import java.net.UnknownHostException; + +/** + * A component that implements the <code>XConnector</code> interface. + * + * <p>The <code>socketConnector</code> is a specialized component that uses TCP + * sockets for communication. The <code>socketConnector</code> is generally + * used by the <code>com.sun.star.connection.Connector</code> service.</p> + * + * @see com.sun.star.connections.XAcceptor + * @see com.sun.star.connections.XConnection + * @see com.sun.star.connections.XConnector + * @see com.sun.star.loader.JavaLoader + * + * @since UDK 1.0 + */ +public final class socketConnector implements XConnector { + /** + * The name of the service. + * + * <p>The <code>JavaLoader</code> acceses this through reflection.</p> + * + * @see com.sun.star.comp.loader.JavaLoader + */ + public static final String __serviceName + = "com.sun.star.connection.socketConnector"; + + /** + * Returns a factory for creating the service. + * + * <p>This method is called by the <code>JavaLoader</code>.</p> + * + * @param implName the name of the implementation for which a service is + * requested. + * @param multiFactory the service manager to be used (if needed). + * @param regKey the registry key. + * @return an <code>XSingleServiceFactory</code> for creating the component. + * + * @see com.sun.star.comp.loader.JavaLoader + */ + public static XSingleServiceFactory __getServiceFactory( + String implName, XMultiServiceFactory multiFactory, XRegistryKey regKey) + { + return implName.equals(socketConnector.class.getName()) + ? FactoryHelper.getServiceFactory(socketConnector.class, + __serviceName, multiFactory, + regKey) + : null; + } + + /** + * Writes the service information into the given registry key. + * + * <p>This method is called by the <code>JavaLoader</code>.</p> + * + * @param regKey the registry key. + * @return <code>true</code> if the operation succeeded. + * + * @see com.sun.star.comp.loader.JavaLoader + */ + public static boolean __writeRegistryServiceInfo(XRegistryKey regKey) { + return FactoryHelper.writeRegistryServiceInfo( + socketConnector.class.getName(), __serviceName, regKey); + } + + /** + * Connects via the described socket to a waiting server. + * + * <p>The connection description has the following format: + * <code><var>type</var></code><!-- + * -->*(<code><var>key</var>=<var>value</var></code>), + * where <code><var>type</var></code> should be <code>socket</code> + * (ignoring case). Supported keys (ignoring case) currently are + * <dl> + * <dt><code>host</code> + * <dd>The name or address of the server. Must be present. + * <dt><code>port</code> + * <dd>The TCP port number of the server (defaults to <code>6001</code>). + * <dt><code>tcpnodelay</code> + * <dd>A flag (<code>0</code>/<code>1</code>) enabling or disabling Nagle's + * algorithm on the resulting connection. + * </dl></p> + * + * @param connectionDescription the description of the connection. + * @return an <code>XConnection</code> to the server. + * + * @see com.sun.star.connections.XAcceptor + * @see com.sun.star.connections.XConnection + */ + public synchronized XConnection connect(String connectionDescription) + throws NoConnectException, ConnectionSetupException + { + if (connected) { + throw new ConnectionSetupException("alread connected"); + } + ConnectionDescriptor desc; + try { + desc = new ConnectionDescriptor(connectionDescription); + } catch (com.sun.star.lang.IllegalArgumentException e) { + throw new ConnectionSetupException(e.toString()); + } + if (desc.getHost() == null) { + throw new ConnectionSetupException("host parameter missing"); + } + // Try all (IPv4 and IPv6) addresses, in case this client is on a + // dual-stack host and the server process is an IPv4-only process, also + // on a dual-stack host (see Stevens, Fenner, Rudoff: "Unix Network + // Programming, Volume 1: The Sockets Networking API, 3rd Edition", + // p. 359): + InetAddress[] adr; + try { + adr = InetAddress.getAllByName(desc.getHost()); + } catch (UnknownHostException e) { + throw new ConnectionSetupException(e.toString()); + } + Socket socket = null; + for (int i = 0; i < adr.length; ++i) { + try { + socket = new Socket(adr[i], desc.getPort()); + break; + } catch (IOException e) { + if (i == adr.length - 1) { + throw new NoConnectException(e.toString()); + } + } + } + XConnection con; + try { + if (desc.getTcpNoDelay() != null) { + socket.setTcpNoDelay(desc.getTcpNoDelay().booleanValue()); + } + con = new SocketConnection(connectionDescription, socket); + } catch (IOException e) { + throw new NoConnectException(e.toString()); + } + connected = true; + return con; + } + + private boolean connected = false; +} diff --git a/jurt/com/sun/star/lib/uno/Proxy.java b/jurt/com/sun/star/lib/uno/Proxy.java new file mode 100644 index 000000000000..f2a7326c81c0 --- /dev/null +++ b/jurt/com/sun/star/lib/uno/Proxy.java @@ -0,0 +1,40 @@ +/************************************************************************* + * + * 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.lib.uno; + +/** + * Marker interface implemented by proxies for UNO objects. + * + * <p>Currently, this interface is used internally by + * <code>com.sun.star.lib.uno.environments.java.java_environment</code> to + * distinguish between proxies and local objects. Any proxy object that shall + * be registered at the <code>java_environment</code> must implement this marker + * interface.</p> + */ +public interface Proxy { +} diff --git a/jurt/com/sun/star/lib/uno/bridges/java_remote/BridgedObject.java b/jurt/com/sun/star/lib/uno/bridges/java_remote/BridgedObject.java new file mode 100644 index 000000000000..90f037d5ae42 --- /dev/null +++ b/jurt/com/sun/star/lib/uno/bridges/java_remote/BridgedObject.java @@ -0,0 +1,49 @@ +/************************************************************************* + * + * 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.lib.uno.bridges.java_remote; + +import com.sun.star.bridge.XBridge; + +/** + * A back door to access the bridge associated with a bridged object. + */ +public final class BridgedObject { + /** + * Obtains the bridge associated with a bridged object. + * + * @param object a reference to a (Java representation of a) UNO object; + * must not be null + * @return the bridge associated with the given object, if it is indeed + * bridged; otherwise, null is returned + */ + public static XBridge getBridge(Object obj) { + return ProxyFactory.getBridge(obj); + } + + private BridgedObject() {} // do not instantiate +} diff --git a/jurt/com/sun/star/lib/uno/bridges/java_remote/ProxyFactory.java b/jurt/com/sun/star/lib/uno/bridges/java_remote/ProxyFactory.java new file mode 100644 index 000000000000..b81db391966f --- /dev/null +++ b/jurt/com/sun/star/lib/uno/bridges/java_remote/ProxyFactory.java @@ -0,0 +1,185 @@ +/************************************************************************* + * + * 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.lib.uno.bridges.java_remote; + +import com.sun.star.bridge.XBridge; +import com.sun.star.lib.util.AsynchronousFinalizer; +import com.sun.star.uno.IQueryInterface; +import com.sun.star.uno.Type; +import com.sun.star.uno.UnoRuntime; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + +/** + * A factory for proxies specific to the <code>java_remote_bridge</code>. + * + * <p>Eventually, this class should be united with all other proxy classes + * specific to certain bridges (for example, the JNI bridge), resulting in a + * generic proxy class.</p> + */ +final class ProxyFactory { + public ProxyFactory(RequestHandler requestHandler, XBridge bridge) { + this.requestHandler = requestHandler; + this.bridge = bridge; + } + + public Object create(String oid, Type type) { + return Proxy.newProxyInstance( + getClass().getClassLoader(), + new Class[] { com.sun.star.lib.uno.Proxy.class, + IQueryInterface.class, type.getZClass() }, + new Handler(oid, type)); + } + + public boolean isProxy(Object obj) { + if (Proxy.isProxyClass(obj.getClass())) { + InvocationHandler h = Proxy.getInvocationHandler(obj); + return h instanceof Handler && ((Handler) h).matches(this); + } else { + return false; + } + } + + public static XBridge getBridge(Object obj) { + if (Proxy.isProxyClass(obj.getClass())) { + InvocationHandler h = Proxy.getInvocationHandler(obj); + if (h instanceof Handler) { + return ((Handler) h).getBridge(); + } + } + return null; + } + + static int getDebugCount() { + synchronized (debugCountLock) { + return debugCount; + } + } + + private static void incrementDebugCount() { + synchronized (debugCountLock) { + ++debugCount; + } + } + + private static void decrementDebugCount() { + synchronized (debugCountLock) { + --debugCount; + } + } + + private final class Handler implements InvocationHandler { + public Handler(String oid, Type type) { + this.oid = oid; + this.type = type; + incrementDebugCount(); + } + + public boolean matches(ProxyFactory factory) { + return ProxyFactory.this == factory; + } + + public XBridge getBridge() { + return bridge; + } + + public Object invoke(Object proxy, Method method, Object[] args) + throws Throwable + { + if (method.equals(METHOD_EQUALS) || method.equals(METHOD_IS_SAME)) { + return new Boolean( + args[0] != null + && oid.equals(UnoRuntime.generateOid(args[0]))); + } else if (method.equals(METHOD_HASH_CODE)) { + return new Integer(oid.hashCode()); + } else if (method.equals(METHOD_TO_STRING)) { + return "[Proxy:" + System.identityHashCode(proxy) + "," + oid + + "," + type + "]"; + } else if (method.equals(METHOD_QUERY_INTERFACE)) { + // See the comment in java_remote_bridge.mapInterfaceTo for one + // reason why this implementation must not satisfy a request for + // a super-interface with a proxy itself: + return args[0].equals(type) ? proxy + : request("queryInterface", args); + } else if (method.equals(METHOD_GET_OID)) { + return oid; + } else { + return request(method.getName(), args); + } + } + + protected void finalize() { + AsynchronousFinalizer.add(new AsynchronousFinalizer.Job() { + public void run() throws Throwable { + try { + request("release", null); + } finally { + decrementDebugCount(); + } + } + }); + } + + private Object request(String operation, Object[] args) throws Throwable + { + return requestHandler.sendRequest(oid, type, operation, args); + } + + private final String oid; + private final Type type; + } + + private static final Method METHOD_EQUALS; + private static final Method METHOD_HASH_CODE; + private static final Method METHOD_TO_STRING; + private static final Method METHOD_QUERY_INTERFACE; + private static final Method METHOD_IS_SAME; + private static final Method METHOD_GET_OID; + static { + try { + METHOD_EQUALS = Object.class.getMethod( + "equals", new Class[] { Object.class }); + METHOD_HASH_CODE = Object.class.getMethod("hashCode", null); + METHOD_TO_STRING = Object.class.getMethod("toString", null); + METHOD_QUERY_INTERFACE = IQueryInterface.class.getMethod( + "queryInterface", new Class[] { Type.class }); + METHOD_IS_SAME = IQueryInterface.class.getMethod( + "isSame", new Class[] { Object.class }); + METHOD_GET_OID = IQueryInterface.class.getMethod("getOid", null); + } catch (NoSuchMethodException e) { + throw new ExceptionInInitializerError(e); + } + } + + private static final Object debugCountLock = new Object(); + private static int debugCount = 0; + + private final RequestHandler requestHandler; + private final XBridge bridge; +} diff --git a/jurt/com/sun/star/lib/uno/bridges/java_remote/RequestHandler.java b/jurt/com/sun/star/lib/uno/bridges/java_remote/RequestHandler.java new file mode 100644 index 000000000000..5bfe57a95299 --- /dev/null +++ b/jurt/com/sun/star/lib/uno/bridges/java_remote/RequestHandler.java @@ -0,0 +1,41 @@ +/************************************************************************* + * + * 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.lib.uno.bridges.java_remote; + +import com.sun.star.uno.Type; + +/** + * The link between the proxies generated by <code>ProxyFactory</code> (which + * receive requests in the form of method calls) and + * <code>java_remote_bridge</code> (which passes those requests on to the remote + * side). + */ +interface RequestHandler { + Object sendRequest(String oid, Type type, String operation, Object[] args) + throws Throwable; +} diff --git a/jurt/com/sun/star/lib/uno/bridges/java_remote/XConnectionInputStream_Adapter.java b/jurt/com/sun/star/lib/uno/bridges/java_remote/XConnectionInputStream_Adapter.java new file mode 100644 index 000000000000..e663a96d1ea7 --- /dev/null +++ b/jurt/com/sun/star/lib/uno/bridges/java_remote/XConnectionInputStream_Adapter.java @@ -0,0 +1,82 @@ +/************************************************************************* + * + * 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.lib.uno.bridges.java_remote; + + +import java.io.IOException; +import java.io.InputStream; + +import com.sun.star.connection.XConnection; + + +class XConnectionInputStream_Adapter extends InputStream { + static private final boolean DEBUG = false; + + protected XConnection _xConnection; + protected byte _bytes[][] = new byte[1][]; + + XConnectionInputStream_Adapter(XConnection xConnection) { + if(xConnection == null) throw new NullPointerException("the XConnection must not be null"); + + if(DEBUG) System.err.println("#### " + getClass().getName() + " - instantiated "); + + _xConnection = xConnection; + } + + public int read() throws IOException { + + int len = 0; + + try { + len = _xConnection.read(_bytes, 1); + } + catch(com.sun.star.io.IOException ioException) { + throw new IOException(ioException.toString()); + } + + if(DEBUG) System.err.println("#### " + getClass().getName() + " - one byte read:" + _bytes[0][0]); + + return len == 0 ? -1 : _bytes[0][0] & 0xff; + } + + public int read(byte[] b, int off, int len) throws IOException { +// byte bytes[][] = new byte[1][]; + + try { + len = _xConnection.read(_bytes, len - off); + } + catch(com.sun.star.io.IOException ioException) { + throw new IOException(ioException.toString()); + } + + System.arraycopy(_bytes[0], 0, b, off, len); + + return len == 0 ? -1 : len; + } +} + diff --git a/jurt/com/sun/star/lib/uno/bridges/java_remote/XConnectionOutputStream_Adapter.java b/jurt/com/sun/star/lib/uno/bridges/java_remote/XConnectionOutputStream_Adapter.java new file mode 100644 index 000000000000..51f3594330ee --- /dev/null +++ b/jurt/com/sun/star/lib/uno/bridges/java_remote/XConnectionOutputStream_Adapter.java @@ -0,0 +1,91 @@ +/************************************************************************* + * + * 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.lib.uno.bridges.java_remote; + + +import java.io.IOException; +import java.io.OutputStream; + +import com.sun.star.connection.XConnection; + + +class XConnectionOutputStream_Adapter extends OutputStream { + static private final boolean DEBUG = false; + + protected XConnection _xConnection; + protected byte _bytes[] = new byte[1]; + + XConnectionOutputStream_Adapter(XConnection xConnection) { + if(DEBUG) System.err.println("#### " + this.getClass() + " - instantiated "); + + _xConnection = xConnection; + } + + public void write(int b) throws IOException { + _bytes[0] = (byte)b; + + try { + _xConnection.write(_bytes); + } + catch(com.sun.star.io.IOException ioException) { + throw new IOException(ioException.toString()); + } + + if(DEBUG) System.err.println("#### " + this.getClass() + " - one byte written:" + _bytes[0]); + } + + public void write(byte[] b, int off, int len) throws IOException { + byte bytes[] = null; + + if(off == 0 && len == b.length) + bytes = b; + + else { + bytes = new byte[len]; + + System.arraycopy(b, off, bytes, 0, len); + } + + try { + _xConnection.write(bytes); + } + catch(com.sun.star.io.IOException ioException) { + throw new IOException(ioException.toString()); + } + } + + public void flush() throws IOException { + try { + _xConnection.flush(); + } + catch(com.sun.star.io.IOException ioException) { + throw new IOException(ioException.toString()); + } + } +} + diff --git a/jurt/com/sun/star/lib/uno/bridges/java_remote/java_remote_bridge.java b/jurt/com/sun/star/lib/uno/bridges/java_remote/java_remote_bridge.java new file mode 100644 index 000000000000..267a84d7515f --- /dev/null +++ b/jurt/com/sun/star/lib/uno/bridges/java_remote/java_remote_bridge.java @@ -0,0 +1,711 @@ +/************************************************************************* + * + * 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.lib.uno.bridges.java_remote; + + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + + +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Map; +import java.util.Vector; + +import com.sun.star.lib.util.DisposeListener; +import com.sun.star.lib.util.DisposeNotifier; + +import com.sun.star.bridge.XBridge; +import com.sun.star.bridge.XInstanceProvider; + +import com.sun.star.connection.XConnection; +import com.sun.star.lang.EventObject; +import com.sun.star.lang.XComponent; +import com.sun.star.lang.XEventListener; +import com.sun.star.lang.DisposedException; + +import com.sun.star.lib.uno.environments.java.java_environment; +import com.sun.star.lib.uno.environments.remote.IProtocol; +import com.sun.star.lib.uno.environments.remote.IReceiver; +import com.sun.star.lib.uno.environments.remote.Job; +import com.sun.star.lib.uno.environments.remote.Message; +import com.sun.star.lib.uno.environments.remote.ThreadId; +import com.sun.star.lib.uno.environments.remote.ThreadPoolManager; +import com.sun.star.lib.uno.environments.remote.IThreadPool; + +import com.sun.star.lib.uno.typedesc.MethodDescription; +import com.sun.star.lib.uno.typedesc.TypeDescription; + + +import com.sun.star.uno.IBridge; +import com.sun.star.uno.IEnvironment; +import com.sun.star.uno.UnoRuntime; +import com.sun.star.uno.XInterface; +import com.sun.star.uno.Type; +import com.sun.star.uno.TypeClass; +import com.sun.star.uno.Any; + +/** + * This class implements a remote bridge. Therefor + * various interfaces are implemented. + * <p> + * The protocol to used is passed by name, the bridge + * then looks for it under <code>com.sun.star.lib.uno.protocols</code>. + * <p> + * @version $Revision: 1.45 $ $ $Date: 2008-04-11 11:18:08 $ + * @author Kay Ramme + * @since UDK1.0 + */ +public class java_remote_bridge + implements IBridge, IReceiver, RequestHandler, XBridge, XComponent, + DisposeNotifier +{ + /** + * When set to true, enables various debugging output. + */ + static private final boolean DEBUG = false; + + private final class MessageDispatcher extends Thread { + public MessageDispatcher() { + super("MessageDispatcher"); + } + + public void run() { + try { + for (;;) { + synchronized (this) { + if (terminate) { + break; + } + } + Message msg = _iProtocol.readMessage(); + Object obj = null; + if (msg.isRequest()) { + String oid = msg.getObjectId(); + Type type = new Type(msg.getType()); + int fid = msg.getMethod().getIndex(); + if (fid == MethodDescription.ID_RELEASE) { + _java_environment.revokeInterface(oid, type); + remRefHolder(type, oid); + if (msg.isSynchronous()) { + sendReply(false, msg.getThreadId(), null); + } + continue; + } + obj = _java_environment.getRegisteredInterface( + oid, type); + if (obj == null + && fid == MethodDescription.ID_QUERY_INTERFACE) + { + if (_xInstanceProvider == null) { + sendReply( + true, msg.getThreadId(), + new com.sun.star.uno.RuntimeException( + "unknown OID " + oid)); + continue; + } else { + UnoRuntime.setCurrentContext( + msg.getCurrentContext()); + try { + obj = _xInstanceProvider.getInstance(oid); + } catch (com.sun.star.uno.RuntimeException e) { + sendReply(true, msg.getThreadId(), e); + continue; + } catch (Exception e) { + sendReply( + true, msg.getThreadId(), + new com.sun.star.uno.RuntimeException( + e.toString())); + continue; + } finally { + UnoRuntime.setCurrentContext(null); + } + } + } + } + _iThreadPool.putJob( + new Job(obj, java_remote_bridge.this, msg)); + } + } catch (Throwable e) { + dispose(new DisposedException(e.toString())); + } + } + + public synchronized void terminate() { + terminate = true; + } + + private boolean terminate = false; + } + + protected XConnection _xConnection; + + protected XInstanceProvider _xInstanceProvider; + + protected String _name = "remote"; + private final String protocol; + protected IProtocol _iProtocol; + protected IEnvironment _java_environment; + protected MessageDispatcher _messageDispatcher; + protected int _life_count = 0; // determines if this bridge is alife, which is controlled by acquire and release calls + + private final Vector _listeners = new Vector(); + + protected IThreadPool _iThreadPool; + + // Variable disposed must only be used while synchronized on this object: + private boolean disposed = false; + + /** + * This method is for testing only. + */ + int getLifeCount() { + return _life_count; + } + + /** + * This method is for testing only. + */ + IProtocol getProtocol() { + return _iProtocol; + } + + // The ref holder stuff strongly holds objects mapped out via this bridge + // (the java_environment only holds them weakly). When this bridge is + // disposed, all remaining ref holder entries are released. + + private static final class RefHolder { + public RefHolder(Type type, Object object) { + this.type = type; + this.object = object; + } + + public Type getType() { + return type; + } + + public void acquire() { + ++count; + } + + public boolean release() { + return --count == 0; + } + + private final Type type; + private final Object object; + private int count = 1; + } + + private final HashMap refHolders = new HashMap(); + // from OID (String) to LinkedList of RefHolder + + private boolean hasRefHolder(String oid, Type type) { + synchronized (refHolders) { + LinkedList l = (LinkedList) refHolders.get(oid); + if (l != null) { + for (Iterator i = l.iterator(); i.hasNext();) { + RefHolder rh = (RefHolder) i.next(); + if (type.isSupertypeOf(rh.getType())) { + return true; + } + } + } + } + return false; + } + + final void addRefHolder(Object obj, Type type, String oid) { + synchronized (refHolders) { + LinkedList l = (LinkedList) refHolders.get(oid); + if (l == null) { + l = new LinkedList(); + refHolders.put(oid, l); + } + boolean found = false; + for (Iterator i = l.iterator(); !found && i.hasNext();) { + RefHolder rh = (RefHolder) i.next(); + if (rh.getType().equals(type)) { + found = true; + rh.acquire(); + } + } + if (!found) { + l.add(new RefHolder(type, obj)); + } + } + acquire(); + } + + final void remRefHolder(Type type, String oid) { + synchronized (refHolders) { + LinkedList l = (LinkedList) refHolders.get(oid); + if (l != null) { + for (Iterator i = l.iterator(); i.hasNext();) { + RefHolder rh = (RefHolder) i.next(); + if (rh.getType().equals(type)) { + try { + if (rh.release()) { + l.remove(rh); + if (l.isEmpty()) { + refHolders.remove(oid); + } + } + } finally { + release(); + } + break; + } + } + } + } + } + + final void freeHolders() { + synchronized (refHolders) { + for (Iterator i1 = refHolders.entrySet().iterator(); i1.hasNext();) + { + Map.Entry e = (Map.Entry) i1.next(); + String oid = (String) e.getKey(); + LinkedList l = (LinkedList) e.getValue(); + for (Iterator i2 = l.iterator(); i2.hasNext();) { + RefHolder rh = (RefHolder) i2.next(); + for (boolean done = false; !done;) { + done = rh.release(); + _java_environment.revokeInterface(oid, rh.getType()); + release(); + } + } + } + refHolders.clear(); + } + } + + public java_remote_bridge( + IEnvironment java_environment, IEnvironment remote_environment, + Object[] args) + throws Exception + { + _java_environment = java_environment; + String proto = (String) args[0]; + _xConnection = (XConnection) args[1]; + _xInstanceProvider = (XInstanceProvider) args[2]; + if (args.length > 3) { + _name = (String) args[3]; + } + String attr; + int i = proto.indexOf(','); + if (i >= 0) { + protocol = proto.substring(0, i); + attr = proto.substring(i + 1); + } else { + protocol = proto; + attr = null; + } + _iProtocol = (IProtocol) Class.forName( + "com.sun.star.lib.uno.protocols." + protocol + "." + protocol). + getConstructor( + new Class[] { + IBridge.class, String.class, InputStream.class, + OutputStream.class }). + newInstance( + new Object[] { + this, attr, + new XConnectionInputStream_Adapter(_xConnection), + new XConnectionOutputStream_Adapter(_xConnection) }); + proxyFactory = new ProxyFactory(this, this); + _iThreadPool = ThreadPoolManager.create(); + _messageDispatcher = new MessageDispatcher(); + _messageDispatcher.start(); + _iProtocol.init(); + } + + private void notifyListeners() { + EventObject eventObject = new EventObject(this); + + Enumeration elements = _listeners.elements(); + while(elements.hasMoreElements()) { + XEventListener xEventListener = (XEventListener)elements.nextElement(); + + try { + xEventListener.disposing(eventObject); + } + catch(com.sun.star.uno.RuntimeException runtimeException) { + // we are here not interested in any exceptions + } + } + } + + /** + * Constructs a new bridge. + * <p> + * This method is not part of the provided <code>api</code> + * and should only be used by the UNO runtime. + * <p> + * @deprecated as of UDK 1.0 + * <p> + * @param args the custom parameters: arg[0] == protocol_name, arg[1] == xConnection, arg[2] == xInstanceProvider + */ + public java_remote_bridge(Object args[]) throws Exception { + this(UnoRuntime.getEnvironment("java", null), UnoRuntime.getEnvironment("remote", null), args); + } + + // @see com.sun.star.uno.IBridge#mapInterfaceTo + public Object mapInterfaceTo(Object object, Type type) { + checkDisposed(); + if (object == null) { + return null; + } else { + String[] oid = new String[1]; + object = _java_environment.registerInterface(object, oid, type); + if (!proxyFactory.isProxy(object)) { + // This branch must be taken iff object either is no proxy at + // all or a proxy from some other bridge. There are objects + // that behave like objects for this bridge but that are not + // detected as such by proxyFactory.isProxy. The only known + // case of such objects is com.sun.star.comp.beans.Wrapper, + // which implements com.sun.star.lib.uno.Proxy and effectively + // is a second proxy around a proxy that can be from this + // bridge. For that case, there is no problem, however: Since + // the proxies generated by ProxyFactory send each + // queryInterface to the original object (i.e., they do not + // short-circuit requests for a super-interface to themselves), + // there will always be an appropriate ProxyFactory-proxy + // registered at the _java_environment, so that the object + // returned by _java_environment.registerInterface will never be + // a com.sun.star.comp.beans.Wrapper. + addRefHolder(object, type, oid[0]); + } + return oid[0]; + } + } + + /** + * Maps an object from destination environment to the source environment. + * <p> + * @return the object in the source environment + * @param object the object to map + * @param type the interface under which is to be mapped + * @see com.sun.star.uno.IBridge#mapInterfaceFrom + */ + public Object mapInterfaceFrom(Object oId, Type type) { + checkDisposed(); + // TODO What happens if an exception is thrown after the call to + // acquire, but before it is guaranteed that a pairing release will be + // called eventually? + acquire(); + String oid = (String) oId; + Object object = _java_environment.getRegisteredInterface(oid, type); + if (object == null) { + object = _java_environment.registerInterface( + proxyFactory.create(oid, type), new String[] { oid }, type); + // the proxy sends a release when finalized + } else if (!hasRefHolder(oid, type)) { + sendInternalRequest(oid, type, "release", null); + } + return object; + } + + /** + * Gives the source environment. + * <p> + * @return the source environment of this bridge + * @see com.sun.star.uno.IBridge#getSourceEnvironment + */ + public IEnvironment getSourceEnvironment() { + return _java_environment; + } + + /** + * Gives the destination environment. + * <p> + * @return the destination environment of this bridge + * @see com.sun.star.uno.IBridge#getTargetEnvironment + */ + public IEnvironment getTargetEnvironment() { + return null; + } + + /** + * Increases the life count. + * <p> + * @see com.sun.star.uno.IBridge#acquire + */ + public synchronized void acquire() { + ++ _life_count; + + if(DEBUG) System.err.println("##### " + getClass().getName() + ".acquire:" + _life_count); + } + + /** + * Decreases the life count. + * If the life count drops to zero, the bridge disposes itself. + * <p> + * @see com.sun.star.uno.IBridge#release + */ + public void release() { + boolean dispose; + synchronized (this) { + --_life_count; + dispose = _life_count <= 0; + } + if (dispose) { + dispose(new com.sun.star.uno.RuntimeException("end of life")); + } + } + + public void dispose() { + dispose(new com.sun.star.uno.RuntimeException("user dispose")); + } + + private void dispose(Throwable throwable) { + synchronized (this) { + if (disposed) { + return; + } + disposed = true; + } + + notifyListeners(); + for (Iterator i = disposeListeners.iterator(); i.hasNext();) { + ((DisposeListener) i.next()).notifyDispose(this); + } + + try { + _messageDispatcher.terminate(); + + _xConnection.close(); + + if (Thread.currentThread() != _messageDispatcher + && _messageDispatcher.isAlive()) + { + // This is a workaround for a Linux Sun JDK1.3 problem: The + // message dispatcher stays in the socket read method, even if + // the socket has been closed. Suspending and resuming the + // message dispatcher lets it notice the closed socket. Only + // use this workaround for Linux JRE 1.3.0 and 1.3.1 from Sun + // and Blackdown. This workaround is dangerouse and may + // hardlock the VM. + if (System.getProperty("os.name", "").toLowerCase().equals( + "linux") + && System.getProperty("java.version", "").startsWith("1.3.") + && (System.getProperty("java.vendor", "").toLowerCase(). + indexOf("sun") != -1 + || System.getProperty("java.vendor", "").toLowerCase(). + indexOf("blackdown") != -1)) + { + _messageDispatcher.suspend(); + _messageDispatcher.resume(); + } + + _messageDispatcher.join(1000); + if (_messageDispatcher.isAlive()) { + _messageDispatcher.interrupt(); + _messageDispatcher.join(); + } + } + + // interrupt all jobs queued by this bridge + _iThreadPool.dispose(throwable); + + // release all out-mapped objects and all in-mapped proxies: + freeHolders(); + // assert _java_environment instanceof java_environment; + ((java_environment) _java_environment).revokeAllProxies(); + + if (DEBUG) { + if (_life_count != 0) { + System.err.println(getClass().getName() + + ".dispose - life count (proxies left):" + + _life_count); + } + _java_environment.list(); + } + + // clear members + _xConnection = null; + _java_environment = null; + _messageDispatcher = null; + } catch (InterruptedException e) { + System.err.println(getClass().getName() + + ".dispose - InterruptedException:" + e); + } catch (com.sun.star.io.IOException e) { + System.err.println(getClass().getName() + ".dispose - IOException:" + + e); + } + } + + // @see com.sun.star.bridge.XBridge#getInstance + public Object getInstance(String instanceName) { + Type t = new Type(XInterface.class); + return sendInternalRequest( + instanceName, t, "queryInterface", new Object[] { t }); + } + + /** + * Gives the name of this bridge + * <p> + * @return the name of this bridge + * @see com.sun.star.bridge.XBridge#getName + */ + public String getName() { + return _name; + } + + /** + * Gives a description of the connection type and protocol used + * <p> + * @return connection type and protocol + * @see com.sun.star.bridge.XBridge#getDescription + */ + public String getDescription() { + return protocol + "," + _xConnection.getDescription(); + } + + public void sendReply(boolean exception, ThreadId threadId, Object result) { + if (DEBUG) { + System.err.println("##### " + getClass().getName() + ".sendReply: " + + exception + " " + result); + } + + checkDisposed(); + + try { + _iProtocol.writeReply(exception, threadId, result); + } catch (IOException e) { + dispose(e); + throw new DisposedException("unexpected " + e); + } catch (RuntimeException e) { + dispose(e); + throw e; + } catch (Error e) { + dispose(e); + throw e; + } + } + + public Object sendRequest( + String oid, Type type, String operation, Object[] params) + throws Throwable + { + Object result = null; + + checkDisposed(); + + boolean goThroughThreadPool = false; + + ThreadId threadId = _iThreadPool.getThreadId(); + Object handle = _iThreadPool.attach(threadId); + try { + boolean sync; + try { + sync = _iProtocol.writeRequest( + oid, TypeDescription.getTypeDescription(type), operation, + threadId, params); + } catch (IOException e) { + DisposedException d = new DisposedException(e.toString()); + dispose(d); + throw d; + } + if (sync && Thread.currentThread() != _messageDispatcher) { + result = _iThreadPool.enter(handle, threadId); + } + } finally { + _iThreadPool.detach(handle, threadId); + if(operation.equals("release")) + release(); // kill this bridge, if this was the last proxy + } + + if(DEBUG) System.err.println("##### " + getClass().getName() + ".sendRequest left:" + result); + + // On the wire (at least in URP), the result of queryInterface is + // transported as an ANY, but in Java it shall be transported as a + // direct reference to the UNO object (represented as a Java Object), + // never boxed in a com.sun.star.uno.Any: + if (operation.equals("queryInterface") && result instanceof Any) { + Any a = (Any) result; + if (a.getType().getTypeClass() == TypeClass.INTERFACE) { + result = a.getObject(); + } else { + result = null; // should never happen + } + } + + return result; + } + + private Object sendInternalRequest( + String oid, Type type, String operation, Object[] arguments) + { + try { + return sendRequest(oid, type, operation, arguments); + } catch (Error e) { + throw e; + } catch (RuntimeException e) { + throw e; + } catch (Throwable e) { + throw new RuntimeException("Unexpected " + e); + } + } + + // Methods XComponent + public void addEventListener(XEventListener xEventListener) { + _listeners.addElement(xEventListener); + } + + public void removeEventListener(XEventListener xEventListener) { + _listeners.removeElement(xEventListener); + } + + // @see NotifyDispose.addDisposeListener + public void addDisposeListener(DisposeListener listener) { + synchronized (this) { + if (!disposed) { + disposeListeners.add(listener); + return; + } + } + listener.notifyDispose(this); + } + + // This function must only be called while synchronized on this object: + private synchronized void checkDisposed() { + if (disposed) { + throw new DisposedException("java_remote_bridge " + this + + " is disposed"); + } + } + + private final ProxyFactory proxyFactory; + + // Access to disposeListeners must be synchronized on <CODE>this</CODE>: + private final ArrayList disposeListeners = new ArrayList(); +} diff --git a/jurt/com/sun/star/lib/uno/bridges/java_remote/makefile.mk b/jurt/com/sun/star/lib/uno/bridges/java_remote/makefile.mk new file mode 100644 index 000000000000..513565ccdfc2 --- /dev/null +++ b/jurt/com/sun/star/lib/uno/bridges/java_remote/makefile.mk @@ -0,0 +1,44 @@ +#************************************************************************* +# +# 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 + +TARGET := com_sun_star_lib_uno_bridges_java_remote +PACKAGE = com$/sun$/star$/lib$/uno$/bridges$/java_remote + +.INCLUDE: $(PRJ)$/util$/makefile.pmk + +JAVAFILES = \ + BridgedObject.java \ + ProxyFactory.java \ + RequestHandler.java \ + XConnectionInputStream_Adapter.java \ + XConnectionOutputStream_Adapter.java \ + java_remote_bridge.java + +.INCLUDE: target.mk diff --git a/jurt/com/sun/star/lib/uno/environments/java/java_environment.java b/jurt/com/sun/star/lib/uno/environments/java/java_environment.java new file mode 100644 index 000000000000..7be0f9e5366d --- /dev/null +++ b/jurt/com/sun/star/lib/uno/environments/java/java_environment.java @@ -0,0 +1,311 @@ +/************************************************************************* + * + * 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.lib.uno.environments.java; + +import com.sun.star.uno.IEnvironment; +import com.sun.star.uno.Type; +import com.sun.star.uno.UnoRuntime; +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; +import java.util.HashMap; +import java.util.Iterator; + +/** + * The java_environment is the environment where objects and + * interfaces are registered, which are mapped out of java or + * into java. + * + * <p>The java_environment implements the <code>IEnvironment</code> interface + * defined in the uno runtime.</p> + * + * @see com.sun.star.uno.UnoRuntime + * @see com.sun.star.uno.IEnvironment + * @since UDK1.0 + */ +public final class java_environment implements IEnvironment { + public java_environment(Object context) { + this.context = context; + } + + // @see com.sun.star.uno.IEnvironment#getContext + public Object getContext() { + return context; + } + + // @see com.sun.star.uno.IEnvironment#getName + public String getName() { + return "java"; + } + + // @see com.sun.star.uno.IEnvironment#registerInterface + public Object registerInterface(Object object, String[] oid, Type type) { + if (oid[0] == null) { + oid[0] = UnoRuntime.generateOid(object); + } + return (isProxy(object) ? proxies : localObjects).register( + object, oid[0], type); + } + + /** + * You have to revoke ANY interface that has been registered via this + * method. + * + * @param oid object id of interface to be revoked + * @param type the type description of the interface + * @see com.sun.star.uno.IEnvironment#revokeInterface + */ + public void revokeInterface(String oid, Type type) { + if (!proxies.revoke(oid, type)) { + localObjects.revoke(oid, type); + } + } + + /** + * Retrieves an interface identified by its object id and type from this + * environment. + * + * @param oid object id of interface to be retrieved + * @param type the type description of the interface to be retrieved + * @see com.sun.star.uno.IEnvironment#getRegisteredInterface + */ + public Object getRegisteredInterface(String oid, Type type) { + Object o = proxies.get(oid, type); + if (o == null) { + o = localObjects.get(oid, type); + } + return o; + } + + /** + * Retrieves the object identifier for a registered interface from this + * environment. + * + * @param object a registered interface + * @see com.sun.star.uno.IEnvironment#getRegisteredObjectIdentifier + */ + public String getRegisteredObjectIdentifier(Object object) { + return UnoRuntime.generateOid(object); + } + + // @see com.sun.star.uno.IEnvironment#list + public void list() { +// TODO??? +// synchronized (proxies) { +// System.err.println("##### " + getClass().getName() + ".list: " +// + getName() + ", " + getContext()); +// for (Iterator it = proxies.values().iterator(); it.hasNext();) { +// System.err.println("#### entry: " + it.next()); +// } +// } + } + + /** + * Revokes all registered proxy interfaces. + * + * <p>This method should be part of <code>IEnvironment</code>. It is called + * from <code>com.sun.star.lib.uno.bridges.java_remote.<!-- + * -->java_remote_bridge.dispose</code>.</p> + */ + public void revokeAllProxies() { + proxies.clear(); + } + + // TODO What's this??? java.lang.Object#equals requires reflexivity... + // + // Maybe this was hacked in so that different bridges use different + // instances of java_environment. That is desirable for the following + // reason: An OID is bridged in over bridge A, a proxy is created on the + // Java side, and recorded in the java_environment. The same OID is then + // bridged in over another bridge B. If there were only one + // java_environment shared by both bridges, the proxy from bridge A would be + // reused. If now bridge A is taken down programatically (e.g., because + // some controlling code somehow deduced that no objects are mapped over + // that bridge any longer), but the proxy is still used by bridge B, using + // the proxy would now result in errors. The explicit API to control + // bridges forbids to transparently share proxies between bridges, and using + // different java_environment instances for different bridges is the way to + // enforce this. + public boolean equals(Object obj) { + return false; + } + + private static final class Registry { + public synchronized Object register( + Object object, String oid, Type type) + { + cleanUp(); + Level1Entry l1 = level1map.get(oid); + if (l1 != null) { + Level2Entry l2 = l1.level2map.get(type); + if (l2 != null) { + Object o = l2.get(); + if (o != null) { + l2.acquire(); + return o; + } + } + } + // TODO If a holder references an unreachable object, but still has + // a positive count, it is replaced with a new holder (referencing a + // reachable object, and with a count of 1). Any later calls to + // revoke that should decrement the count of the previous holder + // would now decrement the count of the new holder, removing it + // prematurely. This is a design flaw that will be fixed when + // IEnvironment.revokeInterface is changed to no longer use + // counting. (And this problem is harmless, as currently a holder + // either references a strongly held object and uses register/revoke + // to control it, or references a weakly held proxy and never + // revokes it.) + if (l1 == null) { + l1 = new Level1Entry(); + level1map.put(oid, l1); + } + l1.level2map.put(type, new Level2Entry(oid, type, object, queue)); + return object; + } + + public synchronized boolean revoke(String oid, Type type) { + Level1Entry l1 = level1map.get(oid); + Level2Entry l2 = null; + if (l1 != null) { + l2 = l1.level2map.get(type); + if (l2 != null && l2.release()) { + removeLevel2Entry(l1, oid, type); + } + } + cleanUp(); + return l2 != null; + } + + public synchronized Object get(String oid, Type type) { + Level1Entry l1 = level1map.get(oid); + return l1 == null ? null : l1.find(type); + } + + public synchronized void clear() { + level1map.clear(); + cleanUp(); + } + + // must only be called while synchronized on this Registry: + private void cleanUp() { + for (;;) { + Level2Entry l2 = (Level2Entry) queue.poll(); + if (l2 == null) { + break; + } + // It is possible that a Level2Entry e1 for the OID/type pair + // (o,t) becomes weakly reachable, then another Level2Entry e2 + // is registered for the same pair (o,t) (a new Level2Entry is + // created since now e1.get() == null), and only then e1 is + // enqueued. To not erroneously remove the new e2 in that case, + // check whether the map still contains e1: + Level1Entry l1 = level1map.get(l2.oid); + if (l1 != null && l1.level2map.get(l2.type) == l2) { + removeLevel2Entry(l1, l2.oid, l2.type); + } + } + } + + // must only be called while synchronized on this Registry: + private void removeLevel2Entry(Level1Entry l1, String oid, Type type) { + l1.level2map.remove(type); + if (l1.level2map.isEmpty()) { + level1map.remove(oid); + } + } + + private static final class Level1Entry { + // must only be called while synchronized on enclosing Registry: + public Object find(Type type) { + // First, look for an exactly matching entry; then, look for an + // arbitrary entry for a subtype of the request type: + Level2Entry l2 = level2map.get(type); + if (l2 != null) { + Object o = l2.get(); + if (o != null) { + return o; + } + } + for (Iterator<Level2Entry> i = level2map.values().iterator(); + i.hasNext();) + { + l2 = i.next(); + if (type.isSupertypeOf(l2.type)) { + Object o = l2.get(); + if (o != null) { + return o; + } + } + } + return null; + } + + public final HashMap<Type, Level2Entry> level2map = + new HashMap<Type, Level2Entry>(); + } + + private static final class Level2Entry extends WeakReference<Object> { + public Level2Entry( + String oid, Type type, Object object, ReferenceQueue queue) + { + super(object, queue); + this.oid = oid; + this.type = type; + } + + // must only be called while synchronized on enclosing Registry: + public void acquire() { + ++count; + } + + // must only be called while synchronized on enclosing Registry: + public boolean release() { + return --count == 0; + } + + public final String oid; + public final Type type; + + private int count = 1; + } + + private final HashMap<String, Level1Entry> level1map = + new HashMap<String, Level1Entry>(); + private final ReferenceQueue queue = new ReferenceQueue(); + } + + private boolean isProxy(Object object) { + return object instanceof com.sun.star.lib.uno.Proxy; + } + + private static final Registry localObjects = new Registry(); + + private final Object context; + private final Registry proxies = new Registry(); +} diff --git a/jurt/com/sun/star/lib/uno/environments/java/makefile.mk b/jurt/com/sun/star/lib/uno/environments/java/makefile.mk new file mode 100644 index 000000000000..de9bb6178f4f --- /dev/null +++ b/jurt/com/sun/star/lib/uno/environments/java/makefile.mk @@ -0,0 +1,44 @@ +#************************************************************************* +# +# 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$/lib$/uno$/environments$/java +TARGET = com_sun_star_lib_uno_environments_java + +# --- Settings ----------------------------------------------------- + +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +JAVAFILES = java_environment.java + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + diff --git a/jurt/com/sun/star/lib/uno/environments/remote/IProtocol.java b/jurt/com/sun/star/lib/uno/environments/remote/IProtocol.java new file mode 100644 index 000000000000..1fae45e9ca23 --- /dev/null +++ b/jurt/com/sun/star/lib/uno/environments/remote/IProtocol.java @@ -0,0 +1,97 @@ +/************************************************************************* + * + * 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.lib.uno.environments.remote; + +import com.sun.star.lib.uno.typedesc.TypeDescription; +import java.io.IOException; + +/** + * An abstraction of remote bridge protocols. + * + * <p>A class implementing a given protocol <var>prot</var> must be named + * <code>com.sun.star.lib.uno.protocols.<var>prot</var>.<var>prot</var></code> + * and must have a public constructor that takes four arguments: The first + * argument of type <code>com.sun.star.uno.IBridge</code> must not be null. The + * second argument of type <code>String</code> represents any attributes; it may + * be null if there are no attributes. The third argument of type + * <code>java.io.InputStream</code> must not be null. The fourth argument of + * type <code>java.io.OutputStream</code> must not be null.</p> + */ +public interface IProtocol { + /** + * Initializes the connection. + * + * <p>This method must be called exactly once, after the + * <code>readMessage</code> loop has already been established.</p> + */ + void init() throws IOException; + + /** + * Reads a request or reply message. + * + * <p>Access to this method from multiple threads must be properly + * synchronized.</p> + * + * @return a non-null message; if the input stream is exhausted, a + * <code>java.io.IOException</code> is thrown instead + */ + Message readMessage() throws IOException; + + /** + * Writes a request message. + * + * @param oid a non-null OID + * @param type a non-null UNO type + * @param function a non-null function (the name of a UNO interface method + * or attribute compatible with the given <code>type</code>, or either + * <code>"queryInterface"</code> or <code>"release"</code>) + * @param threadId a non-null TID + * @param arguments a list of UNO arguments compatible with the given + * <code>type</code> and <code>function</code>; may be null to represent + * an empty list + * @return <code>true</code> if the request message is sent as a synchronous + * request + */ + boolean writeRequest( + String oid, TypeDescription type, String function, ThreadId tid, + Object[] arguments) + throws IOException; + + /** + * Writes a reply message. + * + * @param exception <code>true</code> if the reply corresponds to a raised + * exception + * @param tid a non-null TID + * @param result if <code>exception</code> is <code>true</code>, a non-null + * UNO exception; otherwise, a UNO return value, which may be null to + * represent a <code>VOID</code> return value + */ + void writeReply(boolean exception, ThreadId tid, Object result) + throws IOException; +} diff --git a/jurt/com/sun/star/lib/uno/environments/remote/IReceiver.java b/jurt/com/sun/star/lib/uno/environments/remote/IReceiver.java new file mode 100644 index 000000000000..be4548e5ebc0 --- /dev/null +++ b/jurt/com/sun/star/lib/uno/environments/remote/IReceiver.java @@ -0,0 +1,48 @@ +/************************************************************************* + * + * 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.lib.uno.environments.remote; + +/** + * An abstraction for giving back a reply for a request. + * + * @version $Revision: 1.6 $ $ $Date: 2008-04-11 11:19:43 $ + * @author Kay Ramme + * @see com.sun.star.uno.IQueryInterface + */ +public interface IReceiver { + /** + * Send back a reply for a request. + * + * @param exception <CODE>true</CODE> if an exception (instead of a normal + * result) is sent back. + * @param threadId the thread ID of the request. + * @param result the result of executing the request, or an exception thrown + * while executing the request. + */ + void sendReply(boolean exception, ThreadId threadId, Object result); +} diff --git a/jurt/com/sun/star/lib/uno/environments/remote/IThreadPool.java b/jurt/com/sun/star/lib/uno/environments/remote/IThreadPool.java new file mode 100644 index 000000000000..c70ccfa7e934 --- /dev/null +++ b/jurt/com/sun/star/lib/uno/environments/remote/IThreadPool.java @@ -0,0 +1,127 @@ +/************************************************************************* + * + * 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.lib.uno.environments.remote; + +/** + * This interface is an abstraction of the various + * threadpool implementations. + * <p> + * @version $Revision: 1.7 $ $ $Date: 2008-04-11 11:20:01 $ + * @author Joerg Budischewski + * @author Kay Ramme + * @see com.sun.star.lib.uno.environments.remote.ThreadPoolFactory + * @see com.sun.star.lib.uno.environments.remote.IThreadPoolFactory + * @since UDK1.0 + */ +public interface IThreadPool { + /** + * Retrieves the global threadId for the current thread. + * <p> + * @return the thread id + */ + ThreadId getThreadId(); + + /** + * Attaches this thread to the thread pool. + * <p> + * @see #enter + */ + public void attach(); + + /** + * As above, but hands in an already existing + * instance of the threadid of the current thread. + * Returns a handle which can be used in enter and + * detach calls.<p> + * The function exists for performance + * optimization reasons. + * @see #attach + */ + public Object attach( ThreadId id ); + + /** + * Detaches this thread from the thread pool. + * @see #enter + */ + public void detach(); + + /** + * As above, but hands in an already existing + * instance of the threadid of the current thread + * and a handle returned by attach. + * The function exists for performance + * optimization reasons. + * @see #attach,#detach + */ + public void detach( Object handle, ThreadId id ); + + /** + * Lets this thread enter the thread pool. + * This thread then executes all jobs put via + * <code>putJob</code> until a reply job arrives. + * <p> + * @see #putJob + */ + public Object enter() throws Throwable; + + /** + * as above but hands in an already existing + * instance of the threadid of the current thread + * and a handle returned by attach. + * This thread then executes all jobs put via + * <code>putJob</code> until a reply job arrives. + * <p> + * @see #putJob + */ + public Object enter( Object handle, ThreadId id ) throws Throwable; + + /** + * Queues a job into the jobQueue of the thread belonging + * to the jobs threadId. + * <p> + * @param job the job + */ + public void putJob(Job job); + + /** + * Disposes this thread pool, thus releasing + * all threads by throwing the given + * <code>Throwable</code>. + * <p> + * @param throwing the Throwable + */ + public void dispose(Throwable throwable); + + + /** + * Destroys the thread pool and tries + * to join all created threads immediatly. + */ + public void destroy(); +} + diff --git a/jurt/com/sun/star/lib/uno/environments/remote/JavaThreadPool.java b/jurt/com/sun/star/lib/uno/environments/remote/JavaThreadPool.java new file mode 100644 index 000000000000..3b1fee02b87d --- /dev/null +++ b/jurt/com/sun/star/lib/uno/environments/remote/JavaThreadPool.java @@ -0,0 +1,132 @@ +/************************************************************************* + * + * 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.lib.uno.environments.remote; + +/** + * This class implements a java thread pool. + * <p> + * @version $Revision: 1.13 $ $ $Date: 2008-04-11 11:20:22 $ + * @author Kay Ramme + * @see com.sun.star.uno.UnoRuntime + * @see com.sun.star.lib.uno.environments.remote.ThreadPool + * @see com.sun.star.lib.uno.environments.remote.IThreadPool + * @see com.sun.star.lib.uno.environments.remote.Job + * @see com.sun.star.lib.uno.environments.remote.JobQueue + * @since UDK1.0 + */ +public class JavaThreadPool implements IThreadPool { + /** + * When set to true, enables various debugging output. + */ + private static final boolean DEBUG = false; + + JavaThreadPoolFactory _javaThreadPoolFactory; + + JavaThreadPool(JavaThreadPoolFactory javaThreadPoolFactory) { + _javaThreadPoolFactory = javaThreadPoolFactory; + } + + public ThreadId getThreadId() { + return JavaThreadPoolFactory.getThreadId(); + } + + public Object attach( ThreadId threadId ) + { + if(DEBUG) System.err.println("##### " + getClass().getName() + ".attach - id:" + threadId); + JobQueue jobQueue = _javaThreadPoolFactory.getJobQueue(threadId); + if(jobQueue == null) + jobQueue = new JobQueue(_javaThreadPoolFactory, threadId, false); + + // acquiring the jobQueue registers it at the ThreadPoolFactory + jobQueue.acquire(); + return jobQueue; + } + + public void attach() { + attach( getThreadId() ); + } + + public void detach( Object handle, ThreadId id ) + { + ((JobQueue)handle).release(); + } + + public void detach() { + ThreadId threadId = getThreadId(); + detach(_javaThreadPoolFactory.getJobQueue(threadId), threadId ); + } + + + public Object enter( ) throws Throwable { + ThreadId threadId = getThreadId(); + return enter( _javaThreadPoolFactory.getJobQueue( threadId ), threadId ); + } + + public Object enter( Object handle, ThreadId threadId ) throws Throwable { + return ((JobQueue)handle).enter(this); + } + + public void putJob(Job job) { + if (!job.isRequest() || job.isSynchronous()) { + JobQueue jobQueue = _javaThreadPoolFactory.getJobQueue(job.getThreadId()); + + // this has not be synchronized, cause + // sync jobs can only come over one bridge + // (cause the thread blocks on other side) + if(jobQueue == null) + jobQueue = new JobQueue(_javaThreadPoolFactory, job.getThreadId(), true); + + // put job acquires the queue and registers it at the ThreadPoolFactory + jobQueue.putJob(job, this); + } + else { + // this has to be synchronized, cause + // async jobs of the same thread can come + // over different bridges + synchronized(_javaThreadPoolFactory) { + JobQueue async_jobQueue = _javaThreadPoolFactory.getAsyncJobQueue(job.getThreadId()); + + // ensure there is jobQueue + if(async_jobQueue == null) // so, there is really no async queue + async_jobQueue = new JobQueue(_javaThreadPoolFactory, job.getThreadId()); + + // put job acquires the queue and registers it at the ThreadPoolFactory + async_jobQueue.putJob(job, this); + } + } + } + + public void dispose(Throwable throwable) { + if(DEBUG) System.err.println("##### " + getClass().getName() + ".dispose:" + throwable); + + _javaThreadPoolFactory.dispose(this, throwable); + } + + public void destroy() { + } +} diff --git a/jurt/com/sun/star/lib/uno/environments/remote/JavaThreadPoolFactory.java b/jurt/com/sun/star/lib/uno/environments/remote/JavaThreadPoolFactory.java new file mode 100644 index 000000000000..868a4559a577 --- /dev/null +++ b/jurt/com/sun/star/lib/uno/environments/remote/JavaThreadPoolFactory.java @@ -0,0 +1,94 @@ +/************************************************************************* + * + * 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.lib.uno.environments.remote; + +import java.util.Collection; +import java.util.HashMap; +import java.util.WeakHashMap; + +final class JavaThreadPoolFactory { + public JavaThreadPoolFactory() {} + + public IThreadPool createThreadPool() { + return new JavaThreadPool(this); + } + + public void addJobQueue(JobQueue jobQueue) { + synchronized (jobQueues) { + jobQueues.put(jobQueue.getThreadId(), jobQueue); + } + } + + public void removeJobQueue(JobQueue jobQueue) { + synchronized (jobQueues) { + jobQueues.remove(jobQueue.getThreadId()); + } + } + + public JobQueue getJobQueue(ThreadId threadId) { + synchronized (jobQueues) { + return (JobQueue) jobQueues.get(threadId); + } + } + + public JobQueue getAsyncJobQueue(ThreadId threadId) { + JobQueue q = getJobQueue(threadId); + return q == null ? null : q._async_jobQueue; + } + + public void dispose(Object disposeId, Throwable throwable) { + JobQueue[] qs; + synchronized (jobQueues) { + Collection c = jobQueues.values(); + qs = (JobQueue[]) c.toArray(new JobQueue[c.size()]); + } + for (int i = 0; i < qs.length; ++i) { + qs[i].dispose(disposeId, throwable); + } + } + + public static ThreadId getThreadId() { + Thread t = Thread.currentThread(); + if (t instanceof JobQueue.JobDispatcher) { + return ((JobQueue.JobDispatcher) t).getThreadId(); + } else { + ThreadId id; + synchronized (threadIdMap) { + id = (ThreadId) threadIdMap.get(t); + if (id == null) { + id = ThreadId.createFresh(); + threadIdMap.put(t, id); + } + } + return id; + } + } + + private static final WeakHashMap threadIdMap = new WeakHashMap(); + private final HashMap jobQueues = new HashMap(); +} diff --git a/jurt/com/sun/star/lib/uno/environments/remote/Job.java b/jurt/com/sun/star/lib/uno/environments/remote/Job.java new file mode 100644 index 000000000000..41cf9706f2b6 --- /dev/null +++ b/jurt/com/sun/star/lib/uno/environments/remote/Job.java @@ -0,0 +1,180 @@ +/************************************************************************* + * + * 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.lib.uno.environments.remote; + + +import java.io.PrintWriter; +import java.io.StringWriter; + + +import java.lang.reflect.InvocationTargetException; + +import com.sun.star.lib.uno.typedesc.MethodDescription; +import com.sun.star.uno.Any; +import com.sun.star.uno.IMethodDescription; +import com.sun.star.uno.Type; +import com.sun.star.uno.UnoRuntime; +import com.sun.star.uno.XCurrentContext; + +/** + * The Job is an abstraction for tasks which have to be done + * remotely because of a method invocation. + * <p> + * @version $Revision: 1.17 $ $ $Date: 2008-04-11 11:21:00 $ + * @author Kay Ramme + * @see com.sun.star.lib.uno.environments.remote.ThreadID + * @see com.sun.star.lib.uno.environments.remote.IReceiver + * @since UDK1.0 + */ +public class Job { + protected Job _next; + + protected IReceiver _iReceiver; + protected Message _iMessage; + Object _disposeId; + + protected Object _object; + + public Job(Object object, IReceiver iReceiver, Message iMessage) { + _object = object; + _iReceiver = iReceiver; + _iMessage = iMessage; + } + + /** + * Dispatches a <code>queryInterface</code> call + * <p> + * @return the result of the call (should be an <code>Any</code>) + * @param message the parameter for the call + * @param resultClass the result type as an out parameter + * @param status the status as an out parameter + * @param o_outs the out parameters of the call as out parameters + * @param o_out_sig the out signature as an out parameter + */ + protected Object dispatch_queryInterface(Type type) { + Class zInterface = type.getTypeDescription().getZClass(); + + Object result = null; + + Object face = UnoRuntime.queryInterface(zInterface, _object); + // the hell knows why, but empty interfaces a given back as void anys + if(face != null) + result = new Any(type, face); + return result; + } + + /** + * Execute the job. + * + * @return the result of the message. + */ + public Object execute() throws Throwable { + Object msgResult = _iMessage.getResult(); + if (_iMessage.isRequest()) { + Object result = null; + Throwable exception = null; + IMethodDescription md = _iMessage.getMethod(); + Object[] args = _iMessage.getArguments(); + XCurrentContext oldCC = UnoRuntime.getCurrentContext(); + UnoRuntime.setCurrentContext(_iMessage.getCurrentContext()); + try { + result = md.getIndex() == MethodDescription.ID_QUERY_INTERFACE + ? dispatch_queryInterface((Type) args[0]) + : md.getMethod().invoke(_object, args); + } catch (InvocationTargetException e) { + exception = e.getTargetException(); + if (exception == null) { + exception = e; + } + } catch (Exception e) { + exception = e; + } finally { + UnoRuntime.setCurrentContext(oldCC); + } + if (_iMessage.isSynchronous()) { + if (exception == null) { + _iReceiver.sendReply( + false, _iMessage.getThreadId(), result); + } else { + // Here we have to be aware of non-UNO exceptions, because + // they may kill a remote side which does not know anything + // about their types: + if (exception != null + && !(exception instanceof com.sun.star.uno.Exception) + && !(exception instanceof + com.sun.star.uno.RuntimeException)) + { + StringWriter writer = new StringWriter(); + exception.printStackTrace(new PrintWriter(writer)); + exception = new com.sun.star.uno.RuntimeException( + "Java exception: <" + writer + ">", null); + } + _iReceiver.sendReply( + true, _iMessage.getThreadId(), exception); + } + } + return null; + } else if (_iMessage.isAbnormalTermination()) { + throw remoteUnoRequestRaisedException(_iMessage.getResult()); + } else { + return _iMessage.getResult(); + } + } + + public ThreadId getThreadId() { + return _iMessage.getThreadId(); + } + + public boolean isRequest() { + return _iMessage.isRequest(); + } + + public boolean isSynchronous() { + return _iMessage.isSynchronous(); + } + + public void dispose() { +// _oId = null; +// _iReceiver = null; +// _threadId = null; +// _object = null; +// _operation = null; +// _param = null; +// _exception = null; +// _zInterface = null; +// _disposeId = null; + } + + // The name of this method is chosen to generate a somewhat self-explanatory + // stack trace: + private Exception remoteUnoRequestRaisedException(Object exception) { + Exception e = (Exception) exception; + e.fillInStackTrace(); + return e; + } +} diff --git a/jurt/com/sun/star/lib/uno/environments/remote/JobQueue.java b/jurt/com/sun/star/lib/uno/environments/remote/JobQueue.java new file mode 100644 index 000000000000..f7568a30cef7 --- /dev/null +++ b/jurt/com/sun/star/lib/uno/environments/remote/JobQueue.java @@ -0,0 +1,396 @@ +/************************************************************************* + * + * 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.lib.uno.environments.remote; + + +/** + * The <code>JobQueue</code> implements a queue for jobs. + * For every jobs thread id exists a job queue which is registered + * at the <code>ThreadPool</code>. + * A JobQueue is splitted in a sync job queue and an async job queue. + * The sync job queue is the registerd queue, it delegates async jobs + * (put by <code>putjob</code>) into the async queue, which is only + * known by the sync queue. + * <p> + * @version $Revision: 1.19 $ $ $Date: 2008-04-11 11:21:18 $ + * @author Kay Ramme + * @see com.sun.star.lib.uno.environments.remote.ThreadPool + * @see com.sun.star.lib.uno.environments.remote.Job + * @see com.sun.star.lib.uno.environments.remote.ThreadID + * @since UDK1.0 + */ +public class JobQueue { + /** + * When set to true, enables various debugging output. + */ + private static final boolean DEBUG = false; + + protected Job _head; // the head of the job list + protected Job _tail; // the tail of the job list + + protected ThreadId _threadId; // the thread id of the queue + protected int _ref_count = 0; // the stack deepness + protected boolean _createThread; // create a worker thread, if needed + protected boolean _createThread_now; // create a worker thread, if needed + protected Thread _worker_thread; // the thread that does the jobs + + protected Object _disposeId; // the active dispose id + protected Object _doDispose = null; + protected Throwable _throwable; + + protected JobQueue _async_jobQueue; // chaining job qeueus for asyncs + protected JobQueue _sync_jobQueue; // chaining job qeueus for syncs + + protected boolean _active = false; + + protected JavaThreadPoolFactory _javaThreadPoolFactory; + + /** + * A thread for dispatching jobs + */ + class JobDispatcher extends Thread { + Object _disposeId; + + JobDispatcher(Object disposeId) { + if(DEBUG) System.err.println("JobQueue$JobDispatcher.<init>:" + _threadId); + + _disposeId = disposeId; + } + + ThreadId getThreadId() { + return _threadId; + } + + public void run() { + if(DEBUG) System.err.println("ThreadPool$JobDispatcher.run: " + Thread.currentThread()); + + try { + enter(2000, _disposeId); + } + catch(Throwable throwable) { + if(_head != null || _active) { // there was a job in progress, so give a stack + System.err.println(getClass().getName() + " - exception occurred:" + throwable); + throwable.printStackTrace(System.err); + } + } + finally { + release(); + } + + if(DEBUG) System.err.println("##### " + getClass().getName() + ".run - exit:" + _threadId); + +// try { +// Object object = new Object(); +// synchronized(object) { +// object.wait(); +// } +// } +// catch(InterruptedException interruptedException) { +// } + } + } + + + /** + * Constructs a async job queue with the given thread id + * which belongs to the given sync job queue. + * <p> + * @param threadId the thread id + * @param sync_jobQueue the sync queue this async queue belongs to + * @see com.sun.star.lib.uno.environments.remote.ThreadID + */ + JobQueue(JavaThreadPoolFactory javaThreadPoolFactory, ThreadId threadId) { + _javaThreadPoolFactory = javaThreadPoolFactory; + _threadId = ThreadId.createFresh(); + + _sync_jobQueue = javaThreadPoolFactory.getJobQueue(threadId); + if(_sync_jobQueue == null) { + _sync_jobQueue = new JobQueue(javaThreadPoolFactory, threadId, true); + _sync_jobQueue.acquire(); + } + + _sync_jobQueue._async_jobQueue = this; + + _createThread = true; + _createThread_now = true; + + acquire(); + + if(DEBUG) System.err.println("##### " + getClass().getName() + " - init:" + _threadId); + } + + /** + * Constructs a sync job queue with the given thread id and the given thread. + * <p> + * @param threadId the thread id + * @param createThread if true, the queue creates a worker thread if needed + * @see com.sun.star.lib.uno.environments.remote.ThreadID + */ + JobQueue(JavaThreadPoolFactory javaThreadPoolFactory, ThreadId threadId, boolean createThread){ + _javaThreadPoolFactory = javaThreadPoolFactory; + _threadId = threadId; + _createThread = createThread; + _createThread_now = createThread; + + if(DEBUG) System.err.println("##### " + getClass().getName() + " - init:" + _threadId + " " + createThread); + } + + /** + * Gives the thread id of this queue + * <p> + * @return the thread id + * @see com.sun.star.lib.uno.environments.remote.ThreadID + */ + ThreadId getThreadId() { + return _threadId; + } + + synchronized void acquire() { + // add only synchronous queues . + if(_ref_count <= 0 && _sync_jobQueue == null ) + _javaThreadPoolFactory.addJobQueue(this); + + ++ _ref_count; + } + + synchronized void release() { + -- _ref_count; + + if(_ref_count <= 0) { + // only synchronous queues needs to be removed . + if( _sync_jobQueue == null ) + _javaThreadPoolFactory.removeJobQueue(this); + + + if(_sync_jobQueue != null) { + _sync_jobQueue._async_jobQueue = null; + _sync_jobQueue.release(); + } + } + } + + /** + * Removes a job from the queue. + * <p> + * @return a job or null if timed out + * @param waitTime the maximum amount of time to wait for a job + */ + private Job removeJob(int waitTime) throws Throwable { + if(DEBUG) System.err.println("##### " + getClass().getName() + ".removeJob:" + _head + " " + _threadId); + + Job job = null; + synchronized (this) { + // wait max. waitTime time for a job to enter the queue + boolean waited = false; + while(_head == null && (waitTime == 0 || !waited)) { + if(_doDispose == _disposeId) { + _doDispose = null; + throw _throwable; + } + + // notify sync queues + notifyAll(); + + try { + // wait for new job + wait(waitTime); + } + catch(InterruptedException interruptedException) { + throw new com.sun.star.uno.RuntimeException(getClass().getName() + ".removeJob - unexpected:" + interruptedException); + } + + // signal that we have already waited once + waited = true; + } + + + if(_head != null) { + Job current = _head; + _head = _head._next; + + if(_head == null) + _tail = null; + + job = current; + _active = true; + } + } + + // always wait for asynchron jobqueue to be finished ! + if(job != null && _async_jobQueue != null) { + synchronized(_async_jobQueue) { + // wait for async queue to be empty and last job to be done + while(_async_jobQueue._active || _async_jobQueue._head != null) { + if(DEBUG) System.err.println("waiting for async:" + _async_jobQueue._head + " " + _async_jobQueue._worker_thread); + + if(_doDispose == _disposeId) { + _doDispose = null; + throw _throwable; + } + + try { + _async_jobQueue.wait(); + } + catch(InterruptedException interruptedException) { + throw new com.sun.star.uno.RuntimeException(getClass().getName() + ".removeJob - unexpected:" + interruptedException); + } + } + } + } + + return job; + } + + /** + * Puts a job into the queue. + * <p> + * @param job the job + * @param disposeId a dispose id + */ + synchronized void putJob(Job job, Object disposeId) { + if(DEBUG) System.err.println("##### " + getClass().getName() + ".putJob todoes: " + " job:" + job); + + if(_tail != null) + _tail._next = job; + else + _head = job; + + _tail = job; + + if(_worker_thread == null && _createThread && _createThread_now) { // if there is no thread, which dispatches and if shall create one, create one + + acquire(); + + _createThread_now = false; + new JobDispatcher(disposeId).start(); + } + + // always notify possible waiters + notifyAll(); + } + + /** + * Enters the job queue. + * <p> + * @return the result of the final job (reply) + * @param disposeId a dispose id + */ + Object enter(Object disposeId) throws Throwable { + return enter(0, disposeId); // wait infinitly + } + + /** + * Enters the job queue. + * <p> + * @return the result of the final job (reply) + * @param waitTime the maximum amount of time to wait for a job (0 means wait infinitly) + * @param disposeId a dispose id + */ + Object enter(int waitTime, Object disposeId) throws Throwable { + if(DEBUG) System.err.println("#####" + getClass().getName() + ".enter: " + _threadId); + + boolean quit = false; + + Object hold_disposeId = _disposeId; + _disposeId = disposeId; + + Object result = null; + + Thread hold_worker_thread = _worker_thread; + _worker_thread = Thread.currentThread(); + + while(!quit) { + Job job = null; + + try { + job = removeJob(waitTime); + + if(job != null) { + try { + result = job.execute(); + } + finally { + _active = false; + } + + if (!job.isRequest()) { + job.dispose(); + + quit = true; + } + + job = null; + } + else + quit = true; + + + } + finally { // ensure that this queue becomes disposed, if necessary + if(DEBUG) System.err.println("##### " + getClass().getName() + ".enter leaving: " + _threadId + " " + _worker_thread + " " + hold_worker_thread + " " + result); + + synchronized(this) { + if(job != null || (quit && _head == null)) { + _worker_thread = hold_worker_thread; + + _createThread_now = true; + + _disposeId = hold_disposeId; + + if(_sync_jobQueue != null) + notifyAll(); // notify waiters (e.g. this is an asyncQueue and there is a sync waiting) + } + else + quit = false; + + } + } + } + + return result; + } + + /** + * If the given disposeId is registered, + * interrups the worker thread. + * <p> + * @param disposeId the dispose id + */ + synchronized void dispose(Object disposeId, Throwable throwable) { + if(_sync_jobQueue == null) { // dispose only sync queues + _doDispose = disposeId; + _throwable = throwable; + + // get thread out of wait and let it throw the throwable + if(DEBUG) System.err.println(getClass().getName() + ".dispose - notifying thread"); + + notifyAll(); + } + } +} + diff --git a/jurt/com/sun/star/lib/uno/environments/remote/Message.java b/jurt/com/sun/star/lib/uno/environments/remote/Message.java new file mode 100644 index 000000000000..918b9b1282ad --- /dev/null +++ b/jurt/com/sun/star/lib/uno/environments/remote/Message.java @@ -0,0 +1,195 @@ +/************************************************************************* + * + * 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.lib.uno.environments.remote; + +import com.sun.star.uno.IMethodDescription; +import com.sun.star.uno.ITypeDescription; +import com.sun.star.uno.XCurrentContext; + +/** + A remote request or reply message. +*/ +public class Message { + public Message( + ThreadId threadId, boolean request, String objectId, + ITypeDescription type, IMethodDescription method, boolean synchronous, + XCurrentContext currentContext, boolean abnormalTermination, + Object result, Object[] arguments) + { + this.threadId = threadId; + this.request = request; + this.objectId = objectId; + this.type = type; + this.method = method; + this.synchronous = synchronous; + this.currentContext = currentContext; + this.abnormalTermination = abnormalTermination; + this.result = result; + this.arguments = arguments; + } + + /** + Returns the thread ID of the message. + + <p>Valid for all kinds of messages.</p> + + @return the (non-<code>null</code>) thread ID + */ + public final ThreadId getThreadId() { + return threadId; + } + + /** + Returns whether the message is a request or a reply. + + <p>Valid for all kinds of messages.</p> + + @return <code>true</code> for a request, <code>false</code> for a reply + */ + public final boolean isRequest() { + return request; + } + + /** + Returns the object ID of a request message. + + <p>Valid only for request messages.</p> + + @return the (non-<code>null</code>) object ID for a request, + <code>null</code> for a reply + */ + public final String getObjectId() { + return objectId; + } + + /** + Returns the type of a request message. + + <p>Valid only for request messages.</p> + + @return the (non-<code>null</code>) type for a request, <code>null</code> + for a reply + */ + public final ITypeDescription getType() { + return type; + } + + /** + Returns the method description of a request message. + + <p>Valid only for request messages. The returned + <code>IMethodDescription</code> is consistent with the type of the + message.</p> + + @return the (non-<code>null</code>) method description for a request, + <code>null</code> for a reply + */ + public final IMethodDescription getMethod() { + return method; + } + + /** + Returns whether the request message is synchronous. + + <p>Valid only for request messages.</p> + + @return <code>true</code> for a synchronous request, <code>false</code> + for an asynchronous request or a reply + */ + public final boolean isSynchronous() { + return synchronous; + } + + /** + Returns the current context of a request message. + + <p>Valid only for request messages.</p> + + @return the current context (which may be <code>null</code>) for a + request, <code>null</code> for a reply + */ + public XCurrentContext getCurrentContext() { + return currentContext; + } + + /** + Returns whether the reply message represents abnormal termination. + + <p>Valid only for reply messages.</p> + + @return <code>true</code> for a reply that represents abnormal + termination, <code>false</code> for a reply that represents normal + termination or a request + */ + public final boolean isAbnormalTermination() { + return abnormalTermination; + } + + /** + Returns the result of a reply message. + + <p>Valid only for reply messages.</p> + + @return any (possibly <code>null</code>) return value for a reply that + represents normal termination, the (non-<code>null</code>) exception for + a reply that represents abnormal termination, <code>null</code> for a + request + */ + public final Object getResult() { + return result; + } + + /** + Returns the arguments of a message. + + <p>Valid only for request messages and reply messages that represent + normal termination. Any returned array must not be modified.</p> + + @return the in and in&ndash { + }out arguments for a request (possibly + <code>null</code> for a paramterless function), the out and in&dash { + }out + arguments for a reply that represents normal termination (possibly + <code>null</code> for a parameterless function), <code>null</code> for a + reply that represents abnormal termination + */ + public final Object[] getArguments() { + return arguments; + } + + private final ThreadId threadId; + private final boolean request; + private final String objectId; + private final ITypeDescription type; + private final IMethodDescription method; + private final boolean synchronous; + private final XCurrentContext currentContext; + private final boolean abnormalTermination; + private final Object result; + private final Object[] arguments; +} diff --git a/jurt/com/sun/star/lib/uno/environments/remote/NativeThreadPool.java b/jurt/com/sun/star/lib/uno/environments/remote/NativeThreadPool.java new file mode 100644 index 000000000000..06afce7f1e5d --- /dev/null +++ b/jurt/com/sun/star/lib/uno/environments/remote/NativeThreadPool.java @@ -0,0 +1,100 @@ +/************************************************************************* + * + * 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.lib.uno.environments.remote; + +final class NativeThreadPool implements IThreadPool { + public NativeThreadPool() { + pool = create(); + } + + public ThreadId getThreadId() { + return new ThreadId(threadId()); + } + + public void attach() { + attach(pool); + } + + public Object attach(ThreadId id) { + attach(); + return null; + } + + public void detach() { + detach(pool); + } + + public void detach(Object handle, ThreadId id) { + detach(); + } + + public Object enter() throws Throwable { + Job job = enter(pool); + if (job == null) { + throw dispose; + } + return job.execute(); + } + + public Object enter(Object handle, ThreadId id) throws Throwable { + return enter(); + } + + public void putJob(Job job) { + putJob( + pool, job.getThreadId().getBytes(), job, job.isRequest(), + job.isRequest() && !job.isSynchronous()); + } + + public void dispose(Throwable throwable) { + dispose = throwable; + dispose(pool); + } + + public void destroy() { + destroy(pool); + } + + // The native implementation is in + // bridges/source/jni_uno/nativethreadpool.cxx: + static { + System.loadLibrary("java_uno"); + } + private static native byte[] threadId(); + private static native long create(); + private static native void attach(long pool); + private static native Job enter(long pool); + private static native void detach(long pool); + private static native void putJob( + long pool, byte[] threadId, Job job, boolean request, boolean oneWay); + private static native void dispose(long pool); + private static native void destroy(long pool); + + private final long pool; + private volatile Throwable dispose; +} diff --git a/jurt/com/sun/star/lib/uno/environments/remote/ThreadId.java b/jurt/com/sun/star/lib/uno/environments/remote/ThreadId.java new file mode 100644 index 000000000000..0b570991c11f --- /dev/null +++ b/jurt/com/sun/star/lib/uno/environments/remote/ThreadId.java @@ -0,0 +1,95 @@ +/************************************************************************* + * + * 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.lib.uno.environments.remote; + +import com.sun.star.uno.UnoRuntime; +import java.io.UnsupportedEncodingException; +import java.math.BigInteger; +import java.util.Arrays; + +public final class ThreadId { + public static ThreadId createFresh() { + BigInteger c; + synchronized (PREFIX) { + c = count; + count = count.add(BigInteger.ONE); + } + try { + return new ThreadId((PREFIX + c).getBytes("UTF-8")); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException("this cannot happen: " + e); + } + } + + public ThreadId(byte[] id) { + this.id = id; + } + + public boolean equals(Object obj) { + return obj instanceof ThreadId + && Arrays.equals(id, ((ThreadId) obj).id); + } + + public int hashCode() { + int h = hash; + if (h == 0) { + // Same algorithm as java.util.List.hashCode (also see Java 1.5 + // java.util.Arrays.hashCode(byte[])): + h = 1; + for (int i = 0; i < id.length; ++i) { + h = 31 * h + id[i]; + } + hash = h; + } + return h; + } + + public String toString() { + StringBuffer b = new StringBuffer("[ThreadId:"); + for (int i = 0; i < id.length; ++i) { + String n = Integer.toHexString(id[i] & 0xFF); + if (n.length() == 1) { + b.append('0'); + } + b.append(n); + } + b.append(']'); + return b.toString(); + } + + public byte[] getBytes() { + return id; + } + + private static final String PREFIX + = "java:" + UnoRuntime.getUniqueKey() + ":"; + private static BigInteger count = BigInteger.ZERO; + + private byte[] id; + private int hash = 0; +} diff --git a/jurt/com/sun/star/lib/uno/environments/remote/ThreadPoolManager.java b/jurt/com/sun/star/lib/uno/environments/remote/ThreadPoolManager.java new file mode 100644 index 000000000000..6187eb4b1c4e --- /dev/null +++ b/jurt/com/sun/star/lib/uno/environments/remote/ThreadPoolManager.java @@ -0,0 +1,80 @@ +/************************************************************************* + * + * 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.lib.uno.environments.remote; + +/** + * Manages the UNO thread pool factory. + * + * <P>The thread pool factory is a process-wide resource. It is important that + * all UNO environments within a process share the same thread pool mechanisms: + * if a synchronous UNO call is bridged out from one local UNO environment over + * one remote bridge, and recursively calls back into another local UNO + * environment over another remote bridge, the code in the second environment + * should be executed in the thread that did the original call from the first + * environment.</P> + * + * <P>There are both a Java and a native thread pool factory. A pure Java + * process will always use the Java thread pool factory. A mixed process uses + * the system property <CODE>org.openoffice.native</CODE> (to be set by the + * native code that starts the JVM) to determine which implementation + * to use.</P> + */ +public final class ThreadPoolManager { + /** + * Creates a thread pool instance. + * + * @return a new thread pool instance; will never be <CODE>null</CODE> + */ + public static synchronized IThreadPool create() { + if (useNative) { + return new NativeThreadPool(); + } else { + if (javaFactory == null) { + javaFactory = new JavaThreadPoolFactory(); + } + return javaFactory.createThreadPool(); + } + } + + /** + * Leads to using the native thread pool factory, unless a Java thread pool + * has already been created. + * + * @return <CODE>false</CODE> if a Java thread pool has already been created + */ + public static synchronized boolean useNative() { + useNative = javaFactory == null; + return useNative; + } + + private static boolean useNative + = System.getProperty("org.openoffice.native") != null; + private static JavaThreadPoolFactory javaFactory = null; + + private ThreadPoolManager() {} // do not instantiate +} diff --git a/jurt/com/sun/star/lib/uno/environments/remote/makefile.mk b/jurt/com/sun/star/lib/uno/environments/remote/makefile.mk new file mode 100644 index 000000000000..cc4a7fe7ae83 --- /dev/null +++ b/jurt/com/sun/star/lib/uno/environments/remote/makefile.mk @@ -0,0 +1,50 @@ +#************************************************************************* +# +# 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 + +TARGET := com_sun_star_lib_uno_environments_remote +PACKAGE := com$/sun$/star$/lib$/uno$/environments$/remote + +.INCLUDE: $(PRJ)$/util$/makefile.pmk + +JAVAFILES = \ + IProtocol.java \ + IReceiver.java \ + IThreadPool.java \ + JavaThreadPool.java \ + JavaThreadPoolFactory.java \ + Job.java \ + JobQueue.java \ + Message.java \ + NativeThreadPool.java \ + ThreadId.java \ + ThreadPoolManager.java \ + remote_environment.java + +.INCLUDE: target.mk diff --git a/jurt/com/sun/star/lib/uno/environments/remote/remote_environment.java b/jurt/com/sun/star/lib/uno/environments/remote/remote_environment.java new file mode 100644 index 000000000000..0a782783c00f --- /dev/null +++ b/jurt/com/sun/star/lib/uno/environments/remote/remote_environment.java @@ -0,0 +1,72 @@ +/************************************************************************* + * + * 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.lib.uno.environments.remote; + +import com.sun.star.uno.IEnvironment; +import com.sun.star.uno.Type; + +public final class remote_environment implements IEnvironment { + public remote_environment(Object context) { + this.context = context; + } + + public Object getContext() { + return context; + } + + public String getName() { + return "remote"; + } + + public Object registerInterface(Object object, String[] oid, Type type) { + throw new UnsupportedOperationException( + "java_remote environment is not functional"); + } + + public void revokeInterface(String oid, Type type) { + throw new UnsupportedOperationException( + "java_remote environment is not functional"); + } + + public Object getRegisteredInterface(String oid, Type type) { + throw new UnsupportedOperationException( + "java_remote environment is not functional"); + } + + public String getRegisteredObjectIdentifier(Object object) { + throw new UnsupportedOperationException( + "java_remote environment is not functional"); + } + + public void list() { + throw new UnsupportedOperationException( + "java_remote environment is not functional"); + } + + private final Object context; +} diff --git a/jurt/com/sun/star/lib/uno/makefile.mk b/jurt/com/sun/star/lib/uno/makefile.mk new file mode 100644 index 000000000000..6270e78ce94b --- /dev/null +++ b/jurt/com/sun/star/lib/uno/makefile.mk @@ -0,0 +1,37 @@ +#************************************************************************* +# +# 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 +TARGET = com_sun_star_lib_uno +PACKAGE = com$/sun$/star$/lib$/uno + +.INCLUDE: $(PRJ)$/util$/makefile.pmk + +JAVAFILES = Proxy.java + +.INCLUDE: target.mk diff --git a/jurt/com/sun/star/lib/uno/protocols/urp/Cache.java b/jurt/com/sun/star/lib/uno/protocols/urp/Cache.java new file mode 100644 index 000000000000..48268a53a260 --- /dev/null +++ b/jurt/com/sun/star/lib/uno/protocols/urp/Cache.java @@ -0,0 +1,120 @@ +/************************************************************************* + * + * 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.lib.uno.protocols.urp; + +import java.util.HashMap; + +/** + An LRU cache for arbitrary objects. + + This class is not synchronized, as any necessary synchronization will already + take place in the client. +*/ +final class Cache { + /** + Create a cache. + + @param size the maximum cache size, must be between 0, inclusive, and + NOT_CACHED, exclusive + */ + public Cache(int size) { + maxSize = size; + } + + public int add(boolean[] found, Object content) { + Entry e = (Entry) map.get(content); + found[0] = e != null; + if (e == null) { + if (map.size() < maxSize) { + // There is still room for a new entry at the front: + e = new Entry(content, map.size(), last, null); + if (first == null) { + last = e; + } else { + first.prev = e; + } + first = e; + } else if (last != null) { + // Take last entry out and recycle as new front: + map.remove(last.content); + e = last; + e.content = content; + if (first != last) { + // Reached only if maxSize > 1: + last = last.prev; + last.next = null; + e.prev = null; + e.next = first; + first.prev = e; + first = e; + } + } else { + // Reached iff maxSize == 0: + return NOT_CACHED; + } + map.put(content, e); + } else if (e != first) { + // Move to front (reached only if maxSize > 1): + e.prev.next = e.next; + if (e.next == null) { + last = e.prev; + } else { + e.next.prev = e.prev; + } + e.prev = null; + e.next = first; + first.prev = e; + first = e; + } + return e.index; + } + + public static final int NOT_CACHED = 0xFFFF; + + private static final class Entry { + public Entry(Object content, int index, Entry prev, Entry next) { + this.content = content; + this.index = index; + this.prev = prev; + this.next = next; + } + + public Object content; + public int index; + public Entry prev; + public Entry next; + } + + // first/last form a list of 0 to maxSize entries, most recently used first; + // map contains the same entries; each entry has a unique index in the range + // 0 to maxSize - 1 + private final int maxSize; + private final HashMap map = new HashMap(); // from Object to Entry + private Entry first = null; + private Entry last = null; +} diff --git a/jurt/com/sun/star/lib/uno/protocols/urp/Marshal.java b/jurt/com/sun/star/lib/uno/protocols/urp/Marshal.java new file mode 100644 index 000000000000..2a43041916ce --- /dev/null +++ b/jurt/com/sun/star/lib/uno/protocols/urp/Marshal.java @@ -0,0 +1,390 @@ +/************************************************************************* + * + * 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.lib.uno.protocols.urp; + +import com.sun.star.lib.uno.environments.remote.ThreadId; +import com.sun.star.lib.uno.typedesc.TypeDescription; +import com.sun.star.uno.Any; +import com.sun.star.uno.Enum; +import com.sun.star.uno.IBridge; +import com.sun.star.uno.IFieldDescription; +import com.sun.star.uno.Type; +import com.sun.star.uno.TypeClass; +import com.sun.star.uno.XInterface; +import java.io.ByteArrayOutputStream; +import java.io.DataOutput; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.lang.reflect.Array; +import java.lang.reflect.InvocationTargetException; + +final class Marshal { + public Marshal(IBridge bridge, short cacheSize) { + this.bridge = bridge; + objectIdCache = new Cache(cacheSize); + threadIdCache = new Cache(cacheSize); + typeCache = new Cache(cacheSize); + } + + public void write8Bit(int value) { + try { + output.writeByte(value); + } catch (IOException e) { + throw new RuntimeException(e.toString()); + } + } + + public void write16Bit(int value) { + try { + output.writeShort(value); + } catch (IOException e) { + throw new RuntimeException(e.toString()); + } + } + + public void writeObjectId(String objectId) { + if (objectId == null) { + writeStringValue(null); + write16Bit(0xFFFF); + } else { + boolean[] found = new boolean[1]; + int index = objectIdCache.add(found, objectId); + writeStringValue(found[0] ? null : objectId); + write16Bit(index); + } + } + + public void writeInterface(XInterface object, Type type) { + writeObjectId((String) bridge.mapInterfaceTo(object, type)); + } + + public void writeThreadId(ThreadId threadId) { + byte[] data = threadId.getBytes(); + boolean[] found = new boolean[1]; + int index = threadIdCache.add(found, data); + if (found[0]) { + writeCompressedNumber(0); + } else { + writeCompressedNumber(data.length); + writeBytes(data); + } + write16Bit(index); + } + + public void writeType(TypeDescription type) { + TypeClass typeClass = type.getTypeClass(); + if (TypeDescription.isTypeClassSimple(typeClass)) { + write8Bit(typeClass.getValue()); + } else { + boolean[] found = new boolean[1]; + int index = typeCache.add(found, type.getTypeName()); + write8Bit(typeClass.getValue() | (found[0] ? 0 : 0x80)); + write16Bit(index); + if (!found[0]) { + writeStringValue(type.getTypeName()); + } + } + } + + public void writeValue(TypeDescription type, Object value) { + switch(type.getTypeClass().getValue()) { + case TypeClass.VOID_value: + break; + + case TypeClass.BOOLEAN_value: + writeBooleanValue((Boolean) value); + break; + + case TypeClass.BYTE_value: + writeByteValue((Byte) value); + break; + + case TypeClass.SHORT_value: + case TypeClass.UNSIGNED_SHORT_value: + writeShortValue((Short) value); + break; + + case TypeClass.LONG_value: + case TypeClass.UNSIGNED_LONG_value: + writeLongValue((Integer) value); + break; + + case TypeClass.HYPER_value: + case TypeClass.UNSIGNED_HYPER_value: + writeHyperValue((Long) value); + break; + + case TypeClass.FLOAT_value: + writeFloatValue((Float) value); + break; + + case TypeClass.DOUBLE_value: + writeDoubleValue((Double) value); + break; + + case TypeClass.CHAR_value: + writeCharValue((Character) value); + break; + + case TypeClass.STRING_value: + writeStringValue((String) value); + break; + + case TypeClass.TYPE_value: + writeTypeValue((Type) value); + break; + + case TypeClass.ANY_value: + writeAnyValue(value); + break; + + case TypeClass.SEQUENCE_value: + writeSequenceValue(type, value); + break; + + case TypeClass.ENUM_value: + writeEnumValue(type, (Enum) value); + break; + + case TypeClass.STRUCT_value: + writeStructValue(type, value); + break; + + case TypeClass.EXCEPTION_value: + writeExceptionValue(type, (Exception) value); + break; + + case TypeClass.INTERFACE_value: + writeInterfaceValue(type, (XInterface) value); + break; + + default: + throw new IllegalArgumentException("Bad type descriptor " + type); + } + } + + public byte[] reset() { + byte[] data = buffer.toByteArray(); + buffer.reset(); + return data; + } + + private void writeBooleanValue(Boolean value) { + try { + output.writeBoolean(value != null && value.booleanValue()); + } catch (IOException e) { + throw new RuntimeException(e.toString()); + } + } + + private void writeByteValue(Byte value) { + write8Bit(value == null ? 0 : value.byteValue()); + } + + private void writeShortValue(Short value) { + write16Bit(value == null ? 0 : value.shortValue()); + } + + private void writeLongValue(Integer value) { + write32Bit(value == null ? 0 : value.intValue()); + } + + private void writeHyperValue(Long value) { + try { + output.writeLong(value == null ? 0 : value.longValue()); + } catch (IOException e) { + throw new RuntimeException(e.toString()); + } + } + + private void writeFloatValue(Float value) { + try { + output.writeFloat(value == null ? 0 : value.floatValue()); + } catch (IOException e) { + throw new RuntimeException(e.toString()); + } + } + + private void writeDoubleValue(Double value) { + try { + output.writeDouble(value == null ? 0 : value.doubleValue()); + } catch (IOException e) { + throw new RuntimeException(e.toString()); + } + } + + private void writeCharValue(Character value) { + try { + output.writeChar(value == null ? 0 : value.charValue()); + } catch (IOException e) { + throw new RuntimeException(e.toString()); + } + } + + private void writeStringValue(String value) { + if (value == null) { + writeCompressedNumber(0); + } else { + byte[] data; + try { + data = value.getBytes("UTF8"); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e.toString()); + } + writeCompressedNumber(data.length); + writeBytes(data); + } + } + + private void writeTypeValue(Type value) { + try { + writeType( + TypeDescription.getTypeDescription( + value == null ? Type.VOID : value)); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e.toString()); + } + } + + private void writeAnyValue(Object value) { + TypeDescription type; + if (value == null || value instanceof XInterface) { + type = TypeDescription.getTypeDescription(XInterface.class); + } else if (value instanceof Any) { + Any any = (Any) value; + try { + type = TypeDescription.getTypeDescription(any.getType()); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e.toString()); + } + value = any.getObject(); + } else if (value.getClass() == Object.class) { + // Avoid StackOverflowError: + throw new IllegalArgumentException( + "Object instance does not represent UNO value"); + } else { + type = TypeDescription.getTypeDescription(value.getClass()); + } + writeType(type); + writeValue(type, value); + } + + private void writeSequenceValue(TypeDescription type, Object value) { + if (value == null) { + writeCompressedNumber(0); + } else { + TypeDescription ctype = (TypeDescription) type.getComponentType(); + if (ctype.getTypeClass() == TypeClass.BYTE) { + byte[] data = (byte[]) value; + writeCompressedNumber(data.length); + writeBytes(data); + } else { + int len = Array.getLength(value); + writeCompressedNumber(len); + for (int i = 0; i < len; ++i) { + writeValue(ctype, Array.get(value, i)); + } + } + } + } + + private void writeEnumValue(TypeDescription type, Enum value) { + int n; + if (value == null) { + try { + n = ((Enum) + (type.getZClass().getMethod("getDefault", null). + invoke(null, null))). + getValue(); + } catch (IllegalAccessException e) { + throw new RuntimeException(e.toString()); + } catch (InvocationTargetException e) { + throw new RuntimeException(e.toString()); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e.toString()); + } + } else { + n = value.getValue(); + } + write32Bit(n); + } + + private void writeStructValue(TypeDescription type, Object value) { + IFieldDescription[] fields = type.getFieldDescriptions(); + for (int i = 0; i < fields.length; ++i) { + try { + writeValue( + (TypeDescription) fields[i].getTypeDescription(), + value == null ? null : fields[i].getField().get(value)); + } catch (IllegalAccessException e) { + throw new RuntimeException(e.toString()); + } + } + } + + private void writeExceptionValue(TypeDescription type, Exception value) { + writeStringValue(value == null ? null : value.getMessage()); + writeStructValue(type, value); + } + + private void writeInterfaceValue(TypeDescription type, XInterface value) { + writeInterface(value, new Type(type)); + } + + private void write32Bit(int value) { + try { + output.writeInt(value); + } catch (IOException e) { + throw new RuntimeException(e.toString()); + } + } + + private void writeCompressedNumber(int number) { + if (number >= 0 && number < 0xFF) { + write8Bit(number); + } else { + write8Bit(0xFF); + write32Bit(number); + } + } + + private void writeBytes(byte[] data) { + try { + output.write(data); + } catch (IOException e) { + throw new RuntimeException(e.toString()); + } + } + + private final ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + private final DataOutput output = new DataOutputStream(buffer); + private final IBridge bridge; + private final Cache objectIdCache; + private final Cache threadIdCache; + private final Cache typeCache; +} diff --git a/jurt/com/sun/star/lib/uno/protocols/urp/PendingRequests.java b/jurt/com/sun/star/lib/uno/protocols/urp/PendingRequests.java new file mode 100644 index 000000000000..ac3e039224aa --- /dev/null +++ b/jurt/com/sun/star/lib/uno/protocols/urp/PendingRequests.java @@ -0,0 +1,71 @@ +/************************************************************************* + * + * 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.lib.uno.protocols.urp; + +import com.sun.star.lib.uno.environments.remote.ThreadId; +import com.sun.star.uno.IMethodDescription; +import java.util.HashMap; +import java.util.Stack; + +final class PendingRequests { + public PendingRequests() {} + + public synchronized void push(ThreadId tid, Item item) { + Stack s = (Stack) map.get(tid); + if (s == null) { + s = new Stack(); + map.put(tid, s); + } + s.push(item); + } + + public synchronized Item pop(ThreadId tid) { + Stack s = (Stack) map.get(tid); + Item i = (Item) s.pop(); + if (s.empty()) { + map.remove(tid); + } + return i; + } + + public static final class Item { + public Item( + boolean internal, IMethodDescription function, Object[] arguments) + { + this.internal = internal; + this.function = function; + this.arguments = arguments; + } + + public final boolean internal; + public final IMethodDescription function; + public final Object[] arguments; + } + + private final HashMap map = new HashMap(); // from ThreadId to Stack of Item +} diff --git a/jurt/com/sun/star/lib/uno/protocols/urp/Unmarshal.java b/jurt/com/sun/star/lib/uno/protocols/urp/Unmarshal.java new file mode 100644 index 000000000000..5a500ad3a0c1 --- /dev/null +++ b/jurt/com/sun/star/lib/uno/protocols/urp/Unmarshal.java @@ -0,0 +1,490 @@ +/************************************************************************* + * + * 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.lib.uno.protocols.urp; + +import com.sun.star.lib.uno.environments.remote.ThreadId; +import com.sun.star.lib.uno.typedesc.TypeDescription; +import com.sun.star.uno.Any; +import com.sun.star.uno.Enum; +import com.sun.star.uno.IBridge; +import com.sun.star.uno.IFieldDescription; +import com.sun.star.uno.Type; +import com.sun.star.uno.TypeClass; +import com.sun.star.uno.XInterface; +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.lang.reflect.Array; +import java.lang.reflect.InvocationTargetException; + +final class Unmarshal { + public Unmarshal(IBridge bridge, int cacheSize) { + this.bridge = bridge; + objectIdCache = new String[cacheSize]; + threadIdCache = new ThreadId[cacheSize]; + typeCache = new TypeDescription[cacheSize]; + reset(new byte[0]); + } + + public int read8Bit() { + try { + return input.readUnsignedByte(); + } catch (IOException e) { + throw new RuntimeException(e.toString()); + } + } + + public int read16Bit() { + try { + return input.readUnsignedShort(); + } catch (IOException e) { + throw new RuntimeException(e.toString()); + } + } + + public String readObjectId() { + String id = readStringValue(); + int index = read16Bit(); + if (index == 0xFFFF) { + if (id.length() == 0) { + id = null; + } + } else { + if (id.length() == 0) { + id = objectIdCache[index]; + } else { + objectIdCache[index] = id; + } + } + return id; + } + + public Object readInterface(Type type) { + String id = readObjectId(); + return id == null ? null : bridge.mapInterfaceFrom(id, type); + } + + public ThreadId readThreadId() { + int len = readCompressedNumber(); + byte[] data = null; + ThreadId id = null; + if (len != 0) { + data = new byte[len]; + readBytes(data); + id = new ThreadId(data); + } + int index = read16Bit(); + if (index != 0xFFFF) { + if (len == 0) { + id = threadIdCache[index]; + } else { + threadIdCache[index] = id; + } + } + return id; + } + + public TypeDescription readType() { + int b = read8Bit(); + TypeClass typeClass = TypeClass.fromInt(b & 0x7F); + if (TypeDescription.isTypeClassSimple(typeClass)) { + return TypeDescription.getTypeDescription(typeClass); + } else { + int index = read16Bit(); + TypeDescription type = null; + if ((b & 0x80) != 0) { + try { + type = TypeDescription.getTypeDescription( + readStringValue()); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e.toString()); + } + } + if (index != 0xFFFF) { + if ((b & 0x80) == 0) { + type = typeCache[index]; + } else { + typeCache[index] = type; + } + } + return type; + } + } + + public Object readValue(TypeDescription type) { + switch (type.getTypeClass().getValue()) { + case TypeClass.VOID_value: + return null; + + case TypeClass.BOOLEAN_value: + return readBooleanValue(); + + case TypeClass.BYTE_value: + return readByteValue(); + + case TypeClass.SHORT_value: + case TypeClass.UNSIGNED_SHORT_value: + return readShortValue(); + + case TypeClass.LONG_value: + case TypeClass.UNSIGNED_LONG_value: + return readLongValue(); + + case TypeClass.HYPER_value: + case TypeClass.UNSIGNED_HYPER_value: + return readHyperValue(); + + case TypeClass.FLOAT_value: + return readFloatValue(); + + case TypeClass.DOUBLE_value: + return readDoubleValue(); + + case TypeClass.CHAR_value: + return readCharValue(); + + case TypeClass.STRING_value: + return readStringValue(); + + case TypeClass.TYPE_value: + return readTypeValue(); + + case TypeClass.ANY_value: + return readAnyValue(); + + case TypeClass.SEQUENCE_value: + return readSequenceValue(type); + + case TypeClass.ENUM_value: + return readEnumValue(type); + + case TypeClass.STRUCT_value: + return readStructValue(type); + + case TypeClass.EXCEPTION_value: + return readExceptionValue(type); + + case TypeClass.INTERFACE_value: + return readInterfaceValue(type); + + default: + throw new IllegalArgumentException("Bad type descriptor " + type); + } + } + + public boolean hasMore() { + try { + return input.available() > 0; + } catch (IOException e) { + throw new RuntimeException(e.toString()); + } + } + + public void reset(byte[] data) { + input = new DataInputStream(new ByteArrayInputStream(data)); + } + + private Boolean readBooleanValue() { + try { + return input.readBoolean() ? Boolean.TRUE : Boolean.FALSE; + } catch (IOException e) { + throw new RuntimeException(e.toString()); + } + } + + private Byte readByteValue() { + try { + return new Byte(input.readByte()); + } catch (IOException e) { + throw new RuntimeException(e.toString()); + } + } + + private Short readShortValue() { + try { + return new Short(input.readShort()); + } catch (IOException e) { + throw new RuntimeException(e.toString()); + } + } + + private Integer readLongValue() { + try { + return new Integer(input.readInt()); + } catch (IOException e) { + throw new RuntimeException(e.toString()); + } + } + + private Long readHyperValue() { + try { + return new Long(input.readLong()); + } catch (IOException e) { + throw new RuntimeException(e.toString()); + } + } + + private Float readFloatValue() { + try { + return new Float(input.readFloat()); + } catch (IOException e) { + throw new RuntimeException(e.toString()); + } + } + + private Double readDoubleValue() { + try { + return new Double(input.readDouble()); + } catch (IOException e) { + throw new RuntimeException(e.toString()); + } + } + + private Character readCharValue() { + try { + return new Character(input.readChar()); + } catch (IOException e) { + throw new RuntimeException(e.toString()); + } + } + + private String readStringValue() { + int len = readCompressedNumber(); + byte[] data = new byte[len]; + readBytes(data); + try { + return new String(data, "UTF8"); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e.toString()); + } + } + + private Type readTypeValue() { + return new Type(readType()); + } + + private Object readAnyValue() { + TypeDescription type = readType(); + switch (type.getTypeClass().getValue()) { + case TypeClass.VOID_value: + return Any.VOID; + + case TypeClass.BOOLEAN_value: + return readBooleanValue(); + + case TypeClass.BYTE_value: + return readByteValue(); + + case TypeClass.SHORT_value: + return readShortValue(); + + case TypeClass.UNSIGNED_SHORT_value: + return new Any(Type.UNSIGNED_SHORT, readShortValue()); + + case TypeClass.LONG_value: + return readLongValue(); + + case TypeClass.UNSIGNED_LONG_value: + return new Any(Type.UNSIGNED_LONG, readLongValue()); + + case TypeClass.HYPER_value: + return readHyperValue(); + + case TypeClass.UNSIGNED_HYPER_value: + return new Any(Type.UNSIGNED_HYPER, readHyperValue()); + + case TypeClass.FLOAT_value: + return readFloatValue(); + + case TypeClass.DOUBLE_value: + return readDoubleValue(); + + case TypeClass.CHAR_value: + return readCharValue(); + + case TypeClass.STRING_value: + return readStringValue(); + + case TypeClass.TYPE_value: + return readTypeValue(); + + case TypeClass.SEQUENCE_value: + { + Object value = readSequenceValue(type); + TypeDescription ctype = (TypeDescription) + type.getComponentType(); + while (ctype.getTypeClass() == TypeClass.SEQUENCE) { + ctype = (TypeDescription) ctype.getComponentType(); + } + switch (ctype.getTypeClass().getValue()) { + case TypeClass.UNSIGNED_SHORT_value: + case TypeClass.UNSIGNED_LONG_value: + case TypeClass.UNSIGNED_HYPER_value: + return new Any(new Type(type), value); + + case TypeClass.STRUCT_value: + if (ctype.hasTypeArguments()) { + return new Any(new Type(type), value); + } + default: + return value; + } + } + + case TypeClass.ENUM_value: + return readEnumValue(type); + + case TypeClass.STRUCT_value: + { + Object value = readStructValue(type); + return type.hasTypeArguments() + ? new Any(new Type(type), value) : value; + } + + case TypeClass.EXCEPTION_value: + return readExceptionValue(type); + + case TypeClass.INTERFACE_value: + { + Object value = readInterfaceValue(type); + return type.getZClass() == XInterface.class + ? value : new Any(new Type(type), value); + } + + default: + throw new RuntimeException( + "Reading ANY with bad type " + type.getTypeClass()); + } + } + + private Object readSequenceValue(TypeDescription type) { + int len = readCompressedNumber(); + TypeDescription ctype = (TypeDescription) type.getComponentType(); + if (ctype.getTypeClass() == TypeClass.BYTE) { + byte[] data = new byte[len]; + readBytes(data); + return data; + } else { + Object value = Array.newInstance( + ctype.getTypeClass() == TypeClass.ANY + ? Object.class : ctype.getZClass(), len); + for (int i = 0; i < len; ++i) { + Array.set(value, i, readValue(ctype)); + } + return value; + } + } + + private Enum readEnumValue(TypeDescription type) { + try { + return (Enum) + type.getZClass().getMethod( + "fromInt", new Class[] { int.class }). + invoke(null, new Object[] { readLongValue() }); + } catch (IllegalAccessException e) { + throw new RuntimeException(e.toString()); + } catch (InvocationTargetException e) { + throw new RuntimeException(e.toString()); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e.toString()); + } + } + + private Object readStructValue(TypeDescription type) { + Object value; + try { + value = type.getZClass().newInstance(); + } catch (IllegalAccessException e) { + throw new RuntimeException(e.toString()); + } catch (InstantiationException e) { + throw new RuntimeException(e.toString()); + } + readFields(type, value); + return value; + } + + private Exception readExceptionValue(TypeDescription type) { + Exception value; + try { + value = (Exception) + type.getZClass().getConstructor(new Class[] { String.class }). + newInstance(new Object[] { readStringValue() }); + } catch (IllegalAccessException e) { + throw new RuntimeException(e.toString()); + } catch (InstantiationException e) { + throw new RuntimeException(e.toString()); + } catch (InvocationTargetException e) { + throw new RuntimeException(e.toString()); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e.toString()); + } + readFields(type, value); + return value; + } + + private Object readInterfaceValue(TypeDescription type) { + return readInterface(new Type(type)); + } + + private int readCompressedNumber() { + int number = read8Bit(); + try { + return number < 0xFF ? number : input.readInt(); + } catch (IOException e) { + throw new RuntimeException(e.toString()); + } + } + + private void readBytes(byte[] data) { + try { + input.readFully(data); + } catch (IOException e) { + throw new RuntimeException(e.toString()); + } + } + + private void readFields(TypeDescription type, Object value) { + IFieldDescription[] fields = type.getFieldDescriptions(); + for (int i = 0; i < fields.length; ++i) { + try { + fields[i].getField().set( + value, + readValue( + (TypeDescription) fields[i].getTypeDescription())); + } catch (IllegalAccessException e) { + throw new RuntimeException(e.toString()); + } + } + } + + private final IBridge bridge; + private final String[] objectIdCache; + private final ThreadId[] threadIdCache; + private final TypeDescription[] typeCache; + private DataInputStream input; +} diff --git a/jurt/com/sun/star/lib/uno/protocols/urp/UrpMessage.java b/jurt/com/sun/star/lib/uno/protocols/urp/UrpMessage.java new file mode 100644 index 000000000000..57770dcb0401 --- /dev/null +++ b/jurt/com/sun/star/lib/uno/protocols/urp/UrpMessage.java @@ -0,0 +1,54 @@ +/************************************************************************* + * + * 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.lib.uno.protocols.urp; + +import com.sun.star.lib.uno.environments.remote.Message; +import com.sun.star.lib.uno.environments.remote.ThreadId; +import com.sun.star.uno.IMethodDescription; +import com.sun.star.uno.ITypeDescription; +import com.sun.star.uno.XCurrentContext; + +final class UrpMessage extends Message { + public UrpMessage( + ThreadId threadId, boolean request, String objectId, + ITypeDescription type, IMethodDescription method, boolean synchronous, + XCurrentContext currentContext, boolean abnormalTermination, + Object result, Object[] arguments, boolean internal) + { + super( + threadId, request, objectId, type, method, synchronous, + currentContext, abnormalTermination, result, arguments); + this.internal = internal; + } + + public boolean isInternal() { + return internal; + } + + private final boolean internal; +} diff --git a/jurt/com/sun/star/lib/uno/protocols/urp/makefile.mk b/jurt/com/sun/star/lib/uno/protocols/urp/makefile.mk new file mode 100644 index 000000000000..c1b7357f2a06 --- /dev/null +++ b/jurt/com/sun/star/lib/uno/protocols/urp/makefile.mk @@ -0,0 +1,44 @@ +#************************************************************************* +# +# 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 + +TARGET := com_sun_star_lib_uno_protocols_urp +PACKAGE := com$/sun$/star$/lib$/uno$/protocols$/urp + +.INCLUDE: $(PRJ)$/util$/makefile.pmk + +JAVAFILES = \ + Cache.java \ + Marshal.java \ + PendingRequests.java \ + Unmarshal.java \ + UrpMessage.java \ + urp.java + +.INCLUDE: target.mk diff --git a/jurt/com/sun/star/lib/uno/protocols/urp/urp.java b/jurt/com/sun/star/lib/uno/protocols/urp/urp.java new file mode 100644 index 000000000000..da54bc7612a1 --- /dev/null +++ b/jurt/com/sun/star/lib/uno/protocols/urp/urp.java @@ -0,0 +1,734 @@ +/************************************************************************* + * + * 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.lib.uno.protocols.urp; + +import com.sun.star.bridge.InvalidProtocolChangeException; +import com.sun.star.bridge.ProtocolProperty; +import com.sun.star.bridge.XProtocolProperties; +import com.sun.star.lib.uno.environments.remote.IProtocol; +import com.sun.star.lib.uno.environments.remote.Message; +import com.sun.star.lib.uno.environments.remote.ThreadId; +import com.sun.star.lib.uno.typedesc.MethodDescription; +import com.sun.star.lib.uno.typedesc.TypeDescription; +import com.sun.star.uno.Any; +import com.sun.star.uno.IBridge; +import com.sun.star.uno.IMethodDescription; +import com.sun.star.uno.ITypeDescription; +import com.sun.star.uno.Type; +import com.sun.star.uno.TypeClass; +import com.sun.star.uno.UnoRuntime; +import com.sun.star.uno.XCurrentContext; +import java.io.DataInput; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.lang.reflect.Array; +import java.util.ArrayList; +import java.util.Random; +import java.util.StringTokenizer; + +// This class internally relies on the availability of Java UNO type information +// for the interface type com.sun.star.bridge.XProtocolProperties, even though +// URP itself does not rely on that type. + +public final class urp implements IProtocol { + public urp( + IBridge bridge, String attributes, InputStream input, + OutputStream output) + { + this.input = new DataInputStream(input); + this.output = new DataOutputStream(output); + marshal = new Marshal(bridge, CACHE_SIZE); + unmarshal = new Unmarshal(bridge, CACHE_SIZE); + forceSynchronous = parseAttributes(attributes); + } + + // @see IProtocol#init + public void init() throws IOException { + synchronized (monitor) { + if (state == STATE_INITIAL0) { + sendRequestChange(); + } + } + } + + // @see IProtocol#readMessage + public Message readMessage() throws IOException { + for (;;) { + if (!unmarshal.hasMore()) { + unmarshal.reset(readBlock()); + if (!unmarshal.hasMore()) { + throw new IOException("closeConnection message received"); + } + } + UrpMessage msg; + int header = unmarshal.read8Bit(); + if ((header & HEADER_LONGHEADER) != 0) { + if ((header & HEADER_REQUEST) != 0) { + msg = readLongRequest(header); + } else { + msg = readReply(header); + } + } else { + msg = readShortRequest(header); + } + if (msg.isInternal()) { + handleInternalMessage(msg); + } else { + return msg; + } + } + } + + // @see IProtocol#writeRequest + public boolean writeRequest( + String oid, TypeDescription type, String function, ThreadId tid, + Object[] arguments) + throws IOException + { + if (oid.equals(PROPERTIES_OID)) { + throw new IllegalArgumentException("illegal OID " + oid); + } + synchronized (monitor) { + while (!initialized) { + try { + monitor.wait(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new RuntimeException(e.toString()); + } + } + return writeRequest(false, oid, type, function, tid, arguments); + } + } + + // @see IProtocol#writeReply + public void writeReply(boolean exception, ThreadId tid, Object result) + throws IOException + { + synchronized (output) { + writeQueuedReleases(); + int header = HEADER_LONGHEADER; + PendingRequests.Item pending = pendingIn.pop(tid); + TypeDescription resultType; + ITypeDescription[] argTypes; + Object[] args; + if (exception) { + header |= HEADER_EXCEPTION; + resultType = TypeDescription.getTypeDescription(TypeClass.ANY); + argTypes = null; + args = null; + } else { + resultType = (TypeDescription) + pending.function.getReturnSignature(); + argTypes = pending.function.getOutSignature(); + args = pending.arguments; + } + if (!tid.equals(outL1Tid)) { + header |= HEADER_NEWTID; + outL1Tid = tid; + } else { + tid = null; + } + marshal.write8Bit(header); + if (tid != null) { + marshal.writeThreadId(tid); + } + marshal.writeValue(resultType, result); + if (argTypes != null) { + for (int i = 0; i < argTypes.length; ++i) { + if (argTypes[i] != null) { + marshal.writeValue( + (TypeDescription) argTypes[i].getComponentType(), + Array.get(args[i], 0)); + } + } + } + writeBlock(true); + } + } + + private void sendRequestChange() throws IOException { + if (propertiesTid == null) { + propertiesTid = ThreadId.createFresh(); + } + random = new Random().nextInt(); + writeRequest( + true, PROPERTIES_OID, + TypeDescription.getTypeDescription(XProtocolProperties.class), + PROPERTIES_FUN_REQUEST_CHANGE, propertiesTid, + new Object[] { new Integer(random) }); + state = STATE_REQUESTED; + } + + private void handleInternalMessage(Message message) throws IOException { + if (message.isRequest()) { + String t = message.getType().getTypeName(); + if (!t.equals("com.sun.star.bridge.XProtocolProperties")) { + throw new IOException( + "read URP protocol properties request with unsupported" + + " type " + t); + } + int fid = message.getMethod().getIndex(); + switch (fid) { + case PROPERTIES_FID_REQUEST_CHANGE: + checkSynchronousPropertyRequest(message); + synchronized (monitor) { + switch (state) { + case STATE_INITIAL0: + case STATE_INITIAL: + writeReply( + false, message.getThreadId(), new Integer(1)); + state = STATE_WAIT; + break; + case STATE_REQUESTED: + int n + = ((Integer) message.getArguments()[0]).intValue(); + if (random < n) { + writeReply( + false, message.getThreadId(), new Integer(1)); + state = STATE_WAIT; + } else if (random == n) { + writeReply( + false, message.getThreadId(), new Integer(-1)); + state = STATE_INITIAL; + sendRequestChange(); + } else { + writeReply( + false, message.getThreadId(), new Integer(0)); + } + break; + default: + writeReply( + true, message.getThreadId(), + new com.sun.star.uno.RuntimeException( + "read URP protocol properties requestChange" + + " request in illegal state")); + break; + } + } + break; + case PROPERTIES_FID_COMMIT_CHANGE: + checkSynchronousPropertyRequest(message); + synchronized (monitor) { + if (state == STATE_WAIT) { + ProtocolProperty[] p = (ProtocolProperty[]) + message.getArguments()[0]; + boolean ok = true; + boolean cc = false; + int i = 0; + for (; i < p.length; ++i) { + if (p[i].Name.equals(PROPERTY_CURRENT_CONTEXT)) { + cc = true; + } else { + ok = false; + break; + } + } + if (ok) { + writeReply(false, message.getThreadId(), null); + } else { + writeReply( + true, message.getThreadId(), + new InvalidProtocolChangeException( + "", null, p[i], 1)); + } + state = STATE_INITIAL; + if (!initialized) { + if (cc) { + currentContext = true; + initialized = true; + monitor.notifyAll(); + } else { + sendRequestChange(); + } + } + } else { + writeReply( + true, message.getThreadId(), + new com.sun.star.uno.RuntimeException( + "read URP protocol properties commitChange" + + " request in illegal state")); + } + } + break; + default: + throw new IOException( + "read URP protocol properties request with unsupported" + + " function ID " + fid); + } + } else { + synchronized (monitor) { + if (state == STATE_COMMITTED) { + // commitChange reply: + if (!message.isAbnormalTermination()) { + currentContext = true; + } + state = STATE_INITIAL; + initialized = true; + monitor.notifyAll(); + } else { + // requestChange reply: + if (message.isAbnormalTermination()) { + // remote side probably does not support negotiation: + state = STATE_INITIAL; + initialized = true; + monitor.notifyAll(); + } else { + int n = ((Integer) message.getResult()).intValue(); + switch (n) { + case -1: + case 0: + break; + case 1: + writeRequest( + true, PROPERTIES_OID, + TypeDescription.getTypeDescription( + XProtocolProperties.class), + PROPERTIES_FUN_COMMIT_CHANGE, propertiesTid, + new Object[] { + new ProtocolProperty[] { + new ProtocolProperty( + PROPERTY_CURRENT_CONTEXT, + Any.VOID) } }); + state = STATE_COMMITTED; + break; + default: + throw new IOException( + "read URP protocol properties " + + PROPERTIES_FUN_REQUEST_CHANGE + + " reply with illegal return value " + n); + } + } + } + } + } + } + + private void checkSynchronousPropertyRequest(Message message) + throws IOException + { + if (!message.isSynchronous()) { + throw new IOException( + "read URP protocol properties request for synchronous function" + + " marked as not SYNCHRONOUS"); + } + } + + private byte[] readBlock() throws IOException { + int size = input.readInt(); + input.readInt(); // ignore count + byte[] bytes = new byte[size]; + input.readFully(bytes); + return bytes; + } + + private UrpMessage readLongRequest(int header) throws IOException { + boolean sync = false; + if ((header & HEADER_MOREFLAGS) != 0) { + if (unmarshal.read8Bit() != (HEADER_MUSTREPLY | HEADER_SYNCHRONOUS)) + { + throw new IOException( + "read URP request with bad MUSTREPLY/SYNCHRONOUS byte"); + } + sync = true; + } + int funId = (header & HEADER_FUNCTIONID16) != 0 + ? unmarshal.read16Bit() : unmarshal.read8Bit(); + if ((header & HEADER_NEWTYPE) != 0) { + inL1Type = unmarshal.readType(); + if (inL1Type.getTypeClass() != TypeClass.INTERFACE) { + throw new IOException( + "read URP request with non-interface type " + inL1Type); + } + } + if ((header & HEADER_NEWOID) != 0) { + inL1Oid = unmarshal.readObjectId(); + } + if ((header & HEADER_NEWTID) != 0) { + inL1Tid = unmarshal.readThreadId(); + } + //TODO: check HEADER_IGNORECACHE + return readRequest(funId, sync); + } + + private UrpMessage readShortRequest(int header) { + int funId = (header & HEADER_FUNCTIONID14) != 0 + ? ((header & HEADER_FUNCTIONID) << 8) | unmarshal.read8Bit() + : header & HEADER_FUNCTIONID; + return readRequest(funId, false); + } + + private UrpMessage readRequest(int functionId, boolean forcedSynchronous) { + boolean internal = PROPERTIES_OID.equals(inL1Oid); + // inL1Oid may be null in XInstanceProvider.getInstance("") + XCurrentContext cc = + (currentContext && !internal + && functionId != MethodDescription.ID_RELEASE) + ? (XCurrentContext) unmarshal.readInterface( + new Type(XCurrentContext.class)) + : null; + IMethodDescription desc = inL1Type.getMethodDescription(functionId); + ITypeDescription[] inSig = desc.getInSignature(); + ITypeDescription[] outSig = desc.getOutSignature(); + Object[] args = new Object[inSig.length]; + for (int i = 0; i < args.length; ++i) { + if (inSig[i] != null) { + if (outSig[i] != null) { + Object inout = Array.newInstance( + outSig[i].getComponentType().getZClass(), 1); + Array.set( + inout, 0, + unmarshal.readValue( + (TypeDescription) outSig[i].getComponentType())); + args[i] = inout; + } else { + args[i] = unmarshal.readValue((TypeDescription) inSig[i]); + } + } else { + args[i] = Array.newInstance( + outSig[i].getComponentType().getZClass(), 1); + } + } + boolean sync = forcedSynchronous || !desc.isOneway(); + if (sync) { + pendingIn.push( + inL1Tid, new PendingRequests.Item(internal, desc, args)); + } + return new UrpMessage( + inL1Tid, true, inL1Oid, inL1Type, desc, sync, cc, false, null, args, + internal); + } + + private UrpMessage readReply(int header) { + if ((header & HEADER_NEWTID) != 0) { + inL1Tid = unmarshal.readThreadId(); + } + PendingRequests.Item pending = pendingOut.pop(inL1Tid); + TypeDescription resultType; + ITypeDescription[] argTypes; + Object[] args; + boolean exception = (header & HEADER_EXCEPTION) != 0; + if (exception) { + resultType = TypeDescription.getTypeDescription(TypeClass.ANY); + argTypes = null; + args = null; + } else { + resultType = (TypeDescription) + pending.function.getReturnSignature(); + argTypes = pending.function.getOutSignature(); + args = pending.arguments; + } + Object result = resultType == null + ? null : unmarshal.readValue(resultType); + if (argTypes != null) { + for (int i = 0; i < argTypes.length; ++i) { + if (argTypes[i] != null) { + Array.set( + args[i], 0, + unmarshal.readValue( + (TypeDescription) argTypes[i].getComponentType())); + } + } + } + return new UrpMessage( + inL1Tid, false, null, null, null, false, null, exception, result, + args, pending.internal); + } + + private boolean writeRequest( + boolean internal, String oid, TypeDescription type, String function, + ThreadId tid, Object[] arguments) + throws IOException + { + IMethodDescription desc = type.getMethodDescription(function); + synchronized (output) { + if (desc.getIndex() == MethodDescription.ID_RELEASE + && releaseQueue.size() < MAX_RELEASE_QUEUE_SIZE) + { + releaseQueue.add( + new QueuedRelease(internal, oid, type, desc, tid)); + return false; + } else { + writeQueuedReleases(); + return writeRequest( + internal, oid, type, desc, tid, arguments, true); + } + } + } + + private boolean writeRequest( + boolean internal, String oid, TypeDescription type, + IMethodDescription desc, ThreadId tid, Object[] arguments, + boolean flush) + throws IOException + { + int funId = desc.getIndex(); + if (funId < 0 || funId > MAX_FUNCTIONID16) { + throw new IllegalArgumentException( + "function ID " + funId + " out of range"); + } + boolean forceSync = forceSynchronous + && funId != MethodDescription.ID_RELEASE; + boolean moreFlags = forceSync && desc.isOneway(); + boolean longHeader = moreFlags; + int header = 0; + if (!type.equals(outL1Type)) { + longHeader = true; + header |= HEADER_NEWTYPE; + outL1Type = type; + } else { + type = null; + } + if (!oid.equals(outL1Oid)) { + longHeader = true; + header |= HEADER_NEWOID; + outL1Oid = oid; + } else { + oid = null; + } + if (!tid.equals(outL1Tid)) { + longHeader = true; + header |= HEADER_NEWTID; + outL1Tid = tid; + } else { + tid = null; + } + if (funId > MAX_FUNCTIONID14) { + longHeader = true; + } + if (longHeader) { + header |= HEADER_LONGHEADER | HEADER_REQUEST; + if (funId > MAX_FUNCTIONID8) { + header |= HEADER_FUNCTIONID16; + } + if (moreFlags) { + header |= HEADER_MOREFLAGS; + } + marshal.write8Bit(header); + if (moreFlags) { + marshal.write8Bit(HEADER_MUSTREPLY | HEADER_SYNCHRONOUS); + } + if (funId > MAX_FUNCTIONID8) { + marshal.write16Bit(funId); + } else { + marshal.write8Bit(funId); + } + if (type != null) { + marshal.writeType(type); + } + if (oid != null) { + marshal.writeObjectId(oid); + } + if (tid != null) { + marshal.writeThreadId(tid); + } + } else { + if (funId > HEADER_FUNCTIONID) { + marshal.write8Bit(HEADER_FUNCTIONID14 | (funId >> 8)); + } + marshal.write8Bit(funId); + } + if (currentContext && !internal + && funId != MethodDescription.ID_RELEASE) + { + marshal.writeInterface( + UnoRuntime.getCurrentContext(), + new Type(XCurrentContext.class)); + } + ITypeDescription[] inSig = desc.getInSignature(); + ITypeDescription[] outSig = desc.getOutSignature(); + for (int i = 0; i < inSig.length; ++i) { + if (inSig[i] != null) { + if (outSig[i] != null) { + marshal.writeValue( + (TypeDescription) outSig[i].getComponentType(), + ((Object[]) arguments[i])[0]); + } else { + marshal.writeValue( + (TypeDescription) inSig[i], arguments[i]); + } + } + } + boolean sync = forceSync || !desc.isOneway(); + if (sync) { + pendingOut.push( + outL1Tid, new PendingRequests.Item(internal, desc, arguments)); + } + writeBlock(flush); + return sync; + } + + private void writeBlock(boolean flush) throws IOException { + byte[] data = marshal.reset(); + output.writeInt(data.length); + output.writeInt(1); + output.write(data); + if (flush) { + output.flush(); + } + } + + private void writeQueuedReleases() throws IOException { + for (int i = releaseQueue.size(); i > 0;) { + --i; + QueuedRelease r = (QueuedRelease) releaseQueue.get(i); + writeRequest( + r.internal, r.objectId, r.type, r.method, r.threadId, null, + false); + releaseQueue.remove(i); + } + } + + private static boolean parseAttributes(String attributes) { + boolean forceSynchronous = true; + if (attributes != null) { + StringTokenizer t = new StringTokenizer(attributes, ","); + while (t.hasMoreTokens()) { + String a = t.nextToken(); + String v = null; + int i = a.indexOf('='); + if (i >= 0) { + v = a.substring(i + 1); + a = a.substring(0, i); + } + if (a.equalsIgnoreCase("ForceSynchronous")) { + forceSynchronous = parseBooleanAttributeValue(a, v); + } else if (a.equalsIgnoreCase("negotiate")) { + // Ignored: + parseBooleanAttributeValue(a, v); + } else { + throw new IllegalArgumentException( + "unknown protocol attribute " + a); + } + } + } + return forceSynchronous; + } + + private static boolean parseBooleanAttributeValue( + String attribute, String value) + { + if (value == null) { + throw new IllegalArgumentException( + "missing value for protocol attribute " + attribute); + } + if (value.equals("0")) { + return false; + } else if (value.equals("1")) { + return true; + } else { + throw new IllegalArgumentException( + "bad value " + value + " for protocol attribute " + attribute); + } + } + + private static final class QueuedRelease { + public QueuedRelease( + boolean internal, String objectId, TypeDescription type, + IMethodDescription method, ThreadId threadId) + { + this.internal = internal; + this.objectId = objectId; + this.type = type; + this.method = method; + this.threadId = threadId; + } + + public final boolean internal; + public final String objectId; + public final TypeDescription type; + public final IMethodDescription method; + public final ThreadId threadId; + } + + private static final String PROPERTIES_OID = "UrpProtocolProperties"; + private static final int PROPERTIES_FID_REQUEST_CHANGE = 4; + private static final String PROPERTIES_FUN_REQUEST_CHANGE = "requestChange"; + private static final int PROPERTIES_FID_COMMIT_CHANGE = 5; + private static final String PROPERTIES_FUN_COMMIT_CHANGE = "commitChange"; + private static final String PROPERTY_CURRENT_CONTEXT = "CurrentContext"; + + private static final short CACHE_SIZE = 256; + + private static final int HEADER_LONGHEADER = 0x80; + private static final int HEADER_REQUEST = 0x40; + private static final int HEADER_NEWTYPE = 0x20; + private static final int HEADER_NEWOID = 0x10; + private static final int HEADER_NEWTID = 0x08; + private static final int HEADER_FUNCTIONID16 = 0x04; + private static final int HEADER_IGNORECACHE = 0x02; + private static final int HEADER_MOREFLAGS = 0x01; + private static final int HEADER_MUSTREPLY = 0x80; + private static final int HEADER_SYNCHRONOUS = 0x40; + private static final int HEADER_FUNCTIONID14 = 0x40; + private static final int HEADER_FUNCTIONID = 0x3F; + private static final int HEADER_EXCEPTION = 0x20; + + private static final int MAX_FUNCTIONID16 = 0xFFFF; + private static final int MAX_FUNCTIONID14 = 0x3FFF; + private static final int MAX_FUNCTIONID8 = 0xFF; + + private static final int STATE_INITIAL0 = 0; + private static final int STATE_INITIAL = 1; + private static final int STATE_REQUESTED = 2; + private static final int STATE_COMMITTED = 3; + private static final int STATE_WAIT = 4; + + private static final int MAX_RELEASE_QUEUE_SIZE = 100; + + private final DataInput input; + private final DataOutputStream output; + + private final Marshal marshal; + private final Unmarshal unmarshal; + + private final boolean forceSynchronous; + + private final PendingRequests pendingIn = new PendingRequests(); + private final PendingRequests pendingOut = new PendingRequests(); + + private final Object monitor = new Object(); + private int state = STATE_INITIAL0; + private boolean initialized = false; + private ThreadId propertiesTid = null; + private int random; + private boolean currentContext = false; + + private ThreadId inL1Tid = null; + private String inL1Oid = null; + private TypeDescription inL1Type = null; + + private ThreadId outL1Tid = null; + private String outL1Oid = null; + private ITypeDescription outL1Type = null; + + private final ArrayList releaseQueue = new ArrayList(); // of QueuedRelease +} diff --git a/jurt/com/sun/star/lib/util/AsynchronousFinalizer.java b/jurt/com/sun/star/lib/util/AsynchronousFinalizer.java new file mode 100644 index 000000000000..32303775b191 --- /dev/null +++ b/jurt/com/sun/star/lib/util/AsynchronousFinalizer.java @@ -0,0 +1,102 @@ +/************************************************************************* + * + * 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.lib.util; + +import java.util.LinkedList; + +/** + Helper class to asynchronously execute finalize methods. + + Current JVMs seem not to be robust against long-running finalize methods, in + that such long-running finalize methods may lead to OutOfMemoryErrors. This + class mitigates the problem by asynchronously shifting the bodies of + potentially long-running finalize methods into an extra thread. Classes that + make use of this in their finalize methods are the proxies used in the + intra-process JNI UNO bridge and the inter-process Java URP UNO bridge (where + in both cases finalizers lead to synchronous UNO release calls). + + If JVMs are getting more mature and should no longer have problems with + long-running finalize mehtods, this class could be removed again. +*/ +public final class AsynchronousFinalizer { + /** + Add a job to be executed asynchronously. + + The run method of the given job is called exactly once. If it terminates + abnormally by throwing any Throwable, that is ignored. + + @param job represents the body of some finalize method; must not be null. + */ + public static void add(Job job) { + synchronized (queue) { + boolean first = queue.isEmpty(); + queue.add(job); + if (first) { + queue.notify(); + } + } + } + + /** + An interface to represent bodies of finalize methods. + + Similar to Runnable, except that the run method may throw any Throwable + (which is effectively ignored by AsynchronousFinalizer.add, similar to + any Throwables raised by finalize being ignored). + */ + public interface Job { + void run() throws Throwable; + } + + private static final LinkedList queue = new LinkedList(); + + static { + Thread t = new Thread() { + public void run() { + for (;;) { + Job j; + synchronized (queue) { + while (queue.isEmpty()) { + try { + queue.wait(); + } catch (InterruptedException e) {} + } + j = (Job) queue.remove(0); + } + try { + j.run(); + } catch (Throwable e) {} + } + } + }; + t.setDaemon(true); + t.start(); + } + + private AsynchronousFinalizer() {} +} diff --git a/jurt/com/sun/star/lib/util/NativeLibraryLoader.java b/jurt/com/sun/star/lib/util/NativeLibraryLoader.java new file mode 100644 index 000000000000..05455a87814d --- /dev/null +++ b/jurt/com/sun/star/lib/util/NativeLibraryLoader.java @@ -0,0 +1,118 @@ +/************************************************************************* + * + * 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.lib.util; + +import java.io.File; +import java.net.URL; +import java.net.URLClassLoader; + +/** Helper functions to locate and load native files. + + The methods in this class are designed to find the requested resources in as + many cases as possible. They search various places, roughly from most + specific to most general. This works well if a component is known to bring + with it a certain resource, and that resource has to be found. However, it + might not work very well in cases where you want to check whether a + component brings with it a certain resource or not: a similarly named + resource from another component might be found by the eager search + algorithm. + */ +public final class NativeLibraryLoader { + /** Load a system library, using a given class loader to locate the library. + + This is similar to System.loadLibrary. + + @param loader a class loader; may be null + + @param libname the library name; how this name is mapped to a system + library name is system dependent + */ + public static void loadLibrary(ClassLoader loader, String libname) { + File path = getResource(loader, System.mapLibraryName(libname)); + if (path == null) { + // If the library cannot be found as a class loader resource, try + // the global System.loadLibrary as a last resort: + System.loadLibrary(libname); + } else { + System.load(path.getAbsolutePath()); + } + } + + /** Locate a system resource, using a given class loader. + + This is similar to ClassLoader.getResource, but only works for local + resources (local files), and adds additional functionality for + URLClassLoaders. + + @param loader a class loader; may be null + + @param name a resource name (that is, the name of a file) + + @return a File locating the resource, or null if the resource was not + found + */ + public static File getResource(ClassLoader loader, String name) { + if (loader != null) { + File path = UrlToFileMapper.mapUrlToFile(loader.getResource(name)); + if (path != null) { + return path; + } + } + // URLClassLoaders work on lists of URLs, which are typically URLs + // locating JAR files (scheme://auth/dir1/dir2/some.jar). The following + // code looks for resource name beside the JAR file + // (scheme://auth/dir1/dir2/name) and one directory up + // (scheme://auth/dir1/name). The second step is important in a typical + // OOo installation, where the JAR files are in the program/classes + // directory while the shared libraries are in the program directory. + if (loader instanceof URLClassLoader) { + URL[] urls = ((URLClassLoader) loader).getURLs(); + for (int i = 0; i < urls.length; ++i) { + File path = UrlToFileMapper.mapUrlToFile(urls[i]); + if (path != null) { + File dir = path.isDirectory() ? path : path.getParentFile(); + if (dir != null) { + path = new File(dir, name); + if (path.exists()) { + return path; + } + dir = dir.getParentFile(); + if (dir != null) { + path = new File(dir, name); + if (path.exists()) { + return path; + } + } + } + } + } + } + return null; + } + + private NativeLibraryLoader() {} // do not instantiate +} diff --git a/jurt/com/sun/star/lib/util/StringHelper.java b/jurt/com/sun/star/lib/util/StringHelper.java new file mode 100644 index 000000000000..5962d19e7b14 --- /dev/null +++ b/jurt/com/sun/star/lib/util/StringHelper.java @@ -0,0 +1,51 @@ +/************************************************************************* + * + * 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.lib.util; + +/** jurt.jar internal string helper methods. + */ +public final class StringHelper +{ + private StringHelper() {} // do not instantiate + + public static String replace(String str, char from, String to) { + StringBuffer b = new StringBuffer(); + for (int i = 0;;) { + int j = str.indexOf(from, i); + if (j == -1) { + b.append(str.substring(i)); + break; + } else { + b.append(str.substring(i, j)); + b.append(to); + i = j + 1; + } + } + return b.toString(); + } +} diff --git a/jurt/com/sun/star/lib/util/UrlToFileMapper.java b/jurt/com/sun/star/lib/util/UrlToFileMapper.java new file mode 100644 index 000000000000..22b6ccf0a745 --- /dev/null +++ b/jurt/com/sun/star/lib/util/UrlToFileMapper.java @@ -0,0 +1,161 @@ +/************************************************************************* + * + * 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.lib.util; + +import java.io.File; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.URL; +import java.net.URLDecoder; +import java.net.URLEncoder; + +/** + * Maps Java URL representations to File representations, on any Java version. + * + * @since UDK 3.2.8 + */ +public final class UrlToFileMapper { + + // java.net.URLEncoder.encode(String, String) and java.net.URI are only + // available since Java 1.4: + private static Method urlEncoderEncode; + private static Constructor uriConstructor; + private static Constructor fileConstructor; + static { + try { + urlEncoderEncode = URLEncoder.class.getMethod( + "encode", new Class[] { String.class, String.class }); + Class uriClass = Class.forName("java.net.URI"); + uriConstructor = uriClass.getConstructor( + new Class[] { String.class }); + fileConstructor = File.class.getConstructor( + new Class[] { uriClass }); + } catch (ClassNotFoundException e) { + } catch (NoSuchMethodException e) { + } + } + + /** + * Maps Java URL representations to File representations. + * + * @param url some URL, possibly null. + * @return a corresponding File, or null on failure. + */ + public static File mapUrlToFile(URL url) { + if (url == null) { + return null; + } else if (fileConstructor == null) { + // If java.net.URI is not available, hope that the following works + // well: First, check that the given URL has a certain form. + // Second, use the URLDecoder to decode the URL path (taking care + // not to change any plus signs to spaces), hoping that the used + // default encoding is the proper one for file URLs. Third, create + // a File from the decoded path. + return url.getProtocol().equalsIgnoreCase("file") + && url.getAuthority() == null && url.getQuery() == null + && url.getRef() == null + ? new File(URLDecoder.decode( + StringHelper.replace(url.getPath(), '+', "%2B"))) + : null; + } else { + // If java.net.URI is avaliable, do + // URI uri = new URI(encodedUrl); + // try { + // return new File(uri); + // } catch (IllegalArgumentException e) { + // return null; + // } + // where encodedUrl is url.toString(), but since that may contain + // unsafe characters (e.g., space, " "), it is encoded, as otherwise + // the URI constructor might throw java.net.URISyntaxException (in + // Java 1.5, URL.toURI might be used instead). + String encodedUrl = encode(url.toString()); + try { + Object uri = uriConstructor.newInstance( + new Object[] { encodedUrl }); + try { + return (File) fileConstructor.newInstance( + new Object[] { uri }); + } catch (InvocationTargetException e) { + if (e.getTargetException() instanceof + IllegalArgumentException) { + return null; + } else { + throw e; + } + } + } catch (InstantiationException e) { + throw new RuntimeException("This cannot happen: " + e); + } catch (IllegalAccessException e) { + throw new RuntimeException("This cannot happen: " + e); + } catch (InvocationTargetException e) { + if (e.getTargetException() instanceof Error) { + throw (Error) e.getTargetException(); + } else if (e.getTargetException() instanceof RuntimeException) { + throw (RuntimeException) e.getTargetException(); + } else { + throw new RuntimeException("This cannot happen: " + e); + } + } + } + } + + + + private static String encode(String url) { + StringBuffer buf = new StringBuffer(); + for (int i = 0; i < url.length(); ++i) { + char c = url.charAt(i); + // The RFC 2732 <uric> characters: !$&'()*+,-./:;=?@[]_~ plus digits + // and letters; additionally, do not encode % again. + if (c >= 'a' && c <= 'z' || c >= '?' && c <= '[' + || c >= '$' && c <= ';' || c == '!' || c == '=' || c == ']' + || c == '_' || c == '~') + { + buf.append(c); + } else if (c == ' ') { + buf.append("%20"); + } else { + String enc; + try { + enc = (String) urlEncoderEncode.invoke( + null, + new Object[] { new Character(c).toString(), "UTF-8" }); + } catch (IllegalAccessException e) { + throw new RuntimeException("This cannot happen: " + e); + } catch (InvocationTargetException e) { + throw new RuntimeException("This cannot happen: " + e); + } + buf.append(enc); + } + } + return buf.toString(); + } + + private UrlToFileMapper() {} +} diff --git a/jurt/com/sun/star/lib/util/makefile.mk b/jurt/com/sun/star/lib/util/makefile.mk new file mode 100644 index 000000000000..323e0dd6f376 --- /dev/null +++ b/jurt/com/sun/star/lib/util/makefile.mk @@ -0,0 +1,42 @@ +#************************************************************************* +# +# 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 + +TARGET := com_sun_star_lib_util +PACKAGE := com$/sun$/star$/lib$/util + +.INCLUDE: $(PRJ)$/util$/makefile.pmk + +JAVAFILES = \ + AsynchronousFinalizer.java \ + NativeLibraryLoader.java \ + StringHelper.java \ + UrlToFileMapper.java + +.INCLUDE: target.mk diff --git a/jurt/com/sun/star/uno/AnyConverter.java b/jurt/com/sun/star/uno/AnyConverter.java new file mode 100644 index 000000000000..cbd13fe8589a --- /dev/null +++ b/jurt/com/sun/star/uno/AnyConverter.java @@ -0,0 +1,543 @@ +package com.sun.star.uno; + +/** This class provides static methods which aim at exploring the contents of an + * Any and extracting its value. All public methods take an Object argument that + * either is the immediate object, such as Boolean, Type, interface implementation, + * or an Any that contains an object. <br>The methods which extract the value do a + * widening conversion. See the method comments for the respective conversions. + */ +public class AnyConverter +{ + /** Determines the type of an any object. + + @param object any object + @return type object + */ + static public Type getType( Object object ) + { + Type t; + if (null == object) + { + t = m_XInterface_type; + } + else if (object instanceof Any) + { + t = ((Any)object).getType(); + // nested any + if (TypeClass.ANY_value == t.getTypeClass().getValue()) + return getType( ((Any)object).getObject() ); + } + else + { + t = new Type( object.getClass() ); + } + return t; + } + + /** checks if the any contains the idl type <code>void</code>. + @param object the object to check + @return true when the any is void, false otherwise + */ + static public boolean isVoid(Object object){ + return containsType(TypeClass.VOID, object); + } + + /** checks if the any contains a value of the idl type <code>char</code>. + @param object the object to check + @return true when the any contains a char, false otherwise. + */ + static public boolean isChar(Object object){ + return containsType(TypeClass.CHAR, object); + } + + /** checks if the any contains a value of the idl type <code>boolean</code>. + @param object the object to check + @return true when the any contains a boolean, false otherwise. + */ + static public boolean isBoolean(Object object){ + return containsType(TypeClass.BOOLEAN, object); + } + + /** checks if the any contains a value of the idl type <code>byte</code>. + @param object the object to check + @return true when the any contains a byte, false otherwise. + */ + static public boolean isByte(Object object){ + return containsType(TypeClass.BYTE, object); + } + + /** checks if the any contains a value of the idl type <code>short</code>. + @param object the object to check + @return true when the any contains a short, false otherwise. + */ + static public boolean isShort(Object object){ + return containsType(TypeClass.SHORT, object); + } + + /** checks if the any contains a value of the idl type <code>long</code> (which maps to a java-int). + @param object the object to check + @return true when the any contains a int, false otherwise. + */ + static public boolean isInt(Object object){ + return containsType(TypeClass.LONG, object); + } + + /** checks if the any contains a value of the idl type <code>hyper</code> (which maps to a java-long). + @param object the object to check + @return true when the any contains a long, false otherwise. + */ + static public boolean isLong(Object object){ + return containsType(TypeClass.HYPER, object); + } + + /** checks if the any contains a value of the idl type <code>float</code>. + @param object the object to check + @return true when the any contains a float, false otherwise. + */ + static public boolean isFloat(Object object){ + return containsType(TypeClass.FLOAT, object); + } + + /** checks if the any contains a value of the idl type <code>double</code>. + @param object the object to check + @return true when the any contains a double, false otherwise. + */ + static public boolean isDouble(Object object){ + return containsType(TypeClass.DOUBLE, object); + } + + /** checks if the any contains a value of the idl type <code>string</code>. + @param object the object to check + @return true when the any contains a string, false otherwise. + */ + static public boolean isString(Object object){ + return containsType(TypeClass.STRING, object); + } + + /** checks if the any contains a value of the idl type <code>enum</code>. + @param object the object to check + @return true if the any contains an enum, false otherwise + */ + static public boolean isEnum(Object object) + { + return containsType(TypeClass.ENUM, object); + } + + /** checks if the any contains a value of the idl type <code>type</code>. + @param object the object to check + @return true when the any contains a type, false otherwise. + */ + static public boolean isType(Object object){ + return containsType(TypeClass.TYPE, object); + } + + /** checks if the any contains an interface, struct, exception, sequence or enum. + If <em>object</em> is an any with an interface type, then true is also returned if + the any contains a null reference. This is because interfaces are allowed to have + a null value contrary to other UNO types. + @param object the object to check + @return true if the any contains an object + */ + static public boolean isObject(Object object) + { + int tc = getType(object).getTypeClass().getValue(); + return (TypeClass.INTERFACE_value == tc || + TypeClass.STRUCT_value == tc || + TypeClass.EXCEPTION_value == tc || + TypeClass.SEQUENCE_value == tc || + TypeClass.ENUM_value == tc); + } + + /** checks if the any contains UNO idl sequence value (meaning a java array + containing elements which are values of UNO idl types). + @param object the object to check + @return true when the any contains an object which implements interfaces, false otherwise. + */ + static public boolean isArray(Object object){ + return containsType(TypeClass.SEQUENCE, object); + } + + /** converts an Char object or an Any object containing a Char object into a simple char. + @param object the object to convert + @return the char contained within the object + @throws com.sun.star.lang.IllegalArgumentException in case no char is contained within object + @see #isChar + */ + static public char toChar(Object object) throws com.sun.star.lang.IllegalArgumentException{ + Character ret= (Character)convertSimple(TypeClass.CHAR, null, object); + return ret.charValue(); + } + + /** converts an Boolean object or an Any object containing a Boolean object into a simple boolean. + @param object the object to convert + @return the boolean contained within the object + @throws com.sun.star.lang.IllegalArgumentException in case no boolean is contained within object + @see #isBoolean + */ + static public boolean toBoolean(Object object) throws com.sun.star.lang.IllegalArgumentException{ + Boolean ret= (Boolean)convertSimple(TypeClass.BOOLEAN, null, object); + return ret.booleanValue(); + } + + /** converts an Byte object or an Any object containing a Byte object into a simple byte. + @param object the object to convert + @return the boolean contained within the object + @throws com.sun.star.lang.IllegalArgumentException in case no byte is contained within object + @see #isBoolean + */ + static public byte toByte(Object object) throws com.sun.star.lang.IllegalArgumentException{ + Byte ret= (Byte)convertSimple(TypeClass.BYTE, null, object); + return ret.byteValue(); + } + + /** converts a number object into a simple short and allows widening conversions. + Allowed argument types are Byte, Short or Any containing these types. + @param object the object to convert + @throws com.sun.star.lang.IllegalArgumentException in case no short or byte is contained within object + @return the short contained within the object + */ + static public short toShort(Object object) throws com.sun.star.lang.IllegalArgumentException{ + Short ret= (Short)convertSimple(TypeClass.SHORT, null, object); + return ret.shortValue(); + } + /** converts a number object into an idl unsigned short and allows widening conversions. + Allowed argument types are Anies containing idl unsigned short values. + @param object the object to convert + @throws com.sun.star.lang.IllegalArgumentException + in case no idl unsigned short is contained within Any + @return an (unsigned) short + */ + static public short toUnsignedShort(Object object) + throws com.sun.star.lang.IllegalArgumentException + { + Short ret= (Short)convertSimple(TypeClass.UNSIGNED_SHORT, null, object); + return ret.shortValue(); + } + + /** converts a number object into a simple int and allows widening conversions. + Allowed argument types are Byte, Short, Integer or Any containing these types. + @param object the object to convert + @throws com.sun.star.lang.IllegalArgumentException in case no short, byte or int is contained within object. + @return the int contained within the object + */ + static public int toInt(Object object) throws com.sun.star.lang.IllegalArgumentException{ + Integer ret= (Integer) convertSimple( TypeClass.LONG, null, object); + return ret.intValue(); + } + /** converts a number object into an idl unsigned long and allows widening conversions. + Allowed argument types are Anies containing idl unsigned short or unsigned long values. + @param object the object to convert + @throws com.sun.star.lang.IllegalArgumentException + in case no idl unsigned short nor unsigned long is contained within Any + @return an (unsigned) int + */ + static public int toUnsignedInt(Object object) + throws com.sun.star.lang.IllegalArgumentException + { + Integer ret = (Integer)convertSimple(TypeClass.UNSIGNED_LONG, null, object); + return ret.intValue(); + } + + /** converts a number object into a simple long and allows widening conversions. + Allowed argument types are Byte, Short, Integer, Long or Any containing these types. + @param object the object to convert + @throws com.sun.star.lang.IllegalArgumentException in case no short, byte, int or long + is contained within object. + @return the long contained within the object + */ + static public long toLong(Object object) throws com.sun.star.lang.IllegalArgumentException{ + Long ret= (Long) convertSimple( TypeClass.HYPER, null, object); + return ret.longValue(); + } + /** converts a number object into an idl unsigned hyper and allows widening conversions. + Allowed argument types are Anies containing idl unsigned short, unsigned long or + unsigned hyper values. + @param object the object to convert + @throws com.sun.star.lang.IllegalArgumentException + in case no idl unsigned short, nor unsigned long nor unsigned hyper + is contained within object. + @return an (unsigned) long + */ + static public long toUnsignedLong(Object object) + throws com.sun.star.lang.IllegalArgumentException + { + Long ret = (Long)convertSimple(TypeClass.UNSIGNED_HYPER, null, object); + return ret.longValue(); + } + + /** converts a number object into a simple float and allows widening conversions. + Allowed argument types are Byte, Short, Float or Any containing these types. + @param object the object to convert + @throws com.sun.star.lang.IllegalArgumentException in case no byte, short or float + is contained within object. + @return the float contained within the object + */ + static public float toFloat(Object object) throws com.sun.star.lang.IllegalArgumentException{ + Float ret= (Float) convertSimple( TypeClass.FLOAT,null, object); + return ret.floatValue(); + } + + /** converts a number object into a simple double and allows widening conversions. + Allowed argument types are Byte, Short, Int, Float, Double or Any containing these types. + @param object the object to convert + @throws com.sun.star.lang.IllegalArgumentException in case no byte, short, int, float + or double is contained within object. + @return the double contained within the object + */ + static public double toDouble(Object object) throws com.sun.star.lang.IllegalArgumentException { + Double ret= (Double) convertSimple( TypeClass.DOUBLE, null, object); + return ret.doubleValue(); + } + + /** converts a string or an any containing a string into a string. + @param object the object to convert + @throws com.sun.star.lang.IllegalArgumentException in case no string is contained within object. + @return the string contained within the object + */ + static public String toString(Object object) throws com.sun.star.lang.IllegalArgumentException { + return (String) convertSimple( TypeClass.STRING, null, object); + } + + /** converts a Type or an any containing a Type into a Type. + @param object the object to convert + @throws com.sun.star.lang.IllegalArgumentException in case no type is contained within object. + @return the type contained within the object + */ + static public Type toType(Object object) throws com.sun.star.lang.IllegalArgumentException { + return (Type) convertSimple( TypeClass.TYPE, null, object); + } + + /** converts a UNO object (struct, exception, sequence, enum or interface) or an Any containing + * these types into an UNO object of a specified destination type. + * For interfaces, the argument <em>object</em> is queried for the interface specified + * by the <em>type</em> argument. That query (UnoRuntime.queryInterface) might return null, + * if the interface is not implemented or a null-ref or a VOID any is given. + * + * @param type type of the returned value + * @param object the object that is to be converted + * @return destination object + * @throws com.sun.star.lang.IllegalArgumentException + * in case conversion is not possible + */ + static public Object toObject(Type type, Object object) + throws com.sun.star.lang.IllegalArgumentException + { + return convertSimple( type.getTypeClass(), type, object ); + } + /** converts a UNO object (struct, exception, sequence, enum or interface) or an Any containing + * these types into an UNO object of a specified destination type. + * For interfaces, the argument <em>object</em> is queried for the interface specified + * by the <em>type</em> argument. That query (UnoRuntime.queryInterface) might return null, + * if the interface is not implemented or a null-ref or a VOID any is given. + * + * @param clazz class of the returned value + * @param object the object that is to be converted + * @return destination object + * @throws com.sun.star.lang.IllegalArgumentException + * in case conversion is not possible + */ + static public Object toObject(Class clazz, Object object) + throws com.sun.star.lang.IllegalArgumentException + { + return toObject( new Type( clazz ), object ); + } + + /** converts an array or an any containing an array into an array. + @param object the object to convert + @throws com.sun.star.lang.IllegalArgumentException in case no array is contained within object. + @return the array contained within the object + */ + static public Object toArray( Object object) throws com.sun.star.lang.IllegalArgumentException { + return convertSimple( TypeClass.SEQUENCE, null, object); + } + + /** + Examines the argument <em>object</em> if is correspond to the type in argument <em>what</em>. + <em>object</em> is either matched directly against the type or if it is an any then the + contained object is matched against the type. + */ + static private boolean containsType( TypeClass what, Object object){ + return (getType(object).getTypeClass().getValue() == what.getValue()); + } + + static private final Type m_XInterface_type = new Type( XInterface.class ); + + static private Object convertSimple( TypeClass destTClass, Type destType, Object object_ ) + throws com.sun.star.lang.IllegalArgumentException + { + Object object; + Type type; + if (object_ instanceof Any) + { + // unbox + Any a = (Any)object_; + object = a.getObject(); + type = a.getType(); + // nested any + if (TypeClass.ANY_value == type.getTypeClass().getValue()) + return convertSimple( destTClass, destType, object ); + } + else + { + object = object_; + type = (null == object ? m_XInterface_type : new Type( object.getClass() )); + } + + int tc = type.getTypeClass().getValue(); + int dest_tc = destTClass.getValue(); + + if (null == object) + { + // special for interfaces + if (TypeClass.INTERFACE_value == tc && dest_tc == tc) + return null; + } + else + { + switch (dest_tc) + { + case TypeClass.CHAR_value: + if (tc == TypeClass.CHAR_value) + return object; + break; + case TypeClass.BOOLEAN_value: + if (tc == TypeClass.BOOLEAN_value) + return object; + break; + case TypeClass.BYTE_value: + if (tc == TypeClass.BYTE_value) + return object; + break; + case TypeClass.SHORT_value: + switch (tc) + { + case TypeClass.BYTE_value: + return new Short( ((Byte)object).byteValue() ); + case TypeClass.SHORT_value: + return object; + } + break; + case TypeClass.UNSIGNED_SHORT_value: + switch (tc) + { + case TypeClass.UNSIGNED_SHORT_value: + return object; + } + break; + case TypeClass.LONG_value: + switch (tc) + { + case TypeClass.BYTE_value: + return new Integer( ((Byte)object).byteValue() ); + case TypeClass.SHORT_value: + case TypeClass.UNSIGNED_SHORT_value: + return new Integer( ((Short)object).shortValue() ); + case TypeClass.LONG_value: + return object; + } + break; + case TypeClass.UNSIGNED_LONG_value: + switch (tc) + { + case TypeClass.UNSIGNED_SHORT_value: + return new Integer( ((Short)object).shortValue() ); + case TypeClass.UNSIGNED_LONG_value: + return object; + } + break; + case TypeClass.HYPER_value: + switch (tc) + { + case TypeClass.BYTE_value: + return new Long( ((Byte)object).byteValue() ); + case TypeClass.SHORT_value: + case TypeClass.UNSIGNED_SHORT_value: + return new Long( ((Short)object).shortValue() ); + case TypeClass.LONG_value: + case TypeClass.UNSIGNED_LONG_value: + return new Long( ((Integer)object).intValue() ); + case TypeClass.HYPER_value: + return object; + } + break; + case TypeClass.UNSIGNED_HYPER_value: + switch (tc) + { + case TypeClass.UNSIGNED_SHORT_value: + return new Long( ((Short)object).shortValue() ); + case TypeClass.UNSIGNED_LONG_value: + return new Long( ((Integer)object).intValue() ); + case TypeClass.UNSIGNED_HYPER_value: + return object; + } + break; + case TypeClass.FLOAT_value: + switch (tc) + { + case TypeClass.BYTE_value: + return new Float( ((Byte)object).byteValue() ); + case TypeClass.SHORT_value: + return new Float( ((Short)object).shortValue() ); + case TypeClass.FLOAT_value: + return object; + } + break; + case TypeClass.DOUBLE_value: + switch (tc) + { + case TypeClass.BYTE_value: + return new Double( ((Byte)object).byteValue() ); + case TypeClass.SHORT_value: + return new Double( ((Short)object).shortValue() ); + case TypeClass.LONG_value: + return new Double( ((Integer)object).intValue() ); + case TypeClass.FLOAT_value: + return new Double( ((Float)object).floatValue() ); + case TypeClass.DOUBLE_value: + return object; + } + break; + case TypeClass.ENUM_value: + if (tc == TypeClass.ENUM_value && + (null == destTClass || destType.equals( type ) /* optional destType */)) + { + return object; + } + break; + case TypeClass.STRING_value: + if (tc == TypeClass.STRING_value) + return object; + break; + case TypeClass.TYPE_value: + if (tc == TypeClass.TYPE_value) + return object; + break; + case TypeClass.INTERFACE_value: + // Because object is a class, not an interface, it is + // controversial what kind of Type "new Type(object.class)" + // above should return (UNKNOWN or INTERFACE), so that we should + // not check here for "tc == TypeClass.INTERFACE_value". + // Instead, we check whether object (indirectly) derives from + // XInterface: + if (object instanceof XInterface) + return UnoRuntime.queryInterface( destType, object ); + break; + case TypeClass.STRUCT_value: + case TypeClass.EXCEPTION_value: + if (destType.isSupertypeOf(type)) { + return object; + } + break; + case TypeClass.SEQUENCE_value: + if (tc == TypeClass.SEQUENCE_value && + (null == destType || destType.equals( type ) /* optional destType */)) + { + return object; + } + break; + } + } + throw new com.sun.star.lang.IllegalArgumentException( + "The Argument did not hold the proper type"); + } +} diff --git a/jurt/com/sun/star/uno/Ascii.java b/jurt/com/sun/star/uno/Ascii.java new file mode 100644 index 000000000000..866bcf3960b3 --- /dev/null +++ b/jurt/com/sun/star/uno/Ascii.java @@ -0,0 +1,50 @@ +/************************************************************************* + * + * 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.uno; + +/** + * The Ascii class represents the IDL build in type <code>ascii</code>. + * <p> + * @version $Revision: 1.5 $ $ $Date: 2008-04-11 11:27:21 $ + * @author Markus Meyer + * @deprecated do not use + */ +public final class Ascii { + public final char ascii; + + /** + * Constructs a new <code>Ascii</code>. + * <p> + * @deprecated do not use + * @param c the char value + */ + public Ascii(char c) { + ascii = c; + } +} + diff --git a/jurt/com/sun/star/uno/AsciiString.java b/jurt/com/sun/star/uno/AsciiString.java new file mode 100644 index 000000000000..245375cf1fab --- /dev/null +++ b/jurt/com/sun/star/uno/AsciiString.java @@ -0,0 +1,51 @@ +/************************************************************************* + * + * 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.uno; + +/** + * The Ascii class represents the IDL build in type <code>asciistring</code>. + * <p> + * @version $Revision: 1.5 $ $ $Date: 2008-04-11 11:27:42 $ + * @author Markus Meyer + * @deprecated do not use + */ +public final class AsciiString { + public final String asciistring; + + /** + * Constructs a new <code>AsciiString</code>. + * <p> + * @deprecated do not use + * @param s the String value + */ + public AsciiString(String s) { + asciistring = s; + } + +} + diff --git a/jurt/com/sun/star/uno/MappingException.java b/jurt/com/sun/star/uno/MappingException.java new file mode 100644 index 000000000000..dc65676e1181 --- /dev/null +++ b/jurt/com/sun/star/uno/MappingException.java @@ -0,0 +1,70 @@ +/************************************************************************* + * + * 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.uno; + + +/** + * The mapping Exception. + * The exception is replaced by the com.sun.star.lang.DisposedException. + * @deprecated since UDK 3.0.2 + * <p> + * @version $Revision: 1.6 $ $ $Date: 2008-04-11 11:28:00 $ + * @see com.sun.star.uno.UnoRuntime + * @see com.sun.star.uno.IQueryInterface + * @see com.sun.star.uno.IBridge + */ +public class MappingException extends com.sun.star.uno.RuntimeException { + /** + * Contructs an empty <code>MappingException</code>. + */ + public MappingException() { + super(); + } + + /** + * Contructs an <code>MappingException</code> with a detail message. + * <p> + * @param message the detail message. + */ + public MappingException(String message) { + super(message); + } + + /** + * Contructs an <code>MappingException</code> with a detail message + * and a context. + * <p> + * @param message the detail message. + * @param context the context. + */ + public MappingException(String message, Object context) { + super(message, context); + } +} + + diff --git a/jurt/com/sun/star/uno/WeakReference.java b/jurt/com/sun/star/uno/WeakReference.java new file mode 100644 index 000000000000..904524d8c049 --- /dev/null +++ b/jurt/com/sun/star/uno/WeakReference.java @@ -0,0 +1,147 @@ +/************************************************************************* + * + * 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.uno; + +import com.sun.star.uno.XWeak; +import com.sun.star.uno.UnoRuntime; +import com.sun.star.uno.XAdapter; +import com.sun.star.uno.XReference; + +/** This class holds weak reference to an object. It actually holds a reference to a + com.sun.star.XAdapter implementation and obtains a hard reference if necessary. + */ +public class WeakReference +{ + private final boolean DEBUG= false; + private OWeakRefListener m_listener; + // There is no default constructor. Every instance must register itself with the + // XAdapter interface, which is done in the constructors. Assume we have this code + // WeakReference ref= new WeakReference(); + // ref = someOtherWeakReference; + // + // ref would not be notified (XReference.dispose()) because it did not register + // itself. Therefore the XAdapter would be kept aliver although this is not + // necessary. + + /** Creates an instance of this class. + *@param obj - another instance that is to be copied + */ + public WeakReference(WeakReference obj) + { + if (obj != null) + { + Object weakImpl= obj.get(); + if (weakImpl != null) + { + XWeak weak= UnoRuntime.queryInterface(XWeak.class, weakImpl); + if (weak != null) + { + XAdapter adapter= (XAdapter) weak.queryAdapter(); + if (adapter != null) + m_listener= new OWeakRefListener(adapter); + } + } + } + } + + /** Creates an instance of this class. + *@param obj XWeak implementation + */ + public WeakReference(Object obj) + { + XWeak weak= UnoRuntime.queryInterface(XWeak.class, obj); + if (weak != null) + { + XAdapter adapter= (XAdapter) weak.queryAdapter(); + if (adapter != null) + m_listener= new OWeakRefListener(adapter); + } + } + /** Returns a hard reference to the object that is kept weak by this class. + *@return a hard reference to the XWeak implementation. + */ + public Object get() + { + if (m_listener != null) + return m_listener.get(); + return null; + } +} + +/** Implementation of com.sun.star.uno.XReference for use with WeakReference. + * It keeps the XAdapter implementation and registers always with it. Deregistering + * occurs on notification by the adapter and the adapter is released. + */ +class OWeakRefListener implements XReference +{ + private final boolean DEBUG= false; + private XAdapter m_adapter; + + /** The constructor registered this object with adapter. + *@param adapter the XAdapter implementation. + */ + OWeakRefListener( XAdapter adapter) + { + m_adapter= adapter; + m_adapter.addReference(this); + } + /** Method of com.sun.star.uno.XReference. When called, it deregisteres this + * object with the adapter and releases the reference to it. + */ + synchronized public void dispose() + { + if (m_adapter != null) + { + m_adapter.removeReference(this); + m_adapter= null; + } + } + + /** Obtains a hard reference to the object which is kept weak by the adapter + * and returns it. + * @return hard reference to the otherwise weakly kept object. + */ + synchronized Object get() + { + Object retVal= null; + if (m_adapter != null) + { + retVal= m_adapter.queryAdapted(); + if (retVal == null) + { + // If this object registered as listener with XAdapter while it was notifying + // the listeners then this object might not have been notified. If queryAdapted + // returned null then the weak kept object is dead and the listeners have already + // been notified. And we missed it. + m_adapter.removeReference(this); + m_adapter= null; + } + } + return retVal; + } +} diff --git a/jurt/com/sun/star/uno/makefile.mk b/jurt/com/sun/star/uno/makefile.mk new file mode 100644 index 000000000000..7ab00265e065 --- /dev/null +++ b/jurt/com/sun/star/uno/makefile.mk @@ -0,0 +1,52 @@ +#************************************************************************* +# +# 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$/uno +TARGET = com_sun_star_uno + +# --- Settings ----------------------------------------------------- + +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +JAVAFILES = \ + AnyConverter.java \ + Ascii.java \ + AsciiString.java \ + MappingException.java \ + WeakReference.java + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + +doc: + pwd + cd $(PRJ) && javadoc -sourcepath /usr/local/java/src:unxlngi3.pro/japi:.:../jlibs com.sun.star.lib.util com.sun.star.uno com.sun.star.lib.uno.typeinfo com.sun.star.lib.uno.environments.java com.sun.star.lib.uno.environments.remote com.sun.star.lib.uno.protocols.iiop com.sun.star.lib.uno.bridges.java_remote com.sun.star.comp.loader com.sun.star.comp.connections -d unxlngi3.pro/doc diff --git a/jurt/demo/com/sun/star/demo/DemoServer.java b/jurt/demo/com/sun/star/demo/DemoServer.java new file mode 100644 index 000000000000..53f258b5bd46 --- /dev/null +++ b/jurt/demo/com/sun/star/demo/DemoServer.java @@ -0,0 +1,101 @@ +/************************************************************************* + * + * 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.demo; + +import com.sun.star.bridge.XBridge; +import com.sun.star.bridge.XBridgeFactory; +import com.sun.star.bridge.XInstanceProvider; + +import com.sun.star.comp.servicemanager.ServiceManager; + +import com.sun.star.connection.XAcceptor; +import com.sun.star.connection.XConnection; + +import com.sun.star.uno.UnoRuntime; + +public class DemoServer { + static String neededServices[] = new String[] { + "com.sun.star.comp.servicemanager.ServiceManager", + "com.sun.star.comp.loader.JavaLoader", + "com.sun.star.comp.connections.Acceptor", + "com.sun.star.comp.bridgefactory.BridgeFactory" + }; + + static class InstanceProvider implements XInstanceProvider { + public Object getInstance( /*IN*/String sInstanceName ) throws com.sun.star.container.NoSuchElementException, com.sun.star.uno.RuntimeException { + System.err.println("##### " + getClass().getName() + ".getInstance:" + sInstanceName); + + return null; + } + } + + static public void main(String args[]) throws Exception { + if(args.length != 1) { + System.err.println("usage : SCalc uno:connection;protocol;objectName"); + System.exit(-1); + } + + String conDcp = null; + String protDcp = null; + String rootOid = null; + + String dcp = args[0]; + + if(dcp.indexOf(';') == -1) {// use old style + conDcp = dcp; + protDcp = "iiop"; + rootOid = "classic_uno"; + } + else { // new style + int index = dcp.indexOf(':'); + String url = dcp.substring(0, index).trim(); + dcp = dcp.substring(index + 1).trim(); + + index = dcp.indexOf(';'); + conDcp = dcp.substring(0, index).trim(); + dcp = dcp.substring(index + 1).trim(); + + index = dcp.indexOf(';'); + protDcp = dcp.substring(0, index).trim(); + dcp = dcp.substring(index + 1).trim(); + + rootOid = dcp.trim().trim(); + } + + ServiceManager serviceManager = new ServiceManager(); + serviceManager.addFactories(neededServices); + + XAcceptor xAcceptor = UnoRuntime.queryInterface(XAcceptor.class, serviceManager.createInstance("com.sun.star.connection.Acceptor")); + + System.err.println("waiting for connect..."); + XConnection xConnection = xAcceptor.accept(conDcp); + + XBridgeFactory xBridgeFactory = UnoRuntime.queryInterface(XBridgeFactory.class, serviceManager.createInstance("com.sun.star.bridge.BridgeFactory")); + XBridge xBridge = xBridgeFactory.createBridge(conDcp + ";" + protDcp, protDcp, xConnection, new InstanceProvider()); + + } +} diff --git a/jurt/demo/com/sun/star/demo/TestOffice.java b/jurt/demo/com/sun/star/demo/TestOffice.java new file mode 100644 index 000000000000..5ff3fa77d9e8 --- /dev/null +++ b/jurt/demo/com/sun/star/demo/TestOffice.java @@ -0,0 +1,193 @@ +/************************************************************************* + * + * 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.demo; + + +import java.io.IOException; + + +import com.sun.star.beans.PropertyValue; +import com.sun.star.beans.PropertyState; + +import com.sun.star.bridge.XUnoUrlResolver; + +import com.sun.star.io.BufferSizeExceededException; +import com.sun.star.io.NotConnectedException; +import com.sun.star.io.XInputStream; +import com.sun.star.io.XOutputStream; + +import com.sun.star.frame.XComponentLoader; + +import com.sun.star.lang.XComponent; +import com.sun.star.lang.XMultiServiceFactory; +import com.sun.star.lang.XServiceInfo; + +import com.sun.star.text.XSimpleText; +import com.sun.star.text.XText; +import com.sun.star.text.XTextCursor; +import com.sun.star.text.XTextDocument; +import com.sun.star.text.XTextRange; + +import com.sun.star.uno.IBridge; +import com.sun.star.uno.UnoRuntime; +import com.sun.star.uno.XInterface; +import com.sun.star.uno.XNamingService; + + +public class TestOffice { + static void testPipe(XMultiServiceFactory rSmgr) throws com.sun.star.uno.Exception { + XOutputStream rOut = (XOutputStream) rSmgr.createInstance("com.sun.star.io.Pipe"); + + { + byte bytes[] = new byte[10]; + bytes[0] = 42; + rOut.writeBytes(bytes); + } + + + { + byte bytes[][] = new byte[1][]; + + XInputStream rIn = UnoRuntime.queryInterface(XInputStream.class, rOut); + if(rIn.available() != 10) + System.err.println("wrong bytes available\n"); + + if(rIn.readBytes(bytes, 10) != 10) + System.err.println("wrong bytes read\n"); + + if(42 != bytes[0][0]) + System.err.println("wrong element in sequence\n"); + } + } + + + static void testWriter(XComponent rCmp) throws IOException { + XTextDocument rTextDoc = UnoRuntime.queryInterface(XTextDocument.class, rCmp); + + XText rText = UnoRuntime.queryInterface(XText.class, rTextDoc.getText()); + XTextCursor rCursor = UnoRuntime.queryInterface(XTextCursor.class, rText.createTextCursor()); + XTextRange rRange = UnoRuntime.queryInterface(XTextRange.class, rCursor); + + byte pcText[] = new byte[1024]; + pcText[0] = 0; + System.err.println("pleast type any text\n"); + while(true) { + System.in.read(pcText); + + String string = new String(pcText); + if(string.equals("end")) break; + + string += " "; + + rText.insertString(rRange , string, false); + } + } + + static void testDocument(XMultiServiceFactory rSmgr) throws com.sun.star.uno.Exception, IOException { + XComponentLoader rLoader = UnoRuntime.queryInterface(XComponentLoader.class, rSmgr.createInstance("com.sun.star.frame.Desktop")); + + String urls[] = new String[] { + "private:factory/swriter", + "private:factory/scalc", + "private:factory/sdraw", + "http://www.heise.de", + }; + + String docu[] = new String[] { + "a new writer document ...\n", + "a new calc document ...\n", + "a new draw document ...\n", + "www.heise.de\n", + }; + + for(int i = 0; i < urls.length; ++ i) { + System.err.println("press any key to open " + docu[i]); + + System.in.read(); + while(System.in.available() > 0) + System.in.read(); + + XComponent rComponent = rLoader.loadComponentFromURL(urls[i], "_blank", 0, new PropertyValue[0]); + +// testWriter(rComponent); + System.err.println("press any key to close the document"); + System.in.read(); + while(System.in.available() > 0) + System.in.read(); + + rComponent.dispose(); + } + } + + static void doSomething(Object r) throws com.sun.star.uno.Exception, IOException { + XNamingService rName = UnoRuntime.queryInterface(XNamingService.class, r); + + if(rName != null) { + System.err.println("got the remote naming service !"); + Object rXsmgr = rName.getRegisteredObject("StarOffice.ServiceManager"); + + XMultiServiceFactory rSmgr = UnoRuntime.queryInterface(XMultiServiceFactory.class, rXsmgr); + if(rSmgr != null) { + System.err.println("got the remote service manager !"); +// testPipe(rSmgr); + testDocument(rSmgr); + } + } + } + + + + static String neededServices[] = new String[] { + "com.sun.star.comp.servicemanager.ServiceManager", + "com.sun.star.comp.loader.JavaLoader", + "com.sun.star.comp.connections.Connector", + "com.sun.star.comp.bridgefactory.BridgeFactory", + "com.sun.star.comp.urlresolver.UrlResolver" + }; + + public static void main(String argv[]) throws Exception { + if(argv.length != 1) { + System.err.println("usage : testoffice uno:connection;protocol;objectName"); + System.exit(-1); + } + + com.sun.star.comp.servicemanager.ServiceManager smgr = new com.sun.star.comp.servicemanager.ServiceManager(); + smgr.addFactories(neededServices); + + Object resolver = smgr.createInstance("com.sun.star.bridge.UnoUrlResolver" ); + XUnoUrlResolver resolver_xUnoUrlResolver = UnoRuntime.queryInterface(XUnoUrlResolver.class, resolver); + + Object rInitialObject = resolver_xUnoUrlResolver.resolve(argv[0]); + + if(rInitialObject != null) { + System.err.println("got the remote object"); + doSomething(rInitialObject); + } + } +} + diff --git a/jurt/demo/com/sun/star/demo/makefile.mk b/jurt/demo/com/sun/star/demo/makefile.mk new file mode 100644 index 000000000000..6bc3e1ae9da7 --- /dev/null +++ b/jurt/demo/com/sun/star/demo/makefile.mk @@ -0,0 +1,57 @@ +#************************************************************************* +# +# 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$/demo +TARGET := com_sun_star_demo + +RDB=$(SOLARBINDIR)$/applicat.rdb + +# --- Settings ----------------------------------------------------- +.INCLUDE : settings.mk + +#Files -------------------------------------------------------- + +JARFILES = unoil.jar ridl.jar + +GENJAVACLASSFILES = + +JAVACLASSFILES= \ + $(CLASSDIR)$/$(PACKAGE)$/DemoServer.class \ + $(CLASSDIR)$/$(PACKAGE)$/TestOffice.class + +TYPES={$(subst,.class, $(subst,$/,. $(subst,$(CLASSDIR)$/,-T $(GENJAVACLASSFILES))))} +GENJAVAFILES = {$(subst,.class,.java $(subst,$/class, $(GENJAVACLASSFILES)))} + +JAVAFILES= $(subst,$(CLASSDIR)$/$(PACKAGE)$/, $(subst,.class,.java $(JAVACLASSFILES))) $(GENJAVAFILES) + +# --- Targets ------------------------------------------------------ + + +.INCLUDE : target.mk diff --git a/jurt/prj/build.lst b/jurt/prj/build.lst new file mode 100644 index 000000000000..f3d498b8cdd6 --- /dev/null +++ b/jurt/prj/build.lst @@ -0,0 +1,18 @@ +ju jurt : ridljar sal NULL +ju jurt usr1 - all ju_mkout NULL +ju jurt\com\sun\star\lib\util nmake - all ju_libutil NULL +ju jurt\com\sun\star\uno nmake - all ju_uno NULL +ju jurt\com\sun\star\comp\loader nmake - all ju_co_loader ju_uno ju_libutil NULL +ju jurt\com\sun\star\comp\bridgefactory nmake - all ju_co_bfactr ju_co_loader NULL +ju jurt\com\sun\star\lib\uno nmake - all ju_cssl_uno NULL +ju jurt\com\sun\star\lib\uno\environments\java nmake - all ju_env_java ju_cssl_uno NULL +ju jurt\com\sun\star\lib\uno\environments\remote nmake - all ju_env_remote ju_env_java NULL +ju jurt\com\sun\star\lib\uno\protocols\urp nmake - all ju_prot_urp ju_env_remote NULL +ju jurt\com\sun\star\lib\uno\bridges\java_remote nmake - all ju_brid_jrm ju_co_loader ju_cssl_uno ju_env_remote NULL +ju jurt\com\sun\star\lib\connections\socket nmake - all ju_con_sock ju_co_loader NULL +ju jurt\com\sun\star\lib\connections\pipe nmake - all ju_con_pipe ju_co_loader ju_libutil NULL +ju jurt\com\sun\star\comp\connections nmake - all ju_con ju_co_loader NULL +ju jurt\com\sun\star\comp\servicemanager nmake - all ju_servman NULL +ju jurt\com\sun\star\comp\urlresolver nmake - all ju_urlres ju_co_loader NULL +ju jurt\source\pipe nmake - all ju_src_pipe NULL +ju jurt\util nmake - all ju_ut ju_brid_jrm ju_co_bfactr ju_con ju_con_sock ju_con_pipe ju_cssl_uno ju_env_java ju_prot_urp ju_servman ju_urlres ju_src_pipe ju_libutil ju_uno NULL diff --git a/jurt/prj/d.lst b/jurt/prj/d.lst new file mode 100644 index 000000000000..5223fe2fe5ee --- /dev/null +++ b/jurt/prj/d.lst @@ -0,0 +1,6 @@ +..\%__SRC%\class\jurt.jar %_DEST%\bin%_EXT%\jurt.jar +..\%__SRC%\bin\jpipe*.dll %_DEST%\bin%_EXT%\jpipe*.dll +..\%__SRC%\lib\libjpipe*.so %_DEST%\lib%_EXT%\libjpipe*.so +..\%__SRC%\lib\libjpipe*.dylib %_DEST%\lib%_EXT%\libjpipe*.dylib + +..\%__SRC%\bin\jurt_src.zip %COMMON_DEST%\bin%_EXT%\jurt_src.zip diff --git a/jurt/source/pipe/com_sun_star_lib_connections_pipe_PipeConnection.c b/jurt/source/pipe/com_sun_star_lib_connections_pipe_PipeConnection.c new file mode 100644 index 000000000000..255da24c2f86 --- /dev/null +++ b/jurt/source/pipe/com_sun_star_lib_connections_pipe_PipeConnection.c @@ -0,0 +1,531 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#include "osl/security.h" +#include <osl/pipe.h> + +#include "com_sun_star_lib_connections_pipe_PipeConnection.h" + +/*****************************************************************************/ +/* exception macros */ + +static void ThrowException(JNIEnv * env, char const * type, char const * msg) { + jclass c; + (*env)->ExceptionClear(env); + c = (*env)->FindClass(env, type); + if (c == NULL) { + (*env)->ExceptionClear(env); + (*env)->FatalError(env, "JNI FindClass failed"); + } + if ((*env)->ThrowNew(env, c, msg) != 0) { + (*env)->ExceptionClear(env); + (*env)->FatalError(env, "JNI ThrowNew failed"); + } +} + +/*****************************************************************************/ +/* helper functions prototypes */ + +static oslPipe getPipe(JNIEnv * env, jobject obj_this); +static rtl_uString * jstring2ustring(JNIEnv * env, jstring jstr); + +/*****************************************************************************/ +/* get pipe */ + +static oslPipe getPipe(JNIEnv * env, jobject obj_this) +{ + jclass tclass; + jfieldID fid; + tclass = (*env)->GetObjectClass(env, obj_this); + if (tclass == NULL) + { + ThrowException(env, + "java/lang/RuntimeException", + "native pipe cannot find class"); + return NULL; + } + + fid = (*env)->GetFieldID(env, tclass, "_nPipeHandle", "J"); + if (fid == NULL) + { + ThrowException(env, + "java/lang/RuntimeException", + "native pipe cannot find field"); + return NULL; + } + return (oslPipe) SAL_INT_CAST( + sal_IntPtr, (*env)->GetLongField(env, obj_this, fid)); +} + +/*****************************************************************************/ +/* convert jstring to rtl_uString */ + +static rtl_uString * jstring2ustring(JNIEnv * env, jstring jstr) +{ + const char * cstr; + rtl_uString * ustr = NULL; + cstr = (*env)->GetStringUTFChars(env, jstr, NULL); + rtl_uString_newFromAscii(&ustr, cstr); + (*env)->ReleaseStringUTFChars(env, jstr, cstr); + return ustr; +} + +/*****************************************************************************/ +/* + * Class: com_sun_star_lib_connections_pipe_PipeConnection + * Method: connect + * Signature: (Lcom/sun/star/beans/NativeService;)V + */ +JNIEXPORT void JNICALL Java_com_sun_star_lib_connections_pipe_PipeConnection_createJNI + (JNIEnv * env, jobject obj_this, jstring name) +{ + enum { + START = 0, + INMONITOR, + GOTNAME, + CREATED + }; + + short state = START; + + jclass tclass; + jfieldID fid; + + oslSecurity psec = osl_getCurrentSecurity(); + oslPipe npipe = NULL; + rtl_uString * pname = NULL; + if ((*env)->MonitorEnter(env, obj_this) != 0) + { + ThrowException(env, + "java/lang/RuntimeException", + "native pipe cannot synchronize on the object"); + goto error; + } + state = INMONITOR; + + /* check connection state */ + npipe = getPipe(env, obj_this); + if ((*env)->ExceptionOccurred(env) != NULL) + goto error; + if (npipe != NULL) + { + ThrowException(env, + "com/sun/star/io/IOException", + "native pipe is already connected"); + goto error; + } + + /* save the pipe name */ + tclass = (*env)->GetObjectClass(env, obj_this); + if (tclass == NULL) + { + ThrowException(env, + "java/lang/RuntimeException", + "native pipe cannot find class"); + goto error; + } + + fid = (*env)->GetFieldID(env, tclass, + "_aDescription", "Ljava/lang/String;"); + if (fid == NULL) + { + ThrowException(env, + "java/lang/RuntimeException", + "native pipe cannot find field"); + goto error; + } + + (*env)->SetObjectField(env, obj_this, fid, (jobject)name); + + /* convert pipe name to rtl_uString */ + pname = jstring2ustring(env, name); + if (pname == NULL) + { + ThrowException(env, + "java/lang/RuntimeException", + "native pipe cannot convert name"); + goto error; + } + state = GOTNAME; + + /* try to connect */ + npipe = osl_createPipe(pname, osl_Pipe_OPEN, psec); + if (npipe == NULL) + { + ThrowException(env, + "java/lang/RuntimeException", + "cannot create native pipe"); + goto error; + } + state = CREATED; + + /* save the pipe */ + tclass = (*env)->GetObjectClass(env, obj_this); + if (tclass == NULL) + { + ThrowException(env, + "java/lang/RuntimeException", + "native pipe cannot find class"); + goto error; + } + + fid = (*env)->GetFieldID(env, tclass, "_nPipeHandle", "J"); + if (fid == NULL) + { + ThrowException(env, + "java/lang/RuntimeException", + "native pipe cannot find field"); + goto error; + } + (*env)->SetLongField( + env, obj_this, fid, SAL_INT_CAST(jlong, (sal_IntPtr) npipe)); + + /* done */ + rtl_uString_release(pname); + (*env)->MonitorExit(env, obj_this); + osl_freeSecurityHandle(psec); + return; + + error: + switch (state) + { + case CREATED: + osl_closePipe(npipe); + osl_releasePipe(npipe); + case GOTNAME: + rtl_uString_release(pname); + case INMONITOR: + (*env)->MonitorExit(env, obj_this); + case START: + osl_freeSecurityHandle(psec); + default: + break; + } + return; +} + +/*****************************************************************************/ +/* + * Class: com_sun_star_lib_connections_pipe_PipeConnection + * Method: closeJNI + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_com_sun_star_lib_connections_pipe_PipeConnection_closeJNI + (JNIEnv * env, jobject obj_this) +{ + enum { + START = 0, + INMONITOR + }; + + short state = START; + oslPipe npipe; /* native pipe */ + jclass tclass; /* this class */ + jfieldID fid; /* a field identifier */ + + if ((*env)->MonitorEnter(env, obj_this) != 0) + { + ThrowException(env, + "java/lang/RuntimeException", + "native pipe cannot synchronize on the object"); + goto error; + } + state = INMONITOR; + + /* check connection state */ + npipe = getPipe(env, obj_this); + if ((*env)->ExceptionOccurred(env) != NULL) + goto error; + if (npipe == NULL) + { + ThrowException(env, + "com/sun/star/io/IOException", + "native pipe is not connected"); + goto error; + } + + /* remove the reference to the pipe */ + tclass = (*env)->GetObjectClass(env, obj_this); + if (tclass == NULL) + { + ThrowException(env, + "java/lang/RuntimeException", + "native pipe cannot find class"); + goto error; + } + + fid = (*env)->GetFieldID(env, tclass, "_nPipeHandle", "J"); + if (fid == NULL) + { + ThrowException(env, + "java/lang/RuntimeException", + "native pipe cannot find field"); + goto error; + } + + (*env)->SetLongField(env, obj_this, fid, (jlong)0); + + /* release the pipe */ + osl_closePipe(npipe); + osl_releasePipe(npipe); + + /* done */ + (*env)->MonitorExit(env, obj_this); + return; + + error: + switch (state) + { + case INMONITOR: + (*env)->MonitorExit(env, obj_this); + case START: + default: + break; + } + return; +} + +/*****************************************************************************/ +/* + * Class: com_sun_star_lib_connections_pipe_PipeConnection + * Method: readJNI + * Signature: ([[BI)I + */ +JNIEXPORT jint JNICALL Java_com_sun_star_lib_connections_pipe_PipeConnection_readJNI + (JNIEnv * env, jobject obj_this, jobjectArray buffer, jint len) +{ + enum { + START = 0, + INMONITOR, + AQUIRED, + GOTBUFFER + }; + + short state = START; + oslPipe npipe; /* native pipe */ + void * nbuff = NULL; /* native read buffer */ + jbyteArray bytes; /* java read buffer */ + jint nread; /* number of bytes has been read */ + + /* enter monitor */ + if ((*env)->MonitorEnter(env, obj_this) != 0) + { + ThrowException(env, + "java/lang/RuntimeException", + "native pipe cannot synchronize on the object"); + goto error; + } + state = INMONITOR; + + /* check connection state */ + npipe = getPipe(env, obj_this); + if ((*env)->ExceptionOccurred(env) != NULL) + goto error; + if (npipe == NULL) + { + ThrowException(env, + "com/sun/star/io/IOException", + "native pipe is not connected"); + goto error; + } + + /* aquire pipe */ + osl_acquirePipe( npipe ); + state = AQUIRED; + + /* allocate a buffer */ + if ((nbuff = malloc(len)) == NULL) + { + ThrowException(env, + "java/lang/RuntimeException", + "native pipe out of memory"); + goto error; + } + + state = GOTBUFFER; + + /* exit monitor */ + (*env)->MonitorExit(env, obj_this); + + /* reading */ + nread = osl_readPipe(npipe, nbuff, len); + + /* enter monitor again */ + if ((*env)->MonitorEnter(env, obj_this) != 0) + { + ThrowException(env, + "java/lang/RuntimeException", + "native pipe cannot synchronize on the object"); + goto error; + } + + /* copy buffer */ + if (nread >= 0) + { + bytes = (*env)->NewByteArray(env, len); + if (bytes == NULL) + { + ThrowException(env, + "java/lang/RuntimeException", + "native pipe out of memory"); + goto error; + } + + /* save the data */ + (*env)->SetByteArrayRegion(env, bytes, 0, len, nbuff); + (*env)->SetObjectArrayElement(env, buffer, 0, bytes); + (*env)->DeleteLocalRef(env, bytes); + } + + /* done */ + free(nbuff); + if ( state >= AQUIRED ) + osl_releasePipe( npipe ); + + /* exit monitor */ + (*env)->MonitorExit(env, obj_this); + return nread; + + error: + switch (state) + { + case GOTBUFFER: + free(nbuff); + case INMONITOR: + (*env)->MonitorExit(env, obj_this); + case START: + default: + break; + } + return -1; +} + +/*****************************************************************************/ +/* + * Class: com_sun_star_lib_connections_pipe_PipeConnection + * Method: writeJNI + * Signature: ([B)V + */ +JNIEXPORT void JNICALL Java_com_sun_star_lib_connections_pipe_PipeConnection_writeJNI + (JNIEnv * env, jobject obj_this, jbyteArray buffer) +{ + enum { + START = 0, + INMONITOR, + GOTBUFFER + }; + + short state = START; + oslPipe npipe; /* native pipe */ + long count; /* number of bytes has been written */ + jsize nwrite; /* number of bytes to write */ + jbyte * nbuff = NULL; /* native buffer */ + + if ((*env)->MonitorEnter(env, obj_this) != 0) + { + ThrowException(env, + "java/lang/RuntimeException", + "native pipe cannot synchronize on the object"); + goto error; + } + state = INMONITOR; + + /* check connection state */ + npipe = getPipe(env, obj_this); + if ((*env)->ExceptionOccurred(env) != NULL) + goto error; + if (npipe == NULL) + { + ThrowException(env, + "com/sun/star/io/IOException", + "native pipe is not connected"); + goto error; + } + + nwrite = (*env)->GetArrayLength(env, buffer); + if (nwrite > 0) + { + nbuff = (*env)->GetByteArrayElements(env, buffer, NULL); + if (nbuff == NULL) + { + ThrowException(env, + "java/lang/RuntimeException", + "native pipe out of memory"); + goto error; + } + state = GOTBUFFER; + + (*env)->MonitorExit(env, obj_this); + /* writing */ + count = osl_writePipe(npipe, nbuff, nwrite); + if ((*env)->MonitorEnter(env, obj_this) != 0) + { + ThrowException(env, + "java/lang/RuntimeException", + "native pipe cannot synchronize on the object"); + goto error; + } + if (count != nwrite) + { + ThrowException(env, + "com/sun/star/io/IOException", + "native pipe is failed to write"); + goto error; + } + } + /* done */ + (*env)->ReleaseByteArrayElements(env, buffer, nbuff, JNI_ABORT); + (*env)->MonitorExit(env, obj_this); + return; + + error: + switch (state) + { + case GOTBUFFER: + (*env)->ReleaseByteArrayElements(env, buffer, nbuff, JNI_ABORT); + case INMONITOR: + (*env)->MonitorExit(env, obj_this); + case START: + default: + break; + } + return; +} + +/*****************************************************************************/ +/* + * Class: com_sun_star_lib_connections_pipe_PipeConnection + * Method: flushJNI + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_com_sun_star_lib_connections_pipe_PipeConnection_flushJNI + (JNIEnv * env, jobject obj_this) +{ + (void) env; /* not used */ + (void) obj_this; /* not used */ + return; +} diff --git a/jurt/source/pipe/com_sun_star_lib_connections_pipe_PipeConnection.h b/jurt/source/pipe/com_sun_star_lib_connections_pipe_PipeConnection.h new file mode 100644 index 000000000000..a21e8f979348 --- /dev/null +++ b/jurt/source/pipe/com_sun_star_lib_connections_pipe_PipeConnection.h @@ -0,0 +1,53 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include <jni.h> +/* Header for class com_sun_star_connections_pipe_PipeConnection */ + +#ifndef _Included_com_sun_star_lib_connections_pipe_PipeConnection_h +#define _Included_com_sun_star_lib_connections_pipe_PipeConnection_h +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: com_sun_star_lib_connections_pipe_PipeConnection + * Method: connect + * Signature: (Ljava/lang/String;)V + */ +JNIEXPORT void JNICALL Java_com_sun_star_lib_connections_pipe_PipeConnection_createJNI + (JNIEnv *, jobject, jstring); + +/* + * Class: com_sun_star_lib_connections_pipe_PipeConnection + * Method: readJNI + * Signature: ([[BI)I + */ +JNIEXPORT jint JNICALL Java_com_sun_star_lib_connections_pipe_PipeConnection_readJNI + (JNIEnv *, jobject, jobjectArray, jint); + +/* + * Class: com_sun_star_lib_connections_pipe_PipeConnection + * Method: writeJNI + * Signature: ([B)V + */ +JNIEXPORT void JNICALL Java_com_sun_star_lib_connections_pipe_PipeConnection_writeJNI + (JNIEnv *, jobject, jbyteArray); + +/* + * Class: com_sun_star_lib_connections_pipe_PipeConnection + * Method: flushJNI + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_com_sun_star_lib_connections_pipe_PipeConnection_flushJNI + (JNIEnv *, jobject); + +/* + * Class: com_sun_star_lib_connections_pipe_PipeConnection + * Method: closeJNI + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_com_sun_star_lib_connections_pipe_PipeConnection_closeJNI + (JNIEnv *, jobject); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/jurt/source/pipe/jpipe.dxp b/jurt/source/pipe/jpipe.dxp new file mode 100644 index 000000000000..e07ea907470f --- /dev/null +++ b/jurt/source/pipe/jpipe.dxp @@ -0,0 +1,5 @@ +Java_com_sun_star_lib_connections_pipe_PipeConnection_createJNI +Java_com_sun_star_lib_connections_pipe_PipeConnection_closeJNI +Java_com_sun_star_lib_connections_pipe_PipeConnection_readJNI +Java_com_sun_star_lib_connections_pipe_PipeConnection_writeJNI +Java_com_sun_star_lib_connections_pipe_PipeConnection_flushJNI diff --git a/jurt/source/pipe/makefile.mk b/jurt/source/pipe/makefile.mk new file mode 100644 index 000000000000..e56ece77f5c1 --- /dev/null +++ b/jurt/source/pipe/makefile.mk @@ -0,0 +1,39 @@ +PRJ=..$/.. + +PRJNAME=jurt +TARGET=jpipe +ENABLE_EXCEPTIONS=TRUE + +#? +NO_DEFAULT_STL=TRUE +NO_BSYMBOLIC=TRUE +USE_DEFFILE=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +.IF "$(SOLAR_JAVA)"=="" +nojava: + @echo "Not building jurt because Java is disabled" +.ENDIF + +# --- Files -------------------------------------------------------- + +SLOFILES = \ + $(SLO)$/com_sun_star_lib_connections_pipe_PipeConnection.obj + +SHL1TARGET=$(TARGET) +SHL1LIBS=$(SLB)$/$(TARGET).lib +SHL1STDLIBS=$(SALLIB) +SHL1DEF=$(MISC)$/$(SHL1TARGET).def +SHL1RPATH=URELIB + +DEF1NAME=$(SHL1TARGET) +DEF1EXPORTFILE=$(TARGET).dxp +DEF1DES=jurtpipe + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + diff --git a/jurt/test/com/sun/star/comp/bridgefactory/BridgeFactory_Test.java b/jurt/test/com/sun/star/comp/bridgefactory/BridgeFactory_Test.java new file mode 100644 index 000000000000..d027a412ca5c --- /dev/null +++ b/jurt/test/com/sun/star/comp/bridgefactory/BridgeFactory_Test.java @@ -0,0 +1,106 @@ +/************************************************************************* + * + * 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.bridgefactory; + +import com.sun.star.bridge.BridgeExistsException; +import com.sun.star.bridge.XBridge; +import com.sun.star.comp.connections.PipedConnection; +import com.sun.star.connection.XConnection; +import com.sun.star.lang.XComponent; +import com.sun.star.uno.UnoRuntime; +import complexlib.ComplexTestCase; + +public final class BridgeFactory_Test extends ComplexTestCase { + public String getTestObjectName() { + return getClass().getName(); + } + + public String[] getTestMethodNames() { + return new String[] { "test" }; + } + + public void test() throws Exception { + PipedConnection rightSide = new PipedConnection(new Object[0]); + PipedConnection leftSide = new PipedConnection(new Object[]{rightSide}); + + BridgeFactory bridgeFactory = new BridgeFactory(); // create the needed bridgeFactory + + // create a bridge + XBridge xBridge = bridgeFactory.createBridge("testbridge", "urp", (XConnection)leftSide, null); + + // test that we get the same bridge + assure("", UnoRuntime.areSame(xBridge, + bridgeFactory.getBridge("testbridge"))); + + // test that we can not create another bridge with same name + try { + XBridge dummy = bridgeFactory.createBridge("testbridge", "urp", (XConnection)leftSide, null); + + failed(""); + } + catch(BridgeExistsException bridgeExistsException) { + } + + + // test getExistingBridges + XBridge xBridges[] = bridgeFactory.getExistingBridges(); + assure("", UnoRuntime.areSame(xBridge, xBridges[0])); + + // dispose the bridge + XComponent xComponent = UnoRuntime.queryInterface(XComponent.class, xBridge); + xComponent.dispose(); + + + // test that the bridge has been removed + assure("", bridgeFactory.getBridge("testbridge") == null); + + + + rightSide = new PipedConnection(new Object[0]); + leftSide = new PipedConnection(new Object[]{rightSide}); + + + // test that we really get a new bridge + XBridge xBridge_new = bridgeFactory.createBridge("testbridge", "urp", (XConnection)leftSide, null); + assure("", !UnoRuntime.areSame(xBridge, xBridge_new)); + + for(int i = 0; i <10000; ++ i) { + Object x[] = new Object[100]; + } + + // test getExistingBridges + xBridges = bridgeFactory.getExistingBridges(); + assure("", + xBridges.length == 1 + && UnoRuntime.areSame(xBridge_new, xBridges[0])); + + // dispose the new bridge + XComponent xComponent_new = UnoRuntime.queryInterface(XComponent.class, xBridge_new); + xComponent_new.dispose(); + } +} diff --git a/jurt/test/com/sun/star/comp/bridgefactory/makefile.mk b/jurt/test/com/sun/star/comp/bridgefactory/makefile.mk new file mode 100644 index 000000000000..6de5c582ec83 --- /dev/null +++ b/jurt/test/com/sun/star/comp/bridgefactory/makefile.mk @@ -0,0 +1,36 @@ +#************************************************************************* +# +# 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 +TARGET := test_com_sun_star_comp_bridgefactory + +PACKAGE := com$/sun$/star$/comp$/bridgefactory +JAVATESTFILES := BridgeFactory_Test.java +JARFILES := ridl.jar + +.INCLUDE: javaunittest.mk diff --git a/jurt/test/com/sun/star/comp/connections/PipedConnection_Test.java b/jurt/test/com/sun/star/comp/connections/PipedConnection_Test.java new file mode 100644 index 000000000000..68f9461745e1 --- /dev/null +++ b/jurt/test/com/sun/star/comp/connections/PipedConnection_Test.java @@ -0,0 +1,147 @@ +/************************************************************************* + * + * 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.connections; + +import complexlib.ComplexTestCase; + +public final class PipedConnection_Test extends ComplexTestCase { + public String getTestObjectName() { + return getClass().getName(); + } + + public String[] getTestMethodNames() { + return new String[] { "test" }; + } + + public void test() throws Exception { + PipedConnection rightSide = new PipedConnection(new Object[0]); + PipedConnection leftSide = new PipedConnection(new Object[]{rightSide}); + + byte theByte[] = new byte[1]; + + Reader reader = new Reader(rightSide, theByte); + Writer writer = new Writer(leftSide, theByte, reader); + + reader.start(); + writer.start(); + + Thread.sleep(2000); + + writer.term(); + writer.join(); + + reader.join(); + + assure("", writer._state && reader._state); + } + + static class Reader extends Thread { + PipedConnection _pipedConnection; + byte _theByte[]; + boolean _quit; + boolean _state = false; + + Reader(PipedConnection pipedConnection, byte theByte[]) { + _pipedConnection = pipedConnection; + _theByte = theByte; + } + + public void run() { + try { + byte bytes[][] = new byte[1][]; + + while(!_quit) { + int read = _pipedConnection.read(bytes, 1); + + if(read == 1) { +// System.err.println("read :" + bytes[0][0]); + + if(_theByte[0] != bytes[0][0]) + throw new NullPointerException(); + + synchronized(this) { + notifyAll(); + } + } + else + _quit = true; // EOF + } + + _pipedConnection.close(); + _state = true; + } + catch(com.sun.star.io.IOException ioException) { + System.err.println("#### Reader - unexpected:" + ioException); + } + + } + } + + static class Writer extends Thread { + PipedConnection _pipedConnection; + byte _theByte[]; + Reader _reader; + boolean _quit; + boolean _state = false; + + Writer(PipedConnection pipedConnection, byte theByte[], Reader reader) { + _pipedConnection = pipedConnection; + _reader = reader; + _theByte = theByte; + } + + public void run() { + try { + while(!_quit) { + synchronized(_reader) { + _pipedConnection.write(_theByte); + _pipedConnection.flush(); +// System.err.println("written :" + _theByte[0]); + + _reader.wait(); + } + ++ _theByte[0]; + } + + _pipedConnection.close(); + + _state = true; + } + catch(com.sun.star.io.IOException ioException) { + System.err.println("#### Writer:" + ioException); + } + catch(InterruptedException interruptedException) { + System.err.println("#### Writer:" + interruptedException); + } + } + + public void term() { + _quit = true; + } + } +} diff --git a/jurt/test/com/sun/star/comp/connections/makefile.mk b/jurt/test/com/sun/star/comp/connections/makefile.mk new file mode 100644 index 000000000000..d311cd0b9c07 --- /dev/null +++ b/jurt/test/com/sun/star/comp/connections/makefile.mk @@ -0,0 +1,36 @@ +#************************************************************************* +# +# 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 +TARGET := test_com_sun_star_comp_connections + +PACKAGE := com$/sun$/star$/comp$/connections +JAVATESTFILES := PipedConnection_Test.java +JARFILES := ridl.jar + +.INCLUDE: javaunittest.mk diff --git a/jurt/test/com/sun/star/lib/uno/bridges/java_remote/BridgedObject_Test.java b/jurt/test/com/sun/star/lib/uno/bridges/java_remote/BridgedObject_Test.java new file mode 100644 index 000000000000..5327993fa65b --- /dev/null +++ b/jurt/test/com/sun/star/lib/uno/bridges/java_remote/BridgedObject_Test.java @@ -0,0 +1,73 @@ +/************************************************************************* + * + * 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.lib.uno.bridges.java_remote; + +import com.sun.star.bridge.XBridge; +import com.sun.star.uno.Type; +import com.sun.star.uno.XInterface; +import complexlib.ComplexTestCase; + +public final class BridgedObject_Test extends ComplexTestCase { + public String[] getTestMethodNames() { + return new String[] { "test" }; + } + + public void test() { + RequestHandler handler = new RequestHandler() { + public Object sendRequest( + String oid, Type type, String operation, Object[] args) + { + return null; + } + }; + XBridge bridge1 = new TestBridge(); + ProxyFactory factory1 = new ProxyFactory(handler, bridge1); + XBridge bridge2 = new TestBridge(); + ProxyFactory factory2 = new ProxyFactory(handler, bridge2); + Object object0 = new Object(); + Object object1 = factory1.create("", new Type(XInterface.class)); + Object object2 = factory2.create("", new Type(XInterface.class)); + assure(BridgedObject.getBridge(object0) == null); + assure(BridgedObject.getBridge(object1) == bridge1); + assure(BridgedObject.getBridge(object2) == bridge2); + } + + private static final class TestBridge implements XBridge { + public Object getInstance(String instanceName) { + return null; + } + + public String getName() { + return null; + } + + public String getDescription() { + return null; + } + } +} diff --git a/jurt/test/com/sun/star/lib/uno/bridges/java_remote/ProxyFactory_Test.java b/jurt/test/com/sun/star/lib/uno/bridges/java_remote/ProxyFactory_Test.java new file mode 100644 index 000000000000..8d0fa09a657a --- /dev/null +++ b/jurt/test/com/sun/star/lib/uno/bridges/java_remote/ProxyFactory_Test.java @@ -0,0 +1,145 @@ +/************************************************************************* + * + * 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.lib.uno.bridges.java_remote; + +import com.sun.star.uno.IQueryInterface; +import com.sun.star.uno.MappingException; +import com.sun.star.uno.Type; +import com.sun.star.uno.UnoRuntime; +import com.sun.star.uno.XInterface; +import com.sun.star.uno.XNamingService; +import complexlib.ComplexTestCase; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.UndeclaredThrowableException; + +public final class ProxyFactory_Test extends ComplexTestCase { + public String getTestObjectName() { + return getClass().getName(); + } + + public String[] getTestMethodNames() { + return new String[] { "testQueryInterface", "testExceptionHandling" }; + } + + public void testQueryInterface() { + TestRequestHandler handler = new TestRequestHandler(); + Type type = new Type(XNamingService.class); + Object proxy = new ProxyFactory(handler, null).create("TestOID", type); + assure("", proxy == ((IQueryInterface) proxy).queryInterface(type)); + assure("", proxy == UnoRuntime.queryInterface(type, proxy)); + } + + public void testExceptionHandling() throws Exception { + TestRequestHandler handler = new TestRequestHandler(); + Object proxy = new ProxyFactory(handler, null).create( + "TestOID", new Type(XNamingService.class)); + testExceptions( + handler, + proxy.getClass().getMethod("queryInterface", + new Class[] { Type.class }), + proxy, new Object[] { new Type(XInterface.class) }, + new Class[] { null, MappingException.class, + com.sun.star.uno.RuntimeException.class, + UndeclaredThrowableException.class, + NullPointerException.class, + UndeclaredThrowableException.class }); + testExceptions( + handler, + proxy.getClass().getMethod("getRegisteredObject", + new Class[] { String.class }), + proxy, new Object[] { "TestName" }, + new Class[] { null, MappingException.class, + com.sun.star.uno.RuntimeException.class, + com.sun.star.uno.Exception.class, + NullPointerException.class, Exception.class }); + } + + private void testExceptions(TestRequestHandler handler, Method method, + Object obj, Object[] args, Class[] exceptions) + throws Exception + { + for (int i = 0; i < exceptions.length; ++i) { + handler.setModus(i); + testExceptionType(method, obj, args, exceptions[i]); + } + } + + private void testExceptionType(Method method, Object obj, Object[] args, + Class exception) throws Exception { + try { + method.invoke(obj, args); + assure("expected exception: " + exception, exception == null); + } catch (InvocationTargetException e) { + assure("unexpected exception: " + e.getTargetException(), + exception != null + && exception.isInstance(e.getTargetException())); + // TODO check stack trace + } + } + + private static final class TestRequestHandler implements RequestHandler { + public Object sendRequest(String oid, Type type, String operation, + Object[] args) + throws Throwable + { + if (operation.equals("release")) { + return null; + } + int m; + synchronized (lock) { + m = modus; + } + switch (m) { + case 0: + return operation.equals("getInstance") ? "TestResult" : null; + case 1: + // TODO What is this test, with an obviously obsoleted + // MappingException, good for? + throw new MappingException(); + case 2: + throw new com.sun.star.uno.RuntimeException(); + case 3: + throw new com.sun.star.uno.Exception(); + case 4: + throw new NullPointerException(); + default: + throw new Throwable(); + } + } + + public void setModus(int modus) { + synchronized (lock) { + this.modus = modus; + } + } + + private final Object lock = new Object(); + private int modus = 0; + } +} diff --git a/jurt/test/com/sun/star/lib/uno/bridges/java_remote/java_remote_bridge_Test.java b/jurt/test/com/sun/star/lib/uno/bridges/java_remote/java_remote_bridge_Test.java new file mode 100644 index 000000000000..42187fa2277c --- /dev/null +++ b/jurt/test/com/sun/star/lib/uno/bridges/java_remote/java_remote_bridge_Test.java @@ -0,0 +1,251 @@ +/************************************************************************* + * + * 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.lib.uno.bridges.java_remote; + +import com.sun.star.bridge.XBridge; +import com.sun.star.bridge.XInstanceProvider; +import com.sun.star.comp.connections.PipedConnection; +import com.sun.star.connection.XConnection; +import com.sun.star.container.NoSuchElementException; +import com.sun.star.lib.uno.environments.java.java_environment; +import com.sun.star.lib.uno.typeinfo.MethodTypeInfo; +import com.sun.star.lib.uno.typeinfo.TypeInfo; +import com.sun.star.uno.IQueryInterface; +import com.sun.star.uno.Type; +import com.sun.star.uno.UnoRuntime; +import com.sun.star.uno.XInterface; +import complexlib.ComplexTestCase; +import util.WaitUnreachable; + +public final class java_remote_bridge_Test extends ComplexTestCase { + public String getTestObjectName() { + return getClass().getName(); + } + + public String[] getTestMethodNames() { + return new String[] { "test" }; + } + + public void test() throws Exception { + String protocol = "urp"; + + XConnection connectionA = new PipedConnection(new Object[0]); + XConnection connectionB = new PipedConnection( + new Object[] { connectionA }); + java_remote_bridge bridgeA = new java_remote_bridge( + new java_environment(null), null, + new Object[] { protocol, connectionA, new TestInstanceProvider() }); + java_remote_bridge bridgeB = new java_remote_bridge( + new java_environment(null), null, + new Object[] { protocol, connectionB, null }); + + testGetInstance(bridgeA, bridgeB); + testLifeCycle(bridgeA, bridgeB); + } + + private void testGetInstance(XBridge bridgeA, XBridge bridgeB) { + assure("return null", + bridgeB.getInstance(TestInstanceProvider.NAME_NULL) == null); + + try { + bridgeB.getInstance(TestInstanceProvider.NAME_RUNTIME_EXCEPTION); + failed("throw RuntimeException"); + } catch (com.sun.star.uno.RuntimeException e) { + assure("throw RuntimeException", + e.getMessage().indexOf( + TestInstanceProvider.NAME_RUNTIME_EXCEPTION) != -1); + } + + try { + bridgeB.getInstance( + TestInstanceProvider.NAME_NO_SUCH_ELEMENT_EXCEPTION); + failed("throw NoSuchElementException"); + } catch (com.sun.star.uno.RuntimeException e) { + assure("throw NoSuchElementException", + e.getMessage().indexOf( + TestInstanceProvider.NAME_NO_SUCH_ELEMENT_EXCEPTION) + != -1); + } + + try { + bridgeA.getInstance(TestInstanceProvider.NAME_ANYTHING); + failed("no instance provider"); + } catch (com.sun.star.uno.RuntimeException e) { + assure("no instance provider", + e.getMessage().startsWith("unknown OID ")); + } + } + + private void testLifeCycle(java_remote_bridge bridgeA, + java_remote_bridge bridgeB) + throws InterruptedException + { + // Repeatedly, objects are mapped from bridgeA to bridgeB, where proxies + // for those objects (for the XInterface and TestInterface facets) are + // created. The proxies at bridgeB keep both bridges alive; after those + // proxies have been garbage-collected, both bridges should be disposed. + // It does not work to map a local object from bridgeA to bridgeB, as + // bridgeB would find this object as a local one, too (via the shared, + // static localObjects Registry in java_environment): bridgeB would not + // create a proxy, would rather send back a "release" to bridgeA, and + // both bridges would be disposed while the first object is being + // mapped. Therefore, a HACK is used to install TestProxy objects + // (which behave as if they got mapped in to bridgeA from somewhere + // else) at bridgeA and map those. + + final int COUNT = 100; + XInterface[] proxyBXInterface = new XInterface[COUNT]; + TestInterface[] proxyBTestInterface = new TestInterface[COUNT]; + for (int i = 0; i < COUNT; ++i) { + String name = "TestOID" + i; + Object proxyA = new TestProxy(name); + bridgeA.getSourceEnvironment().registerInterface( + proxyA, new String[] { name }, new Type(XInterface.class)); + + proxyBXInterface[i] = (XInterface) bridgeB.getInstance(name); + + // map object: + proxyBTestInterface[i] = UnoRuntime.queryInterface( + TestInterface.class, proxyBXInterface[i]); + proxyBTestInterface[i].function(); + + // remap object once: + TestInterface remapped = UnoRuntime.queryInterface( + TestInterface.class, proxyBXInterface[i]); + remapped.function(); + + // remap object twice: + remapped = UnoRuntime.queryInterface( + TestInterface.class, proxyBXInterface[i]); + remapped.function(); + } + + assure("calls of object method", TestProxy.getCount() == 3 * COUNT); + + // The following checks rely on the implementation detail that mapping + // different facets of a UNO object (XInterface and TestInterface) leads + // to different proxies: + + assure("bridge A life count", bridgeA.getLifeCount() == 2 * COUNT); + assure("bridge B life count", bridgeB.getLifeCount() == 2 * COUNT); + assure("proxy count", ProxyFactory.getDebugCount() == 2 * COUNT); + + System.out.println("waiting for proxies to become unreachable:"); + for (int i = 0; i < COUNT; ++i) { + WaitUnreachable u1 = new WaitUnreachable(proxyBXInterface[i]); + WaitUnreachable u2 = new WaitUnreachable(proxyBTestInterface[i]); + proxyBXInterface[i] = null; + proxyBTestInterface[i] = null; + u1.waitUnreachable(); + u2.waitUnreachable(); + } + // For whatever strange reason, this sleep seems to be necessary to + // reliably ensure that even the last proxy's finalization is over + // before the following assure is executed: + Thread.sleep(1000); + + assure("proxy count", ProxyFactory.getDebugCount() == 0); + + System.out.println("waiting for pending messages to be done"); + while (bridgeA.getLifeCount() != 0 || bridgeB.getLifeCount() != 0) { + Thread.sleep(100); + } + + assure("Zero bridge A life count", bridgeA.getLifeCount() == 0); + assure("Zero bridge B life count", bridgeB.getLifeCount() == 0); + assure("Zero proxy count", ProxyFactory.getDebugCount() == 0); + } + + public interface TestInterface extends XInterface { + void function(); + + TypeInfo[] UNOTYPEINFO = new TypeInfo[] { + new MethodTypeInfo("function", 0, 0) }; + } + + private static final class TestInstanceProvider + implements XInstanceProvider + { + public Object getInstance(String name) throws NoSuchElementException { + if (name.equals(NAME_NULL)) { + return null; + } else if (name.equals(NAME_RUNTIME_EXCEPTION)) { + throw new com.sun.star.uno.RuntimeException( + getClass().getName() + ", throwing: " + name); + } else if (name.equals(NAME_NO_SUCH_ELEMENT_EXCEPTION)) { + throw new NoSuchElementException( + getClass().getName() + ", throwing: " + name); + } else { + throw new IllegalStateException(); + } + } + + public static final String NAME_NULL = "return null"; + public static final String NAME_RUNTIME_EXCEPTION + = "throw RuntimeException"; + public static final String NAME_NO_SUCH_ELEMENT_EXCEPTION + = "throw NoSuchElementException"; + public static final String NAME_ANYTHING = "anything"; + } + + private static final class TestProxy + implements com.sun.star.lib.uno.Proxy, IQueryInterface, XInterface, + TestInterface + { + public TestProxy(String oid) { + this.oid = oid; + } + + public Object queryInterface(Type type) { + // type should be either XInterface or TestInterface... + return this; + } + + public boolean isSame(Object object) { + return object instanceof TestProxy + && oid.equals(((TestProxy) object).oid); + } + + public String getOid() { + return oid; + } + + public void function() { + synchronized (getClass()) { + ++count; + } + } + + public static synchronized int getCount() { + return count; + } + + private final String oid; + + private static int count = 0; + } +} diff --git a/jurt/test/com/sun/star/lib/uno/bridges/java_remote/makefile.mk b/jurt/test/com/sun/star/lib/uno/bridges/java_remote/makefile.mk new file mode 100644 index 000000000000..49ae7f408837 --- /dev/null +++ b/jurt/test/com/sun/star/lib/uno/bridges/java_remote/makefile.mk @@ -0,0 +1,39 @@ +#************************************************************************* +# +# 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 +TARGET := test_com_sun_star_lib_uno_bridges_java_remote + +PACKAGE := com$/sun$/star$/lib$/uno$/bridges$/java_remote +JAVATESTFILES := \ + BridgedObject_Test.java \ + ProxyFactory_Test.java \ + java_remote_bridge_Test.java +JARFILES := ridl.jar + +.INCLUDE: javaunittest.mk diff --git a/jurt/test/com/sun/star/lib/uno/environments/java/java_environment_Test.java b/jurt/test/com/sun/star/lib/uno/environments/java/java_environment_Test.java new file mode 100644 index 000000000000..162c1636c720 --- /dev/null +++ b/jurt/test/com/sun/star/lib/uno/environments/java/java_environment_Test.java @@ -0,0 +1,66 @@ +/************************************************************************* + * + * 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.lib.uno.environments.java; + +import com.sun.star.uno.Type; +import com.sun.star.uno.XInterface; +import complexlib.ComplexTestCase; + +public final class java_environment_Test extends ComplexTestCase { + public String getTestObjectName() { + return getClass().getName(); + } + + public String[] getTestMethodNames() { + return new String[] { "test" }; + } + + public void test() { + java_environment env = new java_environment(null); + + Object obj = new Integer(3); + String[] oid = new String[1]; + + Object obj2 = env.registerInterface(obj, oid, + new Type(XInterface.class)); + Object obj3 = env.registerInterface(obj, oid, + new Type(XInterface.class)); + assure("register ordinary interface twice", + obj2 == obj && obj3 == obj); + + assure("ask for registered interface", + env.getRegisteredInterface(oid[0], new Type(XInterface.class)) + == obj); + + env.revokeInterface(oid[0], new Type(XInterface.class)); + env.revokeInterface(oid[0], new Type(XInterface.class)); + assure("revoke interface", + env.getRegisteredInterface(oid[0], new Type(XInterface.class)) + == null); + } +} diff --git a/jurt/test/com/sun/star/lib/uno/environments/java/makefile.mk b/jurt/test/com/sun/star/lib/uno/environments/java/makefile.mk new file mode 100644 index 000000000000..ad49dccef88b --- /dev/null +++ b/jurt/test/com/sun/star/lib/uno/environments/java/makefile.mk @@ -0,0 +1,36 @@ +#************************************************************************* +# +# 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 +TARGET := test_com_sun_star_lib_uno_environments_java + +PACKAGE := com$/sun$/star$/lib$/uno$/environments$/java +JAVATESTFILES := java_environment_Test.java +JARFILES := ridl.jar + +.INCLUDE: javaunittest.mk diff --git a/jurt/test/com/sun/star/lib/uno/environments/remote/JavaThreadPoolFactory_Test.java b/jurt/test/com/sun/star/lib/uno/environments/remote/JavaThreadPoolFactory_Test.java new file mode 100644 index 000000000000..8dc1a767b5fa --- /dev/null +++ b/jurt/test/com/sun/star/lib/uno/environments/remote/JavaThreadPoolFactory_Test.java @@ -0,0 +1,56 @@ +/************************************************************************* + * + * 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.lib.uno.environments.remote; + +import complexlib.ComplexTestCase; + +public final class JavaThreadPoolFactory_Test extends ComplexTestCase { + public String[] getTestMethodNames() { + return new String[] { "test" }; + } + + public void test() throws InterruptedException { + ThreadId i1 = JavaThreadPoolFactory.getThreadId(); + assure(i1.equals(JavaThreadPoolFactory.getThreadId())); + final ThreadId[] i2 = new ThreadId[1]; + new Thread() { + public void run() { + synchronized (i2) { + i2[0] = JavaThreadPoolFactory.getThreadId(); + i2.notify(); + } + } + }.start(); + synchronized (i2) { + while (i2[0] == null) { + i2.wait(); + } + } + assure(!i1.equals(i2[0])); + } +} diff --git a/jurt/test/com/sun/star/lib/uno/environments/remote/JobQueue_Test.java b/jurt/test/com/sun/star/lib/uno/environments/remote/JobQueue_Test.java new file mode 100644 index 000000000000..5e83098b8ecd --- /dev/null +++ b/jurt/test/com/sun/star/lib/uno/environments/remote/JobQueue_Test.java @@ -0,0 +1,274 @@ +/************************************************************************* + * + * 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.lib.uno.environments.remote; + +import com.sun.star.lib.uno.typedesc.MethodDescription; +import com.sun.star.lib.uno.typedesc.TypeDescription; +import complexlib.ComplexTestCase; + +public final class JobQueue_Test extends ComplexTestCase { + public String getTestObjectName() { + return getClass().getName(); + } + + public String[] getTestMethodNames() { + return new String[] { "testThreadLeavesJobQueueOnDispose0", + "testThreadLeavesJobQueueOnDispose5000", + "testThreadLeavesJobQueueOnReply0", + "testThreadLeavesJobQueueOnReply5000", + "testStaticThreadExecutesJobs0", + "testStaticThreadExecutesJobs5000", + "testDynamicThreadExecutesJob", + "testStaticThreadExecutesAsyncs", + "testDynamicThreadExecutesAsyncs" }; + } + + public void testThreadLeavesJobQueueOnDispose0() throws InterruptedException + { + testThreadLeavesJobQueueOnDispose(0); + } + + public void testThreadLeavesJobQueueOnDispose5000() + throws InterruptedException + { + testThreadLeavesJobQueueOnDispose(5000); + } + + private void testThreadLeavesJobQueueOnDispose(int waitTime) + throws InterruptedException + { + TestThread t = new TestThread(waitTime); + t.waitToStart(); + String msg = "xcxxxxxxxx"; + t._jobQueue.dispose(t._disposeId, new RuntimeException (msg)); + t.waitToTerminate(); + assure("", t._message.equals(msg)); + } + + public void testThreadLeavesJobQueueOnReply0() throws InterruptedException { + testThreadLeavesJobQueueOnReply(0); + } + + public void testThreadLeavesJobQueueOnReply5000() + throws InterruptedException + { + testThreadLeavesJobQueueOnReply(5000); + } + + private void testThreadLeavesJobQueueOnReply(int waitTime) + throws InterruptedException + { + TestThread t = new TestThread(waitTime); + t.waitToStart(); + // put reply job: + t._jobQueue.putJob( + new Job(null, __iReceiver, + new Message( + null, false, "oid", __workAt_td, null, false, null, + false, null, null)), + null); + t.waitToTerminate(); + assure("", true); // TODO! ??? + } + + public void testStaticThreadExecutesJobs0() throws InterruptedException { + testStaticThreadExecutesJobs(0); + } + + public void testStaticThreadExecutesJobs5000() throws InterruptedException { + testStaticThreadExecutesJobs(5000); + } + + private void testStaticThreadExecutesJobs(int waitTime) + throws InterruptedException + { + TestThread t = new TestThread(waitTime); + t.waitToStart(); + testExecuteJobs(t._jobQueue); + t._jobQueue.dispose(t._disposeId, + new RuntimeException("xxxxxxxxxxxxx")); + t.waitToTerminate(); + } + + public void testDynamicThreadExecutesJob() throws InterruptedException { + testExecuteJobs( + new JobQueue( + __javaThreadPoolFactory, ThreadId.createFresh(), true)); + } + + public void testStaticThreadExecutesAsyncs() throws InterruptedException { + TestThread t = new TestThread(); + JobQueue async_jobQueue = new JobQueue(__javaThreadPoolFactory, + t._threadId); + assure("", async_jobQueue._ref_count == 1); + t._jobQueue = __javaThreadPoolFactory.getJobQueue(t._threadId); + assure("", t._jobQueue._ref_count == 1); + t.waitToStart(); + TestWorkAt workAt = new TestWorkAt(); + testAsyncJobQueue(workAt, async_jobQueue, t._threadId); + t._jobQueue.dispose(t._disposeId, + new RuntimeException("xxxxxxxxxxxxx")); + t.waitToTerminate(); + assure("", workAt._async_counter == TestWorkAt.MESSAGES); + assure("", workAt._sync_counter == TestWorkAt.MESSAGES); + } + + public void testDynamicThreadExecutesAsyncs() throws InterruptedException { + ThreadId threadId = ThreadId.createFresh(); + JobQueue async_jobQueue = new JobQueue(__javaThreadPoolFactory, + threadId); + TestWorkAt workAt = new TestWorkAt(); + testAsyncJobQueue(workAt, async_jobQueue, threadId); + assure("", workAt._async_counter == TestWorkAt.MESSAGES); + assure("", workAt._sync_counter == TestWorkAt.MESSAGES); + } + + private void testExecuteJobs(JobQueue jobQueue) throws InterruptedException + { + TestWorkAt workAt = new TestWorkAt(); + testSendRequests(workAt, "increment", jobQueue); + synchronized (workAt) { + jobQueue.putJob(new Job(workAt, __iReceiver, + new Message( + null, true, "oid", __workAt_td, + ((MethodDescription) + __workAt_td.getMethodDescription( + "notifyme")), + true, null, false, null, null)), + null); + while (!workAt._notified) { + workAt.wait(); + } + } + assure("", workAt._counter == TestWorkAt.MESSAGES); + } + + private void testAsyncJobQueue(TestWorkAt workAt, JobQueue async_jobQueue, + ThreadId threadId) + throws InterruptedException + { + // put slow async calls first, followed by fast sync calls: + testSendRequests(workAt, "asyncCall", async_jobQueue); + testSendRequests(workAt, "syncCall", + __javaThreadPoolFactory.getJobQueue(threadId)); + synchronized (workAt) { + async_jobQueue._sync_jobQueue.putJob( + new Job(workAt, __iReceiver, + new Message( + null, true, "oid", __workAt_td, + ((MethodDescription) + __workAt_td.getMethodDescription("notifyme")), + true, null, false, null, null)), + null); + while (!workAt._notified) { + workAt.wait(); + } + } + assure("", workAt.passedAsyncTest()); + } + + private void testSendRequests(TestWorkAt workAt, String operation, + JobQueue jobQueue) { + Message iMessage = new Message( + null, true, "oid", __workAt_td, + (MethodDescription) __workAt_td.getMethodDescription(operation), + true, null, false, null, null); + for (int i = 0; i < TestWorkAt.MESSAGES; ++ i) { + Thread.yield(); // force scheduling + jobQueue.putJob(new Job(workAt, __iReceiver, iMessage), + new Object()); + } + } + + private static final class TestThread extends Thread { + public final ThreadId _threadId = JavaThreadPoolFactory.getThreadId(); + public final Object _disposeId = new Object(); + public JobQueue _jobQueue = null; + public String _message; + + public TestThread(int waitTime) { + this.waitTime = waitTime; + _jobQueue = new JobQueue(__javaThreadPoolFactory, _threadId, false); + } + + public TestThread() { + waitTime = 0; + } + + public void run() { + synchronized (lock) { + state = STATE_STARTED; + lock.notifyAll(); + } + try { + if (waitTime != 0) { + Thread.sleep(waitTime); + } + _jobQueue.enter(_disposeId); + } catch (Throwable e) { + _message = e.getMessage(); + } + synchronized (lock) { + state = STATE_DONE; + lock.notifyAll(); + } + } + + public void waitToStart() throws InterruptedException { + start(); + synchronized (lock) { + while (state == STATE_INITIAL) { + lock.wait(); + } + } + } + + public void waitToTerminate() throws InterruptedException { + synchronized (lock) { + while (state != STATE_DONE) { + lock.wait(); + } + } + join(); + } + + private final int waitTime; + + private final Object lock = new Object(); + private int state = STATE_INITIAL; + private static final int STATE_INITIAL = 0; + private static final int STATE_STARTED = 1; + private static final int STATE_DONE = 2; + } + + private static final JavaThreadPoolFactory __javaThreadPoolFactory + = new JavaThreadPoolFactory(); + private static final IReceiver __iReceiver = new TestReceiver(); + private static final TypeDescription __workAt_td + = TypeDescription.getTypeDescription(TestIWorkAt.class); +} diff --git a/jurt/test/com/sun/star/lib/uno/environments/remote/TestIWorkAt.java b/jurt/test/com/sun/star/lib/uno/environments/remote/TestIWorkAt.java new file mode 100644 index 000000000000..1c616a84541b --- /dev/null +++ b/jurt/test/com/sun/star/lib/uno/environments/remote/TestIWorkAt.java @@ -0,0 +1,49 @@ +/************************************************************************* + * + * 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.lib.uno.environments.remote; + + +import com.sun.star.lib.uno.typeinfo.MethodTypeInfo; +import com.sun.star.lib.uno.typeinfo.TypeInfo; +import com.sun.star.uno.XInterface; + +public interface TestIWorkAt extends XInterface { + void syncCall() throws Throwable ; + void asyncCall() throws Throwable ; + + void increment() throws Throwable; + + void notifyme(); + + public static final TypeInfo UNOTYPEINFO[] = { + new MethodTypeInfo("increment", 0, 0), + new MethodTypeInfo("notifyme", 1, 0), + new MethodTypeInfo("syncCall", 2, 0), + new MethodTypeInfo("asyncCall", 3, 0) + }; +} diff --git a/jurt/test/com/sun/star/lib/uno/environments/remote/TestMessage.java b/jurt/test/com/sun/star/lib/uno/environments/remote/TestMessage.java new file mode 100644 index 000000000000..f47048e423ed --- /dev/null +++ b/jurt/test/com/sun/star/lib/uno/environments/remote/TestMessage.java @@ -0,0 +1,89 @@ +/************************************************************************* + * + * 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.lib.uno.environments.remote; + + +import com.sun.star.uno.Type; + +import com.sun.star.uno.ITypeDescription; + + +class TestMessage implements IMessage { + boolean _synchron; + ITypeDescription _iTypeDescription; + String _oid; + ThreadId _threadId; + Object _result; + String _operation; + Object _params[]; + + TestMessage(boolean synchron, ITypeDescription iTypeDescription, String oid, ThreadId threadId, Object result, String operation, Object params[]) { + _synchron = synchron; + _iTypeDescription = iTypeDescription; + _oid = oid; + _threadId = threadId; + _result = result; + _operation = operation; + _params = params; + } + + public String getOperation() { + return _operation; + } + + public ThreadId getThreadId() { + return _threadId; + } + + public ITypeDescription getInterface() { + return _iTypeDescription; + } + + public boolean isSynchron() { + return _synchron; + } + + public boolean mustReply() { + return _synchron; + } + + public boolean isException() { + return false; + } + + public String getOid() { + return _oid; + } + + public Object getData(Object params[][]) { + params[0] = _params; + return _result; +// return new Integer(_requestId); + } +} + + diff --git a/jurt/test/com/sun/star/lib/uno/environments/remote/TestReceiver.java b/jurt/test/com/sun/star/lib/uno/environments/remote/TestReceiver.java new file mode 100644 index 000000000000..32ba5ba7473b --- /dev/null +++ b/jurt/test/com/sun/star/lib/uno/environments/remote/TestReceiver.java @@ -0,0 +1,33 @@ +/************************************************************************* + * + * 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.lib.uno.environments.remote; + +final class TestReceiver implements IReceiver { + public void sendReply(boolean exception, ThreadId threadId, Object result) { + } +} diff --git a/jurt/test/com/sun/star/lib/uno/environments/remote/TestWorkAt.java b/jurt/test/com/sun/star/lib/uno/environments/remote/TestWorkAt.java new file mode 100644 index 000000000000..322d7573c697 --- /dev/null +++ b/jurt/test/com/sun/star/lib/uno/environments/remote/TestWorkAt.java @@ -0,0 +1,97 @@ +/************************************************************************* + * + * 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.lib.uno.environments.remote; + +class TestWorkAt implements TestIWorkAt { + /** + * When set to true, enables various debugging output. + */ + private static final boolean DEBUG = false; + + static final int MESSAGES = 35; + + + int _counter; + + int _sync_counter; + int _async_counter; + + Thread _sync_thread; + Thread _async_thread; + + boolean _passedAync = true; + boolean _notified = false; + + public void syncCall() throws Throwable { + ++ _sync_counter; + + if(_async_counter != MESSAGES) + _passedAync = false; + + if(_sync_thread == null) + _sync_thread = Thread.currentThread(); + +// if(_sync_thread != Thread.currentThread()) +// _passedAync = false; + + if(DEBUG) System.err.println("syncCall:" + _sync_counter + " " + _passedAync + " " + Thread.currentThread()); + } + + public void asyncCall() throws Throwable { +// Thread.sleep(50); + + ++ _async_counter; + + if(_async_thread == null) + _async_thread = Thread.currentThread(); + +// if(_async_thread != Thread.currentThread()) +// _passedAync = false; + + if(DEBUG) System.err.println("asyncCall:" + _async_counter + " " + Thread.currentThread()); + } + + public synchronized void increment() throws Throwable { + if(DEBUG) System.err.println("increment - " + Thread.currentThread()); + + ++ _counter; + notifyAll(); + } + + public synchronized void notifyme() { + if(DEBUG) System.err.println("\t\t\tnotifying me" + Thread.currentThread()); + + notifyAll(); + + _notified = true; + } + + public boolean passedAsyncTest() { + return _passedAync && (_sync_counter == MESSAGES); + } +} diff --git a/jurt/test/com/sun/star/lib/uno/environments/remote/ThreadId_Test.java b/jurt/test/com/sun/star/lib/uno/environments/remote/ThreadId_Test.java new file mode 100644 index 000000000000..d9154ce6b0ef --- /dev/null +++ b/jurt/test/com/sun/star/lib/uno/environments/remote/ThreadId_Test.java @@ -0,0 +1,63 @@ +/************************************************************************* + * + * 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.lib.uno.environments.remote; + +import complexlib.ComplexTestCase; +import java.util.Arrays; + +public final class ThreadId_Test extends ComplexTestCase { + public String[] getTestMethodNames() { + return new String[] { "test" }; + } + + public void test() { + ThreadId i1 = ThreadId.createFresh(); + assure(i1.equals(i1)); + assure(!i1.equals(null)); + assure(!i1.equals(new Object())); + assure(i1.hashCode() == i1.hashCode()); + byte[] i1bytes = i1.getBytes(); + assure(i1bytes != null); + assure( + i1bytes.length >= 5 && i1bytes[0] == 'j' && i1bytes[1] == 'a' + && i1bytes[2] == 'v' && i1bytes[3] == 'a' && i1bytes[4] == ':'); + assure(Arrays.equals(i1bytes, i1.getBytes())); + + ThreadId i2 = ThreadId.createFresh(); + assure(!i1.equals(i2)); + assure(!i2.equals(i1)); + assure(!Arrays.equals(i1bytes, i2.getBytes())); + + ThreadId i3 = new ThreadId(i1bytes); + assure(i3.equals(i1)); + assure(!i3.equals(i2)); + assure(i1.equals(i3)); + assure(i1.hashCode() == i3.hashCode()); + assure(Arrays.equals(i1bytes, i3.getBytes())); + } +} diff --git a/jurt/test/com/sun/star/lib/uno/environments/remote/ThreadPool_Test.java b/jurt/test/com/sun/star/lib/uno/environments/remote/ThreadPool_Test.java new file mode 100644 index 000000000000..bed90acfbbcb --- /dev/null +++ b/jurt/test/com/sun/star/lib/uno/environments/remote/ThreadPool_Test.java @@ -0,0 +1,443 @@ +/************************************************************************* + * + * 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.lib.uno.environments.remote; + +import com.sun.star.lib.uno.typedesc.MethodDescription; +import com.sun.star.lib.uno.typedesc.TypeDescription; +import complexlib.ComplexTestCase; + +public class ThreadPool_Test extends ComplexTestCase { + public String getTestObjectName() { + return getClass().getName(); + } + + public String[] getTestMethodNames() { + return new String[] { "testDispose", + "testThreadAsync", + "testDynamicThreadSync", + "testStaticThreadSync", + "testDynamicThreadAsyncSyncOrder", + "testStaticThreadAsyncSyncOrder", + "testStress", + "testAsyncSync" }; + } + + public void testDispose() throws InterruptedException { + IThreadPool iThreadPool = ThreadPoolManager.create(); + TestThread testThread = new TestThread(iThreadPool); + + ThreadId threadId = null; + + // start the test thread + synchronized(testThread) { + testThread.start(); + + testThread.wait(); + + threadId = testThread._threadId; + + // let the thread attach and enter the threadpool + testThread.notifyAll(); + } + + String message = "blabla"; + + // terminate the test thread + synchronized(testThread) { + // put reply job + iThreadPool.dispose(new RuntimeException(message)); + + testThread.wait(); + } + + testThread.join(); + + assure("", testThread._message.equals(message)); + } + + public void testThreadAsync() throws InterruptedException { + TestWorkAt workAt = new TestWorkAt(); + + ThreadId threadId = ThreadId.createFresh(); + + // queue asyncs + for(int i = 0; i < TestWorkAt.MESSAGES; ++ i) { + Thread.yield(); // force scheduling + putJob(workAt, false, threadId, "increment"); + } + + synchronized(workAt) { + putJob(workAt, false, threadId, "notifyme"); + + while(!workAt._notified) + workAt.wait(); + } + + assure("", workAt._counter == TestWorkAt.MESSAGES); + } + + public void testDynamicThreadSync() throws InterruptedException { + TestWorkAt workAt = new TestWorkAt(); + + ThreadId threadId = ThreadId.createFresh(); + + // queue asyncs + for(int i = 0; i < TestWorkAt.MESSAGES; ++ i) { + Thread.yield(); // force scheduling + putJob(workAt, true, threadId, "increment"); + } + + synchronized(workAt) { + putJob(workAt, true, threadId, "notifyme"); + + while(!workAt._notified) + workAt.wait(); + } + + assure("", workAt._counter == TestWorkAt.MESSAGES); + } + + public void testStaticThreadSync() throws InterruptedException { + TestWorkAt workAt = new TestWorkAt(); + + TestThread testThread = new TestThread(); + + ThreadId threadId = null; + + // start the test thread + synchronized(testThread) { + testThread.start(); + + testThread.wait(); + + threadId = testThread._threadId; + + // let the thread attach and enter the threadpool + testThread.notifyAll(); + } + + // queue syncs + for(int i = 0; i < TestWorkAt.MESSAGES; ++ i) { + Thread.yield(); // force scheduling + putJob(workAt, true, threadId, "increment"); + } + + // terminate the test thread + synchronized(testThread) { + // put reply job + putJob(workAt, true, threadId, null); + + testThread.wait(); + } + + testThread.join(); + + assure("", workAt._counter == TestWorkAt.MESSAGES); + } + + public void testDynamicThreadAsyncSyncOrder() throws InterruptedException { + TestWorkAt workAt = new TestWorkAt(); + + ThreadId threadId = ThreadId.createFresh(); + + // queue asyncs + for(int i = 0; i < TestWorkAt.MESSAGES; ++ i) { + Thread.yield(); // force scheduling + putJob(workAt, false, threadId, "asyncCall"); + } + + // queue syncs + for(int i = 0; i < TestWorkAt.MESSAGES; ++ i) { + Thread.yield(); // force scheduling + putJob(workAt, true, threadId, "syncCall"); + } + + synchronized(workAt) { + putJob(workAt, true, threadId, "notifyme"); + + while(!workAt._notified) + workAt.wait(); + } + + assure("", workAt.passedAsyncTest()); + } + + public void testStaticThreadAsyncSyncOrder() throws InterruptedException { + TestWorkAt workAt = new TestWorkAt(); + + TestThread testThread = new TestThread(); + + // start the test thread + synchronized(testThread) { + testThread.start(); + + testThread.wait(); + } + + ThreadId threadId = testThread._threadId; + + // queue asyncs + for(int i = 0; i < TestWorkAt.MESSAGES; ++ i) { + Thread.yield(); // force scheduling + putJob(workAt, false, threadId, "asyncCall"); + } + + // let the thread attach and enter the threadpool + synchronized(testThread) { + testThread.notifyAll(); + } + + // queue syncs + for(int i = 0; i < TestWorkAt.MESSAGES; ++ i) { + Thread.yield(); // force scheduling + putJob(workAt, true, threadId, "syncCall"); + } + + // terminate the test thread + synchronized(testThread) { + // put reply job + putJob(workAt, true, threadId, null); + + testThread.wait(); + } + + testThread.join(); + + assure("", workAt.passedAsyncTest()); + } + + public void testStress() throws InterruptedException { + TestWorkAt workAt = new TestWorkAt(); + for (int i = 0; i < TestWorkAt.MESSAGES; ++i) { + Thread.yield(); // force scheduling + ThreadId threadID = ThreadId.createFresh(); + putJob(workAt, true, threadID, "increment"); + putJob(workAt, false, threadID, "increment"); + } + synchronized (workAt) { + while (workAt._counter < 2 * TestWorkAt.MESSAGES) { + workAt.wait(); + } + } + + abstract class Stress extends Thread { + public Stress(int count) { + this.count = count; + } + + public void run() { + try { + for (int i = 0; i < count; ++i) { + runTest(); + } + } catch (Throwable e) { + e.printStackTrace(System.err); + } + } + + protected abstract void runTest() throws InterruptedException; + + private final int count; + }; + + Stress stress1 = new Stress(50) { + protected void runTest() throws InterruptedException { + testThreadAsync(); + } + }; + stress1.start(); + + Stress stress2 = new Stress(50) { + protected void runTest() throws InterruptedException { + testDynamicThreadSync(); + } + }; + stress2.start(); + + Stress stress3 = new Stress(50) { + protected void runTest() throws InterruptedException { + testStaticThreadSync(); + } + }; + stress3.start(); + + Stress stress4 = new Stress(50) { + protected void runTest() throws InterruptedException { + testDynamicThreadAsyncSyncOrder(); + } + }; + stress4.start(); + + Stress stress5 = new Stress(50) { + protected void runTest() throws InterruptedException { + testStaticThreadAsyncSyncOrder(); + } + }; + stress5.start(); + + Stress stress6 = new Stress(500) { + protected void runTest() throws InterruptedException { + testDispose(); + } + }; + stress6.start(); + + stress1.join(); + stress2.join(); + stress3.join(); + stress4.join(); + stress5.join(); + stress6.join(); + } + + public void testAsyncSync() throws InterruptedException { + TestWorkAt workAt = new TestWorkAt(); + ThreadId threadId = ThreadId.createFresh(); + MyWorkAt myWorkAt = new MyWorkAt( workAt ); + + // queue asyncs + for(int i = 0; i < TestWorkAt.MESSAGES; ++ i) { + if( i == 2 ) + { + putJob( myWorkAt, false , threadId, "asyncCall" ); + } + putJob(workAt, false, threadId, "asyncCall"); + } + + synchronized(workAt) { + putJob(workAt, false, threadId, "notifyme"); + + while(!workAt._notified) + workAt.wait(); + } + + assure("", + workAt._async_counter == TestWorkAt.MESSAGES + && myWorkAt._success); + } + + private static void putJob(TestIWorkAt iWorkAt, boolean synchron, + ThreadId threadId, String operation) { + __iThreadPool.putJob( + new Job(iWorkAt, __iReceiver, + new Message( + threadId, operation != null, "oid", __workAt_td, + (operation == null + ? null + : ((MethodDescription) + __workAt_td.getMethodDescription(operation))), + synchron, null, false, null, null))); + } + + private static final class TestThread extends Thread { + ThreadId _threadId; + Object _disposeId = new Object(); + String _message; + IThreadPool _iThreadPool; + + TestThread() { + this(__iThreadPool); + } + + TestThread(IThreadPool iThreadPool) { + _iThreadPool = iThreadPool; + } + + public void run() { + _threadId = _iThreadPool.getThreadId(); + + + try { + synchronized(this) { + // notify that we are running + notify(); + + _iThreadPool.attach(); + + // wait until we should continue + wait(); + } + + _iThreadPool.enter(); + } + catch(Throwable throwable) { + _message = throwable.getMessage(); + } + + _iThreadPool.detach(); + + synchronized(this) { + // notify the listeners that we are dying + notifyAll(); + } + } + } + + private static final class MyWorkAt implements TestIWorkAt { + public MyWorkAt( TestWorkAt async_WorkAt ) { + _async_WorkAt = async_WorkAt; + } + + public void syncCall() throws Throwable + { + Message iMessage = new Message( + __iThreadPool.getThreadId(), false, "oid", __workAt_td, null, + false, null, false, null, null); + + // marshal reply + ThreadPool_Test.__iThreadPool.putJob( + new Job(this, ThreadPool_Test. __iReceiver, iMessage)); + } + + public void asyncCall() throws Throwable { + for (int i = 0 ; i < 5 ; ++i) { + ThreadPool_Test.__iThreadPool.attach(); + ThreadPool_Test.putJob(this, true, __iThreadPool.getThreadId(), + "syncCall"); + // wait for reply + ThreadPool_Test.__iThreadPool.enter(); + ThreadPool_Test.__iThreadPool.detach(); + } + // async must have waited for this call + _success = _async_WorkAt._async_counter == 2; + } + + public void increment() throws Throwable {} + + public void notifyme() {} + + public boolean _success = false; + + private final TestWorkAt _async_WorkAt; + } + + private static final IThreadPool __iThreadPool = ThreadPoolManager.create(); + private static final IReceiver __iReceiver = new TestReceiver(); + private static final TypeDescription __workAt_td + = TypeDescription.getTypeDescription(TestIWorkAt.class); +} diff --git a/jurt/test/com/sun/star/lib/uno/environments/remote/makefile.mk b/jurt/test/com/sun/star/lib/uno/environments/remote/makefile.mk new file mode 100644 index 000000000000..e2323a54b497 --- /dev/null +++ b/jurt/test/com/sun/star/lib/uno/environments/remote/makefile.mk @@ -0,0 +1,44 @@ +#************************************************************************* +# +# 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 +TARGET := test_com_sun_star_lib_uno_environments_remote + +PACKAGE := com$/sun$/star$/lib$/uno$/environments$/remote +JAVATESTFILES := \ + JavaThreadPoolFactory_Test.java \ + JobQueue_Test.java \ + ThreadId_Test.java \ + ThreadPool_Test.java +JAVAFILES := \ + TestIWorkAt.java \ + TestReceiver.java \ + TestWorkAt.java +JARFILES := ridl.jar + +.INCLUDE: javaunittest.mk diff --git a/jurt/test/com/sun/star/lib/uno/protocols/urp/Cache_Test.java b/jurt/test/com/sun/star/lib/uno/protocols/urp/Cache_Test.java new file mode 100644 index 000000000000..31d3454bde48 --- /dev/null +++ b/jurt/test/com/sun/star/lib/uno/protocols/urp/Cache_Test.java @@ -0,0 +1,106 @@ +/************************************************************************* + * + * 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.lib.uno.protocols.urp; + +import complexlib.ComplexTestCase; + +public final class Cache_Test extends ComplexTestCase { + public String[] getTestMethodNames() { + return new String[] { "test0", "test1", "test2", "test3" }; + } + + public void test0() { + Cache c = new Cache(0); + boolean[] f = new boolean[1]; + int i; + i = c.add(f, "a"); + assure("1", i == Cache.NOT_CACHED && !f[0]); + i = c.add(f, "a"); + assure("2", i == Cache.NOT_CACHED && !f[0]); + i = c.add(f, "b"); + assure("3", i == Cache.NOT_CACHED && !f[0]); + i = c.add(f, "a"); + assure("4", i == Cache.NOT_CACHED && !f[0]); + } + + public void test1() { + Cache c = new Cache(1); + boolean[] f = new boolean[1]; + int i; + i = c.add(f, "a"); + assure("1", i == 0 && !f[0]); + i = c.add(f, "a"); + assure("2", i == 0 && f[0]); + i = c.add(f, "b"); + assure("3", i == 0 && !f[0]); + i = c.add(f, "b"); + assure("4", i == 0 && f[0]); + i = c.add(f, "a"); + assure("5", i == 0 && !f[0]); + } + + public void test2() { + Cache c = new Cache(2); + boolean[] f = new boolean[1]; + int i; + i = c.add(f, "a"); + assure("1", i == 0 && !f[0]); + i = c.add(f, "a"); + assure("2", i == 0 && f[0]); + i = c.add(f, "b"); + assure("3", i == 1 && !f[0]); + i = c.add(f, "b"); + assure("4", i == 1 && f[0]); + i = c.add(f, "a"); + assure("5", i == 0 && f[0]); + i = c.add(f, "c"); + assure("6", i == 1 && !f[0]); + i = c.add(f, "b"); + assure("7", i == 0 && !f[0]); + } + + public void test3() { + Cache c = new Cache(3); + boolean[] f = new boolean[1]; + int i; + i = c.add(f, "a"); + assure("1", i == 0 && !f[0]); + i = c.add(f, "a"); + assure("3", i == 0 && f[0]); + i = c.add(f, "b"); + assure("5", i == 1 && !f[0]); + i = c.add(f, "a"); + assure("3", i == 0 && f[0]); + i = c.add(f, "c"); + assure("7", i == 2 && !f[0]); + i = c.add(f, "d"); + assure("9", i == 1 && !f[0]); + i = c.add(f, "d"); + assure("11", i == 1 && f[0]); + } +} diff --git a/jurt/test/com/sun/star/lib/uno/protocols/urp/Marshaling_Test.java b/jurt/test/com/sun/star/lib/uno/protocols/urp/Marshaling_Test.java new file mode 100644 index 000000000000..4c01e9acc9c6 --- /dev/null +++ b/jurt/test/com/sun/star/lib/uno/protocols/urp/Marshaling_Test.java @@ -0,0 +1,369 @@ +/************************************************************************* + * + * 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.lib.uno.protocols.urp; + +import com.sun.star.lib.uno.typedesc.TypeDescription; +import com.sun.star.uno.Any; +import com.sun.star.uno.IBridge; +import com.sun.star.uno.Type; +import com.sun.star.uno.TypeClass; +import com.sun.star.uno.XInterface; +import complexlib.ComplexTestCase; +import java.lang.reflect.Array; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; + +public final class Marshaling_Test extends ComplexTestCase { + public String getTestObjectName() { + return getClass().getName(); + } + + public String[] getTestMethodNames() { + return new String[] { "test" }; + } + + public void test() throws Exception { + short cacheSize = (short)256; + TestBridge testBridge = new TestBridge(); + Marshal marshal = new Marshal(testBridge, cacheSize); + + TestObject testObject = new TestObject(); + + TestPrimitiveSeqStruct x = new TestPrimitiveSeqStruct(); + x.zAny = new Object[]{new Integer(1), new Double(2) }; + + + Object data[] = new Object[] { + new com.sun.star.uno.RuntimeException("testRuntimeException"), + new com.sun.star.uno.Exception("testException"), + new Boolean(true), + new Byte((byte)47), + new Character('k'), + new Double(0.12345), + TestEnum.B, + new Float(0.5678), + new Integer(0), + new Integer(128), + new Integer(0x0f00), + new Integer(0x0f0000), + new Integer(0x0f000000), + new Integer(-128), + new Integer(0xff00), + new Integer(0xff0000), + new Integer(0xff000000), + new Long(666L), + new Short((short)444), + new String("blabla"), + new Integer(10), // Any as object + new Integer(10), // Any as object + new Any(new Type(Integer.class), new Integer(10)), // Any as Any + new Any(new Type(Integer.class), new Integer(10)), // Any as Any + null, + new TestPrimitiveStruct(), + x, //new TestPrimitiveSeqStruct(), + new byte[]{1,2,3,4,5,6,7}, // primitive sequence + new int[]{7,6,5,4,3,2,1}, // primitive sequence + new Object[]{new Integer(123), new String("hallo")}, // any sequence + new TestPrimitiveStruct[]{new TestPrimitiveStruct(), new TestPrimitiveStruct()}, // sequence of primitive structs + new TestPrimitiveSeqStruct[]{new TestPrimitiveSeqStruct(), new TestPrimitiveSeqStruct()}, // sequence of primitive structs + new TestNestedStruct(), + new TestNestedSeqStruct(), + new Type(Void.class), + new Type(String.class), + new Type(Object.class), + new Type(Byte.class), + new Type(Integer.class), + new Type(Double.class), + new Type(Float.class), + new Type(Character.class), + new Type(Short.class), + new Type(Boolean.class), + new Type(void.class), + new Type(byte.class), + new Type(int.class), + new Type(double.class), + new Type(float.class), + new Type(char.class), + new Type(short.class), + new Type(boolean.class), + new Type(Class.forName("[Ljava.lang.String;")), + new Type(Class.forName("[Ljava.lang.Object;")), + new Type(Class.forName("[B")), + new Type(Class.forName("[Z")), + new Type("boolean"), + new Type("byte"), + new Type("char"), + new Type("short"), + new Type("long"), + new Type("hyper"), + new Type("float"), + new Type("double"), + new Type("string"), + new Type("void"), + new Type("any"), + new Type( + "com.sun.star.lib.uno.protocols.urp.TestEnum", TypeClass.ENUM), + new Type("[]boolean", TypeClass.SEQUENCE), + new Type("[][]byte", TypeClass.SEQUENCE), + new Type("[][][]char", TypeClass.SEQUENCE), + new Type("[][][][]short", TypeClass.SEQUENCE), + new Type("[][][][][]any", TypeClass.SEQUENCE), + new Type("com.sun.star.uno.XInterface", TypeClass.INTERFACE), + new Type("[]com.sun.star.uno.XInterface", TypeClass.SEQUENCE), + testObject, + testObject, + new TestInterfaceStruct(testObject, null) + }; + + TypeDescription dataTypes[] = new TypeDescription[] { + TypeDescription.getTypeDescription(com.sun.star.uno.RuntimeException.class), + TypeDescription.getTypeDescription(com.sun.star.uno.Exception.class), + TypeDescription.getTypeDescription(Boolean.class), + TypeDescription.getTypeDescription(Byte.class), + TypeDescription.getTypeDescription(Character.class), + TypeDescription.getTypeDescription(Double.class), + TypeDescription.getTypeDescription(TestEnum.class), + TypeDescription.getTypeDescription(Float.class), + TypeDescription.getTypeDescription(Integer.class), + TypeDescription.getTypeDescription(Integer.class), + TypeDescription.getTypeDescription(Integer.class), + TypeDescription.getTypeDescription(Integer.class), + TypeDescription.getTypeDescription(Integer.class), + TypeDescription.getTypeDescription(Integer.class), + TypeDescription.getTypeDescription(Integer.class), + TypeDescription.getTypeDescription(Integer.class), + TypeDescription.getTypeDescription(Integer.class), + TypeDescription.getTypeDescription(Long.class), + TypeDescription.getTypeDescription(Short.class), + TypeDescription.getTypeDescription(String.class), + TypeDescription.getTypeDescription(Object.class), + TypeDescription.getTypeDescription(Any.class), + TypeDescription.getTypeDescription(Any.class), + TypeDescription.getTypeDescription(Object.class), + TypeDescription.getTypeDescription(XInterface.class), + TypeDescription.getTypeDescription(TestPrimitiveStruct.class), + TypeDescription.getTypeDescription(TestPrimitiveSeqStruct.class), + TypeDescription.getTypeDescription(Class.forName("[B")), + TypeDescription.getTypeDescription(Class.forName("[I")), + TypeDescription.getTypeDescription(Class.forName("[Lcom.sun.star.uno.Any;")), + TypeDescription.getTypeDescription( + Class.forName( + "[Lcom.sun.star.lib.uno.protocols.urp." + + "TestPrimitiveStruct;")), + TypeDescription.getTypeDescription( + Class.forName( + "[Lcom.sun.star.lib.uno.protocols.urp." + + "TestPrimitiveSeqStruct;")), + TypeDescription.getTypeDescription(TestNestedStruct.class), + TypeDescription.getTypeDescription(TestNestedSeqStruct.class), + TypeDescription.getTypeDescription(Type.class), + TypeDescription.getTypeDescription(Type.class), + TypeDescription.getTypeDescription(Type.class), + TypeDescription.getTypeDescription(Type.class), + TypeDescription.getTypeDescription(Type.class), + TypeDescription.getTypeDescription(Type.class), + TypeDescription.getTypeDescription(Type.class), + TypeDescription.getTypeDescription(Type.class), + TypeDescription.getTypeDescription(Type.class), + TypeDescription.getTypeDescription(Type.class), + TypeDescription.getTypeDescription(Type.class), + TypeDescription.getTypeDescription(Type.class), + TypeDescription.getTypeDescription(Type.class), + TypeDescription.getTypeDescription(Type.class), + TypeDescription.getTypeDescription(Type.class), + TypeDescription.getTypeDescription(Type.class), + TypeDescription.getTypeDescription(Type.class), + TypeDescription.getTypeDescription(Type.class), + TypeDescription.getTypeDescription(Type.class), + TypeDescription.getTypeDescription(Type.class), + TypeDescription.getTypeDescription(Type.class), + TypeDescription.getTypeDescription(Type.class), + TypeDescription.getTypeDescription(Type.class), + TypeDescription.getTypeDescription(Type.class), + TypeDescription.getTypeDescription(Type.class), + TypeDescription.getTypeDescription(Type.class), + TypeDescription.getTypeDescription(Type.class), + TypeDescription.getTypeDescription(Type.class), + TypeDescription.getTypeDescription(Type.class), + TypeDescription.getTypeDescription(Type.class), + TypeDescription.getTypeDescription(Type.class), + TypeDescription.getTypeDescription(Type.class), + TypeDescription.getTypeDescription(Type.class), + TypeDescription.getTypeDescription(Type.class), + TypeDescription.getTypeDescription(Type.class), + TypeDescription.getTypeDescription(Type.class), + TypeDescription.getTypeDescription(Type.class), + TypeDescription.getTypeDescription(Type.class), + TypeDescription.getTypeDescription(Type.class), + TypeDescription.getTypeDescription(Type.class), + TypeDescription.getTypeDescription(Type.class), + TypeDescription.getTypeDescription(XInterface.class), + TypeDescription.getTypeDescription(XInterface.class), + TypeDescription.getTypeDescription(TestInterfaceStruct.class), + }; + + + Unmarshal unmarshal = new Unmarshal(testBridge, cacheSize); + for(int i = 0; i < dataTypes.length; ++ i) { + Object op1 = data[i]; + marshal.writeValue(dataTypes[i], data[i]); + + unmarshal.reset(marshal.reset()); + + Object op2 = unmarshal.readValue(dataTypes[i]); + + if(op1 instanceof Any) + op1 = ((Any)op1).getObject(); + + assure("", compareObjects(op1, op2)); + } + } + + private static boolean compareArrays(Object op1, Object op2) throws Exception { + boolean result = true; + if((op1.getClass().getComponentType() == op2.getClass().getComponentType()) + && (Array.getLength(op1) == Array.getLength(op2))) + { + Class zClass = op1.getClass().getComponentType(); + + for(int i = 0; i < Array.getLength(op1); ++ i) + result = result & compareObjects(Array.get(op1, i), Array.get(op2, i)); + } + + return result; + } + + private static boolean compareInterfaces(XInterface op1, XInterface op2) { + return op1 == op2; + } + + private static boolean compareStructs(Class zClass, Object op1, Object op2) throws Exception { + boolean result = true; + + Field fields[] = zClass.getFields(); + + for(int i = 0; i < fields.length && result; ++ i) { + if((fields[i].getModifiers() & (Modifier.STATIC | Modifier.TRANSIENT)) == 0) { // neither static nor transient ? + result = result & compareObjects(fields[i].get(op1), fields[i].get(op2)); + + if(!result) + System.err.println("blabal :" + fields[i]); + } + } + + return result; + } + + private static boolean compareStructs(Object op1, Object op2) throws Exception { + boolean result = true; + + if(op1.getClass() != op2.getClass()) + result = false; + else { + result = compareStructs(op1.getClass(), op1, op2); + } + + return result; + } + + private static boolean compareThrowable(Throwable op1, Throwable op2) throws Exception { + boolean result = true; + + if(op1.getClass() != op2.getClass()) + result = false; + else { + result = compareStructs(op1.getClass(), op1, op2); + + result = result & op1.getMessage().equals(op2.getMessage()); + } + + return result; + } + + private static boolean compareObjects(Object op1, Object op2) throws Exception { + boolean result = false; + + if(op1 == op2) + result = true; + + else if(op1.getClass().isPrimitive() && op2.getClass().isPrimitive()) + result = op1.equals(op2); + + else if(op1.getClass() == Byte.class && op2.getClass() == Byte.class) + result = op1.equals(op2); + + else if(op1.getClass() == Type.class && op2.getClass() == Type.class) + result = op1.equals(op2); + + else if(op1.getClass() == Boolean.class && op2.getClass() == Boolean.class) + result = op1.equals(op2); + + else if(op1.getClass() == Short.class && op2.getClass() == Short.class) + result = op1.equals(op2); + + else if(Throwable.class.isAssignableFrom(op1.getClass()) && Throwable.class.isAssignableFrom(op2.getClass())) + result = compareThrowable((Throwable)op1, (Throwable)op2); + + else if(op1.getClass() == Integer.class && op2.getClass() == Integer.class) + result = op1.equals(op2); + + else if(op1.getClass() == Character.class && op2.getClass() == Character.class) + result = op1.equals(op2); + + else if(op1.getClass() == Long.class && op2.getClass() == Long.class) + result = op1.equals(op2); + + else if(op1.getClass() == Void.class && op2.getClass() == Void.class) + result = op1.equals(op2); + + else if(op1.getClass() == Float.class && op2.getClass() == Float.class) + result = op1.equals(op2); + + else if(op1.getClass() == Double.class && op2.getClass() == Double.class) + result = op1.equals(op2); + + else if(op1.getClass().isArray() && op2.getClass().isArray()) + result = compareArrays(op1, op2); + + else if(op1.getClass() == Void.class || op2.getClass() == void.class) // write nothing ? + result = true; + + else if(XInterface.class.isAssignableFrom(op1.getClass()) && XInterface.class.isAssignableFrom(op2.getClass())) + result = compareInterfaces((XInterface)op1, (XInterface)op2); + + else if(op1.getClass() == String.class && op2.getClass() == String.class) // is it a String ? + result = ((String)op1).equals((String)op2); + + else if(op1.getClass() == Type.class && op2.getClass() == Type.class) // types? + result = op1.equals(op2); + + else // otherwise it must be a struct + result = compareStructs(op1, op2); + + return result; + } +} diff --git a/jurt/test/com/sun/star/lib/uno/protocols/urp/Protocol_Test.java b/jurt/test/com/sun/star/lib/uno/protocols/urp/Protocol_Test.java new file mode 100644 index 000000000000..393720c9756d --- /dev/null +++ b/jurt/test/com/sun/star/lib/uno/protocols/urp/Protocol_Test.java @@ -0,0 +1,317 @@ +/************************************************************************* + * + * 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.lib.uno.protocols.urp; + +import com.sun.star.lib.uno.environments.remote.Message; +import com.sun.star.lib.uno.environments.remote.IProtocol; +import com.sun.star.lib.uno.environments.remote.ThreadId; +import com.sun.star.lib.uno.typedesc.TypeDescription; +import com.sun.star.uno.Any; +import com.sun.star.uno.IBridge; +import com.sun.star.uno.Type; +import com.sun.star.uno.XInterface; +import complexlib.ComplexTestCase; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; +import java.util.LinkedList; + +public final class Protocol_Test extends ComplexTestCase { + public String[] getTestMethodNames() { + return new String[] { "test" }; + } + + public void test() throws Exception { + IBridge iBridge = new TestBridge(); + PipedInputStream inA = new PipedInputStream(); + PipedOutputStream outA = new PipedOutputStream(inA); + PipedInputStream inB = new PipedInputStream(); + PipedOutputStream outB = new PipedOutputStream(inB); + Endpoint iSender = new Endpoint(iBridge, inA, outB); + Endpoint iReceiver = new Endpoint(iBridge, inB, outA); + + TestObject testObject = new TestObject(); + String oId = (String)iBridge.mapInterfaceTo(testObject, new Type(XInterface.class)); + + testCall(iSender, iReceiver, oId); + testCallWithInParameter(iSender, iReceiver, oId); + testCallWithOutParameter(iSender, iReceiver, oId); + testCallWithInOutParameter(iSender, iReceiver, oId); + testCallWithResult(iSender, iReceiver, oId); + testCallWhichRaisesException(iSender, iReceiver, oId); + testCallWithIn_Out_InOut_Paramters_and_result(iSender, iReceiver, oId); + testCallWhichReturnsAny(iSender, iReceiver, oId); + } + + public void testCall( + Endpoint iSender, Endpoint iReceiver, String oId) throws Exception + { + // send an ordinary request + iSender.writeRequest( + oId, TypeDescription.getTypeDescription(TestXInterface.class), + "method", new ThreadId(new byte[] { 0, 1 }), new Object[0]); + iReceiver.readMessage(); + + // send a reply + iReceiver.writeReply(false, new ThreadId(new byte[] { 0, 1 }), null); + iSender.readMessage(); + } + + public void testCallWithInParameter( + Endpoint iSender, Endpoint iReceiver, String oId) throws Exception + { + // send an ordinary request + iSender.writeRequest( + oId, TypeDescription.getTypeDescription(TestXInterface.class), + "methodWithInParameter", new ThreadId(new byte[] { 0, 1 }), + new Object[] { "hallo" }); + Message iMessage = iReceiver.readMessage(); + Object[] t_params = iMessage.getArguments(); + assure("", "hallo".equals((String)t_params[0])); + + // send a reply + iReceiver.writeReply(false, new ThreadId(new byte[] { 0, 1 }), null); + iMessage = iSender.readMessage(); + } + + public void testCallWithOutParameter( + Endpoint iSender, Endpoint iReceiver, String oId) throws Exception + { + Object params[] = new Object[]{new String[1]}; + iSender.writeRequest( + oId, TypeDescription.getTypeDescription(TestXInterface.class), + "methodWithOutParameter", new ThreadId(new byte[] { 0, 1 }), + params); + Message iMessage = iReceiver.readMessage(); + + + Object[] t_params = iMessage.getArguments(); + ((String [])t_params[0])[0] = "testString"; + + // send an exception as reply + iReceiver.writeReply(false, new ThreadId(new byte[] { 0, 1 }), null); + iSender.readMessage(); + + assure("", "testString".equals(((String [])params[0])[0])); + } + + public void testCallWithInOutParameter( + Endpoint iSender, Endpoint iReceiver, String oId) throws Exception + { + Object params[] = new Object[]{new String[]{"inString"}}; + iSender.writeRequest( + oId, TypeDescription.getTypeDescription(TestXInterface.class), + "methodWithInOutParameter", new ThreadId(new byte[] { 0, 1 }), + params); + Message iMessage = iReceiver.readMessage(); + + + Object[] t_params = iMessage.getArguments(); + assure("", "inString".equals(((String [])t_params[0])[0])); + + // provide reply + ((String [])t_params[0])[0] = "outString"; + + // send an exception as reply + iReceiver.writeReply(false, new ThreadId(new byte[] { 0, 1 }), null); + iSender.readMessage(); + + assure("", "outString".equals(((String [])params[0])[0])); + } + + public void testCallWithResult( + Endpoint iSender, Endpoint iReceiver, String oId) throws Exception + { + // send an ordinary request + iSender.writeRequest( + oId, TypeDescription.getTypeDescription(TestXInterface.class), + "methodWithResult", new ThreadId(new byte[] { 0, 1 }), + new Object[0]); + iReceiver.readMessage(); + + // send a reply + iReceiver.writeReply( + false, new ThreadId(new byte[] { 0, 1 }), "resultString"); + Message iMessage = iSender.readMessage(); + Object result = iMessage.getResult(); + + assure("", "resultString".equals(result)); + } + + public void testCallWhichRaisesException( + Endpoint iSender, Endpoint iReceiver, String oId) throws Exception + { + // send a second request + iSender.writeRequest( + oId, TypeDescription.getTypeDescription(TestXInterface.class), + "method", new ThreadId(new byte[] { 0, 1 }), new Object[0]); + iReceiver.readMessage(); + + // send an exception as reply + iReceiver.writeReply( + true, new ThreadId(new byte[] { 0, 1 }), + new com.sun.star.uno.RuntimeException("test the exception")); + Message iMessage = iSender.readMessage(); + + Object result = iMessage.getResult(); + + assure("", result instanceof com.sun.star.uno.RuntimeException); + } + + public void testCallWithIn_Out_InOut_Paramters_and_result( + Endpoint iSender, Endpoint iReceiver, String oId) throws Exception + { + Object params[] = new Object[]{"hallo", new String[1], new String[]{"inOutString"}}; + iSender.writeRequest( + oId, TypeDescription.getTypeDescription(TestXInterface.class), + "MethodWithIn_Out_InOut_Paramters_and_result", + new ThreadId(new byte[] { 0, 1 }), params); + Message iMessage = iReceiver.readMessage(); + + Object[] t_params = iMessage.getArguments(); + + assure("", "hallo".equals((String)t_params[0])); + + assure("", "inOutString".equals(((String [])t_params[2])[0])); + + ((String [])t_params[1])[0] = "outString"; + ((String [])t_params[2])[0] = "inOutString_res"; + + // send an exception as reply + iReceiver.writeReply( + false, new ThreadId(new byte[] { 0, 1 }), "resultString"); + iMessage = iSender.readMessage(); + + Object result = iMessage.getResult(); + assure("", "outString".equals(((String [])params[1])[0])); + + assure("", "inOutString_res".equals(((String [])params[2])[0])); + + assure("", "resultString".equals(result)); + } + + public void testCallWhichReturnsAny( + Endpoint iSender, Endpoint iReceiver, String oId) throws Exception + { + // send an ordinary request + iSender.writeRequest( + oId, TypeDescription.getTypeDescription(TestXInterface.class), + "returnAny", new ThreadId(new byte[] { 0, 1 }), null); + iReceiver.readMessage(); + // send a reply + iReceiver.writeReply( + false, new ThreadId(new byte[] { 0, 1 }), Any.VOID); + Message iMessage = iSender.readMessage(); + Object result = iMessage.getResult(); + assure("", result instanceof Any + && (TypeDescription.getTypeDescription(((Any) result).getType()). + getZClass() == void.class)); + + // send an ordinary request + iSender.writeRequest( + oId, TypeDescription.getTypeDescription(TestXInterface.class), + "returnAny", new ThreadId(new byte[] { 0, 1 }), null); + iReceiver.readMessage(); + // send a reply + iReceiver.writeReply( + false, new ThreadId(new byte[] { 0, 1 }), + new Any(XInterface.class, null)); + iMessage = iSender.readMessage(); + result = iMessage.getResult(); + assure("", result == null); + + // send an ordinary request + iSender.writeRequest( + oId, TypeDescription.getTypeDescription(TestXInterface.class), + "returnAny", new ThreadId(new byte[] { 0, 1 }), null); + iReceiver.readMessage(); + // send a reply + iReceiver.writeReply( + false, new ThreadId(new byte[] { 0, 1 }), new Integer(501)); + iMessage = iSender.readMessage(); + result = iMessage.getResult(); + assure("", result.equals(new Integer(501))); + } + + private static final class Endpoint { + public Endpoint(IBridge bridge, InputStream input, OutputStream output) + throws IOException + { + protocol = new urp(bridge, null, input, output); + new Thread() { + public void run() { + for (;;) { + Object o; + try { + o = protocol.readMessage(); + } catch (IOException e) { + o = e; + } + synchronized (queue) { + queue.addLast(o); + } + } + } + }.start(); + protocol.init(); + } + + public Message readMessage() throws IOException { + for (;;) { + synchronized (queue) { + if (!queue.isEmpty()) { + Object o = queue.removeFirst(); + if (o instanceof Message) { + return (Message) o; + } else { + throw (IOException) o; + } + } + } + } + } + + public boolean writeRequest( + String oid, TypeDescription type, String function, ThreadId tid, + Object[] arguments) + throws IOException + { + return protocol.writeRequest(oid, type, function, tid, arguments); + } + + public void writeReply(boolean exception, ThreadId tid, Object result) + throws IOException + { + protocol.writeReply(exception, tid, result); + } + + private final IProtocol protocol; + private final LinkedList queue = new LinkedList(); + } +} diff --git a/jurt/test/com/sun/star/lib/uno/protocols/urp/TestBridge.java b/jurt/test/com/sun/star/lib/uno/protocols/urp/TestBridge.java new file mode 100644 index 000000000000..34f864ae3085 --- /dev/null +++ b/jurt/test/com/sun/star/lib/uno/protocols/urp/TestBridge.java @@ -0,0 +1,115 @@ +/************************************************************************* + * + * 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.lib.uno.protocols.urp; + +import java.io.IOException; + +import java.util.Hashtable; + + +import com.sun.star.uno.IBridge; +import com.sun.star.uno.IEnvironment; +import com.sun.star.uno.Type; + + +class TestBridge implements IBridge { + static public final boolean DEBUG = false; + + Hashtable _hashtable = new Hashtable(); + + IEnvironment _source ;//= new com.sun.star.lib.uno.environments.java.java_environment(null); + + + class MyEnv implements IEnvironment { + public Object getContext() { + return null; + } + + public String getName() { + return null; + } + + public Object registerInterface(Object object, String oId[], Type type) { + return null; + } + + public void revokeInterface(String oId, Type type) { + } + + public Object getRegisteredInterface(String oid, Type type) { + Object object = _hashtable.get(oid); + + if(DEBUG) System.err.println("##### " + getClass().getName() + ".getRegisteredInterface:" + oid + " " + object); + + return object; + } + + public String getRegisteredObjectIdentifier(Object object) { + return null; + } + + public void list() { + } + } + + TestBridge() { + _source = new MyEnv(); + } + + public Object mapInterfaceTo(Object object, Type type) { + if (object == null) { + return null; + } else { + String oid = ">" + object.toString() + type.toString() + "<"; + _hashtable.put(oid, object); + return oid; + } + } + + public Object mapInterfaceFrom(Object object, Type type) { + String oid = (String)object; + + return _hashtable.get(oid); + } + + public IEnvironment getSourceEnvironment() { + return _source; + } + + public IEnvironment getTargetEnvironment() { + return null; + } + + public void acquire() {} + + public void release() {} + + public void reset() throws IOException {} + + public void dispose() throws InterruptedException, IOException {} +} + diff --git a/jurt/test/com/sun/star/lib/uno/protocols/urp/TestObject.java b/jurt/test/com/sun/star/lib/uno/protocols/urp/TestObject.java new file mode 100644 index 000000000000..f6be37207765 --- /dev/null +++ b/jurt/test/com/sun/star/lib/uno/protocols/urp/TestObject.java @@ -0,0 +1,70 @@ +/************************************************************************* + * + * 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.lib.uno.protocols.urp; + + + +class TestObject implements TestXInterface { + public void method1( /*IN*/java.lang.Object itf ) throws com.sun.star.uno.Exception, com.sun.star.uno.RuntimeException { + } + + public void method2( /*OUT*/java.lang.Object[] itf ) throws com.sun.star.uno.Exception, com.sun.star.uno.RuntimeException { + } + + public void method3( /*INOUT*/java.lang.Object[] itf ) throws com.sun.star.uno.Exception, com.sun.star.uno.RuntimeException { + } + + public Object method4( ) throws com.sun.star.uno.Exception, com.sun.star.uno.RuntimeException { + return null; + } + + public Object returnAny( ) throws com.sun.star.uno.Exception, com.sun.star.uno.RuntimeException { + return null; + } + + + public void method() throws com.sun.star.uno.Exception, com.sun.star.uno.RuntimeException { + } + + public void methodWithInParameter( /*IN*/String text ) throws com.sun.star.uno.Exception, com.sun.star.uno.RuntimeException { + } + + public void methodWithOutParameter( /*OUT*/String[] text ) throws com.sun.star.uno.Exception, com.sun.star.uno.RuntimeException { + } + + public void methodWithInOutParameter( /*INOUT*/String[] text ) throws com.sun.star.uno.Exception, com.sun.star.uno.RuntimeException { + } + + public String methodWithResult( ) throws com.sun.star.uno.Exception, com.sun.star.uno.RuntimeException { + return "TestObject_resultString"; + } + + public String MethodWithIn_Out_InOut_Paramters_and_result( /*IN*/String text, /*OUT*/String[] outtext, /*INOUT*/String[] inouttext ) throws com.sun.star.uno.Exception, com.sun.star.uno.RuntimeException { + return "TestObject_resultString"; + } +} + diff --git a/jurt/test/com/sun/star/lib/uno/protocols/urp/interfaces.idl b/jurt/test/com/sun/star/lib/uno/protocols/urp/interfaces.idl new file mode 100644 index 000000000000..1b267c434a0f --- /dev/null +++ b/jurt/test/com/sun/star/lib/uno/protocols/urp/interfaces.idl @@ -0,0 +1,119 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#ifndef __com_sun_star_uno_XInterface_idl__ +#include <com/sun/star/uno/XInterface.idl> +#endif + +#ifndef __com_sun_star_beans_XPropertySet_idl_ +#include <com/sun/star/beans/XPropertySet.idl> +#endif + +#ifndef __com_sun_star_uno_Exception_idl__ +#include <com/sun/star/uno/Exception.idl> +#endif + +#ifndef __com_sun_star_uno_Exception_idl__ +#include <com/sun/star/uno/Any.idl> +#endif + + +module com { module sun { module star { module lib { module uno { +module protocols { module urp { + + struct TestPrimitiveStruct { + boolean zBool; + short zShort; + unsigned short zUShort; + long zLong; + unsigned long zULong; + hyper zHyper; + unsigned hyper zUHyper; + float zFloat; + double zDouble; + char zChar; + byte zByte; + string zString; + any zAny; + }; + + struct TestPrimitiveSeqStruct { + sequence<boolean> zBool; + sequence<short> zShort; + sequence<unsigned short> zUShort; + sequence<long> zLong; + sequence<unsigned long> zULong; + sequence<hyper> zHyper; + sequence<unsigned hyper> zUHyper; + sequence<float> zFloat; + sequence<double> zDouble; + sequence<char> zChar; + sequence<byte> zByte; + sequence<string> zString; + sequence<any> zAny; + }; + + struct TestNestedStruct { + TestPrimitiveStruct primitiveStruct; + TestPrimitiveSeqStruct primitiveSeqStruct; + }; + + struct TestNestedSeqStruct { + sequence< sequence< long > > val; + }; + + interface TestXInterface : com::sun::star::uno::XInterface { + void method1([in] com::sun::star::uno::XInterface itf) raises( com::sun::star::uno::Exception ); + void method2([out] com::sun::star::uno::XInterface itf) raises( com::sun::star::uno::Exception ); + void method3([inout] com::sun::star::uno::XInterface itf) raises( com::sun::star::uno::Exception ); + com::sun::star::uno::XInterface method4() raises( com::sun::star::uno::Exception ); + + any returnAny() raises( com::sun::star::uno::Exception ); + + void method() raises( com::sun::star::uno::Exception ); + void methodWithInParameter([in] string text) raises( com::sun::star::uno::Exception ); + void methodWithOutParameter([out] string text) raises( com::sun::star::uno::Exception ); + void methodWithInOutParameter([inout] string text) raises( com::sun::star::uno::Exception ); + string methodWithResult() raises( com::sun::star::uno::Exception ); + + string MethodWithIn_Out_InOut_Paramters_and_result([in] string text, [out] string outtext, [inout] string inouttext) raises( com::sun::star::uno::Exception ); + }; + + struct TestInterfaceStruct + { + com::sun::star::uno::XInterface hallo; + + com::sun::star::beans::XPropertySet hallo2; + }; + + enum TestEnum { + A = 7, + B = 8, + C = 11 + }; + +}; }; }; }; }; }; }; diff --git a/jurt/test/com/sun/star/lib/uno/protocols/urp/makefile.mk b/jurt/test/com/sun/star/lib/uno/protocols/urp/makefile.mk new file mode 100644 index 000000000000..c6e66558b65d --- /dev/null +++ b/jurt/test/com/sun/star/lib/uno/protocols/urp/makefile.mk @@ -0,0 +1,42 @@ +#************************************************************************* +# +# 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 +TARGET := test_com_sun_star_lib_uno_protocols_urp + +PACKAGE := com$/sun$/star$/lib$/uno$/protocols$/urp +JAVATESTFILES := \ + Cache_Test.java \ + Marshaling_Test.java \ + Protocol_Test.java +JAVAFILES := \ + TestBridge.java \ + TestObject.java +JARFILES := ridl.jar +IDLTESTFILES := interfaces.idl + +.INCLUDE: javaunittest.mk diff --git a/jurt/test/com/sun/star/lib/util/NativeLibraryLoader_Test.java b/jurt/test/com/sun/star/lib/util/NativeLibraryLoader_Test.java new file mode 100644 index 000000000000..fbb92f9b88ee --- /dev/null +++ b/jurt/test/com/sun/star/lib/util/NativeLibraryLoader_Test.java @@ -0,0 +1,83 @@ +/************************************************************************* + * + * 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.lib.util; + +import complexlib.ComplexTestCase; +import java.io.File; +import java.net.MalformedURLException; +import java.net.URL; + +public final class NativeLibraryLoader_Test extends ComplexTestCase { + public String[] getTestMethodNames() { + return new String[] { "testEncoded", "testUnencoded" }; + } + + public void testEncoded() throws MalformedURLException { + File dir = new File(System.getProperty("user.dir")); + File subdir = new File(dir, "with space"); + File file1 = new File(subdir, "file"); + + String fileUrl = dir.toURL().toString(); + if (!fileUrl.endsWith("/")) { + fileUrl += "/"; + } + fileUrl += "with%20space/file"; + final URL url = new URL(fileUrl); + + File file2 = NativeLibraryLoader.getResource( + new ClassLoader() { + public URL getResource(String name) { + return url; + } + }, + "dummy"); + assure("Files are equal", file2.equals(file1)); + } + + public void testUnencoded() throws MalformedURLException { + File dir = new File(System.getProperty("user.dir")); + File subdir = new File(dir, "with space"); + File file1 = new File(subdir, "file"); + + String fileUrl = dir.toURL().toString(); + if (!fileUrl.endsWith("/")) { + fileUrl += "/"; + } + fileUrl += "with space/file"; + final URL url = new URL(fileUrl); + + File file2 = NativeLibraryLoader.getResource( + new ClassLoader() { + public URL getResource(String name) { + return url; + } + }, + "dummy"); + assure("Files are equal", file2.equals(file1)); + } +} diff --git a/jurt/test/com/sun/star/lib/util/makefile.mk b/jurt/test/com/sun/star/lib/util/makefile.mk new file mode 100644 index 000000000000..dd411062329f --- /dev/null +++ b/jurt/test/com/sun/star/lib/util/makefile.mk @@ -0,0 +1,36 @@ +#************************************************************************* +# +# 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 +TARGET := test_com_sun_star_lib_util + +PACKAGE := com$/sun$/star$/lib$/util +JAVATESTFILES := \ + NativeLibraryLoader_Test.java + +.INCLUDE: javaunittest.mk diff --git a/jurt/test/com/sun/star/uno/AnyConverter_Test.java b/jurt/test/com/sun/star/uno/AnyConverter_Test.java new file mode 100644 index 000000000000..126b009c4e9a --- /dev/null +++ b/jurt/test/com/sun/star/uno/AnyConverter_Test.java @@ -0,0 +1,905 @@ +/************************************************************************* + * + * 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.uno; + +import com.sun.star.lang.XTypeProvider; +import complexlib.ComplexTestCase; + +public final class AnyConverter_Test extends ComplexTestCase { + public String getTestObjectName() { + return getClass().getName(); + } + + public String[] getTestMethodNames() { + return new String[] { + "test_toBoolean", "test_toChar", "test_toByte", "test_toShort", + "test_toInt", "test_toLong", "test_toFloat", "test_toDouble", + "test_toObject", "test_toString", "test_toType", "test_toArray", + "test_isBoolean", "test_isChar", "test_isByte", "test_isShort", + "test_isInt", "test_isLong", "test_isFloat", "test_isDouble", + "test_isObject", "test_isString", "test_isType", "test_isArray", + "test_isVoid" }; + } + + Any anyBool; // + Any anyChar; // + Any anyByte; // + Any anyShort; // + Any anyInt; // + Any anyLong; // + Any anyFloat; // + Any anyDouble; // + Any anyStr; // + Any anyType; // + Any anyArByte; // + Any anyVoid; // + Any anyXTypeProvider; + + Boolean aBool= new Boolean(true); + Character aChar= new Character('A'); + Byte aByte= new Byte((byte) 111); + Short aShort= new Short((short) 11111); + Integer aInt= new Integer( 1111111); + Long aLong= new Long( 0xffffffff); + Float aFloat= new Float( 3.14); + Double aDouble= new Double( 3.145); + Object aObj= new ATypeProvider(); + String aStr= new String("I am a string"); + Type aType= new Type(String.class); + byte[] arByte= new byte[] {1,2,3}; + + public AnyConverter_Test() { + anyVoid= new Any(new Type(void.class), null); + anyBool= new Any(new Type(Boolean.TYPE), aBool); + anyChar= new Any(new Type(Character.TYPE), aChar); + anyByte= new Any(new Type(Byte.TYPE), aByte); + anyShort= new Any(new Type(Short.TYPE), aShort); + anyInt= new Any(new Type(Integer.TYPE), aInt); + anyLong= new Any(new Type(Long.TYPE), aLong); + anyFloat= new Any(new Type(Float.TYPE), aFloat); + anyDouble= new Any(new Type(Double.TYPE), aDouble); + anyStr= new Any(new Type(String.class), aStr); + anyType= new Any(new Type(Type.class), aType); + anyArByte= new Any(new Type(byte[].class), arByte); + anyXTypeProvider= new Any(new Type(XTypeProvider.class), aObj); + } + + public void test_toBoolean() + throws com.sun.star.lang.IllegalArgumentException + { + // must work + boolean b= AnyConverter.toBoolean(aBool); + assure("", b == aBool.booleanValue()); + b= AnyConverter.toBoolean(anyBool); + assure("", b == ((Boolean)anyBool.getObject()).booleanValue()); + + // must fail + try { AnyConverter.toBoolean(aChar); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toBoolean(anyChar); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toBoolean(aByte); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toBoolean(anyByte); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toBoolean(aShort); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toBoolean(anyShort); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toBoolean(aInt); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toBoolean(anyInt); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toBoolean(aLong); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toBoolean(anyLong); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toBoolean(aFloat); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toBoolean(anyFloat); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toBoolean(aDouble); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toBoolean(anyDouble); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toBoolean(aObj); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toBoolean(aStr); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toBoolean(anyStr); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toBoolean(aType); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toBoolean(anyType); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toBoolean(anyVoid); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toBoolean(arByte); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toBoolean(anyArByte); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + } + + public void test_toChar() + throws com.sun.star.lang.IllegalArgumentException + { + // must work + char b= AnyConverter.toChar(aChar); + assure("", b == aChar.charValue()); + b= AnyConverter.toChar(anyChar); + assure("", b == ((Character)anyChar.getObject()).charValue()); + + // must fail + try { AnyConverter.toChar(aBool); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toChar(anyBool); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toChar(aByte); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toChar(anyByte); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toChar(aShort); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toChar(anyShort); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toChar(aInt); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toChar(anyInt); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toChar(aLong); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toChar(anyLong); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toChar(aFloat); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toChar(anyFloat); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toChar(aDouble); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toChar(anyDouble); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toChar(aObj); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toChar(aStr); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toChar(anyStr); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toChar(aType); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toChar(anyType); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toChar(anyVoid); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toChar(arByte); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toChar(anyArByte); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + } + + public void test_toByte() + throws com.sun.star.lang.IllegalArgumentException + { + // must work + byte val= AnyConverter.toByte(aByte); + assure("", val == aByte.byteValue()); + val= AnyConverter.toByte(anyByte); + assure("", val == ((Byte)anyByte.getObject()).byteValue()); + + // must fail + try { AnyConverter.toByte(aChar); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toByte(anyChar); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toByte(aShort); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toByte(anyShort); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toByte(aInt); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toByte(anyInt); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toByte(aLong); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toByte(anyLong); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toByte(aFloat); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toByte(anyFloat); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toByte(aDouble); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toByte(anyDouble); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toByte(aObj); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toByte(aStr); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toByte(anyStr); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toByte(aType); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toByte(anyType); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toByte(anyVoid); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toByte(arByte); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toByte(anyArByte); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + } + + public void test_toShort() + throws com.sun.star.lang.IllegalArgumentException + { + // must work + short sh= AnyConverter.toShort(aByte); + assure("", sh == aByte.byteValue()); + sh= AnyConverter.toShort(aShort); + assure("", sh == aShort.shortValue()); + sh= AnyConverter.toShort(anyByte); + assure("", sh == ((Byte)anyByte.getObject()).byteValue()); + sh= AnyConverter.toShort(anyShort); + assure("", sh == ((Short) anyShort.getObject()).shortValue()); + Any a = new Any( Type.UNSIGNED_SHORT, new Short((short)5) ); + assure("", 5 == AnyConverter.toUnsignedShort( a )); + + // must fail + try { AnyConverter.toShort(a); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toUnsignedShort(anyShort); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toChar(aBool); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toChar(anyBool); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toShort(aChar); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toShort(anyChar); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toShort(aBool); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toShort(anyBool); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toShort(aInt); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toShort(anyInt); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toShort(aLong); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toShort(anyLong); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toShort(aFloat); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toShort(anyFloat); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toShort(aDouble); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toShort(anyDouble); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toShort(aObj); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toShort(aStr); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toShort(anyStr); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toShort(aType); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toShort(anyType); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toShort(anyVoid); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toShort(arByte); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toShort(anyArByte); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + } + + public void test_toInt() + throws com.sun.star.lang.IllegalArgumentException + { + // must work + int val= AnyConverter.toInt(aByte); + assure("", val == aByte.byteValue()); + val= AnyConverter.toInt(aShort); + assure("", val == aShort.shortValue()); + val= AnyConverter.toInt(aInt); + assure("", val == aInt.intValue()); + val= AnyConverter.toInt(anyByte); + assure("", val == ((Byte)anyByte.getObject()).byteValue()); + val= AnyConverter.toInt(anyShort); + assure("", val == ((Short) anyShort.getObject()).shortValue()); + val= AnyConverter.toInt(anyInt); + assure("", val == ((Integer) anyInt.getObject()).intValue()); + Any a = new Any( Type.UNSIGNED_SHORT, new Short((short)5) ); + assure("", 5 == AnyConverter.toInt(a)); + assure("", 5 == AnyConverter.toUnsignedInt(a)); + a = new Any( Type.UNSIGNED_LONG, new Integer(5) ); + assure("", 5 == AnyConverter.toUnsignedInt(a)); + + // must fail + try { AnyConverter.toUnsignedInt(anyInt); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toInt(a); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toUnsignedInt(anyShort); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toInt(aChar); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toInt(anyChar); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toInt(aBool); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toInt(anyBool); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toInt(aLong); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toInt(anyLong); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toInt(aFloat); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toInt(anyFloat); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toInt(aDouble); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toInt(anyDouble); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toInt(aObj); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toInt(aStr); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toInt(anyStr); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toInt(aType); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toInt(anyType); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toInt(anyVoid); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toInt(arByte); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toInt(anyArByte); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + } + + public void test_toLong() + throws com.sun.star.lang.IllegalArgumentException + { + // must work + long val= AnyConverter.toLong(aByte); + assure("", val == aByte.byteValue()); + val= AnyConverter.toLong(aShort); + assure("", val == aShort.shortValue()); + val= AnyConverter.toLong(aInt); + assure("", val == aInt.intValue()); + val= AnyConverter.toLong(aLong); + assure("", val == aLong.longValue()); + val= AnyConverter.toLong(anyByte); + assure("", val == ((Byte)anyByte.getObject()).byteValue()); + val= AnyConverter.toLong(anyShort); + assure("", val == ((Short) anyShort.getObject()).shortValue()); + val= AnyConverter.toLong(anyInt); + assure("", val == ((Integer) anyInt.getObject()).intValue()); + val= AnyConverter.toLong(anyLong); + assure("", val == ((Long) anyLong.getObject()).longValue()); + Any a = new Any( Type.UNSIGNED_SHORT, new Short((short)5) ); + assure("", 5 == AnyConverter.toLong(a)); + assure("", 5 == AnyConverter.toUnsignedLong(a)); + a = new Any( Type.UNSIGNED_LONG, new Integer(5) ); + assure("", 5 == AnyConverter.toUnsignedLong(a)); + assure("", 5 == AnyConverter.toLong(a)); + a = new Any( Type.UNSIGNED_HYPER, new Long(5) ); + assure("", 5 == AnyConverter.toUnsignedLong(a)); + + // must fail + try { AnyConverter.toUnsignedLong(anyShort); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toUnsignedLong(anyInt); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toLong(a); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toUnsignedLong(anyLong); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toLong(aChar); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toLong(anyChar); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toLong(aBool); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toLong(anyBool); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toLong(aFloat); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toLong(anyFloat); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toLong(aDouble); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toLong(anyDouble); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toLong(aObj); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toLong(aStr); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toLong(anyStr); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toLong(aType); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toLong(anyType); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toLong(anyVoid); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toLong(arByte); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toLong(anyArByte); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + } + + public void test_toFloat() + throws com.sun.star.lang.IllegalArgumentException + { + // must work + float val= AnyConverter.toFloat(aByte); + assure("", val == aByte.byteValue()); // 111 = 111.0 + val= AnyConverter.toFloat(anyByte); + assure("", val == ((Byte)anyByte.getObject()).byteValue()); + val= AnyConverter.toFloat(aShort); + assure("", val == aShort.shortValue()); //11111 = 11111.0 + val= AnyConverter.toFloat(anyShort); + assure("", val == ((Short) anyShort.getObject()).shortValue()); + val= AnyConverter.toFloat(aFloat); + assure("", val == aFloat.floatValue()); + val= AnyConverter.toFloat(anyFloat); + assure("", val == ((Float) anyFloat.getObject()).floatValue()); + + // must fail + try { AnyConverter.toFloat(aChar); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toFloat(anyChar); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toFloat(aBool); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toFloat(anyBool); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toFloat(aInt); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toFloat(anyInt); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toFloat(aLong); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toFloat(anyLong); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toFloat(aDouble); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toFloat(anyDouble); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toFloat(aObj); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toFloat(aStr); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toFloat(anyStr); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toFloat(aType); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toFloat(anyType); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toFloat(anyVoid); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toFloat(arByte); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toFloat(anyArByte); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + } + + public void test_toDouble() + throws com.sun.star.lang.IllegalArgumentException + { + // must work + double val= AnyConverter.toDouble(aByte); + assure("", val == aByte.byteValue()); // 111 = 111.0 + val= AnyConverter.toDouble(anyByte); + assure("", val == ((Byte)anyByte.getObject()).byteValue()); + val= AnyConverter.toDouble(aShort); + assure("", val == aShort.shortValue()); //11111 = 11111.0 + val= AnyConverter.toDouble(anyShort); + assure("", val == ((Short) anyShort.getObject()).shortValue()); + val= AnyConverter.toDouble(aInt); + assure("", val == aInt.intValue()); + val= AnyConverter.toDouble(anyInt); + assure("", val == ((Integer) anyInt.getObject()).intValue()); + val= AnyConverter.toDouble(aFloat); + assure("", val == aFloat.floatValue()); + val= AnyConverter.toDouble(anyFloat); + float float1= ((Float) anyFloat.getObject()).floatValue(); + assure("", val <= (float1 + 0.1) || val >= (float1 - 0.1)); + val= AnyConverter.toDouble(aDouble); + assure("", val == aDouble.doubleValue()); + val= AnyConverter.toDouble(anyDouble); + assure("", val == ((Double) anyDouble.getObject()).doubleValue()); + + // must fail + try { AnyConverter.toDouble(aChar); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toDouble(anyChar); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toDouble(aBool); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toDouble(anyBool); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toDouble(aLong); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toDouble(anyLong); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toDouble(aObj); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toDouble(aStr); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toDouble(anyStr); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toDouble(aType); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toDouble(anyType); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toDouble(anyVoid); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toDouble(arByte); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toDouble(anyArByte); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + } + + public void test_toObject() + throws com.sun.star.lang.IllegalArgumentException + { + // must work + Type _type= new Type(XTypeProvider.class); + Object val= AnyConverter.toObject(_type, aObj); + assure("", UnoRuntime.areSame(val, aObj)); + val= AnyConverter.toObject( + _type, new Any( new Type(XTypeProvider.class), null)); + assure("", val == null); + + // structs, exceptions + com.sun.star.lang.IllegalArgumentException exc = + new com.sun.star.lang.IllegalArgumentException(); + Any any_exc = new Any( + new Type("com.sun.star.lang.IllegalArgumentException", + TypeClass.EXCEPTION), exc); + assure("", + AnyConverter.toObject( + new Type(com.sun.star.lang.IllegalArgumentException.class), + any_exc).equals(exc)); + assure("", + AnyConverter.toObject( + new Type(com.sun.star.uno.Exception.class), any_exc).equals( + exc)); + try { + AnyConverter.toObject( + new Type(com.sun.star.uno.RuntimeException.class), any_exc); + failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {}; + any_exc = new Any(com.sun.star.lang.IllegalArgumentException.class, + exc); + assure("", + AnyConverter.toObject( + new Type(com.sun.star.lang.IllegalArgumentException.class), + any_exc).equals(exc)); + assure("", + AnyConverter.toObject(new Type(com.sun.star.uno.Exception.class), + any_exc).equals(exc)); + try { + AnyConverter.toObject( + new Type(com.sun.star.uno.RuntimeException.class), any_exc); + failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {}; + + // must fail + try { AnyConverter.toObject(_type, aType); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toObject(_type, anyType); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toObject(_type, anyVoid); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toObject(_type, new Object()); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + } + + public void test_toString() + throws com.sun.star.lang.IllegalArgumentException + { + // must work + String val= AnyConverter.toString(aStr); + assure("", aStr.equals(val)); + val= AnyConverter.toString(anyStr); + assure("", ((String)anyStr.getObject()).equals(val)); + + // must fail + try { AnyConverter.toString(aBool); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toString(anyBool); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toString(aChar); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toString(anyChar); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toString(aByte); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toString(anyByte); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toString(aShort); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toString(anyShort); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toString(aInt); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toString(anyInt); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toString(aLong); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toString(anyLong); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toString(aFloat); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toString(anyFloat); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toString(aDouble); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toString(anyDouble); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toString(aObj); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toString(aType); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toString(anyType); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toString(anyVoid); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toString(arByte); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toString(anyArByte); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + } + + public void test_toType() + throws com.sun.star.lang.IllegalArgumentException + { + // must work + Type val= AnyConverter.toType(aType); + assure("", val == aType); + val= AnyConverter.toType(anyType); + assure("", val == anyType.getObject()); + + // must fail + try { AnyConverter.toType(aBool); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toType(anyBool); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toType(aChar); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toType(anyChar); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toType(aByte); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toType(anyByte); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toType(aShort); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toType(anyShort); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toType(aInt); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toType(anyInt); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toType(aLong); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toType(anyLong); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toType(aFloat); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toType(anyFloat); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toType(aDouble); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toType(anyDouble); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toType(aObj); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toType(aStr); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toType(anyStr); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toType(anyVoid); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toType(arByte); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toType(anyArByte); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + } + + public void test_toArray() + throws com.sun.star.lang.IllegalArgumentException + { + // must work + Object val= AnyConverter.toArray(arByte); + assure("", val == arByte); + val= AnyConverter.toArray(anyArByte); + assure("", val == anyArByte.getObject()); + + // must fail + try { AnyConverter.toType(aBool); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toType(anyBool); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toType(aChar); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toType(anyChar); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toType(aByte); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toType(anyByte); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toType(aShort); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toType(anyShort); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toType(aInt); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toType(anyInt); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toType(aLong); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toType(anyLong); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toType(aFloat); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toType(anyFloat); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toType(aDouble); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toType(anyDouble); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toType(aObj); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toType(aStr); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toType(anyStr); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toType(anyVoid); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toType(arByte); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + try { AnyConverter.toType(anyArByte); failed(""); + } catch (com.sun.star.lang.IllegalArgumentException ie) {} + } + + public void test_isBoolean() { + assure("", AnyConverter.isBoolean(aBool)); + assure("", AnyConverter.isBoolean(anyBool)); + assure("", !AnyConverter.isBoolean(aChar)); + } + + public void test_isChar() { + assure("", AnyConverter.isChar(aChar)); + assure("", AnyConverter.isChar(anyChar)); + assure("", !AnyConverter.isChar(aBool)); + } + + public void test_isByte() { + assure("", AnyConverter.isByte(aByte)); + assure("", AnyConverter.isByte(anyByte)); + assure("", !AnyConverter.isByte(aBool)); + } + + public void test_isShort() { + assure("", AnyConverter.isShort(aShort)); + assure("", AnyConverter.isShort(anyShort)); + assure("", Type.SHORT.equals(AnyConverter.getType(anyShort))); + Any a = new Any( Type.UNSIGNED_SHORT, new Short((short)5) ); + assure("", Type.UNSIGNED_SHORT.equals(AnyConverter.getType(a))); + assure("", !AnyConverter.isShort(a)); + assure("", !Type.SHORT.equals(AnyConverter.getType(a))); + assure("", !AnyConverter.isShort(aBool)); + } + + public void test_isInt() { + assure("", AnyConverter.isInt(aInt)); + assure("", AnyConverter.isInt(anyInt)); + assure("", Type.LONG.equals(AnyConverter.getType(anyInt))); + Any a = new Any(Type.UNSIGNED_LONG, new Integer(5)); + assure("", Type.UNSIGNED_LONG.equals(AnyConverter.getType(a))); + assure("", !AnyConverter.isInt(a)); + assure("", !Type.LONG.equals(AnyConverter.getType(a))); + assure("", !AnyConverter.isInt(aBool)); + } + + public void test_isLong() { + assure("", AnyConverter.isLong(aLong)); + assure("", AnyConverter.isLong(anyLong)); + assure("", Type.HYPER.equals(AnyConverter.getType(anyLong))); + Any a = new Any( Type.UNSIGNED_HYPER, new Long(5) ); + assure("", Type.UNSIGNED_HYPER.equals( AnyConverter.getType(a) )); + assure("", !AnyConverter.isLong(a)); + assure("", !Type.HYPER.equals( AnyConverter.getType(a) )); + assure("", !AnyConverter.isLong(aBool)); + } + + public void test_isFloat() { + assure("", AnyConverter.isFloat(aFloat)); + assure("", AnyConverter.isFloat(anyFloat)); + assure("", !AnyConverter.isFloat(aDouble)); + } + + public void test_isDouble() { + assure("", AnyConverter.isDouble(aDouble)); + assure("", AnyConverter.isDouble(anyDouble)); + assure("", !AnyConverter.isDouble(aFloat)); + } + + public void test_isObject() { + assure("", AnyConverter.isObject(aObj)); + assure("", AnyConverter.isObject( new Any( XInterface.class, null))); + assure("", !AnyConverter.isObject(new Object())); + } + + public void test_isString() { + assure("", AnyConverter.isString(aStr)); + assure("", AnyConverter.isString(anyStr)); + assure("", !AnyConverter.isString(new Object())); + } + + public void test_isType() { + assure("", AnyConverter.isType(aType)); + assure("", AnyConverter.isType(anyType)); + assure("", !AnyConverter.isType(new Object())); + } + + public void test_isArray() { + assure("", AnyConverter.isArray(arByte)); + assure("", AnyConverter.isArray(anyArByte)); + assure("", !AnyConverter.isArray(new Object())); + } + + public void test_isVoid() { + assure("", AnyConverter.isVoid(anyVoid)); + assure("", !AnyConverter.isVoid(new Object())); + } +} + + +class ATypeProvider implements com.sun.star.lang.XTypeProvider +{ + + public byte[] getImplementationId() + { + return new byte[]{1,2,3}; + } + + public com.sun.star.uno.Type[] getTypes() + { + return new Type[]{new Type(XTypeProvider.class)}; + } + +} diff --git a/jurt/test/com/sun/star/uno/UnoRuntime_EnvironmentTest.java b/jurt/test/com/sun/star/uno/UnoRuntime_EnvironmentTest.java new file mode 100644 index 000000000000..0ee0e1d32ccd --- /dev/null +++ b/jurt/test/com/sun/star/uno/UnoRuntime_EnvironmentTest.java @@ -0,0 +1,96 @@ +/************************************************************************* + * + * 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.uno; + +import com.sun.star.comp.connections.PipedConnection; +import complexlib.ComplexTestCase; +import util.WaitUnreachable; + +public final class UnoRuntime_EnvironmentTest extends ComplexTestCase { + public String getTestObjectName() { + return getClass().getName(); + } + + public String[] getTestMethodNames() { + return new String[] { "test_getEnvironment", "test_getBridge" }; + } + + public void test_getEnvironment() throws java.lang.Exception { + Object o1 = new Object(); + Object o2 = new Object(); + + // get two environments with different contexts + WaitUnreachable java_environment1 = new WaitUnreachable( + UnoRuntime.getEnvironment("java", o1)); + WaitUnreachable java_environment2 = new WaitUnreachable( + UnoRuntime.getEnvironment("java", o2)); + + // ensure that the environments are different + assure("", java_environment1.get() != java_environment2.get()); + + // test if we get the same environment when we reget it + assure("", + UnoRuntime.areSame(java_environment1.get(), + UnoRuntime.getEnvironment("java", o1))); + assure("", + UnoRuntime.areSame(java_environment2.get(), + UnoRuntime.getEnvironment("java", o2))); + + // drop the environments and wait until they are gc + java_environment1.waitUnreachable(); + java_environment2.waitUnreachable(); + } + + public void test_getBridge() throws java.lang.Exception { + PipedConnection conn = new PipedConnection(new Object[0]); + new PipedConnection(new Object[] { conn }); + + // get a bridge + IBridge iBridge = UnoRuntime.getBridgeByName( + "java", null, "remote", "testname", + new Object[] { "urp", conn, null }); + + // reget the bridge, it must be the same as above + IBridge iBridge_tmp = UnoRuntime.getBridgeByName( + "java", null, "remote", "testname", + new Object[] { "urp", conn, null }); + assure("", UnoRuntime.areSame(iBridge_tmp, iBridge)); + + // dispose the bridge, this removes the entry from the runtime + iBridge.dispose(); + + conn = new PipedConnection(new Object[0]); + new PipedConnection(new Object[] { conn }); + + // reget the bridge, it must be a different one + iBridge_tmp = UnoRuntime.getBridgeByName( + "java", null, "remote", "testname", + new Object[]{ "urp", conn, null }); + assure("", !UnoRuntime.areSame(iBridge_tmp, iBridge)); + } +} diff --git a/jurt/test/com/sun/star/uno/WeakReference_Test.java b/jurt/test/com/sun/star/uno/WeakReference_Test.java new file mode 100644 index 000000000000..6520803cb22c --- /dev/null +++ b/jurt/test/com/sun/star/uno/WeakReference_Test.java @@ -0,0 +1,118 @@ +/************************************************************************* + * + * 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.uno; + +import complexlib.ComplexTestCase; +import java.util.ArrayList; +import java.util.Iterator; +import util.WaitUnreachable; + +public final class WeakReference_Test extends ComplexTestCase { + public String getTestObjectName() { + return getClass().getName(); + } + + public String[] getTestMethodNames() { + return new String[] { "test" }; + } + + public void test() { + Object o = new MockWeak(); + WeakReference r1 = new WeakReference(o); + WeakReference r2 = new WeakReference(r1); + assure("", r1.get() == o); + assure("", r2.get() == o); + WaitUnreachable u = new WaitUnreachable(o); + o = null; + u.waitUnreachable(); + assure("a3", r1.get() == null); + assure("a4", r2.get() == null); + } + + private static final class MockWeak implements XWeak { + public XAdapter queryAdapter() { + return adapter; + } + + protected void finalize() { + adapter.dispose(); + } + + private static final class Adapter implements XAdapter { + public Adapter(Object obj) { + ref = new java.lang.ref.WeakReference(obj); + } + + public Object queryAdapted() { + return ref.get(); + } + + public void addReference(XReference ref) { + synchronized (this) { + if (listeners != null) { + listeners.add(ref); + return; + } + } + ref.dispose(); + } + + public synchronized void removeReference(XReference ref) { + if (listeners != null) { + listeners.remove(ref); + } + } + + public void dispose() { + ArrayList l; + synchronized (this){ + l = listeners; + listeners = null; + } + if (l != null) { + java.lang.RuntimeException ex = null; + for (Iterator i = l.iterator(); i.hasNext();) { + try { + ((XReference) i.next()).dispose(); + } catch (java.lang.RuntimeException e) { + ex = e; + } + } + if (ex != null) { + throw ex; + } + } + } + + private final java.lang.ref.WeakReference ref; + private ArrayList listeners = new ArrayList(); + } + + private final Adapter adapter = new Adapter(this); + } +} diff --git a/jurt/test/com/sun/star/uno/makefile.mk b/jurt/test/com/sun/star/uno/makefile.mk new file mode 100644 index 000000000000..ecf0115c3441 --- /dev/null +++ b/jurt/test/com/sun/star/uno/makefile.mk @@ -0,0 +1,39 @@ +#************************************************************************* +# +# 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 +TARGET := test_com_sun_star_uno + +PACKAGE := com$/sun$/star$/uno +JAVATESTFILES := \ + AnyConverter_Test.java \ + UnoRuntime_EnvironmentTest.java \ + WeakReference_Test.java +JARFILES := ridl.jar + +.INCLUDE: javaunittest.mk diff --git a/jurt/test/makefile.mk b/jurt/test/makefile.mk new file mode 100644 index 000000000000..146480c6db39 --- /dev/null +++ b/jurt/test/makefile.mk @@ -0,0 +1,39 @@ +#************************************************************************* +# +# 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. +# +#************************************************************************* +# Quick and dirty way to run all tests in sub-directories; probably only works +# on Unix. +# Can be removed once tests are included in regular builds. + +all .PHONY: + cd com/sun/star/comp/bridgefactory && dmake + cd com/sun/star/comp/connections && dmake + cd com/sun/star/lib/uno/bridges/java_remote && dmake + cd com/sun/star/lib/uno/environments/java && dmake + cd com/sun/star/lib/uno/environments/remote && dmake + cd com/sun/star/lib/uno/protocols/urp && dmake + cd com/sun/star/lib/util && dmake + cd com/sun/star/uno && dmake diff --git a/jurt/util/delzip b/jurt/util/delzip new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/jurt/util/delzip diff --git a/jurt/util/makefile.mk b/jurt/util/makefile.mk new file mode 100644 index 000000000000..fdc672ae6f09 --- /dev/null +++ b/jurt/util/makefile.mk @@ -0,0 +1,52 @@ +#************************************************************************* +# +# 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 +TARGET = jurt + +# --- Settings ----------------------------------------------------- + +.INCLUDE: makefile.pmk + +JARCLASSDIRS = com +JARTARGET = $(TARGET).jar +JARCOMPRESS = TRUE +JARCLASSPATH = $(JARFILES) ../../lib/ ../bin/ +CUSTOMMANIFESTFILE = manifest + +# Special work necessary for building java reference with javadoc. +# The source of puplic APIs must be delivered and used later in the +# odk module. +ZIP1TARGET=$(TARGET)_src +ZIP1FLAGS=-u -r +ZIP1DIR=$(PRJ) +ZIP1LIST=com -x "*makefile.mk" + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/jurt/util/makefile.pmk b/jurt/util/makefile.pmk new file mode 100644 index 000000000000..08df516ea3b0 --- /dev/null +++ b/jurt/util/makefile.pmk @@ -0,0 +1,32 @@ +#************************************************************************* +# +# 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. +# +#************************************************************************* + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +JARFILES = ridl.jar unoloader.jar diff --git a/jurt/util/manifest b/jurt/util/manifest new file mode 100644 index 000000000000..1cb880553436 --- /dev/null +++ b/jurt/util/manifest @@ -0,0 +1,7 @@ +Sealed: true + +Name: com/sun/star/lib/util/ +Sealed: false + +Name: com/sun/star/uno/ +Sealed: false diff --git a/jurt/workbench/com/sun/star/comp/urlresolver/UrlResolver_Test.java b/jurt/workbench/com/sun/star/comp/urlresolver/UrlResolver_Test.java new file mode 100644 index 000000000000..a78a2dffd1ad --- /dev/null +++ b/jurt/workbench/com/sun/star/comp/urlresolver/UrlResolver_Test.java @@ -0,0 +1,95 @@ +/************************************************************************* + * + * 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.urlresolver; + +import com.sun.star.uno.XComponentContext; +import com.sun.star.comp.helper.Bootstrap; +import com.sun.star.lang.XMultiComponentFactory; +import com.sun.star.bridge.UnoUrlResolver; +import com.sun.star.bridge.XUnoUrlResolver; +import com.sun.star.beans.XPropertySet; +import com.sun.star.uno.UnoRuntime; +//import com.sun.star.connection.NoConnectionException; + +/** start the office with these options <br> + soffice -accept=socket,host=localhost,port=8100;urp; +*/ +public class UrlResolver_Test +{ + public static void main(String[] args) { + try { + XComponentContext xcomponentcontext = Bootstrap.createInitialComponentContext( null ); + + // initial serviceManager + XMultiComponentFactory xLocalServiceManager = xcomponentcontext.getServiceManager(); + + // create a connector, so that it can contact the office + XUnoUrlResolver urlResolver + = UnoUrlResolver.create( xcomponentcontext ); + + Object initialObject = urlResolver.resolve( + "uno:socket,host=localhost,port=8100;urp;StarOffice.ServiceManager" ); + + XMultiComponentFactory xOfficeFactory= UnoRuntime.queryInterface( + XMultiComponentFactory.class, initialObject ); + + // retrieve the component context (it's not yet exported from the office) + // Query for the XPropertySet interface. + XPropertySet xProperySet = UnoRuntime.queryInterface( + XPropertySet.class, xOfficeFactory); + + // Get the default context from the office server. + Object oDefaultContext = xProperySet.getPropertyValue( "DefaultContext" ); + + // Query for the interface XComponentContext. + XComponentContext xOfficeComponentContext = UnoRuntime.queryInterface( + XComponentContext.class, oDefaultContext ); + + // now create the desktop service + // NOTE: use the office component context here ! + Object oDesktop = xOfficeFactory.createInstanceWithContext("com.sun.star.frame.Desktop", + xOfficeComponentContext ); + } catch(com.sun.star.connection.NoConnectException e) { + System.out.println(e.getMessage()); + e.printStackTrace(); + } catch(com.sun.star.connection.ConnectionSetupException ce) { + System.out.println(ce.getMessage()); + ce.printStackTrace(); + } catch(com.sun.star.lang.IllegalArgumentException ie) { + System.out.println(ie.getMessage()); + ie.printStackTrace(); + } catch(com.sun.star.beans.UnknownPropertyException ue) { + System.out.println(ue.getMessage()); + ue.printStackTrace(); + } catch(java.lang.Exception ee) { + System.out.println(ee.getMessage()); + ee.printStackTrace(); + } + + } +} diff --git a/jurt/workbench/com/sun/star/comp/urlresolver/makefile.mk b/jurt/workbench/com/sun/star/comp/urlresolver/makefile.mk new file mode 100644 index 000000000000..c1378b37c99c --- /dev/null +++ b/jurt/workbench/com/sun/star/comp/urlresolver/makefile.mk @@ -0,0 +1,53 @@ +#************************************************************************* +# +# 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 +TARGET := workbench_com_sun_star_comp_urlresolver + +PACKAGE := com$/sun$/star$/comp$/urlresolver +JAVAFILES := UrlResolver_Test.java +JARFILES := ridl.jar juh.jar + +.INCLUDE: settings.mk + +# Put the generated class files into <platform>/class/workbench/ instead of +# <platform>/class/ (otherwise, these class files might end up being zipped into +# the generated jurt.jar): +.IF "$(XCLASSPATH)" == "" +XCLASSPATH := $(CLASSDIR) +.ELSE +XCLASSPATH !:= $(XCLASSPATH)$(PATH_SEPERATOR)$(CLASSDIR) +.ENDIF +CLASSDIR !:= $(CLASSDIR)$/workbench + +.INCLUDE: target.mk + +$(JAVAFILES): $(MISC)$/$(TARGET).createdclassdir +$(MISC)$/$(TARGET).createdclassdir: + - $(MKDIR) $(CLASSDIR) + $(TOUCH) $@ |