diff options
101 files changed, 8323 insertions, 0 deletions
diff --git a/framework/bundles/org.eclipse.ecf/.classpath b/framework/bundles/org.eclipse.ecf/.classpath new file mode 100644 index 000000000..065ac06e1 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/.classpath @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="src"/> + <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/framework/bundles/org.eclipse.ecf/.cvsignore b/framework/bundles/org.eclipse.ecf/.cvsignore new file mode 100644 index 000000000..ba077a403 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/.cvsignore @@ -0,0 +1 @@ +bin diff --git a/framework/bundles/org.eclipse.ecf/.group b/framework/bundles/org.eclipse.ecf/.group new file mode 100644 index 000000000..23bd714c5 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/.group @@ -0,0 +1,45 @@ +## Composent .group configuration file.
+## $groupid is the unique identifier for the collaboration group
+## associated with this project
+
+# Group ID. This is the group id of the collaboration group
+# associated with this project
+group=lU7TqVH67bHXmBpu4XMXtg--
+
+# Enabled flag. If this is set to false, no collab session will be started
+enabled=true
+
+# Appserver URL
+appserverurl=http://www.composent.com:8100/Makalu
+
+# uncomment following line load object classes from remote server
+repobjectcodebase=http://www.composent.com/code/composent/;http://www.composent.com/code/composent/bin/
+
+# Group Home Page
+grouphomepage=http://www.composent.com/
+
+# Group cache directory. Relative to project directory.
+groupcachedir=teamfiles
+
+# Group Blogger Account Types
+blogger.accounttypes=
+# Group Blogger Accounts
+blogger.accounts=
+# Group Blogger Passwords
+blogger.passwords=
+
+# Group Mailing List Account Types
+mailinglist.accounttypes=
+# Group Mailing List Accounts
+mailinglist.accounts=
+# Group Mailing List Passwords
+mailinglist.passwords=
+
+# Group IM Account Types
+im.accounttypes=
+# Group IM Accounts
+im.accounts=
+# Group IM Passwords
+im.passwords=
+
+## end .group file
diff --git a/framework/bundles/org.eclipse.ecf/.project b/framework/bundles/org.eclipse.ecf/.project new file mode 100644 index 000000000..a2d4a00a3 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/.project @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>org.eclipse.ecf</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ManifestBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.SchemaBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.pde.PluginNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + <nature>com.composent.client.collabnature</nature> +</natures> +</projectDescription> diff --git a/framework/bundles/org.eclipse.ecf/META-INF/MANIFEST.MF b/framework/bundles/org.eclipse.ecf/META-INF/MANIFEST.MF new file mode 100644 index 000000000..62e81e5c2 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/META-INF/MANIFEST.MF @@ -0,0 +1,16 @@ +Manifest-Version: 1.0 +Bundle-Name: Eclipse Communications Framework (ECF) +Bundle-SymbolicName: org.eclipse.ecf +Bundle-Version: 0.1.0 +Bundle-ClassPath: ecf.jar +Bundle-Activator: org.eclipse.ecf.internal.core.ECFPlugin +Bundle-Vendor: Eclipse.org +Bundle-Localization: plugin +Require-Bundle: org.eclipse.core.runtime +Eclipse-AutoStart: true +Provide-Package: org.eclipse.ecf.core, + org.eclipse.ecf.core.events, + org.eclipse.ecf.core.identity, + org.eclipse.ecf.core.identity.provider, + org.eclipse.ecf.core.provider, + org.eclipse.ecf.core.util diff --git a/framework/bundles/org.eclipse.ecf/build.properties b/framework/bundles/org.eclipse.ecf/build.properties new file mode 100644 index 000000000..308448314 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/build.properties @@ -0,0 +1,5 @@ +source.ecf.jar = src/ +output.ecf.jar = bin/ +bin.includes = plugin.xml,\ + META-INF/,\ + ecf.jar diff --git a/framework/bundles/org.eclipse.ecf/plugin.properties b/framework/bundles/org.eclipse.ecf/plugin.properties new file mode 100644 index 000000000..d4005ffba --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/plugin.properties @@ -0,0 +1,12 @@ +/**************************************************************************** +* Copyright (c) 2004 Composent, Inc. and others. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: +* Composent, Inc. - initial API and implementation +*****************************************************************************/ +ExtPoint.Provider=Eclipse.org + diff --git a/framework/bundles/org.eclipse.ecf/plugin.xml b/framework/bundles/org.eclipse.ecf/plugin.xml new file mode 100644 index 000000000..b3e456446 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/plugin.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?eclipse version="3.0"?> +<plugin> + <extension-point id="containerFactory" name="ECF Container Factory" schema="schema/containerFactory.exsd"/> + <extension-point id="namespace" name="ECF Namespace" schema="schema/namespace.exsd"/> +</plugin> diff --git a/framework/bundles/org.eclipse.ecf/schema/containerFactory.exsd b/framework/bundles/org.eclipse.ecf/schema/containerFactory.exsd new file mode 100644 index 000000000..c8adbf9bb --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/schema/containerFactory.exsd @@ -0,0 +1,162 @@ +<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.ecf">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.ecf" id="containerFactory" name="ECF Container Factory"/>
+ </appInfo>
+ <documentation>
+ This extension allows plugins to register themselves as 'providers' of ECF shared object containers. Once registered via this extension point, plugins can then provide implementations of custom ISharedObjectContainer instances via the ECF container factory (<b>org.eclipse.ecf.core.SharedObjectContainerFactory</b>). +<p>Plugins using this extension point can define a new implementation of any desired communications protocol, and expose that protocol as an instance of an <b>ISharedObjectContainer</b>. When client requests are made to ECF to create <b>ISharedObjectContainer</b> instances, then requests to create instances of the appropriate type will be re-directed to the given extension.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence>
+ <element ref="containerFactory" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="containerFactory">
+ <annotation>
+ <documentation>
+ The container factory extension point
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ The class implementing the containerFactory extension point. This class must implement the org.eclipse.ecf.core.provider.ISharedObjectContainerInstantiator interface.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+ An optional name for the extension. If no name is provided, the fully qualified class name is used as the name. Note that this name must <b>not</b> conflict with any other name in the ECF SharedObjectContainerFactory in order to be successfully registered. Care should therefore be taken in selection of a name such that it does not conflict with other implementations.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="description" type="string">
+ <annotation>
+ <documentation>
+ An optional description of the implementation of this extension point
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ 1.0.0
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ Here's an extension that associates a class org.eclipse.ecf.test.FooContainerFactory with name 'foo' in the ECF <b>SharedObjectContainerFactory</b>: + +<pre> +<extension point="org.eclipse.ecf.containerFactory"> + <containerFactory name="foo" class="org.eclipse.ecf.test.FooContainerFactory" description="My container factory"/> +</extension> +</pre> + +Here is some example code to implement this class: + +<pre> +package org.eclipse.ecf.test; + +import org.eclipse.ecf.core.ISharedObjectContainer; +import org.eclipse.ecf.core.SharedObjectContainerInstantiationException; +import org.eclipse.ecf.core.provider.ISharedObjectContainerInstantiator; + +public class FooContainerFactory implements ISharedObjectContainerInstantiator { + + public FooContainerFactory() { + super(); + } + public ISharedObjectContainer makeInstance(Class[] argTypes, Object[] args) + throws SharedObjectContainerInstantiationException { + // Create/return instance of FooSharedObjectContainer + // Note that FooSharedObjectContainer class must + // implement ISharedObjectContainer + return new FooSharedObjectContainer(); + } +} +</pre> + +In this example, the given class implements the <b>ISharedObjectContainerInstantiator</b>.makeInstance method by creating and returning a new instance of FooSharedObjectContainer, a class also defined in the extension plugin. As noted in the code, this class must implement <b>ISharedObjectContainer</b>, so that it can successfully be returned from makeInstance. + +<h3>Example Usage of Container by Clients</h3> + +Clients that wish to use the 'foo' container implementation can do so simply by making the following call to create an <b>ISharedObjectContainer</b>: + +<pre> +ISharedObjectContainer newContainer = SharedObjectContainerFactory.makeSharedObjectContainer('foo'); +// Further use of newContainer instance here + +</pre>
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ The API for this extension point is provided by the <b>org.eclipse.ecf.core.SharedObjectContainerFactory</b> static methods. Specifically, the 'makeSharedObjectContainer' static methods are to be used by clients. The functionality provided by the extension point mechanism can be used at runtime via the <b>SharedObjectContainerFactory.addDescription(SharedObjectContainerDescription)</b> method.
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ The supplied implementations of this extension point are:
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+ Copyright (c) 2004 Composent, Inc. and others. +All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0 which accompanies this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html. Contributors: Composent, Inc. - initial API and implementation
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/framework/bundles/org.eclipse.ecf/schema/namespace.exsd b/framework/bundles/org.eclipse.ecf/schema/namespace.exsd new file mode 100644 index 000000000..f516b062e --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/schema/namespace.exsd @@ -0,0 +1,192 @@ +<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.ecf">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.ecf" id="namespace" name="ECF Namespace"/>
+ </appInfo>
+ <documentation>
+ Extension point that allows other plugins to define new Namespaces for instantiating new types of identity. Plugins can register themselves as 'providers' for namespaces that they define, and will then be called when ECF clients use the <b>org.eclipse.ecf.core.identity.IDFactory.makeID</b> identity factory. +<p> +Plugins implementing this extension point must define an instantiatorClass that implements <b>org.eclipse.ecf.core.identity.provider.IDInstantiator</b>.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence>
+ <element ref="namespace" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="namespace">
+ <annotation>
+ <documentation>
+ Element allowing extension plugins to define new namespaces
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="instantiatorClass" type="string" use="required">
+ <annotation>
+ <documentation>
+ Required class name. <b>Must</b> implement <b>org.eclipse.identity.provider.IDInstantiator</b>
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+ Optional name for new namespace. If not provided, the name will be assumed to be the fully qualified name of the instantiatorClass. Note that this name must <b>not</b> conflict with any other namespace name in the ECF IDFactory in order to be successfully registered. Care should therefore be taken in selection of a name such that it does not conflict with other implementations.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="namespaceClass" type="string">
+ <annotation>
+ <documentation>
+ Optional class name of the Namespace class. Defaults to <b>org.eclipse.ecf.core.identity.Namespace</b>. Implementers may choose to create a subclass of the Namespace class, and can provide that class name here to use that class as the Namespace implementation. Note that the class, if provided, <b>must</b> extend <b>org.eclipse.ecf.core.identity.Namespace</b> and also must implement the two public constructors defined in the Namespace superclass.
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="description" type="string">
+ <annotation>
+ <documentation>
+ An optional description for the implementation of this extension point
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ 1.0.0
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ Here's an extension definition that associates an namespace instantiatorClass with namespace 'testid' in the ECF <b>org.eclipse.ecf.core.identity.IDFactory</b>: + +<pre> + <extension point="org.eclipse.ecf.namespace"> + <namespace name="testid" instantiatorClass="org.eclipse.ecf.test.FooIDInstantiator" description="my namespace implementation"/> + </extension> +</pre> + +Here is some example code to implement this FooIDInstantiator class: + +<pre> +package org.eclipse.ecf.test; + +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.core.identity.IDInstantiationException; +import org.eclipse.ecf.core.identity.Namespace; + +public class FooIDInstantiator implements + org.eclipse.ecf.core.identity.provider.IDInstantiator { + + public FooIDInstantiator() { + super(); + } + public ID makeInstance(Namespace ns, Class[] argTypes, Object[] args) + throws IDInstantiationException { + return new FooID(ns, (String) args[0]); + } +} +</pre> + +In this example, the given class implements the <b>IDInstantiator</b>.makeInstance method by creating and returning a new instance of FooID, a class also defined in the extension plugin. This class must implement <b>ID</b>, so that it can successfully be returned from makeInstance. + +<h3>Example Usage of IDFactory by Clients</h3> + +Clients that wish to use the 'testid' ID instantiator implementation can do so simply by making the following call to create an <b>IDFactory</b>: + +<pre> +ID newID = IDFactory.makeID('testid','email@emailserver.com'); +// Further use of newID instance here + +</pre>
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ The API for this extension point is provided by the <b>org.eclipse.ecf.core.IDFactory</b> static methods. Specifically, the 'makeID' static methods are to be used by clients. The functionality provided by the extension point mechanism can be used at runtime via the <b>IDFactory.addNamespace(Namespace)</b> method.
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ The following implementations of this extension point are provided by ECF itself: +<p> +StringID -- A namespace of ID instances that are implemented by <b>org.eclipse.ecf.core.identity.StringID</b> +<p>Clients may use this namespace with calls to: +<pre> +ID newID = org.eclipse.ecf.core.identity.IDFactory.makeStringID('idstringvalue'); +</pre> +</p> +</p> +<p> +LongID -- A namespace of ID instances that are implemented by <b>org.eclipse.ecf.core.identity.LongID</b> +<p>Clients may use this namespace with calls to: +<pre> +ID newID = org.eclipse.ecf.core.identity.IDFactory.makeLongID(2004L); +</pre> +</p> +</p> +<p> +GUID -- A namespace of ID instances that are implemented by <b>org.eclipse.ecf.core.identity.GUID</b> +<p>Clients may use this namespace with calls to: +<pre> +ID newID = org.eclipse.ecf.core.identity.IDFactory.makeGUID(16); +</pre> +</p> +</p>
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+ Copyright (c) 2004 Composent, Inc. and others. +All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0 which accompanies this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html. Contributors: Composent, Inc. - initial API and implementation
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/IIDentifiable.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/IIDentifiable.java new file mode 100644 index 000000000..178049341 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/IIDentifiable.java @@ -0,0 +1,8 @@ +package org.eclipse.ecf.core; + +import org.eclipse.ecf.core.identity.ID; + +public interface IIDentifiable { + + public ID getID(); +} diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/IOSGIService.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/IOSGIService.java new file mode 100644 index 000000000..6cd35c47d --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/IOSGIService.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core; + +import java.util.Dictionary; + +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceReference; +import org.osgi.framework.ServiceRegistration; + +/* + * Interface provided to ISharedObject instances via ISharedObjectContext + * + */ +public interface IOSGIService { + + // OSGI Service interfaces + public ServiceReference getServiceReference(String svc); + public Object getService(ServiceReference reference); + public ServiceReference[] getServiceReferences(String clazz, String filter) + throws InvalidSyntaxException; + public ServiceRegistration registerService(String[] clazzes, + Object service, Dictionary properties); + public ServiceRegistration registerService(String clazz, Object service, + Dictionary properties); + +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/ISharedObject.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/ISharedObject.java new file mode 100644 index 000000000..951169904 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/ISharedObject.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core; + +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.core.util.Event; + +public interface ISharedObject { + + /* + * Initialize this ISharedObject. The ISharedObjectContainer for this + * ISharedObject must call this method with a non-null instance of + * ISharedObjectConfig. ISharedObject implementations can use this + * initialization to perform any initialization necessary prior to receiving + * any events (via handleEvent/s). Note that the ISharedObjectContext + * provided via the ISharedObjectConfig.getSharedObjectContext() method is + * *not* guaranteed to allow any method calls until after this init() method + * call has completed. + * + * @param initData the initialization data passed by the + * ISharedObjectContainer upon initialization @exception + * SharedObjectInitException thrown by ISharedObject to halt initialization + * prematurely. ISharedObjectContainer may respond to such an exception by + * halt any further processing by ISharedObject + */ + public void init(ISharedObjectConfig initData) + throws SharedObjectInitException; + + /* + * Handle Event passed to this ISharedObject. The ISharedObjectContainer + * will pass events to all SharedObjects via this method and the + * handleEvents method. + * + * @param event the Event for the ISharedObject to process + */ + public void handleEvent(Event event); + + /* + * Handle Events passed to this ISharedObject. The ISharedObjectContainer + * will pass events to all SharedObjects via this method and the + * handleEvents method. + * + * @param event the Events [] for the ISharedObject to process + */ + public void handleEvents(Event[] events); + + /* + * Method called by the ISharedObjectContainer upon ISharedObject + * destruction. Once this method is called, no more Events will be passed to + * a ISharedObject until the init method is called again. + */ + public void dispose(ID containerID); + + /** + * Provide access to an adapter object. This method guarantees that any + * non-null object instance provided is an instance of the class provided as + * the first parameter. + * + * @param clazz + * the Class of the adapter. The returned Object instance must + * implement the given clazz + * @returns Object the adaptor object + */ + public Object getAdapter(Class clazz); +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/ISharedObjectConfig.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/ISharedObjectConfig.java new file mode 100644 index 000000000..95c9cef5f --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/ISharedObjectConfig.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core; + +import java.util.Map; + +import org.eclipse.ecf.core.identity.ID; + +public interface ISharedObjectConfig { + + /** + * Get the ID associated with this ISharedObject by its container. + * Containers must provide an implementation of this configuration that + * provides a non-null ID instance in response to this method call. + * + * @return ID that ISharedObject can use for imlementing its own + * ISharedObject.getID(). Cannot be null. + */ + public ID getSharedObjectID(); + /** + * Get the ID of the container that is the home of the primary copy of the + * ISharedObject instance. + * + * @return the ID of the container that is the home of the primary copy of + * the ISharedObject instance. Cannot be null. + */ + public ID getHomeContainerID(); + /** + * Get the ISharedObjectContext instance for this ISharedObject. The + * ISharedObjectContext provides access to container-provided services, + * including messaging to remote containers and to remote replicas of the + * ISharedObject, as well as access to OSGI-platform services. + * + * @return ISharedObjectContext for the ISharedObject to use to access + * container and OSGI platform-provided services. + */ + public ISharedObjectContext getContext(); + /** + * Get properties associated with with this ISharedObject + * + * @return Map with properties associated with this ISharedObject + * instance + */ + public Map getProperties(); +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/ISharedObjectConnector.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/ISharedObjectConnector.java new file mode 100644 index 000000000..7e9d6ab2b --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/ISharedObjectConnector.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core; + +import org.eclipse.ecf.core.events.SharedObjectEvent; +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.core.util.AsynchResult; +import org.eclipse.ecf.core.util.QueueException; + +public interface ISharedObjectConnector { + + public ID getSender(); + public ID[] getReceivers(); + public void enqueue(SharedObjectEvent event) throws QueueException; + public void enqueue(SharedObjectEvent[] events) throws QueueException; + public AsynchResult[] callAsynch(SharedObjectEvent arg) throws Exception; + public void dispose(); +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/ISharedObjectContainer.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/ISharedObjectContainer.java new file mode 100644 index 000000000..215e0d10d --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/ISharedObjectContainer.java @@ -0,0 +1,123 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core; + +import java.io.IOException; + +import org.eclipse.ecf.core.identity.ID; + +/* + * ISharedObjectContainer. The core interface that must be implemented by all + * instances of ISharedObjectContainer + */ +public interface ISharedObjectContainer { + + /** + * Return the ISharedObjectContainerConfig for this ISharedObjectContainer. + * The returned value must always be non-null. + * + * @return ISharedObjectContainerConfig for the given ISharedObjectContainer + * instance + */ + public ISharedObjectContainerConfig getConfig(); + /** + * Add listener to ISharedObjectContainer. Listener will be notified when + * container events occur + * + * @param l + * the ISharedObjectContainerListener to add + * @param filter + * the filter to define types of container events to receive + */ + public void addListener(ISharedObjectContainerListener l, String filter); + /** + * Remove listener from ISharedObjectContainer. + * + * @param l + * the ISharedObjectContainerListener to remove + */ + public void removeListener(ISharedObjectContainerListener l); + /** + * Dispose this ISharedObjectContainer instance. The container instance + * will be made inactive after the completion of this method and will be + * unavailable for subsequent usage + * + * @param waittime + */ + public void dispose(long waittime); + /** + * Join a container group. The group to join is identified by the first + * parameter (groupID) using any required authentication provided via the + * second parameter (loginData). This method provides an implementation + * independent way for container implementations to connect, authenticate, + * and communicate with a remote service or group of services. Providers are + * responsible for implementing this operation in a way appropriate to the + * given remote service and expected protocol. + * + * @param groupID + * the ID of the remote service to join + * @param loginData + * any required login/authentication data to allow this container + * to authenticate + * @exception IOException + * thrown if communication cannot be established with remote + * service + */ + public void joinGroup(ID groupID, Object loginData) + throws SharedObjectContainerJoinException; + /** + * Leave a container group. This operation will disconnect the local + * container instance from any previously joined group. + */ + public void leaveGroup(); + /** + * Get the group id that this container has joined. Return null if no group has + * previously been joined. + * + * @return ID of the group previously joined + */ + public ID getGroupID(); + /** + * Get the current membership of the joined group. This method will + * accurately report the current group membership of the connected group. + * + * @return ID[] the IDs of the current group membership + */ + public ID[] getGroupMembership(); + /** + * @return true if this ISharedObjectContainer instance is in the + * 'manager' role for the group, false otherwise + */ + public boolean isGroupManager(); + /** + * @return true if this ISharedObjectContainer instance is in a server + * role for the group, false otherwise + */ + public boolean isGroupServer(); + + /** + * Get SharedObjectManager for this container + * + * @return ISharedObjectManager for this container instance + */ + public ISharedObjectManager getSharedObjectManager(); + + /** + * Returns an object which is an instance of the given class associated with + * this object. + * + * @param adapter + * the adapter class to lookup + * @return Object a object castable to the given class, or null if this + * object does not have an adapter for the given class + */ + public Object getAdapter(Class adapter); + +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/ISharedObjectContainerConfig.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/ISharedObjectContainerConfig.java new file mode 100644 index 000000000..8aa7f6e73 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/ISharedObjectContainerConfig.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core; + +import java.util.Map; + +import org.eclipse.ecf.core.identity.ID; + +public interface ISharedObjectContainerConfig { + + /** + * The ID of the owner ISharedObjectContainer. Must be non-null, and the ID + * must be unique within the namespace of the relevant set of + * ISharedObjectContainer instances. + * + * @return ID the non-null ID instance that uniquely identifies the + * ISharedObjectContainer instance that uses this config. + */ + public ID getID(); + /** + * The properties associated with the owner ISharedObjectContainer + * + * @return Map the properties associated with owner + * ISharedObjectContainer + */ + public Map getProperties(); + /** + * Returns an object which is an instance of the given class associated with + * this object. + * + * @param adapter + * the adapter class to lookup + * @return Object a object castable to the given class, or null if this + * object does not have an adapter for the given class + */ + public Object getAdapter(Class clazz); +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/ISharedObjectContainerListener.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/ISharedObjectContainerListener.java new file mode 100644 index 000000000..19fe3846d --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/ISharedObjectContainerListener.java @@ -0,0 +1,16 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core; + +import org.eclipse.ecf.core.events.ContainerEvent; + +public interface ISharedObjectContainerListener { + public void handleEvent(ContainerEvent evt); +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/ISharedObjectContainerTransaction.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/ISharedObjectContainerTransaction.java new file mode 100644 index 000000000..b9496a433 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/ISharedObjectContainerTransaction.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core; + +public interface ISharedObjectContainerTransaction { + + public static final byte ACTIVE = 0; + public static final byte VOTING = 1; + public static final byte PREPARED = 2; + public static final byte COMMITTED = 3; + public static final byte ABORTED = 4; + + /** + * Method called to wait for a transaction to complete. + * + * @throws SharedObjectAddAbortException + */ + public void waitToCommit() throws SharedObjectAddAbortException; + /** + * Get state of transaction. Returns one of 'ACTIVE', 'VOTING', 'PREPARED', + * 'COMMITTED', or 'ABORTED'. + * + * @return byte code. Returns one of 'ACTIVE', 'VOTING', 'PREPARED', + * 'COMMITTED', or 'ABORTED'. + */ + public byte getTransactionState(); +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/ISharedObjectContext.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/ISharedObjectContext.java new file mode 100644 index 000000000..c41d41489 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/ISharedObjectContext.java @@ -0,0 +1,180 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core; + +import java.io.IOException; +import java.io.Serializable; + +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.core.util.QueueEnqueue; + +public interface ISharedObjectContext { + + /** + * Get the local container instance's ID + * + * @return the ID of the enclosing container + */ + public ID getContainerID(); + /** + * Get the ISharedObjectManager for this context + * @return + */ + public ISharedObjectManager getSharedObjectManager(); + /** + * Get the QueueEnqueue instance associated with this ISharedObject. If the + * given container provides a queue for this ISharedObject, this method will + * return a QueueEnqueue reference to the appropriate queue. + * + * @return QueueEnqueue instance if an active queue is associated with this + * ISharedObject. If no active queue is associated with the + * ISharedObject, returns null. + * + */ + public QueueEnqueue getQueue(); + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#joinGroup(org.eclipse.ecf.identity.ID, + * java.lang.Object) + */ + public Object joinGroup(ID groupID, Object loginData) + throws SharedObjectContainerJoinException; + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#leaveGroup() + */ + public Object leaveGroup(); + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#getGroupID() + */ + public ID getGroupID(); + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#isGroupManager() + */ + public boolean isGroupManager(); + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#isGroupServer() + */ + public boolean isGroupServer(); + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#getGroupMembership() + */ + public ID[] getGroupMembership(); + + /** + * Send message to create a remote instance of an ISharedObject with the + * same ID as this instance (ISharedObject.getID() returns same unique + * value). This method allows ISharedObject instances (with a reference to a + * valid ISharedObjectContext) to send messages to remote containers asking + * them to create an instance of a new ISharedObject. The given + * ISharedObjectDescription provides the specification of the new object. + * + * @param toContainerID + * the ID of the remote ISharedObjectContainer that is the target + * of the create request. If this parameter is null, the request + * is assumed to be made of <b>all </b> remote containers + * currently in the given group (excepting the local container). + * + * @param sd + * the SharedObjectDescription describing the class, constructor + * and other properties to be associated with the new instance + * + * @throws IOException + * thrown if message cannot be sent by container + */ + public void sendCreate(ID toContainerID, SharedObjectDescription sd) + throws IOException; + /** + * Send message to dispose of a remote instance of the ISharedObject with + * same ID as this instance (ISharedObject.getID() returns same unique + * value). This method allows ISharedObject instances to control the + * destruction of remote replicas. + * + * @param toContainerID + * the ID of the remote ISharedObjectContainer that is the target + * of the dispose request. If this parameter is null, the request + * is assumed to be made of <b>all </b> remote containers + * currently in the given group (excepting the local container). + * + * @throws IOException + * thrown if message cannot be sent by container + */ + public void sendDispose(ID toContainerID) throws IOException; + /** + * Send arbitrary message to remote instance of the ISharedObject with same + * ID as this instance (ISharedObject.getID() returns same unique value). + * This method allows ISharedObject instances to send arbitrary data to one + * or more remote replicas of this ISharedObject. + * + * @param toContainerID + * the ID of the remote ISharedObjectContainer that is the target + * container for the message request. If this parameter is null, + * the request is assumed to be made of <b>all </b> remote + * containers currently in the given group (excepting the local + * container). + * + * @throws IOException + * thrown if message cannot be sent by container + */ + public void sendMessage(ID toContainerID, byte[] data) throws IOException; + /** + * Send arbitrary message to remote instance of the ISharedObject with same + * ID as this instance (ISharedObject.getID() returns same unique value). + * This method allows ISharedObject instances to send arbitrary data to one + * or more remote replicas of this ISharedObject. + * + * @param toContainerID + * the ID of the remote ISharedObjectContainer that is the target + * container for the message request. If this parameter is null, + * the request is assumed to be made of <b>all </b> remote + * containers currently in the given group (excepting the local + * container). + * + * @throws IOException + * thrown if message cannot be sent by container, or if data + * cannot be serialized + */ + public void sendMessage(ID toContainerID, Serializable data) + throws IOException; + + /** + * Returns an object which is an instance of the given class associated with + * this object. + * + * @param adapter + * the adapter class to lookup + * @return Object a object castable to the given class, or null if this + * object does not have an adapter for the given class + */ + public Object getAdapter(Class clazz); + + /** + * Get a reference to a proxy instance that allows the registration and + * access to local OSGI-platform-provided services. If this method returns + * null, then such services are not available. + * + * @return null if OSGI platform services cannot be accessed, a valid + * instance of the given interface if the context allows access to + * such services + */ + public IOSGIService getServiceAccess(); +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/ISharedObjectManager.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/ISharedObjectManager.java new file mode 100644 index 000000000..fab40d3ee --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/ISharedObjectManager.java @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core; + +import java.util.List; +import java.util.Map; + +import org.eclipse.ecf.core.identity.ID; + +public interface ISharedObjectManager { + + /** + * Get the array of SharedObject instances currently contained by this + * ISharedObjectContainer + * + * @return ID[] the IDs of currently contained ISharedObject instances + */ + public ID[] getSharedObjectIDs(); + /** + * Create a new ISharedObject within this container from the given + * SharedObjectDescription. + * + * @param sd + * the SharedObjectDescription that describes the SharedObject to + * be created + * @param trans + * the transaction governing the creation of the shared object. + * If null, creation will not be transactional + * @return ID the sharedObjectID of the added ISharedObject + * @throws SharedObjectCreateException + * if the SharedObject cannot be created + */ + public ID createSharedObject(SharedObjectDescription sd, + ISharedObjectContainerTransaction trans) + throws SharedObjectCreateException; + /** + * Add an ISharedObject to this container. + * + * @param sharedObjectID + * the ID of new SharedObject + * @param sharedObject + * the ISharedObject instance to add + * @param properties + * the Map associated with the added ISharedObject + * @param trans + * the transaction governing the creation of the shared object. + * If null, creation will not be transactional + * @return ID the sharedObjectID of the added ISharedObject + * @throws SharedObjectAddException + * if the add cannot be accomplished for any reason + */ + public ID addSharedObject(ID sharedObjectID, ISharedObject sharedObject, + Map dict, ISharedObjectContainerTransaction trans) + throws SharedObjectAddException; + + /** + * Get the ISharedObject instance corresponding to the given sharedObjectID. + * + * @param sharedObjectID + * of the desired ISharedObject + * @return ISharedObject found. Return null if ISharedObject not found. + */ + public ISharedObject getSharedObject(ID sharedObjectID); + /** + * Remove the given sharedObjectID from this ISharedObjectContainer. + * + * @param sharedObjectID + * the ID of the ISharedObject to remove + * @return ISharedObject removed. Returns null if ISharedObject not found + */ + public ISharedObject removeSharedObject(ID sharedObjectID); + /** + * Create an ISharedObjectConnector instance for sending messages from a + * single ISharedObject to one or more receiver ISharedObjects. All + * specified ISharedObject instances must be contained by this + * ISharedObjectContainer. + * + * @param sharedObjectFrom + * the ID of the sender ISharedObject + * @param sharedObjectsTo + * the ID[] of the receiver ISharedObjects + * @return a valid instance of ISharedObjectConnector. Null if no connector + * can be made + * @throws SharedObjectConnectException + * thrown if specified sender or receivers do not exist within + * the context of this container + */ + public ISharedObjectConnector connectSharedObjects(ID sharedObjectFrom, + ID[] sharedObjectsTo) throws SharedObjectConnectException; + /** + * Destroy an ISharedObjectConnector instance. + * + * @param connector + * the connector previously created via connectSharedObjects + * @throws SharedObjectConnectException + * thrown if specified connector does not exist in the context + * of this container + */ + public void disconnectSharedObjects(ISharedObjectConnector connector) + throws SharedObjectDisconnectException; + + /** + * Get the sharedObjectConnectors associated with the given sharedObjectID + * + * @return List of ISharedObjectConnector instances + */ + public List getSharedObjectConnectors(ID sharedObjectFrom); +} diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/SharedObjectAddAbortException.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/SharedObjectAddAbortException.java new file mode 100644 index 000000000..deb7a1f16 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/SharedObjectAddAbortException.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core; + +public class SharedObjectAddAbortException extends SharedObjectAddException { + + protected long timeout = -1L; + + public SharedObjectAddAbortException() { + super(); + } + public SharedObjectAddAbortException(String arg0) { + super(arg0); + } + public SharedObjectAddAbortException(String msg, Throwable cause) { + super(msg, cause); + } + public SharedObjectAddAbortException(String msg, Throwable cause, + int timeout) { + super(msg, cause); + this.timeout = timeout; + } + public SharedObjectAddAbortException(Throwable cause) { + super(cause); + } + + public long getTimeout() { + return timeout; + } + +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/SharedObjectAddException.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/SharedObjectAddException.java new file mode 100644 index 000000000..0b190c4d2 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/SharedObjectAddException.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core; + +import org.eclipse.ecf.core.util.ECFException; + +public class SharedObjectAddException extends ECFException { + + public SharedObjectAddException() { + super(); + } + public SharedObjectAddException(String arg0) { + super(arg0); + } + public SharedObjectAddException(String msg, Throwable cause) { + super(msg, cause); + } + + public SharedObjectAddException(Throwable cause) { + super(cause); + } +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/SharedObjectConnectException.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/SharedObjectConnectException.java new file mode 100644 index 000000000..e4b95b368 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/SharedObjectConnectException.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core; + +import org.eclipse.ecf.core.util.ECFException; + +public class SharedObjectConnectException extends ECFException { + + public SharedObjectConnectException() { + super(); + } + + public SharedObjectConnectException(String arg0) { + super(arg0); + } + + public SharedObjectConnectException(String msg, Throwable cause) { + super(msg, cause); + } + + public SharedObjectConnectException(Throwable cause) { + super(cause); + } + +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/SharedObjectContainerDescription.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/SharedObjectContainerDescription.java new file mode 100644 index 000000000..5da30d18b --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/SharedObjectContainerDescription.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core; + +import org.eclipse.ecf.core.provider.ISharedObjectContainerInstantiator; + +public class SharedObjectContainerDescription { + + protected String name; + protected String instantiatorClass; + protected ClassLoader classLoader; + protected ISharedObjectContainerInstantiator instantiator; + protected String description; + + protected int hashCode = 0; + + public SharedObjectContainerDescription(ClassLoader loader, String name, + String instantiatorClass, String desc) { + this.classLoader = loader; + if (name == null) + throw new RuntimeException(new InstantiationException( + "sharedobjectcontainer description name cannot be null")); + this.name = name; + this.instantiatorClass = instantiatorClass; + this.hashCode = name.hashCode(); + this.description = desc; + } + public SharedObjectContainerDescription(String name, ISharedObjectContainerInstantiator inst, String desc) { + this.instantiator = inst; + this.name = name; + this.classLoader = this.instantiator.getClass().getClassLoader(); + this.description = desc; + } + public String getName() { + return name; + } + public ClassLoader getClassLoader() { + return classLoader; + } + public boolean equals(Object other) { + if (!(other instanceof SharedObjectContainerDescription)) + return false; + SharedObjectContainerDescription scd = (SharedObjectContainerDescription) other; + return scd.name.equals(name); + } + + public int hashCode() { + return hashCode; + } + + public String toString() { + StringBuffer b = new StringBuffer("SharedObjectContainerDescription["); + b.append(name).append(";"); + b.append(instantiatorClass).append("]"); + return b.toString(); + } + + protected ISharedObjectContainerInstantiator getInstantiator() + throws ClassNotFoundException, InstantiationException, + IllegalAccessException { + synchronized (this) { + if (instantiator == null) + initializeInstantiator(classLoader); + return instantiator; + } + } + + private void initializeInstantiator(ClassLoader cl) + throws ClassNotFoundException, InstantiationException, + IllegalAccessException { + if (cl == null) + cl = this.getClass().getClassLoader(); + // Load instantiator class + Class clazz = Class.forName(instantiatorClass, true, cl); + // Make new instance + instantiator = (ISharedObjectContainerInstantiator) clazz.newInstance(); + } + + /** + * @return Returns the description. + */ + public String getDescription() { + return description; + } +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/SharedObjectContainerFactory.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/SharedObjectContainerFactory.java new file mode 100644 index 000000000..2bc34381b --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/SharedObjectContainerFactory.java @@ -0,0 +1,281 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core; + +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.List; + +import org.eclipse.ecf.core.provider.ISharedObjectContainerInstantiator; +import org.eclipse.ecf.core.util.AbstractFactory; +import org.eclipse.ecf.internal.impl.standalone.StandaloneContainer; + +/* + * Factory class for creating ISharedObjectContainer instances. This is the + * top-level class for the org.eclipse.ecf 'asynch container' factory. The + * static methods on this class can be used to create ISharedObjectContainer and + * SharedObjectContainerGroup instances. + * + */ +public class SharedObjectContainerFactory { + + protected static final String DEFAULT_SHAREDOBJECT_CONTAINER = "standalone"; + protected static final String DEFAULT_SHAREDOBJECT_CONTAINER_INSTANTIATOR = StandaloneContainer.Creator.class + .getName(); + protected static final String DEFAULT_SHAREDOBJECT_CONTAINER_DESCRIPTION = "standalone container"; + + private static Hashtable containerdescriptions = new Hashtable(); + + static { + addDescription0(new SharedObjectContainerDescription(null, + DEFAULT_SHAREDOBJECT_CONTAINER, + DEFAULT_SHAREDOBJECT_CONTAINER_INSTANTIATOR, + DEFAULT_SHAREDOBJECT_CONTAINER_DESCRIPTION)); + } + /* + * Add a SharedObjectContainerDescription to the set of known + * SharedObjectContainerDescriptions. + * + * @param scd the SharedObjectContainerDescription to add to this factory + * @return SharedObjectContainerDescription the old description of the same + * name, null if none found + */ + public final static SharedObjectContainerDescription addDescription( + SharedObjectContainerDescription scd) { + return addDescription0(scd); + } + /** + * Get a collection of the SharedObjectContainerDescriptions currently known to + * this factory. This allows clients to query the factory to determine what if + * any other SharedObjectContainerDescriptions are currently registered with + * the factory, and if so, what they are. + * + * @return List of SharedObjectContainerDescription instances + */ + public final static List getDescriptions() { + return getDescriptions0(); + } + protected static List getDescriptions0() { + return new ArrayList(containerdescriptions.values()); + } + protected static SharedObjectContainerDescription addDescription0( + SharedObjectContainerDescription n) { + if (n == null) + return null; + return (SharedObjectContainerDescription) containerdescriptions.put(n + .getName(), n); + } + /** + * Check to see if a given named description is already contained by this + * factory + * + * @param scd + * the SharedObjectContainerDescription to look for + * @return true if description is already known to factory, false otherwise + */ + public final static boolean containsDescription( + SharedObjectContainerDescription scd) { + return containsDescription0(scd); + } + protected static boolean containsDescription0( + SharedObjectContainerDescription scd) { + if (scd == null) + return false; + return containerdescriptions.containsKey(scd.getName()); + } + protected static SharedObjectContainerDescription getDescription0( + SharedObjectContainerDescription scd) { + if (scd == null) + return null; + return (SharedObjectContainerDescription) containerdescriptions.get(scd + .getName()); + } + protected static SharedObjectContainerDescription getDescription0( + String name) { + if (name == null) + return null; + return (SharedObjectContainerDescription) containerdescriptions.get(name); + } + /** + * Get the known SharedObjectContainerDescription given it's name. + * + * @param name + * @return SharedObjectContainerDescription found + * @throws SharedObjectContainerInstantiationException + */ + public final static SharedObjectContainerDescription getDescriptionByName( + String name) throws SharedObjectContainerInstantiationException { + SharedObjectContainerDescription res = getDescription0(name); + if (res == null) { + throw new SharedObjectContainerInstantiationException( + "SharedObjectContainerDescription named '" + name + + "' not found"); + } + return res; + } + /** + * Make ISharedObjectContainer instance. Given a + * SharedObjectContainerDescription object, a String [] of argument types, + * and an Object [] of parameters, this method will + * <p> + * <ul> + * <li>lookup the known SharedObjectContainerDescriptions to find one of + * matching name</li> + * <li>if found, will retrieve or create an + * ISharedObjectContainerInstantiator for that description</li> + * <li>Call the ISharedObjectContainerInstantiator.makeInstance method to + * return an instance of ISharedObjectContainer</li> + * </ul> + * + * @param desc + * the SharedObjectContainerDescription to use to create the + * instance + * @param argTypes + * a String [] defining the types of the args parameter + * @param args + * an Object [] of arguments passed to the makeInstance method of + * the ISharedObjectContainerInstantiator + * @return a valid instance of ISharedObjectContainer + * @throws SharedObjectContainerInstantiationException + */ + public static ISharedObjectContainer makeSharedObjectContainer( + SharedObjectContainerDescription desc, String[] argTypes, + Object[] args) throws SharedObjectContainerInstantiationException { + if (desc == null) + throw new SharedObjectContainerInstantiationException( + "SharedObjectContainerDescription cannot be null"); + SharedObjectContainerDescription cd = getDescription0(desc); + if (cd == null) + throw new SharedObjectContainerInstantiationException( + "SharedObjectContainerDescription named '" + desc.getName() + + "' not found"); + Class clazzes[] = null; + ISharedObjectContainerInstantiator instantiator = null; + try { + instantiator = (ISharedObjectContainerInstantiator) cd + .getInstantiator(); + clazzes = AbstractFactory.getClassesForTypes(argTypes, args, cd.getClassLoader()); + } catch (Exception e) { + throw new SharedObjectContainerInstantiationException( + "Exception getting ISharedObjectContainerInstantiatior", e); + } + if (instantiator == null) + throw new SharedObjectContainerInstantiationException( + "Instantiator for SharedObjectContainerDescription " + + cd.getName() + " is null"); + // Ask instantiator to actually create instance + return (ISharedObjectContainer) instantiator + .makeInstance(clazzes, args); + } + /** + * Make ISharedObjectContainer instance. Given a + * SharedObjectContainerDescription name, this method will + * <p> + * <ul> + * <li>lookup the known SharedObjectContainerDescriptions to find one of + * matching name</li> + * <li>if found, will retrieve or create an + * ISharedObjectContainerInstantiator for that description</li> + * <li>Call the ISharedObjectContainerInstantiator.makeInstance method to + * return an instance of ISharedObjectContainer</li> + * </ul> + * + * @param desc + * the SharedObjectContainerDescription name to lookup + * @return a valid instance of ISharedObjectContainer + * @throws SharedObjectContainerInstantiationException + */ + public static ISharedObjectContainer makeSharedObjectContainer( + String descriptionName) + throws SharedObjectContainerInstantiationException { + return makeSharedObjectContainer( + getDescriptionByName(descriptionName), null, null); + } + /** + * Make ISharedObjectContainer instance. Given a + * SharedObjectContainerDescription name, this method will + * <p> + * <ul> + * <li>lookup the known SharedObjectContainerDescriptions to find one of + * matching name</li> + * <li>if found, will retrieve or create an + * ISharedObjectContainerInstantiator for that description</li> + * <li>Call the ISharedObjectContainerInstantiator.makeInstance method to + * return an instance of ISharedObjectContainer</li> + * </ul> + * + * @param desc + * the SharedObjectContainerDescription name to lookup + * @param args + * the Object [] of arguments passed to the + * ISharedObjectContainerInstantiator.makeInstance method + * @return a valid instance of ISharedObjectContainer + * @throws SharedObjectContainerInstantiationException + */ + public static ISharedObjectContainer makeSharedObjectContainer( + String descriptionName, Object[] args) + throws SharedObjectContainerInstantiationException { + return makeSharedObjectContainer( + getDescriptionByName(descriptionName), null, args); + } + /** + * Make ISharedObjectContainer instance. Given a + * SharedObjectContainerDescription name, this method will + * <p> + * <ul> + * <li>lookup the known SharedObjectContainerDescriptions to find one of + * matching name</li> + * <li>if found, will retrieve or create an + * ISharedObjectContainerInstantiator for that description</li> + * <li>Call the ISharedObjectContainerInstantiator.makeInstance method to + * return an instance of ISharedObjectContainer</li> + * </ul> + * + * @param desc + * the SharedObjectContainerDescription name to lookup + * @param argsTypes + * the String [] of argument types of the following args + * @param args + * the Object [] of arguments passed to the + * ISharedObjectContainerInstantiator.makeInstance method + * @return a valid instance of ISharedObjectContainer + * @throws SharedObjectContainerInstantiationException + */ + public static ISharedObjectContainer makeSharedObjectContainer( + String descriptionName, String[] argsTypes, Object[] args) + throws SharedObjectContainerInstantiationException { + return makeSharedObjectContainer( + getDescriptionByName(descriptionName), argsTypes, args); + } + /** + * Remove given description from set known to this factory. + * + * @param scd + * the SharedObjectContainerDescription to remove + * @return the removed SharedObjectContainerDescription, null if nothing + * removed + */ + public final static SharedObjectContainerDescription removeDescription( + SharedObjectContainerDescription scd) { + return removeDescription0(scd); + } + protected static SharedObjectContainerDescription removeDescription0( + SharedObjectContainerDescription n) { + if (n == null) + return null; + return (SharedObjectContainerDescription) containerdescriptions.remove(n + .getName()); + } + + private SharedObjectContainerFactory() { + // No instantiation other than as factory + } + +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/SharedObjectContainerInitException.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/SharedObjectContainerInitException.java new file mode 100644 index 000000000..45ea8fd9b --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/SharedObjectContainerInitException.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core; + +import org.eclipse.ecf.core.util.ECFException; + +public class SharedObjectContainerInitException extends ECFException { + + public SharedObjectContainerInitException() { + super(); + } + + public SharedObjectContainerInitException(String message) { + super(message); + } + + public SharedObjectContainerInitException(Throwable cause) { + super(cause); + } + + public SharedObjectContainerInitException(String message, Throwable cause) { + super(message, cause); + } + +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/SharedObjectContainerInstantiationException.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/SharedObjectContainerInstantiationException.java new file mode 100644 index 000000000..eb881f372 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/SharedObjectContainerInstantiationException.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core; + +import org.eclipse.ecf.core.util.ECFException; + +public class SharedObjectContainerInstantiationException extends ECFException { + + public SharedObjectContainerInstantiationException() { + super(); + } + + public SharedObjectContainerInstantiationException(String message) { + super(message); + } + + public SharedObjectContainerInstantiationException(Throwable cause) { + super(cause); + } + + public SharedObjectContainerInstantiationException(String message, + Throwable cause) { + super(message, cause); + } + +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/SharedObjectContainerJoinException.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/SharedObjectContainerJoinException.java new file mode 100644 index 000000000..e05b62289 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/SharedObjectContainerJoinException.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core; + +public class SharedObjectContainerJoinException extends Exception { + + public SharedObjectContainerJoinException() { + super(); + } + + /** + * @param message + */ + public SharedObjectContainerJoinException(String message) { + super(message); + } + + /** + * @param cause + */ + public SharedObjectContainerJoinException(Throwable cause) { + super(cause); + } + + /** + * @param message + * @param cause + */ + public SharedObjectContainerJoinException(String message, Throwable cause) { + super(message, cause); + } + +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/SharedObjectCreateException.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/SharedObjectCreateException.java new file mode 100644 index 000000000..a85e7b8ba --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/SharedObjectCreateException.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core; + +import org.eclipse.ecf.core.util.ECFException; + +public class SharedObjectCreateException extends ECFException { + + public SharedObjectCreateException() { + super(); + } + public SharedObjectCreateException(String arg0) { + super(arg0); + } + public SharedObjectCreateException(String msg, Throwable cause) { + super(msg, cause); + } + + public SharedObjectCreateException(Throwable cause) { + super(cause); + } +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/SharedObjectDescription.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/SharedObjectDescription.java new file mode 100644 index 000000000..eca9407c1 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/SharedObjectDescription.java @@ -0,0 +1,97 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core; + +import java.io.Serializable; +import java.util.Hashtable; +import java.util.Map; + +import org.eclipse.ecf.core.identity.ID; + +public class SharedObjectDescription implements Serializable { + + protected static long staticID = 0; + + protected transient ClassLoader classLoader; + protected ID id; + protected ID homeid; + protected String className; + protected Map properties; + protected long identifier; + + public static long getNextUniqueIdentifier() { + return staticID++; + } + public SharedObjectDescription(ClassLoader loader, ID objectID, ID homeID, + String className, Map dict, long ident) { + this.classLoader = loader; + this.id = objectID; + this.homeid = homeID; + this.className = className; + if (dict != null) this.properties = dict; + else this.properties = new Hashtable(); + this.identifier = ident; + } + + public SharedObjectDescription(ClassLoader loader, ID id, String className, Map dict, long ident) { + this(loader, id, null, className, dict, ident); + } + public SharedObjectDescription(ClassLoader loader, ID id, String className, Map dict) { + this(loader, id, null, className, dict, getNextUniqueIdentifier()); + } + public SharedObjectDescription(ClassLoader loader, ID id, String className) { + this(loader, id, null, className, null, getNextUniqueIdentifier()); + } + public SharedObjectDescription(ID id, String className, Map dict, long ident) { + this(null, id, null, className, dict, ident); + } + public SharedObjectDescription(ID id, String className, Map dict) { + this(null, id, null, className, dict, getNextUniqueIdentifier()); + } + public SharedObjectDescription(ID id, String className, long ident) { + this(null, id, null, className, null, ident); + } + public SharedObjectDescription(ID id, String className) { + this(id, className, getNextUniqueIdentifier()); + } + public ID getID() { + return id; + } + public void setID(ID theID) { + this.id = theID; + } + public ID getHomeID() { + return homeid; + } + public void setHomeID(ID theID) { + this.homeid = theID; + } + public String getClassname() { + return className; + } + public void setClassname(String theName) { + this.className = theName; + } + public Map getProperties() { + return properties; + } + public void getProperties(Map props) { + this.properties = props; + } + public ClassLoader getClassLoader() { + return classLoader; + } + public long getIdentifier() { + return identifier; + } + public void setIdentifier(long identifier) { + this.identifier = identifier; + } +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/SharedObjectDisconnectException.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/SharedObjectDisconnectException.java new file mode 100644 index 000000000..f7b9e0536 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/SharedObjectDisconnectException.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core; + +import org.eclipse.ecf.core.util.ECFException; + +public class SharedObjectDisconnectException extends ECFException { + + public SharedObjectDisconnectException() { + super(); + } + + public SharedObjectDisconnectException(String arg0) { + super(arg0); + } + + public SharedObjectDisconnectException(String msg, Throwable cause) { + super(msg, cause); + } + + public SharedObjectDisconnectException(Throwable cause) { + super(cause); + } + +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/SharedObjectInitException.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/SharedObjectInitException.java new file mode 100644 index 000000000..3990cbc17 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/SharedObjectInitException.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core; + +import org.eclipse.ecf.core.util.ECFException; + +public class SharedObjectInitException extends ECFException { + + public SharedObjectInitException() { + super(); + } + + public SharedObjectInitException(String arg0) { + super(arg0); + } + + public SharedObjectInitException(String msg, Throwable cause) { + super(msg, cause); + } + + public SharedObjectInitException(Throwable cause) { + super(cause); + } + +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/SharedObjectNotFoundException.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/SharedObjectNotFoundException.java new file mode 100644 index 000000000..a7c4178aa --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/SharedObjectNotFoundException.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core; + +import org.eclipse.ecf.core.util.ECFException; + +public class SharedObjectNotFoundException extends ECFException { + + public SharedObjectNotFoundException() { + super(); + } + + public SharedObjectNotFoundException(String arg0) { + super(arg0); + } + + public SharedObjectNotFoundException(String msg, Throwable cause) { + super(msg, cause); + } + + public SharedObjectNotFoundException(Throwable cause) { + super(cause); + } + +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/events/ContainerEvent.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/events/ContainerEvent.java new file mode 100644 index 000000000..4ce57b457 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/events/ContainerEvent.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core.events; + +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.core.util.Event; + +public interface ContainerEvent extends Event { + + public ID getContainerID(); +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/events/LocalSharedObjectEvent.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/events/LocalSharedObjectEvent.java new file mode 100644 index 000000000..d241360ee --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/events/LocalSharedObjectEvent.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ +package org.eclipse.ecf.core.events; + +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.core.util.Event; + +public class LocalSharedObjectEvent implements SharedObjectEvent { + + ID sender; + Event event; + + public LocalSharedObjectEvent(ID s, Event evt) { + super(); + this.sender = s; + this.event = evt; + } + + public ID getSenderSharedObjectID() { + return sender; + } + public Event getEvent() { + return event; + } + + public String toString() { + StringBuffer sb = new StringBuffer("LocalSharedObjectEvent[sender:"); + if (sender != null) + sb.append(sender.getName()).append(","); + else + sb.append("null,"); + sb.append("event:").append(event).append("]"); + return sb.toString(); + } +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/events/RemoteSharedObjectEvent.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/events/RemoteSharedObjectEvent.java new file mode 100644 index 000000000..9ab2b7a3a --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/events/RemoteSharedObjectEvent.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core.events; + +import java.io.Serializable; + +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.core.util.Event; + +public class RemoteSharedObjectEvent implements SharedObjectEvent, Serializable { + + ID senderSharedObjectID; + ID containerID; + Serializable data; + + public RemoteSharedObjectEvent(ID sender, ID cont, Serializable data) { + super(); + this.senderSharedObjectID = sender; + this.containerID = cont; + } + + public ID getContainer() { + return containerID; + } + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.api.events.SharedObjectEvent#getSenderSharedObject() + */ + public ID getSenderSharedObjectID() { + return senderSharedObjectID; + } + public Event getEvent() { + return this; + } + public Serializable getData() { + return data; + } + + public String toString() { + StringBuffer sb = new StringBuffer("RemoteSharedObjectEvent[sender:"); + if (senderSharedObjectID != null) + sb.append(senderSharedObjectID.getName()).append(","); + else + sb.append("null,"); + sb.append("container:"); + if (containerID != null) + sb.append(containerID.getName()).append(","); + sb.append("data:"); + sb.append(data).append("]"); + return sb.toString(); + } +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/events/SharedObjectActivatedEvent.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/events/SharedObjectActivatedEvent.java new file mode 100644 index 000000000..535e83127 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/events/SharedObjectActivatedEvent.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core.events; + +import org.eclipse.ecf.core.identity.ID; + +public class SharedObjectActivatedEvent implements ContainerEvent { + + ID activated; + ID[] members; + ID containerID; + + public SharedObjectActivatedEvent(ID container, ID act, ID[] others) { + super(); + this.containerID = container; + this.activated = act; + this.members = others; + } + + public ID getActivated() { + return activated; + } + + public ID getContainerID() { + return containerID; + } + public ID[] getMembers() { + return members; + } + + public String toString() { + StringBuffer sb = new StringBuffer( + "SharedObjectActivatedEvent[activated:"); + if (activated != null) + sb.append(activated.getName()).append(","); + else + sb.append("null,"); + sb.append("["); + for (int i = 0; i < members.length; i++) { + sb.append(members[i].getName()); + if (i < members.length - 1) + sb.append(","); + } + sb.append("]]"); + return sb.toString(); + } +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/events/SharedObjectContainerDepartedEvent.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/events/SharedObjectContainerDepartedEvent.java new file mode 100644 index 000000000..2d5a2fa8e --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/events/SharedObjectContainerDepartedEvent.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core.events; + +import org.eclipse.ecf.core.identity.ID; + +public class SharedObjectContainerDepartedEvent implements ContainerEvent { + + ID other; + ID containerID; + + public SharedObjectContainerDepartedEvent(ID container, ID o) { + super(); + this.containerID = container; + this.other = o; + } + + public ID getDepartedContainer() { + return other; + } + public ID getContainerID() { + return containerID; + } +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/events/SharedObjectContainerEjectedEvent.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/events/SharedObjectContainerEjectedEvent.java new file mode 100644 index 000000000..aa9ba0a75 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/events/SharedObjectContainerEjectedEvent.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core.events; + +import java.io.Serializable; + +import org.eclipse.ecf.core.identity.ID; + +public class SharedObjectContainerEjectedEvent implements ContainerEvent { + + ID containerID = null; + ID groupManagerID = null; + + Serializable data = null; + + public SharedObjectContainerEjectedEvent(ID containerID, ID groupManagerID, + Serializable data) { + this.containerID = containerID; + this.groupManagerID = groupManagerID; + this.data = data; + } + public ID getContainerID() { + return containerID; + } + + public ID getGroupManager() { + return groupManagerID; + } + public Serializable getData() { + return data; + } + +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/events/SharedObjectContainerJoinEvent.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/events/SharedObjectContainerJoinEvent.java new file mode 100644 index 000000000..68b72b1f8 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/events/SharedObjectContainerJoinEvent.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core.events; + +import org.eclipse.ecf.core.identity.ID; + +public class SharedObjectContainerJoinEvent implements ContainerEvent { + + ID other; + ID containerID; + + public SharedObjectContainerJoinEvent(ID container, ID o) { + super(); + this.containerID = container; + this.other = o; + } + + public ID getOtherContainerID() { + return other; + } + + public ID getContainerID() { + return containerID; + } +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/events/SharedObjectContainerLeaveEvent.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/events/SharedObjectContainerLeaveEvent.java new file mode 100644 index 000000000..2d3c6faa8 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/events/SharedObjectContainerLeaveEvent.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core.events; + +import java.io.Serializable; + +import org.eclipse.ecf.core.identity.ID; + +public class SharedObjectContainerLeaveEvent implements ContainerEvent { + + ID containerID = null; + ID groupManagerID = null; + + Serializable data = null; + + public SharedObjectContainerLeaveEvent(ID containerID, ID groupManagerID) { + this.containerID = containerID; + this.groupManagerID = groupManagerID; + } + public ID getContainerID() { + return containerID; + } + + public ID getGroupManager() { + return groupManagerID; + } + public void setData(Serializable data) { + this.data = data; + } + +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/events/SharedObjectDeactivatedEvent.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/events/SharedObjectDeactivatedEvent.java new file mode 100644 index 000000000..09839ea8c --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/events/SharedObjectDeactivatedEvent.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core.events; + +import org.eclipse.ecf.core.identity.ID; + +public class SharedObjectDeactivatedEvent implements ContainerEvent { + + ID deactivated; + ID containerID; + + public SharedObjectDeactivatedEvent(ID container, ID deact) { + super(); + this.containerID = container; + this.deactivated = deact; + } + public ID getDeactivated() { + return deactivated; + } + public ID getContainerID() { + return containerID; + } + public String toString() { + StringBuffer sb = new StringBuffer( + "SharedObjectDeactivatedEvent[deactivated:"); + if (deactivated != null) + sb.append(deactivated.getName()); + else + sb.append("null"); + sb.append("]"); + return sb.toString(); + } +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/events/SharedObjectEvent.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/events/SharedObjectEvent.java new file mode 100644 index 000000000..8c0fee4b8 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/events/SharedObjectEvent.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core.events; + +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.core.util.Event; + +public interface SharedObjectEvent extends Event { + + public ID getSenderSharedObjectID(); + + public Event getEvent(); + +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/identity/BaseID.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/identity/BaseID.java new file mode 100644 index 000000000..8585bdec2 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/identity/BaseID.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core.identity; + +import java.net.URI; +import java.net.URISyntaxException; + +public abstract class BaseID implements ID { + + /** + * + * @uml.property name="namespace" + * @uml.associationEnd + * @uml.property name="namespace" multiplicity="(1 1)" + */ + Namespace namespace; + + protected BaseID(Namespace namespace) { + if (namespace == null) + throw new RuntimeException(new InstantiationException( + "namespace cannot be null")); + this.namespace = namespace; + } + + public int compareTo(Object o) { + if (o == null || !(o instanceof BaseID)) + throw new ClassCastException("incompatible types for compare"); + return namespace.getCompareToForObject(this, (BaseID) o); + } + public boolean equals(Object o) { + if (o == null) + return false; + if (!(o instanceof BaseID)) { + return false; + } + return namespace.testIDEquals(this, (BaseID) o); + } + public String getName() { + return namespace.getNameForID(this); + } + + /** + * + * @uml.property name="namespace" + */ + public Namespace getNamespace() { + return namespace; + } + + public int hashCode() { + return namespace.getHashCodeForID(this); + } + protected abstract int namespaceCompareTo(BaseID o); + protected abstract boolean namespaceEquals(BaseID o); + protected abstract String namespaceGetName(); + protected abstract int namespaceHashCode(); + protected abstract URI namespaceToURI() throws URISyntaxException; + public URI toURI() throws URISyntaxException { + return namespace.getURIForID(this); + } +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/identity/GUID.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/identity/GUID.java new file mode 100644 index 000000000..3eac78297 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/identity/GUID.java @@ -0,0 +1,131 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core.identity; + +import java.security.SecureRandom; + +import org.eclipse.ecf.core.identity.provider.IDInstantiator; +import org.eclipse.ecf.core.util.Base64; + +/** + * Globally unique ID class. + * + */ +public class GUID extends StringID { + + public static class Creator implements IDInstantiator { + public ID makeInstance(Namespace ns, Class[] argTypes, Object[] args) + throws IDInstantiationException { + if (args.length == 1) return new GUID(ns, ((Integer) args[0]).intValue()); + else return new GUID(ns); + } + } + + public static final String SR_DEFAULT_ALGO = "SHA1PRNG"; + public static final String SR_DEFAULT_PROVIDER = null; + public static final int DEFAULT_BYTE_LENGTH = 20; + + public static final String GUID_NAME = GUID.class.getName(); + public static final String GUID_INSTANTIATOR_CLASS = GUID.Creator.class + .getName(); + + // Class specific SecureRandom instance + protected static transient SecureRandom random; + + /** + * Protected constructor for factory-based construction + * + * @param n + * the Namespace this identity will belong to + * @param s + * the String defining this StringID + */ + protected GUID(Namespace n, String algo, String provider, int byteLength) + throws IDInstantiationException { + super(n, ""); + // Get SecureRandom instance for class + SecureRandom r = null; + try { + r = getRandom(algo, provider); + } catch (Exception e) { + throw new IDInstantiationException("GUID creation failure: " + + e.getMessage()); + } + // make sure we have reasonable byteLength + if (byteLength <= 0) + byteLength = 1; + byte[] newBytes = new byte[byteLength]; + // Fill up random bytes + random.nextBytes(newBytes); + // Set value + value = Base64.encode(newBytes); + } + + protected GUID(Namespace n, int byteLength) throws IDInstantiationException { + this(n, SR_DEFAULT_ALGO, SR_DEFAULT_PROVIDER, byteLength); + } + + protected GUID(Namespace n) throws IDInstantiationException { + this(n, DEFAULT_BYTE_LENGTH); + } + + /** + * Get SecureRandom instance for creation of random number. + * + * @param algo + * the String algorithm specification (e.g. "SHA1PRNG") for + * creation of the SecureRandom instance + * @param provider + * the provider of the implementation of the given algorighm + * (e.g. "SUN") + * @return SecureRandom + * @exception Exception + * thrown if SecureRandom instance cannot be created/accessed + */ + protected static synchronized SecureRandom getRandom(String algo, + String provider) throws Exception { + // Given algo and provider, get SecureRandom instance + if (random == null) { + initializeRandom(algo, provider); + } + return random; + } + + protected static synchronized void initializeRandom(String algo, + String provider) throws Exception { + random = provider == null ? SecureRandom.getInstance(algo) + : SecureRandom.getInstance(algo, provider); + } + + public String toString() { + if (value == null) + return ""; + int strlen = value.length(); + StringBuffer sb = new StringBuffer(strlen + 10); + String packname = this.getClass().getPackage().getName(); + int pnLength = packname.length(); + sb.insert(0, packname + ".GUID[").insert(pnLength + 6, value).insert( + strlen + pnLength + 6, ']'); + return sb.toString(); + } + + // Test code + public static final void main(String[] args) throws Exception { + System.out.println("Testing creation of GUID instance"); + System.out.println("Calling initializeRandom() for the first time..."); + initializeRandom(SR_DEFAULT_ALGO, SR_DEFAULT_PROVIDER); + System.out + .println("This will take a long time because of the SecureRandom seed process"); + GUID myGUID = new GUID(null, 24); + System.out.println("Created GUID: " + myGUID); + GUID myGUID2 = new GUID(null); + System.out.println("Created second GUID: " + myGUID2); + } +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/identity/ID.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/identity/ID.java new file mode 100644 index 000000000..363d81c05 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/identity/ID.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core.identity; + +import java.net.URI; +import java.net.URISyntaxException; + +/** + * Contract for ECF identity. + * <p> + * The contract defined by this interface is similar-to, but stronger than that + * implied by Object.equals() and Object.hashCode. + * <p> + * Any classes implementing this interface must provide instances that are + * unique within the namespace returned by getNamespace(), rather than unique + * just within the JVM that currently contains the object instance. + * <p> + * So, for example, if there are two instances of an email Namespace, equals + * should return true if the email addresses are the same, and false if they are + * not the same. + * <p> + * Typically, Namespaces are registered with the IDFactory class (via + * addNamespace) in order to allow the custom creation of instances that + * implement this interface. + * + * @author Scott B. Lewis, slewis@composent.com + */ + +public interface ID extends java.io.Serializable, java.lang.Comparable, + java.security.Principal { + + public boolean equals(Object obj); + + /** + * Get the unique name of this identity. + * + * @return String unique name for this identity + * + * @uml.property name="name" + */ + public String getName(); + + /** + * Get the Namespace instance associated with this identity + * + * @return Namespace the Namespace corresponding to this identity + * + * @uml.property name="namespace" + * @uml.associationEnd + * @uml.property name="namespace" multiplicity="(0 1)" + */ + public Namespace getNamespace(); + + public int hashCode(); + /** + * If available, return this identity in URI form. If not available, throw + * URISyntaxException + * + * @return URI the URI representation of this identity + */ + public URI toURI() throws URISyntaxException; +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/identity/IDFactory.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/identity/IDFactory.java new file mode 100644 index 000000000..f1a8e53dd --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/identity/IDFactory.java @@ -0,0 +1,289 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core.identity; + +import java.security.AccessController; +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.List; + +import org.eclipse.ecf.core.identity.provider.IDInstantiator; +import org.eclipse.ecf.core.util.AbstractFactory; + +/** + * A factory class for creating ID instances. This is the factory for plugins to + * manufacture ID instances. + * + */ +public class IDFactory { + + public static final String SECURITY_PROPERTY = IDFactory.class.getName() + + ".security"; + + private static Hashtable namespaces = new Hashtable(); + private static boolean securityEnabled = false; + + static { + addNamespace0(new Namespace(IDFactory.class.getClassLoader(), + StringID.STRINGID_NAME, StringID.STRINGID_INSTANTIATOR_CLASS, + null)); + addNamespace0(new Namespace(IDFactory.class.getClassLoader(), + GUID.GUID_NAME, GUID.GUID_INSTANTIATOR_CLASS, null)); + addNamespace0(new Namespace(IDFactory.class.getClassLoader(), + LongID.LONGID_NAME, LongID.LONGID_INSTANTIATOR_CLASS, null)); + try { + securityEnabled = (System.getProperty(SECURITY_PROPERTY) != null); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * Add the given Namespace to our table of available Namespaces + * + * @param n + * the Namespace to add + * @return Namespace the namespace already in table (null if Namespace not + * previously in table) + * @exception SecurityException + * thrown if caller does not have appropriate + * NamespacePermission for given namespace + */ + public final static Namespace addNamespace(Namespace n) + throws SecurityException { + if (n == null) + return null; + checkPermission(new NamespacePermission(n.getPermissionName(), + NamespacePermission.ADD_NAMESPACE)); + return addNamespace0(n); + } + + protected final static Namespace addNamespace0(Namespace n) { + if (n == null) + return null; + return (Namespace) namespaces.put(n.getName(), n); + } + + protected final static void checkPermission(NamespacePermission p) + throws SecurityException { + if (securityEnabled) + AccessController.checkPermission(p); + } + /** + * Check whether table contains given Namespace instance + * + * @param n + * the Namespace to look for + * @return true if table does contain given Namespace, false otherwise + * @exception SecurityException + * thrown if caller does not have appropriate + * NamespacePermission for given namespace + */ + public final static boolean containsNamespace(Namespace n) + throws SecurityException { + if (n == null) + return false; + checkPermission(new NamespacePermission(n.getPermissionName(), + NamespacePermission.CONTAINS_NAMESPACE)); + return containsNamespace0(n); + } + public final static List getNamespaces() { + return new ArrayList(namespaces.values()); + } + protected final static boolean containsNamespace0(Namespace n) { + if (n == null) + return false; + return namespaces.containsKey(n.getName()); + } + /** + * Get the given Namespace instance from table + * + * @param n + * the Namespace to look for + * @return Namespace + * @exception SecurityException + * thrown if caller does not have appropriate + * NamespacePermission for given namespace + */ + public final static Namespace getNamespace(Namespace n) + throws SecurityException { + if (n == null) + return null; + checkPermission(new NamespacePermission(n.getPermissionName(), + NamespacePermission.GET_NAMESPACE)); + return getNamespace0(n); + } + + public final static Namespace getNamespaceByName(String name) + throws SecurityException { + Namespace ns = new Namespace(null, name, null, null); + return getNamespace(ns); + } + + protected final static Namespace getNamespace0(Namespace n) { + if (n == null) + return null; + return (Namespace) namespaces.get(n.getName()); + } + + public static final ID makeGUID() throws IDInstantiationException { + return makeGUID(GUID.DEFAULT_BYTE_LENGTH); + } + + public static final ID makeGUID(int length) throws IDInstantiationException { + Namespace n = new Namespace(GUID.class.getClassLoader(), + GUID.GUID_NAME, GUID.GUID_INSTANTIATOR_CLASS, null); + return makeID(n, new String[] { Namespace.class.getName(), + Integer.class.getName() }, new Object[] { n, + new Integer(length) }); + } + + protected static void log(String s) { + // XXX TODO + } + + protected static void logException(String s, Throwable t) { + // XXX TODO + } + + protected static void logAndThrow(String s, Throwable t) + throws IDInstantiationException { + IDInstantiationException e = new IDInstantiationException(s, t); + logException(s, t); + throw e; + } + protected static void logAndThrow(String s) throws IDInstantiationException { + IDInstantiationException e = new IDInstantiationException(s); + logException(s, null); + throw e; + } + /** + * Make a new identity. Given a classloader, Namespace, constructor argument + * types, and an array of arguments, return a new instance of an ID + * belonging to the given Namespace + * + * @param n + * the Namespace to which the ID will belong + * @param argTypes + * a String [] of the arg types for the ID instance constructor + * @param args + * an Object [] of the args for the ID instance constructor + * @exception Exception + * thrown if class for instantiator or instance can't be + * loaded, if something goes wrong during instance + * construction or if instance cannot be created + */ + public static final ID makeID(Namespace n, String[] argTypes, Object[] args) + throws IDInstantiationException { + // Verify namespace is non-null + if (n == null) + logAndThrow("Namespace cannot be null"); + log("makeID(" + n.getName() + ")"); + // Make sure that namespace is in table of known namespace. If not, + // throw...we don't create any instances that we don't know about! + Namespace ns = getNamespace0(n); + if (ns == null) + logAndThrow("Namespace '" + n.getName() + "' not found"); + // We're OK, go ahead and setup array of classes for call to + // instantiator + Class clazzes[] = null; + ClassLoader cl = ns.getClass().getClassLoader(); + try { + clazzes = AbstractFactory.getClassesForTypes(argTypes, args, cl); + } catch (ClassNotFoundException e) { + logAndThrow("Exception in getClassesForTypes", e); + } + // Get actual instantiator from namespace + IDInstantiator instantiator = null; + try { + instantiator = (IDInstantiator) ns.getInstantiator(); + } catch (Exception e) { + logAndThrow("Exception in getInstantiator", e); + } + if (instantiator == null) + throw new IDInstantiationException("Instantiator for namespace '" + + n.getName() + "' is null"); + // Ask instantiator to actually create instance + return instantiator.makeInstance(ns, clazzes, args); + } + public static final ID makeID(String namespacename, String[] argTypes, + Object[] args) throws IDInstantiationException { + return makeID(getNamespaceByName(namespacename), argTypes, args); + } + /** + * Make a new identity. Given a Namespace, and an array of instance + * constructor arguments, return a new instance of an ID belonging to the + * given Namespace + * + * @param n + * the Namespace to which the ID will belong + * @param args + * an Object [] of the args for the ID instance constructor + * @exception Exception + * thrown if class for instantiator or instance can't be + * loaded, if something goes wrong during instance + * construction or if instance cannot be created + */ + public static final ID makeID(Namespace n, Object[] args) + throws IDInstantiationException { + return makeID(n, null, args); + } + public static final ID makeID(String namespacename, Object[] args) + throws IDInstantiationException { + return makeID(getNamespaceByName(namespacename), args); + } + + public static final ID makeStringID(String idstring) + throws IDInstantiationException { + Namespace n = new Namespace(StringID.class.getClassLoader(), + StringID.STRINGID_NAME, StringID.STRINGID_INSTANTIATOR_CLASS, + null); + return makeID(n, new String[] { String.class.getName() }, + new Object[] { idstring }); + } + public static final ID makeLongID(Long l) throws IDInstantiationException { + Namespace n = new Namespace(LongID.class.getClassLoader(), + LongID.LONGID_NAME, LongID.LONGID_INSTANTIATOR_CLASS, null); + return makeID(n, new String[] { String.class.getName() }, + new Object[] { l }); + } + public static final ID makeLongID(long l) throws IDInstantiationException { + Namespace n = new Namespace(LongID.class.getClassLoader(), + LongID.LONGID_NAME, LongID.LONGID_INSTANTIATOR_CLASS, null); + return makeID(n, new String[] { String.class.getName() }, + new Object[] { new Long(l) }); + } + /** + * Remove the given Namespace from our table of available Namespaces + * + * @param n + * the Namespace to remove + * @return Namespace the namespace already in table (null if Namespace not + * previously in table) + * @exception SecurityException + * thrown if caller does not have appropriate + * NamespacePermission for given namespace + */ + public final static Namespace removeNamespace(Namespace n) + throws SecurityException { + if (n == null) + return null; + checkPermission(new NamespacePermission(n.getPermissionName(), + NamespacePermission.REMOVE_NAMESPACE)); + return removeNamespace0(n); + } + + protected final static Namespace removeNamespace0(Namespace n) { + if (n == null) + return null; + return (Namespace) namespaces.remove(n); + } + +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/identity/IDInstantiationException.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/identity/IDInstantiationException.java new file mode 100644 index 000000000..8ce863a71 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/identity/IDInstantiationException.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core.identity; + +import org.eclipse.ecf.core.util.ECFException; + +public class IDInstantiationException extends ECFException { + + public IDInstantiationException() { + super(); + } + + public IDInstantiationException(String message) { + super(message); + } + + public IDInstantiationException(Throwable cause) { + super(cause); + } + + public IDInstantiationException(String message, Throwable cause) { + super(message, cause); + } + +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/identity/LongID.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/identity/LongID.java new file mode 100644 index 000000000..2798e7c22 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/identity/LongID.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core.identity; + +import java.net.URI; +import java.net.URISyntaxException; + +import org.eclipse.ecf.core.identity.provider.IDInstantiator; + +public class LongID extends BaseID { + + Long value = null; + + public static class Creator implements IDInstantiator { + public ID makeInstance(Namespace ns, Class[] argTypes, Object[] args) + throws IDInstantiationException { + return new StringID(ns, (String) args[0]); + } + } + public static final String LONGID_INSTANTIATOR_CLASS = LongID.Creator.class + .getName(); + + public static final String LONGID_NAME = LongID.class.getName(); + + protected LongID(Namespace n, Long v) { + super(n); + value = v; + } + protected LongID(Namespace n, long v) { + super(n); + value = new Long(v); + } + protected int namespaceCompareTo(BaseID o) { + Long ovalue = ((LongID) o).value; + return value.compareTo(ovalue); + } + + protected boolean namespaceEquals(BaseID o) { + if (!(o instanceof LongID)) + return false; + LongID obj = (LongID) o; + return value.equals(obj); + } + + protected String namespaceGetName() { + return value.toString(); + } + + protected int namespaceHashCode() { + return value.hashCode(); + } + + protected URI namespaceToURI() throws URISyntaxException { + throw new URISyntaxException(value.toString(), + "LongID instances cannot create URL values"); + } + + public long longValue() { + return value.longValue(); + } +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/identity/Namespace.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/identity/Namespace.java new file mode 100644 index 000000000..f22168661 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/identity/Namespace.java @@ -0,0 +1,160 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core.identity; + +import java.io.Serializable; +import java.net.URI; +import java.net.URISyntaxException; + +import org.eclipse.ecf.core.identity.provider.IDInstantiator; + +/** + * Namespace class. This class defines the properties associated with an + * identity Namespace. Namespaces are defined by a unique 'name' (e.g. 'email', + * 'icq', 'aolim'), and an 'instantiatorClass'. The instantiator class defines a + * class that implements the org.eclipse.ecf.identity.provider.IDInstantiator + * interface and is responsible for creating instances of the given namespace. + * The instances created by the instantiatorClass <b>must </b> implement the + * org.eclipse.ecf.identity.ID interface, but otherwise can provide any other + * identity functionality desired. + * + */ +public class Namespace implements Serializable { + + private String name; + private String instantiatorClass; + private String description; + + private int hashCode = 0; + private ClassLoader classLoader = null; + + private transient IDInstantiator instantiator = null; + + /** + * + * @param name + * the name of the Namespace + * @param instantiatorClass + * the fully qualified classname of the class responsible for + * creating id instances that can exist within this namespace. + * @param description + * a description to be associated with this Namespace + */ + public Namespace(ClassLoader cl, String name, String instantiatorClass, + String desc) { + this.classLoader = cl; + this.name = name; + this.instantiatorClass = instantiatorClass; + this.description = desc; + this.hashCode = name.hashCode(); + } + public Namespace(String name, IDInstantiator inst, String desc) { + this.instantiator = inst; + this.instantiatorClass = this.instantiator.getClass().getName(); + this.classLoader = this.instantiator.getClass().getClassLoader(); + this.name = name; + this.description = desc; + this.hashCode = name.hashCode(); + } + /** + * Override of Object.equals. This equals method returns true if the + * provided Object is also a Namespace instance, and the names of the two + * instances match. + * + * @param other + * the Object to test for equality + */ + public boolean equals(Object other) { + if (!(other instanceof Namespace)) + return false; + return ((Namespace) other).name.equals(name); + } + + public String getDescription() { + return description; + } + + /** + * Get an ISharedObjectContainerInstantiator using the classloader used to + * load the Namespace class + * + * @return ISharedObjectContainerInstantiator associated with this Namespace + * instance + * @exception Exception + * thrown if instantiator class cannot be loaded, or if it + * cannot be cast to ISharedObjectContainerInstantiator + * interface + * + * @uml.property name="instantiator" + */ + protected IDInstantiator getInstantiator() throws ClassNotFoundException, + InstantiationException, IllegalAccessException { + synchronized (this) { + if (instantiator == null) + initializeInstantiator(classLoader); + return instantiator; + } + } + + protected boolean testIDEquals(BaseID first, BaseID second) { + // First check that namespaces are the same and non-null + Namespace sn = second.getNamespace(); + if (sn == null || !this.equals(sn)) + return false; + return first.namespaceEquals(second); + } + protected String getNameForID(BaseID id) { + return id.namespaceGetName(); + } + protected URI getURIForID(BaseID id) throws URISyntaxException { + return id.namespaceToURI(); + } + protected int getCompareToForObject(BaseID first, BaseID second) { + return first.namespaceCompareTo(second); + } + protected int getHashCodeForID(BaseID id) { + return id.namespaceHashCode(); + } + + /** + * @return String name of Namespace instance + * + * @uml.property name="name" + */ + public String getName() { + return name; + } + + protected String getPermissionName() { + return toString(); + } + + public int hashCode() { + return hashCode; + } + protected void initializeInstantiator(ClassLoader cl) + throws ClassNotFoundException, InstantiationException, + IllegalAccessException { + if (cl == null) + classLoader = this.getClass().getClassLoader(); + // Load instantiator class + Class clazz = Class.forName(instantiatorClass, true, classLoader); + // Make new instance + instantiator = (IDInstantiator) clazz.newInstance(); + } + + public String toString() { + StringBuffer b = new StringBuffer("Namespace["); + b.append(name).append(";"); + b.append(instantiatorClass).append(";"); + b.append(description).append("]"); + return b.toString(); + } +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/identity/NamespacePermission.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/identity/NamespacePermission.java new file mode 100644 index 000000000..b58e944e6 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/identity/NamespacePermission.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core.identity; + +import java.security.BasicPermission; +import java.security.Permission; + +public class NamespacePermission extends BasicPermission { + + public static final String ADD_NAMESPACE = "add"; + public static final String ALL_NAMESPACE = "all"; + public static final String CONTAINS_NAMESPACE = "contains"; + public static final String GET_NAMESPACE = "get"; + public static final String REMOVE_NAMESPACE = "remove"; + + protected String actions; + + public NamespacePermission(String s) { + super(s); + } + + public NamespacePermission(String s, String s1) { + super(s, s1); + actions = s1; + } + + /** + * + * @uml.property name="actions" + */ + public String getActions() { + return actions; + } + + public boolean implies(Permission p) { + if ((p == null) || (p.getClass() != getClass())) + return false; + NamespacePermission np = (NamespacePermission) p; + String actions = getActions(); + if (actions == null) + return false; + if (actions.equals(ALL_NAMESPACE) || actions.equals(np.getActions())) + return true; + return false; + } +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/identity/StringID.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/identity/StringID.java new file mode 100644 index 000000000..06290bf25 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/identity/StringID.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core.identity; + +import java.net.URI; +import java.net.URISyntaxException; + +import org.eclipse.ecf.core.identity.provider.IDInstantiator; + +/** + * A string-based identity + * + * @author Scott B. Lewis, slewis@composent.com + */ +public class StringID extends BaseID { + + public static class Creator implements IDInstantiator { + public ID makeInstance(Namespace ns, Class[] argTypes, Object[] args) + throws IDInstantiationException { + return new StringID(ns, (String) args[0]); + } + } + public static final String STRINGID_INSTANTIATOR_CLASS = StringID.Creator.class + .getName(); + + public static final String STRINGID_NAME = StringID.class.getName(); + + protected String value; + + /** + * Protected constructor for factory-based construction + * + * @param n + * the Namespace this identity will belong to + * @param s + * the String defining this StringID + */ + protected StringID(Namespace n, String s) { + super(n); + value = s; + setEmptyNamespace(); + } + public int compareTo(Object o) { + setEmptyNamespace(); + return super.compareTo(o); + } + public boolean equals(Object o) { + setEmptyNamespace(); + return super.equals(o); + } + public String getName() { + setEmptyNamespace(); + return super.getName(); + } + public int hashCode() { + setEmptyNamespace(); + return super.hashCode(); + } + public Namespace getNamespace() { + setEmptyNamespace(); + return namespace; + } + public String toString() { + setEmptyNamespace(); + int strlen = value.length(); + StringBuffer sb = new StringBuffer(strlen + 10); + sb.insert(0, "StringID[").insert(9, value).insert(strlen + 9, ']'); + return sb.toString(); + } + public URI toURI() throws URISyntaxException { + setEmptyNamespace(); + return super.toURI(); + } + protected int namespaceCompareTo(BaseID obj) { + String ovalue = ((StringID) obj).value; + return value.compareTo(ovalue); + } + protected boolean namespaceEquals(BaseID obj) { + if (!(obj instanceof StringID)) + return false; + StringID o = (StringID) obj; + return value.equals(o.getName()); + } + protected String namespaceGetName() { + return value; + } + protected int namespaceHashCode() { + return value.hashCode() ^ getClass().hashCode(); + } + protected URI namespaceToURI() throws URISyntaxException { + return new URI(getName()); + } + protected synchronized void setEmptyNamespace() { + if (namespace == null) { + namespace = IDFactory.getNamespaceByName(StringID.class.getName()); + } + } +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/identity/provider/IDInstantiator.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/identity/provider/IDInstantiator.java new file mode 100644 index 000000000..e091d70ec --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/identity/provider/IDInstantiator.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core.identity.provider; + +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.core.identity.IDInstantiationException; +import org.eclipse.ecf.core.identity.Namespace; + +public interface IDInstantiator { + + public ID makeInstance(Namespace ns, Class[] argTypes, Object[] args) + throws IDInstantiationException; +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/provider/ISharedObjectContainerInstantiator.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/provider/ISharedObjectContainerInstantiator.java new file mode 100644 index 000000000..aeafa608d --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/provider/ISharedObjectContainerInstantiator.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core.provider; + +import org.eclipse.ecf.core.ISharedObjectContainer; +import org.eclipse.ecf.core.SharedObjectContainerInstantiationException; + +public interface ISharedObjectContainerInstantiator { + + public ISharedObjectContainer makeInstance(Class[] argTypes, Object[] args) + throws SharedObjectContainerInstantiationException; +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/util/AbstractFactory.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/util/AbstractFactory.java new file mode 100644 index 000000000..6ea9ea7aa --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/util/AbstractFactory.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core.util; + +public class AbstractFactory { + + public static Class[] getClassesForTypes(String[] argTypes, Object[] args, + ClassLoader cl) throws ClassNotFoundException { + Class clazzes[] = null; + if (args == null || args.length == 0) + clazzes = new Class[0]; + else if (argTypes != null) { + clazzes = new Class[argTypes.length]; + for (int i = 0; i < argTypes.length; i++) { + clazzes[i] = Class.forName(argTypes[i], true, cl); + } + } else { + clazzes = new Class[args.length]; + for (int i = 0; i < args.length; i++) { + if (args[i] == null) + clazzes[i] = null; + else + clazzes[i] = args[i].getClass(); + } + } + return clazzes; + } + +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/util/AsynchResult.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/util/AsynchResult.java new file mode 100644 index 000000000..a93cb9bac --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/util/AsynchResult.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core.util; + +import java.lang.reflect.InvocationTargetException; + +public class AsynchResult { + protected Object resultValue = null; + protected boolean resultReady = false; + protected InvocationTargetException resultException = null; + + public AsynchResult() { + } + public Runnable setter(final Callable function) { + return new Runnable() { + public void run() { + try { + set(function.call()); + } catch (Throwable ex) { + setException(ex); + } + } + }; + } + protected Object doGet() throws InvocationTargetException { + if (resultException != null) + throw resultException; + else + return resultValue; + } + public synchronized Object get() throws InterruptedException, + InvocationTargetException { + while (!resultReady) + wait(); + return doGet(); + } + public synchronized Object get(long msecs) throws TimeoutException, + InterruptedException, InvocationTargetException { + long startTime = (msecs <= 0) ? 0 : System.currentTimeMillis(); + long waitTime = msecs; + if (resultReady) + return doGet(); + else if (waitTime <= 0) + throw new TimeoutException(msecs); + else { + for (;;) { + wait(waitTime); + if (resultReady) + return doGet(); + else { + waitTime = msecs - (System.currentTimeMillis() - startTime); + if (waitTime <= 0) + throw new TimeoutException(msecs); + } + } + } + } + public synchronized void set(Object newValue) { + resultValue = newValue; + resultReady = true; + notifyAll(); + } + public synchronized void setException(Throwable ex) { + resultException = new InvocationTargetException(ex); + resultReady = true; + notifyAll(); + } + public synchronized InvocationTargetException getException() { + return resultException; + } + public synchronized boolean isReady() { + return resultReady; + } + public synchronized Object peek() { + return resultValue; + } + public synchronized void clear() { + resultValue = null; + resultException = null; + resultReady = false; + } + +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/util/Base64.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/util/Base64.java new file mode 100644 index 000000000..394051ba8 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/util/Base64.java @@ -0,0 +1,161 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core.util; + +/** + * + * Encode/decode byte arrays into base64 strings. Code originally + * acquired from + * ftp://ftp.ora.com/pub/examples/java/crypto/files/oreilly/jonathan/util/ + * + * Several small modifications were made: the '_' character was substituted for + * the '/' character, the '-' char substituted for the '=' char, and the '.' + * substituted for the '+' char so that the resulting string does not use any of + * the reserved characters in the URI reserved character set as described in + * RFC2396. See ftp://ftp.isi.edu/in-notes/rfc2396.txt for details. + * + */ +public final class Base64 { + + /** + * Encode a byte array into a String + * + * @param raw + * the raw data to encode + * @return String that is base64 encoded + */ + public static String encode(byte[] raw) { + if (raw == null) + throw new NumberFormatException("Input data cannot be null"); + + StringBuffer encoded = new StringBuffer(); + for (int i = 0; i < raw.length; i += 3) { + encoded.append(encodeBlock(raw, i)); + } + return encoded.toString(); + } + + protected static char[] encodeBlock(byte[] raw, int offset) { + int block = 0; + int slack = raw.length - offset - 1; + int end = (slack >= 2) ? 2 : slack; + for (int i = 0; i <= end; i++) { + byte b = raw[offset + i]; + int neuter = (b < 0) ? b + 256 : b; + block += neuter << (8 * (2 - i)); + } + char[] base64 = new char[4]; + for (int i = 0; i < 4; i++) { + int sixbit = (block >>> (6 * (3 - i))) & 0x3f; + base64[i] = getChar(sixbit); + } + // modify to use '-' instead of '=' + if (slack < 1) + base64[2] = '-'; + if (slack < 2) + base64[3] = '-'; + return base64; + } + + protected static char getChar(int sixBit) { + if (sixBit >= 0 && sixBit <= 25) + return (char) ('A' + sixBit); + if (sixBit >= 26 && sixBit <= 51) + return (char) ('a' + (sixBit - 26)); + if (sixBit >= 52 && sixBit <= 61) + return (char) ('0' + (sixBit - 52)); + if (sixBit == 62) + return '.'; + // modify to use '_' instead of '/' + if (sixBit == 63) + return '_'; + return '?'; + } + + /** + * Decode base64 string into a byte array. + * + * @param base64 + * the base64 encoded string + * @return byte[] the resulting decoded data array + * @exception NumberFormatException + * thrown if String not in base64 format. + */ + public static byte[] decode(String base64) throws NumberFormatException { + int pad = 0; + for (int i = base64.length() - 1; base64.charAt(i) == '-'; i--) + pad++; + int length = base64.length() * 6 / 8 - pad; + byte[] raw = new byte[length]; + int rawIndex = 0; + for (int i = 0; i < base64.length(); i += 4) { + int block = (getValue(base64.charAt(i)) << 18) + + (getValue(base64.charAt(i + 1)) << 12) + + (getValue(base64.charAt(i + 2)) << 6) + + (getValue(base64.charAt(i + 3))); + for (int j = 0; j < 3 && rawIndex + j < raw.length; j++) + raw[rawIndex + j] = (byte) ((block >> (8 * (2 - j))) & 0xff); + rawIndex += 3; + } + return raw; + } + + protected static int getValue(char c) throws NumberFormatException { + if (c >= 'A' && c <= 'Z') + return c - 'A'; + if (c >= 'a' && c <= 'z') + return c - 'a' + 26; + if (c >= '0' && c <= '9') + return c - '0' + 52; + if (c == '.') + return 62; + // modify to use '_' instead of '/' + if (c == '_') + return 63; + // modify to use '-' instead of '=' + if (c == '-') + return 0; + throw new NumberFormatException("Invalid value '" + c + + "' in base64 string"); + } + + public static void main(String[] args) throws Exception { + System.out.println("Starting Base64 test program."); + + int byteLength = 16; + + java.security.SecureRandom ar = new java.security.SecureRandom(); + byte[] buf = new byte[byteLength]; + ar.nextBytes(buf); + System.out.println("Secure random bytes are:"); + for (int i = 0; i < buf.length; i++) + System.out.print(buf[i] + " "); + System.out.println(); + + System.out.println("Converting secure random number to Base64..."); + String res = Base64.encode(buf); + System.out.println("Converted string is: "); + System.out.println(res); + + byte[] buf2 = new byte[byteLength]; + System.out.println("Converting string back to byte array..."); + buf2 = Base64.decode(res); + System.out.println("Converted byte array as: "); + for (int i = 0; i < buf2.length; i++) + System.out.print(buf2[i] + " "); + System.out.println(); + + System.out.println("Trying to decode a bogus string..."); + buf2 = Base64.decode("ADDFDSFasdfasdf%$###"); + + System.out.println("Done."); + } + +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/util/Callable.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/util/Callable.java new file mode 100644 index 000000000..a74b87fec --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/util/Callable.java @@ -0,0 +1,15 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core.util; + +public interface Callable { + /** Perform some action that returns a result or throws an exception * */ + Object call() throws Throwable; +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/util/ECFException.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/util/ECFException.java new file mode 100644 index 000000000..ca0c65e52 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/util/ECFException.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core.util; + +public class ECFException extends Exception { + + public ECFException() { + super(); + } + + /** + * @param message + */ + public ECFException(String message) { + super(message); + } + + /** + * @param cause + */ + public ECFException(Throwable cause) { + super(cause); + } + + /** + * @param message + * @param cause + */ + public ECFException(String message, Throwable cause) { + super(message, cause); + } + +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/util/EnqueuePredicate.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/util/EnqueuePredicate.java new file mode 100644 index 000000000..a271ffa16 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/util/EnqueuePredicate.java @@ -0,0 +1,14 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core.util; + +public interface EnqueuePredicate { + boolean accept(Event element); +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/util/Event.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/util/Event.java new file mode 100644 index 000000000..33996667f --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/util/Event.java @@ -0,0 +1,16 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core.util; + +import java.io.Serializable; + +public interface Event extends Serializable { + // No methods. This is a 'tag' interface +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/util/EventProcessor.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/util/EventProcessor.java new file mode 100644 index 000000000..43976300c --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/util/EventProcessor.java @@ -0,0 +1,14 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core.util; + +public interface EventProcessor { + public Object processEvent(Event e) throws Exception; +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/util/Queue.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/util/Queue.java new file mode 100644 index 000000000..d263aca27 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/util/Queue.java @@ -0,0 +1,14 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core.util; + +public interface Queue extends QueueDequeue, QueueEnqueue { + +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/util/QueueDequeue.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/util/QueueDequeue.java new file mode 100644 index 000000000..fece9c311 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/util/QueueDequeue.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core.util; + +public interface QueueDequeue { + /* + * Dequeue a single event. Returns null if no Events available for dequeue + * @return Event the Event dequeued. Null if queue is empty. + */ + Event dequeue(); + /* + * Dequeue several events in one operation. num events are dequeued. + * + * @return Event[] the Events dequeue. Returns null if there are not + * sufficient events on queue to support dequeuing num events + */ + Event[] dequeue(int num); + /* + * Dequeue all available Events. @return Event[] the events on this queue. + * Returns null if there are no events in queue + */ + Event[] dequeue_all(); + /* + * Dequeue a single Event. Blocks until an Event is available for dequeue, + * or until timeout_millis have elapsed. If timeout_millis is -1, dequeue + * does not timeout. @param timeout_millis the timeout for a dequeue in + * milliseconds. @return Event removed from queue. Returns null if no events + * on queue. + */ + Event blocking_dequeue(int timeout_millis); + /* + * Dequeue a multiple Events. Blocks until num Events are available for + * dequeue, or until timeout_millis have elapsed. If timeout_millis is -1, + * dequeue does not timeout. @param timeout_millis the timeout for a dequeue + * in milliseconds. @param num the number of Events to dequeue @return Event [] + * the num Events removed from queue + */ + Event[] blocking_dequeue(int timeout_millis, int num); + /* + * Dequeue all Events currently on queue. Blocks until num Events are + * available for dequeue, or until timeout_millis have elapsed. If + * timeout_millis is -1, dequeue does not timeout. @param timeout_millis the + * timeout for a dequeue in milliseconds. @param num the number of Events to + * dequeue @return Event [] the num Events removed from queue + */ + Event[] blocking_dequeue_all(int timeout_millis); + /* + * Provide the current size of the queue (the number of Events) currently on + * the queue. @return size the int size of the queue + */ + int size(); +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/util/QueueEnqueue.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/util/QueueEnqueue.java new file mode 100644 index 000000000..3b66c68c2 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/util/QueueEnqueue.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core.util; + +public interface QueueEnqueue { + void enqueue(Event element) throws QueueException; + void enqueue(Event[] elements) throws QueueException; + + Object enqueue_prepare(Event[] elements) throws QueueException; + + void enqueue_commit(Object enqueue_key); + void enqueue_abort(Object enqueue_key); + + boolean enqueue_lossy(Event element); + + /** + * + * @uml.property name="enqueuePredicate" + */ + void setEnqueuePredicate(EnqueuePredicate pred); + + /** + * + * @uml.property name="enqueuePredicate" + * @uml.associationEnd + * @uml.property name="enqueuePredicate" multiplicity="(0 1)" + */ + EnqueuePredicate getEnqueuePredicate(); + + int size(); + +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/util/QueueException.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/util/QueueException.java new file mode 100644 index 000000000..ed6aa6901 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/util/QueueException.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core.util; + +public class QueueException extends Exception { + + /** + * + * @uml.property name="theQueue" + * @uml.associationEnd + * @uml.property name="theQueue" multiplicity="(0 1)" + */ + Queue theQueue = null; + + public QueueException() { + super(); + } + + public QueueException(Queue queue) { + theQueue = queue; + } + public QueueException(String message) { + super(message); + } + public QueueException(String message, Throwable cause) { + super(message, cause); + } + public QueueException(Throwable cause) { + super(cause); + } + public Queue getQueue() { + return theQueue; + } +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/util/SimpleQueue.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/util/SimpleQueue.java new file mode 100644 index 000000000..15c67c6d0 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/util/SimpleQueue.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core.util; + +public interface SimpleQueue { + + public boolean enqueue(Object obj); + public Object dequeue(); + public Object peekQueue(); + public Object removeHead(); + public void close(); +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/util/TimeoutException.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/util/TimeoutException.java new file mode 100644 index 000000000..24fc19d8a --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/core/util/TimeoutException.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.core.util; + +public class TimeoutException extends InterruptedException { + + public final long duration; + public TimeoutException(long time) { + duration = time; + } + public TimeoutException(long time, String message) { + super(message); + duration = time; + } +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/comm/AsynchConnectionDescription.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/comm/AsynchConnectionDescription.java new file mode 100644 index 000000000..e4f64edc9 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/comm/AsynchConnectionDescription.java @@ -0,0 +1,75 @@ +package org.eclipse.ecf.internal.comm; + +public class AsynchConnectionDescription { + + protected String name; + protected String instantiatorClass; + + protected IAsynchConnectionInstantiator instantiator; + protected int hashCode = 0; + protected ClassLoader classLoader = null; + + public AsynchConnectionDescription(ClassLoader loader, + + String name, String instantiatorClass) { + if (name == null) + throw new RuntimeException(new InstantiationException( + "stagecontainer description name cannot be null")); + this.classLoader = loader; + this.name = name; + this.instantiatorClass = instantiatorClass; + this.hashCode = name.hashCode(); + } + public AsynchConnectionDescription(String name, + IAsynchConnectionInstantiator inst) { + this.instantiator = inst; + this.classLoader = this.instantiator.getClass().getClassLoader(); + this.instantiatorClass = this.instantiatorClass.getClass().getName(); + this.hashCode = name.hashCode(); + } + public String getName() { + return name; + } + public ClassLoader getClassLoader() { + return classLoader; + } + public boolean equals(Object other) { + if (!(other instanceof AsynchConnectionDescription)) + return false; + AsynchConnectionDescription scd = (AsynchConnectionDescription) other; + return scd.name.equals(name); + } + + public int hashCode() { + return hashCode; + } + + public String toString() { + StringBuffer b = new StringBuffer("AsynchConnectionDescription["); + b.append(name).append(";"); + b.append(instantiatorClass).append("]"); + return b.toString(); + } + + protected IAsynchConnectionInstantiator getInstantiator() + throws ClassNotFoundException, InstantiationException, + IllegalAccessException { + synchronized (this) { + if (instantiator == null) + initializeInstantiator(classLoader); + return instantiator; + } + } + + protected void initializeInstantiator(ClassLoader cl) + throws ClassNotFoundException, InstantiationException, + IllegalAccessException { + if (cl == null) + cl = this.getClass().getClassLoader(); + // Load instantiator class + Class clazz = Class.forName(instantiatorClass, true, cl); + // Make new instance + instantiator = (IAsynchConnectionInstantiator) clazz.newInstance(); + } + +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/comm/AsynchConnectionEvent.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/comm/AsynchConnectionEvent.java new file mode 100644 index 000000000..6b6caa5f2 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/comm/AsynchConnectionEvent.java @@ -0,0 +1,7 @@ +package org.eclipse.ecf.internal.comm; + +public class AsynchConnectionEvent extends ConnectionEvent { + public AsynchConnectionEvent(IAsynchConnection conn, Object data) { + super(conn, data); + } +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/comm/AsynchConnectionFactory.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/comm/AsynchConnectionFactory.java new file mode 100644 index 000000000..cb7d52b3d --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/comm/AsynchConnectionFactory.java @@ -0,0 +1,140 @@ +package org.eclipse.ecf.internal.comm; + +import java.util.Hashtable; + +import org.eclipse.ecf.core.util.AbstractFactory; + +public class AsynchConnectionFactory { + + private static Hashtable connectiontypes = new Hashtable(); + + static { + /* + AsynchConnectionDescription cdtcp = + new AsynchConnectionDescription( + TCPReliableConnection.class.getName(), + "1.0.0", + TCPReliableConnection.Creator.class.getName()); + addDescription(cdtcp); + + AsynchConnectionDescription cdjms = + new AsynchConnectionDescription( + JMSClientReliableConnection.class.getName(), + "1.0.0", + JMSClientReliableConnection.Creator.class.getName()); + addDescription(cdjms); + + + AsynchConnectionDescription cdxmpp = + new AsynchConnectionDescription( + SmackConnection.class.getName(), + "1.0.0", + SmackConnection.Creator.class.getName()); + addDescription(cdxmpp); + */ + } + + public final static AsynchConnectionDescription getDescription(AsynchConnectionDescription scd) { + return getDescription0(scd); + } + protected static AsynchConnectionDescription getDescription0(AsynchConnectionDescription scd) { + if (scd == null) + return null; + return (AsynchConnectionDescription) connectiontypes.get(scd.getName()); + } + protected static AsynchConnectionDescription getDescription0(String name) { + if (name == null) + return null; + return (AsynchConnectionDescription) connectiontypes.get(name); + } + public final static AsynchConnectionDescription getDescriptionByName(String name) { + return getDescription0(name); + } + public final static AsynchConnectionDescription removeDescription(AsynchConnectionDescription scd) { + return removeDescription0(scd); + } + + protected static AsynchConnectionDescription removeDescription0(AsynchConnectionDescription n) { + if (n == null) + return null; + return (AsynchConnectionDescription) connectiontypes.remove(n.getName()); + } + public final static AsynchConnectionDescription addDescription(AsynchConnectionDescription scd) { + return addDescription0(scd); + } + + protected static AsynchConnectionDescription addDescription0(AsynchConnectionDescription n) { + if (n == null) + return null; + return (AsynchConnectionDescription) connectiontypes.put(n.getName(), n); + } + public final static boolean containsDescription(AsynchConnectionDescription scd) { + return containsDescription0(scd); + } + protected static boolean containsDescription0(AsynchConnectionDescription scd) { + if (scd == null) + return false; + return connectiontypes.containsKey(scd.getName()); + } + + public static IAsynchConnection makeAsynchConnection(AsynchConnectionDescription desc, + String[] argTypes, + Object[] args) + throws ConnectionInstantiationException { + + if (desc == null) + throw new ConnectionInstantiationException("AsynchConnectionDescription cannot be null"); + AsynchConnectionDescription cd = getDescription0(desc); + if (cd == null) + throw new ConnectionInstantiationException( + "AsynchConnectionDescription " + desc.getName() + " not found"); + IAsynchConnectionInstantiator instantiator = null; + Class clazzes[] = null; + try { + instantiator = (IAsynchConnectionInstantiator) cd.getInstantiator(); + clazzes = AbstractFactory.getClassesForTypes(argTypes, args, cd.getClassLoader()); + if (instantiator == null) + throw new InstantiationException( + "Instantiator for AsynchConnectionDescription " + + cd.getName() + + " is null"); + } catch (Exception e) { + throw new ConnectionInstantiationException("Exception getting instantiator for '"+desc.getName()+"'",e); + } + // Ask instantiator to actually create instance + return instantiator.makeInstance(clazzes, args); + } + public static IAsynchConnection makeAsynchConnection( + AsynchConnectionDescription desc, + Object[] args) + throws ConnectionInstantiationException { + return makeAsynchConnection(desc, null, args); + } + public static IAsynchConnection makeAsynchConnection( + String descriptionName, + Object[] args) + throws ConnectionInstantiationException { + return makeAsynchConnection( + getDescriptionByName(descriptionName), + args); + } + public static IAsynchConnection makeAsynchConnection( + String descriptionName, + String[] argTypes, + Object[] args) + throws ConnectionInstantiationException { + return makeAsynchConnection( + getDescriptionByName(descriptionName), + argTypes, + args); + } + public static IAsynchConnection makeAsynchConnection( + String descriptionName) + throws ConnectionInstantiationException { + return makeAsynchConnection( + getDescriptionByName(descriptionName), + null, + null); + } + +} diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/comm/ConnectionEvent.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/comm/ConnectionEvent.java new file mode 100644 index 000000000..58ae847cd --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/comm/ConnectionEvent.java @@ -0,0 +1,29 @@ +package org.eclipse.ecf.internal.comm; + +import org.eclipse.ecf.core.util.Event; + +public class ConnectionEvent implements Event { + + Object odata = null; + byte [] bdata = null; + IConnection connection = null; + + public ConnectionEvent(IConnection source, Object odata) { + this.connection = source; + this.odata = odata; + } + public ConnectionEvent(IConnection source, byte [] bdata) { + this.connection = source; + this.bdata = bdata; + } + public IConnection getConnection() { + return connection; + } + public Object getOData() { + return odata; + } + public byte [] getBData() { + return bdata; + } + +} diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/comm/ConnectionInstantiationException.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/comm/ConnectionInstantiationException.java new file mode 100644 index 000000000..19a12e54b --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/comm/ConnectionInstantiationException.java @@ -0,0 +1,31 @@ +package org.eclipse.ecf.internal.comm; + +public class ConnectionInstantiationException extends Exception { + + public ConnectionInstantiationException() { + super(); + } + + /** + * @param message + */ + public ConnectionInstantiationException(String message) { + super(message); + } + + /** + * @param cause + */ + public ConnectionInstantiationException(Throwable cause) { + super(cause); + } + + /** + * @param message + * @param cause + */ + public ConnectionInstantiationException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/comm/DisconnectConnectionEvent.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/comm/DisconnectConnectionEvent.java new file mode 100644 index 000000000..e61d7f210 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/comm/DisconnectConnectionEvent.java @@ -0,0 +1,23 @@ +package org.eclipse.ecf.internal.comm; + + +public class DisconnectConnectionEvent extends ConnectionEvent { + + Throwable exception = null; + + public DisconnectConnectionEvent( + IAsynchConnection conn, + Throwable e, + Object data) { + super(conn, data); + exception = e; + } + + public Object getData() { + return super.getOData(); + } + + public Throwable getException() { + return exception; + } +} diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/comm/IAsynchConnection.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/comm/IAsynchConnection.java new file mode 100644 index 000000000..7a4e044f1 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/comm/IAsynchConnection.java @@ -0,0 +1,11 @@ +package org.eclipse.ecf.internal.comm; + +import java.io.IOException; + +import org.eclipse.ecf.core.identity.ID; + +public interface IAsynchConnection extends IConnection { + + public void sendAsynch(ID receiver, byte [] data) throws IOException; + public void sendAsynch(ID receiver, Object data) throws IOException; +} diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/comm/IAsynchConnectionEventHandler.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/comm/IAsynchConnectionEventHandler.java new file mode 100644 index 000000000..be4a8aa29 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/comm/IAsynchConnectionEventHandler.java @@ -0,0 +1,7 @@ +package org.eclipse.ecf.internal.comm; + +import java.io.IOException; + +public interface IAsynchConnectionEventHandler extends IConnectionEventHandler { + public void handleAsynchEvent(ConnectionEvent event) throws IOException; +} diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/comm/IAsynchConnectionInstantiator.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/comm/IAsynchConnectionInstantiator.java new file mode 100644 index 000000000..4a5424e9c --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/comm/IAsynchConnectionInstantiator.java @@ -0,0 +1,8 @@ +package org.eclipse.ecf.internal.comm; + +import org.eclipse.ecf.internal.comm.ConnectionInstantiationException; +import org.eclipse.ecf.internal.comm.IAsynchConnection; + +public interface IAsynchConnectionInstantiator { + public IAsynchConnection makeInstance(Class [] clazzes, Object [] args) throws ConnectionInstantiationException; +} diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/comm/IConnection.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/comm/IConnection.java new file mode 100644 index 000000000..00685cc72 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/comm/IConnection.java @@ -0,0 +1,20 @@ +package org.eclipse.ecf.internal.comm; + +import java.io.IOException; +import java.util.Map; + +import org.eclipse.ecf.core.identity.ID; + +public interface IConnection { + + public Object connect(ID remote, Object data, int timeout) throws IOException; + public void disconnect() throws IOException; + public boolean isConnected(); + public ID getLocalID(); + public void start(); + public void stop(); + public boolean isStarted(); + public Map getProperties(); + public IConnectionEventHandler addCommEventListener(IConnectionEventHandler listener); + public void removeCommEventListener(IConnectionEventHandler listener); +} diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/comm/IConnectionEventHandler.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/comm/IConnectionEventHandler.java new file mode 100644 index 000000000..a8a205294 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/comm/IConnectionEventHandler.java @@ -0,0 +1,8 @@ +package org.eclipse.ecf.internal.comm; + +public interface IConnectionEventHandler { + + public boolean handleSuspectEvent(ConnectionEvent event); + public void handleDisconnectEvent(ConnectionEvent event); + public Object getAdapter(Class clazz); +} diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/comm/IConnectionRequestHandler.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/comm/IConnectionRequestHandler.java new file mode 100644 index 000000000..8d65c5f1c --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/comm/IConnectionRequestHandler.java @@ -0,0 +1,7 @@ +package org.eclipse.ecf.internal.comm; + + +public interface IConnectionRequestHandler +{ + public Object checkConnect(String hostname, Object data, IConnection conn) throws Exception; +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/comm/ISynchConnection.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/comm/ISynchConnection.java new file mode 100644 index 000000000..4c3eed2b8 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/comm/ISynchConnection.java @@ -0,0 +1,11 @@ +package org.eclipse.ecf.internal.comm; + +import java.io.IOException; + +import org.eclipse.ecf.core.identity.ID; + +public interface ISynchConnection extends IConnection { + + public Object sendSynch(ID receiver, byte [] data) throws IOException; + public Object sendSynch(ID receiver, Object data) throws IOException; +} diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/comm/ISynchConnectionEventHandler.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/comm/ISynchConnectionEventHandler.java new file mode 100644 index 000000000..d0dbd1f43 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/comm/ISynchConnectionEventHandler.java @@ -0,0 +1,8 @@ +package org.eclipse.ecf.internal.comm; + +import java.io.IOException; + +public interface ISynchConnectionEventHandler extends IConnectionEventHandler { + + public Object handleSynchEvent(ConnectionEvent event) throws IOException; +} diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/comm/SynchConnectionEvent.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/comm/SynchConnectionEvent.java new file mode 100644 index 000000000..29fd588e0 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/comm/SynchConnectionEvent.java @@ -0,0 +1,9 @@ +package org.eclipse.ecf.internal.comm; + +import java.io.Serializable; + +public class SynchConnectionEvent extends ConnectionEvent { + public SynchConnectionEvent(ISynchConnection conn, Serializable data) { + super(conn, data); + } +} diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/core/ECFPlugin.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/core/ECFPlugin.java new file mode 100644 index 000000000..7c0661594 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/core/ECFPlugin.java @@ -0,0 +1,301 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.internal.core; + +import java.lang.reflect.Constructor; +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtension; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.IExtensionRegistry; +import org.eclipse.core.runtime.ILog; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Plugin; +import org.eclipse.core.runtime.Status; +import org.eclipse.ecf.core.SharedObjectContainerDescription; +import org.eclipse.ecf.core.SharedObjectContainerFactory; +import org.eclipse.ecf.core.identity.IDFactory; +import org.eclipse.ecf.core.identity.Namespace; +import org.eclipse.ecf.core.identity.provider.IDInstantiator; +import org.eclipse.ecf.core.provider.ISharedObjectContainerInstantiator; +import org.osgi.framework.BundleContext; + +/* + * Plugin class for Eclipse Communications Framework core + * + * @author slewis + * + */ +public class ECFPlugin extends Plugin { + + public static final String PLUGIN_RESOURCE_BUNDLE = "org.eclipse.ecf.ECFPluginResources"; + + public static final String NAMESPACE_EPOINT = "org.eclipse.ecf.namespace"; + public static final String INSTANTIATOR_CLASS_ATTRIBUTE = "instantiatorClass"; + public static final String INSTANTIATOR_NAME_ATTRIBUTE = "name"; + public static final String NAMESPACE_CLASS_ATTRIBUTE = "namespaceClass"; + public static final String INSTANTIATOR_DATA_ATTRIBUTE = "description"; + public static final String NAMESPACE_DEFAULT_CLASS = "org.eclipse.ecf.identity.Namespace"; + + public static final String CONTAINER_FACTORY_EPOINT = "org.eclipse.ecf.containerFactory"; + public static final String CONTAINER_FACTORY_EPOINT_CLASS_ATTRIBUTE = "class"; + public static final String CONTAINER_FACTORY_EPOINT_NAME_ATTRIBUTE = "name"; + public static final String CONTAINER_FACTORY_EPOINT_DESC_ATTRIBUTE = "description"; + + public static final int FACTORY_DOES_NOT_IMPLEMENT_ERRORCODE = 10; + public static final int FACTORY_NAME_COLLISION_ERRORCODE = 20; + + public static final int INSTANTIATOR_DOES_NOT_IMPLEMENT_ERRORCODE = 30; + public static final int INSTANTIATOR_NAME_COLLISION_ERRORCODE = 50; + public static final int INSTANTIATOR_NAMESPACE_LOAD_ERRORCODE = 60; + + //The shared instance. + private static ECFPlugin plugin; + //Resource bundle. + private ResourceBundle resourceBundle; + + public ECFPlugin() { + super(); + plugin = this; + try { + resourceBundle = ResourceBundle.getBundle(PLUGIN_RESOURCE_BUNDLE); + } catch (MissingResourceException x) { + resourceBundle = null; + } + } + public static void log(IStatus status) { + if (status == null) + return; + ILog log = plugin.getLog(); + if (log != null) { + log.log(status); + } else { + System.err.println("No log output. Status Message: " + + status.getMessage()); + } + } + protected void setupContainerExtensionPoint(BundleContext bc) { + String bundleName = getDefault().getBundle().getSymbolicName(); + IExtensionRegistry reg = Platform.getExtensionRegistry(); + IExtensionPoint extensionPoint = reg + .getExtensionPoint(CONTAINER_FACTORY_EPOINT); + if (extensionPoint == null) { + return; + } + IConfigurationElement[] members = extensionPoint + .getConfigurationElements(); + // For each configuration element + for (int m = 0; m < members.length; m++) { + IConfigurationElement member = members[m]; + // Get the label of the extender plugin and the ID of the extension. + IExtension extension = member.getDeclaringExtension(); + Object exten = null; + try { + // The only required attribute is "class" + exten = member + .createExecutableExtension(CONTAINER_FACTORY_EPOINT_CLASS_ATTRIBUTE); + // Verify that object implements ISharedObjectContainerFactory + if (!(exten instanceof ISharedObjectContainerInstantiator)) { + IStatus s = new Status( + Status.ERROR, + bundleName, + FACTORY_DOES_NOT_IMPLEMENT_ERRORCODE, + getResourceString("ExtPointError.ContainerNoImplPrefix") + + exten.getClass().getName() + + getResourceString("ExtPointError.ContainerNoImplSuffix") + + extension + .getExtensionPointUniqueIdentifier(), + null); + throw new CoreException(s); + } + ClassLoader cl = exten.getClass().getClassLoader(); + String clazz = exten.getClass().getName(); + // Get name and get version, if available + String name = member + .getAttribute(CONTAINER_FACTORY_EPOINT_NAME_ATTRIBUTE); + if (name == null) { + name = clazz; + } + String description = member.getAttribute(CONTAINER_FACTORY_EPOINT_DESC_ATTRIBUTE); + if (description == null) { + description = ""; + } + SharedObjectContainerDescription scd = new SharedObjectContainerDescription( + name, (ISharedObjectContainerInstantiator) exten, description); + if (SharedObjectContainerFactory.containsDescription(scd)) { + // It's already there...log and throw as we can't use the + // same named factory + IStatus s = new Status( + Status.ERROR, + bundleName, + FACTORY_NAME_COLLISION_ERRORCODE, + getResourceString("ExtPointError.ContainerNameCollisionPrefix") + + name + + getResourceString("ExtPointError.ContainerNameCollisionSuffix") + + extension + .getExtensionPointUniqueIdentifier(), + null); + throw new CoreException(s); + } + // Now add the description and we're ready to go. + SharedObjectContainerFactory.addDescription(scd); + } catch (CoreException e) { + log(e.getStatus()); + } + } + + } + + protected void setupIdentityExtensionPoint(BundleContext context) { + String bundleName = getDefault().getBundle().getSymbolicName(); + // Process extension points + IExtensionRegistry reg = Platform.getExtensionRegistry(); + IExtensionPoint extensionPoint = reg + .getExtensionPoint(NAMESPACE_EPOINT); + if (extensionPoint == null) { + return; + } + IConfigurationElement[] members = extensionPoint + .getConfigurationElements(); + // For each service: + for (int m = 0; m < members.length; m++) { + IConfigurationElement member = members[m]; + // Get the label of the extender plugin and the ID of the + // extension. + IExtension extension = member.getDeclaringExtension(); + try { + String nsInstantiatorClass = member + .getAttribute(INSTANTIATOR_CLASS_ATTRIBUTE); + if (nsInstantiatorClass == null) { + throw new CoreException(null); + } + String nsName = member + .getAttribute(INSTANTIATOR_NAME_ATTRIBUTE); + if (nsName == null) { + nsName = nsInstantiatorClass; + } + String nsClassName = member + .getAttribute(NAMESPACE_CLASS_ATTRIBUTE); + if (nsClassName == null) { + nsClassName = NAMESPACE_DEFAULT_CLASS; + } + String nsData = member + .getAttribute(INSTANTIATOR_DATA_ATTRIBUTE); + // Load instantiator class and create instance + Object obj = member + .createExecutableExtension(INSTANTIATOR_CLASS_ATTRIBUTE); + // Verify that object implements IDInstantiator + if (!(obj instanceof IDInstantiator)) { + IStatus s = new Status( + Status.ERROR, + bundleName, + INSTANTIATOR_DOES_NOT_IMPLEMENT_ERRORCODE, + getResourceString("ExtPointError.IDNoImplPrefix") + + obj.getClass().getName() + + getResourceString("ExtPointError.IDNoImplSuffix") + + extension + .getExtensionPointUniqueIdentifier(), + null); + throw new CoreException(s); + } + ClassLoader loader = obj.getClass().getClassLoader(); + Namespace ns = null; + try { + Class nsClass = Class.forName(nsClassName, true, loader); + Constructor cons = nsClass + .getDeclaredConstructor(new Class[] { String.class, + IDInstantiator.class, String.class }); + ns = (Namespace) cons.newInstance(new Object[] { nsName, + obj, nsData }); + } catch (Exception e) { + IStatus s = new Status( + Status.ERROR, + bundleName, + INSTANTIATOR_NAMESPACE_LOAD_ERRORCODE, + getResourceString("ExtPointError.IDNameLoadErrorPrefix") + + nsName + + getResourceString("ExtPointError.IDNameLoadErrorSuffix") + + extension + .getExtensionPointUniqueIdentifier(), + e); + throw new CoreException(s); + } + if (IDFactory.containsNamespace(ns)) { + // It's already there...log and throw as we can't use the + // same named factory + IStatus s = new Status( + Status.ERROR, + bundleName, + INSTANTIATOR_NAME_COLLISION_ERRORCODE, + getResourceString("ExtPointError.IDNameCollisionPrefix") + + nsName + + getResourceString("ExtPointError.IDNameCollisionSuffix") + + extension + .getExtensionPointUniqueIdentifier(), + null); + throw new CoreException(s); + } + // Now add to known namespaces + IDFactory.addNamespace(ns); + } catch (CoreException e) { + log(e.getStatus()); + } + } + + } + + /** + * This method is called upon plug-in activation + */ + public void start(BundleContext context) throws Exception { + super.start(context); + setupContainerExtensionPoint(context); + setupIdentityExtensionPoint(context); + } + + /** + * This method is called when the plug-in is stopped + */ + public void stop(BundleContext context) throws Exception { + super.stop(context); + } + + /** + * Returns the shared instance. + */ + public static ECFPlugin getDefault() { + return plugin; + } + + /** + * Returns the string from the plugin's resource bundle, or 'key' if not + * found. + */ + public static String getResourceString(String key) { + ResourceBundle bundle = ECFPlugin.getDefault().getResourceBundle(); + try { + return (bundle != null) ? bundle.getString(key) : "!" + key + "!"; + } catch (MissingResourceException e) { + return "!" + key + "!"; + } + } + + /** + * Returns the plugin's resource bundle, + */ + public ResourceBundle getResourceBundle() { + return resourceBundle; + } + +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/core/ECFPlugin.properties b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/core/ECFPlugin.properties new file mode 100644 index 000000000..3c1744748 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/core/ECFPlugin.properties @@ -0,0 +1,24 @@ +/**************************************************************************** +* Copyright (c) 2004 Composent, Inc. and others. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: +* Composent, Inc. - initial API and implementation +*****************************************************************************/ +ExtPointError.ContainerNoImplPrefix=Container factory with class +ExtPointError.ContainerNoImplSuffix= does not implement ISharedObjectContainerInstantiator. Ignoring registration for containerFactory extension point + +ExtPointError.ContainerNameCollisionPrefix=ECF container factory with name +ExtPointError.ContainerNameCollisionSuffix=already found. Ignoring registration for containerFactory extension point + +ExtPointError.IDNoImplPrefix=ID creator with class +ExtPointError.IDNoImplSuffix= does not implement IDInstantiator. Ignoring registration for namespace extension point + +ExtPointError.IDNameCollisionPrefix=ECF namespace with name +ExtPointError.IDNameCollisionSuffix=already found. Ignoring registration for namespace extension point + +ExtPointError.IDNameLoadErrorPrefix=Could not create namespace with name +ExtPointError.IDNameLoadErrorSuffix=Ignoring registration for namespace extension point diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/impl/standalone/ContainerMessage.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/impl/standalone/ContainerMessage.java new file mode 100644 index 000000000..17b579e71 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/impl/standalone/ContainerMessage.java @@ -0,0 +1,105 @@ +package org.eclipse.ecf.internal.impl.standalone; + +import java.io.Serializable; + +import org.eclipse.ecf.core.identity.ID; + +public final class ContainerMessage { + public final static byte LEAVE = 1; + public final static byte CHANGE = 2; + public final static byte CREATE_REPOBJ = 3; + public final static byte CREATE_REPOBJ_RESP = 4; + public final static byte REPOBJ_MSG = 5; + public final static byte DESTROY_REPOBJ = 6; + + public static final class CreateResponse implements Serializable { + static final long serialVersionUID = -1159925727012441883L; + /** + * @serial myObjID the RepObject ID this create response message is + * in reference to. + */ + ID myObjID; + /** + * @serial myExcept the Exception associated with this create response + * message. Null if no exception generated and everything was + * created properly. + */ + Throwable myExcept; + /** + * @serial mySeq the sequence number issued in the original create + * message. + */ + long mySeq; + + public CreateResponse(ID objID, Throwable except, long sequence) { + myObjID = objID; + myExcept = except; + mySeq = sequence; + } + + } + + public static final class ContainerItemChange implements Serializable { + static final long serialVersionUID = -491316501905217599L; + /** + * @serial changeIDs IDs of SharedObjectContainer group members that are part of this change message. + */ + ID changeIDs[]; + /** + * @serial add boolean indicating whether this change message is an + * add or delete. + */ + boolean add; + /** + * @serial itemData arbitrary data associated with change message. + */ + Serializable myData; + + ContainerItemChange(ID id, boolean a, Serializable data) { + changeIDs = new ID[1]; + changeIDs[0] = id; + add = a; + myData = data; + } + + ContainerItemChange(ID id, boolean a) { + this(id, a, null); + } + + ContainerItemChange(ID id[], boolean a, Serializable data) { + changeIDs = id; + add = a; + myData = data; + } + + ContainerItemChange(ID id[], boolean a) { + this(id, a, null); + } + } + + public static final class SharedObjectPacket implements Serializable { + static final long serialVersionUID = 7884246114924888824L; + ID myFromID; + Serializable myData; + + SharedObjectPacket(ID fromID, Serializable data) { + myFromID = fromID; + myData = data; + } + + } + + public static final class SharedObjectDestroyInfo implements Serializable { + static final long serialVersionUID = -3314198945413220488L; + /** + * @serial myObjID the RepObject ID that is to be destroyed in response + * to this message. + */ + ID myObjID; + + SharedObjectDestroyInfo(ID objID) { + myObjID = objID; + } + } + +} diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/impl/standalone/ContainerPacket.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/impl/standalone/ContainerPacket.java new file mode 100644 index 000000000..691e05cb1 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/impl/standalone/ContainerPacket.java @@ -0,0 +1,22 @@ +package org.eclipse.ecf.internal.impl.standalone; + +import org.eclipse.ecf.core.identity.ID; + +import java.io.Serializable; + +public final class ContainerPacket implements Serializable { + static final long serialVersionUID = 8416382883801007164L; + ID fromID; + public ID toID; + long sequence; + byte msg; + Serializable theData; + + ContainerPacket(ID from, ID to, long seq, byte m, Serializable data) { + fromID = from; + toID = to; + sequence = seq; + msg = m; + theData = data; + } +} diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/impl/standalone/Debug.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/impl/standalone/Debug.java new file mode 100644 index 000000000..a4340e24c --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/impl/standalone/Debug.java @@ -0,0 +1,35 @@ +package org.eclipse.ecf.internal.impl.standalone; + +public class Debug { + + public static boolean ON = false; + protected static Debug staticDebug = null; + + public static Debug create(String key) { + return new Debug(key); + } + + static { + try { + staticDebug = Debug.create("org.composent.api.impl.Debug"); + } catch (Throwable t) { + t.printStackTrace(System.err); + } + } + public static void errDumpStack(Throwable e, String msg) { + if (staticDebug != null) staticDebug.dumpStack(e,msg); + } + public void dumpStack(Throwable e, String msg) { + msg(msg); + e.printStackTrace(System.err); + } + public void msg(String msg) { + System.err.println(msg); + } + protected Debug(String key) { + } + public static void setThreadDebugGroup(Object obj) { + // Do nothing + } + +} diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/impl/standalone/SharedObjectContainer.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/impl/standalone/SharedObjectContainer.java new file mode 100644 index 000000000..209c37a1c --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/impl/standalone/SharedObjectContainer.java @@ -0,0 +1,1454 @@ +package org.eclipse.ecf.internal.impl.standalone; + +import java.io.IOException; +import java.io.Serializable; +import java.lang.reflect.Constructor; +import java.net.URL; +import java.net.URLClassLoader; +import java.security.AccessController; +import java.security.Permissions; +import java.security.PrivilegedAction; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; +import java.util.Enumeration; +import java.util.Map; +import java.util.Vector; + +import org.eclipse.ecf.core.ISharedObject; +import org.eclipse.ecf.core.ISharedObjectConfig; +import org.eclipse.ecf.core.ISharedObjectConnector; +import org.eclipse.ecf.core.ISharedObjectContainer; +import org.eclipse.ecf.core.ISharedObjectContainerConfig; +import org.eclipse.ecf.core.ISharedObjectContainerListener; +import org.eclipse.ecf.core.ISharedObjectContainerTransaction; +import org.eclipse.ecf.core.ISharedObjectContext; +import org.eclipse.ecf.core.SharedObjectAddException; +import org.eclipse.ecf.core.SharedObjectConnectException; +import org.eclipse.ecf.core.SharedObjectContainerJoinException; +import org.eclipse.ecf.core.SharedObjectCreateException; +import org.eclipse.ecf.core.SharedObjectDescription; +import org.eclipse.ecf.core.SharedObjectDisconnectException; +import org.eclipse.ecf.core.SharedObjectInitException; +import org.eclipse.ecf.core.SharedObjectNotFoundException; +import org.eclipse.ecf.core.events.ContainerEvent; +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.core.util.AbstractFactory; +import org.eclipse.ecf.core.util.Event; +import org.eclipse.ecf.internal.comm.AsynchConnectionEvent; +import org.eclipse.ecf.internal.comm.ConnectionEvent; +import org.eclipse.ecf.internal.comm.DisconnectConnectionEvent; +import org.eclipse.ecf.internal.comm.IAsynchConnection; +import org.eclipse.ecf.internal.comm.IAsynchConnectionEventHandler; +import org.eclipse.ecf.internal.comm.ISynchConnectionEventHandler; +import org.eclipse.ecf.internal.comm.SynchConnectionEvent; +import org.eclipse.ecf.internal.impl.standalone.gmm.Item; +import org.eclipse.ecf.internal.util.queue.SimpleQueueImpl; + +public abstract class SharedObjectContainer implements ISharedObjectContainer { + public static Debug debug = + Debug.create(SharedObjectContainer.class.getName()); + // Messages + public static final String CONTAINERCLOSING = "space is closing"; + public static final String BADPARAMDATA = "invalid parameter"; + public static final String BADDATA = "invalid data"; + public static final String JOINFAIL = "join fail"; + public static final String NOTCONNECTED = "not connected"; + public static final String CONNECTEDFAIL = "currently connected"; + public static final String CONNECTINGFAIL = "currently connecting"; + public static final String CONNECTLOCALLYREFUSED = "join fail locally"; + public static final String SHAREDOBJECTALREADYEXISTS = + "shared object already exists: "; + + protected static final Object[] nullArgs = new Object[0]; + protected static final Class[] nullTypes = new Class[0]; + + ISharedObjectContainerConfig config; + protected SharedObjectContainerManager sharedObjectContainerManager; + long sequenceNumber; + MsgReceiver msgReceiver; + boolean isClosing = false; + ThreadGroup sharedObjectLoadingThreadGroup; + ThreadGroup sharedObjectThreadGroup; + + public SharedObjectContainer(ISharedObjectContainerConfig config) throws SecurityException { + this.config = config; + sharedObjectContainerManager = new SharedObjectContainerManager(this, new Item(config.getID())); + sequenceNumber = 0; + msgReceiver = new MsgReceiver(); + sharedObjectLoadingThreadGroup = getParentLoadingTG(); + sharedObjectThreadGroup = getParentSharedObjectTG(); + } + protected ThreadGroup getParentLoadingTG() { + return new ThreadGroup(getID() + ":LoadingThreads"); + } + protected ThreadGroup getParentSharedObjectTG() { + return new ThreadGroup(getID() + ":SharedObjectThreads"); + } + public final ID getID() { + return config.getID(); + } + public ISharedObjectContainerConfig getConfig() { + return config; + } + public final int getItemSize() { + return sharedObjectContainerManager.getSize(); + } + public final int getMaxItems() { + return sharedObjectContainerManager.getMaxItems(); + } + public final int setMaxItems(int max) { + return sharedObjectContainerManager.setMaxItems(max); + } + public final ID[] getOtherItemsIDs() { + return sharedObjectContainerManager.getOtherItemIDs(); + } + public final ID[] getActiveObjIDs() { + return sharedObjectContainerManager.getActiveKeys(); + } + public final boolean isClosing() { + return isClosing; + } + public abstract boolean isServer(); + public abstract boolean isManager(); + /* + public ID createRepObject( + ID newID, + String className, + URL[] codeBase, + String[] argTypes, + Object[] params) + throws Exception { + if (isClosing) + throw new IllegalStateException(CONTAINERCLOSING); + if (newID == null || className == null) + throw new IllegalAccessError(BADPARAMDATA); + SharedObjectDescription info = + new SharedObjectDescription( + getID(), + className, + codeBase, + argTypes, + params, + 0L); + info.setObjID(newID); + logSpaceEvent(LOGLOCALCREATE, info); + addLocalAndWait(info, load(info)); + return newID; + } + */ + /* + public ID addRepObject(ID objID, URL[] codeBase, ISharedObject obj) + throws RepObjectException, AbortException, IllegalAccessException { + if (isClosing) + throw new IllegalStateException(CONTAINERCLOSING); + if (objID == null || obj == null) + throw new IllegalAccessException(BADPARAMDATA); + if (Debug.ON && debug != null) { + debug.msg( + "addRepObject(" + objID + ", " + codeBase + ", " + obj); + } + // First, create init data for this object + SharedObjectDescription info = + new SharedObjectDescription( + getID(), + obj.getClass().getName(), + codeBase, + null, + 0L); + info.setObjID(objID); + logSpaceEvent(LOGLOCALADD, info); + // Do the real work + addLocalAndWait(info, obj); + return objID; + } + protected void addLocalAndWait(SharedObjectDescription info, ISharedObject obj) + throws IllegalAccessException, RepObjectException, AbortException { + addLocal(info, obj); + // If object implements TransactionRepObject interface, call waitForCompleted method + if (obj instanceof TransactionRepObject + && getID().equals(info.myHomeID)) { + if (Debug.ON && debug != null) { + debug.msg( + "addLocalAndWait. Waiting on TransactionRepObject " + + obj + + " for completion"); + } + // Wait as defined by object + ((TransactionRepObject) obj).waitForCommitted(); + } + } + */ + /* + protected void addLocal(SharedObjectDescription info, ISharedObject obj) + throws IllegalAccessException, RepObjectException { + RepObjConfig aConfig = makeRepObjConfig(info, null); + // Log that this is happening + logSpaceEvent(LOGINIT, aConfig); + // Call init + try { + obj.init(aConfig); + boolean res = + sharedObjectContainerManager.addRepObj( + new SharedObjectWrapper( + aConfig, + obj, + this, + getRepObjectThreadGroup(info, aConfig))); + if (!res) + throw new RepObjectException( + SHAREDOBJECTALREADYEXISTS + aConfig.getID()); + ; + } catch (RepObjectException e) { + logSpaceException(LOGCREATEEXCEPTION, e, info); + throw e; + } + // Create SharedObjectWrapper, and add to local membership manager + logSpaceEvent(LOGACTIVATE, aConfig); + } + */ + protected ISharedObject load(final SharedObjectDescription info) + throws Exception { + ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); + if (contextClassLoader == null) contextClassLoader = SharedObjectContainer.class.getClassLoader(); + Map dict = info.getProperties(); + String [] constructorArgTypes = null; + Object [] constructorArgs = null; + if (dict != null) { + constructorArgTypes = (String []) dict.get("constructorArgTypes"); + constructorArgs = (Object []) dict.get("constructorArgs"); + } + final ClassLoader cl = getClassLoader(contextClassLoader,info); + Class argTypes[] = AbstractFactory.getClassesForTypes(constructorArgTypes,constructorArgs,cl); + final Class[] types = argTypes; + + Object [] args = constructorArgs; + if (args == null) + args = new Object[0]; + + final Object [] theArgs = args; + final Class newClass = Class.forName(info.getClassname(), true, cl); + Object newObject = null; + try { + newObject = + AccessController.doPrivileged(new PrivilegedExceptionAction() { + public Object run() throws Exception { + Constructor aConstructor = newClass.getConstructor(types); + logContainerEvent(null, info); + aConstructor.setAccessible(true); + Thread.currentThread().setContextClassLoader(cl); + return aConstructor.newInstance(theArgs); + } + }); + } catch (java.security.PrivilegedActionException e) { + logContainerException(null, e.getException(), info); + throw e.getException(); + } + return verifyRepObjType(info, newObject); + } + public abstract void joinSpace(ID remoteSpace, Serializable data) + throws IOException; + public abstract void leaveSpace(); + + protected void destroyItems(boolean includeLocal) { + synchronized (sharedObjectContainerManager) { + Object[] members = sharedObjectContainerManager.getItems(); + for (int i = 0; i < members.length; i++) { + ID id = (ID) ((Item) members[i]).getID(); + if (includeLocal || !id.equals(getID())) { + memberLeave( + id, + (IAsynchConnection) ((Item) members[i]).getData()); + } + } + } + } + public final void terminate(long timeout) throws SecurityException { + if (Debug.ON && debug != null) { + debug.msg("terminate(" + timeout + ")"); + } + // First, check to see that caller thread has permission to access + // the two thread groups. + sharedObjectLoadingThreadGroup.checkAccess(); + sharedObjectThreadGroup.checkAccess(); + if (Debug.ON && debug != null) { + debug.msg( + "terminate. Caller thread has access to terminating threads."); + } + logContainerEvent(null, new Long(timeout)); + // No group member or replicated object changes while the member removal is going on + synchronized (sharedObjectContainerManager) { + // First, set closing flag. This prevents other threads from doing things to + // prevent shutdown. Once this is set, this space is a goner. + if (isClosing) { + if (Debug.ON && debug != null) { + debug.msg( + "terminate. Space already terminated."); + } + return; + } else + isClosing = true; + // Allow subclasses to run termination code. + subclassOverrideableTerminate(); + + // Then destroy all members. This will forcibly close all connections to remote spaces, + // destroy client replications, and also destroy host replications if includeHosts is true + if (Debug.ON && debug != null) { + debug.msg("terminate. Calling destroyMembers..."); + } + destroyItems(true); + if (Debug.ON && debug != null) { + debug.msg("terminate. DestroyMembers complete."); + } + } + if (Debug.ON && debug != null) { + debug.msg("terminate. Calling loading group interrupt."); + } + try { + // If any loading threads, just interrupt them...they don't get a chance to complete + sharedObjectLoadingThreadGroup.interrupt(); + synchronized (this) { + notifyAll(); + } + } catch (Exception e) { + } + + long endTime = System.currentTimeMillis() + timeout; + // Everything should now be going away. + // Before we forcibly interrupt executing threads, however, we will wait timeout ms + try { + while (checkForRunningThreads() + && System.currentTimeMillis() < endTime) { + if (Debug.ON && debug != null) { + debug.msg( + "terminate. Waiting for " + timeout / 10 + "ms"); + } + synchronized (this) { + wait(timeout / 10); + } + } + } catch (InterruptedException e) { + } finally { + // Do the nasty + interruptThreads(); + logContainerEvent(null, getID()); + if (Debug.ON && debug != null) { + debug.msg("termination complete for " + getID()); + } + } + } + protected boolean checkForRunningThreads() { + int activeCount = sharedObjectThreadGroup.activeCount(); + int activeGroupCount = sharedObjectThreadGroup.activeGroupCount(); + if (Debug.ON && debug != null) { + debug.msg( + "checkForRunningThreads(). Active is " + + activeCount + + ". ActiveGroup is " + + activeGroupCount); + } + return ((activeCount + activeGroupCount) > 0); + } + + protected void subclassOverrideableTerminate() { + // Allow subclasses to provide termination code + } + + protected void interruptThreads() { + if (Debug.ON && debug != null) { + debug.msg("interruptThreads()"); + } + try { + // Interrupt replicated object threads + sharedObjectThreadGroup.interrupt(); + synchronized (this) { + notifyAll(); + } + } catch (Exception e) { + } + } + + protected void sendMsg(ID toID, byte msg, Serializable data) + throws IOException { + synchronized (sharedObjectContainerManager) { + ID ourID = getID(); + if (!ourID.equals(toID)) + queuePacket(new ContainerPacket(ourID, toID, getSeqNumber(), msg, data)); + } + } + protected ID[] sendCreateMsg(ID toID, SharedObjectDescription createInfo) + throws IOException { + ID[] ids = null; + if (toID == null) { + synchronized (sharedObjectContainerManager) { + // Send message to all + // XXX TODO + //sendMsg(null, ContainerMessage.CREATE_REPOBJ, createInfo); + ids = getOtherItemsIDs(); + } + } else { + if (getID().equals(toID)) { + ids = new ID[0]; + } else { + // XXX TODO + //sendMsg(toID, ContainerMessage.CREATE_REPOBJ, createInfo); + ids = new ID[1]; + ids[0] = toID; + } + } + return ids; + } + protected void deliverEventToSharedObject(ID fromID, ID target, Event msg) + throws SharedObjectNotFoundException { + if (target == null) + throw new SharedObjectNotFoundException(); + synchronized (sharedObjectContainerManager) { + SharedObjectWrapper aMeta = sharedObjectContainerManager.getFromActive(target); + if (aMeta == null) + throw new SharedObjectNotFoundException(target.getName()); + // Deliver message + aMeta.deliverEventFromSharedObject(fromID, msg); + } + } + protected void deliverEventToSharedObjects(ID fromID, ID[] targets, Event msg) { + synchronized (sharedObjectContainerManager) { + if (targets == null) + targets = sharedObjectContainerManager.getActiveKeys(); + for (int i = 0; i < targets.length; i++) { + try { + if (!fromID.equals(targets[i])) { + deliverEventToSharedObject( + fromID, + targets[i], + null + /* + new SharedObjectEvent( + msg.getClassName(), + msg.getMethodName(), + msg.getArgs()) + */ + ); + + } + } catch (SharedObjectNotFoundException e) { + logContainerException( + null, + e, + targets[i]); + } + } + } + } + abstract protected void queuePacket(ContainerPacket packet) throws IOException; + abstract protected void forwardToRemote( + ID from, + ID to, + byte msg, + Serializable data) + throws IOException; + abstract protected void forwardExcluding( + ID from, + ID excluding, + byte msg, + Serializable data) + throws IOException; + protected final void forward( + ID fromID, + ID toID, + byte msg, + Serializable data) + throws IOException { + if (toID == null) { + forwardExcluding(fromID, fromID, msg, data); + } else { + forwardToRemote(fromID, toID, msg, data); + } + } + + protected void handleAsynchEvent(AsynchConnectionEvent evt) + throws IOException, IllegalAccessException { + if (isClosing) + throw new IllegalStateException(CONTAINERCLOSING); + processAsynchPacket(verifyPacket((Serializable) evt.getOData())); + } + protected void processAsynchPacket(ContainerPacket p) throws IOException, IllegalAccessException { + switch (p.msg) { + case ContainerMessage.CHANGE : + handleChangeMsg(p.fromID, p.toID, p.sequence, p.theData); + break; + case ContainerMessage.CREATE_REPOBJ : + handleCreateMsg(p.fromID, p.toID, p.sequence, p.theData); + break; + case ContainerMessage.CREATE_REPOBJ_RESP : + handleCreateRespMsg(p.fromID, p.toID, p.sequence, p.theData); + break; + case ContainerMessage.REPOBJ_MSG : + handleSharedObjectEvent(p.fromID, p.toID, p.sequence, p.theData); + break; + case ContainerMessage.DESTROY_REPOBJ : + handleDestroyMsg(p.fromID, p.toID, p.sequence, p.theData); + break; + default : + if (Debug.ON && debug != null) { + debug.msg("UNRECOGNIZED MESSAGE...throwing"); + } + IllegalAccessException e = + new IllegalAccessException( + BADDATA + + ":" + + p.fromID + + ":" + + p.toID + + ":" + + p.sequence + + ":" + + p.msg); + logContainerException(null, e, null); + throw e; + } + } + + protected ContainerPacket verifyPacket(Serializable data) throws IOException, IllegalAccessException { + ContainerPacket p = null; + try { + p = (ContainerPacket) data; + } catch (ClassCastException e) { + throw new IllegalAccessException(BADDATA + ":" + data); + } + return p; + } + + protected Serializable handleSynchEvent(SynchConnectionEvent evt) + throws IOException, IllegalAccessException { + if (isClosing) + throw new IllegalStateException(CONTAINERCLOSING); + return processSynchPacket((IAsynchConnection) evt.getConnection(), verifyPacket((Serializable) evt.getOData())); + } + protected Serializable processSynchPacket( + IAsynchConnection conn, + ContainerPacket aPacket) + throws IOException { + if (aPacket.fromID == null) { + IllegalAccessException e = + new IllegalAccessException( + BADDATA + ":" + aPacket.fromID + ":" + aPacket.toID); + logContainerException(null, e, aPacket); + } + if (aPacket.msg == ContainerMessage.LEAVE) { + handleSpaceLeave(aPacket); + synchronized (sharedObjectContainerManager) { + memberLeave(aPacket.fromID, conn); + } + } + return null; + } + + protected Serializable getLeaveData(ID leaveReceiver) { + /* + RepSpaceLeaveListener l = null; + synchronized (myLeaveListenerLock) { + l = myLeaveListener; + } + Serializable result = null; + if (l != null) { + result = l.getLeaveData(getID(), leaveReceiver); + } + if (Debug.ON && debug != null) { + debug.msg( + "getLeaveData(" + leaveReceiver + ") returns " + result); + } + return result; + */ + return null; + } + protected void handleSpaceLeave(ContainerPacket aPacket) { + if (aPacket == null) + return; + if (Debug.ON && debug != null) { + debug.msg( + "handleSpaceLeave(" + + aPacket.fromID + + "," + + aPacket.theData + + ")"); + } + /* + RepSpaceLeaveListener l = null; + synchronized (myLeaveListenerLock) { + l = myLeaveListener; + } + if (l != null) { + l.handleSpaceLeave(getID(), aPacket.fromID, aPacket.theData); + } + */ + } + protected void handleDisconnectEvent(DisconnectConnectionEvent evt) { + processDisconnect((IAsynchConnection) evt.getConnection(), evt.getException(), (SimpleQueueImpl) evt.getData()); + } + protected void processDisconnect( + IAsynchConnection conn, + Throwable e, + SimpleQueueImpl unsent) { + // Get GMM lock (no group membership changes during this) + synchronized (sharedObjectContainerManager) { + if (e != null) { + ID memID = getIDForConnection(conn); + if (memID != null) { + memberLeave(memID, conn); + } + } + handleUnsent(unsent, e); + } + } + protected abstract void handleChangeMsg( + ID fromID, + ID toID, + long seqNum, + Serializable data) + throws IOException; + protected void handleCreateMsg( + ID fromID, + ID toID, + long seqNum, + Serializable data) + throws IOException, IllegalAccessException { + SharedObjectDescription createInfo = null; + try { + createInfo = (SharedObjectDescription) data; + if (fromID == null + || createInfo == null + || createInfo.getID() == null + || createInfo.getHomeID() == null + || createInfo.getClassname() == null) + throw new Exception(); + } catch (Exception e) { + IllegalAccessException t = + new IllegalAccessException( + BADDATA + + ":" + + fromID + + ":" + + toID + + ":" + + seqNum + + ":" + + ContainerMessage.CREATE_REPOBJ); + logContainerException(null, t, data); + throw t; + } + Object obj = checkCreateObject(fromID, toID, seqNum, createInfo); + if (obj != null && (toID == null || toID.equals(getID()))) { + // Then check to see if returned object was permissions object...if so, then + // pass along to LoadingRepObject + LoadingSharedObject newObj = + new LoadingSharedObject(createInfo, handleObjectCheckResult(obj)); + synchronized (sharedObjectContainerManager) { + // Put into membership manager. This starts thread for retrieving class bytes, etc. + if (!sharedObjectContainerManager.addToLoading(newObj)) { + // Instance of object already there. Send failure msg back. + try { + sendMsg( + fromID, + ContainerMessage.CREATE_REPOBJ_RESP, + new ContainerMessage.CreateResponse( + createInfo.getID(), + new SharedObjectAddException( + createInfo.getID() + " already present"), + createInfo.getIdentifier())); + } catch (Exception e1) { + // If an exception is thrown by this, disconnection has already occurred, + // so no need to rethrow + if (Debug.ON && debug != null) { + debug.dumpStack( + e1, + "Exception sending create failure message back to " + + fromID); + } + logContainerException(null, e1, null); + } + } + // Forward to other remote repspace instances and return. This only has + // effect if this repspace is a server. + forward(fromID, toID, ContainerMessage.CREATE_REPOBJ, data); + return; + } + } + // Even if we don't create the object, if we're a server, we'll forward the message + // to others. Servers can prevent this by throwing an ioexception from checkCreateObject. + synchronized (sharedObjectContainerManager) { + forward(fromID, toID, ContainerMessage.CREATE_REPOBJ, data); + } + } + protected Permissions handleObjectCheckResult(Object obj) { + if (obj == null) + return null; + Permissions p = null; + if (obj instanceof Vector) { + Vector v = (Vector) obj; + for (java.util.Enumeration e = v.elements(); + e.hasMoreElements(); + ) { + Object o = e.nextElement(); + if (o instanceof java.security.Permission) { + if (p == null) + p = new Permissions(); + p.add((java.security.Permission) o); + } + } + } + return p; + } + protected Object checkCreateObject( + ID fromID, + ID toID, + long seqNum, + SharedObjectDescription constructor) + throws IOException { + if (Debug.ON && debug != null) { + debug.msg( + "checkCreateObject(" + + fromID + + ", " + + toID + + ", " + + seqNum + + ", " + + constructor); + } + /* + synchronized (myCreateHandlerLock) { + if (checkCreateHandler != null) { + logSpaceEvent(LOGCHECKCREATE, constructor); + return checkCreateHandler.checkCreateObject( + fromID, + toID, + seqNum, + constructor); + } else + // By default, allow the object to be created by returning reference to self + return this; + } + */ + return this; + } + protected void handleCreateRespMsg( + ID fromID, + ID toID, + long seqNum, + Serializable data) + throws IOException, IllegalAccessException { + ContainerMessage.CreateResponse resp = null; + try { + resp = (ContainerMessage.CreateResponse) data; + if (fromID == null || toID == null || resp == null) + throw new Exception(); + } catch (Exception e) { + IllegalAccessException t = + new IllegalAccessException( + BADDATA + + ":" + + fromID + + ":" + + toID + + ":" + + seqNum + + ":" + + ContainerMessage.CREATE_REPOBJ_RESP); + logContainerException(null, t, data); + throw t; + } + synchronized (sharedObjectContainerManager) { + if (toID != null && toID.equals(getID())) { + // Get SharedObjectWrapper from local membership manager + SharedObjectWrapper aMeta = + sharedObjectContainerManager.getFromActive(resp.myObjID); + if (aMeta == null) { + // Not found...just log; + logContainerException( + null, + new SharedObjectNotFoundException(resp.myObjID.getName()), + null); + return; + } + // Otherwise, deliver message locally + aMeta.createMsgResp(fromID, resp); + } else { + forwardToRemote( + fromID, + toID, + ContainerMessage.CREATE_REPOBJ_RESP, + data); + } + } + } + protected void handleSharedObjectEvent( + ID fromID, + ID toID, + long seqNum, + Serializable data) + throws IOException, IllegalAccessException { + ContainerMessage.SharedObjectPacket aPacket = null; + try { + aPacket = (ContainerMessage.SharedObjectPacket) data; + if (fromID == null || aPacket == null || aPacket.myFromID == null) + throw new Exception(); + } catch (Exception e) { + IllegalAccessException t = + new IllegalAccessException( + BADDATA + + ":" + + fromID + + ":" + + toID + + ":" + + seqNum + + ":" + + ContainerMessage.REPOBJ_MSG); + logContainerException(null, t, null); + throw t; + } + synchronized (sharedObjectContainerManager) { + if (toID == null || toID.equals(getID())) { + SharedObjectWrapper aMeta = + sharedObjectContainerManager.getFromActive(aPacket.myFromID); + if (aMeta == null) { + // Not found...just log; + logContainerException( + null, + new SharedObjectNotFoundException(aPacket.myFromID.getName()), + null); + } else + aMeta.deliverObjectFromRemote(fromID, aPacket.myData); + } + // forward on in either case + forward(fromID, toID, ContainerMessage.REPOBJ_MSG, data); + } + } + protected void handleDestroyMsg( + ID fromID, + ID toID, + long seqNum, + Serializable data) + throws IOException, IllegalAccessException { + ContainerMessage.SharedObjectDestroyInfo info = null; + try { + info = (ContainerMessage.SharedObjectDestroyInfo) data; + if (fromID == null || info == null || info.myObjID == null) + throw new Exception(); + } catch (Exception e) { + IllegalAccessException t = + new IllegalAccessException( + BADDATA + + ":" + + fromID + + ":" + + toID + + ":" + + seqNum + + ":" + + ContainerMessage.DESTROY_REPOBJ); + logContainerException(null, t, null); + throw t; + } + synchronized (sharedObjectContainerManager) { + if (sharedObjectContainerManager.isLoading(info.myObjID)) { + sharedObjectContainerManager.removeSharedObjectFromLoading(info.myObjID); + } else { + try { + sharedObjectContainerManager.destroySharedObject(info.myObjID); + } catch (Exception e) { + logContainerException( + null, + e, + info.myObjID); + } + } + // forward on + forward(fromID, toID, ContainerMessage.DESTROY_REPOBJ, data); + } + } + protected void handleUnsent(SimpleQueueImpl unsent, Throwable e) { + Object[] msgs = unsent.flush(); + if (msgs != null) { + for (int i = 0; i < msgs.length; i++) { + try { + ContainerPacket p = (ContainerPacket) msgs[i]; + if (p.msg == ContainerMessage.REPOBJ_MSG) { + ContainerMessage.SharedObjectPacket repPacket = + (ContainerMessage.SharedObjectPacket) p.theData; + SharedObjectWrapper aMeta = + sharedObjectContainerManager.getFromActive( + repPacket.myFromID); + if (aMeta != null) { + aMeta.deliverRemoteMessageFailed( + p.toID, + repPacket.myData, + e); + } + } + } catch (ClassCastException except) { + // Ignore...wrong type of message + } + } + } + } + protected abstract ID getIDForConnection(IAsynchConnection conn); + + protected ClassLoader getClassLoader(final ClassLoader contextClassLoader, final SharedObjectDescription aConfig) { + final URL[] urls = null; + return ( + ClassLoader) AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + ClassLoader loader = null; + if (urls == null) { + // Use same classloader that was used to load this class + loader = contextClassLoader; + } else { + loader = + new URLClassLoader(urls, contextClassLoader); + } + return loader; + } + }); + } + protected ISharedObject verifyRepObjType( + SharedObjectDescription config, + Object newObject) + throws ClassCastException { + return (ISharedObject) newObject; + } + protected ISharedObjectConfig makeRepObjConfig( + SharedObjectDescription aConfig, + Permissions perms) + throws IllegalAccessException { + // XXX TODO + //return new RepObjConfig(aConfig, makeReference(aConfig, perms)); + return null; + } + protected ISharedObjectContext makeReference( + SharedObjectDescription aConfig, + Permissions perms) + throws IllegalAccessException { + if (Debug.ON && debug != null) { + debug.msg( + "makeReference(" + aConfig + ", " + perms + ")"); + } + // XXX TODO + //return new RepSpaceReference(this, aConfig.myObjID, perms); + return null; + } + protected ThreadGroup getLoadingThreadGroup(SharedObjectDescription createData) { + // Return null. Subclasses may override as desired. + return sharedObjectLoadingThreadGroup; + } + protected ThreadGroup getSharedObjectThreadGroup( + SharedObjectDescription info, + ISharedObjectConfig config) { + // Return null. Subclasses may override as desired. + return sharedObjectThreadGroup; + } + protected Thread getSharedObjectThread( + ID identity, + ThreadGroup tg, + Runnable run, + String name) { + return new Thread(tg, run, name); + } + protected void logContainerEvent(String msg, Object param) { + } + protected void logContainerException(String msg, Exception e, Object param) { + } + protected void logSharedObjectEvent(ID repobjID, String msg, Object param) { + } + protected void logSharedObjectException( + ID repobjID, + String msg, + Exception e, + Object param) { + } + + protected void moveFromLoadingToActive(SharedObjectWrapper ro) + throws SharedObjectNotFoundException { + sharedObjectContainerManager.moveFromLoadingToActive(ro); + } + + protected void removeFromLoading(ID id) { + sharedObjectContainerManager.removeSharedObjectFromLoading(id); + } + + synchronized final long getSeqNumber() { + return sequenceNumber++; + } + protected boolean addNewRemoteItem(ID itemID) { + return addNewRemoteItem(itemID, null); + } + protected boolean addNewRemoteItem(ID itemID, Object data) { + return sharedObjectContainerManager.addItem(new Item(itemID, data)); + } + protected boolean removeRemoteItem(ID itemID) { + logContainerEvent(null, itemID); + return sharedObjectContainerManager.removeItem(itemID); + } + protected void memberLeave(ID leaveID, IAsynchConnection conn) { + // No changes to group membership while this is happening + if (removeRemoteItem(leaveID)) { + try { + forwardExcluding( + getID(), + leaveID, + ContainerMessage.CHANGE, + new ContainerMessage.ContainerItemChange(leaveID, false)); + } catch (IOException e) { + if (Debug.ON && debug != null) { + debug.dumpStack( + e, + "memberLeave. Exception calling forwardExcluding"); + } + logContainerException(null, e, null); + + } + } + // disconnect connection + killConnection(conn); + } + protected final void killConnection(IAsynchConnection conn) { + try { + if (conn != null) + conn.disconnect(); + } catch (IOException e) { + if (Debug.ON && debug != null) { + debug.dumpStack(e, "Exception disconnecting " + conn); + } + logContainerException(null, e, conn); + } + } + public ISharedObject getSharedObject(ID objID) { + if (objID == null) return null; + SharedObjectWrapper meta = sharedObjectContainerManager.getFromActive(objID); + if (meta == null) return null; + return meta.sharedObject; + } + + public ISharedObject getSharedObjectFromAny(ID objID) + throws SharedObjectNotFoundException { + if (objID == null) + throw new SharedObjectNotFoundException(); + return sharedObjectContainerManager.getFromAny(objID).sharedObject; + } + public void destroySharedObject(ID id) throws SharedObjectNotFoundException { + if (id == null) + throw new SharedObjectNotFoundException(); + logContainerEvent(null, id); + sharedObjectContainerManager.destroySharedObject(id); + } + public void destroySharedObjectSelf(ID id) throws SharedObjectNotFoundException { + if (id == null) + throw new SharedObjectNotFoundException(); + SharedObjectWrapper meta = sharedObjectContainerManager.getFromActive(id); + if (meta == null) + throw new SharedObjectNotFoundException(); + meta.destroySelf(); + } + protected void notifySharedObjectActivated(ID obj) { + logContainerEvent(null, obj); + sharedObjectContainerManager.notifyOthersActivated(obj); + } + protected void notifySharedObjectDeactivated(ID obj) { + logContainerEvent(null, obj); + sharedObjectContainerManager.notifyOthersDeactivated(obj); + } + protected final class MsgReceiver implements IAsynchConnectionEventHandler, ISynchConnectionEventHandler { + + public void handleDisconnectEvent(ConnectionEvent evt) { + SharedObjectContainer.this.handleDisconnectEvent( + (DisconnectConnectionEvent) evt); + } + public boolean handleSuspectEvent(ConnectionEvent event) { + // Do nothing + // Returning true indicates that further processing of this + // event should continue + return true; + } + public ClassLoader getClassLoaderForID(ID id) { + return this.getClass().getClassLoader(); + } + public void handleAsynchEvent(ConnectionEvent evt) throws IOException { + // Pass to handler + try { + SharedObjectContainer.this.handleAsynchEvent((AsynchConnectionEvent) evt); + } catch (IllegalAccessException e) { + throw new IOException("Illegal data access handling event "+evt); + } + } + public Object handleSynchEvent(ConnectionEvent evt) + throws IOException { + // Handle synch packet + try { + return SharedObjectContainer.this.handleSynchEvent((SynchConnectionEvent) evt); + } catch (IllegalAccessException e) { + throw new IOException("Illegal data access handling event "+evt); + } + } + + public Object getAdapter(Class clazz) { + return null; + } + } + protected final class LoadingSharedObject implements ISharedObject { + Thread runnerThread; + SharedObjectDescription sharedObjectDescription; + Permissions loadingPerms; + + LoadingSharedObject(SharedObjectDescription create) { + sharedObjectDescription = create; + } + + LoadingSharedObject(SharedObjectDescription create, Permissions perms) { + sharedObjectDescription = create; + loadingPerms = perms; + } + + void start() { + if (runnerThread == null) { + runnerThread = + ( + Thread) AccessController + .doPrivileged(new PrivilegedAction() { + public Object run() { + return getThread(); + } + }); + runnerThread.start(); + } + } + Thread getThread() { + return new Thread(getLoadingThreadGroup(sharedObjectDescription), new Runnable() { + public void run() { + try { + if (Debug.ON && debug != null) { + debug.msg( + "Starting loading of object " + + sharedObjectDescription.getID()); + } + // Check to make sure thread has not been interrupted and space is not closing...if it has, throw + if (Thread.currentThread().isInterrupted() + || isClosing) + throw new InterruptedException("Interrupted"); + logContainerEvent(null, sharedObjectDescription); + // First load given object + ISharedObject obj = load(sharedObjectDescription); + if (Debug.ON && debug != null) { + debug.msg( + "Calling init for object " + sharedObjectDescription.getID()); + } + // Get config info for new object + ISharedObjectConfig aConfig = + makeRepObjConfig(sharedObjectDescription, loadingPerms); + // Log that this is happening + logContainerEvent(null, aConfig); + // Call init method on new object. + obj.init(aConfig); + // Check to make sure thread has not been interrupted...if it has, throw + if (Thread.currentThread().isInterrupted() + || isClosing) + throw new InterruptedException("Interrupted"); + + if (Debug.ON && debug != null) { + debug.msg( + "Putting object " + + sharedObjectDescription.getID() + + " in local membership manager"); + } + // If not currently *on* loading list, does nothing. + logContainerEvent(null, aConfig); + // Create meta object and move from loading to active list. + SharedObjectContainer.this.moveFromLoadingToActive( + new SharedObjectWrapper( + aConfig, + obj, + SharedObjectContainer.this, + getSharedObjectThreadGroup(sharedObjectDescription, aConfig))); + } catch (Exception e) { + if (Debug.ON && debug != null) { + debug.dumpStack( + e, + "Exception loading new object " + + sharedObjectDescription.getID()); + } + SharedObjectContainer.this.removeFromLoading(sharedObjectDescription.getID()); + try { + SharedObjectContainer.this.sendMsg( + sharedObjectDescription.getID(), + ContainerMessage.CREATE_REPOBJ_RESP, + new ContainerMessage.CreateResponse( + sharedObjectDescription.getID(), + e, + sharedObjectDescription.getIdentifier())); + } catch (Exception e1) { + logContainerException(null, e1, null); + // If this message send fails, we're doomed anyway + if (Debug.ON && debug != null) { + debug.dumpStack( + e1, + "Exception sending create failure message for object " + + sharedObjectDescription.getID()); + } + } + logContainerException( + "loadingRunner. Exception loading for " + + sharedObjectDescription.getID(), + e, + null); + } + } + }, "LoadingRunner for " + sharedObjectDescription.getID()); + } + // ISharedObject + public void init(ISharedObjectConfig aConfig) throws SharedObjectInitException { + // Not relevant for this class + } + public void handleEvent(Event msg) { + // Not relevant for this class...might want to handle a remote destroy message eventually. + } + public void handleEvents(Event [] msgs) { + // Not relevant for this class...might want to handle a remote destroy message eventually. + } + public void dispose(ID spaceID) { + // Not relevant for this class + } + public Object getAdapter(Class clazz) { + return null; + } + public ID getID() { + return sharedObjectDescription.getID(); + } + public ID getHomeID() { + return sharedObjectDescription.getHomeID(); + } + } + + + Vector listeners = new Vector(); + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#addPeerListener(org.eclipse.ecf.core.ISharedObjectContainerListener) + */ + public void addListener(ISharedObjectContainerListener l) { + listeners.add(l); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#removePeerListener(org.eclipse.ecf.core.ISharedObjectContainerListener) + */ + public void removeListener(ISharedObjectContainerListener l) { + listeners.remove(l); + } + protected void fireListeners(ContainerEvent evt) { + for (Enumeration e = listeners.elements(); e.hasMoreElements();) { + ISharedObjectContainerListener l = (ISharedObjectContainerListener) e + .nextElement(); + l.handleEvent(evt); + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#terminatePeer(long) + */ + public void dispose(long waittime) { + // TODO Auto-generated method stub + + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#joinGroup(org.eclipse.ecf.identity.ID, + * java.lang.Object) + */ + public void joinGroup(ID groupID, Object loginData) + throws SharedObjectContainerJoinException { + try { + joinSpace(groupID,(Serializable)loginData); + } catch (IOException e) { + throw new SharedObjectContainerJoinException("IOException joining",e); + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#leaveGroup() + */ + public void leaveGroup() { + leaveSpace(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#getGroupID() + */ + public ID getGroupID() { + return null; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#getGroupMembership() + */ + public ID[] getGroupMembership() { + return getOtherItemsIDs(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#isGroupManager() + */ + public boolean isGroupManager() { + return isManager(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#isGroupServer() + */ + public boolean isGroupServer() { + return isServer(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#getAdapter(java.lang.Class) + */ + public Object getAdapter(Class clazz) { + return null; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#getSharedObjectIDs() + */ + public ID[] getSharedObjectIDs() { + return getActiveObjIDs(); + } + + protected static Object loadObject(final ClassLoader cl, String className, + String[] argTypes, Object[] a) throws Exception { + final Class[] types = AbstractFactory.getClassesForTypes(argTypes, a, + cl); + final Object[] args = (a == null) ? nullArgs : a; + // Load RepObject class(es), after getting appropriate classloader + final Class newClass = Class.forName(className, true, cl); + Object newObject = null; + try { + // Do privileged operation. Get appropriate constructor from new + // class, + // and create new instance. + newObject = AccessController + .doPrivileged(new PrivilegedExceptionAction() { + public Object run() throws Exception { + Constructor aConstructor = newClass + .getConstructor(types); + aConstructor.setAccessible(true); + // Now actually create the object. + return aConstructor.newInstance(args); + } + }); + } catch (PrivilegedActionException e) { + throw e.getException(); + } + return newObject; + } + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#createSharedObject(org.eclipse.ecf.core.SharedObjectDescription) + */ + public ID createSharedObject(SharedObjectDescription sd, + ISharedObjectContainerTransaction trans) + throws SharedObjectCreateException { + // TODO Auto-generated method stub + return null; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#addSharedObject(org.eclipse.ecf.identity.ID, + * org.eclipse.ecf.core.ISharedObject, java.util.Map, + * org.eclipse.ecf.core.ISharedObjectContainerTransaction) + */ + public ID addSharedObject(ID sharedObjectID, ISharedObject sharedObject, + Map dict, ISharedObjectContainerTransaction trans) + throws SharedObjectAddException { + // TODO Auto-generated method stub + return null; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#getSharedObjectAdapter(org.eclipse.ecf.identity.ID, + * java.lang.Class) + */ + public Object getSharedObjectAdapter(ID sharedObjectID, Class adapterClass) + throws SharedObjectNotFoundException { + synchronized (sharedObjectContainerManager) { + ISharedObject so = getSharedObject(sharedObjectID); + if (so == null) throw new SharedObjectNotFoundException("shared object "+sharedObjectID.getName()+ " not found"); + return so.getAdapter(adapterClass); + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#removeSharedObject(org.eclipse.ecf.identity.ID) + */ + public ISharedObject removeSharedObject(ID sharedObjectID) { + synchronized (sharedObjectContainerManager) { + ISharedObject so = getSharedObject(sharedObjectID); + if (so == null) return null; + try { + destroySharedObject(sharedObjectID); + } catch (SharedObjectNotFoundException e) { + return null; + } + return so; + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#connectSharedObjects(org.eclipse.ecf.identity.ID, + * org.eclipse.ecf.identity.ID[]) + */ + public ISharedObjectConnector connectSharedObjects(ID sharedObjectFrom, + ID[] sharedObjectsTo) throws SharedObjectConnectException { + // TODO Auto-generated method stub + return null; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#disconnectSharedObjects(org.eclipse.ecf.core.ISharedObjectConnector) + */ + public void disconnectSharedObjects(ISharedObjectConnector connector) + throws SharedObjectDisconnectException { + // TODO Auto-generated method stub + } + + +} diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/impl/standalone/SharedObjectContainerManager.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/impl/standalone/SharedObjectContainerManager.java new file mode 100644 index 000000000..4ea7c701d --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/impl/standalone/SharedObjectContainerManager.java @@ -0,0 +1,341 @@ +package org.eclipse.ecf.internal.impl.standalone; + +import org.eclipse.ecf.core.SharedObjectNotFoundException; +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.internal.impl.standalone.Debug; +import org.eclipse.ecf.internal.impl.standalone.gmm.GroupManager; +import org.eclipse.ecf.internal.impl.standalone.gmm.Item; +import org.eclipse.ecf.internal.impl.standalone.gmm.ItemChange; + +import java.util.Observer; +import java.util.Observable; +import java.util.HashSet; +import java.util.TreeMap; +import java.util.Iterator; + +class SharedObjectContainerManager implements Observer { + static Debug myDebug = Debug.create(SharedObjectContainerManager.class.getName()); + + SharedObjectContainer container; + Item containerPeer; + GroupManager groupManager; + int maxItems = -1; + TreeMap loadingSharedObjects, activeSharedObjects; + + SharedObjectContainerManager(SharedObjectContainer space, Item ourMember) { + container = space; + groupManager = new GroupManager(); + groupManager.addObserver(this); + loadingSharedObjects = new TreeMap(); + activeSharedObjects = new TreeMap(); + addItem(ourMember); + containerPeer = ourMember; + } + + synchronized boolean addItem(Item m) { + if (maxItems > 0 && getSize() > maxItems) { + return false; + } else { + return groupManager.addItem(m); + } + } + synchronized int setMaxItems(int max) { + int old = maxItems; + maxItems = max; + return old; + } + synchronized int getMaxItems() { + return maxItems; + } + + synchronized boolean removeItem(Item m) { + boolean res = groupManager.removeItem(m); + if (res) { + destroySharedObjects(m); + } + return res; + } + + synchronized boolean removeItem(ID id) { + Item m = getItemForID(id); + if (m == null) + return false; + return removeItem(m); + } + + void removeAllItems() { + removeAllItems(null); + } + + void removeClientItems() { + removeAllItems(containerPeer); + } + + synchronized void removeAllItems(Item exception) { + Object m[] = getItems(); + for (int i = 0; i < m.length; i++) { + Item mem = (Item) m[i]; + if (exception == null || !exception.equals(mem)) + removeItem(mem); + } + } + + synchronized Object[] getItems() { + return groupManager.getItems(); + } + + synchronized ID[] getOtherItemIDs() { + return groupManager.getItemIDs(containerPeer.getID()); + } + + synchronized ID[] getItemIDs() { + return groupManager.getItemIDs(null); + } + + synchronized Item getItemForID(ID id) { + Item newItem = new Item(id); + for (Iterator i = iterator(); i.hasNext();) { + Item old = (Item) i.next(); + if (newItem.equals(old)) + return old; + } + return null; + } + + synchronized int getSize() { + return groupManager.getSize(); + } + + synchronized boolean containsItem(Item m) { + return groupManager.containsItem(m); + } + + synchronized Iterator iterator() { + return groupManager.iterator(); + } + + // End group membership change methods + + // Methods for adding/removing RepObjs + synchronized boolean addSharedObject(SharedObjectWrapper ro) { + // Verify that it's not already present anywhere + if (getFromAny(ro.getObjID()) != null) + return false; + // Add it to active map + addSharedObjectToActive(ro); + // Notify ro about existing members + return true; + } + + synchronized boolean addToLoading(SharedObjectContainer.LoadingSharedObject lro) { + if (getFromAny(lro.getID()) != null) + return false; + loadingSharedObjects.put( + lro.getID(), + new SharedObjectWrapper(lro.getID(), lro.getHomeID(), lro, container)); + // And start the thing + lro.start(); + return true; + } + + synchronized void moveFromLoadingToActive(SharedObjectWrapper ro) + throws SharedObjectNotFoundException { + if (removeSharedObjectFromLoading(ro.getObjID())) + addSharedObjectToActive(ro); + } + + boolean removeSharedObjectFromLoading(ID id) { + if (loadingSharedObjects.remove(id) != null) { + return true; + } else + return false; + } + + synchronized ID[] getActiveKeys() { + return (ID[]) activeSharedObjects.keySet().toArray(new ID[0]); + } + + void addSharedObjectToActive(SharedObjectWrapper ro) { + // Get current membership in ids array + ID[] ids = getActiveKeys(); + // Actually add to active map + activeSharedObjects.put(ro.getObjID(), ro); + // Pass array of IDs to replicated object + ro.activated(ids); + } + + synchronized void notifyOthersActivated(ID id) { + notifyOtherChanged(id, activeSharedObjects, true); + } + + synchronized void notifyOthersDeactivated(ID id) { + notifyOtherChanged(id, activeSharedObjects, false); + } + + void notifyOtherChanged(ID id, TreeMap aMap, boolean activated) { + for (Iterator i = aMap.values().iterator(); i.hasNext();) { + SharedObjectWrapper other = (SharedObjectWrapper) i.next(); + if (!id.equals(other.getObjID())) { + other.otherChanged(id, activated); + } + } + } + + synchronized void destroySharedObject(ID id) throws SharedObjectNotFoundException { + SharedObjectWrapper ro = removeFromMap(id, activeSharedObjects); + if (ro == null) + throw new SharedObjectNotFoundException(id + " not active"); + ro.deactivated(); + } + + synchronized SharedObjectWrapper getFromMap(ID objID, TreeMap aMap) { + return (SharedObjectWrapper) aMap.get(objID); + } + + synchronized SharedObjectWrapper removeFromMap(ID objID, TreeMap aMap) { + return (SharedObjectWrapper) aMap.remove(objID); + } + + SharedObjectWrapper getFromLoading(ID objID) { + return getFromMap(objID, loadingSharedObjects); + } + + SharedObjectWrapper getFromActive(ID objID) { + return getFromMap(objID, activeSharedObjects); + } + + synchronized SharedObjectWrapper getFromAny(ID objID) { + SharedObjectWrapper ro = getFromMap(objID, activeSharedObjects); + if (ro != null) + return ro; + ro = getFromMap(objID, loadingSharedObjects); + return ro; + } + + // Notification methods + void notifyAllOfItemChange(Item m, TreeMap map, boolean add) { + for (Iterator i = map.values().iterator(); i.hasNext();) { + SharedObjectWrapper ro = (SharedObjectWrapper) i.next(); + ro.memberChanged(m, add); + } + } + + public void update(Observable o, Object arg) { + ItemChange mc = (ItemChange) arg; + notifyAllOfItemChange(mc.getItem(), activeSharedObjects, mc.isAdd()); + } + + synchronized void destroySharedObjects(Item m) { + destroySharedObjects(m, true); + } + + synchronized void clear() { + destroySharedObjects(null, true); + } + + void destroySharedObjects(Item m, boolean match) { + try { + HashSet set = getRemoveIDs(m.getID(), match); + Iterator i = set.iterator(); + + while (i.hasNext()) { + ID removeID = (ID) i.next(); + if (isLoading(removeID)) { + removeSharedObjectFromLoading(removeID); + } else { + container.destroySharedObject(removeID); + } + } + + } catch (SharedObjectNotFoundException e) { + if (debug()) { + myDebug.dumpStack( + e, + "Exception destroying for " + m + ", match: " + match); + } + } + } + + HashSet getRemoveIDs(ID homeID, boolean match) { + HashSet aSet = new HashSet(); + for (Iterator i = new DestroyIterator(loadingSharedObjects, homeID, match); + i.hasNext(); + ) { + aSet.add(i.next()); + } + for (Iterator i = new DestroyIterator(activeSharedObjects, homeID, match); + i.hasNext(); + ) { + aSet.add(i.next()); + } + return aSet; + } + + synchronized boolean isActive(ID id) { + return activeSharedObjects.containsKey(id); + } + + synchronized boolean isLoading(ID id) { + return loadingSharedObjects.containsKey(id); + } + + boolean debug() { + if (myDebug == null) + return false; + return true; + } + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("RSM["); + sb.append(groupManager); + sb.append(";L:").append(loadingSharedObjects); + sb.append(";A:").append(activeSharedObjects).append("]"); + return sb.toString(); + } + +} + +class DestroyIterator implements Iterator { + ID next; + ID homeID; + Iterator i; + boolean match; + + public DestroyIterator(TreeMap map, ID hID, boolean m) { + i = map.values().iterator(); + homeID = hID; + next = null; + match = m; + } + + public boolean hasNext() { + if (next == null) + next = getNext(); + return (next != null); + } + + public Object next() { + if (hasNext()) { + ID value = next; + next = null; + return value; + } else { + throw new java.util.NoSuchElementException(); + } + } + + ID getNext() { + while (i.hasNext()) { + SharedObjectWrapper ro = (SharedObjectWrapper) i.next(); + if (homeID == null || (match ^ !ro.getHomeID().equals(homeID))) { + return ro.getObjID(); + } + } + return null; + } + + public void remove() { + throw new UnsupportedOperationException(); + } +} diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/impl/standalone/SharedObjectWrapper.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/impl/standalone/SharedObjectWrapper.java new file mode 100644 index 000000000..9a695e1bd --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/impl/standalone/SharedObjectWrapper.java @@ -0,0 +1,319 @@ +package org.eclipse.ecf.internal.impl.standalone; + +import java.io.Serializable; +import java.security.AccessController; +import java.security.PrivilegedAction; + +import org.eclipse.ecf.core.ISharedObject; +import org.eclipse.ecf.core.ISharedObjectConfig; +import org.eclipse.ecf.core.SharedObjectInitException; +import org.eclipse.ecf.core.events.SharedObjectActivatedEvent; +import org.eclipse.ecf.core.events.SharedObjectContainerDepartedEvent; +import org.eclipse.ecf.core.events.SharedObjectContainerJoinEvent; +import org.eclipse.ecf.core.events.SharedObjectDeactivatedEvent; +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.core.util.AsynchResult; +import org.eclipse.ecf.core.util.Event; +import org.eclipse.ecf.internal.impl.standalone.gmm.Item; +import org.eclipse.ecf.internal.util.queue.SimpleQueueImpl; + +final class SharedObjectWrapper { + static Debug debug = Debug.create(SharedObjectWrapper.class.getName()); + + protected ISharedObject sharedObject; + private ISharedObjectConfig sharedObjectConfig; + private ID sharedObjectID; + private ID sharedObjectHomeID; + private SharedObjectContainer container; + private ID containerID; + private ThreadGroup threadGroup; + private Thread thread; + private SimpleQueueImpl queue; + + SharedObjectWrapper( + ID objID, + ID homeID, + SharedObjectContainer.LoadingSharedObject obj, + SharedObjectContainer space) { + sharedObjectID = objID; + sharedObjectHomeID = homeID; + sharedObject = obj; + container = space; + containerID = space.getID(); + sharedObjectConfig = null; + threadGroup = null; + thread = null; + queue = new SimpleQueueImpl(); + } + SharedObjectWrapper( + ISharedObjectConfig aConfig, + ISharedObject obj, + SharedObjectContainer space, + ThreadGroup group) { + sharedObjectConfig = aConfig; + sharedObjectID = sharedObjectConfig.getSharedObjectID(); + sharedObjectHomeID = sharedObjectConfig.getHomeContainerID(); + sharedObject = obj; + container = space; + containerID = space.getID(); + threadGroup = group; + thread = null; + queue = new SimpleQueueImpl(); + } + + void init() throws SharedObjectInitException { + sharedObject.init(sharedObjectConfig); + } + ID getObjID() { + return sharedObjectID; + } + + ID getHomeID() { + return sharedObjectHomeID; + } + + void activated(ID[] ids) { + // First, make space reference accessible to use by RepObject + //sharedObjectConfig.makeActive(); + thread = + (Thread) AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + // Get thread instance + Thread aThread = getThread(); + return aThread; + } + }); + thread.start(); + send(new SharedObjectActivatedEvent(containerID, sharedObjectID, ids)); + container.notifySharedObjectActivated(sharedObjectID); + + } + void deactivated() { + send(new SharedObjectDeactivatedEvent(containerID,sharedObjectID)); + container.notifySharedObjectDeactivated(sharedObjectID); + destroyed(); + } + private void destroyed() { + if (!queue.isStopped()) { + /* + RepSpaceReference mySpaceRef = sharedObjectConfig.getSpaceReference(); + if (mySpaceRef != null) { + mySpaceRef.clear(); + } + */ + // Enqueue destroy message on our RepObject's queue + if (thread != null) + queue.enqueue(new DisposeEvent()); + // Close queue...RepObject will receive no more messages from this point on. + queue.close(); + } + + } + void otherChanged(ID otherID, boolean activated) { + if (activated && thread != null) { + send(new SharedObjectActivatedEvent(containerID,otherID,null)); + } else { + send(new SharedObjectDeactivatedEvent(containerID,otherID)); + } + } + void memberChanged(Item m, boolean add) { + if (thread != null) { + if (add) { + send(new SharedObjectContainerJoinEvent(containerID,m.getID())); + } else { + send(new SharedObjectContainerDepartedEvent(containerID,m.getID())); + } + } + } + Thread getThread() { + // Get new thread instance from space. + return container + .getSharedObjectThread(sharedObjectID, threadGroup, new Runnable() { + public void run() { + if (Debug.ON && debug != null) { + debug.msg("Starting runner for " + sharedObjectID); + } + // The debug class will associate this thread with container + Debug.setThreadDebugGroup(container.getID()); + // Then process messages on queue until interrupted or queue closed + //Msg aMsg = null; + Event evt = null; + for (;;) { + // make sure the thread hasn't been interrupted and get Msg from SimpleQueueImpl + if (Thread.currentThread().isInterrupted()) + break; + + evt = (Event) queue.dequeue(); + if (Thread.currentThread().isInterrupted() || evt == null) + break; + + try { + if (evt instanceof ProcEvent) { + SharedObjectWrapper.this.svc(((ProcEvent)evt).getEvent()); + } else if (evt instanceof DisposeEvent) { + SharedObjectWrapper.this.doDestroy(); + } + } catch (Throwable t) { + if (Debug.ON && debug != null) { + debug.dumpStack( + t, + "Exception executing event " + + evt + + " on meta " + + this); + } + handleRuntimeException(t); + } + } + // If the thread was interrupted, then show appropriate spam + if (Thread.currentThread().isInterrupted()) { + if (Debug.ON && debug != null) { + debug.msg( + "Runner for " + + sharedObjectID + + " terminating after being interrupted"); + } + } else { + if (Debug.ON && debug != null) { + debug.msg( + "Runner for " + sharedObjectID + " terminating normally"); + } + } + } + }, "Runner for " + sharedObjectID); + } + private void send(Event evt) { + queue.enqueue(new ProcEvent(evt)); + } + + protected static class ProcEvent implements Event { + Event theEvent = null; + ProcEvent(Event event) { + theEvent = event; + } + Event getEvent() { + return theEvent; + } + } + protected static class DisposeEvent implements Event { + DisposeEvent() { + } + } + void svc(Event evt) { + sharedObject.handleEvent(evt); + } + void doDestroy() { + sharedObject.dispose(containerID); + } + + void createMsgResp(ID fromID, ContainerMessage.CreateResponse resp) { + /* + if (sharedObjectConfig.getMsgMask().get(MsgMask.CREATERESPONSE) + && thread != null) { + send( + Msg.makeMsg( + null, + CREATE_RESP_RCVD, + fromID, + resp.myExcept, + new Long(resp.mySeq))); + } + */ + } + void deliverObjectFromRemote(ID fromID, Serializable data) { + // If we have a container, forward message onto container + /* + if (myContainerID != null) { + forwardToContainer( + Msg.makeMsg(null, REMOTE_REPOBJ_MSG, fromID, data)); + // otherwise, send to our object (assuming it has thread and that it wants to receive message) + } else if ( + sharedObjectConfig.getMsgMask().get(MsgMask.REMOTEDATA) + && thread != null) { + send(Msg.makeMsg(null, REMOTE_REPOBJ_MSG, fromID, data)); + } + */ + } + + void forwardToContainer(Event msg) { + /* + try { + container.deliverForwardToRepObject(sharedObjectID, myContainerID, msg); + } catch (Exception e) { + handleRuntimeException(e); + } + */ + } + void deliverEventFromSharedObject(ID fromID, Event evt) { + /* + if (myContainerID != null) { + forwardToContainer(Msg.makeMsg(null, REPOBJ_MSG, fromID, msg)); + // otherwise, send to our object (assuming it has thread and that it wants to receive message) + } else if ( + sharedObjectConfig.getMsgMask().get(MsgMask.REPOBJMSG) && thread != null) { + send(Msg.makeMsg(null, REPOBJ_MSG, fromID, msg)); + } + */ + } + void deliverRequestFromRepObject(ID fromID, Event evt, AsynchResult future) { + /* + if (myContainerID != null) { + forwardToContainer( + Msg.makeMsg(null, REPOBJ_REQ, fromID, msg, future)); + } else if ( + sharedObjectConfig.getMsgMask().get(MsgMask.REPOBJMSG) && thread != null) { + // Check to see that messages may be received...determined by the REPOBJMSG + // bit in msg mask + send(Msg.makeMsg(null, REPOBJ_REQ, fromID, msg, future)); + } + */ + } + void deliverForwardedMsg(ID fromID, Event evt) { + /* + if (myContainerID != null) { + forwardToContainer(Msg.makeMsg(null, REPOBJ_FOR, fromID, msg)); + } else if ( + sharedObjectConfig.getMsgMask().get(MsgMask.REPOBJMSG) && thread != null) { + send(Msg.makeMsg(null, REPOBJ_FOR, fromID, msg)); + } + */ + } + void deliverRemoteMessageFailed( + ID toID, + Serializable object, + Throwable e) { + /* + if (sharedObjectConfig.getMsgMask().get(MsgMask.REPOBJMSG) && thread != null) { + send(Msg.makeMsg(null, REMOTE_REPOBJ_MSG_FAILED, toID, object, e)); + } + */ + } + + void destroySelf() { + /* + if (thread != null) { + send(Msg.makeMsg(null, REPOBJ_DESTROY_SELF)); + } + */ + } + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("SharedObjectWrapper[").append(getObjID()).append("]"); + return sb.toString(); + } + void handleRuntimeException(Throwable except) { + if (Debug.ON && debug != null) { + debug.dumpStack( + except, + "handleRuntimeException called for " + sharedObjectID); + } + try { + Debug.errDumpStack( + except, + "handleRuntimeException called for " + sharedObjectID); + } catch (Throwable e) { + } + } + +} diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/impl/standalone/StandaloneConfig.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/impl/standalone/StandaloneConfig.java new file mode 100644 index 000000000..00d25ed11 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/impl/standalone/StandaloneConfig.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ +package org.eclipse.ecf.internal.impl.standalone; + +import java.util.Map; +import java.util.Hashtable; + +import org.eclipse.ecf.core.ISharedObjectContainerConfig; +import org.eclipse.ecf.core.identity.ID; + +public class StandaloneConfig implements ISharedObjectContainerConfig { + + protected ID id; + + public StandaloneConfig(ID theID) { + this.id = theID; + } + public ID getID() { + return id; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainerConfig#getProperties() + */ + public Map getProperties() { + return new Hashtable(); + } + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainerConfig#getAdapter(java.lang.Class) + */ + public Object getAdapter(Class clazz) { + return null; + } +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/impl/standalone/StandaloneContainer.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/impl/standalone/StandaloneContainer.java new file mode 100644 index 000000000..8e0cb7004 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/impl/standalone/StandaloneContainer.java @@ -0,0 +1,457 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.internal.impl.standalone; + +import java.lang.reflect.Constructor; +import java.security.AccessController; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; +import java.util.ArrayList; +import java.util.Map; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.List; +import java.util.Vector; + +import org.eclipse.ecf.core.ISharedObject; +import org.eclipse.ecf.core.ISharedObjectConnector; +import org.eclipse.ecf.core.ISharedObjectContainer; +import org.eclipse.ecf.core.ISharedObjectContainerConfig; +import org.eclipse.ecf.core.ISharedObjectContainerListener; +import org.eclipse.ecf.core.ISharedObjectContainerTransaction; +import org.eclipse.ecf.core.ISharedObjectManager; +import org.eclipse.ecf.core.SharedObjectAddException; +import org.eclipse.ecf.core.SharedObjectConnectException; +import org.eclipse.ecf.core.SharedObjectContainerInstantiationException; +import org.eclipse.ecf.core.SharedObjectContainerJoinException; +import org.eclipse.ecf.core.SharedObjectCreateException; +import org.eclipse.ecf.core.SharedObjectDescription; +import org.eclipse.ecf.core.SharedObjectDisconnectException; +import org.eclipse.ecf.core.SharedObjectNotFoundException; +import org.eclipse.ecf.core.events.ContainerEvent; +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.core.identity.IDFactory; +import org.eclipse.ecf.core.identity.IDInstantiationException; +import org.eclipse.ecf.core.provider.ISharedObjectContainerInstantiator; +import org.eclipse.ecf.core.util.AbstractFactory; + +public class StandaloneContainer implements ISharedObjectContainer, ISharedObjectManager { + + protected static final Object[] nullArgs = new Object[0]; + protected static final Class[] nullTypes = new Class[0]; + + ISharedObjectContainerConfig config = null; + Vector listeners = new Vector(); + Hashtable sharedObjectTable; + + public static final String STANDALONE_NAME = "standalone"; + + public static class Creator implements ISharedObjectContainerInstantiator { + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.provider.ISharedObjectContainerInstantiator#makeInstance(java.lang.Class[], + * java.lang.Object[]) + */ + public ISharedObjectContainer makeInstance(Class[] argTypes, + Object[] args) + throws SharedObjectContainerInstantiationException { + ID newID = null; + if (args == null || args.length == 0) { + try { + newID = IDFactory.makeGUID(); + } catch (IDInstantiationException e) { + throw new SharedObjectContainerInstantiationException( + "Cannot create GUID ID for StandaloneContainer"); + } + } else { + try { + newID = IDFactory.makeStringID((String) args[0]); + } catch (IDInstantiationException e) { + throw new SharedObjectContainerInstantiationException( + "Cannot create GUID ID for StandaloneContainer"); + } + } + return new StandaloneContainer(new StandaloneConfig(newID)); + } + } + public StandaloneContainer(StandaloneConfig config) { + super(); + this.config = config; + sharedObjectTable = new Hashtable(); + } + + public ISharedObjectManager getSharedObjectManager() { + return this; + } + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#getPeerID() + */ + public ID getID() { + return config.getID(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#getPeerConfig() + */ + public ISharedObjectContainerConfig getConfig() { + return config; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#addPeerListener(org.eclipse.ecf.core.ISharedObjectContainerListener) + */ + public void addListener(ISharedObjectContainerListener l, String filter) { + listeners.add(l); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#removePeerListener(org.eclipse.ecf.core.ISharedObjectContainerListener) + */ + public void removeListener(ISharedObjectContainerListener l) { + listeners.remove(l); + } + protected void fireListeners(ContainerEvent evt) { + for (Enumeration e = listeners.elements(); e.hasMoreElements();) { + ISharedObjectContainerListener l = (ISharedObjectContainerListener) e + .nextElement(); + l.handleEvent(evt); + } + } + + private void disposeSharedObjects() { + Enumeration e = sharedObjectTable.elements(); + while (e.hasMoreElements()) { + SharedObjectWrapper wrapper = (SharedObjectWrapper) e.nextElement(); + wrapper.deactivated(); + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#terminatePeer(long) + */ + public void dispose(long waittime) { + synchronized (sharedObjectTable) { + disposeSharedObjects(); + sharedObjectTable.clear(); + } + } + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#joinGroup(org.eclipse.ecf.identity.ID, + * java.lang.Object) + */ + public void joinGroup(ID groupID, Object loginData) + throws SharedObjectContainerJoinException { + throw new SharedObjectContainerJoinException( + "Standalone container cannot join external groups"); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#leaveGroup() + */ + public void leaveGroup() { + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#getGroupID() + */ + public ID getGroupID() { + return null; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#getGroupMembership() + */ + public ID[] getGroupMembership() { + return new ID[] { getID() }; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#isGroupManager() + */ + public boolean isGroupManager() { + return false; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#isGroupServer() + */ + public boolean isGroupServer() { + return false; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#getAdapter(java.lang.Class) + */ + public Object getAdapter(Class clazz) { + return null; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#getSharedObjectIDs() + */ + public ID[] getSharedObjectIDs() { + return (ID[]) sharedObjectTable.keySet().toArray(new ID[0]); + } + + protected static Object loadObject(final ClassLoader cl, String className, + String[] argTypes, Object[] a) throws Exception { + final Class[] types = AbstractFactory.getClassesForTypes(argTypes, a, + cl); + final Object[] args = (a == null) ? nullArgs : a; + // Load RepObject class(es), after getting appropriate classloader + final Class newClass = Class.forName(className, true, cl); + Object newObject = null; + try { + // Do privileged operation. Get appropriate constructor from new + // class, + // and create new instance. + newObject = AccessController + .doPrivileged(new PrivilegedExceptionAction() { + public Object run() throws Exception { + Constructor aConstructor = newClass + .getConstructor(types); + aConstructor.setAccessible(true); + // Now actually create the object. + return aConstructor.newInstance(args); + } + }); + } catch (PrivilegedActionException e) { + throw e.getException(); + } + return newObject; + } + protected ISharedObject loadSharedObject(SharedObjectDescription desc) throws Exception { + ClassLoader descClassLoader = desc.getClassLoader(); + Map dict = desc.getProperties(); + String [] constructorArgTypes = null; + Object [] constructorArgs = null; + if (dict != null) { + constructorArgTypes = (String []) dict.get("constructorArgTypes"); + constructorArgs = (Object []) dict.get("constructorArgs"); + } + return (ISharedObject) loadObject((descClassLoader==null)?getSharedObjectClassLoader(desc):descClassLoader,desc.getClassname(),constructorArgTypes,constructorArgs); + } + protected ClassLoader getSharedObjectClassLoader(SharedObjectDescription desc) { + return this.getClass().getClassLoader(); + } + + protected ISharedObject addSharedObjectAndWait( + SharedObjectDescription sd, + ISharedObject s, + ISharedObjectContainerTransaction t) + throws Exception { + if (sd.getID() == null || s == null) + return null; + // Wait right here until committed + ISharedObject so = + addSharedObject0( + sd, + s); + if (t != null) + t.waitToCommit(); + return s; + } + protected ISharedObject addSharedObject0( + SharedObjectDescription sd, + ISharedObject s) + throws Exception { + addSharedObjectWrapper( + makeNewSharedObjectWrapper(sd, s)); + return s; + } + protected StandaloneSharedObjectWrapper makeNewSharedObjectWrapper(SharedObjectDescription sd, ISharedObject s) { + StandaloneSharedObjectConfig newConfig = makeNewSharedObjectConfig(sd,this); + return new StandaloneSharedObjectWrapper(newConfig,s,this); + } + protected StandaloneSharedObjectConfig makeNewSharedObjectConfig(SharedObjectDescription sd, StandaloneContainer cont) { + ID homeID = sd.getHomeID(); + if (homeID == null) homeID = getID(); + return new StandaloneSharedObjectConfig(sd.getID(),homeID,this,sd.getProperties()); + } + protected StandaloneSharedObjectWrapper addSharedObjectWrapper(StandaloneSharedObjectWrapper wrapper) throws Exception { + if (wrapper == null) + return null; + ID id = wrapper.getObjID(); + synchronized (sharedObjectTable) { + if (sharedObjectTable.get(id) != null) { + throw new SharedObjectAddException( + "SharedObject with id " + id + " already in use"); + } + // Put in table + sharedObjectTable.put(id, wrapper); + // Call initialize + wrapper.init(); + // Send activated message + wrapper.activated(getSharedObjectIDs()); + } + return wrapper; + } + + protected void notifySharedObjectActivated(ID activated) { + synchronized (sharedObjectTable) { + for(Enumeration e=sharedObjectTable.elements(); e.hasMoreElements(); ) { + StandaloneSharedObjectWrapper w = (StandaloneSharedObjectWrapper) e.nextElement(); + if (!activated.equals(w.getObjID())) { + w.otherChanged(activated,getSharedObjectIDs(),true); + } + } + } + } + protected void notifySharedObjectDeactivated(ID deactivated) { + synchronized (sharedObjectTable) { + for(Enumeration e=sharedObjectTable.elements(); e.hasMoreElements(); ) { + StandaloneSharedObjectWrapper w = (StandaloneSharedObjectWrapper) e.nextElement(); + if (!deactivated.equals(w.getObjID())) { + w.otherChanged(deactivated,getSharedObjectIDs(),false); + } + } + } + } + + protected Thread getSharedObjectThread(ID id, Runnable target, String name) { + return new Thread(target,name); + } + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#createSharedObject(org.eclipse.ecf.core.SharedObjectDescription) + */ + public ID createSharedObject(SharedObjectDescription sd, + ISharedObjectContainerTransaction trans) + throws SharedObjectCreateException { + ID result = null; + try { + ISharedObject so = loadSharedObject(sd); + result = sd.getID(); + addSharedObjectAndWait(sd,so,trans); + } catch (Exception e) { + throw new SharedObjectCreateException("Exception creating shared object",e); + } + return result; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#addSharedObject(org.eclipse.ecf.identity.ID, + * org.eclipse.ecf.core.ISharedObject, java.util.Map, + * org.eclipse.ecf.core.ISharedObjectContainerTransaction) + */ + public ID addSharedObject(ID sharedObjectID, ISharedObject sharedObject, + Map dict, ISharedObjectContainerTransaction trans) + throws SharedObjectAddException { + ID result = null; + try { + ISharedObject so = sharedObject; + result = sharedObjectID; + SharedObjectDescription sd = new SharedObjectDescription(sharedObject.getClass().getClassLoader(), + sharedObjectID,getID(),sharedObject.getClass().getName(),dict,0); + addSharedObjectAndWait(sd,so,trans); + } catch (Exception e) { + throw new SharedObjectAddException("Exception creating shared object",e); + } + return result; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#getSharedObjectAdapter(org.eclipse.ecf.identity.ID, + * java.lang.Class) + */ + public Object getSharedObjectAdapter(ID sharedObjectID, Class adapterClass) + throws SharedObjectNotFoundException { + ISharedObject so = getSharedObject(sharedObjectID); + if (so == null) throw new SharedObjectNotFoundException("Shared object "+sharedObjectID.getName() + " not found"); + return so.getAdapter(adapterClass); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#getSharedObject(org.eclipse.ecf.identity.ID) + */ + public ISharedObject getSharedObject(ID sharedObjectID) { + StandaloneSharedObjectWrapper w = (StandaloneSharedObjectWrapper) sharedObjectTable.get(sharedObjectID); + if (w == null) return null; + else return w.sharedObject; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#removeSharedObject(org.eclipse.ecf.identity.ID) + */ + public ISharedObject removeSharedObject(ID sharedObjectID) { + StandaloneSharedObjectWrapper w = (StandaloneSharedObjectWrapper) sharedObjectTable.remove(sharedObjectID); + if (w == null) return null; + else return w.sharedObject; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#connectSharedObjects(org.eclipse.ecf.identity.ID, + * org.eclipse.ecf.identity.ID[]) + */ + public ISharedObjectConnector connectSharedObjects(ID sharedObjectFrom, + ID[] sharedObjectsTo) throws SharedObjectConnectException { + // TODO Auto-generated method stub + return null; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ecf.core.ISharedObjectContainer#disconnectSharedObjects(org.eclipse.ecf.core.ISharedObjectConnector) + */ + public void disconnectSharedObjects(ISharedObjectConnector connector) + throws SharedObjectDisconnectException { + // TODO Auto-generated method stub + } + + /** + * Get the sharedObjectConnectors associated with the given sharedObjectID + * + * @return List of ISharedObjectConnector instances + */ + public List getSharedObjectConnectors(ID sharedObjectFrom) { + // TODO return actual list contents + return new ArrayList(); + } + +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/impl/standalone/StandaloneContainerManager.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/impl/standalone/StandaloneContainerManager.java new file mode 100644 index 000000000..f8cf7efbc --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/impl/standalone/StandaloneContainerManager.java @@ -0,0 +1,335 @@ +package org.eclipse.ecf.internal.impl.standalone; + +import org.eclipse.ecf.core.SharedObjectNotFoundException; +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.internal.impl.standalone.Debug; +import org.eclipse.ecf.internal.impl.standalone.gmm.GroupManager; +import org.eclipse.ecf.internal.impl.standalone.gmm.Item; +import org.eclipse.ecf.internal.impl.standalone.gmm.ItemChange; + +import java.util.Observer; +import java.util.Observable; +import java.util.HashSet; +import java.util.TreeMap; +import java.util.Iterator; + +class StandaloneContainerManager implements Observer { + static Debug myDebug = Debug.create(StandaloneContainerManager.class.getName()); + + StandaloneContainer container; + Item containerPeer; + GroupManager groupManager; + int maxItems = -1; + TreeMap loadingSharedObjects, activeSharedObjects; + + StandaloneContainerManager(StandaloneContainer space, Item ourMember) { + container = space; + groupManager = new GroupManager(); + groupManager.addObserver(this); + loadingSharedObjects = new TreeMap(); + activeSharedObjects = new TreeMap(); + addItem(ourMember); + containerPeer = ourMember; + } + + synchronized boolean addItem(Item m) { + if (maxItems > 0 && getSize() > maxItems) { + return false; + } else { + return groupManager.addItem(m); + } + } + synchronized int setMaxItems(int max) { + int old = maxItems; + maxItems = max; + return old; + } + synchronized int getMaxItems() { + return maxItems; + } + + synchronized boolean removeItem(Item m) { + boolean res = groupManager.removeItem(m); + if (res) { + destroySharedObjects(m); + } + return res; + } + + synchronized boolean removeItem(ID id) { + Item m = getItemForID(id); + if (m == null) + return false; + return removeItem(m); + } + + void removeAllItems() { + removeAllItems(null); + } + + void removeClientItems() { + removeAllItems(containerPeer); + } + + synchronized void removeAllItems(Item exception) { + Object m[] = getItems(); + for (int i = 0; i < m.length; i++) { + Item mem = (Item) m[i]; + if (exception == null || !exception.equals(mem)) + removeItem(mem); + } + } + + synchronized Object[] getItems() { + return groupManager.getItems(); + } + + synchronized ID[] getOtherItemIDs() { + return groupManager.getItemIDs(containerPeer.getID()); + } + + synchronized ID[] getItemIDs() { + return groupManager.getItemIDs(null); + } + + synchronized Item getItemForID(ID id) { + Item newItem = new Item(id); + for (Iterator i = iterator(); i.hasNext();) { + Item old = (Item) i.next(); + if (newItem.equals(old)) + return old; + } + return null; + } + + synchronized int getSize() { + return groupManager.getSize(); + } + + synchronized boolean containsItem(Item m) { + return groupManager.containsItem(m); + } + + synchronized Iterator iterator() { + return groupManager.iterator(); + } + + // End group membership change methods + + // Methods for adding/removing RepObjs + synchronized boolean addSharedObject(SharedObjectWrapper ro) { + // Verify that it's not already present anywhere + if (getFromAny(ro.getObjID()) != null) + return false; + // Add it to active map + addSharedObjectToActive(ro); + // Notify ro about existing members + return true; + } + + synchronized boolean addToLoading(SharedObjectContainer.LoadingSharedObject lro) { + /* + if (getFromAny(lro.getID()) != null) + return false; + loadingSharedObjects.put( + lro.getID(), + new SharedObjectWrapper(lro.getID(), lro.getHomeID(), lro, container)); + // And start the thing + lro.start(); + */ + return true; + } + + synchronized void moveFromLoadingToActive(SharedObjectWrapper ro) + throws SharedObjectNotFoundException { + if (removeSharedObjectFromLoading(ro.getObjID())) + addSharedObjectToActive(ro); + } + + boolean removeSharedObjectFromLoading(ID id) { + if (loadingSharedObjects.remove(id) != null) { + return true; + } else + return false; + } + + synchronized ID[] getActiveKeys() { + return (ID[]) activeSharedObjects.keySet().toArray(new ID[0]); + } + + void addSharedObjectToActive(SharedObjectWrapper ro) { + // Get current membership in ids array + ID[] ids = getActiveKeys(); + // Actually add to active map + activeSharedObjects.put(ro.getObjID(), ro); + // Pass array of IDs to replicated object + ro.activated(ids); + } + + synchronized void notifyOthersActivated(ID id) { + notifyOtherChanged(id, activeSharedObjects, true); + } + + synchronized void notifyOthersDeactivated(ID id) { + notifyOtherChanged(id, activeSharedObjects, false); + } + + void notifyOtherChanged(ID id, TreeMap aMap, boolean activated) { + for (Iterator i = aMap.values().iterator(); i.hasNext();) { + SharedObjectWrapper other = (SharedObjectWrapper) i.next(); + if (!id.equals(other.getObjID())) { + other.otherChanged(id, activated); + } + } + } + + synchronized void destroySharedObject(ID id) throws SharedObjectNotFoundException { + SharedObjectWrapper ro = removeFromMap(id, activeSharedObjects); + if (ro == null) + throw new SharedObjectNotFoundException(id + " not active"); + ro.deactivated(); + } + + synchronized SharedObjectWrapper getFromMap(ID objID, TreeMap aMap) { + return (SharedObjectWrapper) aMap.get(objID); + } + + synchronized SharedObjectWrapper removeFromMap(ID objID, TreeMap aMap) { + return (SharedObjectWrapper) aMap.remove(objID); + } + + SharedObjectWrapper getFromLoading(ID objID) { + return getFromMap(objID, loadingSharedObjects); + } + + SharedObjectWrapper getFromActive(ID objID) { + return getFromMap(objID, activeSharedObjects); + } + + synchronized SharedObjectWrapper getFromAny(ID objID) { + SharedObjectWrapper ro = getFromMap(objID, activeSharedObjects); + if (ro != null) + return ro; + ro = getFromMap(objID, loadingSharedObjects); + return ro; + } + + // Notification methods + void notifyAllOfItemChange(Item m, TreeMap map, boolean add) { + for (Iterator i = map.values().iterator(); i.hasNext();) { + SharedObjectWrapper ro = (SharedObjectWrapper) i.next(); + ro.memberChanged(m, add); + } + } + + public void update(Observable o, Object arg) { + ItemChange mc = (ItemChange) arg; + notifyAllOfItemChange(mc.getItem(), activeSharedObjects, mc.isAdd()); + } + + synchronized void destroySharedObjects(Item m) { + destroySharedObjects(m, true); + } + + synchronized void clear() { + destroySharedObjects(null, true); + } + + void destroySharedObjects(Item m, boolean match) { + HashSet set = getRemoveIDs(m.getID(), match); + Iterator i = set.iterator(); + + while (i.hasNext()) { + ID removeID = (ID) i.next(); + if (isLoading(removeID)) { + removeSharedObjectFromLoading(removeID); + } else { + container.removeSharedObject(removeID); + } + } + } + + HashSet getRemoveIDs(ID homeID, boolean match) { + HashSet aSet = new HashSet(); + for (Iterator i = new DestroyIterator(loadingSharedObjects, homeID, match); + i.hasNext(); + ) { + aSet.add(i.next()); + } + for (Iterator i = new DestroyIterator(activeSharedObjects, homeID, match); + i.hasNext(); + ) { + aSet.add(i.next()); + } + return aSet; + } + + synchronized boolean isActive(ID id) { + return activeSharedObjects.containsKey(id); + } + + synchronized boolean isLoading(ID id) { + return loadingSharedObjects.containsKey(id); + } + + boolean debug() { + if (myDebug == null) + return false; + return true; + } + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("RSM["); + sb.append(groupManager); + sb.append(";L:").append(loadingSharedObjects); + sb.append(";A:").append(activeSharedObjects).append("]"); + return sb.toString(); + } + + class DestroyIterator implements Iterator { + ID next; + ID homeID; + Iterator i; + boolean match; + + public DestroyIterator(TreeMap map, ID hID, boolean m) { + i = map.values().iterator(); + homeID = hID; + next = null; + match = m; + } + + public boolean hasNext() { + if (next == null) + next = getNext(); + return (next != null); + } + + public Object next() { + if (hasNext()) { + ID value = next; + next = null; + return value; + } else { + throw new java.util.NoSuchElementException(); + } + } + + ID getNext() { + while (i.hasNext()) { + SharedObjectWrapper ro = (SharedObjectWrapper) i.next(); + if (homeID == null || (match ^ !ro.getHomeID().equals(homeID))) { + return ro.getObjID(); + } + } + return null; + } + + public void remove() { + throw new UnsupportedOperationException(); + } + } + +} + diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/impl/standalone/StandaloneSharedObjectConfig.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/impl/standalone/StandaloneSharedObjectConfig.java new file mode 100644 index 000000000..b3737d38f --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/impl/standalone/StandaloneSharedObjectConfig.java @@ -0,0 +1,64 @@ +/* + * Created on Nov 29, 2004 + * + */ +package org.eclipse.ecf.internal.impl.standalone; + +import java.util.Map; + +import org.eclipse.ecf.core.ISharedObjectConfig; +import org.eclipse.ecf.core.ISharedObjectContext; +import org.eclipse.ecf.core.identity.ID; + +public class StandaloneSharedObjectConfig implements ISharedObjectConfig { + + StandaloneContainer container = null; + ID sharedObjectID; + ID homeContainerID; + boolean isActive; + Map properties; + + public StandaloneSharedObjectConfig(ID sharedObjectID, ID homeContainerID, StandaloneContainer cont, Map dict) { + super(); + this.sharedObjectID = sharedObjectID; + this.homeContainerID = homeContainerID; + this.container = cont; + isActive = false; + properties = dict; + } + + protected void makeActive() { + isActive = true; + } + + /* (non-Javadoc) + * @see org.eclipse.ecf.core.ISharedObjectConfig#getSharedObjectID() + */ + public ID getSharedObjectID() { + return sharedObjectID; + } + + /* (non-Javadoc) + * @see org.eclipse.ecf.core.ISharedObjectConfig#getHomeContainerID() + */ + public ID getHomeContainerID() { + return homeContainerID; + } + + /* (non-Javadoc) + * @see org.eclipse.ecf.core.ISharedObjectConfig#getContext() + */ + public ISharedObjectContext getContext() { + if (isActive) { + return null; + } else return null; + } + + /* (non-Javadoc) + * @see org.eclipse.ecf.core.ISharedObjectConfig#getProperties() + */ + public Map getProperties() { + return properties; + } + +} diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/impl/standalone/StandaloneSharedObjectWrapper.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/impl/standalone/StandaloneSharedObjectWrapper.java new file mode 100644 index 000000000..248d55a0a --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/impl/standalone/StandaloneSharedObjectWrapper.java @@ -0,0 +1,216 @@ +package org.eclipse.ecf.internal.impl.standalone; + +import java.security.AccessController; +import java.security.PrivilegedAction; + +import org.eclipse.ecf.core.ISharedObject; +import org.eclipse.ecf.core.SharedObjectInitException; +import org.eclipse.ecf.core.events.SharedObjectActivatedEvent; +import org.eclipse.ecf.core.events.SharedObjectContainerDepartedEvent; +import org.eclipse.ecf.core.events.SharedObjectContainerJoinEvent; +import org.eclipse.ecf.core.events.SharedObjectDeactivatedEvent; +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.core.util.Event; +import org.eclipse.ecf.internal.impl.standalone.gmm.Item; +import org.eclipse.ecf.internal.util.queue.SimpleQueueImpl; + +final class StandaloneSharedObjectWrapper { + static Debug debug = Debug.create(StandaloneSharedObjectWrapper.class.getName()); + + protected ISharedObject sharedObject; + private StandaloneSharedObjectConfig sharedObjectConfig; + private ID sharedObjectID; + private ID sharedObjectHomeID; + private StandaloneContainer container; + private ID containerID; + private Thread thread; + private SimpleQueueImpl queue; + + StandaloneSharedObjectWrapper( + StandaloneSharedObjectConfig aConfig, + ISharedObject obj, + StandaloneContainer space) { + sharedObjectConfig = aConfig; + sharedObjectID = sharedObjectConfig.getSharedObjectID(); + sharedObjectHomeID = sharedObjectConfig.getHomeContainerID(); + sharedObject = obj; + container = space; + containerID = space.getID(); + thread = null; + queue = new SimpleQueueImpl(); + } + + void init() throws SharedObjectInitException { + sharedObject.init(sharedObjectConfig); + } + ID getObjID() { + return sharedObjectID; + } + + ID getHomeID() { + return sharedObjectHomeID; + } + + void activated(ID[] ids) { + // First, make space reference accessible to use by RepObject + sharedObjectConfig.makeActive(); + thread = + (Thread) AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + // Get thread instance + Thread aThread = getThread(); + return aThread; + } + }); + thread.start(); + send(new SharedObjectActivatedEvent(containerID, sharedObjectID, ids)); + container.notifySharedObjectActivated(sharedObjectID); + + } + void deactivated() { + send(new SharedObjectDeactivatedEvent(containerID,sharedObjectID)); + container.notifySharedObjectDeactivated(sharedObjectID); + destroyed(); + } + private void destroyed() { + if (!queue.isStopped()) { + /* + RepSpaceReference mySpaceRef = sharedObjectConfig.getSpaceReference(); + if (mySpaceRef != null) { + mySpaceRef.clear(); + } + */ + // Enqueue destroy message on our RepObject's queue + if (thread != null) + queue.enqueue(new DisposeEvent()); + // Close queue...RepObject will receive no more messages from this point on. + queue.close(); + } + + } + void otherChanged(ID otherID, ID[] all, boolean activated) { + if (activated && thread != null) { + send(new SharedObjectActivatedEvent(containerID,otherID,all)); + } else { + send(new SharedObjectDeactivatedEvent(containerID,otherID)); + } + } + void memberChanged(Item m, boolean add) { + if (thread != null) { + if (add) { + send(new SharedObjectContainerJoinEvent(containerID,m.getID())); + } else { + send(new SharedObjectContainerDepartedEvent(containerID,m.getID())); + } + } + } + Thread getThread() { + // Get new thread instance from space. + + return container + .getSharedObjectThread(sharedObjectID, new Runnable() { + public void run() { + if (Debug.ON && debug != null) { + debug.msg("Starting runner for " + sharedObjectID); + } + // The debug class will associate this thread with container + Debug.setThreadDebugGroup(container.getID()); + // Then process messages on queue until interrupted or queue closed + //Msg aMsg = null; + Event evt = null; + for (;;) { + // make sure the thread hasn't been interrupted and get Msg from SimpleQueueImpl + if (Thread.currentThread().isInterrupted()) + break; + + evt = (Event) queue.dequeue(); + if (Thread.currentThread().isInterrupted() || evt == null) + break; + + try { + if (evt instanceof ProcEvent) { + StandaloneSharedObjectWrapper.this.svc(((ProcEvent)evt).getEvent()); + } else if (evt instanceof DisposeEvent) { + StandaloneSharedObjectWrapper.this.doDestroy(); + } + } catch (Throwable t) { + if (Debug.ON && debug != null) { + debug.dumpStack( + t, + "Exception executing event " + + evt + + " on meta " + + this); + } + handleRuntimeException(t); + } + } + // If the thread was interrupted, then show appropriate spam + if (Thread.currentThread().isInterrupted()) { + if (Debug.ON && debug != null) { + debug.msg( + "Runner for " + + sharedObjectID + + " terminating after being interrupted"); + } + } else { + if (Debug.ON && debug != null) { + debug.msg( + "Runner for " + sharedObjectID + " terminating normally"); + } + } + } + }, "SOID:" + sharedObjectID); + } + private void send(Event evt) { + queue.enqueue(new ProcEvent(evt)); + } + + protected static class ProcEvent implements Event { + Event theEvent = null; + ProcEvent(Event event) { + theEvent = event; + } + Event getEvent() { + return theEvent; + } + } + protected static class DisposeEvent implements Event { + DisposeEvent() { + } + } + void svc(Event evt) { + sharedObject.handleEvent(evt); + } + void doDestroy() { + sharedObject.dispose(containerID); + } + + void destroySelf() { + /* + if (thread != null) { + send(Msg.makeMsg(null, REPOBJ_DESTROY_SELF)); + } + */ + } + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("SharedObjectWrapper[").append(getObjID()).append("]"); + return sb.toString(); + } + void handleRuntimeException(Throwable except) { + if (Debug.ON && debug != null) { + debug.dumpStack( + except, + "handleRuntimeException called for " + sharedObjectID); + } + try { + Debug.errDumpStack( + except, + "handleRuntimeException called for " + sharedObjectID); + } catch (Throwable e) { + } + } + +} diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/impl/standalone/gmm/GroupManager.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/impl/standalone/gmm/GroupManager.java new file mode 100644 index 000000000..a81894c3d --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/impl/standalone/gmm/GroupManager.java @@ -0,0 +1,79 @@ +package org.eclipse.ecf.internal.impl.standalone.gmm; + +import java.util.Observable; +import java.util.TreeSet; +import java.util.Iterator; + +import org.eclipse.ecf.core.identity.ID; + +public class GroupManager extends Observable { + TreeSet items; + + public GroupManager() { + items = new TreeSet(); + } + + public boolean addItem(Item m) { + boolean res = items.add(m); + if (res) { + setChanged(); + notifyObservers(new ItemChange(m, true)); + } + return res; + } + + public boolean removeItem(Item m) { + boolean res = items.remove(m); + if (res) { + setChanged(); + notifyObservers(new ItemChange(m, false)); + } + return res; + } + + public void removeAllItems() { + Object items[] = getItems(); + for (int i = 0; i < items.length; i++) { + removeItem((Item) items[i]); + } + } + + public Object[] getItems() { + return items.toArray(); + } + + public ID[] getItemIDs(ID exclude) { + TreeSet newSet = null; + if (exclude != null) { + newSet = (TreeSet) items.clone(); + newSet.remove(new Item(exclude)); + } else { + newSet = items; + } + ID ids[] = new ID[newSet.size()]; + Iterator iter = newSet.iterator(); + int j = 0; + while (iter.hasNext()) { + ids[j++] = (ID) ((Item) iter.next()).getID(); + } + return ids; + } + + public int getSize() { + return items.size(); + } + + public boolean containsItem(Item m) { + return items.contains(m); + } + + public Iterator iterator() { + return items.iterator(); + } + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("GMM").append(items); + return sb.toString(); + } +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/impl/standalone/gmm/Item.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/impl/standalone/gmm/Item.java new file mode 100644 index 000000000..1ce8c18f1 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/impl/standalone/gmm/Item.java @@ -0,0 +1,52 @@ +package org.eclipse.ecf.internal.impl.standalone.gmm; + +import org.eclipse.ecf.core.identity.ID; + +public class Item implements Comparable { + ID itemID; + Object itemData; + + public Item(ID id) { + this(id, null); + } + + public Item(ID id, Object data) { + itemID = id; + itemData = data; + } + + public boolean equals(Object o) { + if (o != null && o instanceof Item) { + return itemID.equals(((Item) o).itemID); + } else + return false; + } + + public int hashCode() { + return itemID.hashCode(); + } + + public int compareTo(Object o) { + if (o != null && o instanceof Item) { + return itemID.compareTo(((Item) o).itemID); + } else + return 0; + } + + public ID getID() { + return itemID; + } + + public Object getData() { + return itemData; + } + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("Item[").append(itemID).append(";").append( + itemData).append( + "]"); + return sb.toString(); + } + +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/impl/standalone/gmm/ItemChange.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/impl/standalone/gmm/ItemChange.java new file mode 100644 index 000000000..2e5885d18 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/impl/standalone/gmm/ItemChange.java @@ -0,0 +1,19 @@ +package org.eclipse.ecf.internal.impl.standalone.gmm; + +public class ItemChange { + Item item; + boolean added; + + public ItemChange(Item item, boolean added) { + this.item = item; + this.added = added; + } + + public Item getItem() { + return item; + } + + public boolean isAdd() { + return added; + } +}
\ No newline at end of file diff --git a/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/util/queue/SimpleQueueImpl.java b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/util/queue/SimpleQueueImpl.java new file mode 100644 index 000000000..9b77a6cbf --- /dev/null +++ b/framework/bundles/org.eclipse.ecf/src/org/eclipse/ecf/internal/util/queue/SimpleQueueImpl.java @@ -0,0 +1,116 @@ +/******************************************************************************* + * Copyright (c) 2004 Composent, Inc. and others. All rights reserved. This + * program and the accompanying materials are made available under the terms of + * the Eclipse Public License v1.0 which accompanies this distribution, and is + * available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: Composent, Inc. - initial API and implementation + ******************************************************************************/ + +package org.eclipse.ecf.internal.util.queue; + +import java.util.List; +import java.util.LinkedList; + +import org.eclipse.ecf.core.util.SimpleQueue; + +public class SimpleQueueImpl implements SimpleQueue { + List list; + boolean stopped; + + public SimpleQueueImpl() { + list = new LinkedList(); + stopped = false; + } + + public synchronized boolean enqueue(Object obj) { + if (isStopped() || obj == null) { + return false; + } + // Add item to the list + list.add(obj); + // Notify waiting thread. Dequeue should only be read by one thread, so + // only need + // notify() rather than notifyAll(). + notify(); + return true; + } + + public synchronized Object dequeue() { + Object val = peekQueue(); + if (val != null) { + removeHead(); + } + return val; + } + + public synchronized Object peekQueue() { + while (isEmpty()) { + if (stopped) { + return null; + } else { + try { + wait(); + } catch (Exception e) { + return null; + } + } + } + return list.get(0); + } + + public synchronized Object peekQueue(long waitMS) { + if (waitMS == 0) + return peekQueue(); + if (stopped) { + return null; + } else { + try { + wait(waitMS); + } catch (Exception e) { + return null; + } + } + if (isEmpty()) + return null; + else + return list.get(0); + } + + public synchronized Object removeHead() { + if (list.isEmpty()) + return null; + return list.remove(0); + } + + public synchronized boolean isEmpty() { + return list.isEmpty(); + } + + public synchronized void stop() { + stopped = true; + } + + public synchronized boolean isStopped() { + return stopped; + } + + public synchronized Object[] flush() { + Object[] out = list.toArray(); + list.clear(); + close(); + return out; + } + + public synchronized void close() { + stop(); + notifyAll(); + } + + public String toString() { + StringBuffer sb = new StringBuffer("SimpleQueueImpl["); + sb.append(list).append("]"); + return sb.toString(); + } +} + |