diff options
author | hstaudacher | 2009-10-06 08:21:08 +0000 |
---|---|---|
committer | hstaudacher | 2009-10-06 08:21:08 +0000 |
commit | c830b5d2c96b636437c1a423439aed42b2759b6c (patch) | |
tree | c5e338f3cdb0c920d4ca25ef88366f192723218e /framework | |
parent | 2cda6ecd0c39dc5d6170012e6b722e5e03c79a9c (diff) | |
download | org.eclipse.ecf-c830b5d2c96b636437c1a423439aed42b2759b6c.tar.gz org.eclipse.ecf-c830b5d2c96b636437c1a423439aed42b2759b6c.tar.xz org.eclipse.ecf-c830b5d2c96b636437c1a423439aed42b2759b6c.zip |
RESOLVED - bug 275722: [rest] REST abstraction for ECF
https://bugs.eclipse.org/bugs/show_bug.cgi?id=275722
Diffstat (limited to 'framework')
11 files changed, 322 insertions, 77 deletions
diff --git a/framework/bundles/org.eclipse.ecf.remoteservice.rest/.project b/framework/bundles/org.eclipse.ecf.remoteservice.rest/.project index 461918136..f6106ebfa 100644 --- a/framework/bundles/org.eclipse.ecf.remoteservice.rest/.project +++ b/framework/bundles/org.eclipse.ecf.remoteservice.rest/.project @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <projectDescription> - <name>org.eclipse.ecf.internal.remoteservice.rest</name> + <name>org.eclipse.ecf.remoteservice.rest</name> <comment></comment> <projects> </projects> @@ -20,6 +20,11 @@ <arguments> </arguments> </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ds.core.builder</name> + <arguments> + </arguments> + </buildCommand> </buildSpec> <natures> <nature>org.eclipse.pde.PluginNature</nature> 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 index c280292d8..cdd3cf4a1 100644 --- a/framework/bundles/org.eclipse.ecf.remoteservice.rest/META-INF/MANIFEST.MF +++ b/framework/bundles/org.eclipse.ecf.remoteservice.rest/META-INF/MANIFEST.MF @@ -26,4 +26,7 @@ Import-Package: org.apache.commons.httpclient;version="3.0.1", 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" +Require-Bundle: org.eclipse.ecf;bundle-version="3.0.0", + org.eclipse.equinox.ds;bundle-version="[1.1.0,2.0.0)";resolution:=optional, + org.eclipse.osgi.services;bundle-version="3.2.0" +Service-Component: META-INF/dspresent.xml diff --git a/framework/bundles/org.eclipse.ecf.remoteservice.rest/META-INF/dspresent.xml b/framework/bundles/org.eclipse.ecf.remoteservice.rest/META-INF/dspresent.xml new file mode 100644 index 000000000..d33bb0266 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf.remoteservice.rest/META-INF/dspresent.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.ecf.remoteservice.rest"> + <implementation class="org.eclipse.ecf.remoteservice.rest.util.DSPresent"/> + <service> + <provide interface="org.eclipse.ecf.remoteservice.rest.util.IDSPresent"/> + </service> +</scr:component> diff --git a/framework/bundles/org.eclipse.ecf.remoteservice.rest/build.properties b/framework/bundles/org.eclipse.ecf.remoteservice.rest/build.properties index 2dcc4bdc6..68dc42252 100644 --- a/framework/bundles/org.eclipse.ecf.remoteservice.rest/build.properties +++ b/framework/bundles/org.eclipse.ecf.remoteservice.rest/build.properties @@ -1,6 +1,7 @@ -source.. = src/ output.. = bin/ bin.includes = META-INF/,\ .,\ plugin.xml,\ - bin/ + bin/,\ + META-INF/dspresent.xml +source.. = src/ 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 index c63626ea5..b151ca928 100644 --- 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 @@ -1,18 +1,20 @@ /******************************************************************************* -* 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 -*******************************************************************************/ + * 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.IRestResourceRepresentationFactory; 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; +import org.osgi.framework.ServiceRegistration; /** * The activator class controls the plug-in life cycle @@ -26,43 +28,64 @@ public class Activator implements BundleActivator { private static Activator plugin; private BundleContext context; - + + private ServiceRegistration factoryRegistration; + + private ServiceRegistration resourceRegistration; /* * (non-Javadoc) - * @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext) + * + * @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 ); + this.factoryRegistration = registerResourceRepresentationFactory(context); + this.resourceRegistration = registerXMLService(context); + } + + private ServiceRegistration registerResourceRepresentationFactory(BundleContext context) { + IRestResourceRepresentationFactory factory = new ResourceRepresentationFactory(); + return context.registerService(IRestResourceRepresentationFactory.class.getName(), factory, null); } - private void registerXMLService(BundleContext context) { + private ServiceRegistration registerXMLService(BundleContext context) { IRestResource xmlResource = new XMLResource(); - context.registerService(IRestResource.class.getName(), xmlResource, null); + return context.registerService(IRestResource.class.getName(), xmlResource, null); } /* * (non-Javadoc) - * @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext) + * + * @see + * org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext) */ public void stop(BundleContext context) throws Exception { plugin = null; + unregister(factoryRegistration); + unregister(resourceRegistration); + } + + private void unregister(ServiceRegistration registration) { + if (registration != null) { + registration.unregister(); + } } /** * Returns the shared instance - * + * * @return the shared instance */ public static synchronized Activator getDefault() { - if(plugin == null) { - plugin = new Activator(); + 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 index b193cbf36..6f559ed91 100644 --- 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 @@ -1,12 +1,14 @@ /******************************************************************************* -* 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 -*******************************************************************************/ + * 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 + * Andre Dietisheim - support declaratively registered resource representations + *******************************************************************************/ package org.eclipse.ecf.internal.remoteservice.rest; import java.io.IOException; @@ -17,6 +19,7 @@ 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.IRestResourceRepresentationFactory; import org.eclipse.ecf.remoteservice.rest.resource.IRestResource; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleEvent; @@ -25,89 +28,168 @@ 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; +/** + * A factory for creating ResourceRepresentation objects. + */ +public class ResourceRepresentationFactory implements IRestResourceRepresentationFactory, IAdaptable { + + /** The resources. */ private List resources = new ArrayList(); - + + /** + * The Class RestResourceTracker. + */ private class RestResourceTracker extends ServiceTracker { + /** + * Instantiates a new rest resource tracker. + * + * @param context + * the context + */ public RestResourceTracker(BundleContext context) { - super(context, IRestResource.class.getName(), null); + super(context, IRestResource.class.getName(), null); } - + + /* + * (non-Javadoc) + * + * @see + * org.osgi.util.tracker.ServiceTracker#addingService(org.osgi.framework + * .ServiceReference) + */ public Object addingService(ServiceReference reference) { Object service = context.getService(reference); - if(service != null && service instanceof IRestResource) { - if(!resources.contains(service)) - resources.add(service); + if (service instanceof IRestResource) { + addResourceRepresentation((IRestResource) service); } return service; } - + + /* + * (non-Javadoc) + * + * @see + * org.osgi.util.tracker.ServiceTracker#removedService(org.osgi.framework + * .ServiceReference, java.lang.Object) + */ public void removedService(ServiceReference reference, Object service) { - resources.remove(service); - context.ungetService(reference); + if (service instanceof IRestResource) { + removeResourceRepresentation((IRestResource) service); + context.ungetService(reference); + } } - - } - - private ResourceRepresentationFactory() { - } - public static ResourceRepresentationFactory getDefault() { - if(factory == null) { - factory = new ResourceRepresentationFactory(); - factory.init(); - } - return factory; + /** + * Instantiates a new resource representation factory. + */ + public ResourceRepresentationFactory() { + init(); } + /** + * Inits the. + */ 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); - } + addResourceRepresentations(context); } catch (InvalidSyntaxException e) { - e.printStackTrace(); + // ignore } + initServiceTracker(activator, context); + } + + /** + * Inits the service tracker. + * + * @param activator + * the activator + * @param context + * the context + */ + private void initServiceTracker(Activator activator, BundleContext context) { final ServiceTracker resourceTracker = new RestResourceTracker(context); resourceTracker.open(); + activator.getContext().addBundleListener(new BundleListener() { - + public void bundleChanged(BundleEvent event) { - if(event.getType() == BundleEvent.STOPPING) + 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. + * Adds the resource representations. + * + * @param context + * the context + * + * @throws InvalidSyntaxException + * the invalid syntax exception */ - public Object createResourceRepresentation(HttpMethod method, IRestCall restCall) throws ParseException, IOException { + private void addResourceRepresentations(BundleContext context) throws InvalidSyntaxException { + ServiceReference[] references = context.getServiceReferences(IRestResource.class.getName(), null); + if (references != null) { + for (int i = 0; i < references.length; i++) { + Object service = context.getService(references[i]); + if (service instanceof IRestResource) + addResourceRepresentation((IRestResource) service); + } + } + } + + /** + * 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())) + IRestResource resource = (IRestResource) resources.get(i); + if (resource.getIdentifier().equals(restCall.getEstimatedResourceIdentifier())) return resource.createRepresentation(method.getResponseBodyAsString()); } return null; } + /** + * Adds the resource representation. + * + * @param restResource + * the rest resource + */ + private void addResourceRepresentation(IRestResource restResource) { + synchronized (resources) { + if (!resources.contains(restResource)) { + this.resources.add(restResource); + } + } + } + + /** + * Removes the resource representation. + * + * @param restResource + * the rest resource + */ + private void removeResourceRepresentation(IRestResource restResource) { + synchronized (resources) { + this.resources.remove(restResource); + } + } + 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/remoteservice/rest/IRestResourceRepresentationFactory.java b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/IRestResourceRepresentationFactory.java new file mode 100644 index 000000000..5883529ff --- /dev/null +++ b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/IRestResourceRepresentationFactory.java @@ -0,0 +1,21 @@ +package org.eclipse.ecf.remoteservice.rest; + +import java.io.IOException; +import java.text.ParseException; + +import org.apache.commons.httpclient.HttpMethod; +import org.eclipse.ecf.remoteservice.rest.resource.IRestResource; + +public interface IRestResourceRepresentationFactory { + + /** + * 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 abstract Object createResourceRepresentation(HttpMethod method, IRestCall restCall) throws ParseException, + IOException; +}
\ No newline at end of file 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 index 8428ae155..aac56da43 100644 --- 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 @@ -42,7 +42,7 @@ 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.internal.remoteservice.rest.Activator; import org.eclipse.ecf.remoteservice.IRemoteCall; import org.eclipse.ecf.remoteservice.IRemoteCallListener; import org.eclipse.ecf.remoteservice.IRemoteService; @@ -54,6 +54,8 @@ 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; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceReference; /** * This class represents a REST service from the client side of view. So a RESTful @@ -236,9 +238,8 @@ public class RestService implements IRemoteService { try { int responseCode = httpClient.executeMethod(httpMethod); if(responseCode == HttpStatus.SC_OK) { - response = ResourceRepresentationFactory.getDefault() - .createResourceRepresentation(httpMethod, restCall); - if(proxy != null && proxy instanceof IRestResponseProcessor) + response = getResourceRepresentation(restCall, httpMethod); + if (proxy != null && proxy instanceof IRestResponseProcessor) ((IRestResponseProcessor) proxy).processResource(response); } else throw new ECFException("Service returned status code: " + responseCode); @@ -251,8 +252,46 @@ public class RestService implements IRemoteService { } return response; } - - protected void handleRequestHeaders(HttpMethod httpMethod, Map requestHeaders) { + + /** + * Gets the resource representation for a given rest call and http method. + * The resource representation is queried from the + * IRestResourceRepresentationFactory service + * + * @param restCall + * the rest call + * @param httpMethod + * the http method + * @param response + * the response + * + * @return the resource representation + * + * @throws ParseException + * the parse exception + * @throws IOException + * Signals that an I/O exception has occurred. + * + * @see IRestCall#getEstimatedResourceIdentifier() + * @see IRestCall#getMethod() + * @see IRestResourceRepresentationFactory + */ + private Object getResourceRepresentation(final IRestCall restCall, HttpMethod httpMethod) throws ParseException, + IOException { + Object response = null; + BundleContext context = Activator.getDefault().getContext(); + ServiceReference serviceReference = context.getServiceReference(IRestResourceRepresentationFactory.class + .getName()); + if (serviceReference != null) { + IRestResourceRepresentationFactory factory = (IRestResourceRepresentationFactory) context + .getService(serviceReference); + response = factory.createResourceRepresentation(httpMethod, restCall); + } + return response; + } + + protected void handleRequestHeaders(HttpMethod httpMethod, + Map requestHeaders) { if(requestHeaders != null) { Set keySet = requestHeaders.keySet(); Object[] headers = keySet.toArray(); diff --git a/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/util/DSPresent.java b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/util/DSPresent.java new file mode 100644 index 000000000..fc4e149cb --- /dev/null +++ b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/util/DSPresent.java @@ -0,0 +1,16 @@ +package org.eclipse.ecf.remoteservice.rest.util; + +/** + * The Class DSPresent. + */ +public class DSPresent implements IDSPresent { + + /* (non-Javadoc) + * @see org.eclipse.ecf.remoteservice.rest.util.IDSPresent#isPresent() + */ + public boolean isPresent() { + // if registered, it is present! + return true; + } + +} diff --git a/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/util/DSUtil.java b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/util/DSUtil.java new file mode 100644 index 000000000..9ca709ba6 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/util/DSUtil.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * 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: + * Andre Dietisheim - initial API and implementation + *******************************************************************************/ +package org.eclipse.ecf.remoteservice.rest.util; + +import org.osgi.framework.BundleContext; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceReference; + +public class DSUtil { + /** + * Checks whether the declarative services daemon is running. + * + * @param context + * the context + * + * @return <tt>true</tt>, if is declarative services are running + */ + public static boolean isRunning(BundleContext context) { + ServiceReference[] serviceReferences = null; + try { + serviceReferences = context.getServiceReferences(IDSPresent.class.getName(), null); + } catch (InvalidSyntaxException e) { + // ignore + } + return serviceReferences != null && serviceReferences.length > 0; + } + +} diff --git a/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/util/IDSPresent.java b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/util/IDSPresent.java new file mode 100644 index 000000000..83c152c12 --- /dev/null +++ b/framework/bundles/org.eclipse.ecf.remoteservice.rest/src/org/eclipse/ecf/remoteservice/rest/util/IDSPresent.java @@ -0,0 +1,13 @@ +package org.eclipse.ecf.remoteservice.rest.util; + +public interface IDSPresent { + + /** + * Checks whether declarative service is present. This service is configured + * by declarative services, so if it's registered to the OSGI runtime, DS is + * present + * + * @return true, if is present + */ + public boolean isPresent(); +}
\ No newline at end of file |