summaryrefslogtreecommitdiff
path: root/jurt/com/sun/star
diff options
context:
space:
mode:
Diffstat (limited to 'jurt/com/sun/star')
-rw-r--r--jurt/com/sun/star/comp/bridgefactory/BridgeFactory.java231
-rw-r--r--jurt/com/sun/star/comp/bridgefactory/makefile.mk47
-rw-r--r--jurt/com/sun/star/comp/connections/Acceptor.java173
-rw-r--r--jurt/com/sun/star/comp/connections/Connector.java154
-rw-r--r--jurt/com/sun/star/comp/connections/ConstantInstanceProvider.java142
-rw-r--r--jurt/com/sun/star/comp/connections/Implementation.java104
-rw-r--r--jurt/com/sun/star/comp/connections/PipedConnection.java286
-rw-r--r--jurt/com/sun/star/comp/connections/makefile.mk47
-rw-r--r--jurt/com/sun/star/comp/loader/FactoryHelper.java567
-rw-r--r--jurt/com/sun/star/comp/loader/JavaLoader.java486
-rw-r--r--jurt/com/sun/star/comp/loader/JavaLoaderFactory.java107
-rw-r--r--jurt/com/sun/star/comp/loader/RegistrationClassFinder.java136
-rw-r--r--jurt/com/sun/star/comp/loader/makefile.mk51
-rw-r--r--jurt/com/sun/star/comp/servicemanager/ServiceManager.java929
-rw-r--r--jurt/com/sun/star/comp/servicemanager/makefile.mk47
-rw-r--r--jurt/com/sun/star/comp/urlresolver/UrlResolver.java174
-rw-r--r--jurt/com/sun/star/comp/urlresolver/makefile.mk47
-rw-r--r--jurt/com/sun/star/lib/connections/pipe/PipeConnection.java257
-rw-r--r--jurt/com/sun/star/lib/connections/pipe/makefile.mk45
-rw-r--r--jurt/com/sun/star/lib/connections/pipe/pipeAcceptor.java149
-rw-r--r--jurt/com/sun/star/lib/connections/pipe/pipeConnector.java145
-rw-r--r--jurt/com/sun/star/lib/connections/socket/ConnectionDescriptor.java110
-rw-r--r--jurt/com/sun/star/lib/connections/socket/SocketConnection.java255
-rw-r--r--jurt/com/sun/star/lib/connections/socket/makefile.mk46
-rw-r--r--jurt/com/sun/star/lib/connections/socket/socketAcceptor.java210
-rw-r--r--jurt/com/sun/star/lib/connections/socket/socketConnector.java184
-rw-r--r--jurt/com/sun/star/lib/uno/Proxy.java43
-rw-r--r--jurt/com/sun/star/lib/uno/bridges/java_remote/BridgedObject.java52
-rw-r--r--jurt/com/sun/star/lib/uno/bridges/java_remote/ProxyFactory.java188
-rw-r--r--jurt/com/sun/star/lib/uno/bridges/java_remote/RequestHandler.java44
-rw-r--r--jurt/com/sun/star/lib/uno/bridges/java_remote/XConnectionInputStream_Adapter.java85
-rw-r--r--jurt/com/sun/star/lib/uno/bridges/java_remote/XConnectionOutputStream_Adapter.java94
-rw-r--r--jurt/com/sun/star/lib/uno/bridges/java_remote/java_remote_bridge.java714
-rw-r--r--jurt/com/sun/star/lib/uno/bridges/java_remote/makefile.mk48
-rw-r--r--jurt/com/sun/star/lib/uno/environments/java/java_environment.java354
-rw-r--r--jurt/com/sun/star/lib/uno/environments/java/makefile.mk48
-rw-r--r--jurt/com/sun/star/lib/uno/environments/remote/IProtocol.java100
-rw-r--r--jurt/com/sun/star/lib/uno/environments/remote/IReceiver.java51
-rw-r--r--jurt/com/sun/star/lib/uno/environments/remote/IThreadPool.java130
-rw-r--r--jurt/com/sun/star/lib/uno/environments/remote/JavaThreadPool.java135
-rw-r--r--jurt/com/sun/star/lib/uno/environments/remote/JavaThreadPoolFactory.java97
-rw-r--r--jurt/com/sun/star/lib/uno/environments/remote/Job.java183
-rw-r--r--jurt/com/sun/star/lib/uno/environments/remote/JobQueue.java399
-rw-r--r--jurt/com/sun/star/lib/uno/environments/remote/Message.java198
-rw-r--r--jurt/com/sun/star/lib/uno/environments/remote/NativeThreadPool.java103
-rw-r--r--jurt/com/sun/star/lib/uno/environments/remote/ThreadId.java98
-rw-r--r--jurt/com/sun/star/lib/uno/environments/remote/ThreadPoolManager.java83
-rw-r--r--jurt/com/sun/star/lib/uno/environments/remote/makefile.mk54
-rw-r--r--jurt/com/sun/star/lib/uno/environments/remote/remote_environment.java75
-rw-r--r--jurt/com/sun/star/lib/uno/makefile.mk41
-rw-r--r--jurt/com/sun/star/lib/uno/protocols/urp/Cache.java123
-rw-r--r--jurt/com/sun/star/lib/uno/protocols/urp/Marshal.java393
-rw-r--r--jurt/com/sun/star/lib/uno/protocols/urp/PendingRequests.java74
-rw-r--r--jurt/com/sun/star/lib/uno/protocols/urp/Unmarshal.java493
-rw-r--r--jurt/com/sun/star/lib/uno/protocols/urp/UrpMessage.java57
-rw-r--r--jurt/com/sun/star/lib/uno/protocols/urp/makefile.mk48
-rw-r--r--jurt/com/sun/star/lib/uno/protocols/urp/urp.java737
-rw-r--r--jurt/com/sun/star/lib/util/AsynchronousFinalizer.java105
-rw-r--r--jurt/com/sun/star/lib/util/NativeLibraryLoader.java121
-rw-r--r--jurt/com/sun/star/lib/util/StringHelper.java54
-rw-r--r--jurt/com/sun/star/lib/util/UrlToFileMapper.java164
-rw-r--r--jurt/com/sun/star/lib/util/makefile.mk46
-rw-r--r--jurt/com/sun/star/uno/AnyConverter.java543
-rw-r--r--jurt/com/sun/star/uno/Ascii.java53
-rw-r--r--jurt/com/sun/star/uno/AsciiString.java54
-rw-r--r--jurt/com/sun/star/uno/MappingException.java73
-rw-r--r--jurt/com/sun/star/uno/WeakReference.java150
-rw-r--r--jurt/com/sun/star/uno/makefile.mk56
68 files changed, 11890 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..6dd90b3dd590
--- /dev/null
+++ b/jurt/com/sun/star/comp/bridgefactory/BridgeFactory.java
@@ -0,0 +1,231 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: BridgeFactory.java,v $
+ * $Revision: 1.11 $
+ *
+ * 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..6691c8357980
--- /dev/null
+++ b/jurt/com/sun/star/comp/bridgefactory/makefile.mk
@@ -0,0 +1,47 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.6 $
+#
+# 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..f0cae47aa4f3
--- /dev/null
+++ b/jurt/com/sun/star/comp/connections/Acceptor.java
@@ -0,0 +1,173 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: Acceptor.java,v $
+ * $Revision: 1.5 $
+ *
+ * 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..a74db7d26e5e
--- /dev/null
+++ b/jurt/com/sun/star/comp/connections/Connector.java
@@ -0,0 +1,154 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: Connector.java,v $
+ * $Revision: 1.4 $
+ *
+ * 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..bf31e731cdf7
--- /dev/null
+++ b/jurt/com/sun/star/comp/connections/ConstantInstanceProvider.java
@@ -0,0 +1,142 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: ConstantInstanceProvider.java,v $
+ * $Revision: 1.3 $
+ *
+ * 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..bbb6e56dd1ff
--- /dev/null
+++ b/jurt/com/sun/star/comp/connections/Implementation.java
@@ -0,0 +1,104 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: Implementation.java,v $
+ * $Revision: 1.3 $
+ *
+ * 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..1c508206b86b
--- /dev/null
+++ b/jurt/com/sun/star/comp/connections/PipedConnection.java
@@ -0,0 +1,286 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: PipedConnection.java,v $
+ * $Revision: 1.3 $
+ *
+ * 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..02f536af5ae9
--- /dev/null
+++ b/jurt/com/sun/star/comp/connections/makefile.mk
@@ -0,0 +1,47 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.6 $
+#
+# 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..83c1c567509f
--- /dev/null
+++ b/jurt/com/sun/star/comp/loader/FactoryHelper.java
@@ -0,0 +1,567 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: FactoryHelper.java,v $
+ * $Revision: 1.9 $
+ *
+ * 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..cf0d9995d7f6
--- /dev/null
+++ b/jurt/com/sun/star/comp/loader/JavaLoader.java
@@ -0,0 +1,486 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: JavaLoader.java,v $
+ * $Revision: 1.16 $
+ *
+ * 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..15490069cdef
--- /dev/null
+++ b/jurt/com/sun/star/comp/loader/JavaLoaderFactory.java
@@ -0,0 +1,107 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: JavaLoaderFactory.java,v $
+ * $Revision: 1.4 $
+ *
+ * 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..b5e4129229ab
--- /dev/null
+++ b/jurt/com/sun/star/comp/loader/RegistrationClassFinder.java
@@ -0,0 +1,136 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: RegistrationClassFinder.java,v $
+ * $Revision: 1.10 $
+ *
+ * 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..df744429839c
--- /dev/null
+++ b/jurt/com/sun/star/comp/loader/makefile.mk
@@ -0,0 +1,51 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.5 $
+#
+# 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..b791c6501a36
--- /dev/null
+++ b/jurt/com/sun/star/comp/servicemanager/ServiceManager.java
@@ -0,0 +1,929 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: ServiceManager.java,v $
+ * $Revision: 1.10 $
+ *
+ * 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..7b03ad8875d2
--- /dev/null
+++ b/jurt/com/sun/star/comp/servicemanager/makefile.mk
@@ -0,0 +1,47 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.5 $
+#
+# 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..6c63ccbd8490
--- /dev/null
+++ b/jurt/com/sun/star/comp/urlresolver/UrlResolver.java
@@ -0,0 +1,174 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: UrlResolver.java,v $
+ * $Revision: 1.6 $
+ *
+ * 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..c386491aeeec
--- /dev/null
+++ b/jurt/com/sun/star/comp/urlresolver/makefile.mk
@@ -0,0 +1,47 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.5 $
+#
+# 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..1039c37cfbbc
--- /dev/null
+++ b/jurt/com/sun/star/lib/connections/pipe/PipeConnection.java
@@ -0,0 +1,257 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: PipeConnection.java,v $
+ * $Revision: 1.7 $
+ *
+ * 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..4548ba3568b5
--- /dev/null
+++ b/jurt/com/sun/star/lib/connections/pipe/makefile.mk
@@ -0,0 +1,45 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.5 $
+#
+# 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..7de17241e3f1
--- /dev/null
+++ b/jurt/com/sun/star/lib/connections/pipe/pipeAcceptor.java
@@ -0,0 +1,149 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: pipeAcceptor.java,v $
+ * $Revision: 1.4 $
+ *
+ * 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..f296c2f58185
--- /dev/null
+++ b/jurt/com/sun/star/lib/connections/pipe/pipeConnector.java
@@ -0,0 +1,145 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: pipeConnector.java,v $
+ * $Revision: 1.4 $
+ *
+ * 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..c9c613fc8e20
--- /dev/null
+++ b/jurt/com/sun/star/lib/connections/socket/ConnectionDescriptor.java
@@ -0,0 +1,110 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: ConnectionDescriptor.java,v $
+ * $Revision: 1.3 $
+ *
+ * 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..0a49f476fe20
--- /dev/null
+++ b/jurt/com/sun/star/lib/connections/socket/SocketConnection.java
@@ -0,0 +1,255 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: SocketConnection.java,v $
+ * $Revision: 1.6 $
+ *
+ * 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..c167678e1116
--- /dev/null
+++ b/jurt/com/sun/star/lib/connections/socket/makefile.mk
@@ -0,0 +1,46 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.6 $
+#
+# 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..e4b053844c54
--- /dev/null
+++ b/jurt/com/sun/star/lib/connections/socket/socketAcceptor.java
@@ -0,0 +1,210 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: socketAcceptor.java,v $
+ * $Revision: 1.6 $
+ *
+ * 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..bbd11b4ce6ab
--- /dev/null
+++ b/jurt/com/sun/star/lib/connections/socket/socketConnector.java
@@ -0,0 +1,184 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: socketConnector.java,v $
+ * $Revision: 1.7 $
+ *
+ * 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..eff59b246d34
--- /dev/null
+++ b/jurt/com/sun/star/lib/uno/Proxy.java
@@ -0,0 +1,43 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: Proxy.java,v $
+ * $Revision: 1.4 $
+ *
+ * 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..58880c02ca50
--- /dev/null
+++ b/jurt/com/sun/star/lib/uno/bridges/java_remote/BridgedObject.java
@@ -0,0 +1,52 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: BridgedObject.java,v $
+ * $Revision: 1.4 $
+ *
+ * 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..6ca071d2fe0e
--- /dev/null
+++ b/jurt/com/sun/star/lib/uno/bridges/java_remote/ProxyFactory.java
@@ -0,0 +1,188 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: ProxyFactory.java,v $
+ * $Revision: 1.8 $
+ *
+ * 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..646e9211d07c
--- /dev/null
+++ b/jurt/com/sun/star/lib/uno/bridges/java_remote/RequestHandler.java
@@ -0,0 +1,44 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: RequestHandler.java,v $
+ * $Revision: 1.4 $
+ *
+ * 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..f08a33000340
--- /dev/null
+++ b/jurt/com/sun/star/lib/uno/bridges/java_remote/XConnectionInputStream_Adapter.java
@@ -0,0 +1,85 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: XConnectionInputStream_Adapter.java,v $
+ * $Revision: 1.4 $
+ *
+ * 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..cc29e0d3c27f
--- /dev/null
+++ b/jurt/com/sun/star/lib/uno/bridges/java_remote/XConnectionOutputStream_Adapter.java
@@ -0,0 +1,94 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: XConnectionOutputStream_Adapter.java,v $
+ * $Revision: 1.4 $
+ *
+ * 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..78213624d4ed
--- /dev/null
+++ b/jurt/com/sun/star/lib/uno/bridges/java_remote/java_remote_bridge.java
@@ -0,0 +1,714 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: java_remote_bridge.java,v $
+ * $Revision: 1.45 $
+ *
+ * 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..738869fc851a
--- /dev/null
+++ b/jurt/com/sun/star/lib/uno/bridges/java_remote/makefile.mk
@@ -0,0 +1,48 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.8 $
+#
+# 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..36404f28d57e
--- /dev/null
+++ b/jurt/com/sun/star/lib/uno/environments/java/java_environment.java
@@ -0,0 +1,354 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: java_environment.java,v $
+ * $Revision: 1.17 $
+ *
+ * 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;
+import java.util.LinkedList;
+
+/**
+ * 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 Object register(Object object, String oid, Type type) {
+ synchronized (map) {
+ cleanUp();
+ Level1Entry l1 = getLevel1Entry(oid);
+ if (l1 != null) {
+ Level2Entry l2 = l1.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();
+ map.put(oid, l1);
+ }
+ l1.add(new Level2Entry(oid, type, object, queue));
+ }
+ return object;
+ }
+
+ public boolean revoke(String oid, Type type) {
+ synchronized (map) {
+ Level1Entry l1 = getLevel1Entry(oid);
+ Level2Entry l2 = null;
+ if (l1 != null) {
+ l2 = l1.get(type);
+ if (l2 != null && l2.release()) {
+ removeLevel2Entry(oid, l1, l2);
+ }
+ }
+ cleanUp();
+ return l2 != null;
+ }
+ }
+
+ public Object get(String oid, Type type) {
+ synchronized (map) {
+ Level1Entry l1 = getLevel1Entry(oid);
+ return l1 == null ? null : l1.find(type);
+ }
+ }
+
+ public void clear() {
+ synchronized (map) {
+ map.clear();
+ cleanUp();
+ }
+ }
+
+ // must only be called while synchronized on map:
+ 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:
+ String oid = l2.getOid();
+ Level1Entry l1 = getLevel1Entry(oid);
+ if (l1 != null && l1.get(l2.getType()) == l2) {
+ removeLevel2Entry(oid, l1, l2);
+ }
+ }
+ }
+
+ // must only be called while synchronized on map:
+ private Level1Entry getLevel1Entry(String oid) {
+ return (Level1Entry) map.get(oid);
+ }
+
+ // must only be called while synchronized on map:
+ private void removeLevel2Entry(String oid, Level1Entry l1,
+ Level2Entry l2) {
+ if (l1.remove(l2)) {
+ map.remove(oid);
+ }
+ }
+
+ private static final class Level1Entry {
+ // must only be called while synchronized on map:
+ public Level2Entry get(Type type) {
+ for (Iterator i = list.iterator(); i.hasNext();) {
+ Level2Entry l2 = (Level2Entry) i.next();
+ if (l2.getType().equals(type)) {
+ return l2;
+ }
+ }
+ return null;
+ }
+
+ // must only be called while synchronized on map:
+ 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:
+ for (Iterator i = list.iterator(); i.hasNext();) {
+ Level2Entry l2 = (Level2Entry) i.next();
+ if (l2.getType().equals(type)) {
+ Object o = l2.get();
+ if (o != null) {
+ return o;
+ }
+ }
+ }
+ for (Iterator i = list.iterator(); i.hasNext();) {
+ Level2Entry l2 = (Level2Entry) i.next();
+ if (type.isSupertypeOf(l2.getType())) {
+ Object o = l2.get();
+ if (o != null) {
+ return o;
+ }
+ }
+ }
+ return null;
+ }
+
+ // must only be called while synchronized on map:
+ public void add(Level2Entry l2) {
+ list.add(l2);
+ }
+
+ // must only be called while synchronized on map:
+ public boolean remove(Level2Entry l2) {
+ list.remove(l2);
+ return list.isEmpty();
+ }
+
+ private final LinkedList list = new LinkedList(); // of Level2Entry
+ }
+
+ private static final class Level2Entry extends WeakReference {
+ public Level2Entry(String oid, Type type, Object object,
+ ReferenceQueue queue) {
+ super(object, queue);
+ this.oid = oid;
+ this.type = type;
+ }
+
+ public String getOid() {
+ return oid;
+ }
+
+ public Type getType() {
+ return type;
+ }
+
+ // must only be called while synchronized on map:
+ public void acquire() {
+ ++count;
+ }
+
+ // must only be called while synchronized on map:
+ public boolean release() {
+ return --count == 0;
+ }
+
+ private final String oid;
+ private final Type type;
+ private int count = 1;
+ }
+
+ private final HashMap map = new HashMap();
+ // from OID (String) to 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..627aa5bafc27
--- /dev/null
+++ b/jurt/com/sun/star/lib/uno/environments/java/makefile.mk
@@ -0,0 +1,48 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.5 $
+#
+# 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..a6d03ca4bd11
--- /dev/null
+++ b/jurt/com/sun/star/lib/uno/environments/remote/IProtocol.java
@@ -0,0 +1,100 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: IProtocol.java,v $
+ * $Revision: 1.11 $
+ *
+ * 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..70668ed76ac2
--- /dev/null
+++ b/jurt/com/sun/star/lib/uno/environments/remote/IReceiver.java
@@ -0,0 +1,51 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: IReceiver.java,v $
+ * $Revision: 1.6 $
+ *
+ * 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..24865e369f85
--- /dev/null
+++ b/jurt/com/sun/star/lib/uno/environments/remote/IThreadPool.java
@@ -0,0 +1,130 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: IThreadPool.java,v $
+ * $Revision: 1.7 $
+ *
+ * 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..99d0773dad41
--- /dev/null
+++ b/jurt/com/sun/star/lib/uno/environments/remote/JavaThreadPool.java
@@ -0,0 +1,135 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: JavaThreadPool.java,v $
+ * $Revision: 1.13 $
+ *
+ * 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..57d60f77a7d7
--- /dev/null
+++ b/jurt/com/sun/star/lib/uno/environments/remote/JavaThreadPoolFactory.java
@@ -0,0 +1,97 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: JavaThreadPoolFactory.java,v $
+ * $Revision: 1.7 $
+ *
+ * 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..c625ca6b5317
--- /dev/null
+++ b/jurt/com/sun/star/lib/uno/environments/remote/Job.java
@@ -0,0 +1,183 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: Job.java,v $
+ * $Revision: 1.17 $
+ *
+ * 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..f09f8f48c72d
--- /dev/null
+++ b/jurt/com/sun/star/lib/uno/environments/remote/JobQueue.java
@@ -0,0 +1,399 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: JobQueue.java,v $
+ * $Revision: 1.19 $
+ *
+ * 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..6fee943a7dbc
--- /dev/null
+++ b/jurt/com/sun/star/lib/uno/environments/remote/Message.java
@@ -0,0 +1,198 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: Message.java,v $
+ * $Revision: 1.4 $
+ *
+ * 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..7c36a6a3decd
--- /dev/null
+++ b/jurt/com/sun/star/lib/uno/environments/remote/NativeThreadPool.java
@@ -0,0 +1,103 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: NativeThreadPool.java,v $
+ * $Revision: 1.5 $
+ *
+ * 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..2a19f3a0329b
--- /dev/null
+++ b/jurt/com/sun/star/lib/uno/environments/remote/ThreadId.java
@@ -0,0 +1,98 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: ThreadId.java,v $
+ * $Revision: 1.6 $
+ *
+ * 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..03789f42ee5a
--- /dev/null
+++ b/jurt/com/sun/star/lib/uno/environments/remote/ThreadPoolManager.java
@@ -0,0 +1,83 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: ThreadPoolManager.java,v $
+ * $Revision: 1.4 $
+ *
+ * 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..d2729c75ffcc
--- /dev/null
+++ b/jurt/com/sun/star/lib/uno/environments/remote/makefile.mk
@@ -0,0 +1,54 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.9 $
+#
+# 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..a807765e4701
--- /dev/null
+++ b/jurt/com/sun/star/lib/uno/environments/remote/remote_environment.java
@@ -0,0 +1,75 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: remote_environment.java,v $
+ * $Revision: 1.6 $
+ *
+ * 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..64d8703281df
--- /dev/null
+++ b/jurt/com/sun/star/lib/uno/makefile.mk
@@ -0,0 +1,41 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.5 $
+#
+# 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..3f3e801aeed5
--- /dev/null
+++ b/jurt/com/sun/star/lib/uno/protocols/urp/Cache.java
@@ -0,0 +1,123 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: Cache.java,v $
+ * $Revision: 1.4 $
+ *
+ * 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..0895903de75e
--- /dev/null
+++ b/jurt/com/sun/star/lib/uno/protocols/urp/Marshal.java
@@ -0,0 +1,393 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: Marshal.java,v $
+ * $Revision: 1.20.8.1 $
+ *
+ * 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..dea1d8c68845
--- /dev/null
+++ b/jurt/com/sun/star/lib/uno/protocols/urp/PendingRequests.java
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: PendingRequests.java,v $
+ * $Revision: 1.4 $
+ *
+ * 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..c05f549d4265
--- /dev/null
+++ b/jurt/com/sun/star/lib/uno/protocols/urp/Unmarshal.java
@@ -0,0 +1,493 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: Unmarshal.java,v $
+ * $Revision: 1.18 $
+ *
+ * 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..434f49349e1b
--- /dev/null
+++ b/jurt/com/sun/star/lib/uno/protocols/urp/UrpMessage.java
@@ -0,0 +1,57 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: UrpMessage.java,v $
+ * $Revision: 1.4 $
+ *
+ * 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..e0be9e61dec2
--- /dev/null
+++ b/jurt/com/sun/star/lib/uno/protocols/urp/makefile.mk
@@ -0,0 +1,48 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.6 $
+#
+# 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..05b8b2f8804c
--- /dev/null
+++ b/jurt/com/sun/star/lib/uno/protocols/urp/urp.java
@@ -0,0 +1,737 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: urp.java,v $
+ * $Revision: 1.18 $
+ *
+ * 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..d9895cf1b96f
--- /dev/null
+++ b/jurt/com/sun/star/lib/util/AsynchronousFinalizer.java
@@ -0,0 +1,105 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: AsynchronousFinalizer.java,v $
+ * $Revision: 1.3 $
+ *
+ * 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..9e05851673d3
--- /dev/null
+++ b/jurt/com/sun/star/lib/util/NativeLibraryLoader.java
@@ -0,0 +1,121 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: NativeLibraryLoader.java,v $
+ * $Revision: 1.10 $
+ *
+ * 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..9f545b2a0516
--- /dev/null
+++ b/jurt/com/sun/star/lib/util/StringHelper.java
@@ -0,0 +1,54 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: StringHelper.java,v $
+ * $Revision: 1.4 $
+ *
+ * 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..c2a93fc44a74
--- /dev/null
+++ b/jurt/com/sun/star/lib/util/UrlToFileMapper.java
@@ -0,0 +1,164 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: UrlToFileMapper.java,v $
+ * $Revision: 1.5 $
+ *
+ * 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..b417e83b4d01
--- /dev/null
+++ b/jurt/com/sun/star/lib/util/makefile.mk
@@ -0,0 +1,46 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.12 $
+#
+# 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..925c524a69cd
--- /dev/null
+++ b/jurt/com/sun/star/uno/Ascii.java
@@ -0,0 +1,53 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: Ascii.java,v $
+ * $Revision: 1.5 $
+ *
+ * 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..1b014742d793
--- /dev/null
+++ b/jurt/com/sun/star/uno/AsciiString.java
@@ -0,0 +1,54 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: AsciiString.java,v $
+ * $Revision: 1.5 $
+ *
+ * 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..d8880644e4ea
--- /dev/null
+++ b/jurt/com/sun/star/uno/MappingException.java
@@ -0,0 +1,73 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: MappingException.java,v $
+ * $Revision: 1.6 $
+ *
+ * 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..fc3b6f8100ba
--- /dev/null
+++ b/jurt/com/sun/star/uno/WeakReference.java
@@ -0,0 +1,150 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: WeakReference.java,v $
+ * $Revision: 1.3 $
+ *
+ * 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..13b81bf3ac31
--- /dev/null
+++ b/jurt/com/sun/star/uno/makefile.mk
@@ -0,0 +1,56 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.9 $
+#
+# 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