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 2016/03/11 20:43:47 UTC
[48/50] [abbrv] aries-rsa git commit: Switching to aries package names
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/5f4c6604/discovery/zookeeper/src/main/java/org/apache/cxf/dosgi/discovery/zookeeper/util/Utils.java
----------------------------------------------------------------------
diff --git a/discovery/zookeeper/src/main/java/org/apache/cxf/dosgi/discovery/zookeeper/util/Utils.java b/discovery/zookeeper/src/main/java/org/apache/cxf/dosgi/discovery/zookeeper/util/Utils.java
index 5fcb111..62f2268 100644
--- a/discovery/zookeeper/src/main/java/org/apache/cxf/dosgi/discovery/zookeeper/util/Utils.java
+++ b/discovery/zookeeper/src/main/java/org/apache/cxf/dosgi/discovery/zookeeper/util/Utils.java
@@ -18,16 +18,17 @@
*/
package org.apache.cxf.dosgi.discovery.zookeeper.util;
-import java.util.Arrays;
-import java.util.Collection;
+import java.util.ArrayList;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import org.apache.aries.rsa.util.StringPlus;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.service.remoteserviceadmin.EndpointListener;
@@ -46,54 +47,24 @@ public final class Utils {
}
/**
- * Returns the value of a "string+" property as an array of strings.
- * <p>
- * A "string+" property can have a value which is either a string,
- * an array of strings, or a collection of strings.
- * <p>
- * If the given value is not of one of the valid types, or is null,
- * an empty array is returned.
- *
- * @param property a "string+" property value
- * @return the property value as an array of strings, or an empty array
- */
- public static String[] getStringPlusProperty(Object property) {
- if (property instanceof String) {
- return new String[] {(String)property};
- } else if (property instanceof String[]) {
- return (String[])property;
- } else if (property instanceof Collection) {
- try {
- @SuppressWarnings("unchecked")
- Collection<String> strings = (Collection<String>)property;
- return strings.toArray(new String[strings.size()]);
- } catch (ArrayStoreException ase) {
- // ignore collections with wrong type
- }
- }
- return new String[0];
- }
-
- /**
* Removes nulls and empty strings from the given string array.
*
* @param strings an array of strings
* @return a new array containing the non-null and non-empty
* elements of the original array in the same order
*/
- public static String[] removeEmpty(String[] strings) {
- String[] result = new String[strings.length];
- int copied = 0;
+ public static List<String> removeEmpty(List<String> strings) {
+ List<String> result = new ArrayList<String>();
for (String s : strings) {
if (s != null && !s.isEmpty()) {
- result[copied++] = s;
+ result.add(s);
}
}
- return copied == result.length ? result : Arrays.copyOf(result, copied);
+ return result;
}
- public static String[] getScopes(ServiceReference<?> sref) {
- return removeEmpty(getStringPlusProperty(sref.getProperty(EndpointListener.ENDPOINT_LISTENER_SCOPE)));
+ public static List<String> getScopes(ServiceReference<?> sref) {
+ return removeEmpty(StringPlus.normalize(sref.getProperty(EndpointListener.ENDPOINT_LISTENER_SCOPE)));
}
// copied from the DSW OSGiUtils class
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/5f4c6604/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/publish/PublishingEndpointListenerFactoryTest.java
----------------------------------------------------------------------
diff --git a/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/publish/PublishingEndpointListenerFactoryTest.java b/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/publish/PublishingEndpointListenerFactoryTest.java
index e63b805..a8498fd 100644
--- a/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/publish/PublishingEndpointListenerFactoryTest.java
+++ b/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/publish/PublishingEndpointListenerFactoryTest.java
@@ -24,8 +24,8 @@ import java.util.List;
import junit.framework.TestCase;
import org.apache.zookeeper.ZooKeeper;
-import org.easymock.classextension.EasyMock;
-import org.easymock.classextension.IMocksControl;
+import org.easymock.EasyMock;
+import org.easymock.IMocksControl;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.remoteserviceadmin.EndpointListener;
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/5f4c6604/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/publish/PublishingEndpointListenerTest.java
----------------------------------------------------------------------
diff --git a/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/publish/PublishingEndpointListenerTest.java b/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/publish/PublishingEndpointListenerTest.java
index aa1b68e..31c2802 100644
--- a/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/publish/PublishingEndpointListenerTest.java
+++ b/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/publish/PublishingEndpointListenerTest.java
@@ -23,17 +23,15 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import junit.framework.TestCase;
-
-import org.apache.cxf.dosgi.endpointdesc.EndpointDescriptionParser;
-import org.apache.cxf.dosgi.endpointdesc.PropertiesMapper;
+import org.apache.aries.rsa.discovery.endpoint.EndpointDescriptionParser;
+import org.apache.aries.rsa.discovery.endpoint.PropertiesMapper;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;
+import org.easymock.EasyMock;
import org.easymock.IAnswer;
-import org.easymock.classextension.EasyMock;
-import org.easymock.classextension.IMocksControl;
+import org.easymock.IMocksControl;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.Filter;
@@ -45,6 +43,8 @@ import org.osgi.service.remoteserviceadmin.RemoteConstants;
import org.osgi.xmlns.rsa.v1_0.EndpointDescriptionType;
import org.osgi.xmlns.rsa.v1_0.PropertyType;
+import junit.framework.TestCase;
+
public class PublishingEndpointListenerTest extends TestCase {
public void testEndpointRemovalAdding() throws KeeperException, InterruptedException {
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/5f4c6604/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/subscribe/InterfaceMonitorManagerTest.java
----------------------------------------------------------------------
diff --git a/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/subscribe/InterfaceMonitorManagerTest.java b/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/subscribe/InterfaceMonitorManagerTest.java
index 7d6f67f..5e5cb63 100644
--- a/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/subscribe/InterfaceMonitorManagerTest.java
+++ b/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/subscribe/InterfaceMonitorManagerTest.java
@@ -24,9 +24,9 @@ import java.util.List;
import java.util.Map;
import org.apache.zookeeper.ZooKeeper;
+import org.easymock.EasyMock;
import org.easymock.IAnswer;
-import org.easymock.classextension.EasyMock;
-import org.easymock.classextension.IMocksControl;
+import org.easymock.IMocksControl;
import org.junit.Test;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/5f4c6604/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/subscribe/InterfaceMonitorTest.java
----------------------------------------------------------------------
diff --git a/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/subscribe/InterfaceMonitorTest.java b/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/subscribe/InterfaceMonitorTest.java
index 67afb16..044b360 100644
--- a/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/subscribe/InterfaceMonitorTest.java
+++ b/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/subscribe/InterfaceMonitorTest.java
@@ -29,8 +29,8 @@ import org.apache.zookeeper.Watcher.Event.EventType;
import org.apache.zookeeper.Watcher.Event.KeeperState;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;
-import org.easymock.classextension.EasyMock;
-import org.easymock.classextension.IMocksControl;
+import org.easymock.EasyMock;
+import org.easymock.IMocksControl;
import org.osgi.service.remoteserviceadmin.EndpointListener;
import static org.easymock.EasyMock.eq;
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/5f4c6604/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/util/UtilsTest.java
----------------------------------------------------------------------
diff --git a/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/util/UtilsTest.java b/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/util/UtilsTest.java
index 08c830c..de4d9af 100644
--- a/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/util/UtilsTest.java
+++ b/discovery/zookeeper/src/test/java/org/apache/cxf/dosgi/discovery/zookeeper/util/UtilsTest.java
@@ -18,15 +18,15 @@
*/
package org.apache.cxf.dosgi.discovery.zookeeper.util;
-import java.util.Arrays;
+import java.util.List;
-import junit.framework.TestCase;
-
-import org.easymock.classextension.EasyMock;
-import org.easymock.classextension.IMocksControl;
+import org.easymock.EasyMock;
+import org.easymock.IMocksControl;
import org.osgi.framework.ServiceReference;
import org.osgi.service.remoteserviceadmin.EndpointListener;
+import junit.framework.TestCase;
+
public class UtilsTest extends TestCase {
public void testGetZooKeeperPath() {
@@ -38,57 +38,6 @@ public class UtilsTest extends TestCase {
assertEquals(Utils.PATH_PREFIX, Utils.getZooKeeperPath(""));
}
- public void testGetStringPlusProperty() {
- String[] out = Utils.getStringPlusProperty("MyString");
- assertEquals(1, out.length);
- assertEquals("MyString", out[0]);
-
- out = Utils.getStringPlusProperty(new String[]{"MyString"});
- assertEquals(1, out.length);
- assertEquals("MyString", out[0]);
-
- out = Utils.getStringPlusProperty(Arrays.asList("MyString"));
- assertEquals(1, out.length);
- assertEquals("MyString", out[0]);
-
- out = Utils.getStringPlusProperty(Arrays.asList(1));
- assertEquals(0, out.length);
-
- out = Utils.getStringPlusProperty(new Object());
- assertEquals(0, out.length);
-
- out = Utils.getStringPlusProperty(null);
- assertEquals(0, out.length);
- }
-
- public void testRemoveEmpty() {
- String[] out = Utils.removeEmpty(new String[0]);
- assertEquals(0, out.length);
-
- out = Utils.removeEmpty(new String[]{null});
- assertEquals(0, out.length);
-
- out = Utils.removeEmpty(new String[]{""});
- assertEquals(0, out.length);
-
- out = Utils.removeEmpty(new String[]{"hi"});
- assertEquals(1, out.length);
- assertEquals("hi", out[0]);
-
- out = Utils.removeEmpty(new String[]{"", "hi", null});
- assertEquals(1, out.length);
- assertEquals("hi", out[0]);
-
- out = Utils.removeEmpty(new String[]{"hi", null, "", ""});
- assertEquals(1, out.length);
- assertEquals("hi", out[0]);
-
- out = Utils.removeEmpty(new String[]{"", "hi", null, "", "", "bye", null});
- assertEquals(2, out.length);
- assertEquals("hi", out[0]);
- assertEquals("bye", out[1]);
- }
-
public void testGetScopes() {
IMocksControl c = EasyMock.createNiceControl();
@@ -101,10 +50,10 @@ public class UtilsTest extends TestCase {
c.replay();
- String[] ret = Utils.getScopes(sref);
+ List<String> ret = Utils.getScopes(sref);
c.verify();
- assertEquals(1, ret.length);
- assertEquals(scopes[0], ret[0]);
+ assertEquals(1, ret.size());
+ assertEquals(scopes[0], ret.get(0));
}
}
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/5f4c6604/features/src/main/resources/features.xml
----------------------------------------------------------------------
diff --git a/features/src/main/resources/features.xml b/features/src/main/resources/features.xml
index fa14ba6..4470deb 100644
--- a/features/src/main/resources/features.xml
+++ b/features/src/main/resources/features.xml
@@ -3,6 +3,7 @@
<repository>mvn:org.apache.cxf.karaf/apache-cxf/${cxf.version}/xml/features</repository>
<feature name="aries-rsa-core" version="${project.version}">
+ <bundle>mvn:org.apache.aries.rsa/spi/${project.version}</bundle>
<bundle>mvn:org.apache.aries.rsa/core/${project.version}</bundle>
<bundle>mvn:org.apache.aries.rsa/topology-manager/${project.version}</bundle>
</feature>
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/5f4c6604/parent/pom.xml
----------------------------------------------------------------------
diff --git a/parent/pom.xml b/parent/pom.xml
index 256e06f..c30aa10 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -53,13 +53,6 @@
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
- <version>${slf4j.version}</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.aries.rsa</groupId>
- <artifactId>spi</artifactId>
- <version>${project.version}</version>
<scope>provided</scope>
</dependency>
@@ -108,6 +101,12 @@
<version>${slf4j.version}</version>
</dependency>
<dependency>
+ <groupId>org.apache.aries.rsa</groupId>
+ <artifactId>spi</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
@@ -131,14 +130,12 @@
<build>
<defaultGoal>install</defaultGoal>
-
-
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>${felix.plugin.version}</version>
+ <version>3.0.1</version>
<extensions>true</extensions>
</plugin>
<plugin>
@@ -168,10 +165,10 @@
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>3.0.1</version>
<extensions>true</extensions>
<configuration>
<instructions>
+ <Export-Package>!*</Export-Package>
<_include>-bnd.bnd</_include>
</instructions>
</configuration>
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/5f4c6604/provider/tcp/pom.xml
----------------------------------------------------------------------
diff --git a/provider/tcp/pom.xml b/provider/tcp/pom.xml
index 2edfb3b..e14a39b 100644
--- a/provider/tcp/pom.xml
+++ b/provider/tcp/pom.xml
@@ -19,9 +19,9 @@
<dependencies>
<dependency>
- <groupId>org.apache.cxf.dosgi</groupId>
- <artifactId>cxf-dosgi-ri-provider-api</artifactId>
- <version>${project.version}</version>
+ <groupId>org.apache.aries.rsa</groupId>
+ <artifactId>spi</artifactId>
+ <scope>provided</scope>
</dependency>
</dependencies>
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/5f4c6604/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/Activator.java
----------------------------------------------------------------------
diff --git a/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/Activator.java b/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/Activator.java
index 128c3d8..c26292a 100644
--- a/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/Activator.java
+++ b/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/Activator.java
@@ -21,7 +21,7 @@ package org.apache.aries.rsa.provider.tcp;
import java.util.Dictionary;
import java.util.Hashtable;
-import org.apache.cxf.dosgi.dsw.api.DistributionProvider;
+import org.apache.aries.rsa.spi.DistributionProvider;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.service.remoteserviceadmin.RemoteConstants;
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/5f4c6604/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/TCPProvider.java
----------------------------------------------------------------------
diff --git a/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/TCPProvider.java b/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/TCPProvider.java
index 07c5a05..c103abb 100644
--- a/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/TCPProvider.java
+++ b/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/TCPProvider.java
@@ -23,9 +23,9 @@ import java.lang.reflect.Proxy;
import java.net.URI;
import java.util.Map;
-import org.apache.cxf.dosgi.dsw.api.DistributionProvider;
-import org.apache.cxf.dosgi.dsw.api.Endpoint;
-import org.apache.cxf.dosgi.dsw.api.IntentUnsatisfiedException;
+import org.apache.aries.rsa.spi.DistributionProvider;
+import org.apache.aries.rsa.spi.Endpoint;
+import org.apache.aries.rsa.spi.IntentUnsatisfiedException;
import org.osgi.framework.BundleContext;
import org.osgi.service.remoteserviceadmin.EndpointDescription;
import org.osgi.service.remoteserviceadmin.RemoteConstants;
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/5f4c6604/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/TcpEndpoint.java
----------------------------------------------------------------------
diff --git a/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/TcpEndpoint.java b/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/TcpEndpoint.java
index 5bc9d7a..8f61e3c 100644
--- a/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/TcpEndpoint.java
+++ b/provider/tcp/src/main/java/org/apache/aries/rsa/provider/tcp/TcpEndpoint.java
@@ -21,7 +21,7 @@ package org.apache.aries.rsa.provider.tcp;
import java.io.IOException;
import java.util.Map;
-import org.apache.cxf.dosgi.dsw.api.Endpoint;
+import org.apache.aries.rsa.spi.Endpoint;
import org.osgi.service.remoteserviceadmin.EndpointDescription;
import org.osgi.service.remoteserviceadmin.RemoteConstants;
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/5f4c6604/provider/tcp/src/test/java/org/apache/aries/rsa/provider/tcp/TcpProviderTest.java
----------------------------------------------------------------------
diff --git a/provider/tcp/src/test/java/org/apache/aries/rsa/provider/tcp/TcpProviderTest.java b/provider/tcp/src/test/java/org/apache/aries/rsa/provider/tcp/TcpProviderTest.java
index 583c5e1..5d57c41 100644
--- a/provider/tcp/src/test/java/org/apache/aries/rsa/provider/tcp/TcpProviderTest.java
+++ b/provider/tcp/src/test/java/org/apache/aries/rsa/provider/tcp/TcpProviderTest.java
@@ -27,8 +27,8 @@ import java.util.concurrent.TimeUnit;
import org.apache.aries.rsa.provider.tcp.myservice.MyService;
import org.apache.aries.rsa.provider.tcp.myservice.MyServiceImpl;
-import org.apache.cxf.dosgi.dsw.api.Endpoint;
-import org.apache.cxf.dosgi.dsw.api.EndpointHelper;
+import org.apache.aries.rsa.spi.Endpoint;
+import org.apache.aries.rsa.util.EndpointHelper;
import org.easymock.EasyMock;
import org.junit.After;
import org.junit.Assert;
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/5f4c6604/rsa/bnd.bnd
----------------------------------------------------------------------
diff --git a/rsa/bnd.bnd b/rsa/bnd.bnd
index d32545d..1222aef 100644
--- a/rsa/bnd.bnd
+++ b/rsa/bnd.bnd
@@ -1,5 +1,3 @@
-Bundle-Activator: org.apache.cxf.dosgi.dsw.service.Activator
-Export-Package: \
- org.apache.cxf.dosgi.dsw.api,\
- org.apache.cxf.dosgi.dsw.service,\
- org.osgi.service.remoteserviceadmin
+Bundle-Activator: org.apache.aries.rsa.core.Activator
+Private-Package: org.apache.aries.rsa.core
+Export-Package: org.osgi.service.remoteserviceadmin
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/5f4c6604/rsa/pom.xml
----------------------------------------------------------------------
diff --git a/rsa/pom.xml b/rsa/pom.xml
index b220283..d2359c0 100644
--- a/rsa/pom.xml
+++ b/rsa/pom.xml
@@ -20,7 +20,7 @@
<dependency>
<groupId>org.apache.aries.rsa</groupId>
<artifactId>spi</artifactId>
- <version>${project.version}</version>
+ <scope>provided</scope>
</dependency>
</dependencies>
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/5f4c6604/rsa/src/main/java/org/apache/aries/rsa/core/Activator.java
----------------------------------------------------------------------
diff --git a/rsa/src/main/java/org/apache/aries/rsa/core/Activator.java b/rsa/src/main/java/org/apache/aries/rsa/core/Activator.java
new file mode 100644
index 0000000..cb347f4
--- /dev/null
+++ b/rsa/src/main/java/org/apache/aries/rsa/core/Activator.java
@@ -0,0 +1,37 @@
+/**
+ * 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.rsa.core;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+public class Activator implements BundleActivator {
+
+ private DistributionProviderTracker tracker;
+
+ public void start(BundleContext bundlecontext) throws Exception {
+ tracker = new DistributionProviderTracker(bundlecontext);
+ tracker.open();
+ }
+
+ public void stop(BundleContext context) throws Exception {
+ tracker.close();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/5f4c6604/rsa/src/main/java/org/apache/aries/rsa/core/ClientServiceFactory.java
----------------------------------------------------------------------
diff --git a/rsa/src/main/java/org/apache/aries/rsa/core/ClientServiceFactory.java b/rsa/src/main/java/org/apache/aries/rsa/core/ClientServiceFactory.java
new file mode 100644
index 0000000..54bbc54
--- /dev/null
+++ b/rsa/src/main/java/org/apache/aries/rsa/core/ClientServiceFactory.java
@@ -0,0 +1,110 @@
+/**
+ * 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.rsa.core;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.aries.rsa.spi.DistributionProvider;
+import org.apache.aries.rsa.spi.IntentUnsatisfiedException;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.wiring.BundleWiring;
+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();
+ final BundleContext consumerContext = requestingBundle.getBundleContext();
+ final ClassLoader consumerLoader = requestingBundle.adapt(BundleWiring.class).getClassLoader();
+ try {
+ LOG.debug("getService() from serviceFactory for {}", interfaceNames);
+ final List<Class<?>> interfaces = new ArrayList<Class<?>>();
+ for (String ifaceName : interfaceNames) {
+ interfaces.add(consumerLoader.loadClass(ifaceName));
+ }
+ Object proxy = AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ public Object run() {
+ Class<?>[] ifAr = interfaces.toArray(new Class[]{});
+ return handler.importEndpoint(consumerLoader, consumerContext, 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/aries-rsa/blob/5f4c6604/rsa/src/main/java/org/apache/aries/rsa/core/DistributionProviderTracker.java
----------------------------------------------------------------------
diff --git a/rsa/src/main/java/org/apache/aries/rsa/core/DistributionProviderTracker.java b/rsa/src/main/java/org/apache/aries/rsa/core/DistributionProviderTracker.java
new file mode 100644
index 0000000..4c3d36c
--- /dev/null
+++ b/rsa/src/main/java/org/apache/aries/rsa/core/DistributionProviderTracker.java
@@ -0,0 +1,73 @@
+/**
+ * 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.rsa.core;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import org.apache.aries.rsa.spi.DistributionProvider;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.remoteserviceadmin.RemoteServiceAdmin;
+import org.osgi.util.tracker.ServiceTracker;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@SuppressWarnings("rawtypes")
+public class DistributionProviderTracker extends ServiceTracker<DistributionProvider, ServiceRegistration> {
+ private static final Logger LOG = LoggerFactory.getLogger(Activator.class);
+
+ public DistributionProviderTracker(BundleContext context) {
+ super(context, DistributionProvider.class, null);
+ }
+
+ @Override
+ public ServiceRegistration addingService(ServiceReference<DistributionProvider> reference) {
+ LOG.debug("RemoteServiceAdmin Implementation is starting up");
+ DistributionProvider provider = context.getService(reference);
+ BundleContext apiContext = getAPIContext();
+ RemoteServiceAdminCore rsaCore = new RemoteServiceAdminCore(context,
+ apiContext,
+ provider);
+ RemoteServiceadminFactory rsaf = new RemoteServiceadminFactory(rsaCore);
+ Dictionary<String, Object> props = new Hashtable<String, Object>();
+ props.put("remote.intents.supported", reference.getProperty("remote.intents.supported"));
+ props.put("remote.configs.supported", reference.getProperty("remote.configs.supported"));
+ LOG.info("Registering RemoteServiceAdmin for provider " + provider.getClass().getName());
+ return context.registerService(RemoteServiceAdmin.class.getName(), rsaf, props);
+ }
+
+ protected BundleContext getAPIContext() {
+ Bundle apiBundle = FrameworkUtil.getBundle(DistributionProvider.class);
+ BundleContext apiContext = apiBundle.getBundleContext();
+ return apiContext;
+ }
+
+ @Override
+ public void removedService(ServiceReference<DistributionProvider> reference,
+ ServiceRegistration reg) {
+ LOG.debug("RemoteServiceAdmin Implementation is shutting down now");
+ reg.unregister();
+ super.removedService(reference, reg);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/5f4c6604/rsa/src/main/java/org/apache/aries/rsa/core/EventAdminHelper.java
----------------------------------------------------------------------
diff --git a/rsa/src/main/java/org/apache/aries/rsa/core/EventAdminHelper.java b/rsa/src/main/java/org/apache/aries/rsa/core/EventAdminHelper.java
new file mode 100644
index 0000000..e59c0ef
--- /dev/null
+++ b/rsa/src/main/java/org/apache/aries/rsa/core/EventAdminHelper.java
@@ -0,0 +1,151 @@
+/**
+ * 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.rsa.core;
+
+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/aries-rsa/blob/5f4c6604/rsa/src/main/java/org/apache/aries/rsa/core/EventProducer.java
----------------------------------------------------------------------
diff --git a/rsa/src/main/java/org/apache/aries/rsa/core/EventProducer.java b/rsa/src/main/java/org/apache/aries/rsa/core/EventProducer.java
new file mode 100644
index 0000000..4098201
--- /dev/null
+++ b/rsa/src/main/java/org/apache/aries/rsa/core/EventProducer.java
@@ -0,0 +1,114 @@
+/**
+ * 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.rsa.core;
+
+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/aries-rsa/blob/5f4c6604/rsa/src/main/java/org/apache/aries/rsa/core/ExportReferenceImpl.java
----------------------------------------------------------------------
diff --git a/rsa/src/main/java/org/apache/aries/rsa/core/ExportReferenceImpl.java b/rsa/src/main/java/org/apache/aries/rsa/core/ExportReferenceImpl.java
new file mode 100644
index 0000000..1366d56
--- /dev/null
+++ b/rsa/src/main/java/org/apache/aries/rsa/core/ExportReferenceImpl.java
@@ -0,0 +1,77 @@
+/**
+ * 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.rsa.core;
+
+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/aries-rsa/blob/5f4c6604/rsa/src/main/java/org/apache/aries/rsa/core/ExportRegistrationImpl.java
----------------------------------------------------------------------
diff --git a/rsa/src/main/java/org/apache/aries/rsa/core/ExportRegistrationImpl.java b/rsa/src/main/java/org/apache/aries/rsa/core/ExportRegistrationImpl.java
new file mode 100644
index 0000000..5a1dd66
--- /dev/null
+++ b/rsa/src/main/java/org/apache/aries/rsa/core/ExportRegistrationImpl.java
@@ -0,0 +1,152 @@
+/**
+ * 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.rsa.core;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.aries.rsa.spi.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;
+ }
+}
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/5f4c6604/rsa/src/main/java/org/apache/aries/rsa/core/ImportRegistrationImpl.java
----------------------------------------------------------------------
diff --git a/rsa/src/main/java/org/apache/aries/rsa/core/ImportRegistrationImpl.java b/rsa/src/main/java/org/apache/aries/rsa/core/ImportRegistrationImpl.java
new file mode 100644
index 0000000..680d2af
--- /dev/null
+++ b/rsa/src/main/java/org/apache/aries/rsa/core/ImportRegistrationImpl.java
@@ -0,0 +1,230 @@
+/**
+ * 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.rsa.core;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.remoteserviceadmin.EndpointDescription;
+import org.osgi.service.remoteserviceadmin.ImportReference;
+import org.osgi.service.remoteserviceadmin.ImportRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@SuppressWarnings("rawtypes")
+public class ImportRegistrationImpl implements ImportRegistration, ImportReference {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ImportRegistrationImpl.class);
+
+ private volatile Throwable exception;
+ private volatile ServiceRegistration importedService; // used only in parent
+ private EndpointDescription endpoint;
+ private volatile ClientServiceFactory clientServiceFactory;
+ private RemoteServiceAdminCore rsaCore;
+ private boolean closed;
+ private boolean detached; // used only in parent
+
+ private ImportRegistrationImpl parent;
+ private List<ImportRegistrationImpl> children; // used only in parent
+
+ public ImportRegistrationImpl(Throwable ex) {
+ exception = ex;
+ initParent();
+ }
+
+ public ImportRegistrationImpl(EndpointDescription endpoint, RemoteServiceAdminCore rsac) {
+ this.endpoint = endpoint;
+ this.rsaCore = rsac;
+ initParent();
+ }
+
+ /**
+ * Creates a clone of the given parent instance.
+ */
+ public ImportRegistrationImpl(ImportRegistrationImpl ir) {
+ // we always want a link to the parent...
+ parent = ir.getParent();
+ exception = parent.getException();
+ endpoint = parent.getImportedEndpointDescription();
+ clientServiceFactory = parent.clientServiceFactory;
+ rsaCore = parent.rsaCore;
+
+ parent.instanceAdded(this);
+ }
+
+ private void initParent() {
+ parent = this;
+ children = new ArrayList<ImportRegistrationImpl>(1);
+ }
+
+ private void ensureParent() {
+ if (parent != this) {
+ throw new IllegalStateException("this method may only be called on the parent");
+ }
+ }
+
+ /**
+ * Called on parent when a child is added.
+ *
+ * @param iri the child
+ */
+ private synchronized void instanceAdded(ImportRegistrationImpl iri) {
+ ensureParent();
+ children.add(iri);
+ }
+
+ /**
+ * Called on parent when a child is closed.
+ *
+ * @param iri the child
+ */
+ private void instanceClosed(ImportRegistrationImpl iri) {
+ ensureParent();
+ synchronized (this) {
+ children.remove(iri);
+ if (!children.isEmpty() || detached || !closed) {
+ return;
+ }
+ detached = true;
+ }
+
+ LOG.debug("really closing ImportRegistration now");
+
+ if (importedService != null) {
+ try {
+ importedService.unregister();
+ } catch (IllegalStateException ise) {
+ LOG.debug("imported service is already unregistered");
+ }
+ importedService = null;
+ }
+ if (clientServiceFactory != null) {
+ clientServiceFactory.setCloseable(true);
+ }
+ }
+
+ public void close() {
+ LOG.debug("close() called");
+
+ synchronized (this) {
+ if (isInvalid()) {
+ return;
+ }
+ closed = true;
+ }
+ rsaCore.removeImportRegistration(this);
+ parent.instanceClosed(this);
+ }
+
+ /**
+ * Closes all ImportRegistrations which share the same parent as this one.
+ */
+ public void closeAll() {
+ if (this == parent) {
+ LOG.info("closing down all child ImportRegistrations");
+
+ // we must iterate over a copy of children since close() removes the child
+ // from the list (which would cause a ConcurrentModificationException)
+ for (ImportRegistrationImpl ir : copyChildren()) {
+ ir.close();
+ }
+ this.close();
+ } else {
+ parent.closeAll();
+ }
+ }
+
+ private List<ImportRegistrationImpl> copyChildren() {
+ synchronized (this) {
+ return new ArrayList<ImportRegistrationImpl>(children);
+ }
+ }
+
+ public EndpointDescription getImportedEndpointDescription() {
+ return isInvalid() ? null : endpoint;
+ }
+
+ @Override
+ public EndpointDescription getImportedEndpoint() {
+ return getImportedEndpointDescription();
+ }
+
+ @Override
+ public ServiceReference getImportedService() {
+ return isInvalid() || parent.importedService == null ? null : parent.importedService.getReference();
+ }
+
+ @Override
+ public ImportReference getImportReference() {
+ return this;
+ }
+
+ @Override
+ public Throwable getException() {
+ return exception;
+ }
+
+ public void setException(Throwable ex) {
+ exception = ex;
+ }
+
+ private synchronized boolean isInvalid() {
+ return exception != null || closed;
+ }
+
+ /**
+ * Sets the {@link ServiceRegistration} representing the locally
+ * registered {@link ClientServiceFactory} service which provides
+ * proxies to the remote imported service. It is set only on the parent.
+ *
+ * @param sreg the ServiceRegistration
+ */
+ public void setImportedServiceRegistration(ServiceRegistration sreg) {
+ ensureParent();
+ importedService = sreg;
+ }
+
+ /**
+ * Sets the {@link ClientServiceFactory} which is the implementation
+ * of the locally registered service which provides proxies to the
+ * remote imported service. It is set only on the parent.
+ *
+ * @param csf the ClientServiceFactory
+ */
+ public void setClientServiceFactory(ClientServiceFactory csf) {
+ ensureParent();
+ clientServiceFactory = csf;
+ }
+
+ public ImportRegistrationImpl getParent() {
+ return parent;
+ }
+
+ /**
+ * Returns the imported endpoint even if this
+ * instance is closed or has an exception.
+ *
+ * @return the imported endpoint
+ */
+ public EndpointDescription getImportedEndpointAlways() {
+ return endpoint;
+ }
+}
http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/5f4c6604/rsa/src/main/java/org/apache/aries/rsa/core/PackageUtil.java
----------------------------------------------------------------------
diff --git a/rsa/src/main/java/org/apache/aries/rsa/core/PackageUtil.java b/rsa/src/main/java/org/apache/aries/rsa/core/PackageUtil.java
new file mode 100644
index 0000000..fe58bdf
--- /dev/null
+++ b/rsa/src/main/java/org/apache/aries/rsa/core/PackageUtil.java
@@ -0,0 +1,85 @@
+/**
+ * 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.rsa.core;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.packageadmin.ExportedPackage;
+import org.osgi.service.packageadmin.PackageAdmin;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@SuppressWarnings("deprecation")
+public final class PackageUtil {
+
+ public static final Logger LOG = LoggerFactory.getLogger(PackageUtil.class);
+
+ private PackageUtil() {
+ }
+
+ /**
+ * Tries to retrieve the version of iClass via the PackageAdmin.
+ *
+ * @param iClass tThe interface for which the version should be found
+ * @param bc any valid BundleContext
+ * @return the version of the interface or "0.0.0" if no version information could be found or an error
+ * occurred during the retrieval
+ */
+ public static String getVersion(Class<?> iClass, BundleContext bc) {
+ ServiceReference<PackageAdmin> paRef = bc.getServiceReference(PackageAdmin.class);
+ if (paRef != null) {
+ PackageAdmin pa = bc.getService(paRef);
+ try {
+ Bundle b = pa.getBundle(iClass);
+ if (b == null) {
+ LOG.info("Unable to find interface version for interface " + iClass.getName()
+ + ". Falling back to 0.0.0");
+ return "0.0.0";
+ }
+ LOG.debug("Interface source bundle: {}", b.getSymbolicName());
+
+ ExportedPackage[] ep = pa.getExportedPackages(b);
+ LOG.debug("Exported Packages of the source bundle: {}", (Object)ep);
+
+ String pack = iClass.getPackage().getName();
+ LOG.debug("Looking for Package: {}", pack);
+ if (ep != null) {
+ for (ExportedPackage p : ep) {
+ if (p != null
+ && pack.equals(p.getName())) {
+ LOG.debug("found package -> Version: {}", p.getVersion());
+ return p.getVersion().toString();
+ }
+ }
+ }
+ } finally {
+ if (pa != null) {
+ bc.ungetService(paRef);
+ }
+ }
+ } else {
+ LOG.error("Was unable to obtain the package admin service -> can't resolve interface versions");
+ }
+
+ LOG.info("Unable to find interface version for interface " + iClass.getName()
+ + ". Falling back to 0.0.0");
+ return "0.0.0";
+ }
+}