You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by cs...@apache.org on 2017/02/24 16:41:59 UTC

[12/12] aries-jax-rs-whiteboard git commit: Source formatting and reorganization

Source formatting and reorganization


Project: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/repo
Commit: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/commit/576f7e39
Tree: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/tree/576f7e39
Diff: http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/diff/576f7e39

Branch: refs/heads/master
Commit: 576f7e39547e3ff0e45187beeee4a150938e3c67
Parents: 5b7b1eb
Author: Carlos Sierra <cs...@apache.org>
Authored: Fri Feb 24 17:40:21 2017 +0100
Committer: Carlos Sierra <cs...@apache.org>
Committed: Fri Feb 24 17:40:21 2017 +0100

----------------------------------------------------------------------
 .../activator/CXFJaxRsBundleActivator.java      | 297 +++++--------------
 .../internal/CXFJaxRsServiceRegistrator.java    |  61 ++--
 .../aries/jax/rs/whiteboard/internal/Utils.java | 187 ++++++++++++
 3 files changed, 287 insertions(+), 258 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/blob/576f7e39/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/activator/CXFJaxRsBundleActivator.java
----------------------------------------------------------------------
diff --git a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/activator/CXFJaxRsBundleActivator.java b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/activator/CXFJaxRsBundleActivator.java
index d369b47..ab06853 100644
--- a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/activator/CXFJaxRsBundleActivator.java
+++ b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/activator/CXFJaxRsBundleActivator.java
@@ -19,23 +19,18 @@ package org.apache.aries.jax.rs.whiteboard.activator;
 
 import javax.servlet.Servlet;
 import javax.ws.rs.core.Application;
-import javax.ws.rs.ext.Provider;
 import javax.ws.rs.ext.RuntimeDelegate;
 
 import org.apache.aries.jax.rs.whiteboard.internal.CXFJaxRsServiceRegistrator;
-import org.apache.aries.jax.rs.whiteboard.internal.CXFJaxRsServiceRegistrator.ServiceInformation;
 import org.apache.aries.osgi.functional.OSGi;
 import org.apache.aries.osgi.functional.OSGiResult;
 import org.apache.cxf.Bus;
 import org.apache.cxf.BusFactory;
 import org.apache.cxf.bus.CXFBusFactory;
-import org.apache.cxf.jaxrs.lifecycle.ResourceProvider;
-import org.apache.cxf.message.Message;
 import org.apache.cxf.transport.servlet.CXFNonSpringServlet;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceObjects;
 import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
 import org.osgi.framework.wiring.BundleWiring;
@@ -43,14 +38,11 @@ import org.osgi.framework.wiring.BundleWiring;
 import java.util.Dictionary;
 import java.util.HashMap;
 import java.util.Hashtable;
-import java.util.Map;
 
 import static java.lang.String.format;
 import static org.apache.aries.jax.rs.whiteboard.AriesJaxRSWhiteboardConstants.*;
-import static org.apache.aries.osgi.functional.OSGi.bundleContext;
+import static org.apache.aries.jax.rs.whiteboard.internal.Utils.*;
 import static org.apache.aries.osgi.functional.OSGi.just;
-import static org.apache.aries.osgi.functional.OSGi.onClose;
-import static org.apache.aries.osgi.functional.OSGi.register;
 import static org.apache.aries.osgi.functional.OSGi.serviceReferences;
 import static org.apache.aries.osgi.functional.OSGi.services;
 import static org.osgi.service.jaxrs.whiteboard.JaxRSWhiteboardConstants.*;
@@ -61,41 +53,12 @@ import static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.HTTP_WHIT
 
 public class CXFJaxRsBundleActivator implements BundleActivator {
 
-    private BundleContext _bundleContext;
     private OSGiResult<?> _applicationsResult;
-    private OSGiResult<?> _singletonsResult;
-    private OSGiResult<?> _extensionsResult;
     private OSGiResult<?> _applicationSingletonsResult;
-
-    private static <T> OSGi<T> service(ServiceReference<T> serviceReference) {
-        return
-            bundleContext().flatMap(bundleContext ->
-            onClose(() -> bundleContext.ungetService(serviceReference)).then(
-            just(bundleContext.getService(serviceReference))
-        ));
-    }
-
-    private static <T> OSGi<ServiceObjects<T>> serviceObjects(
-        ServiceReference<T> serviceReference) {
-
-        return
-            bundleContext().flatMap(bundleContext ->
-            just(bundleContext.getServiceObjects(serviceReference))
-        );
-    }
-
-    private static OSGi<CXFJaxRsServiceRegistrator> cxfRegistrator(
-        Bus bus, Application application, Map<String, Object> props) {
-
-        CXFJaxRsServiceRegistrator registrator =
-            new CXFJaxRsServiceRegistrator(bus, application, props);
-
-        return
-            onClose(registrator::close).then(
-            register(CXFJaxRsServiceRegistrator.class, registrator, props).then(
-            just(registrator)
-        ));
-    }
+    private BundleContext _bundleContext;
+    private Bus _bus;
+    private OSGiResult<?> _extensionsResult;
+    private OSGiResult<?> _singletonsResult;
 
     @Override
     public void start(BundleContext bundleContext) throws Exception {
@@ -103,9 +66,9 @@ public class CXFJaxRsBundleActivator implements BundleActivator {
         initRuntimeDelegate(bundleContext);
 
         // TODO make the context path of the JAX-RS Whiteboard configurable.
-        Bus bus = BusFactory.newInstance(
+        _bus = BusFactory.newInstance(
             CXFBusFactory.class.getName()).createBus();
-        registerCXFServletService(bus);
+        registerCXFServletService(_bus);
 
         OSGi<?> applications =
             serviceReferences(Application.class, getApplicationFilter()).
@@ -115,16 +78,37 @@ public class CXFJaxRsBundleActivator implements BundleActivator {
                     ref, JAX_RS_APPLICATION_BASE)).
                 flatMap(properties ->
             service(ref).flatMap(application ->
-            cxfRegistrator(bus, application, properties)
+            cxfRegistrator(_bus, application, properties)
         )));
 
         _applicationsResult = applications.run(bundleContext);
 
+        OSGi<?> applicationSingletons =
+            serviceReferences(format("(%s=*)", JAX_RS_APPLICATION_SELECT)).
+                flatMap(ref ->
+            just(ref.getProperty(JAX_RS_APPLICATION_SELECT).toString()).
+                flatMap(applicationFilter ->
+            services(CXFJaxRsServiceRegistrator.class, applicationFilter).
+                flatMap(registrator ->
+            safeRegisterGeneric(ref, registrator)
+        )));
+
+        _applicationSingletonsResult = applicationSingletons.run(bundleContext);
+
         Application defaultApplication = new Application() {};
 
         CXFJaxRsServiceRegistrator defaultServiceRegistrator =
             new CXFJaxRsServiceRegistrator(
-                bus, defaultApplication, new HashMap<>());
+                _bus, defaultApplication, new HashMap<>());
+
+        OSGi<?> extensions =
+            serviceReferences(getExtensionFilter()).flatMap(ref ->
+                waitForExtensionDependencies(ref,
+                    safeRegisterExtension(ref, defaultServiceRegistrator)
+                )
+            );
+
+        _extensionsResult = extensions.run(bundleContext);
 
         OSGi<?> singletons =
             serviceReferences(getSingletonsFilter()).
@@ -141,80 +125,21 @@ public class CXFJaxRsBundleActivator implements BundleActivator {
         );
 
         _singletonsResult = singletons.run(bundleContext);
-
-        OSGi<?> extensions =
-            serviceReferences(getExtensionFilter()).flatMap(ref ->
-            waitForExtensionDependencies(ref,
-                safeRegisterExtension(ref, defaultServiceRegistrator)
-            )
-        );
-
-        _extensionsResult = extensions.run(bundleContext);
-
-        OSGi<?> applicationSingletons =
-            serviceReferences(format("(%s=*)", JAX_RS_APPLICATION_SELECT)).
-                flatMap(ref ->
-            just(ref.getProperty(JAX_RS_APPLICATION_SELECT).toString()).
-                flatMap(applicationFilter ->
-            services(CXFJaxRsServiceRegistrator.class, applicationFilter).
-                flatMap(registrator ->
-            testProvider(ref).flatMap(isProvider -> {
-                if (isProvider) {
-                    return safeRegisterExtension(ref, registrator);
-                }
-                else {
-                    return safeRegisterEndpoint(ref, registrator);
-                }
-            })
-        )));
-
-        _applicationSingletonsResult = applicationSingletons.run(bundleContext);
     }
 
-    private OSGi<Boolean> testProvider(ServiceReference<?> serviceReference) {
-        return bundleContext().flatMap(bundleContext -> {
-            Object service = bundleContext.getService(serviceReference);
-            Class<?> serviceClass = service.getClass();
-            if (serviceClass.isAnnotationPresent(Provider.class)) {
-                return just(Boolean.TRUE);
-            }
-            else {
-                return just(Boolean.FALSE);
-            }
-        });
-    }
-
-    private OSGi<?> safeRegisterExtension(
-        ServiceReference<Object> ref,
-        CXFJaxRsServiceRegistrator registrator) {
-
-        return
-            service(ref).flatMap(extension ->
-            onClose(() -> registrator.removeProvider(extension)).
-                foreach(ign ->
-            registrator.addProvider(extension)
-        ));
+    @Override
+    public void stop(BundleContext context) throws Exception {
+        _applicationsResult.close();
+        _applicationSingletonsResult.close();
+        _extensionsResult.close();
+        _singletonsResult.close();
     }
 
-    /**
-     * Initialize instance so it is never looked up again
-     * @param bundleContext
-     */
-    private void initRuntimeDelegate(BundleContext bundleContext) {
-        Thread thread = Thread.currentThread();
-        ClassLoader oldClassLoader = thread.getContextClassLoader();
-        BundleWiring bundleWiring = bundleContext.getBundle().adapt(
-            BundleWiring.class);
-        thread.setContextClassLoader(bundleWiring.getClassLoader());
-        try {
-            RuntimeDelegate.getInstance();
-        }
-        finally {
-            thread.setContextClassLoader(oldClassLoader);
-        }
+    private static String buildExtensionFilter(String filter) {
+        return String.format("(&%s%s)", getExtensionFilter(), filter);
     }
 
-    private String[] canonicalize(Object propertyValue) {
+    private static String[] canonicalize(Object propertyValue) {
         if (propertyValue == null) {
             return new String[0];
         }
@@ -224,111 +149,42 @@ public class CXFJaxRsBundleActivator implements BundleActivator {
         return new String[]{propertyValue.toString()};
     }
 
-    private String buildExtensionFilter(String filter) {
-        return format("(&%s%s)", getExtensionFilter(), filter);
+    private static CXFNonSpringServlet createCXFServlet(Bus bus) {
+        CXFNonSpringServlet cxfNonSpringServlet = new CXFNonSpringServlet();
+        cxfNonSpringServlet.setBus(bus);
+        return cxfNonSpringServlet;
     }
 
-    private OSGi<?> waitForExtensionDependencies(
-        ServiceReference<?> serviceReference, OSGi<?> program) {
-
-        String[] extensionDependencies = canonicalize(
-            serviceReference.getProperty(JAX_RS_EXTENSION_SELECT));
-
-        for (String extensionDependency : extensionDependencies) {
-            program =
-                serviceReferences(buildExtensionFilter(extensionDependency)).
-                then(program);
-        }
-
-        return program;
+    private static String getApplicationFilter() {
+        return format("(%s=*)", JAX_RS_APPLICATION_BASE);
     }
 
-    private <T> OSGi<?> safeRegisterEndpoint(
-        ServiceReference<T> ref, CXFJaxRsServiceRegistrator registrator) {
-
-        return
-            bundleContext().flatMap(bundleContext ->
-            serviceObjects(ref).flatMap(service ->
-            registerEndpoint(ref, registrator, service).
-                flatMap(serviceInformation ->
-            onClose(
-                () -> unregisterEndpoint(registrator, serviceInformation)))));
+    private static String getExtensionFilter() {
+        return format("(%s=*)", JAX_RS_EXTENSION_NAME);
     }
 
-    private <T> OSGi<ServiceInformation> registerEndpoint(
-        ServiceReference<?> ref,
-        CXFJaxRsServiceRegistrator registrator,
-        ServiceObjects<T> serviceObjects) {
+    private static String getSingletonsFilter() {
+        return format("(%s=*)", JAX_RS_RESOURCE_BASE);
+    }
 
+    /**
+     * Initialize instance so it is never looked up again
+     * @param bundleContext
+     */
+    private void initRuntimeDelegate(BundleContext bundleContext) {
         Thread thread = Thread.currentThread();
-        ClassLoader contextClassLoader = thread.getContextClassLoader();
-        ClassLoader classLoader = ref.getBundle().adapt(BundleWiring.class).
-            getClassLoader();
-        Object resourceBaseObject = ref.getProperty(JAX_RS_RESOURCE_BASE);
-
-        ResourceProvider resourceProvider = getResourceProvider(serviceObjects);
-
-        String resourceBase;
-
-        if (resourceBaseObject == null) {
-            resourceBase = "";
-        }
-        else {
-            resourceBase = resourceBaseObject.toString();
-        }
+        ClassLoader oldClassLoader = thread.getContextClassLoader();
+        BundleWiring bundleWiring = bundleContext.getBundle().adapt(
+            BundleWiring.class);
+        thread.setContextClassLoader(bundleWiring.getClassLoader());
         try {
-            thread.setContextClassLoader(classLoader);
-            ServiceInformation serviceInformation = new ServiceInformation(
-                resourceBase, resourceProvider);
-            registrator.add(serviceInformation);
-            return just(serviceInformation);
+            RuntimeDelegate.getInstance();
         }
         finally {
-            thread.setContextClassLoader(contextClassLoader);
+            thread.setContextClassLoader(oldClassLoader);
         }
     }
 
-    private <T> ResourceProvider getResourceProvider(
-        ServiceObjects<T> serviceObjects) {
-
-        ResourceProvider resourceProvider;
-        T service = serviceObjects.getService();
-        Class<?> serviceClass = service.getClass();
-
-        resourceProvider = new ResourceProvider() {
-
-            @Override
-            public Object getInstance(Message m) {
-                return serviceObjects.getService();
-            }
-
-            @Override
-            public void releaseInstance(Message m, Object o) {
-                serviceObjects.ungetService((T)o);
-            }
-
-            @Override
-            public Class<?> getResourceClass() {
-                return serviceClass;
-            }
-
-            @Override
-            public boolean isSingleton() {
-                return false;
-            }
-        };
-
-        serviceObjects.ungetService(service);
-        return resourceProvider;
-    }
-
-    private void unregisterEndpoint(
-        CXFJaxRsServiceRegistrator registrator,
-        ServiceInformation serviceInformation) {
-
-        registrator.remove(serviceInformation);
-    }
-
     private ServiceRegistration<Servlet> registerCXFServletService(Bus bus) {
         Dictionary<String, Object> properties = new Hashtable<>();
         properties.put(HTTP_WHITEBOARD_CONTEXT_SELECT,
@@ -341,30 +197,19 @@ public class CXFJaxRsBundleActivator implements BundleActivator {
             Servlet.class, cxfNonSpringServlet, properties);
     }
 
-    private CXFNonSpringServlet createCXFServlet(Bus bus) {
-        CXFNonSpringServlet cxfNonSpringServlet = new CXFNonSpringServlet();
-        cxfNonSpringServlet.setBus(bus);
-        return cxfNonSpringServlet;
-    }
-
-    private String getExtensionFilter() {
-        return format("(%s=*)", JAX_RS_EXTENSION_NAME);
-    }
+    private static OSGi<?> waitForExtensionDependencies(
+        ServiceReference<?> serviceReference, OSGi<?> program) {
 
-    private String getApplicationFilter() {
-        return format("(%s=*)", JAX_RS_APPLICATION_BASE);
-    }
+        String[] extensionDependencies = canonicalize(
+            serviceReference.getProperty(JAX_RS_EXTENSION_SELECT));
 
-    private String getSingletonsFilter() {
-        return format("(%s=*)", JAX_RS_RESOURCE_BASE);
-    }
+        for (String extensionDependency : extensionDependencies) {
+            program =
+                serviceReferences(buildExtensionFilter(extensionDependency)).
+                then(program);
+        }
 
-    @Override
-    public void stop(BundleContext context) throws Exception {
-        _applicationSingletonsResult.close();
-        _applicationsResult.close();
-        _extensionsResult.close();
-        _singletonsResult.close();
+        return program;
     }
 
 }

http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/blob/576f7e39/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/CXFJaxRsServiceRegistrator.java
----------------------------------------------------------------------
diff --git a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/CXFJaxRsServiceRegistrator.java b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/CXFJaxRsServiceRegistrator.java
index 1ac45ee..dd91521 100644
--- a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/CXFJaxRsServiceRegistrator.java
+++ b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/CXFJaxRsServiceRegistrator.java
@@ -36,16 +36,18 @@ import org.apache.cxf.jaxrs.model.URITemplate;
 import org.apache.cxf.jaxrs.provider.json.JSONProvider;
 import org.osgi.framework.ServiceReference;
 
+import static org.apache.aries.jax.rs.whiteboard.internal.Utils.safeToString;
 import static org.osgi.service.jaxrs.whiteboard.JaxRSWhiteboardConstants.*;
 
 public class CXFJaxRsServiceRegistrator {
+
     private volatile boolean _closed = false;
     private final Application _application;
     private final Bus _bus;
     private final Map<String, Object> _properties;
     private final Collection<Object> _providers = new ArrayList<>();
     private Server _server;
-    private final Collection<ServiceInformation> _services = new ArrayList<>();
+    private final Collection<ResourceInformation> _services = new ArrayList<>();
 
     private static final String CXF_ENDPOINT_ADDRESS = "CXF_ENDPOINT_ADDRESS";
 
@@ -59,9 +61,11 @@ public class CXFJaxRsServiceRegistrator {
         rewire();
     }
 
-    public static Map<String, Object> getProperties(ServiceReference<?> sref, String addressKey) {
+    public static Map<String, Object> getProperties(
+        ServiceReference<?> sref, String addressKey) {
+
         String[] propertyKeys = sref.getPropertyKeys();
-        Map<String, Object> properties = new HashMap<String, Object>(propertyKeys.length);
+        Map<String, Object> properties = new HashMap<>(propertyKeys.length);
 
         for (String key : propertyKeys) {
             if (key.equals(JAX_RS_RESOURCE_BASE)) {
@@ -70,48 +74,49 @@ public class CXFJaxRsServiceRegistrator {
             properties.put(key, sref.getProperty(key));
         }
 
-        properties.put(CXF_ENDPOINT_ADDRESS, sref.getProperty(addressKey).toString());
+        properties.put(
+            CXF_ENDPOINT_ADDRESS, sref.getProperty(addressKey).toString());
         return properties;
     }
 
-    public void close() {
+    public void add(ResourceInformation resourceInformation) {
         if (_closed) {
             return;
         }
 
-        if (_server != null) {
-            _server.destroy();
-        }
+        _services.add(resourceInformation);
 
-        _closed = true;
+        rewire();
     }
 
-    public void add(ServiceInformation serviceInformation) {
+    public void addProvider(Object provider) {
         if (_closed) {
             return;
         }
 
-        _services.add(serviceInformation);
+        _providers.add(provider);
 
         rewire();
     }
 
-    public void remove(ServiceInformation serviceInformation) {
+    public void close() {
         if (_closed) {
             return;
         }
 
-        _services.remove(serviceInformation);
+        if (_server != null) {
+            _server.destroy();
+        }
 
-        rewire();
+        _closed = true;
     }
 
-    public void addProvider(Object provider) {
+    public void remove(ResourceInformation resourceInformation) {
         if (_closed) {
             return;
         }
 
-        _providers.add(provider);
+        _services.remove(resourceInformation);
 
         rewire();
     }
@@ -125,6 +130,7 @@ public class CXFJaxRsServiceRegistrator {
 
         rewire();
     }
+
     protected synchronized void rewire() {
         if (_server != null) {
             _server.destroy();
@@ -162,13 +168,14 @@ public class CXFJaxRsServiceRegistrator {
         JAXRSServiceFactoryBean serviceFactory =
             jaxRsServerFactoryBean.getServiceFactory();
 
-        for (ServiceInformation serviceInformation : _services) {
+        for (ResourceInformation resourceInformation : _services) {
 
             ResourceProvider resourceProvider =
-                serviceInformation.getResourceProvider();
+                resourceInformation.getResourceProvider();
 
             jaxRsServerFactoryBean.setResourceProvider(resourceProvider);
 
+            //FIXME: this is hack to programmatically prefix only resource path
             List<ClassResourceInfo> classResourceInfo =
                 serviceFactory.getClassResourceInfo();
 
@@ -178,23 +185,13 @@ public class CXFJaxRsServiceRegistrator {
                     URITemplate uriTemplate = resourceInfo.getURITemplate();
                     resourceInfo.setURITemplate(
                         new URITemplate(
-                            serviceInformation.getPrefixPath() +
+                            resourceInformation.getPrefixPath() +
                                 uriTemplate.getValue()));
                 }
             }
         }
 
-        Object cxfEndpointAddressObject = _properties.get(
-            CXF_ENDPOINT_ADDRESS);
-
-        String address;
-
-        if (cxfEndpointAddressObject == null) {
-            address = "";
-        }
-        else {
-            address = cxfEndpointAddressObject.toString();
-        }
+        String address = safeToString(_properties.get(CXF_ENDPOINT_ADDRESS));
 
         if (address != null) {
             jaxRsServerFactoryBean.setAddress(address);
@@ -205,11 +202,11 @@ public class CXFJaxRsServiceRegistrator {
         _server.start();
     }
 
-    public static class ServiceInformation {
+    public static class ResourceInformation {
         private final String prefixPath;
         private final ResourceProvider _resourceProvider;
 
-        public ServiceInformation(
+        public ResourceInformation(
             String prefixPath, ResourceProvider resourceProvider) {
 
             this.prefixPath = prefixPath;

http://git-wip-us.apache.org/repos/asf/aries-jax-rs-whiteboard/blob/576f7e39/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/Utils.java
----------------------------------------------------------------------
diff --git a/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/Utils.java b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/Utils.java
new file mode 100644
index 0000000..0951f6e
--- /dev/null
+++ b/jax-rs.whiteboard/src/main/java/org/apache/aries/jax/rs/whiteboard/internal/Utils.java
@@ -0,0 +1,187 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.aries.jax.rs.whiteboard.internal;
+
+import org.apache.aries.jax.rs.whiteboard.internal.CXFJaxRsServiceRegistrator.ResourceInformation;
+import org.apache.aries.osgi.functional.OSGi;
+import org.apache.cxf.Bus;
+import org.apache.cxf.jaxrs.lifecycle.ResourceProvider;
+import org.apache.cxf.message.Message;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceObjects;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.wiring.BundleWiring;
+
+import javax.ws.rs.core.Application;
+import javax.ws.rs.ext.Provider;
+import java.util.Map;
+
+import static org.apache.aries.osgi.functional.OSGi.bundleContext;
+import static org.apache.aries.osgi.functional.OSGi.just;
+import static org.apache.aries.osgi.functional.OSGi.onClose;
+import static org.apache.aries.osgi.functional.OSGi.register;
+import static org.osgi.service.jaxrs.whiteboard.JaxRSWhiteboardConstants.JAX_RS_RESOURCE_BASE;
+
+/**
+ * @author Carlos Sierra Andr�s
+ */
+public class Utils {
+
+    public static <T> OSGi<T> service(ServiceReference<T> serviceReference) {
+        return
+            bundleContext().flatMap(bundleContext ->
+            onClose(() -> bundleContext.ungetService(serviceReference)).then(
+            just(bundleContext.getService(serviceReference))
+        ));
+    }
+
+    public static <T> OSGi<ServiceObjects<T>> serviceObjects(
+        ServiceReference<T> serviceReference) {
+
+        return
+            bundleContext().flatMap(bundleContext ->
+            just(bundleContext.getServiceObjects(serviceReference))
+        );
+    }
+
+    public static OSGi<CXFJaxRsServiceRegistrator> cxfRegistrator(
+        Bus bus, Application application, Map<String, Object> props) {
+
+        CXFJaxRsServiceRegistrator registrator =
+            new CXFJaxRsServiceRegistrator(bus, application, props);
+
+        return
+            onClose(registrator::close).then(
+            register(CXFJaxRsServiceRegistrator.class, registrator, props).then(
+            just(registrator)
+        ));
+    }
+
+    public static OSGi<?> safeRegisterGeneric(
+        ServiceReference<?> serviceReference,
+        CXFJaxRsServiceRegistrator registrator) {
+
+        return bundleContext().flatMap(bundleContext -> {
+            Object service = bundleContext.getService(serviceReference);
+            Class<?> serviceClass = service.getClass();
+            bundleContext.ungetService(serviceReference);
+            if (serviceClass.isAnnotationPresent(Provider.class)) {
+                return safeRegisterExtension(serviceReference, registrator);
+            }
+            else {
+                return safeRegisterEndpoint(serviceReference, registrator);
+            }
+        });
+    }
+
+    public static OSGi<?> safeRegisterExtension(
+        ServiceReference<?> serviceReference,
+        CXFJaxRsServiceRegistrator registrator) {
+
+        return
+            service(serviceReference).flatMap(extension ->
+            onClose(() -> registrator.removeProvider(extension)).
+                foreach(ign ->
+            registrator.addProvider(extension)
+        ));
+    }
+
+    public static <T> OSGi<?> safeRegisterEndpoint(
+        ServiceReference<T> ref, CXFJaxRsServiceRegistrator registrator) {
+
+        return
+            bundleContext().flatMap(bundleContext ->
+            serviceObjects(ref).flatMap(service ->
+            registerEndpoint(ref, registrator, service).
+                flatMap(serviceInformation ->
+            onClose(() ->
+                unregisterEndpoint(registrator, serviceInformation)))));
+    }
+
+    public static <T> OSGi<ResourceInformation> registerEndpoint(
+        ServiceReference<?> serviceReference,
+        CXFJaxRsServiceRegistrator registrator,
+        ServiceObjects<T> serviceObjects) {
+
+        Thread thread = Thread.currentThread();
+        ClassLoader contextClassLoader = thread.getContextClassLoader();
+        Bundle bundle = serviceReference.getBundle();
+        BundleWiring bundleWiring = bundle.adapt(BundleWiring.class);
+        ClassLoader classLoader = bundleWiring.getClassLoader();
+        ResourceProvider resourceProvider = getResourceProvider(serviceObjects);
+        String resourceBase = safeToString(
+            serviceReference.getProperty(JAX_RS_RESOURCE_BASE));
+
+        try {
+            thread.setContextClassLoader(classLoader);
+            ResourceInformation resourceInformation = new ResourceInformation(
+                resourceBase, resourceProvider);
+            registrator.add(resourceInformation);
+            return just(resourceInformation);
+        }
+        finally {
+            thread.setContextClassLoader(contextClassLoader);
+        }
+    }
+
+    public static String safeToString(Object resourceBaseObject) {
+        return resourceBaseObject == null ? "" : resourceBaseObject.toString();
+    }
+
+    public static <T> ResourceProvider getResourceProvider(
+        ServiceObjects<T> serviceObjects) {
+
+        ResourceProvider resourceProvider;
+        T service = serviceObjects.getService();
+        Class<?> serviceClass = service.getClass();
+
+        resourceProvider = new ResourceProvider() {
+
+            @Override
+            public Object getInstance(Message m) {
+                return serviceObjects.getService();
+            }
+
+            @Override
+            public void releaseInstance(Message m, Object o) {
+                serviceObjects.ungetService((T)o);
+            }
+
+            @Override
+            public Class<?> getResourceClass() {
+                return serviceClass;
+            }
+
+            @Override
+            public boolean isSingleton() {
+                return false;
+            }
+        };
+
+        serviceObjects.ungetService(service);
+        return resourceProvider;
+    }
+
+    public static void unregisterEndpoint(
+        CXFJaxRsServiceRegistrator registrator,
+        ResourceInformation resourceInformation) {
+
+        registrator.remove(resourceInformation);
+    }
+
+}