cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cschnei...@apache.org
Subject [3/4] cxf-dosgi git commit: [DOSGI-229] Use separate bundles for API and RSA impl. Remove dynamic import
Date Mon, 07 Mar 2016 23:49:06 GMT
http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/4ed2614d/dsw/cxf-dosgi-rsa/src/main/java/org/apache/cxf/dosgi/dsw/service/StringPlus.java
----------------------------------------------------------------------
diff --git a/dsw/cxf-dosgi-rsa/src/main/java/org/apache/cxf/dosgi/dsw/service/StringPlus.java b/dsw/cxf-dosgi-rsa/src/main/java/org/apache/cxf/dosgi/dsw/service/StringPlus.java
new file mode 100644
index 0000000..e449f1d
--- /dev/null
+++ b/dsw/cxf-dosgi-rsa/src/main/java/org/apache/cxf/dosgi/dsw/service/StringPlus.java
@@ -0,0 +1,72 @@
+/**
+ * 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.cxf.dosgi.dsw.service;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public final class StringPlus {
+
+    private static final Logger LOG = LoggerFactory.getLogger(StringPlus.class);
+
+    private StringPlus() {
+        // never constructed
+    }
+
+    @SuppressWarnings("rawtypes")
+    public static String[] normalize(Object object) {
+        if (object instanceof String) {
+            String s = (String)object;
+            String[] values = s.split(",");
+            List<String> list = new ArrayList<String>();
+            for (String val : values) {
+                String actualValue = val.trim();
+                if (!actualValue.isEmpty()) {
+                    list.add(actualValue);
+                }
+            }
+            return list.toArray(new String[list.size()]);
+        }
+
+        if (object instanceof String[]) {
+            return (String[])object;
+        }
+        
+        if (object instanceof Collection) {
+            Collection col = (Collection)object;
+            List<String> ar = new ArrayList<String>(col.size());
+            for (Object o : col) {
+                if (o instanceof String) {
+                    String s = (String)o;
+                    ar.add(s);
+                } else {
+                    LOG.warn("stringPlus contained non string element in list! Element was skipped");
+                }
+            }
+            return ar.toArray(new String[ar.size()]);
+        }
+
+        return null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/4ed2614d/dsw/cxf-dosgi-rsa/src/test/java/org/apache/cxf/dosgi/dsw/service/ClientServiceFactoryTest.java
----------------------------------------------------------------------
diff --git a/dsw/cxf-dosgi-rsa/src/test/java/org/apache/cxf/dosgi/dsw/service/ClientServiceFactoryTest.java b/dsw/cxf-dosgi-rsa/src/test/java/org/apache/cxf/dosgi/dsw/service/ClientServiceFactoryTest.java
new file mode 100644
index 0000000..20cdd02
--- /dev/null
+++ b/dsw/cxf-dosgi-rsa/src/test/java/org/apache/cxf/dosgi/dsw/service/ClientServiceFactoryTest.java
@@ -0,0 +1,88 @@
+/**
+ * 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.cxf.dosgi.dsw.service;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+import org.apache.cxf.dosgi.dsw.api.DistributionProvider;
+import org.easymock.EasyMock;
+import org.easymock.IMocksControl;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.remoteserviceadmin.EndpointDescription;
+import org.osgi.service.remoteserviceadmin.RemoteConstants;
+
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.isA;
+
+
+public class ClientServiceFactoryTest extends TestCase {
+
+    @SuppressWarnings({
+     "rawtypes", "unchecked"
+    })
+    public void testGetService() throws ClassNotFoundException {
+        final Object myTestProxyObject = new Object();
+
+        IMocksControl control = EasyMock.createControl();
+        EndpointDescription endpoint = createTestEndpointDesc();
+        ImportRegistrationImpl iri = new ImportRegistrationImpl(endpoint, null);
+
+        BundleContext requestingContext = control.createMock(BundleContext.class);
+        Bundle requestingBundle = control.createMock(Bundle.class);
+        EasyMock.expect(requestingBundle.loadClass(String.class.getName())).andReturn((Class)String.class);
+        EasyMock.expect(requestingBundle.getBundleContext()).andReturn(requestingContext);
+        ServiceRegistration sreg = control.createMock(ServiceRegistration.class);
+
+
+        DistributionProvider handler = mockDistributionProvider(myTestProxyObject);
+        control.replay();
+
+        ClientServiceFactory csf = new ClientServiceFactory(endpoint, handler, iri);
+        assertSame(myTestProxyObject, csf.getService(requestingBundle, sreg));
+    }
+
+    /**
+     * Creating dummy class as I was not able to really mock it
+     * @param myTestProxyObject
+     * @return
+     */
+    private DistributionProvider mockDistributionProvider(final Object proxy) {
+        DistributionProvider handler = EasyMock.createMock(DistributionProvider.class);
+        EasyMock.expect(handler.importEndpoint(anyObject(BundleContext.class), 
+                                               isA(Class[].class), 
+                                               anyObject(EndpointDescription.class))).andReturn(proxy);
+        EasyMock.replay(handler);
+        return handler;
+    }
+
+    private EndpointDescription createTestEndpointDesc() {
+        Map<String, Object> map = new HashMap<String, Object>();
+        map.put(RemoteConstants.ENDPOINT_ID, "http://google.de");
+        map.put(RemoteConstants.SERVICE_IMPORTED_CONFIGS, "myGreatConfiguration");
+        map.put(Constants.OBJECTCLASS, new String[]{String.class.getName()});
+        EndpointDescription endpoint = new EndpointDescription(map);
+        return endpoint;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/4ed2614d/dsw/cxf-dosgi-rsa/src/test/java/org/apache/cxf/dosgi/dsw/service/EventProducerTest.java
----------------------------------------------------------------------
diff --git a/dsw/cxf-dosgi-rsa/src/test/java/org/apache/cxf/dosgi/dsw/service/EventProducerTest.java b/dsw/cxf-dosgi-rsa/src/test/java/org/apache/cxf/dosgi/dsw/service/EventProducerTest.java
new file mode 100644
index 0000000..71d3ed7
--- /dev/null
+++ b/dsw/cxf-dosgi-rsa/src/test/java/org/apache/cxf/dosgi/dsw/service/EventProducerTest.java
@@ -0,0 +1,189 @@
+/**
+ * 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.cxf.dosgi.dsw.service;
+
+import java.util.Arrays;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.UUID;
+
+import org.apache.cxf.dosgi.dsw.api.Endpoint;
+import org.easymock.EasyMock;
+import org.easymock.IAnswer;
+import org.junit.Assert;
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.Version;
+import org.osgi.service.event.Event;
+import org.osgi.service.event.EventAdmin;
+import org.osgi.service.remoteserviceadmin.EndpointDescription;
+import org.osgi.service.remoteserviceadmin.ExportReference;
+import org.osgi.service.remoteserviceadmin.ExportRegistration;
+import org.osgi.service.remoteserviceadmin.RemoteServiceAdminEvent;
+
+@SuppressWarnings({"rawtypes", "unchecked"})
+public class EventProducerTest {
+    
+    
+    @Test
+    public void testPublishNotification() throws Exception {
+        RemoteServiceAdminCore remoteServiceAdminCore = EasyMock.createNiceMock(RemoteServiceAdminCore.class);
+        EasyMock.replay(remoteServiceAdminCore);
+
+        final EndpointDescription epd = EasyMock.createNiceMock(EndpointDescription.class);
+        EasyMock.expect(epd.getServiceId()).andReturn(Long.MAX_VALUE).anyTimes();
+        final String uuid = UUID.randomUUID().toString();
+        EasyMock.expect(epd.getFrameworkUUID()).andReturn(uuid).anyTimes();
+        EasyMock.expect(epd.getId()).andReturn("foo://bar").anyTimes();
+        final List<String> interfaces = Arrays.asList("org.foo.Bar", "org.boo.Far");
+        EasyMock.expect(epd.getInterfaces()).andReturn(interfaces).anyTimes();
+        EasyMock.expect(epd.getConfigurationTypes()).andReturn(Arrays.asList("org.apache.cxf.ws")).anyTimes();
+        EasyMock.replay(epd);
+        final ServiceReference sref = EasyMock.createNiceMock(ServiceReference.class);
+        EasyMock.replay(sref);
+
+        final Bundle bundle = EasyMock.createNiceMock(Bundle.class);
+        EasyMock.expect(bundle.getBundleId()).andReturn(42L).anyTimes();
+        EasyMock.expect(bundle.getSymbolicName()).andReturn("test.bundle").anyTimes();
+        Dictionary<String, String> headers = new Hashtable<String, String>();
+        headers.put("Bundle-Version", "1.2.3.test");
+        EasyMock.expect(bundle.getHeaders()).andReturn(headers).anyTimes();
+        EasyMock.replay(bundle);
+
+        EventAdmin ea = EasyMock.createNiceMock(EventAdmin.class);
+        ea.postEvent((Event) EasyMock.anyObject());
+        EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
+            @Override
+            public Object answer() throws Throwable {
+                Event event = (Event) EasyMock.getCurrentArguments()[0];
+
+                Assert.assertEquals("org/osgi/service/remoteserviceadmin/EXPORT_REGISTRATION", event.getTopic());
+                Assert.assertSame(bundle, event.getProperty("bundle"));
+                Assert.assertEquals(42L, event.getProperty("bundle.id"));
+                Assert.assertEquals("test.bundle", event.getProperty("bundle.symbolicname"));
+                Assert.assertEquals(new Version(1, 2, 3, "test"), event.getProperty("bundle.version"));
+                Assert.assertNull(event.getProperty("cause"));
+                Assert.assertEquals(epd, event.getProperty("export.registration"));
+
+                Assert.assertEquals(Long.MAX_VALUE, event.getProperty("service.remote.id"));
+                Assert.assertEquals(uuid, event.getProperty("service.remote.uuid"));
+                Assert.assertEquals("foo://bar", event.getProperty("service.remote.uri"));
+                Assert.assertTrue(Arrays.equals(interfaces.toArray(new String[] {}),
+                                                (String[]) event.getProperty("objectClass")));
+
+                Assert.assertNotNull(event.getProperty("timestamp"));
+
+                RemoteServiceAdminEvent rsae = (RemoteServiceAdminEvent) event.getProperty("event");
+                Assert.assertNull(rsae.getException());
+                Assert.assertEquals(RemoteServiceAdminEvent.EXPORT_REGISTRATION, rsae.getType());
+                Assert.assertSame(bundle, rsae.getSource());
+                ExportReference er = rsae.getExportReference();
+                Assert.assertSame(epd, er.getExportedEndpoint());
+                Assert.assertSame(sref, er.getExportedService());
+
+                return null;
+            }
+        });
+        EasyMock.replay(ea);
+
+        ServiceReference eaSref = EasyMock.createNiceMock(ServiceReference.class);
+        EasyMock.replay(eaSref);
+
+        BundleContext bc = EasyMock.createNiceMock(BundleContext.class);
+        EasyMock.expect(bc.getBundle()).andReturn(bundle).anyTimes();
+        EasyMock.expect(bc.getAllServiceReferences(EventAdmin.class.getName(), null))
+            .andReturn(new ServiceReference[] {eaSref}).anyTimes();
+        EasyMock.expect(bc.getService(eaSref)).andReturn(ea).anyTimes();
+        Endpoint endpoint = EasyMock.mock(Endpoint.class);
+        EasyMock.expect(endpoint.description()).andReturn(epd);
+        EasyMock.replay(endpoint);
+        EasyMock.replay(bc);
+        EventProducer eventProducer = new EventProducer(bc);
+
+        ExportRegistrationImpl ereg = new ExportRegistrationImpl(sref, endpoint, remoteServiceAdminCore);
+        eventProducer.publishNotification(ereg);
+    }
+
+    @Test
+    public void testPublishErrorNotification() throws Exception {
+        RemoteServiceAdminCore rsaCore = EasyMock.createNiceMock(RemoteServiceAdminCore.class);
+        EasyMock.replay(rsaCore);
+
+        final EndpointDescription endpoint = EasyMock.createNiceMock(EndpointDescription.class);
+        EasyMock.expect(endpoint.getInterfaces()).andReturn(Arrays.asList("org.foo.Bar")).anyTimes();
+        EasyMock.replay(endpoint);
+        final ServiceReference sref = EasyMock.createNiceMock(ServiceReference.class);
+        EasyMock.replay(sref);
+
+        final Bundle bundle = EasyMock.createNiceMock(Bundle.class);
+        EasyMock.expect(bundle.getBundleId()).andReturn(42L).anyTimes();
+        EasyMock.expect(bundle.getSymbolicName()).andReturn("test.bundle").anyTimes();
+        EasyMock.expect(bundle.getHeaders()).andReturn(new Hashtable<String, String>()).anyTimes();
+        EasyMock.replay(bundle);
+
+        final Exception exportException = new Exception();
+
+        EventAdmin ea = EasyMock.createNiceMock(EventAdmin.class);
+        ea.postEvent((Event) EasyMock.anyObject());
+        EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
+            @Override
+            public Object answer() throws Throwable {
+                Event event = (Event) EasyMock.getCurrentArguments()[0];
+
+                Assert.assertEquals("org/osgi/service/remoteserviceadmin/EXPORT_ERROR", event.getTopic());
+                Assert.assertSame(bundle, event.getProperty("bundle"));
+                Assert.assertEquals(42L, event.getProperty("bundle.id"));
+                Assert.assertEquals("test.bundle", event.getProperty("bundle.symbolicname"));
+                Assert.assertEquals(new Version("0"), event.getProperty("bundle.version"));
+                Assert.assertSame(exportException, event.getProperty("cause"));
+                Assert.assertEquals(endpoint, event.getProperty("export.registration"));
+                Assert.assertTrue(Arrays.equals(new String[] {"org.foo.Bar"},
+                                                (String[]) event.getProperty("objectClass")));
+
+                RemoteServiceAdminEvent rsae = (RemoteServiceAdminEvent) event.getProperty("event");
+                Assert.assertSame(exportException, rsae.getException());
+                Assert.assertEquals(RemoteServiceAdminEvent.EXPORT_ERROR, rsae.getType());
+                Assert.assertSame(bundle, rsae.getSource());
+                ExportReference er = rsae.getExportReference();
+                Assert.assertSame(endpoint, er.getExportedEndpoint());
+                Assert.assertSame(sref, er.getExportedService());
+
+                return null;
+            }
+        });
+        EasyMock.replay(ea);
+
+        ServiceReference eaSref = EasyMock.createNiceMock(ServiceReference.class);
+        EasyMock.replay(eaSref);
+
+        BundleContext bc = EasyMock.createNiceMock(BundleContext.class);
+        EasyMock.expect(bc.getBundle()).andReturn(bundle).anyTimes();
+        EasyMock.expect(bc.getAllServiceReferences(EventAdmin.class.getName(), null))
+            .andReturn(new ServiceReference[] {eaSref}).anyTimes();
+        EasyMock.expect(bc.getService(eaSref)).andReturn(ea).anyTimes();
+        EasyMock.replay(bc);
+        EventProducer eventProducer = new EventProducer(bc);
+
+        ExportRegistrationImpl ereg = new ExportRegistrationImpl(rsaCore, exportException);
+        eventProducer.publishNotification(Arrays.<ExportRegistration>asList(ereg));
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/4ed2614d/dsw/cxf-dosgi-rsa/src/test/java/org/apache/cxf/dosgi/dsw/service/ImportRegistrationImplTest.java
----------------------------------------------------------------------
diff --git a/dsw/cxf-dosgi-rsa/src/test/java/org/apache/cxf/dosgi/dsw/service/ImportRegistrationImplTest.java b/dsw/cxf-dosgi-rsa/src/test/java/org/apache/cxf/dosgi/dsw/service/ImportRegistrationImplTest.java
new file mode 100644
index 0000000..23902a5
--- /dev/null
+++ b/dsw/cxf-dosgi-rsa/src/test/java/org/apache/cxf/dosgi/dsw/service/ImportRegistrationImplTest.java
@@ -0,0 +1,178 @@
+/**
+ * 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.cxf.dosgi.dsw.service;
+
+import org.easymock.EasyMock;
+import org.easymock.IMocksControl;
+import org.junit.Test;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.remoteserviceadmin.EndpointDescription;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+public class ImportRegistrationImplTest {
+
+    @Test
+    public void testException() {
+        IMocksControl c = EasyMock.createNiceControl();
+        Exception e = c.createMock(Exception.class);
+        c.replay();
+
+        ImportRegistrationImpl i = new ImportRegistrationImpl(e);
+
+        assertEquals(e, i.getException());
+        assertNull(i.getImportedEndpointDescription());
+        assertNull(i.getImportedService());
+        assertEquals(i, i.getParent());
+    }
+
+    @Test
+    public void testDefaultCtor() {
+        IMocksControl c = EasyMock.createNiceControl();
+        EndpointDescription endpoint = c.createMock(EndpointDescription.class);
+        RemoteServiceAdminCore rsac = c.createMock(RemoteServiceAdminCore.class);
+
+        c.replay();
+
+        ImportRegistrationImpl i = new ImportRegistrationImpl(endpoint, rsac);
+
+        assertNull(i.getException());
+        assertEquals(i, i.getParent());
+        assertEquals(endpoint, i.getImportedEndpointDescription());
+    }
+
+    @SuppressWarnings("rawtypes")
+    @Test
+    public void testCloneAndClose() {
+        IMocksControl c = EasyMock.createControl();
+        EndpointDescription endpoint = c.createMock(EndpointDescription.class);
+        RemoteServiceAdminCore rsac = c.createMock(RemoteServiceAdminCore.class);
+
+        ServiceRegistration sr = c.createMock(ServiceRegistration.class);
+        ServiceReference sref = c.createMock(ServiceReference.class);
+        EasyMock.expect(sr.getReference()).andReturn(sref).anyTimes();
+
+        c.replay();
+
+        ImportRegistrationImpl i1 = new ImportRegistrationImpl(endpoint, rsac);
+
+        ImportRegistrationImpl i2 = new ImportRegistrationImpl(i1);
+
+        ImportRegistrationImpl i3 = new ImportRegistrationImpl(i2);
+
+        try {
+            i2.setImportedServiceRegistration(sr);
+            assertTrue("An exception should be thrown here !", false);
+        } catch (IllegalStateException e) {
+            // must be thrown here
+        }
+
+        i1.setImportedServiceRegistration(sr);
+
+        assertEquals(i1, i1.getParent());
+        assertEquals(i1, i2.getParent());
+        assertEquals(i1, i3.getParent());
+
+        assertEquals(endpoint, i1.getImportedEndpointDescription());
+        assertEquals(endpoint, i2.getImportedEndpointDescription());
+        assertEquals(endpoint, i3.getImportedEndpointDescription());
+
+        c.verify();
+        c.reset();
+
+        rsac.removeImportRegistration(EasyMock.eq(i3));
+        EasyMock.expectLastCall().once();
+
+        c.replay();
+
+        i3.close();
+        i3.close(); // shouldn't change anything
+
+        assertNull(i3.getImportedEndpointDescription());
+
+        c.verify();
+        c.reset();
+
+        rsac.removeImportRegistration(EasyMock.eq(i1));
+        EasyMock.expectLastCall().once();
+
+        c.replay();
+
+        i1.close();
+
+        c.verify();
+        c.reset();
+
+        rsac.removeImportRegistration(EasyMock.eq(i2));
+        EasyMock.expectLastCall().once();
+
+        sr.unregister();
+        EasyMock.expectLastCall().once();
+
+        c.replay();
+
+        i2.close();
+
+        c.verify();
+    }
+
+    @Test
+    public void testCloseAll() {
+        IMocksControl c = EasyMock.createControl();
+        EndpointDescription endpoint = c.createMock(EndpointDescription.class);
+        RemoteServiceAdminCore rsac = c.createMock(RemoteServiceAdminCore.class);
+
+        c.replay();
+
+        ImportRegistrationImpl i1 = new ImportRegistrationImpl(endpoint, rsac);
+
+        ImportRegistrationImpl i2 = new ImportRegistrationImpl(i1);
+
+        ImportRegistrationImpl i3 = new ImportRegistrationImpl(i2);
+
+        assertEquals(i1, i1.getParent());
+        assertEquals(i1, i2.getParent());
+        assertEquals(i1, i3.getParent());
+
+        c.verify();
+        c.reset();
+
+        rsac.removeImportRegistration(EasyMock.eq(i2));
+        EasyMock.expectLastCall().once();
+
+        c.replay();
+
+        i2.close();
+
+        c.verify();
+        c.reset();
+
+        rsac.removeImportRegistration(EasyMock.eq(i1));
+        EasyMock.expectLastCall().once();
+        rsac.removeImportRegistration(EasyMock.eq(i3));
+        EasyMock.expectLastCall().once();
+
+        c.replay();
+        i3.closeAll();
+        c.verify();
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/4ed2614d/dsw/cxf-dosgi-rsa/src/test/java/org/apache/cxf/dosgi/dsw/service/RemoteServiceAdminCoreTest.java
----------------------------------------------------------------------
diff --git a/dsw/cxf-dosgi-rsa/src/test/java/org/apache/cxf/dosgi/dsw/service/RemoteServiceAdminCoreTest.java b/dsw/cxf-dosgi-rsa/src/test/java/org/apache/cxf/dosgi/dsw/service/RemoteServiceAdminCoreTest.java
new file mode 100644
index 0000000..af7052f
--- /dev/null
+++ b/dsw/cxf-dosgi-rsa/src/test/java/org/apache/cxf/dosgi/dsw/service/RemoteServiceAdminCoreTest.java
@@ -0,0 +1,491 @@
+/**
+ * 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.cxf.dosgi.dsw.service;
+
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.cxf.dosgi.dsw.api.DistributionProvider;
+import org.apache.cxf.dosgi.dsw.api.Endpoint;
+import org.easymock.EasyMock;
+import org.easymock.IAnswer;
+import org.easymock.IMocksControl;
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.remoteserviceadmin.EndpointDescription;
+import org.osgi.service.remoteserviceadmin.ExportRegistration;
+import org.osgi.service.remoteserviceadmin.ImportRegistration;
+import org.osgi.service.remoteserviceadmin.RemoteConstants;
+
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.isA;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+@SuppressWarnings({
+    "rawtypes", "unchecked"
+   })
+public class RemoteServiceAdminCoreTest {
+
+    private static final String MYCONFIG = "myconfig";
+
+    @Test
+    public void testDontExportOwnServiceProxies() throws InvalidSyntaxException {
+        IMocksControl c = EasyMock.createControl();
+        Bundle b = c.createMock(Bundle.class);
+        BundleContext bc = c.createMock(BundleContext.class);
+
+        EasyMock.expect(bc.getBundle()).andReturn(b).anyTimes();
+        bc.addServiceListener(EasyMock.<ServiceListener>anyObject(), EasyMock.<String>anyObject());
+        EasyMock.expectLastCall().anyTimes();
+        bc.removeServiceListener(EasyMock.<ServiceListener>anyObject());
+        EasyMock.expectLastCall().anyTimes();
+
+        Dictionary<String, String> d = new Hashtable<String, String>();
+        EasyMock.expect(b.getHeaders()).andReturn(d).anyTimes();
+
+        ServiceReference sref = c.createMock(ServiceReference.class);
+        EasyMock.expect(sref.getBundle()).andReturn(b).anyTimes();
+        EasyMock.expect(sref.getPropertyKeys())
+            .andReturn(new String[]{"objectClass", "service.exported.interfaces"}).anyTimes();
+        EasyMock.expect(sref.getProperty("objectClass")).andReturn(new String[] {"a.b.C"}).anyTimes();
+        EasyMock.expect(sref.getProperty(RemoteConstants.SERVICE_IMPORTED)).andReturn(true).anyTimes();
+        EasyMock.expect(sref.getProperty("service.exported.interfaces")).andReturn("*").anyTimes();
+
+        DistributionProvider provider = c.createMock(DistributionProvider.class);
+
+        c.replay();
+
+        RemoteServiceAdminCore rsaCore = new RemoteServiceAdminCore(bc, bc, provider);
+
+        // must return an empty List as sref if from the same bundle
+        List<ExportRegistration> exRefs = rsaCore.exportService(sref, null);
+
+        assertNotNull(exRefs);
+        assertEquals(0, exRefs.size());
+
+        // must be empty
+        assertEquals(rsaCore.getExportedServices().size(), 0);
+
+        c.verify();
+    }
+
+    @Test
+    public void testImport() {
+        IMocksControl c = EasyMock.createNiceControl();
+        Bundle b = c.createMock(Bundle.class);
+        BundleContext bc = c.createMock(BundleContext.class);
+
+        Dictionary<String, String> d = new Hashtable<String, String>();
+        EasyMock.expect(b.getHeaders()).andReturn(d).anyTimes();
+
+        EasyMock.expect(bc.getBundle()).andReturn(b).anyTimes();
+        EasyMock.expect(b.getSymbolicName()).andReturn("BundleName").anyTimes();
+
+        EndpointDescription endpoint = creatEndpointDesc("unsupportedConfiguration");
+
+        DistributionProvider provider = c.createMock(DistributionProvider.class);
+        EasyMock.expect(provider.getSupportedTypes())
+            .andReturn(new String[]{MYCONFIG}).atLeastOnce();
+        c.replay();
+
+        RemoteServiceAdminCore rsaCore = new RemoteServiceAdminCore(bc, bc, provider);
+
+        // must be null as the endpoint doesn't contain any usable configurations
+        assertNull(rsaCore.importService(endpoint));
+        // must be empty
+        assertEquals(0, rsaCore.getImportedEndpoints().size());
+
+        EndpointDescription endpoint2 = creatEndpointDesc(MYCONFIG);
+
+        ImportRegistration ireg = rsaCore.importService(endpoint2);
+        assertNotNull(ireg);
+
+        assertEquals(1, rsaCore.getImportedEndpoints().size());
+
+        // lets import the same endpoint once more -> should get a copy of the ImportRegistration
+        ImportRegistration ireg2 = rsaCore.importService(endpoint2);
+        assertNotNull(ireg2);
+        assertEquals(2, rsaCore.getImportedEndpoints().size());
+
+        assertEquals(ireg.getImportReference(), (rsaCore.getImportedEndpoints().toArray())[0]);
+
+        assertEquals(ireg.getImportReference().getImportedEndpoint(), ireg2.getImportReference()
+            .getImportedEndpoint());
+
+        // remove the registration
+
+        // first call shouldn't remove the import
+        ireg2.close();
+        assertEquals(1, rsaCore.getImportedEndpoints().size());
+
+        // second call should really close and remove the import
+        ireg.close();
+        assertEquals(0, rsaCore.getImportedEndpoints().size());
+
+        c.verify();
+    }
+
+    private EndpointDescription creatEndpointDesc(String configType) {
+        Map<String, Object> p = new HashMap<String, Object>();
+        p.put(RemoteConstants.ENDPOINT_ID, "http://google.de");
+        p.put(Constants.OBJECTCLASS, new String[] {
+            "es.schaaf.my.class"
+        });
+        p.put(RemoteConstants.SERVICE_IMPORTED_CONFIGS, configType);
+        EndpointDescription endpoint = new EndpointDescription(p);
+        return endpoint;
+    }
+
+    @Test
+    public void testExport() throws Exception {
+        BundleContext bc = EasyMock.createMock(BundleContext.class);
+        EasyMock.expect(bc.getProperty(Constants.FRAMEWORK_VERSION)).andReturn(null).anyTimes();
+        bc.addServiceListener(EasyMock.<ServiceListener>anyObject(), EasyMock.<String>anyObject());
+        EasyMock.expectLastCall().anyTimes();
+        bc.removeServiceListener(EasyMock.<ServiceListener>anyObject());
+        EasyMock.expectLastCall().anyTimes();
+        EasyMock.expect(bc.getServiceReferences(EasyMock.<String>anyObject(),
+                                                EasyMock.<String>anyObject())).andReturn(null).anyTimes();
+        EasyMock.expect(bc.getAllServiceReferences(EasyMock.<String>anyObject(),
+                                                   EasyMock.<String>anyObject())).andReturn(null).anyTimes();
+
+        Bundle b = createDummyRsaBundle(bc);
+
+        final Map<String, Object> sProps = new HashMap<String, Object>();
+        sProps.put("objectClass", new String[] {"java.lang.Runnable"});
+        sProps.put("service.id", 51L);
+        sProps.put("myProp", "myVal");
+        sProps.put("service.exported.interfaces", "*");
+        ServiceReference sref = mockServiceReference(sProps);
+
+        Runnable svcObject = EasyMock.createNiceMock(Runnable.class);
+        EasyMock.replay(svcObject);
+
+        EasyMock.expect(bc.getService(sref)).andReturn(svcObject).anyTimes();
+        EasyMock.expect(bc.getBundle()).andReturn(b).anyTimes();
+        EasyMock.expect(bc.createFilter("(service.id=51)"))
+            .andReturn(FrameworkUtil.createFilter("(service.id=51)")).anyTimes();
+        EasyMock.replay(bc);
+
+        Map<String, Object> eProps = new HashMap<String, Object>(sProps);
+        eProps.put("endpoint.id", "http://something");
+        eProps.put("service.imported.configs", new String[] {"org.apache.cxf.ws"});
+        final EndpointDescription epd = new EndpointDescription(eProps);
+        Endpoint er = new Endpoint() {
+            
+            @Override
+            public void close() throws IOException {
+            }
+            
+            @Override
+            public EndpointDescription description() {
+                return epd;
+            }
+        };
+
+        DistributionProvider handler = EasyMock.createMock(DistributionProvider.class);
+        EasyMock.expect(handler.exportService(anyObject(ServiceReference.class), 
+                                              anyObject(Map.class), isA(Class[].class))).andReturn(er);
+        EasyMock.replay(handler);
+
+        RemoteServiceAdminCore rsaCore = new RemoteServiceAdminCore(bc, bc, handler);
+
+        // Export the service for the first time
+        List<ExportRegistration> ereg = rsaCore.exportService(sref, null);
+        assertEquals(1, ereg.size());
+        assertNull(ereg.get(0).getException());
+        assertSame(sref, ereg.get(0).getExportReference().getExportedService());
+        EndpointDescription endpoint = ereg.get(0).getExportReference().getExportedEndpoint();
+
+        Map<String, Object> edProps = endpoint.getProperties();
+        assertEquals("http://something", edProps.get("endpoint.id"));
+        assertNotNull(edProps.get("service.imported"));
+        assertTrue(Arrays.equals(new String[] {"java.lang.Runnable"},
+                                 (Object[]) edProps.get("objectClass")));
+        assertTrue(Arrays.equals(new String[] {"org.apache.cxf.ws"},
+                                 (Object[]) edProps.get("service.imported.configs")));
+
+        // Ask to export the same service again, this should not go through the whole process again but simply return
+        // a copy of the first instance.
+        final Map<String, Object> sProps2 = new HashMap<String, Object>();
+        sProps2.put("objectClass", new String[] {"java.lang.Runnable"});
+        sProps2.put("service.id", 51L);
+        sProps2.put("service.exported.interfaces", "*");
+        ServiceReference sref2 = mockServiceReference(sProps2);
+        Map<String, Object> props2 = new HashMap<String, Object>();
+        props2.put("myProp", "myVal");
+        List<ExportRegistration> ereg2 = rsaCore.exportService(sref2, props2);
+
+        assertEquals(1, ereg2.size());
+        assertNull(ereg2.get(0).getException());
+        assertEquals(ereg.get(0).getExportReference().getExportedEndpoint().getProperties(),
+                ereg2.get(0).getExportReference().getExportedEndpoint().getProperties());
+
+        // Look at the exportedServices data structure
+        Field field = RemoteServiceAdminCore.class.getDeclaredField("exportedServices");
+        field.setAccessible(true);
+        Map<Map<String, Object>, Collection<ExportRegistration>> exportedServices =
+                (Map<Map<String, Object>, Collection<ExportRegistration>>) field.get(rsaCore);
+
+        assertEquals("One service was exported", 1, exportedServices.size());
+        assertEquals("There are 2 export registrations (identical copies)",
+                2, exportedServices.values().iterator().next().size());
+
+        // Unregister one of the exports
+        rsaCore.removeExportRegistration((ExportRegistrationImpl) ereg.get(0));
+        assertEquals("One service was exported", 1, exportedServices.size());
+        assertEquals("There 1 export registrations left",
+                1, exportedServices.values().iterator().next().size());
+
+        // Unregister the other export
+        rsaCore.removeExportRegistration((ExportRegistrationImpl) ereg2.get(0));
+        assertEquals("No more exported services", 0, exportedServices.size());
+    }
+
+    private Bundle createDummyRsaBundle(BundleContext bc) {
+        Bundle b = EasyMock.createNiceMock(Bundle.class);
+        EasyMock.expect(b.getBundleContext()).andReturn(bc).anyTimes();
+        EasyMock.expect(b.getSymbolicName()).andReturn("rsabundle").anyTimes();
+        EasyMock.expect(b.getHeaders()).andReturn(new Hashtable<String, String>()).anyTimes();
+        EasyMock.replay(b);
+        return b;
+    }
+
+    @Test
+    public void testExportException() throws Exception {
+        BundleContext bc = EasyMock.createNiceMock(BundleContext.class);
+
+        Bundle b = createDummyRsaBundle(bc);
+
+        final Map<String, Object> sProps = new HashMap<String, Object>();
+        sProps.put("objectClass", new String[] {"java.lang.Runnable"});
+        sProps.put("service.id", 51L);
+        sProps.put("service.exported.interfaces", "*");
+        ServiceReference sref = mockServiceReference(sProps);
+
+        Runnable svcObject = EasyMock.createNiceMock(Runnable.class);
+        EasyMock.replay(svcObject);
+
+        EasyMock.expect(bc.getService(sref)).andReturn(svcObject).anyTimes();
+        EasyMock.expect(bc.getBundle()).andReturn(b).anyTimes();
+        EasyMock.replay(bc);
+
+        Map<String, Object> eProps = new HashMap<String, Object>(sProps);
+        eProps.put("endpoint.id", "http://something");
+        eProps.put("service.imported.configs", new String[] {"org.apache.cxf.ws"});
+
+        DistributionProvider handler = EasyMock.createMock(DistributionProvider.class);
+        EasyMock.expect(handler.exportService(anyObject(ServiceReference.class), 
+                                              anyObject(Map.class), isA(Class[].class))).andThrow(new TestException());
+        EasyMock.replay(handler);
+
+        RemoteServiceAdminCore rsaCore = new RemoteServiceAdminCore(bc, bc, handler);
+
+        List<ExportRegistration> ereg = rsaCore.exportService(sref, sProps);
+        assertEquals(1, ereg.size());
+        assertTrue(ereg.get(0).getException() instanceof TestException);
+
+        // Look at the exportedServices data structure
+        Field field = RemoteServiceAdminCore.class.getDeclaredField("exportedServices");
+        field.setAccessible(true);
+        Map<Map<String, Object>, Collection<ExportRegistration>> exportedServices =
+                (Map<Map<String, Object>, Collection<ExportRegistration>>) field.get(rsaCore);
+
+        assertEquals("One service was exported", 1, exportedServices.size());
+        assertEquals("There is 1 export registration",
+                1, exportedServices.values().iterator().next().size());
+
+    }
+
+    private ServiceReference mockServiceReference(final Map<String, Object> sProps) throws ClassNotFoundException {
+        BundleContext bc = EasyMock.createNiceMock(BundleContext.class);
+
+        Bundle b = EasyMock.createNiceMock(Bundle.class);
+        EasyMock.expect(b.getBundleContext()).andReturn(bc).anyTimes();
+        EasyMock.expect((Class)b.loadClass(Runnable.class.getName())).andReturn(Runnable.class);
+        EasyMock.replay(b);
+
+        EasyMock.expect(bc.getBundle()).andReturn(b).anyTimes();
+        EasyMock.replay(bc);
+
+        ServiceReference sref = EasyMock.createNiceMock(ServiceReference.class);
+        EasyMock.expect(sref.getBundle()).andReturn(b).anyTimes();
+        EasyMock.expect(sref.getPropertyKeys()).andReturn(sProps.keySet().toArray(new String[] {})).anyTimes();
+        EasyMock.expect(sref.getProperty((String) EasyMock.anyObject())).andAnswer(new IAnswer<Object>() {
+            @Override
+            public Object answer() throws Throwable {
+                return sProps.get(EasyMock.getCurrentArguments()[0]);
+            }
+        }).anyTimes();
+        EasyMock.replay(sref);
+        return sref;
+    }
+
+    @SuppressWarnings("serial")
+    private static class TestException extends RuntimeException {
+    }
+    
+    @Test
+    public void testOverlayProperties() {
+        Map<String, Object> sProps = new HashMap<String, Object>();
+        Map<String, Object> aProps = new HashMap<String, Object>();
+
+        RemoteServiceAdminCore.overlayProperties(sProps, aProps);
+        assertEquals(0, sProps.size());
+
+        sProps.put("aaa", "aval");
+        sProps.put("bbb", "bval");
+        sProps.put(Constants.OBJECTCLASS, new String[] {"X"});
+        sProps.put(Constants.SERVICE_ID, 17L);
+
+        aProps.put("AAA", "achanged");
+        aProps.put("CCC", "CVAL");
+        aProps.put(Constants.OBJECTCLASS, new String[] {"Y"});
+        aProps.put(Constants.SERVICE_ID.toUpperCase(), 51L);
+
+        Map<String, Object> aPropsOrg = new HashMap<String, Object>(aProps);
+        RemoteServiceAdminCore.overlayProperties(sProps, aProps);
+        assertEquals("The additional properties should not be modified", aPropsOrg, aProps);
+
+        assertEquals(5, sProps.size());
+        assertEquals("achanged", sProps.get("aaa"));
+        assertEquals("bval", sProps.get("bbb"));
+        assertEquals("CVAL", sProps.get("CCC"));
+        assertTrue("Should not be possible to override the objectClass property",
+                Arrays.equals(new String[] {"X"}, (Object[]) sProps.get(Constants.OBJECTCLASS)));
+        assertEquals("Should not be possible to override the service.id property",
+                17L, sProps.get(Constants.SERVICE_ID));
+    }
+    
+    @Test
+    public void testOverlayProperties2() {
+        Map<String, Object> original = new HashMap<String, Object>();
+
+        original.put("MyProp", "my value");
+        original.put(Constants.OBJECTCLASS, "myClass");
+
+        Map<String, Object> copy = new HashMap<String, Object>();
+        copy.putAll(original);
+
+        // nothing should change here
+        Map<String, Object> overload = new HashMap<String, Object>();
+        RemoteServiceAdminCore.overlayProperties(copy, overload);
+
+        assertEquals(original.size(), copy.size());
+        for (Object key : original.keySet()) {
+            assertEquals(original.get(key), copy.get(key));
+        }
+
+        copy.clear();
+        copy.putAll(original);
+
+        // a property should be added
+        overload = new HashMap<String, Object>();
+        overload.put("new", "prop");
+
+        RemoteServiceAdminCore.overlayProperties(copy, overload);
+
+        assertEquals(original.size() + 1, copy.size());
+        for (Object key : original.keySet()) {
+            assertEquals(original.get(key), copy.get(key));
+        }
+        assertNotNull(overload.get("new"));
+        assertEquals("prop", overload.get("new"));
+
+        copy.clear();
+        copy.putAll(original);
+
+        // only one property should be added
+        overload = new HashMap<String, Object>();
+        overload.put("new", "prop");
+        overload.put("NEW", "prop");
+
+        RemoteServiceAdminCore.overlayProperties(copy, overload);
+
+        assertEquals(original.size() + 1, copy.size());
+        for (Object key : original.keySet()) {
+            assertEquals(original.get(key), copy.get(key));
+        }
+        assertNotNull(overload.get("new"));
+        assertEquals("prop", overload.get("new"));
+
+        copy.clear();
+        copy.putAll(original);
+
+        // nothing should change here
+        overload = new HashMap<String, Object>();
+        overload.put(Constants.OBJECTCLASS, "assd");
+        overload.put(Constants.SERVICE_ID, "asasdasd");
+        RemoteServiceAdminCore.overlayProperties(copy, overload);
+
+        assertEquals(original.size(), copy.size());
+        for (Object key : original.keySet()) {
+            assertEquals(original.get(key), copy.get(key));
+        }
+
+        copy.clear();
+        copy.putAll(original);
+
+        // overwrite own prop
+        overload = new HashMap<String, Object>();
+        overload.put("MyProp", "newValue");
+        RemoteServiceAdminCore.overlayProperties(copy, overload);
+
+        assertEquals(original.size(), copy.size());
+        for (Object key : original.keySet()) {
+            if (!"MyProp".equals(key)) {
+                assertEquals(original.get(key), copy.get(key));
+            }
+        }
+        assertEquals("newValue", copy.get("MyProp"));
+
+        copy.clear();
+        copy.putAll(original);
+
+        // overwrite own prop in different case
+        overload = new HashMap<String, Object>();
+        overload.put("MYPROP", "newValue");
+        RemoteServiceAdminCore.overlayProperties(copy, overload);
+
+        assertEquals(original.size(), copy.size());
+        for (Object key : original.keySet()) {
+            if (!"MyProp".equals(key)) {
+                assertEquals(original.get(key), copy.get(key));
+            }
+        }
+        assertEquals("newValue", copy.get("MyProp"));
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/4ed2614d/dsw/cxf-dosgi-rsa/src/test/java/org/apache/cxf/dosgi/dsw/service/StringPlusTest.java
----------------------------------------------------------------------
diff --git a/dsw/cxf-dosgi-rsa/src/test/java/org/apache/cxf/dosgi/dsw/service/StringPlusTest.java b/dsw/cxf-dosgi-rsa/src/test/java/org/apache/cxf/dosgi/dsw/service/StringPlusTest.java
new file mode 100644
index 0000000..5447966
--- /dev/null
+++ b/dsw/cxf-dosgi-rsa/src/test/java/org/apache/cxf/dosgi/dsw/service/StringPlusTest.java
@@ -0,0 +1,63 @@
+/**
+ * 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.cxf.dosgi.dsw.service;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+public class StringPlusTest {
+
+    @Test
+    public void testSplitString() {
+        String[] values = StringPlus.normalize("1, 2");
+        assertEquals(2, values.length);
+        assertEquals(values[0], "1");
+        assertEquals(values[1], "2");
+    }
+
+    @Test
+    public void testNormalizeStringPlus() {
+        String s1 = "s1";
+        String s2 = "s2";
+        String s3 = "s3";
+
+        String[] sa = new String[] {
+            s1, s2, s3
+        };
+
+        Collection<Object> sl = new ArrayList<Object>(4);
+        sl.add(s1);
+        sl.add(s2);
+        sl.add(s3);
+        sl.add(new Object()); // must be skipped
+
+        assertArrayEquals(null, StringPlus.normalize(new Object()));
+        assertArrayEquals(new String[] {
+            s1
+        }, StringPlus.normalize(s1));
+        assertArrayEquals(sa, StringPlus.normalize(sa));
+        assertArrayEquals(sa, StringPlus.normalize(sl));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/4ed2614d/dsw/cxf-dsw/pom.xml
----------------------------------------------------------------------
diff --git a/dsw/cxf-dsw/pom.xml b/dsw/cxf-dsw/pom.xml
index 3693a23..44fdc98 100644
--- a/dsw/cxf-dsw/pom.xml
+++ b/dsw/cxf-dsw/pom.xml
@@ -22,8 +22,7 @@
     <modelVersion>4.0.0</modelVersion>
     <artifactId>cxf-dosgi-ri-dsw-cxf</artifactId>
     <packaging>bundle</packaging>
-    <name>CXF dOSGi Remote Service Admin Implementation</name>
-    <description>The CXF Remote Service Admin as described in the OSGi Remote Service Admin specification</description>
+    <name>CXF dOSGi Distribution provider</name>
 
     <parent>
         <groupId>org.apache.cxf.dosgi</groupId>
@@ -50,6 +49,12 @@
             <artifactId>org.osgi.compendium</artifactId>
         </dependency>
 
+
+        <dependency>
+            <groupId>org.apache.cxf.dosgi</groupId>
+            <artifactId>cxf-dosgi-provider-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
         <dependency>
             <groupId>org.apache.cxf</groupId>
             <artifactId>cxf-core</artifactId>
@@ -132,9 +137,6 @@
                             !*
                         </Export-Package>
                         <Bundle-Activator>org.apache.cxf.dosgi.dsw.Activator</Bundle-Activator>
-                        
-                        <!-- Is currently needed to create a proxy of an interface given in String form -->
-                        <DynamicImport-Package>*</DynamicImport-Package>
                     </instructions>
                 </configuration>
             </plugin>

http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/4ed2614d/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/Activator.java
----------------------------------------------------------------------
diff --git a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/Activator.java b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/Activator.java
index c2383aa..743e8f2 100644
--- a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/Activator.java
+++ b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/Activator.java
@@ -34,8 +34,6 @@ import org.apache.cxf.dosgi.dsw.qos.IntentManager;
 import org.apache.cxf.dosgi.dsw.qos.IntentManagerImpl;
 import org.apache.cxf.dosgi.dsw.qos.IntentMap;
 import org.apache.cxf.dosgi.dsw.qos.IntentTracker;
-import org.apache.cxf.dosgi.dsw.service.RemoteServiceAdminCore;
-import org.apache.cxf.dosgi.dsw.service.RemoteServiceadminFactory;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleListener;
@@ -43,7 +41,6 @@ import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceRegistration;
 import org.osgi.service.cm.ConfigurationException;
 import org.osgi.service.cm.ManagedService;
-import org.osgi.service.remoteserviceadmin.RemoteServiceAdmin;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -89,14 +86,11 @@ public class Activator implements ManagedService, BundleActivator {
         httpServiceManager = new HttpServiceManager(bc, httpBase, cxfServletAlias);
         DistributionProvider cxfProvider
             = new CXFDistributionProvider(bc, intentManager, httpServiceManager);
-        RemoteServiceAdminCore rsaCore = new RemoteServiceAdminCore(bc, cxfProvider);
-        RemoteServiceadminFactory rsaf = new RemoteServiceadminFactory(rsaCore);
         Dictionary<String, Object> props = new Hashtable<String, Object>();
         String[] supportedIntents = intentMap.keySet().toArray(new String[] {});
         props.put("remote.intents.supported", supportedIntents);
         props.put("remote.configs.supported", cxfProvider.getSupportedTypes());
-        LOG.info("Registering RemoteServiceAdminFactory...");
-        rsaFactoryReg = bc.registerService(RemoteServiceAdmin.class.getName(), rsaf, props);
+        rsaFactoryReg = bc.registerService(DistributionProvider.class.getName(), cxfProvider, props);
         ServiceDecoratorImpl serviceDecorator = new ServiceDecoratorImpl();
         bundleListener = new ServiceDecoratorBundleListener(serviceDecorator);
         bc.addBundleListener(bundleListener);

http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/4ed2614d/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/api/DistributionProvider.java
----------------------------------------------------------------------
diff --git a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/api/DistributionProvider.java b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/api/DistributionProvider.java
deleted file mode 100644
index c7328db..0000000
--- a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/api/DistributionProvider.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/**
- * 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.cxf.dosgi.dsw.api;
-
-import java.util.Map;
-
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.remoteserviceadmin.EndpointDescription;
-
-@SuppressWarnings("rawtypes")
-public interface DistributionProvider {
-
-    String[] getSupportedTypes();
-
-    /**
-     * @param sref reference of the service to be exported
-     * @param effectiveProperties combined properties of the service and additional properties from rsa
-     * @param exportedInterface name of the interface to be exported
-     * @return closeable Endpoint that represents the service that is exposed to the outside world
-     */
-    Endpoint exportService(ServiceReference<?> sref, 
-                           Map<String, Object> effectiveProperties,
-                           Class[] exportedInterfaces);
-
-    /**
-     * @param sref reference of the service offered to the requesting bundle
-     * @param interfaces interfaces of the service to proxy
-     * @param endpoint description of the remote endpoint
-     * @return service proxy to be given to the requesting bundle
-     * @throws IntentUnsatisfiedException
-     */
-    Object importEndpoint(BundleContext consumerContext, 
-                          Class[] interfaces, 
-                          EndpointDescription endpoint)
-        throws IntentUnsatisfiedException;
-    
-}

http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/4ed2614d/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/api/Endpoint.java
----------------------------------------------------------------------
diff --git a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/api/Endpoint.java b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/api/Endpoint.java
deleted file mode 100644
index f45b562..0000000
--- a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/api/Endpoint.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * 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.cxf.dosgi.dsw.api;
-
-import java.io.Closeable;
-
-import org.osgi.service.remoteserviceadmin.EndpointDescription;
-
-public interface Endpoint extends Closeable {
-    EndpointDescription description();
-}

http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/4ed2614d/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/api/IntentUnsatisfiedException.java
----------------------------------------------------------------------
diff --git a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/api/IntentUnsatisfiedException.java b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/api/IntentUnsatisfiedException.java
deleted file mode 100644
index 4e27938..0000000
--- a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/api/IntentUnsatisfiedException.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * 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.cxf.dosgi.dsw.api;
-
-public class IntentUnsatisfiedException extends RuntimeException {
-
-    private static final long serialVersionUID = 1L;
-
-    private final String intent;
-
-    public IntentUnsatisfiedException(String intent) {
-        super(intent);
-        this.intent = intent;
-    }
-
-    public String getIntent() {
-        return intent;
-    }
-}

http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/4ed2614d/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/ClientServiceFactory.java
----------------------------------------------------------------------
diff --git a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/ClientServiceFactory.java b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/ClientServiceFactory.java
deleted file mode 100644
index b482b64..0000000
--- a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/ClientServiceFactory.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/**
- * 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.cxf.dosgi.dsw.service;
-
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import org.apache.cxf.dosgi.dsw.api.DistributionProvider;
-import org.apache.cxf.dosgi.dsw.api.IntentUnsatisfiedException;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.ServiceFactory;
-import org.osgi.framework.ServiceRegistration;
-import org.osgi.service.remoteserviceadmin.EndpointDescription;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@SuppressWarnings("rawtypes")
-public class ClientServiceFactory implements ServiceFactory {
-
-    private static final Logger LOG = LoggerFactory.getLogger(ClientServiceFactory.class);
-
-    private EndpointDescription endpoint;
-    private DistributionProvider handler;
-    private ImportRegistrationImpl importRegistration;
-
-    private boolean closeable;
-    private int serviceCounter;
-
-    public ClientServiceFactory(EndpointDescription endpoint,
-                                DistributionProvider handler, ImportRegistrationImpl ir) {
-        this.endpoint = endpoint;
-        this.handler = handler;
-        this.importRegistration = ir;
-    }
-
-    public Object getService(final Bundle requestingBundle, final ServiceRegistration sreg) {
-        List<String> interfaceNames = endpoint.getInterfaces();
-        try {
-            LOG.debug("getService() from serviceFactory for {}", interfaceNames);
-            final List<Class<?>> interfaces = new ArrayList<Class<?>>();
-            for (String ifaceName : interfaceNames) {
-                interfaces.add(requestingBundle.loadClass(ifaceName));
-            }
-            Object proxy = AccessController.doPrivileged(new PrivilegedAction<Object>() {
-                public Object run() {
-                    Class<?>[] ifAr = interfaces.toArray(new Class[]{});
-                    return handler.importEndpoint(requestingBundle.getBundleContext(), ifAr, endpoint);
-                }
-            });
-
-            synchronized (this) {
-                serviceCounter++;
-            }
-            return proxy;
-        } catch (IntentUnsatisfiedException iue) {
-            LOG.info("Did not create proxy for {} because intent {} could not be satisfied",
-                    interfaceNames, iue.getIntent());
-        } catch (Exception e) {
-            LOG.warn("Problem creating a remote proxy for {}", interfaceNames, e);
-        }
-        return null;
-    }
-
-    public void ungetService(Bundle requestingBundle, ServiceRegistration sreg, Object serviceObject) {
-        String[] interfaces = (String[])sreg.getReference().getProperty(org.osgi.framework.Constants.OBJECTCLASS);
-        LOG.info("Releasing a client object, interfaces: {}", Arrays.toString(interfaces));
-
-        synchronized (this) {
-            serviceCounter--;
-            LOG.debug("Services still provided by this ServiceFactory: {}", serviceCounter);
-            closeIfUnused();
-        }
-    }
-
-    public void setCloseable(boolean closeable) {
-        synchronized (this) {
-            this.closeable = closeable;
-            closeIfUnused();
-        }
-    }
-
-    private synchronized void closeIfUnused() {
-        if (serviceCounter <= 0 && closeable) {
-            importRegistration.closeAll();
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/4ed2614d/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/EventAdminHelper.java
----------------------------------------------------------------------
diff --git a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/EventAdminHelper.java b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/EventAdminHelper.java
deleted file mode 100644
index 4868efa..0000000
--- a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/EventAdminHelper.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/**
- * 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.cxf.dosgi.dsw.service;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.Version;
-import org.osgi.service.event.Event;
-import org.osgi.service.event.EventAdmin;
-import org.osgi.service.remoteserviceadmin.EndpointDescription;
-import org.osgi.service.remoteserviceadmin.RemoteServiceAdminEvent;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class EventAdminHelper {
-
-    private static final Logger LOG = LoggerFactory.getLogger(EventAdminHelper.class);
-
-    private BundleContext bctx;
-
-    public EventAdminHelper(BundleContext bc) {
-        bctx = bc;
-    }
-
-    private Event createEvent(Map<String, Object> props, String type) {
-        String topic = "org/osgi/service/remoteserviceadmin/" + type;
-        props.put("bundle", bctx.getBundle());
-        props.put("bundle.id", bctx.getBundle().getBundleId());
-        props.put("bundle.symbolicname", bctx.getBundle().getSymbolicName());
-
-        String version = (String)bctx.getBundle().getHeaders().get("Bundle-Version");
-        Version v = version != null ? new Version(version) : Version.emptyVersion;
-        setIfNotNull(props, "bundle.version", v);
-
-        return new Event(topic, props);
-    }
-
-    public void notifyEventAdmin(RemoteServiceAdminEvent rsae) {
-        String topic = remoteServiceAdminEventTypeToString(rsae.getType());
-
-        Map<String, Object> props = new HashMap<String, Object>();
-        setIfNotNull(props, "cause", rsae.getException());
-
-        EndpointDescription endpoint = null;
-        if (rsae.getImportReference() != null) {
-            endpoint = ((ImportRegistrationImpl)rsae.getImportReference()).getImportedEndpointAlways();
-            setIfNotNull(props, "import.registration", endpoint);
-        } else if (rsae.getExportReference() != null) {
-            endpoint = rsae.getExportReference().getExportedEndpoint();
-            setIfNotNull(props, "export.registration", endpoint);
-        }
-
-        if (endpoint != null) {
-            setIfNotNull(props, "service.remote.id", endpoint.getServiceId());
-            setIfNotNull(props, "service.remote.uuid", endpoint.getFrameworkUUID());
-            setIfNotNull(props, "service.remote.uri", endpoint.getId());
-            setIfNotNull(props, "objectClass", endpoint.getInterfaces().toArray());
-            setIfNotNull(props, "service.imported.configs", endpoint.getConfigurationTypes());
-        }
-        props.put("timestamp", System.currentTimeMillis());
-        props.put("event", rsae);
-
-        Event event = createEvent(props, topic);
-        notifyEventAdmins(topic, event);
-    }
-
-    @SuppressWarnings({
-     "rawtypes", "unchecked"
-    })
-    private void notifyEventAdmins(String topic, Event event) {
-        ServiceReference[] refs = null;
-        try {
-            refs = bctx.getAllServiceReferences(EventAdmin.class.getName(), null);
-        } catch (InvalidSyntaxException e) {
-            LOG.error("Failed to get EventAdmin: " + e.getMessage(), e);
-        }
-
-        if (refs != null) {
-            LOG.debug("Publishing event to {} EventAdmins; Topic:[{}]", refs.length, topic);
-            for (ServiceReference serviceReference : refs) {
-                EventAdmin eventAdmin = (EventAdmin) bctx.getService(serviceReference);
-                try {
-                    eventAdmin.postEvent(event);
-                } finally {
-                    if (eventAdmin != null) {
-                        bctx.ungetService(serviceReference);
-                    }
-                }
-            }
-        }
-    }
-
-    private <K, V> void setIfNotNull(Map<K, V> map, K key, V val) {
-        if (val != null) {
-            map.put(key, val);
-        }
-    }
-
-    private static String remoteServiceAdminEventTypeToString(int type) {
-        String retval;
-        switch (type) {
-        case RemoteServiceAdminEvent.EXPORT_ERROR:
-            retval = "EXPORT_ERROR";
-            break;
-        case RemoteServiceAdminEvent.EXPORT_REGISTRATION:
-            retval = "EXPORT_REGISTRATION";
-            break;
-        case RemoteServiceAdminEvent.EXPORT_UNREGISTRATION:
-            retval = "EXPORT_UNREGISTRATION";
-            break;
-        case RemoteServiceAdminEvent.EXPORT_WARNING:
-            retval = "EXPORT_WARNING";
-            break;
-        case RemoteServiceAdminEvent.IMPORT_ERROR:
-            retval = "IMPORT_ERROR";
-            break;
-        case RemoteServiceAdminEvent.IMPORT_REGISTRATION:
-            retval = "IMPORT_REGISTRATION";
-            break;
-        case RemoteServiceAdminEvent.IMPORT_UNREGISTRATION:
-            retval = "IMPORT_UNREGISTRATION";
-            break;
-        case RemoteServiceAdminEvent.IMPORT_WARNING:
-            retval = "IMPORT_WARNING";
-            break;
-        default:
-            retval = "UNKNOWN_EVENT";
-        }
-        return retval;
-    }
-}

http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/4ed2614d/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/EventProducer.java
----------------------------------------------------------------------
diff --git a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/EventProducer.java b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/EventProducer.java
deleted file mode 100644
index 26a46ab..0000000
--- a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/EventProducer.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/**
- * 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.cxf.dosgi.dsw.service;
-
-import java.util.List;
-
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.remoteserviceadmin.ExportRegistration;
-import org.osgi.service.remoteserviceadmin.ImportRegistration;
-import org.osgi.service.remoteserviceadmin.RemoteServiceAdminEvent;
-import org.osgi.service.remoteserviceadmin.RemoteServiceAdminListener;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class EventProducer {
-
-    private static final Logger LOG = LoggerFactory.getLogger(EventProducer.class);
-    private final BundleContext bctx;
-    private final EventAdminHelper eaHelper;
-
-    public EventProducer(BundleContext bc) {
-        bctx = bc;
-        eaHelper = new EventAdminHelper(bctx);
-    }
-
-    protected void publishNotification(List<ExportRegistration> erl) {
-        for (ExportRegistration exportRegistration : erl) {
-            publishNotification(exportRegistration);
-        }
-    }
-
-    protected void publishNotification(ExportRegistration er) {
-        int type = er.getException() == null
-            ? RemoteServiceAdminEvent.EXPORT_REGISTRATION
-            : RemoteServiceAdminEvent.EXPORT_ERROR;
-        notify(type, null, er);
-    }
-
-    protected void publishNotification(ImportRegistration ir) {
-        int type = ir.getException() == null
-            ? RemoteServiceAdminEvent.IMPORT_REGISTRATION
-            : RemoteServiceAdminEvent.IMPORT_ERROR;
-        notify(type, ir, null);
-    }
-
-    public void notifyRemoval(ExportRegistration er) {
-        notify(RemoteServiceAdminEvent.EXPORT_UNREGISTRATION, null, er);
-    }
-
-    public void notifyRemoval(ImportRegistration ir) {
-        notify(RemoteServiceAdminEvent.IMPORT_UNREGISTRATION, ir, null);
-    }
-
-    // only one of ir or er must be set, and the other must be null
-    private void notify(int type, ImportRegistration ir, ExportRegistration er) {
-        try {
-            RemoteServiceAdminEvent event = ir != null
-                ? new RemoteServiceAdminEvent(type, bctx.getBundle(), ir.getImportReference(), ir.getException())
-                : new RemoteServiceAdminEvent(type, bctx.getBundle(), er.getExportReference(), er.getException());
-            notifyListeners(event);
-            eaHelper.notifyEventAdmin(event);
-        } catch (IllegalStateException ise) {
-            LOG.debug("can't send notifications since bundle context is no longer valid");
-        }
-    }
-
-    @SuppressWarnings({
-     "rawtypes", "unchecked"
-    })
-    private void notifyListeners(RemoteServiceAdminEvent rsae) {
-        try {
-            ServiceReference[] listenerRefs = bctx.getServiceReferences(
-                    RemoteServiceAdminListener.class.getName(), null);
-            if (listenerRefs != null) {
-                for (ServiceReference sref : listenerRefs) {
-                    RemoteServiceAdminListener rsal = (RemoteServiceAdminListener)bctx.getService(sref);
-                    if (rsal != null) {
-                        try {
-                            Bundle bundle = sref.getBundle();
-                            if (bundle != null) {
-                                LOG.debug("notify RemoteServiceAdminListener {} of bundle {}",
-                                        rsal, bundle.getSymbolicName());
-                                rsal.remoteAdminEvent(rsae);
-                            }
-                        } finally {
-                            bctx.ungetService(sref);
-                        }
-                    }
-                }
-            }
-        } catch (InvalidSyntaxException e) {
-            LOG.error(e.getMessage(), e);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/4ed2614d/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/ExportReferenceImpl.java
----------------------------------------------------------------------
diff --git a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/ExportReferenceImpl.java b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/ExportReferenceImpl.java
deleted file mode 100644
index 497aa9c..0000000
--- a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/ExportReferenceImpl.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/**
- * 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.cxf.dosgi.dsw.service;
-
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.remoteserviceadmin.EndpointDescription;
-import org.osgi.service.remoteserviceadmin.ExportReference;
-
-@SuppressWarnings("rawtypes")
-public class ExportReferenceImpl implements ExportReference {
-
-    private ServiceReference serviceReference;
-    private EndpointDescription endpoint;
-
-    public ExportReferenceImpl(ServiceReference serviceReference, EndpointDescription endpoint) {
-        this.serviceReference = serviceReference;
-        this.endpoint = endpoint;
-    }
-
-    public ExportReferenceImpl(ExportReference exportReference) {
-        this(exportReference.getExportedService(), exportReference.getExportedEndpoint());
-    }
-
-    public EndpointDescription getExportedEndpoint() {
-        return endpoint;
-    }
-
-    public ServiceReference getExportedService() {
-        return serviceReference;
-    }
-
-    @Override
-    public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + (endpoint == null ? 0 : endpoint.hashCode());
-        result = prime * result + (serviceReference == null ? 0 : serviceReference.hashCode());
-        return result;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj == null || getClass() != obj.getClass()) {
-            return false;
-        }
-        ExportReferenceImpl other = (ExportReferenceImpl) obj;
-        boolean ed = endpoint == null ? other.endpoint == null
-                : endpoint.equals(other.endpoint);
-        boolean sr = serviceReference == null ? other.serviceReference == null
-                : serviceReference.equals(other.serviceReference);
-        return ed && sr;
-    }
-
-    synchronized void close() {
-        this.endpoint = null;
-        this.serviceReference = null;
-    }
-}

http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/4ed2614d/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/ExportRegistrationImpl.java
----------------------------------------------------------------------
diff --git a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/ExportRegistrationImpl.java b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/ExportRegistrationImpl.java
deleted file mode 100644
index d80bd40..0000000
--- a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/ExportRegistrationImpl.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/**
- * 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.cxf.dosgi.dsw.service;
-
-import java.io.Closeable;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.cxf.dosgi.dsw.api.Endpoint;
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.remoteserviceadmin.EndpointDescription;
-import org.osgi.service.remoteserviceadmin.ExportReference;
-import org.osgi.service.remoteserviceadmin.ExportRegistration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@SuppressWarnings("rawtypes")
-public class ExportRegistrationImpl implements ExportRegistration {
-
-    private static final Logger LOG = LoggerFactory.getLogger(ExportRegistrationImpl.class);
-
-    private final RemoteServiceAdminCore rsaCore;
-    private final ExportReferenceImpl exportReference;
-    private final Closeable server;
-    private final Throwable exception;
-
-    private final ExportRegistrationImpl parent;
-    private int instanceCount;
-    private volatile boolean closed;
-
-    private ExportRegistrationImpl(ExportRegistrationImpl parent, RemoteServiceAdminCore rsaCore,
-            ExportReferenceImpl exportReference, Closeable server, Throwable exception) {
-        this.parent = parent != null ? parent.parent : this; // a parent points to itself
-        this.parent.addInstance();
-        this.rsaCore = rsaCore;
-        this.exportReference = exportReference;
-        this.server = server;
-        this.exception = exception;
-    }
-
-    // create a clone of the provided ExportRegistrationImpl that is linked to it
-    public ExportRegistrationImpl(ExportRegistrationImpl parent) {
-        this(parent, parent.rsaCore, new ExportReferenceImpl(parent.exportReference),
-            parent.server, parent.exception);
-    }
-
-    // create a new (parent) instance which was exported successfully with the given server
-    public ExportRegistrationImpl(ServiceReference sref, Endpoint endpoint, RemoteServiceAdminCore rsaCore) {
-        this(null, rsaCore, new ExportReferenceImpl(sref, endpoint.description()), endpoint, null);
-    }
-
-    // create a new (parent) instance which failed to be exported with the given exception
-    public ExportRegistrationImpl(RemoteServiceAdminCore rsaCore, Throwable exception) {
-        this(null, rsaCore, null, null, exception);
-    }
-
-    private void ensureParent() {
-        if (parent != this) {
-            throw new IllegalStateException("this method may only be called on the parent");
-        }
-    }
-
-    public ExportReference getExportReference() {
-        if (exportReference == null) {
-            throw new IllegalStateException(getException());
-        }
-        return closed ? null : exportReference;
-    }
-
-    public Throwable getException() {
-        return closed ? null : exception;
-    }
-
-    public final void close() {
-        synchronized (this) {
-            if (closed) {
-                return;
-            }
-            closed = true;
-        }
-
-        rsaCore.removeExportRegistration(this);
-        exportReference.close();
-        parent.removeInstance();
-    }
-
-    private void addInstance() {
-        ensureParent();
-        synchronized (this) {
-            instanceCount++;
-        }
-    }
-
-    private void removeInstance() {
-        ensureParent();
-        synchronized (this) {
-            instanceCount--;
-            if (instanceCount <= 0) {
-                LOG.debug("really closing ExportRegistration now!");
-
-                if (server != null) {
-                    try {
-                        server.close();
-                    } catch (IOException e) {
-                        LOG.warn("Error closing ExportRegistration", e);
-                    }
-                }
-            }
-        }
-    }
-
-    @Override
-    public String toString() {
-        if (closed) {
-            return "ExportRegistration closed";
-        }
-        EndpointDescription endpoint = getExportReference().getExportedEndpoint();
-        ServiceReference serviceReference = getExportReference().getExportedService();
-        String r = "EndpointDescription for ServiceReference " + serviceReference;
-
-        r += "\n*** EndpointDescription: ****\n";
-        if (endpoint == null) {
-            r += "---> NULL <---- \n";
-        } else {
-            Set<Map.Entry<String, Object>> props = endpoint.getProperties().entrySet();
-            for (Map.Entry<String, Object> entry : props) {
-                Object value = entry.getValue();
-                r += entry.getKey() + " => "
-                    + (value instanceof Object[] ? Arrays.toString((Object[]) value) : value) + "\n";
-            }
-        }
-        return r;
-    }
-}


Mime
View raw message