Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorslewis2009-09-11 17:00:09 +0000
committerslewis2009-09-11 17:00:09 +0000
commit9ccd593403985d518253dda4598a52960444cbbd (patch)
tree03245a5e147dadd085c71b399b44776134fbc83d /framework/bundles/org.eclipse.ecf.remoteservice.rest
parent09d1d3acab7578e711795dd24b86e0be47e325c9 (diff)
downloadorg.eclipse.ecf-9ccd593403985d518253dda4598a52960444cbbd.tar.gz
org.eclipse.ecf-9ccd593403985d518253dda4598a52960444cbbd.tar.xz
org.eclipse.ecf-9ccd593403985d518253dda4598a52960444cbbd.zip
Initial checkin of REST api work from google soc project 2009 from Holger Staudacher. CQ for IP review/approval of contribution: http://dev.eclipse.org/ipzilla/show_bug.cgi?id=3504
Diffstat (limited to 'framework/bundles/org.eclipse.ecf.remoteservice.rest')
-rw-r--r--framework/bundles/org.eclipse.ecf.remoteservice.rest/.classpath7
-rw-r--r--framework/bundles/org.eclipse.ecf.remoteservice.rest/.project28
-rw-r--r--framework/bundles/org.eclipse.ecf.remoteservice.rest/.settings/org.eclipse.jdt.core.prefs69
-rw-r--r--framework/bundles/org.eclipse.ecf.remoteservice.rest/META-INF/MANIFEST.MF29
-rw-r--r--framework/bundles/org.eclipse.ecf.remoteservice.rest/build.properties6
-rw-r--r--framework/bundles/org.eclipse.ecf.remoteservice.rest/plugin.xml20
-rw-r--r--framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/internal/remoteservice/rest/Activator.java70
-rw-r--r--framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/internal/remoteservice/rest/ResourceRepresentationFactory.java113
-rw-r--r--framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/internal/remoteservice/rest/RestServiceRegistry.java171
-rw-r--r--framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/IRestCall.java105
-rw-r--r--framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/IRestResponseProcessor.java26
-rw-r--r--framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/RestContainer.java357
-rw-r--r--framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/RestContainerInstantiatior.java60
-rw-r--r--framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/RestService.java409
-rw-r--r--framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/RestServiceReference.java51
-rw-r--r--framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/RestServiceRegistration.java106
-rw-r--r--framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/identity/RestID.java96
-rw-r--r--framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/identity/RestNamespace.java81
-rw-r--r--framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/resource/IRestResource.java38
-rw-r--r--framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/resource/XMLResource.java55
-rw-r--r--framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/util/DeleteRestCall.java44
-rw-r--r--framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/util/GetRestCall.java50
-rw-r--r--framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/util/PostRestCall.java46
-rw-r--r--framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/util/PutRestCall.java43
-rw-r--r--framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/util/RestCall.java77
-rw-r--r--framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/util/RestCallFactory.java107
-rw-r--r--framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/util/RestRemoteCall.java39
27 files changed, 2303 insertions, 0 deletions
diff --git a/framework/bundles/org.eclipse.ecf.remoteservice.rest/.classpath b/framework/bundles/org.eclipse.ecf.remoteservice.rest/.classpath
new file mode 100644
index 000000000..2fbb7a23e
--- /dev/null
+++ b/framework/bundles/org.eclipse.ecf.remoteservice.rest/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.4"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/framework/bundles/org.eclipse.ecf.remoteservice.rest/.project b/framework/bundles/org.eclipse.ecf.remoteservice.rest/.project
new file mode 100644
index 000000000..461918136
--- /dev/null
+++ b/framework/bundles/org.eclipse.ecf.remoteservice.rest/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.ecf.internal.remoteservice.rest</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>
+ </natures>
+</projectDescription>
diff --git a/framework/bundles/org.eclipse.ecf.remoteservice.rest/.settings/org.eclipse.jdt.core.prefs b/framework/bundles/org.eclipse.ecf.remoteservice.rest/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..7fae09b79
--- /dev/null
+++ b/framework/bundles/org.eclipse.ecf.remoteservice.rest/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,69 @@
+#Wed Aug 19 11:43:46 PDT 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2
+org.eclipse.jdt.core.compiler.compliance=1.4
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=warning
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=ignore
+org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=warning
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=ignore
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
+org.eclipse.jdt.core.compiler.problem.nullReference=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=ignore
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.3
diff --git a/framework/bundles/org.eclipse.ecf.remoteservice.rest/META-INF/MANIFEST.MF b/framework/bundles/org.eclipse.ecf.remoteservice.rest/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..c280292d8
--- /dev/null
+++ b/framework/bundles/org.eclipse.ecf.remoteservice.rest/META-INF/MANIFEST.MF
@@ -0,0 +1,29 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: REST API based on the remote service API
+Bundle-SymbolicName: org.eclipse.ecf.remoteservice.rest;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.eclipse.ecf.internal.remoteservice.rest.Activator
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: J2SE-1.4
+Export-Package: org.eclipse.ecf.internal.remoteservice.rest;x-internal:=true,
+ org.eclipse.ecf.remoteservice.rest,
+ org.eclipse.ecf.remoteservice.rest.identity,
+ org.eclipse.ecf.remoteservice.rest.resource,
+ org.eclipse.ecf.remoteservice.rest.util
+Import-Package: org.apache.commons.httpclient;version="3.0.1",
+ org.apache.commons.httpclient.auth;version="3.0.1",
+ org.apache.commons.httpclient.methods;version="3.0.1",
+ org.apache.commons.httpclient.params;version="3.0.1",
+ org.eclipse.core.runtime;version="3.4.0",
+ org.eclipse.ecf.core.sharedobject,
+ org.eclipse.ecf.provider.generic,
+ org.eclipse.ecf.provider.remoteservice.generic,
+ org.eclipse.ecf.remoteservice,
+ org.eclipse.ecf.remoteservice.events,
+ org.eclipse.ecf.remoteservice.util,
+ org.eclipse.ecf.remoteservice.util.tracker,
+ org.eclipse.equinox.concurrent.future;version="1.0.0",
+ org.osgi.framework;version="1.5.0",
+ org.osgi.util.tracker;version="1.4.2"
+Require-Bundle: org.eclipse.ecf;bundle-version="3.0.0"
diff --git a/framework/bundles/org.eclipse.ecf.remoteservice.rest/build.properties b/framework/bundles/org.eclipse.ecf.remoteservice.rest/build.properties
new file mode 100644
index 000000000..2dcc4bdc6
--- /dev/null
+++ b/framework/bundles/org.eclipse.ecf.remoteservice.rest/build.properties
@@ -0,0 +1,6 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml,\
+ bin/
diff --git a/framework/bundles/org.eclipse.ecf.remoteservice.rest/plugin.xml b/framework/bundles/org.eclipse.ecf.remoteservice.rest/plugin.xml
new file mode 100644
index 000000000..747f90590
--- /dev/null
+++ b/framework/bundles/org.eclipse.ecf.remoteservice.rest/plugin.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+ <extension
+ point="org.eclipse.ecf.containerFactory">
+ <containerFactory
+ class="org.eclipse.ecf.remoteservice.rest.RestContainerInstantiatior"
+ description="Client Container for the REST style"
+ name="ecf.rest.client">
+ </containerFactory>
+ </extension>
+ <extension
+ point="org.eclipse.ecf.identity.namespace">
+ <namespace
+ class="org.eclipse.ecf.remoteservice.rest.identity.RestNamespace"
+ name="ecf.rest.namespace">
+ </namespace>
+ </extension>
+
+</plugin>
diff --git a/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/internal/remoteservice/rest/Activator.java b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/internal/remoteservice/rest/Activator.java
new file mode 100644
index 000000000..c63626ea5
--- /dev/null
+++ b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/internal/remoteservice/rest/Activator.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+* Copyright (c) 2009 EclipseSource 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:
+* EclipseSource - initial API and implementation
+*******************************************************************************/
+package org.eclipse.ecf.internal.remoteservice.rest;
+
+import org.eclipse.ecf.remoteservice.rest.resource.IRestResource;
+import org.eclipse.ecf.remoteservice.rest.resource.XMLResource;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator implements BundleActivator {
+
+ // The plug-in ID
+ public static final String PLUGIN_ID = "org.eclipse.ecf.remoteservice.rest";
+
+ // The shared instance
+ private static Activator plugin;
+
+ private BundleContext context;
+
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext context) throws Exception {
+ plugin = this;
+ this.context = context;
+ registerXMLService( context );
+ }
+
+ private void registerXMLService(BundleContext context) {
+ IRestResource xmlResource = new XMLResource();
+ context.registerService(IRestResource.class.getName(), xmlResource, null);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static synchronized Activator getDefault() {
+ if(plugin == null) {
+ plugin = new Activator();
+ }
+ return plugin;
+ }
+
+ public BundleContext getContext() {
+ return context;
+ }
+
+}
diff --git a/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/internal/remoteservice/rest/ResourceRepresentationFactory.java b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/internal/remoteservice/rest/ResourceRepresentationFactory.java
new file mode 100644
index 000000000..b193cbf36
--- /dev/null
+++ b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/internal/remoteservice/rest/ResourceRepresentationFactory.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+* Copyright (c) 2009 EclipseSource 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:
+* EclipseSource - initial API and implementation
+*******************************************************************************/
+package org.eclipse.ecf.internal.remoteservice.rest;
+
+import java.io.IOException;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.httpclient.HttpMethod;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.ecf.remoteservice.rest.IRestCall;
+import org.eclipse.ecf.remoteservice.rest.resource.IRestResource;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.BundleListener;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
+
+public class ResourceRepresentationFactory implements IAdaptable {
+
+ private static ResourceRepresentationFactory factory;
+ private List resources = new ArrayList();
+
+ private class RestResourceTracker extends ServiceTracker {
+
+ public RestResourceTracker(BundleContext context) {
+ super(context, IRestResource.class.getName(), null);
+ }
+
+ public Object addingService(ServiceReference reference) {
+ Object service = context.getService(reference);
+ if(service != null && service instanceof IRestResource) {
+ if(!resources.contains(service))
+ resources.add(service);
+ }
+ return service;
+ }
+
+ public void removedService(ServiceReference reference, Object service) {
+ resources.remove(service);
+ context.ungetService(reference);
+ }
+
+ }
+
+ private ResourceRepresentationFactory() {
+
+ }
+
+ public static ResourceRepresentationFactory getDefault() {
+ if(factory == null) {
+ factory = new ResourceRepresentationFactory();
+ factory.init();
+ }
+ return factory;
+ }
+
+ private void init() {
+ Activator activator = Activator.getDefault();
+ BundleContext context = activator.getContext();
+ try {
+ ServiceReference[] references = context.getServiceReferences(IRestResource.class.getName(), null);
+ for (int i = 0; i < references.length; i++) {
+ Object service = context.getService(references[i]);
+ if(service instanceof IRestResource)
+ resources.add((IRestResource)service);
+ }
+ } catch (InvalidSyntaxException e) {
+ e.printStackTrace();
+ }
+ final ServiceTracker resourceTracker = new RestResourceTracker(context);
+ resourceTracker.open();
+ activator.getContext().addBundleListener(new BundleListener() {
+
+ public void bundleChanged(BundleEvent event) {
+ if(event.getType() == BundleEvent.STOPPING)
+ resourceTracker.close();
+ }
+ });
+ }
+
+ /**
+ * Creates a resource representation for the resource defined in {@link IRestCall}'s
+ * getEstimatedResourceIdentifier() Method. This will be compared with all
+ * registered services of the type {@link IRestResource} by calling their getIdentifier()
+ * methods. If a service matches the estimated identifier it's parse method will
+ * be invoked to parse the content of the resource.
+ */
+ public Object createResourceRepresentation(HttpMethod method, IRestCall restCall) throws ParseException, IOException {
+ for (int i = 0; i < resources.size(); i++) {
+ IRestResource resource = (IRestResource)resources.get(i);
+ if(resource.getIdentifier().equals(restCall.getEstimatedResourceIdentifier()))
+ return resource.createRepresentation(method.getResponseBodyAsString());
+ }
+ return null;
+ }
+
+ public Object getAdapter(Class adapter) {
+ if(adapter == List.class)
+ return resources;
+ return null;
+ }
+
+}
diff --git a/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/internal/remoteservice/rest/RestServiceRegistry.java b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/internal/remoteservice/rest/RestServiceRegistry.java
new file mode 100644
index 000000000..11ea9ade5
--- /dev/null
+++ b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/internal/remoteservice/rest/RestServiceRegistry.java
@@ -0,0 +1,171 @@
+/*******************************************************************************
+* Copyright (c) 2009 EclipseSource 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:
+* EclipseSource - initial API and implementation
+*******************************************************************************/
+package org.eclipse.ecf.internal.remoteservice.rest;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.ecf.core.ContainerConnectException;
+import org.eclipse.ecf.core.identity.ID;
+import org.eclipse.ecf.core.security.IConnectContext;
+import org.eclipse.ecf.provider.remoteservice.generic.RemoteFilterImpl;
+import org.eclipse.ecf.remoteservice.IRemoteFilter;
+import org.eclipse.ecf.remoteservice.IRemoteService;
+import org.eclipse.ecf.remoteservice.IRemoteServiceID;
+import org.eclipse.ecf.remoteservice.IRemoteServiceReference;
+import org.eclipse.ecf.remoteservice.IRemoteServiceRegistration;
+import org.eclipse.ecf.remoteservice.rest.RestContainer;
+import org.eclipse.ecf.remoteservice.rest.RestServiceReference;
+import org.eclipse.ecf.remoteservice.rest.RestServiceRegistration;
+import org.osgi.framework.InvalidSyntaxException;
+
+/**
+ * A registry for RestServices to fit the remote service API.
+ */
+public class RestServiceRegistry implements Serializable {
+
+ private static final long serialVersionUID = -7002609161000008043L;
+ private static long nextServiceId = 0L;
+ private ID containerId;
+ private List registrations;
+ private RestContainer container;
+ private IConnectContext connectContext;
+
+ public RestServiceRegistry(RestContainer container) {
+ this.containerId = container.getID();
+ this.container = container;
+ registrations = new ArrayList();
+ }
+
+ public RestContainer getContainer() {
+ return container;
+ }
+
+ public long getNextServiceId() {
+ return nextServiceId++;
+ }
+
+ public ID getContainerId() {
+ return containerId;
+ }
+
+ public void registerRegistration(RestServiceRegistration registration) {
+ if(!registrations.contains(registration))
+ registrations.add(registration);
+ }
+
+ public void unregisterRegistration(RestServiceRegistration registration) {
+ registrations.remove(registration);
+ }
+
+ public IRemoteService findService(IRemoteServiceReference reference) {
+ for (int i = 0; i < registrations.size(); i++) {
+ RestServiceRegistration reg = (RestServiceRegistration) registrations.get(i);
+ if( reg.getReference().equals(reference))
+ return reg.getService();
+ }
+ return null;
+ }
+
+ public IRemoteServiceReference findServiceReference(IRemoteServiceID serviceID) {
+ for (int i = 0; i < registrations.size(); i++) {
+ IRemoteServiceRegistration reg = (IRemoteServiceRegistration)registrations.get(i);
+ if( serviceID.equals(reg.getID()))
+ return reg.getReference();
+ }
+ return null;
+ }
+
+ public IRemoteServiceReference[] getRemoteServiceReferences(ID target, String clazz, String filter) {
+ if (target == null)
+ return getRemoteServiceReferences((ID[]) null, clazz, filter);
+ // If we're not already connected, then connect to targetID
+ // If we *are* already connected, then we do *not* connect to target, but rather just search for targetID/endpoint
+ if (container.getConnectedID() == null) {
+ try {
+ container.connect(target, connectContext);
+ } catch (ContainerConnectException e) {
+ e.printStackTrace();
+ }
+ }
+ // Now we're connected (or already were connected), so we look for remote service references for target
+ return getRemoteServiceReferences(new ID[] {target}, clazz, filter);
+ }
+
+ public IRemoteServiceReference[] getRemoteServiceReferences(ID[] idFilter, String clazz, String filter) {
+ if (clazz == null)
+ return null;
+ List result = new ArrayList();
+ IRemoteFilter remoteFilter = null;
+ try {
+ remoteFilter = (filter == null) ? null : new RemoteFilterImpl(filter);
+ } catch (InvalidSyntaxException e) {
+ e.printStackTrace();
+ }
+ for (int i = 0; i < registrations.size(); i++) {
+ RestServiceRegistration reg = (RestServiceRegistration)registrations.get(i);
+ if(idFilter == null || containsID( reg, idFilter)) {
+ String[] clazzes = reg.getClazzes();
+ boolean found = false;
+ for (int j = 0; j < clazzes.length && !found; j++) {
+ if(clazz.equals(clazzes[j]) && !result.contains(reg.getReference())) {
+ result.add(reg.getReference());
+ found = true;
+ }
+ }
+ }
+ }
+ // check the filter
+ if(remoteFilter != null){
+ for (int i = 0; i < result.size(); i++) {
+ RestServiceReference ref = (RestServiceReference)result.get(i);
+ if(!remoteFilter.match(ref))
+ result.remove(i);
+ }
+ }
+ if(result.size() > 0 ) {
+ RestServiceReference[] array = new RestServiceReference[result.size()];
+ result.toArray(array);
+ return (array.length == 0) ? null : array;
+ }
+ return null;
+ }
+
+ private boolean containsID(RestServiceRegistration reg, ID[] idFilter) {
+ for (int i = 0; i < idFilter.length; i++) {
+ if(reg.getID().equals(idFilter[i]))
+ return true;
+ }
+ return false;
+ }
+
+ public IRemoteServiceID getRemoteServiceID(ID containerID, long containerRelativeID) {
+ if(containerID.equals(this.containerId)) {
+ for (int i = 0; i < registrations.size(); i++) {
+ RestServiceRegistration reg = (RestServiceRegistration) registrations.get(i);
+ if(reg.getID().getContainerRelativeID() == containerRelativeID)
+ return reg.getID();
+ }
+ }
+ return null;
+ }
+
+ public String[] getClazzes(IRemoteServiceReference reference) {
+ for (int i = 0; i < registrations.size(); i++) {
+ RestServiceRegistration reg = (RestServiceRegistration) registrations.get(i);
+ if(reg.getReference().equals(reference)) {
+ return reg.getClazzes();
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/IRestCall.java b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/IRestCall.java
new file mode 100644
index 000000000..ab17f88dd
--- /dev/null
+++ b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/IRestCall.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2009 EclipseSource 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:
+ * EclipseSource - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ecf.remoteservice.rest;
+
+import java.net.URI;
+import java.util.Map;
+
+import org.apache.commons.httpclient.methods.RequestEntity;
+import org.eclipse.ecf.remoteservice.rest.util.RestCallFactory;
+
+/**
+ * This class acts as a container for a specific REST service call. It can be
+ * implemented from scratch or created via {@link RestCallFactory}.
+ */
+public interface IRestCall {
+
+ /**
+ * Http GET method.
+ */
+ public static final String HTTP_GET = "GET";
+ /**
+ * Http POST method.
+ */
+ public static final String HTTP_POST = "POST";
+ /**
+ * Http PUT method.
+ */
+ public static final String HTTP_PUT = "PUT";
+ /**
+ * Htpp DELETE method.
+ */
+ public static final String HTTP_DELETE = "DELETE";
+
+ /**
+ * Every rest web service returns a resource representation. I.e a
+ * representation as a xml file from a xml resource.
+ *
+ * @return the identifier for a estimated resource, i.e.
+ * ecf.rest.resource.xml. Will not be <code>null</code>.
+ */
+ public String getEstimatedResourceIdentifier();
+
+ /**
+ * Defines the URI for the rest service. This should be a unique URI which
+ * belongs to a rest service i.e on the web.
+ *
+ * @return the URI of a rest service. Will not be <code>null</code>.
+ */
+ public URI getURI();
+
+ /**
+ * Defines the HTTP method for this type of rest call. For example a GET or
+ * POST method.
+ *
+ * @return the HTTP Method as one of the IRestCall HTTP_* constants. Will
+ * not be <code>null</code>.
+ */
+ public String getMethod();
+
+ /**
+ * Defines the call specific request headers.
+ *
+ * @return a {@link Map} object which contains the header parameters. May be
+ * <code>null</code>.
+ */
+ public Map getRequestHeaders();
+
+ /**
+ * Defines the key-value pairs parameter for this call. A Rest Call may
+ * either have parameters or a RequestEntity (mutual exclusive).
+ *
+ * @return an array containing key-value pairs in the format: key=value. May
+ * be <code>null</code>.
+ *
+ * @see #getRequestEntity()
+ */
+ public Object[] getParameters();
+
+ /**
+ * Get timeout (in ms) for the rest call.
+ *
+ * @return long timeout in ms
+ */
+ public long getTimeout();
+
+ /**
+ * Gets the request entity. The RequestEntity is typically used to transmit
+ * data by HTTP_POST and HTTP_PUT calls. HTTP_GET calls may not use a
+ * request entity A. Rest Call may either have parameters or a RequestEntity
+ * (mutual exclusive)
+ *
+ * @return the request entity
+ *
+ * @see RequestEntity
+ */
+ public RequestEntity getRequestEntity();
+
+}
diff --git a/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/IRestResponseProcessor.java b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/IRestResponseProcessor.java
new file mode 100644
index 000000000..eaee3edbe
--- /dev/null
+++ b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/IRestResponseProcessor.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+* Copyright (c) 2009 EclipseSource 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:
+* EclipseSource - initial API and implementation
+*******************************************************************************/
+package org.eclipse.ecf.remoteservice.rest;
+
+/**
+ * If a POJO is used as a REST service object than it has to implement this interface
+ * to get called if a response from the service was received. Otherwise the POJO
+ * gets no content.
+ */
+public interface IRestResponseProcessor {
+
+ /**
+ * This method is called if the response from a rest service was received.
+ *
+ * @param response the parsed resource representation.
+ */
+ public void processResource(Object response);
+
+}
diff --git a/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/RestContainer.java b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/RestContainer.java
new file mode 100644
index 000000000..2e94d20d4
--- /dev/null
+++ b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/RestContainer.java
@@ -0,0 +1,357 @@
+/*******************************************************************************
+* Copyright (c) 2009 EclipseSource 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:
+* EclipseSource - initial API and implementation
+*******************************************************************************/
+package org.eclipse.ecf.remoteservice.rest;
+
+import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.ecf.core.AbstractContainer;
+import org.eclipse.ecf.core.ContainerConnectException;
+import org.eclipse.ecf.core.IContainer;
+import org.eclipse.ecf.core.events.ContainerConnectedEvent;
+import org.eclipse.ecf.core.events.ContainerConnectingEvent;
+import org.eclipse.ecf.core.events.ContainerDisconnectedEvent;
+import org.eclipse.ecf.core.events.ContainerDisconnectingEvent;
+import org.eclipse.ecf.core.events.ContainerDisposeEvent;
+import org.eclipse.ecf.core.identity.ID;
+import org.eclipse.ecf.core.identity.Namespace;
+import org.eclipse.ecf.core.jobs.JobsExecutor;
+import org.eclipse.ecf.core.security.IConnectContext;
+import org.eclipse.ecf.core.util.ECFException;
+import org.eclipse.ecf.internal.remoteservice.rest.RestServiceRegistry;
+import org.eclipse.ecf.remoteservice.IRemoteCall;
+import org.eclipse.ecf.remoteservice.IRemoteFilter;
+import org.eclipse.ecf.remoteservice.IRemoteService;
+import org.eclipse.ecf.remoteservice.IRemoteServiceContainer;
+import org.eclipse.ecf.remoteservice.IRemoteServiceContainerAdapter;
+import org.eclipse.ecf.remoteservice.IRemoteServiceID;
+import org.eclipse.ecf.remoteservice.IRemoteServiceListener;
+import org.eclipse.ecf.remoteservice.IRemoteServiceReference;
+import org.eclipse.ecf.remoteservice.IRemoteServiceRegistration;
+import org.eclipse.ecf.remoteservice.RemoteServiceContainer;
+import org.eclipse.ecf.remoteservice.events.IRemoteServiceEvent;
+import org.eclipse.ecf.remoteservice.events.IRemoteServiceRegisteredEvent;
+import org.eclipse.ecf.remoteservice.events.IRemoteServiceUnregisteredEvent;
+import org.eclipse.ecf.remoteservice.rest.identity.RestID;
+import org.eclipse.ecf.remoteservice.util.RemoteFilterImpl;
+import org.eclipse.equinox.concurrent.future.IExecutor;
+import org.eclipse.equinox.concurrent.future.IFuture;
+import org.eclipse.equinox.concurrent.future.IProgressRunnable;
+import org.osgi.framework.InvalidSyntaxException;
+
+/**
+ * A container for REST services. This was implemented using the ECF#RemoteServiceAPI.
+ */
+public class RestContainer extends AbstractContainer implements IRemoteServiceContainerAdapter, IRemoteServiceContainer {
+
+ public static final String NAME = "ecf.rest.client";
+ private ID connectedId;
+ private ID id;
+ private List remoteServiceListeners = new ArrayList();
+ private List containerListeners = new ArrayList();
+ private RestServiceRegistry registry;
+ private List referencesInUse = new ArrayList();
+ private RemoteServiceContainer remoteServiceContainer;
+ private IConnectContext connectContext;
+ private URL originBaseUrl;
+ private Map restCalls = new HashMap();
+
+ public RestContainer(ID id) {
+ this.id = id;
+ remoteServiceContainer = new RemoteServiceContainer(this, this);
+ registry = new RestServiceRegistry(this);
+ }
+
+ public RestContainer() {
+ }
+
+ public void connect(ID targetID, IConnectContext connectContext) throws ContainerConnectException {
+ fireContainerEvent(new ContainerConnectingEvent(id, targetID));
+ if(targetID instanceof RestID){
+ URL baseURL = ((RestID)targetID).getBaseURL();
+ if(this.id instanceof RestID) {
+ RestID restId = (RestID)this.id;
+ originBaseUrl = restId.getBaseURL();
+ restId.setBaseUrl(baseURL);
+ }
+ }
+ connectedId = targetID;
+ this.connectContext = connectContext;
+ fireContainerEvent(new ContainerConnectedEvent(id, targetID));
+ }
+
+ public void disconnect() {
+ ID oldId = connectedId;
+ fireContainerEvent(new ContainerDisconnectingEvent(id, oldId));
+ connectedId = null;
+ connectContext = null;
+ if(id instanceof RestID)
+ ((RestID)id).setBaseUrl(originBaseUrl);
+ fireContainerEvent(new ContainerDisconnectedEvent(id, oldId));
+ }
+
+ public void dispose() {
+ disconnect();
+ fireContainerEvent(new ContainerDisposeEvent(id));
+ containerListeners.clear();
+ remoteServiceListeners.clear();
+
+ }
+
+ void fireRemoteServiceEvent(IRemoteServiceEvent event) {
+ synchronized (remoteServiceListeners) {
+ for (int i = 0; i < remoteServiceListeners.size(); i++) {
+ ((IRemoteServiceListener) remoteServiceListeners.get(i)).handleServiceEvent(event);
+ }
+ }
+ }
+
+ public Namespace getConnectNamespace() {
+ if( connectedId != null )
+ return connectedId.getNamespace();
+ return null;
+ }
+
+ public ID getConnectedID() {
+ return connectedId;
+ }
+
+
+ public ID getID() {
+ return id;
+ }
+
+ public void addRemoteServiceListener(IRemoteServiceListener listener) {
+ remoteServiceListeners.add(listener);
+ }
+
+ public IFuture asyncGetRemoteServiceReferences(final ID[] idFilter, final String clazz, final String filter) {
+ IExecutor executor = new JobsExecutor("asyncGetRemoteServiceReferences"); //$NON-NLS-1$
+ return executor.execute(new IProgressRunnable() {
+ public Object run(IProgressMonitor monitor) throws Exception {
+ return getRemoteServiceReferences(idFilter, clazz, filter);
+ }
+ }, null);
+ }
+
+ public IFuture asyncGetRemoteServiceReferences(final ID target, final String clazz, final String filter) {
+ IExecutor executor = new JobsExecutor("asyncGetRemoteServiceReferences"); //$NON-NLS-1$
+ return executor.execute(new IProgressRunnable() {
+ public Object run(IProgressMonitor monitor) throws Exception {
+ return getRemoteServiceReferences(target, clazz, filter);
+ }
+ }, null);
+ }
+
+ public IRemoteFilter createRemoteFilter(String filter) throws InvalidSyntaxException {
+ return new RemoteFilterImpl(filter);
+ }
+
+ public IRemoteServiceReference[] getAllRemoteServiceReferences(String clazz, String filter) throws InvalidSyntaxException {
+ return null;
+ }
+
+ public IRemoteService getRemoteService(IRemoteServiceReference reference) {
+ IRemoteService service = registry.findService(reference);
+ if(service != null)
+ referencesInUse.add(reference);
+ return service;
+ }
+
+ public IRemoteServiceID getRemoteServiceID(ID containerID, long containerRelativeID) {
+ return registry.getRemoteServiceID( containerID, containerRelativeID);
+ }
+
+ public Namespace getRemoteServiceNamespace() {
+ if(id == null)
+ return null;
+ return id.getNamespace();
+ }
+
+ public IRemoteServiceReference getRemoteServiceReference(IRemoteServiceID serviceID) {
+ return registry.findServiceReference(serviceID);
+ }
+
+ public IRemoteServiceReference[] getRemoteServiceReferences(ID[] idFilter, String clazz, String filter) throws InvalidSyntaxException {
+ return registry.getRemoteServiceReferences(idFilter, clazz, filter);
+ }
+
+ public IRemoteServiceReference[] getRemoteServiceReferences(ID target, String clazz, String filter) throws InvalidSyntaxException, ContainerConnectException {
+ return registry.getRemoteServiceReferences( target, clazz, filter);
+ }
+
+ public IRemoteServiceRegistration registerRemoteService(final String[] clazzes, Object service, Dictionary properties) {
+ final RestServiceRegistration registration = new RestServiceRegistration(clazzes, service, properties, registry);
+ fireRemoteServiceEvent(new IRemoteServiceRegisteredEvent() {
+
+ public IRemoteServiceReference getReference() {
+ return registration.getReference();
+ }
+
+ public ID getLocalContainerID() {
+ return registration.getContainerID();
+ }
+
+ public ID getContainerID() {
+ return id;
+ }
+
+ public String[] getClazzes() {
+ return clazzes;
+ }
+ });
+ if(service instanceof RestService)
+ ((RestService)service).setReference(registration.getReference());
+ registry.registerRegistration(registration);
+ return registration;
+ }
+
+ public void removeRemoteServiceListener(IRemoteServiceListener listener) {
+ remoteServiceListeners.remove(listener);
+ }
+
+ public void setConnectContextForAuthentication(IConnectContext connectContext) {
+ this.connectContext = connectContext;
+ }
+
+ public boolean ungetRemoteService(final IRemoteServiceReference reference) {
+ boolean result = referencesInUse.contains(reference);
+ referencesInUse.remove(reference);
+ fireRemoteServiceEvent(new IRemoteServiceUnregisteredEvent() {
+
+ public IRemoteServiceReference getReference() {
+ return reference;
+ }
+
+ public ID getLocalContainerID() {
+ return id;
+ }
+
+ public ID getContainerID() {
+ return id;
+ }
+
+ public String[] getClazzes() {
+ return registry.getClazzes( reference );
+ }
+ });
+ return result;
+ }
+
+ public IContainer getContainer() {
+ return remoteServiceContainer.getContainer();
+ }
+
+ public IRemoteServiceContainerAdapter getContainerAdapter() {
+ return remoteServiceContainer.getContainerAdapter();
+ }
+
+ public IRemoteService getRemoteService(String targetLocation, String serviceInterfaceClass, String filter) throws ContainerConnectException, InvalidSyntaxException {
+ return remoteServiceContainer.getRemoteService(targetLocation, serviceInterfaceClass, filter);
+ }
+
+ public IRemoteService getRemoteService(String targetLocation, String serviceInterfaceClass) throws ContainerConnectException {
+ return remoteServiceContainer.getRemoteService(targetLocation, serviceInterfaceClass);
+ }
+
+ public IRemoteService getRemoteService(String serviceInterfaceClass) {
+ return remoteServiceContainer.getRemoteService(serviceInterfaceClass);
+ }
+
+ IConnectContext getConnectContext() {
+ return connectContext;
+ }
+
+ public IRestCall lookupRestCall(IRemoteCall call) {
+ String key = call.getMethod();
+ return (IRestCall) restCalls.get(key);
+ }
+
+ /**
+ * Registers a POJO object as a REST service. The service object has to implement
+ * {@link IRestResponseProcessor} to get notified about an incoming response.
+ * This method also registers a {@link IRemoteService} object for the rest service.
+ * To associate a {@link IRemoteCall} to the rest service object the
+ * {@link IRemoteCall#getMethod()} will be used. Therefore a {@link Map} has to
+ * passed to this method with a {@link String} as key and an {@link IRestCall} object
+ * as value.
+ *
+ * @param clazzes a String array woth classnames which the service object has to implement.
+ * @param service the service object as a POJO
+ * @param restCalls a {@link Map} with String as keys and {@link IRestCall} objects as value.
+ * @param properties to be associated with service.
+ *
+ * @return The service registration for the registered {@link IRemoteService}.
+ * Will not return <code>null</code>.
+ */
+ public RestServiceRegistration registerRestService( String[] clazzes, Object service, Map restCalls, Dictionary properties) throws ECFException {
+ if(checkServiceClass(clazzes, service) == null && service instanceof IRestResponseProcessor) {
+ // map the keys to the restCalls
+ Object[] keys = restCalls.keySet().toArray();
+ for (int i = 0; i < keys.length; i++) {
+ Object restCall = restCalls.get(keys[i]);
+ if(!(restCall instanceof IRestCall))
+ throw new ECFException("registered calls must be instacnes of IRestCall");
+ this.restCalls.put(keys[i], restCall);
+ }
+ RestService restService = new RestService(service);
+ return (RestServiceRegistration) registerRemoteService(new String[]{RestService.class.getName()}, restService, properties);
+ } else
+ throw new IllegalArgumentException("service does not implement all classes or IRestResponseProcessor");
+ }
+
+ /**
+ * Return the name of the class that is not satisfied by the service object.
+ * @param clazzes Array of class names.
+ * @param serviceObject Service object.
+ * @return The name of the class that is not satisfied by the service object.
+ */
+ private String checkServiceClass(final String[] clazzes, final Object serviceObject) {
+ ClassLoader cl = (ClassLoader) AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return serviceObject.getClass().getClassLoader();
+ }
+ });
+ for (int i = 0, len = clazzes.length; i < len; i++) {
+ try {
+ Class serviceClazz = cl == null ? Class.forName(clazzes[i]) : cl.loadClass(clazzes[i]);
+ if (!serviceClazz.isInstance(serviceObject))
+ return clazzes[i];
+ } catch (ClassNotFoundException e) {
+ //This check is rarely done
+ if (extensiveCheckServiceClass(clazzes[i], serviceObject.getClass()))
+ return clazzes[i];
+ }
+ }
+ return null;
+ }
+
+ private static boolean extensiveCheckServiceClass(String clazz, Class serviceClazz) {
+ if (clazz.equals(serviceClazz.getName()))
+ return false;
+ Class[] interfaces = serviceClazz.getInterfaces();
+ for (int i = 0, len = interfaces.length; i < len; i++)
+ if (!extensiveCheckServiceClass(clazz, interfaces[i]))
+ return false;
+ Class superClazz = serviceClazz.getSuperclass();
+ if (superClazz != null)
+ if (!extensiveCheckServiceClass(clazz, superClazz))
+ return false;
+ return true;
+ }
+
+}
diff --git a/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/RestContainerInstantiatior.java b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/RestContainerInstantiatior.java
new file mode 100644
index 000000000..d4c293dbd
--- /dev/null
+++ b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/RestContainerInstantiatior.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+* Copyright (c) 2009 EclipseSource 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:
+* EclipseSource - initial API and implementation
+*******************************************************************************/
+package org.eclipse.ecf.remoteservice.rest;
+
+import java.net.URL;
+
+import org.eclipse.ecf.core.ContainerCreateException;
+import org.eclipse.ecf.core.ContainerTypeDescription;
+import org.eclipse.ecf.core.IContainer;
+import org.eclipse.ecf.core.identity.ID;
+import org.eclipse.ecf.core.provider.IContainerInstantiator;
+import org.eclipse.ecf.remoteservice.rest.identity.RestID;
+import org.eclipse.ecf.remoteservice.rest.identity.RestNamespace;
+
+/**
+ * This class is omnly used for creating instances of {@link RestContainer}.
+ */
+public class RestContainerInstantiatior implements IContainerInstantiator {
+
+ public IContainer createInstance(ContainerTypeDescription description, Object[] parameters) throws ContainerCreateException {
+ if(!description.getName().equals(RestContainer.NAME))
+ throw new ContainerCreateException();
+ if(parameters == null)
+ throw new ContainerCreateException();
+ if(parameters.length > 0 && (parameters[0] instanceof URL)) {
+ URL baseUrl = (URL) parameters[0];
+ RestNamespace namespace = new RestNamespace(RestNamespace.NAME, description.getDescription());
+ RestID id = new RestID(namespace, baseUrl);
+ return new RestContainer(id);
+ }
+ if(parameters.length > 0 && (parameters[0] instanceof ID)) {
+ return new RestContainer((ID) parameters[0]);
+ }
+ throw new ContainerCreateException();
+
+ }
+
+ public String[] getSupportedAdapterTypes(ContainerTypeDescription description) {
+
+ return null;
+ }
+
+ public String[] getSupportedIntents(ContainerTypeDescription description) {
+ return null;
+ }
+
+ public Class[][] getSupportedParameterTypes(ContainerTypeDescription description) {
+ if(!description.getName().equals(RestContainer.NAME))
+ throw new IllegalArgumentException("Description must be "+RestContainer.NAME);
+ return new Class[][]{{ URL.class }};
+ }
+
+}
diff --git a/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/RestService.java b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/RestService.java
new file mode 100644
index 000000000..8428ae155
--- /dev/null
+++ b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/RestService.java
@@ -0,0 +1,409 @@
+/*******************************************************************************
+ * Copyright (c) 2009 EclipseSource 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:
+ * EclipseSource - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ecf.remoteservice.rest;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URL;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.httpclient.Credentials;
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.HttpException;
+import org.apache.commons.httpclient.HttpMethod;
+import org.apache.commons.httpclient.HttpStatus;
+import org.apache.commons.httpclient.NameValuePair;
+import org.apache.commons.httpclient.UsernamePasswordCredentials;
+import org.apache.commons.httpclient.auth.AuthScope;
+import org.apache.commons.httpclient.methods.DeleteMethod;
+import org.apache.commons.httpclient.methods.GetMethod;
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.commons.httpclient.methods.PutMethod;
+import org.apache.commons.httpclient.methods.RequestEntity;
+import org.apache.commons.httpclient.methods.StringRequestEntity;
+import org.apache.commons.httpclient.params.HttpClientParams;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.ecf.core.identity.ID;
+import org.eclipse.ecf.core.security.Callback;
+import org.eclipse.ecf.core.security.CallbackHandler;
+import org.eclipse.ecf.core.security.IConnectContext;
+import org.eclipse.ecf.core.security.NameCallback;
+import org.eclipse.ecf.core.security.ObjectCallback;
+import org.eclipse.ecf.core.security.UnsupportedCallbackException;
+import org.eclipse.ecf.core.util.ECFException;
+import org.eclipse.ecf.internal.remoteservice.rest.ResourceRepresentationFactory;
+import org.eclipse.ecf.remoteservice.IRemoteCall;
+import org.eclipse.ecf.remoteservice.IRemoteCallListener;
+import org.eclipse.ecf.remoteservice.IRemoteService;
+import org.eclipse.ecf.remoteservice.IRemoteServiceReference;
+import org.eclipse.ecf.remoteservice.events.IRemoteCallCompleteEvent;
+import org.eclipse.ecf.remoteservice.events.IRemoteCallStartEvent;
+import org.eclipse.ecf.remoteservice.rest.identity.RestID;
+import org.eclipse.equinox.concurrent.future.AbstractExecutor;
+import org.eclipse.equinox.concurrent.future.IFuture;
+import org.eclipse.equinox.concurrent.future.IProgressRunnable;
+import org.eclipse.equinox.concurrent.future.ThreadsExecutor;
+
+/**
+ * This class represents a REST service from the client side of view. So a RESTful
+ * web service can be accessed via the methods provided by this class. Mostly the
+ * methods are inherited from {@link IRemoteService}.
+ */
+public class RestService implements IRemoteService {
+
+ /**
+ * inner class implementing the asynchronous result object. This
+ * implementation also provides the calling infrastructure.
+ */
+ private class AsyncResult extends Thread {
+
+ // the result of the call.
+ Object result;
+
+ // the exception, if any happened during the call.
+ Throwable exception;
+
+ // the remote call object.
+ IRestCall call;
+
+ // the callback listener, if provided.
+ private IRemoteCallListener listener;
+
+ // constructor
+ AsyncResult(final IRestCall call, final IRemoteCallListener listener) {
+ this.call = call;
+ this.listener = listener;
+ }
+
+ // the call happens here.
+ public void run() {
+ Object r = null;
+ Throwable e = null;
+
+ final long reqID = getNextID();
+
+ if (listener != null) {
+ listener.handleEvent(new IRemoteCallStartEvent() {
+ public IRemoteCall getCall() {
+ // TODO: should return the remoteCall
+ return null;
+ }
+
+ public IRemoteServiceReference getReference() {
+ return reference;
+ }
+
+ public long getRequestId() {
+ return reqID;
+ }
+ });
+ }
+
+ try {
+ r = callSync(call);
+ } catch (Throwable t) {
+ e = t;
+ }
+
+ synchronized (AsyncResult.this) {
+ result = r;
+ exception = e;
+ AsyncResult.this.notify();
+ }
+
+ if (listener != null) {
+ listener.handleEvent(new IRemoteCallCompleteEvent() {
+
+ public Throwable getException() {
+ return exception;
+ }
+
+ public Object getResponse() {
+ return result;
+ }
+
+ public boolean hadException() {
+ return exception != null;
+ }
+
+ public long getRequestId() {
+ return reqID;
+ }
+ });
+ }
+ }
+ }
+
+ private int nextID;
+ private IRemoteServiceReference reference;
+ private Object proxy;
+
+ public RestService(IRemoteServiceReference reference) {
+ this.reference = reference;
+ }
+
+ public RestService(Object proxy) {
+ this.proxy = proxy;
+ reference = null;
+ }
+
+ public RestService() {
+ reference = null;
+ }
+
+ /**
+ * get the next call id.
+ *
+ * @return the next call id.
+ */
+ synchronized long getNextID() {
+ return nextID++;
+ }
+
+ public void callAsync(IRemoteCall call, IRemoteCallListener listener) {
+ callAsync(lookupRestCall(call), listener);
+ }
+
+ public void callAsync(IRestCall restCall, IRemoteCallListener listener) {
+ new AsyncResult(restCall, listener).start();
+ }
+
+ public IFuture callAsync(final IRemoteCall call) {
+ return callAsync(lookupRestCall(call));
+ }
+
+ public IFuture callAsync(final IRestCall call) {
+ final AbstractExecutor executor = new ThreadsExecutor();
+ return executor.execute(new IProgressRunnable() {
+ public Object run(IProgressMonitor monitor) throws Exception {
+ return callSync(call);
+ }
+ }, null);
+ }
+
+ public Object callSync(IRemoteCall call) throws ECFException {
+ return callSync(lookupRestCall(call));
+ }
+
+ public Object callSync(IRestCall call) throws ECFException {
+ if(call == null)
+ throw new ECFException("no IRestCall found for IRemoteCall");
+ return callHttpMethod(call);
+ }
+
+ private IRestCall lookupRestCall(IRemoteCall call) {
+ if(reference instanceof RestServiceReference) {
+ RestServiceReference ref = (RestServiceReference) reference;
+ RestContainer container = ref.getContainer();
+ return container.lookupRestCall(call);
+ }
+ return null;
+ }
+
+ /**
+ * Calls the Rest service with given URL of IRestCall. The returned value is
+ * the response body as an InputStream.
+ *
+ * @param restCall
+ * The Rest Service to call represented by an IRestCall object
+ * @return The InputStream of the response body or <code>null</code> if an
+ * error occurs.
+ */
+ public Object callHttpMethod(final IRestCall restCall) throws ECFException {
+ // call the method
+ HttpClient httpClient = new HttpClient();
+ String url = handleURI(restCall.getURI().toString());
+ HttpMethod httpMethod = createHttpMethod(restCall, url);
+ // add additional request headers
+ handleRequestHeaders(httpMethod, restCall.getRequestHeaders());
+ // handle authentication
+ handleAuthentication(httpClient, httpMethod);
+ Object response = null;
+ // needed because a resource can link to another resource
+ httpClient.getParams().setParameter(HttpClientParams.ALLOW_CIRCULAR_REDIRECTS, new Boolean(true));
+ // execute method
+ try {
+ int responseCode = httpClient.executeMethod(httpMethod);
+ if(responseCode == HttpStatus.SC_OK) {
+ response = ResourceRepresentationFactory.getDefault()
+ .createResourceRepresentation(httpMethod, restCall);
+ if(proxy != null && proxy instanceof IRestResponseProcessor)
+ ((IRestResponseProcessor) proxy).processResource(response);
+ } else
+ throw new ECFException("Service returned status code: " + responseCode);
+ } catch (HttpException e) {
+ throw new ECFException(e);
+ } catch (IOException e) {
+ throw new ECFException(e);
+ } catch (ParseException e) {
+ throw new ECFException(e);
+ }
+ return response;
+ }
+
+ protected void handleRequestHeaders(HttpMethod httpMethod, Map requestHeaders) {
+ if(requestHeaders != null) {
+ Set keySet = requestHeaders.keySet();
+ Object[] headers = keySet.toArray();
+ for(int i = 0; i < headers.length; i++) {
+ String key = (String) headers[i];
+ String value = (String) requestHeaders.get(key);
+ httpMethod.addRequestHeader(key, value);
+ }
+ }
+ }
+
+ protected HttpMethod createHttpMethod(IRestCall restCall, String url) throws ECFException {
+ HttpMethod httpMethod = null;
+ String method = restCall.getMethod();
+ if(method.equals(IRestCall.HTTP_GET)) {
+ httpMethod = new GetMethod(url);
+ addGetParams(httpMethod, restCall.getParameters());
+ } else if(method.equals(IRestCall.HTTP_POST)) {
+ httpMethod = new PostMethod(url);
+ addPostParams(httpMethod, restCall.getParameters(), restCall
+ .getRequestEntity());
+ } else if(method.equals(IRestCall.HTTP_PUT)) {
+ httpMethod = new PutMethod(url);
+ addPutRequestBody(restCall, httpMethod);
+ } else if(method.equals(IRestCall.HTTP_DELETE)) {
+ httpMethod = new DeleteMethod(url);
+ } else {
+ throw new ECFException("HTTP method not supported");
+ }
+ return httpMethod;
+ }
+
+ protected void addPutRequestBody(IRestCall restCall, HttpMethod httpMethod) throws ECFException {
+ PutMethod putMethod = (PutMethod) httpMethod;
+ if(restCall.getParameters()[0] instanceof String) {
+ String body = (String) restCall.getParameters()[0];
+ RequestEntity entity;
+ try {
+ entity = new StringRequestEntity(body, null, null);
+ } catch (UnsupportedEncodingException e) {
+ throw new ECFException(
+ "An error occured while creating the request entity", e);
+ }
+ putMethod.setRequestEntity(entity);
+ } else {
+ throw new ECFException(
+ "For put the first Parameter must be a String");
+ }
+ }
+
+ protected void addPostParams(HttpMethod httpMethod, Object[] restParams, RequestEntity requestEntity) {
+ PostMethod postMethod = (PostMethod) httpMethod;
+ // query parameters exclude a request entity
+ if(restParams != null && restParams.length > 0) {
+ postMethod.addParameters(toNameValuePairs(restParams));
+ } else if(requestEntity != null) {
+ postMethod.setRequestEntity(requestEntity);
+ }
+ }
+
+ protected void addGetParams(HttpMethod httpMethod, Object[] restParams) {
+ if(restParams != null) {
+ httpMethod.setQueryString(toNameValuePairs(restParams));
+ }
+ }
+
+ private NameValuePair[] toNameValuePairs(Object[] restParams) {
+ List nameValueList = new ArrayList(restParams.length);
+ for(int i = 0; i < restParams.length; i++) {
+ if(restParams[i] instanceof String) {
+ String param = (String) restParams[i];
+ int indexOfEquals = param.indexOf('=');
+ String key = param.substring(0, indexOfEquals);
+ String value = param.substring(indexOfEquals + 1, param
+ .length());
+ nameValueList.add(new NameValuePair(key, value));
+ }
+ }
+ return (NameValuePair[]) nameValueList.toArray(new NameValuePair[nameValueList.size()]);
+ }
+
+ protected void handleAuthentication(HttpClient httpClient, HttpMethod method) {
+ if(reference instanceof RestServiceReference) {
+ RestServiceReference ref = (RestServiceReference) reference;
+ RestContainer container = ref.getContainer();
+ IConnectContext connectContext = container.getConnectContext();
+ if(connectContext != null) {
+ NameCallback nameCallback = new NameCallback("");
+ ObjectCallback passwordCallback = new ObjectCallback();
+ Callback[] callbacks = new Callback[] { nameCallback,
+ passwordCallback };
+ CallbackHandler callbackHandler = connectContext
+ .getCallbackHandler();
+ if(callbackHandler == null)
+ return;
+ try {
+ callbackHandler.handle(callbacks);
+ String username = nameCallback.getName();
+ String password = (String) passwordCallback.getObject();
+ AuthScope authscope = new AuthScope(null, -1);
+ Credentials credentials = new UsernamePasswordCredentials(
+ username, password);
+ httpClient.getState()
+ .setCredentials(authscope, credentials);
+ method.setDoAuthentication(true);
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (UnsupportedCallbackException e) {
+ e.printStackTrace();
+ }
+
+ }
+ }
+ }
+
+ private String handleURI(String uri) {
+ if(uri.indexOf("http://") > -1)
+ return uri;
+ ID containerID = reference.getContainerID();
+
+ if(containerID instanceof RestID) {
+ RestID id = (RestID) containerID;
+ URL baseURL = id.getBaseURL();
+ String baseUrlString = baseURL.toExternalForm();
+ int length = baseUrlString.length();
+ char[] lastChar = new char[1];
+ baseUrlString.getChars(length - 1, length, lastChar, 0);
+ char[] firstMethodChar = new char[1];
+ uri.getChars(0, 1, firstMethodChar, 0);
+ if((lastChar[0] == '/' && firstMethodChar[0] != '/')
+ || (lastChar[0] != '/' && firstMethodChar[0] == '/'))
+ return baseUrlString + uri;
+ else if(lastChar[0] == '/' && firstMethodChar[0] == '/') {
+ String tempurl = baseUrlString.substring(0, length - 1);
+ return tempurl + uri;
+ } else if(lastChar[0] != '/' && firstMethodChar[0] != '/')
+ return baseUrlString + "/" + uri;
+ }
+ return null;
+ }
+
+ public Object getProxy() throws ECFException {
+ return proxy;
+ }
+
+ void setReference(IRemoteServiceReference reference) {
+ this.reference = reference;
+ }
+
+ public void fireAsync(IRemoteCall call) throws ECFException {
+ callAsync(call);
+ }
+
+}
diff --git a/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/RestServiceReference.java b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/RestServiceReference.java
new file mode 100644
index 000000000..fa52ceed0
--- /dev/null
+++ b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/RestServiceReference.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+* Copyright (c) 2009 EclipseSource 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:
+* EclipseSource - initial API and implementation
+*******************************************************************************/
+package org.eclipse.ecf.remoteservice.rest;
+
+import org.eclipse.ecf.core.identity.ID;
+import org.eclipse.ecf.remoteservice.IRemoteServiceID;
+import org.eclipse.ecf.remoteservice.IRemoteServiceReference;
+
+/**
+ * Objects of this class represents the reference for a {@link RestService}.
+ */
+public class RestServiceReference implements IRemoteServiceReference {
+
+ private RestServiceRegistration registration;
+
+ public RestServiceReference(RestServiceRegistration restServiceRegistration) {
+ registration = restServiceRegistration;
+ }
+
+ RestContainer getContainer(){
+ return registration.getContainer();
+ }
+
+ public ID getContainerID() {
+ return registration.getContainerID();
+ }
+
+ public IRemoteServiceID getID() {
+ return registration.getID();
+ }
+
+ public Object getProperty(String key) {
+ return registration.getProperty(key);
+ }
+
+ public String[] getPropertyKeys() {
+ return registration.getPropertyKeys();
+ }
+
+ public boolean isActive() {
+ return registration != null;
+ }
+
+}
diff --git a/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/RestServiceRegistration.java b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/RestServiceRegistration.java
new file mode 100644
index 000000000..e99decdef
--- /dev/null
+++ b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/RestServiceRegistration.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+* Copyright (c) 2009 EclipseSource 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:
+* EclipseSource - initial API and implementation
+*******************************************************************************/
+package org.eclipse.ecf.remoteservice.rest;
+
+import java.net.URL;
+import java.util.Dictionary;
+import java.util.Enumeration;
+
+import org.eclipse.ecf.core.identity.ID;
+import org.eclipse.ecf.core.identity.IDFactory;
+import org.eclipse.ecf.core.identity.Namespace;
+import org.eclipse.ecf.internal.remoteservice.rest.RestServiceRegistry;
+import org.eclipse.ecf.remoteservice.IRemoteService;
+import org.eclipse.ecf.remoteservice.IRemoteServiceID;
+import org.eclipse.ecf.remoteservice.IRemoteServiceReference;
+import org.eclipse.ecf.remoteservice.IRemoteServiceRegistration;
+import org.eclipse.ecf.remoteservice.rest.identity.RestID;
+import org.eclipse.ecf.remoteservice.rest.identity.RestNamespace;
+
+/**
+ * This class acts as the registration for {@link RestService}s.
+ */
+public class RestServiceRegistration implements IRemoteServiceRegistration {
+
+ private IRemoteServiceReference reference;
+ private Object service;
+ private String[] clazzes;
+ private Dictionary properties;
+ private ID containerId;
+ private RestServiceRegistry registry;
+ private IRemoteServiceID serviceID;
+
+ public RestServiceRegistration(String[] clazzes, Object service, Dictionary properties, RestServiceRegistry registry) {
+ this.service = service;
+ this.clazzes = clazzes;
+ this.properties = properties;
+ containerId = registry.getContainerId();
+ reference = new RestServiceReference(this);
+ this.registry = registry;
+ registry.registerRegistration(this);
+ }
+
+ public String[] getClazzes() {
+ return clazzes;
+ }
+
+ public ID getContainerID() {
+ return containerId;
+ }
+
+ public IRemoteServiceID getID() {
+ if(serviceID == null){
+ Namespace namespace = IDFactory.getDefault().getNamespaceByName(RestNamespace.NAME);
+ URL baseURL = ((RestID)containerId).getBaseURL();
+ serviceID = (IRemoteServiceID) IDFactory.getDefault().createID(namespace, new Object[] {baseURL, containerId, new Long(registry.getNextServiceId())});
+ }
+ return serviceID;
+ }
+
+ public Object getProperty(String key) {
+ return properties.get(key);
+ }
+
+ public String[] getPropertyKeys() {
+ int length = properties.size();
+ Enumeration keys = properties.keys();
+ String[] result = new String[length];
+ int i = 0;
+ while (keys.hasMoreElements()) {
+ Object element = keys.nextElement();
+ if(element instanceof String){
+ result[i] = (String) element;
+ i++;
+ }
+ }
+ return result;
+ }
+
+ public IRemoteService getService() {
+ return (IRemoteService)service;
+ }
+
+ public IRemoteServiceReference getReference() {
+ return reference;
+ }
+
+ public void setProperties(Dictionary properties) {
+ this.properties = properties;
+ }
+
+ public void unregister() {
+ registry.unregisterRegistration(this);
+ }
+
+ RestContainer getContainer() {
+ return registry.getContainer();
+ }
+
+}
diff --git a/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/identity/RestID.java b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/identity/RestID.java
new file mode 100644
index 000000000..68aa7c564
--- /dev/null
+++ b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/identity/RestID.java
@@ -0,0 +1,96 @@
+/*******************************************************************************
+* Copyright (c) 2009 EclipseSource 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:
+* EclipseSource - initial API and implementation
+*******************************************************************************/
+package org.eclipse.ecf.remoteservice.rest.identity;
+
+import java.net.URL;
+
+import org.eclipse.ecf.core.identity.BaseID;
+import org.eclipse.ecf.core.identity.ID;
+import org.eclipse.ecf.core.identity.Namespace;
+import org.eclipse.ecf.remoteservice.IRemoteServiceID;
+import org.eclipse.ecf.remoteservice.rest.RestContainer;
+
+/**
+ * An ECF ID to instatiate a {@link RestContainer}.
+ */
+public class RestID extends BaseID implements IRemoteServiceID {
+
+ private static final long serialVersionUID = -7725015677223101132L;
+ URL baseUrl;
+ private Long serviceID;
+ private ID containerId;
+
+ /**
+ * Contructor to create a RestID with a {@link Namespace}.
+ *
+ * @param namespace Must be an instance of {@link RestNamespace}.
+ * @param baseURL an URL which will be associated with this ID to call REST services,
+ * i.e. http://twitter.com for Twitter services.
+ */
+ public RestID( Namespace namespace, URL baseURL ) {
+ super(namespace);
+ this.baseUrl = baseURL;
+ }
+
+ /**
+ * @see RestID#RestID(Namespace, URL).
+ *
+ * @param serviceID the service ID to use.
+ */
+ public RestID(RestNamespace restNamespace, URL url, Long serviceID) {
+ this(restNamespace, url);
+ this.serviceID = serviceID;
+ }
+
+ /**
+ * @see RestID#RestID(RestNamespace, URL, Long).
+ *
+ * @param containerId the ID of the associated container.
+ */
+ public RestID(RestNamespace restNamespace, URL url, ID containerId, Long serviceID) {
+ this(restNamespace, url, serviceID);
+ this.containerId = containerId;
+ }
+
+ public int namespaceCompareTo(BaseID o) {
+ return this.baseUrl.toExternalForm().compareTo(((RestID) o).toExternalForm());
+ }
+
+ public boolean namespaceEquals(BaseID o) {
+ return this.baseUrl.equals(((RestID) o).baseUrl);
+ }
+
+ public String namespaceGetName() {
+ return this.baseUrl.toExternalForm();
+ }
+
+ public int namespaceHashCode() {
+ return this.baseUrl.hashCode();
+ }
+
+ public URL getBaseURL() {
+ return baseUrl;
+ }
+
+ public ID getContainerID() {
+ return containerId;
+ }
+
+ public long getContainerRelativeID() {
+ if(serviceID == null)
+ return 0;
+ return serviceID.longValue();
+ }
+
+ public void setBaseUrl(URL baseUrl) {
+ this.baseUrl = baseUrl;
+ }
+
+}
diff --git a/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/identity/RestNamespace.java b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/identity/RestNamespace.java
new file mode 100644
index 000000000..56af8a1ca
--- /dev/null
+++ b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/identity/RestNamespace.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+* Copyright (c) 2009 EclipseSource 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:
+* EclipseSource - initial API and implementation
+*******************************************************************************/
+package org.eclipse.ecf.remoteservice.rest.identity;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.eclipse.ecf.core.identity.ID;
+import org.eclipse.ecf.core.identity.IDCreateException;
+import org.eclipse.ecf.core.identity.Namespace;
+import org.eclipse.ecf.remoteservice.rest.RestContainer;
+
+/**
+ * This class represents a {@link Namespace} for {@link RestContainer}s.
+ */
+public class RestNamespace extends Namespace {
+
+ private static final long serialVersionUID = -398861350452016954L;
+
+ /**
+ * The name of this namespace.
+ */
+ public static final String NAME = "ecf.rest.namespace";
+
+ /**
+ * The scheme of this namespace.
+ */
+ public static final String SCHEME = "rest";
+
+
+ public RestNamespace() {
+ }
+
+ public RestNamespace(String name, String desc) {
+ super(name, desc);
+ }
+
+ /**
+ * Creates an instance of an {@link RestID}. The parameters must contain specific information.
+ *
+ * First it should contain a String which represents the {@link RestID#baseUrl}.
+ * Additional it could contain a ServiceId and/or a ContainerId.
+ *
+ * @param parameters a collection of attributes to call the right constructor on {@link RestID}.
+ * @return an instance of {@link RestID}. Will not be <code>null</code>.
+ */
+ public ID createInstance(Object[] parameters) throws IDCreateException {
+ URL url = null;
+ if(parameters[0] instanceof String) {
+ try {
+ url = new URL((String) parameters[0]);
+ } catch (MalformedURLException e) {
+ throw new IllegalArgumentException(e.getLocalizedMessage());
+ }
+ } else if((parameters[0] instanceof URL)) {
+ url = (URL) parameters[0];
+ } else
+ throw new IllegalArgumentException("the first parameter must be transformable to an URL");
+ if(parameters.length == 2 && parameters[1] instanceof Long)
+ return new RestID(this, url, (Long)parameters[1] );
+ if( parameters.length == 3 && parameters[1] instanceof ID && parameters[2] instanceof Long)
+ return new RestID(this, url, (ID)parameters[1], (Long)parameters[2] );
+ return new RestID(this, url );
+ }
+
+ public String getScheme() {
+ return SCHEME;
+ }
+
+ public Class[][] getSupportedParameterTypes() {
+ return new Class[][] { { URL.class } };
+ }
+
+}
diff --git a/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/resource/IRestResource.java b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/resource/IRestResource.java
new file mode 100644
index 000000000..92068dc70
--- /dev/null
+++ b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/resource/IRestResource.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+* Copyright (c) 2009 EclipseSource 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:
+* EclipseSource - initial API and implementation
+*******************************************************************************/
+package org.eclipse.ecf.remoteservice.rest.resource;
+
+import java.text.ParseException;
+
+/**
+ * This interface can be used to register services for the resource representation creation process.
+ * A sample implementation can be found on {@link XMLResource} for XML.
+ */
+public interface IRestResource {
+
+ /**
+ * Returns the identifier of this resource. This is used to check which resource
+ * should be used to parse a response from a IRestCall. Therefore the result from
+ * {@link IRestCall#getEstimatedIdentifier} will be compared with the result of this method.
+ *
+ * @return the identifier for this resource. Cannot be <code>null</code>
+ */
+ public String getIdentifier();
+
+ /**
+ * Parse a REST response to a given format i.e. XML or JSON. Implementations
+ * can be registered with a normal OSGi service.
+ *
+ * @param responseBody the string representation from the response.
+ * @return the parsed response. Can be <code>null</code>
+ */
+ public Object createRepresentation(String responseBody) throws ParseException;
+
+}
diff --git a/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/resource/XMLResource.java b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/resource/XMLResource.java
new file mode 100644
index 000000000..9d00b9356
--- /dev/null
+++ b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/resource/XMLResource.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+* Copyright (c) 2009 EclipseSource 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:
+* EclipseSource - initial API and implementation
+*******************************************************************************/
+package org.eclipse.ecf.remoteservice.rest.resource;
+
+import java.io.IOException;
+import java.io.StringReader;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.eclipse.ecf.internal.remoteservice.rest.Activator;
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * This class is a sample implementation of {@link IRestResource}. This will be used
+ * to create XML Resource representations and will be registered when the API is
+ * started, {@link Activator#start(org.osgi.framework.BundleContext)}.
+ */
+public class XMLResource implements IRestResource {
+
+ public String getIdentifier() {
+ return "ecf.rest.resource.xml";
+ }
+
+ public Object createRepresentation(String responseBody) throws IllegalArgumentException {
+ DocumentBuilderFactory documentFactory = DocumentBuilderFactory.newInstance();
+ String errorMsg = "Response can't be parsed, reason: ";
+ try {
+ DocumentBuilder builder = documentFactory.newDocumentBuilder();
+ InputSource src = new InputSource(new StringReader(responseBody));
+ Document dom = builder.parse(src);
+ return dom;
+ } catch (ParserConfigurationException e) {
+ throw new IllegalArgumentException(errorMsg + e.getMessage());
+ } catch (SAXException e) {
+ throw new IllegalArgumentException(errorMsg + e.getMessage());
+ } catch (IOException e) {
+ throw new IllegalArgumentException(errorMsg + e.getMessage());
+ }
+
+
+
+ }
+
+}
diff --git a/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/util/DeleteRestCall.java b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/util/DeleteRestCall.java
new file mode 100644
index 000000000..bb2785f13
--- /dev/null
+++ b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/util/DeleteRestCall.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2009 EclipseSource 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:
+ * EclipseSource - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ecf.remoteservice.rest.util;
+
+import java.net.URI;
+import java.util.Map;
+
+import org.apache.commons.httpclient.methods.RequestEntity;
+import org.eclipse.ecf.remoteservice.rest.IRestCall;
+
+/**
+ * Implementation for http DELETE.
+ */
+public class DeleteRestCall extends RestCall {
+
+ public DeleteRestCall(URI uri, String resourceIdentifier, Object[] params, Map requestHeaders, long timeout) {
+ this(uri, resourceIdentifier, params, null, requestHeaders, timeout);
+ }
+
+ public DeleteRestCall(URI uri, String resourceIdentifier, RequestEntity requestEntity, Map requestHeaders,
+ long timeout) {
+ this(uri, resourceIdentifier, null, requestEntity, requestHeaders, timeout);
+ }
+
+ protected DeleteRestCall(URI uri, String resourceIdentifier, Object[] params, RequestEntity requestEntity,
+ Map requestHeaders, long timeout) {
+ super(uri, resourceIdentifier, params, requestEntity, requestHeaders, timeout);
+ }
+
+ public DeleteRestCall(URI uri, String resourceIdentifier, Map requestHeaders, long timeout) {
+ this(uri, resourceIdentifier, null, null, requestHeaders, timeout);
+ }
+
+ public String getMethod() {
+ return IRestCall.HTTP_DELETE;
+ }
+}
diff --git a/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/util/GetRestCall.java b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/util/GetRestCall.java
new file mode 100644
index 000000000..521f84b9c
--- /dev/null
+++ b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/util/GetRestCall.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2009 EclipseSource 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:
+ * EclipseSource - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ecf.remoteservice.rest.util;
+
+import java.net.URI;
+import java.util.Map;
+
+import org.apache.commons.httpclient.methods.RequestEntity;
+import org.eclipse.ecf.remoteservice.rest.IRestCall;
+
+/**
+ * Implementation for http GET.
+ */
+public class GetRestCall extends RestCall {
+
+ public GetRestCall(URI uri, String resourceIdentifier, Object[] params, Map requestHeaders, long timeout) {
+ this(uri, resourceIdentifier, params, null, requestHeaders, timeout);
+ }
+
+ public GetRestCall(URI uri, String resourceIdentifier, RequestEntity requestEntity, Map requestHeaders, long timeout) {
+ this(uri, resourceIdentifier, null, requestEntity, requestHeaders, timeout);
+ }
+
+ protected GetRestCall(URI uri, String resourceIdentifier, Object[] params, RequestEntity requestEntity,
+ Map requestHeaders, long timeout) {
+ super(uri, resourceIdentifier, params, requestEntity, requestHeaders, timeout);
+ }
+
+ public GetRestCall(URI uri, String resourceIdentifier, Map requestHeaders,
+ long timeout) {
+ this(uri, resourceIdentifier, null, null, requestHeaders, timeout);
+ }
+
+
+ public String getMethod() {
+ return IRestCall.HTTP_GET;
+ }
+
+ public RequestEntity getRequestEntity() {
+ // GET calls may not have request entities
+ return null;
+ }
+}
diff --git a/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/util/PostRestCall.java b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/util/PostRestCall.java
new file mode 100644
index 000000000..809b0e8f6
--- /dev/null
+++ b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/util/PostRestCall.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2009 EclipseSource 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:
+ * EclipseSource - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ecf.remoteservice.rest.util;
+
+import java.net.URI;
+import java.util.Map;
+
+import org.apache.commons.httpclient.methods.RequestEntity;
+import org.eclipse.ecf.remoteservice.rest.IRestCall;
+
+/**
+ * Implementation for http POST.
+ */
+public class PostRestCall extends RestCall {
+
+ protected PostRestCall(URI uri, String resourceIdentifier, Object[] params, RequestEntity requestEntity,
+ Map requestHeaders, long timeout) {
+ super(uri, resourceIdentifier, params, requestEntity, requestHeaders, timeout);
+ }
+
+ public PostRestCall(URI uri, String resourceIdentifier, Object[] params, Map requestHeaders, long timeout) {
+ super(uri, resourceIdentifier, params, null, requestHeaders, timeout);
+ }
+
+ public PostRestCall(URI uri, String resourceIdentifier, RequestEntity requestEntity, Map requestHeaders,
+ long timeout) {
+ super(uri, resourceIdentifier, null, requestEntity, requestHeaders, timeout);
+ }
+
+ public PostRestCall(URI uri, String resourceIdentifier, Map requestHeaders,
+ long timeout) {
+ this(uri, resourceIdentifier, null, null, requestHeaders, timeout);
+ }
+
+ public String getMethod() {
+ return IRestCall.HTTP_POST;
+ }
+
+}
diff --git a/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/util/PutRestCall.java b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/util/PutRestCall.java
new file mode 100644
index 000000000..4d23941fb
--- /dev/null
+++ b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/util/PutRestCall.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2009 EclipseSource 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:
+ * EclipseSource - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ecf.remoteservice.rest.util;
+
+import java.net.URI;
+import java.util.Map;
+
+import org.apache.commons.httpclient.methods.RequestEntity;
+import org.eclipse.ecf.remoteservice.rest.IRestCall;
+
+/**
+ * Implementation for http PUT.
+ */
+public class PutRestCall extends RestCall {
+
+ public PutRestCall(URI uri, String resourceIdentifier, Object[] params, RequestEntity requestEntity,
+ Map requestHeaders, long timeout) {
+ super(uri, resourceIdentifier, params, requestEntity, requestHeaders, timeout);
+ }
+
+ public PutRestCall(URI uri, String resourceIdentifier, Map requestHeaders, Object[] params, long timeout) {
+ this(uri, resourceIdentifier, params, null, requestHeaders, timeout);
+ }
+
+ public PutRestCall(URI uri, String resourceIdentifier, RequestEntity requestEntity, Map requestHeaders, long timeout) {
+ this(uri, resourceIdentifier, null, requestEntity, requestHeaders, timeout);
+ }
+
+ public PutRestCall(URI uri, String resourceIdentifier, Map requestHeaders, long timeout) {
+ this(uri, resourceIdentifier, null, null, requestHeaders, timeout);
+ }
+
+ public String getMethod() {
+ return IRestCall.HTTP_PUT;
+ }
+}
diff --git a/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/util/RestCall.java b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/util/RestCall.java
new file mode 100644
index 000000000..ee60b7d2a
--- /dev/null
+++ b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/util/RestCall.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2009 EclipseSource 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:
+ * EclipseSource - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ecf.remoteservice.rest.util;
+
+import java.net.URI;
+import java.util.Map;
+
+import org.apache.commons.httpclient.methods.RequestEntity;
+import org.eclipse.ecf.remoteservice.rest.IRestCall;
+
+/**
+ * This class acts as the super class for the service object {@link GetRestCall},
+ * {@link PostRestCall}, {@link DeleteRestCall} and {@link PutRestCall}. Sub classes
+ * may override the methods from {@link IRestCall}.
+ */
+public class RestCall implements IRestCall {
+
+ private long timeout;
+ private Map requestHeaders;
+ private Object[] params;
+ private RequestEntity requestEntity;
+ private String resourceIdentifier;
+ private URI uri;
+ private String method;
+
+
+ protected RestCall(URI uri, String resourceIdentifier, Object[] params, RequestEntity requestEntity, Map requestHeaders, long timeout) {
+ this.uri = uri;
+ this.resourceIdentifier = resourceIdentifier;
+ this.params = params;
+ this.requestEntity = requestEntity;
+ this.requestHeaders = requestHeaders;
+ this.timeout = timeout;
+ }
+
+ protected RestCall(String method, URI uri, String resourceIdentifier, Object[] params, RequestEntity requestEntity, Map requestHeaders, long timeout) {
+ this(uri, resourceIdentifier, params, requestEntity, requestHeaders, timeout);
+ this.method = method;
+ }
+
+ public String getEstimatedResourceIdentifier() {
+ return resourceIdentifier;
+ }
+
+ public String getMethod() {
+ return method;
+ }
+
+ public Object[] getParameters() {
+ return params;
+ }
+
+ public Map getRequestHeaders() {
+ return requestHeaders;
+ }
+
+ public long getTimeout() {
+ return timeout;
+ }
+
+ public URI getURI() {
+ return uri;
+ }
+
+ public RequestEntity getRequestEntity() {
+ return requestEntity;
+ }
+
+
+}
diff --git a/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/util/RestCallFactory.java b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/util/RestCallFactory.java
new file mode 100644
index 000000000..8ef188660
--- /dev/null
+++ b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/util/RestCallFactory.java
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * Copyright (c) 2009 EclipseSource 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:
+ * EclipseSource - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ecf.remoteservice.rest.util;
+
+import java.net.URI;
+import java.util.Map;
+
+import org.apache.commons.httpclient.methods.RequestEntity;
+import org.eclipse.ecf.remoteservice.rest.IRestCall;
+
+/**
+ * Factory to support the creation of {@link IRestCall} objects.
+ */
+public class RestCallFactory {
+
+ /**
+ * Creates a specific {@link IRestCall}.
+ *
+ * @param method
+ * The type of the http method. GET, PUT, DELETE or POST.
+ * @param uri
+ * {@link IRestCall#getURI()}
+ * @param resourceIdentifier
+ * {@link IRestCall#getEstimatedResourceIdentifier()}
+ * @param params
+ * {@link IRestCall#getParameters()}
+ * @param requestHeaders
+ * {@link IRestCall#getRequestHeaders()}
+ * @param timeout
+ * {@link IRestCall#getTimeout()}
+ *
+ * @return {@link IRestCall} object filled with the overgiven params. Will
+ * not be <code>null</code>.
+ */
+ public static IRestCall createRestCall(final String method, final URI uri, final String resourceIdentifier,
+ final Object[] params, final Map requestHeaders, final long timeout) {
+
+ return createRestCall(method, uri, resourceIdentifier, params, null, requestHeaders, timeout);
+ }
+
+ /**
+ * Creates a specific {@link IRestCall}.
+ *
+ * @param method
+ * The type of the http method. GET, PUT, DELETE or POST.
+ * @param uri
+ * {@link IRestCall#getURI()}
+ * @param resourceIdentifier
+ * {@link IRestCall#getEstimatedResourceIdentifier()}
+ * @param requestEntity
+ * {@link IRestCall#getRequestEntity()}
+ * @param requestHeaders
+ * {@link IRestCall#getRequestHeaders()}
+ * @param timeout
+ * {@link IRestCall#getTimeout()}
+ *
+ * @return {@link IRestCall} object filled with the overgiven params. Will
+ * not be <code>null</code>.
+ */
+ public static IRestCall createRestCall(final String method, final URI uri, final String resourceIdentifier,
+ final RequestEntity requestEntity, final Map requestHeaders, final long timeout) {
+ return createRestCall(method, uri, resourceIdentifier, null, requestEntity, requestHeaders, timeout);
+ }
+
+ /**
+ * Creates a specific {@link IRestCall}.
+ *
+ * @param method
+ * The type of the http method. GET, PUT, DELETE or POST.
+ * @param uri
+ * {@link IRestCall#getURI()}
+ * @param resourceIdentifier
+ * {@link IRestCall#getEstimatedResourceIdentifier()}
+ * @param requestHeaders
+ * {@link IRestCall#getRequestHeaders()}
+ * @param timeout
+ * {@link IRestCall#getTimeout()}
+ *
+ * @return {@link IRestCall} object filled with the overgiven params. Will
+ * not be <code>null</code>.
+ */
+ public static IRestCall createRestCall(final String method, final URI uri, final String resourceIdentifier,
+ final Map requestHeaders, final long timeout) {
+ return createRestCall(method, uri, resourceIdentifier, null, null, requestHeaders, timeout);
+ }
+
+ private static IRestCall createRestCall(final String method, final URI uri, final String resourceIdentifier,
+ final Object[] params, final RequestEntity requestEntity, final Map requestHeaders, final long timeout) {
+
+ if (method.equals(IRestCall.HTTP_GET))
+ return new GetRestCall(uri, resourceIdentifier, params, requestEntity, requestHeaders, timeout);
+ if (method.equals(IRestCall.HTTP_POST))
+ return new PostRestCall(uri, resourceIdentifier, params, requestEntity, requestHeaders, timeout);
+ if (method.equals(IRestCall.HTTP_DELETE))
+ return new DeleteRestCall(uri, resourceIdentifier, params, requestEntity, requestHeaders, timeout);
+ if (method.equals(IRestCall.HTTP_PUT))
+ return new PutRestCall(uri, resourceIdentifier, params, requestEntity, requestHeaders, timeout);
+ return new RestCall(method, uri, resourceIdentifier, params, requestEntity, requestHeaders, timeout);
+ }
+}
diff --git a/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/util/RestRemoteCall.java b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/util/RestRemoteCall.java
new file mode 100644
index 000000000..125dd58f8
--- /dev/null
+++ b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/util/RestRemoteCall.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+* Copyright (c) 2009 EclipseSource 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:
+* EclipseSource - initial API and implementation
+*******************************************************************************/
+package org.eclipse.ecf.remoteservice.rest.util;
+
+import org.eclipse.ecf.remoteservice.IRemoteCall;
+import org.eclipse.ecf.remoteservice.rest.IRestCall;
+
+/**
+ * Service class for creating a {@link IRemoteCall}. This will be used to associate
+ * an {@link IRemoteCall} with an {@link IRestCall}. Therefore the {@link #getMethod()}
+ * method will used as key.
+ */
+public class RestRemoteCall implements IRemoteCall {
+
+ private String key;
+
+ public RestRemoteCall(String key) {
+ this.key = key;
+ }
+
+ public String getMethod() {
+ return key;
+ }
+
+ public Object[] getParameters() {
+ return null;
+ }
+
+ public long getTimeout() {
+ return 0;
+ }
+}

Back to the top