Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorslewis2014-08-05 19:21:45 +0000
committerslewis2014-08-05 19:21:45 +0000
commit153452c851d65cff3650baa1cb8b2f171bc32608 (patch)
tree72722461a644cb86d3316d7518bbb065c48f8e81
parent9b955309d8557a1553076e24114717b6ac16a746 (diff)
downloadorg.eclipse.ecf-153452c851d65cff3650baa1cb8b2f171bc32608.tar.gz
org.eclipse.ecf-153452c851d65cff3650baa1cb8b2f171bc32608.tar.xz
org.eclipse.ecf-153452c851d65cff3650baa1cb8b2f171bc32608.zip
Releasing RSA 1.1/R6 vesion of OSGi compendium classes with source code.
CQ: http://dev.eclipse.org/ipzilla/show_bug.cgi?id=8527 Change-Id: Icccc63680eed4ef30bf1da28ade0101d76ecd83a
-rw-r--r--osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/.classpath2
-rw-r--r--osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/META-INF/MANIFEST.MF5
-rw-r--r--osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/build.properties23
-rw-r--r--osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/bundle.properties4
-rw-r--r--osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/EndpointDescription$1.classbin1473 -> 0 bytes
-rw-r--r--osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/EndpointDescription$UnmodifiableDictionary.classbin2394 -> 0 bytes
-rw-r--r--osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/EndpointDescription.classbin11549 -> 0 bytes
-rw-r--r--osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/EndpointEvent.classbin923 -> 0 bytes
-rw-r--r--osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/EndpointEventListener.classbin368 -> 0 bytes
-rw-r--r--osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/EndpointListener.classbin497 -> 0 bytes
-rw-r--r--osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/EndpointPermission.classbin7466 -> 0 bytes
-rw-r--r--osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/EndpointPermissionCollection.classbin5440 -> 0 bytes
-rw-r--r--osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/ExportReference.classbin465 -> 0 bytes
-rw-r--r--osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/ExportRegistration.classbin613 -> 0 bytes
-rw-r--r--osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/ImportReference.classbin465 -> 0 bytes
-rw-r--r--osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/ImportRegistration.classbin481 -> 0 bytes
-rw-r--r--osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/RemoteConstants.classbin1280 -> 0 bytes
-rw-r--r--osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/RemoteServiceAdmin.classbin937 -> 0 bytes
-rw-r--r--osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/RemoteServiceAdminEvent.classbin2499 -> 0 bytes
-rw-r--r--osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/RemoteServiceAdminListener.classbin353 -> 0 bytes
-rw-r--r--osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/package-info.classbin247 -> 0 bytes
-rw-r--r--osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/osgi/osgi.annotation.jarbin0 -> 13199 bytes
-rw-r--r--osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/osgi/src.zipbin0 -> 36427 bytes
-rw-r--r--osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src.zipbin32293 -> 0 bytes
-rw-r--r--osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/EndpointDescription.java677
-rw-r--r--osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/EndpointEvent.java141
-rw-r--r--osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/EndpointEventListener.java108
-rw-r--r--osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/EndpointListener.java134
-rw-r--r--osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/EndpointPermission.java653
-rw-r--r--osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/ExportReference.java48
-rw-r--r--osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/ExportRegistration.java109
-rw-r--r--osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/ImportReference.java48
-rw-r--r--osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/ImportRegistration.java92
-rw-r--r--osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/RemoteConstants.java237
-rw-r--r--osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/RemoteServiceAdmin.java131
-rw-r--r--osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/RemoteServiceAdminEvent.java186
-rw-r--r--osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/RemoteServiceAdminListener.java46
-rw-r--r--osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/namespace/DiscoveryNamespace.java49
-rw-r--r--osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/namespace/DistributionNamespace.java49
-rw-r--r--osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/namespace/TopologyNamespace.java66
-rw-r--r--osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/namespace/package-info.java33
-rw-r--r--osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/namespace/packageinfo1
-rw-r--r--osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/package-info.java43
-rw-r--r--osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/packageinfo (renamed from osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/packageinfo)0
44 files changed, 2875 insertions, 10 deletions
diff --git a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/.classpath b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/.classpath
index 80407c8d4..304e86186 100644
--- a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/.classpath
+++ b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/.classpath
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
- <classpathentry path="" kind="lib" exported="true" sourcepath="src.zip"/>
+ <classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="output" path="bin"/>
diff --git a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/META-INF/MANIFEST.MF b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/META-INF/MANIFEST.MF
index e6f79b073..ec6666224 100644
--- a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/META-INF/MANIFEST.MF
+++ b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/META-INF/MANIFEST.MF
@@ -8,5 +8,6 @@ Bundle-RequiredExecutionEnvironment: J2SE-1.5
Bundle-Localization: bundle
Bundle-Description: %bundle.description
Bundle-Copyright: %bundle.copyright
-Export-Package: org.osgi.service.remoteserviceadmin;version="1.1"
-Import-Package: org.osgi.framework
+Export-Package: org.osgi.service.remoteserviceadmin;version="1.1.0",org.osgi.service.remoteserviceadmin.namespace;version="1.0.0"
+Import-Package: org.osgi.framework;version="[1.7,2)",org.osgi.resource;version="[1.0,2)"
+Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.5))"
diff --git a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/build.properties b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/build.properties
index 038305b5c..099a08adc 100644
--- a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/build.properties
+++ b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/build.properties
@@ -1,12 +1,25 @@
-bin.includes = bundle.properties,\
+############################################################################
+# Copyright (c) 2010 Composent Inc., and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+############################################################################
+bin.includes = .,\
+ bundle.properties,\
about.html,\
META-INF/,\
- org/,\
about_files/
-src.includes = src.zip,\
+src.includes = osgi/src.zip,\
about.html,\
about_files/,\
- org/,\
bundle.properties
-output.. = /
+output.. = bin/
+
+jars.extra.classpath = osgi/osgi.annotation.jar
+jars.compile.order = .
+source.. = src/
+jre.compilation.profile = JavaSE-1.6
+
\ No newline at end of file
diff --git a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/bundle.properties b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/bundle.properties
index 55e788211..a2d3e1c3f 100644
--- a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/bundle.properties
+++ b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/bundle.properties
@@ -6,7 +6,7 @@
# http://www.eclipse.org/legal/epl-v10.html
#
############################################################################
-bundle.name=OSGi R5 RemoteServiceAdmin API
+bundle.name=OSGi R6 RemoteServiceAdmin API
bundle.provider=Eclipse.org - ECF
-bundle.description=OSGi Service Platform Release 5.0 Remote Service Admin Service Interfaces and Classes
+bundle.description=OSGi Service Platform Release 6.0 Remote Service Admin Service Interfaces and Classes
bundle.copyright=Copyright (c) 2010 Composent Inc., and others. All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0 which accompanies this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html
diff --git a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/EndpointDescription$1.class b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/EndpointDescription$1.class
deleted file mode 100644
index 48d70a50c..000000000
--- a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/EndpointDescription$1.class
+++ /dev/null
Binary files differ
diff --git a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/EndpointDescription$UnmodifiableDictionary.class b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/EndpointDescription$UnmodifiableDictionary.class
deleted file mode 100644
index a3c0d898e..000000000
--- a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/EndpointDescription$UnmodifiableDictionary.class
+++ /dev/null
Binary files differ
diff --git a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/EndpointDescription.class b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/EndpointDescription.class
deleted file mode 100644
index 5978a3e97..000000000
--- a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/EndpointDescription.class
+++ /dev/null
Binary files differ
diff --git a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/EndpointEvent.class b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/EndpointEvent.class
deleted file mode 100644
index 8dde48adb..000000000
--- a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/EndpointEvent.class
+++ /dev/null
Binary files differ
diff --git a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/EndpointEventListener.class b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/EndpointEventListener.class
deleted file mode 100644
index f4e9c3c30..000000000
--- a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/EndpointEventListener.class
+++ /dev/null
Binary files differ
diff --git a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/EndpointListener.class b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/EndpointListener.class
deleted file mode 100644
index 83e2bacbf..000000000
--- a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/EndpointListener.class
+++ /dev/null
Binary files differ
diff --git a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/EndpointPermission.class b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/EndpointPermission.class
deleted file mode 100644
index 97c803f78..000000000
--- a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/EndpointPermission.class
+++ /dev/null
Binary files differ
diff --git a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/EndpointPermissionCollection.class b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/EndpointPermissionCollection.class
deleted file mode 100644
index 5ac10353b..000000000
--- a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/EndpointPermissionCollection.class
+++ /dev/null
Binary files differ
diff --git a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/ExportReference.class b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/ExportReference.class
deleted file mode 100644
index 0baf1813b..000000000
--- a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/ExportReference.class
+++ /dev/null
Binary files differ
diff --git a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/ExportRegistration.class b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/ExportRegistration.class
deleted file mode 100644
index 211d3db6d..000000000
--- a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/ExportRegistration.class
+++ /dev/null
Binary files differ
diff --git a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/ImportReference.class b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/ImportReference.class
deleted file mode 100644
index 85e5d44b8..000000000
--- a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/ImportReference.class
+++ /dev/null
Binary files differ
diff --git a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/ImportRegistration.class b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/ImportRegistration.class
deleted file mode 100644
index 60cf3e1af..000000000
--- a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/ImportRegistration.class
+++ /dev/null
Binary files differ
diff --git a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/RemoteConstants.class b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/RemoteConstants.class
deleted file mode 100644
index 2d5baeff4..000000000
--- a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/RemoteConstants.class
+++ /dev/null
Binary files differ
diff --git a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/RemoteServiceAdmin.class b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/RemoteServiceAdmin.class
deleted file mode 100644
index ff5bf744f..000000000
--- a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/RemoteServiceAdmin.class
+++ /dev/null
Binary files differ
diff --git a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/RemoteServiceAdminEvent.class b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/RemoteServiceAdminEvent.class
deleted file mode 100644
index db07c2e2f..000000000
--- a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/RemoteServiceAdminEvent.class
+++ /dev/null
Binary files differ
diff --git a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/RemoteServiceAdminListener.class b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/RemoteServiceAdminListener.class
deleted file mode 100644
index fac771d94..000000000
--- a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/RemoteServiceAdminListener.class
+++ /dev/null
Binary files differ
diff --git a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/package-info.class b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/package-info.class
deleted file mode 100644
index 80a859087..000000000
--- a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/package-info.class
+++ /dev/null
Binary files differ
diff --git a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/osgi/osgi.annotation.jar b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/osgi/osgi.annotation.jar
new file mode 100644
index 000000000..dda27d2fe
--- /dev/null
+++ b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/osgi/osgi.annotation.jar
Binary files differ
diff --git a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/osgi/src.zip b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/osgi/src.zip
new file mode 100644
index 000000000..3d6ab5a5c
--- /dev/null
+++ b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/osgi/src.zip
Binary files differ
diff --git a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src.zip b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src.zip
deleted file mode 100644
index d7207c94e..000000000
--- a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src.zip
+++ /dev/null
Binary files differ
diff --git a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/EndpointDescription.java b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/EndpointDescription.java
new file mode 100644
index 000000000..d0d7a8831
--- /dev/null
+++ b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/EndpointDescription.java
@@ -0,0 +1,677 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2013). All Rights Reserved.
+ *
+ * Licensed 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.osgi.service.remoteserviceadmin;
+
+import static org.osgi.service.remoteserviceadmin.RemoteConstants.*;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.Version;
+
+/**
+ * A description of an endpoint that provides sufficient information for a
+ * compatible distribution provider to create a connection to this endpoint
+ *
+ * An Endpoint Description is easy to transfer between different systems because
+ * it is property based where the property keys are strings and the values are
+ * simple types. This allows it to be used as a communications device to convey
+ * available endpoint information to nodes in a network.
+ *
+ * An Endpoint Description reflects the perspective of an <i>importer</i>. That
+ * is, the property keys have been chosen to match filters that are created by
+ * client bundles that need a service. Therefore the map must not contain any
+ * {@code service.exported.*} property and must contain the corresponding
+ * {@code service.imported.*} ones.
+ *
+ * The {@code service.intents} property must contain the intents provided by the
+ * service itself combined with the intents added by the exporting distribution
+ * provider. Qualified intents appear fully expanded on this property.
+ *
+ * @Immutable
+ * @author $Id$
+ */
+
+public class EndpointDescription {
+ private final Map<String, Object> properties;
+ private final List<String> interfaces;
+ private final long serviceId;
+ private final String frameworkUUID;
+ private final String id;
+
+ /**
+ * Create an Endpoint Description from a Map.
+ *
+ * <p>
+ * The {@link RemoteConstants#ENDPOINT_ID endpoint.id},
+ * {@link RemoteConstants#SERVICE_IMPORTED_CONFIGS service.imported.configs}
+ * and {@code objectClass} properties must be set.
+ *
+ * @param properties The map from which to create the Endpoint Description.
+ * The keys in the map must be type {@code String} and, since the
+ * keys are case insensitive, there must be no duplicates with case
+ * variation.
+ * @throws IllegalArgumentException When the properties are not proper for
+ * an Endpoint Description.
+ */
+
+ public EndpointDescription(Map<String, ?> properties) {
+ Map<String, Object> props = new TreeMap<String, Object>(String.CASE_INSENSITIVE_ORDER);
+ try {
+ props.putAll(properties);
+ } catch (ClassCastException e) {
+ IllegalArgumentException iae = new IllegalArgumentException("non-String key in properties");
+ iae.initCause(e);
+ throw iae;
+ }
+ if (props.size() < properties.size()) {
+ throw new IllegalArgumentException("duplicate keys with different cases in properties: " + new ArrayList<String>(props.keySet()).removeAll(properties.keySet()));
+ }
+
+ conditionProperties(props);
+ this.properties = Collections.unmodifiableMap(props);
+ /* properties must be initialized before calling the following methods */
+ interfaces = verifyObjectClassProperty();
+ serviceId = verifyLongProperty(ENDPOINT_SERVICE_ID);
+ frameworkUUID = verifyStringProperty(ENDPOINT_FRAMEWORK_UUID);
+ id = verifyStringProperty(ENDPOINT_ID).trim();
+ if (id == null) {
+ throw new IllegalArgumentException(ENDPOINT_ID + " property must be set");
+ }
+ if (getConfigurationTypes().isEmpty()) {
+ throw new IllegalArgumentException(SERVICE_IMPORTED_CONFIGS + " property must be set and non-empty");
+ }
+ }
+
+ /**
+ * Create an Endpoint Description based on a Service Reference and a Map of
+ * properties. The properties in the map take precedence over the properties
+ * in the Service Reference.
+ *
+ * <p>
+ * This method will automatically set the
+ * {@link RemoteConstants#ENDPOINT_FRAMEWORK_UUID endpoint.framework.uuid}
+ * and {@link RemoteConstants#ENDPOINT_SERVICE_ID endpoint.service.id}
+ * properties based on the specified Service Reference as well as the
+ * {@link RemoteConstants#SERVICE_IMPORTED service.imported} property if
+ * they are not specified as properties.
+ * <p>
+ * The {@link RemoteConstants#ENDPOINT_ID endpoint.id},
+ * {@link RemoteConstants#SERVICE_IMPORTED_CONFIGS service.imported.configs}
+ * and {@code objectClass} properties must be set.
+ *
+ * @param reference A service reference that can be exported.
+ * @param properties Map of properties. This argument can be {@code null}.
+ * The keys in the map must be type {@code String} and, since the
+ * keys are case insensitive, there must be no duplicates with case
+ * variation.
+ * @throws IllegalArgumentException When the properties are not proper for
+ * an Endpoint Description
+ */
+ public EndpointDescription(final ServiceReference<?> reference, final Map<String, ?> properties) {
+ Map<String, Object> props = new TreeMap<String, Object>(String.CASE_INSENSITIVE_ORDER);
+
+ if (properties != null) {
+ try {
+ props.putAll(properties);
+ } catch (ClassCastException e) {
+ IllegalArgumentException iae = new IllegalArgumentException("non-String key in properties");
+ iae.initCause(e);
+ throw iae;
+ }
+ if (props.size() < properties.size()) {
+ throw new IllegalArgumentException("duplicate keys with different cases in properties: " + new ArrayList<String>(props.keySet()).removeAll(properties.keySet()));
+ }
+ }
+
+ for (String key : reference.getPropertyKeys()) {
+ if (!props.containsKey(key)) {
+ props.put(key, reference.getProperty(key));
+ }
+ }
+
+ if (!props.containsKey(ENDPOINT_SERVICE_ID)) {
+ props.put(ENDPOINT_SERVICE_ID, reference.getProperty(Constants.SERVICE_ID));
+ }
+ if (!props.containsKey(ENDPOINT_FRAMEWORK_UUID)) {
+ String uuid = null;
+ try {
+ uuid = AccessController.doPrivileged(new PrivilegedAction<String>() {
+ public String run() {
+ return reference.getBundle().getBundleContext().getProperty("org.osgi.framework.uuid");
+ }
+ });
+ } catch (SecurityException e) {
+ // if we don't have permission, we can't get the property
+ }
+ if (uuid != null) {
+ props.put(ENDPOINT_FRAMEWORK_UUID, uuid);
+ }
+ }
+ conditionProperties(props);
+ this.properties = Collections.unmodifiableMap(props);
+ /* properties must be initialized before calling the following methods */
+ interfaces = verifyObjectClassProperty();
+ serviceId = verifyLongProperty(ENDPOINT_SERVICE_ID);
+ frameworkUUID = verifyStringProperty(ENDPOINT_FRAMEWORK_UUID);
+ id = verifyStringProperty(ENDPOINT_ID).trim();
+ if (id == null) {
+ throw new IllegalArgumentException(ENDPOINT_ID + " property must be set");
+ }
+ if (getConfigurationTypes().isEmpty()) {
+ throw new IllegalArgumentException(SERVICE_IMPORTED_CONFIGS + " property must be set and non-empty");
+ }
+ }
+
+ private static final String SERVICE_EXPORTED_ = "service.exported.";
+ private static final int SERVICE_EXPORTED_length = SERVICE_EXPORTED_.length();
+
+ /**
+ * Condition the properties.
+ *
+ * @param props Property map to condition.
+ */
+ private void conditionProperties(Map<String, Object> props) {
+ // ensure service.imported is set
+ if (!props.containsKey(SERVICE_IMPORTED)) {
+ props.put(SERVICE_IMPORTED, Boolean.toString(true));
+ }
+
+ // remove service.exported.* properties
+ for (Iterator<String> iter = props.keySet().iterator(); iter.hasNext();) {
+ String key = iter.next();
+ if (SERVICE_EXPORTED_.regionMatches(true, 0, key, 0, SERVICE_EXPORTED_length)) {
+ iter.remove();
+ }
+ }
+ }
+
+ /**
+ * Verify and obtain the interface list from the properties.
+ *
+ * @return A list with the interface names.
+ * @throws IllegalArgumentException If the objectClass property is not set
+ * or is empty or if the package version property values are
+ * malformed.
+ */
+ private List<String> verifyObjectClassProperty() {
+ Object o = properties.get(Constants.OBJECTCLASS);
+ if (!(o instanceof String[])) {
+ throw new IllegalArgumentException("objectClass value must be of type String[]");
+ }
+ String[] objectClass = (String[]) o;
+ if (objectClass.length < 1) {
+ throw new IllegalArgumentException("objectClass is empty");
+ }
+ for (String interf : objectClass) {
+ int index = interf.lastIndexOf('.');
+ if (index == -1) {
+ continue;
+ }
+ String packageName = interf.substring(0, index);
+ try {
+ /* Make sure any package version properties are well formed */
+ getPackageVersion(packageName);
+ } catch (IllegalArgumentException e) {
+ IllegalArgumentException iae = new IllegalArgumentException("Improper version for package " + packageName);
+ iae.initCause(e);
+ throw iae;
+ }
+ }
+ return Collections.unmodifiableList(Arrays.asList(objectClass));
+ }
+
+ /**
+ * Verify and obtain a required String property.
+ *
+ * @param propName The name of the property
+ * @return The value of the property or {@code null} if the property is not
+ * set.
+ * @throws IllegalArgumentException when the property doesn't have the
+ * correct data type.
+ */
+ private String verifyStringProperty(String propName) {
+ Object r = properties.get(propName);
+ try {
+ return (String) r;
+ } catch (ClassCastException e) {
+ IllegalArgumentException iae = new IllegalArgumentException("property value is not a String: " + propName);
+ iae.initCause(e);
+ throw iae;
+ }
+ }
+
+ /**
+ * Verify and obtain a required long property.
+ *
+ * @param propName The name of the property
+ * @return The value of the property or 0 if the property is not set.
+ * @throws IllegalArgumentException when the property doesn't have the
+ * correct data type.
+ */
+ private long verifyLongProperty(String propName) {
+ Object r = properties.get(propName);
+ if (r == null) {
+ return 0l;
+ }
+ try {
+ return ((Long) r).longValue();
+ } catch (ClassCastException e) {
+ IllegalArgumentException iae = new IllegalArgumentException("property value is not a Long: " + propName);
+ iae.initCause(e);
+ throw iae;
+ }
+ }
+
+ /**
+ * Returns the endpoint's id.
+ *
+ * The id is an opaque id for an endpoint. No two different endpoints must
+ * have the same id. Two Endpoint Descriptions with the same id must
+ * represent the same endpoint.
+ *
+ * The value of the id is stored in the {@link RemoteConstants#ENDPOINT_ID}
+ * property.
+ *
+ * @return The id of the endpoint, never {@code null}. The returned value
+ * has leading and trailing whitespace removed.
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * Provide the list of interfaces implemented by the exported service.
+ *
+ * The value of the interfaces is derived from the {@code objectClass}
+ * property.
+ *
+ * @return An unmodifiable list of Java interface names implemented by this
+ * endpoint.
+ */
+ public List<String> getInterfaces() {
+ return interfaces;
+ }
+
+ /**
+ * Provide the version of the given package name.
+ *
+ * The version is encoded by prefixing the given package name with
+ * {@link RemoteConstants#ENDPOINT_PACKAGE_VERSION_
+ * endpoint.package.version.}, and then using this as an endpoint property
+ * key. For example:
+ *
+ * <pre>
+ * endpoint.package.version.com.acme
+ * </pre>
+ *
+ * The value of this property is in String format and will be converted to a
+ * {@code Version} object by this method.
+ *
+ * @param packageName The name of the package for which a version is
+ * requested.
+ * @return The version of the specified package or
+ * {@code Version.emptyVersion} if the package has no version in
+ * this Endpoint Description.
+ * @throws IllegalArgumentException If the version property value is not
+ * String.
+ */
+ public Version getPackageVersion(String packageName) {
+ String key = ENDPOINT_PACKAGE_VERSION_ + packageName;
+ Object value = properties.get(key);
+ String version;
+ try {
+ version = (String) value;
+ } catch (ClassCastException e) {
+ IllegalArgumentException iae = new IllegalArgumentException(key + " property value is not a String");
+ iae.initCause(e);
+ throw iae;
+ }
+ return Version.parseVersion(version);
+ }
+
+ /**
+ * Returns the service id for the service exported through this endpoint.
+ *
+ * This is the service id under which the framework has registered the
+ * service. This field together with the Framework UUID is a globally unique
+ * id for a service.
+ *
+ * The value of the remote service id is stored in the
+ * {@link RemoteConstants#ENDPOINT_SERVICE_ID} endpoint property.
+ *
+ * @return Service id of a service or 0 if this Endpoint Description does
+ * not relate to an OSGi service.
+ *
+ */
+ public long getServiceId() {
+ return serviceId;
+ }
+
+ /**
+ * Returns the configuration types.
+ *
+ * A distribution provider exports a service with an endpoint. This endpoint
+ * uses some kind of communications protocol with a set of configuration
+ * parameters. There are many different types but each endpoint is
+ * configured by only one configuration type. However, a distribution
+ * provider can be aware of different configuration types and provide
+ * synonyms to increase the change a receiving distribution provider can
+ * create a connection to this endpoint.
+ *
+ * This value of the configuration types is stored in the
+ * {@link RemoteConstants#SERVICE_IMPORTED_CONFIGS} service property.
+ *
+ * @return An unmodifiable list of the configuration types used for the
+ * associated endpoint and optionally synonyms.
+ */
+ public List<String> getConfigurationTypes() {
+ return getStringPlusProperty(SERVICE_IMPORTED_CONFIGS);
+ }
+
+ /**
+ * Return the list of intents implemented by this endpoint.
+ *
+ * The intents are based on the service.intents on an imported service,
+ * except for any intents that are additionally provided by the importing
+ * distribution provider. All qualified intents must have been expanded.
+ *
+ * This value of the intents is stored in the
+ * {@link RemoteConstants#SERVICE_INTENTS} service property.
+ *
+ * @return An unmodifiable list of expanded intents that are provided by
+ * this endpoint.
+ */
+ public List<String> getIntents() {
+ return getStringPlusProperty(SERVICE_INTENTS);
+ }
+
+ /**
+ * Reads a 'String+' property from the properties map, which may be of type
+ * String, String[] or Collection&lt;String&gt; and returns it as an
+ * unmodifiable List.
+ *
+ * @param key The property
+ * @return An unmodifiable list
+ */
+ private List<String> getStringPlusProperty(String key) {
+ Object value = properties.get(key);
+ if (value == null) {
+ return emptyList();
+ }
+
+ if (value instanceof String) {
+ return Collections.singletonList((String) value);
+ }
+
+ if (value instanceof String[]) {
+ String[] values = (String[]) value;
+ List<String> result = new ArrayList<String>(values.length);
+ for (String v : values) {
+ if (v != null) {
+ result.add(v);
+ }
+ }
+ return Collections.unmodifiableList(result);
+ }
+
+ if (value instanceof Collection<?>) {
+ Collection<?> values = (Collection<?>) value;
+ List<String> result = new ArrayList<String>(values.size());
+ for (Iterator<?> iter = values.iterator(); iter.hasNext();) {
+ Object v = iter.next();
+ if (v instanceof String) {
+ result.add((String) v);
+ }
+ }
+ return Collections.unmodifiableList(result);
+ }
+
+ return emptyList();
+ }
+
+ @SuppressWarnings("unchecked")
+ private static <T> List<T> emptyList() {
+ return Collections.EMPTY_LIST;
+ }
+
+ /**
+ * Return the framework UUID for the remote service, if present.
+ *
+ * The value of the remote framework uuid is stored in the
+ * {@link RemoteConstants#ENDPOINT_FRAMEWORK_UUID} endpoint property.
+ *
+ * @return Remote Framework UUID, or {@code null} if this endpoint is not
+ * associated with an OSGi framework having a framework uuid.
+ */
+ public String getFrameworkUUID() {
+ return frameworkUUID;
+ }
+
+ /**
+ * Returns all endpoint properties.
+ *
+ * @return An unmodifiable map referring to the properties of this Endpoint
+ * Description.
+ */
+ public Map<String, Object> getProperties() {
+ return properties;
+ }
+
+ /**
+ * Answers if this Endpoint Description refers to the same service instance
+ * as the given Endpoint Description.
+ *
+ * Two Endpoint Descriptions point to the same service if they have the same
+ * id or their framework UUIDs and remote service ids are equal.
+ *
+ * @param other The Endpoint Description to look at
+ * @return True if this endpoint description points to the same service as
+ * the other
+ */
+ public boolean isSameService(EndpointDescription other) {
+ if (this.equals(other)) {
+ return true;
+ }
+
+ if (this.getFrameworkUUID() == null) {
+ return false;
+ }
+
+ return (this.getServiceId() == other.getServiceId()) && this.getFrameworkUUID().equals(other.getFrameworkUUID());
+ }
+
+ /**
+ * Returns a hash code value for the object.
+ *
+ * @return An integer which is a hash code value for this object.
+ */
+ @Override
+ public int hashCode() {
+ return getId().hashCode();
+ }
+
+ /**
+ * Compares this {@code EndpointDescription} object to another object.
+ *
+ * <p>
+ * An Endpoint Description is considered to be <b>equal to</b> another
+ * Endpoint Description if their ids are equal.
+ *
+ * @param other The {@code EndpointDescription} object to be compared.
+ * @return {@code true} if {@code object} is a {@code EndpointDescription}
+ * and is equal to this object; {@code false} otherwise.
+ */
+ @Override
+ public boolean equals(Object other) {
+ if (this == other) {
+ return true;
+ }
+ if (!(other instanceof EndpointDescription)) {
+ return false;
+ }
+ return getId().equals(((EndpointDescription) other).getId());
+ }
+
+ /**
+ * Tests the properties of this {@code EndpointDescription} against the
+ * given filter using a case insensitive match.
+ *
+ * @param filter The filter to test.
+ * @return {@code true} If the properties of this
+ * {@code EndpointDescription} match the filter, {@code false}
+ * otherwise.
+ * @throws IllegalArgumentException If {@code filter} contains an invalid
+ * filter string that cannot be parsed.
+ */
+ public boolean matches(String filter) {
+ Filter f;
+ try {
+ f = FrameworkUtil.createFilter(filter);
+ } catch (InvalidSyntaxException e) {
+ IllegalArgumentException iae = new IllegalArgumentException(e.getMessage());
+ iae.initCause(e);
+ throw iae;
+ }
+ Dictionary<String, Object> d = new UnmodifiableDictionary<String, Object>(properties);
+ /*
+ * we can use matchCase here since properties already supports case
+ * insensitive key lookup.
+ */
+ return f.matchCase(d);
+ }
+
+ /**
+ * Returns the string representation of this EndpointDescription.
+ *
+ * @return String form of this EndpointDescription.
+ */
+ @Override
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append('{');
+ Iterator<Map.Entry<String, Object>> iter = properties.entrySet().iterator();
+ boolean comma = false;
+ while (iter.hasNext()) {
+ Map.Entry<String, Object> entry = iter.next();
+ if (comma) {
+ sb.append(", ");
+ } else {
+ comma = true;
+ }
+ sb.append(entry.getKey());
+ sb.append('=');
+ Object value = entry.getValue();
+ if (value != null) {
+ Class<?> valueType = value.getClass();
+ if (Object[].class.isAssignableFrom(valueType)) {
+ append(sb, (Object[]) value);
+ continue;
+ }
+ }
+ sb.append(value);
+ }
+ sb.append('}');
+ return sb.toString();
+ }
+
+ /**
+ * Append the specified Object array to the specified StringBuffer.
+ *
+ * @param sb Receiving StringBuffer.
+ * @param value Object array to append to the specified StringBuffer.
+ */
+ private static void append(StringBuffer sb, Object[] value) {
+ sb.append('[');
+ boolean comma = false;
+ final int length = value.length;
+ for (int i = 0; i < length; i++) {
+ if (comma) {
+ sb.append(", ");
+ } else {
+ comma = true;
+ }
+ sb.append(String.valueOf(value[i]));
+ }
+ sb.append(']');
+ }
+
+ /**
+ * Unmodifiable Dictionary wrapper for a Map. This class is also used by
+ * EndpointPermission.
+ */
+ static final class UnmodifiableDictionary<K, V> extends Dictionary<K, V> {
+ private final Map<K, V> wrapped;
+
+ UnmodifiableDictionary(Map<K, V> wrapped) {
+ this.wrapped = wrapped;
+ }
+
+ @Override
+ public Enumeration<V> elements() {
+ return Collections.enumeration(wrapped.values());
+ }
+
+ @Override
+ public V get(Object key) {
+ return wrapped.get(key);
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return wrapped.isEmpty();
+ }
+
+ @Override
+ public Enumeration<K> keys() {
+ return Collections.enumeration(wrapped.keySet());
+ }
+
+ @Override
+ public V put(K key, V value) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public V remove(Object key) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int size() {
+ return wrapped.size();
+ }
+
+ @Override
+ public String toString() {
+ return wrapped.toString();
+ }
+ }
+}
diff --git a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/EndpointEvent.java b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/EndpointEvent.java
new file mode 100644
index 000000000..3a781045e
--- /dev/null
+++ b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/EndpointEvent.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) OSGi Alliance (2013). All Rights Reserved.
+ *
+ * Licensed 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.osgi.service.remoteserviceadmin;
+
+/**
+ * An Endpoint Event.
+ * <p/>
+ *
+ * {@code EndpointEvent} objects are delivered to all registered
+ * {@link EndpointEventListener} services where the {@link EndpointDescription}
+ * properties match one of the filters specified in the
+ * {@link EndpointEventListener#ENDPOINT_LISTENER_SCOPE} registration properties
+ * of the Endpoint Event Listener.
+ * <p/>
+ *
+ * A type code is used to identify the type of event. The following event types
+ * are defined:
+ * <ul>
+ * <li>{@link #ADDED}</li>
+ * <li>{@link #REMOVED}</li>
+ * <li>{@link #MODIFIED}</li>
+ * <li>{@link #MODIFIED_ENDMATCH}</li>
+ * </ul>
+ * Additional event types may be defined in the future.
+ * <p/>
+ *
+ * @see EndpointEventListener
+ * @Immutable
+ * @since 1.1
+ */
+public class EndpointEvent {
+ /**
+ * An endpoint has been added.
+ * <p/>
+ *
+ * This {@code EndpointEvent} type indicates that a new endpoint has been
+ * added. The endpoint is represented by the associated
+ * {@link EndpointDescription} object.
+ */
+ public static final int ADDED = 0x00000001;
+
+ /**
+ * An endpoint has been removed.
+ * <p/>
+ *
+ * This {@code EndpointEvent} type indicates that an endpoint has been
+ * removed. The endpoint is represented by the associated
+ * {@link EndpointDescription} object.
+ */
+ public static final int REMOVED = 0x00000002;
+
+ /**
+ * The properties of an endpoint have been modified.
+ * <p/>
+ *
+ * This {@code EndpointEvent} type indicates that the properties of an
+ * existing endpoint have been modified. The endpoint is represented by the
+ * associated {@link EndpointDescription} object and its properties can be
+ * obtained via {@link EndpointDescription#getProperties()}. The endpoint
+ * properties still match the filters as specified in the
+ * {@link EndpointEventListener#ENDPOINT_LISTENER_SCOPE} filter.
+ */
+ public static final int MODIFIED = 0x00000004;
+
+ /**
+ * The properties of an endpoint have been modified and the new properties
+ * no longer match the listener's filter.
+ * <p/>
+ *
+ * This {@code EndpointEvent} type indicates that the properties of an
+ * existing endpoint have been modified and no longer match the filter. The
+ * endpoint is represented by the associated {@link EndpointDescription}
+ * object and its properties can be obtained via
+ * {@link EndpointDescription#getProperties()}. As a consequence of the
+ * modification the filters as specified in the
+ * {@link EndpointEventListener#ENDPOINT_LISTENER_SCOPE} do not match any
+ * more.
+ */
+ public static final int MODIFIED_ENDMATCH = 0x00000008;
+
+ /**
+ * Reference to the associated endpoint description.
+ */
+ private final EndpointDescription endpoint;
+
+ /**
+ * Type of the event.
+ */
+ private final int type;
+
+ /**
+ * Constructs a {@code EndpointEvent} object from the given arguments.
+ *
+ * @param type The event type. See {@link #getType()}.
+ * @param endpoint The endpoint associated with the event.
+ */
+ public EndpointEvent(int type, EndpointDescription endpoint) {
+ this.endpoint = endpoint;
+ this.type = type;
+ }
+
+ /**
+ * Return the endpoint associated with this event.
+ *
+ * @return The endpoint associated with the event.
+ */
+ public EndpointDescription getEndpoint() {
+ return endpoint;
+ }
+
+ /**
+ * Return the type of this event.
+ * <p/>
+ * The type values are:
+ * <ul>
+ * <li>{@link #ADDED}</li>
+ * <li>{@link #REMOVED}</li>
+ * <li>{@link #MODIFIED}</li>
+ * <li>{@link #MODIFIED_ENDMATCH}</li>
+ * </ul>
+ *
+ * @return The type of this event.
+ */
+ public int getType() {
+ return type;
+ }
+}
diff --git a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/EndpointEventListener.java b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/EndpointEventListener.java
new file mode 100644
index 000000000..ad599a546
--- /dev/null
+++ b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/EndpointEventListener.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) OSGi Alliance (2013). All Rights Reserved.
+ *
+ * Licensed 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.osgi.service.remoteserviceadmin;
+
+/**
+ * A white board service that represents a listener for endpoints.
+ *
+ * An Endpoint Event Listener represents a participant in the distributed model
+ * that is interested in Endpoint Descriptions.
+ *
+ * This white board service can be used in many different scenarios. However,
+ * the primary use case is to allow a remote manager to be informed of Endpoint
+ * Descriptions available in the network and inform the network about available
+ * Endpoint Descriptions.
+ *
+ * Both the network bundle and the manager bundle register an Endpoint Event
+ * Listener service. The manager informs the network bundle about Endpoints that
+ * it creates. The network bundles then uses a protocol like SLP to announce
+ * these local end-points to the network.
+ *
+ * If the network bundle discovers a new Endpoint through its discovery
+ * protocol, then it sends an Endpoint Description to all the Endpoint Listener
+ * services that are registered (except its own) that have specified an interest
+ * in that endpoint.
+ *
+ * Endpoint Event Listener services can express their <i>scope</i> with the
+ * service property {@link #ENDPOINT_LISTENER_SCOPE}. This service property is a
+ * list of filters. An Endpoint Description should only be given to a Endpoint
+ * Event Listener when there is at least one filter that matches the Endpoint
+ * Description properties.
+ *
+ * This filter model is quite flexible. For example, a discovery bundle is only
+ * interested in locally originating Endpoint Descriptions. The following filter
+ * ensures that it only sees local endpoints.
+ *
+ * <pre>
+ * (org.osgi.framework.uuid=72dc5fd9-5f8f-4f8f-9821-9ebb433a5b72)
+ * </pre>
+ *
+ * In the same vein, a manager that is only interested in remote Endpoint
+ * Descriptions can use a filter like:
+ *
+ * <pre>
+ * (!(org.osgi.framework.uuid=72dc5fd9-5f8f-4f8f-9821-9ebb433a5b72))
+ * </pre>
+ *
+ * Where in both cases, the given UUID is the UUID of the local framework that
+ * can be found in the Framework properties.
+ *
+ * The Endpoint Event Listener's scope maps very well to the service hooks. A
+ * manager can just register all filters found from the Listener Hook as its
+ * scope. This will automatically provide it with all known endpoints that match
+ * the given scope, without having to inspect the filter string.
+ *
+ * In general, when an Endpoint Description is discovered, it should be
+ * dispatched to all registered Endpoint Event Listener services. If a new
+ * Endpoint Event Listener is registered, it should be informed about all
+ * currently known Endpoints that match its scope. If a getter of the Endpoint
+ * Listener service is unregistered, then all its registered Endpoint
+ * Description objects must be removed.
+ *
+ * The Endpoint Event Listener models a <i>best effort</i> approach.
+ * Participating bundles should do their utmost to keep the listeners up to
+ * date, but implementers should realize that many endpoints come through
+ * unreliable discovery processes.
+ *
+ * The Endpoint Event Listener supersedes the {@link EndpointListener} interface
+ * as it also supports notifications around modifications of endpoints.
+ *
+ * @ThreadSafe
+ * @since 1.1
+ */
+public interface EndpointEventListener {
+ /**
+ * Specifies the interest of this listener with filters. This listener is
+ * only interested in Endpoint Descriptions where its properties match the
+ * given filter. The type of this property must be {@code String+}.
+ */
+ String ENDPOINT_LISTENER_SCOPE = "endpoint.listener.scope";
+
+ /**
+ * Notification that an endpoint has changed.
+ *
+ * Details of the change is captured in the Endpoint Event provided. This
+ * could be that an endpoint was added, removed or modified.
+ *
+ * @param event The event containing the details about the change.
+ * @param filter The filter from the {@link #ENDPOINT_LISTENER_SCOPE} that
+ * matches (or for {@link EndpointEvent#MODIFIED_ENDMATCH} and
+ * {@link EndpointEvent#REMOVED} used to match) the endpoint, must
+ * not be {@code null}.
+ */
+ void endpointChanged(EndpointEvent event, String filter);
+}
diff --git a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/EndpointListener.java b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/EndpointListener.java
new file mode 100644
index 000000000..c3888f065
--- /dev/null
+++ b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/EndpointListener.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) OSGi Alliance (2009, 2013). All Rights Reserved.
+ *
+ * Licensed 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.osgi.service.remoteserviceadmin;
+
+import org.osgi.annotation.versioning.ConsumerType;
+
+/**
+ * Deprecated white board service that represents a listener for endpoints.
+ *
+ * An Endpoint Listener represents a participant in the distributed model that
+ * is interested in Endpoint Descriptions.
+ *
+ * The Endpoint Listener is called back when matching endpoints are added or
+ * removed. Consumers interested in the modification of endpoints, when
+ * associated service properties are changed, should use an
+ * {@link EndpointEventListener} instead.
+ *
+ * This white board service can be used in many different scenarios. However,
+ * the primary use case is to allow a remote manager to be informed of Endpoint
+ * Descriptions available in the network and inform the network about available
+ * Endpoint Descriptions.
+ *
+ * Both the network bundle and the manager bundle register an Endpoint Listener
+ * service. The manager informs the network bundle about Endpoints that it
+ * creates. The network bundles then uses a protocol like SLP to announce these
+ * local end-points to the network.
+ *
+ * If the network bundle discovers a new Endpoint through its discovery
+ * protocol, then it sends an Endpoint Description to all the Endpoint Listener
+ * services that are registered (except its own) that have specified an interest
+ * in that endpoint.
+ *
+ * Endpoint Listener services can express their <i>scope</i> with the service
+ * property {@link #ENDPOINT_LISTENER_SCOPE}. This service property is a list of
+ * filters. An Endpoint Description should only be given to a Endpoint Listener
+ * when there is at least one filter that matches the Endpoint Description
+ * properties.
+ *
+ * This filter model is quite flexible. For example, a discovery bundle is only
+ * interested in locally originating Endpoint Descriptions. The following filter
+ * ensure that it only sees local endpoints.
+ *
+ * <pre>
+ * (org.osgi.framework.uuid=72dc5fd9-5f8f-4f8f-9821-9ebb433a5b72)
+ * </pre>
+ *
+ * In the same vein, a manager that is only interested in remote Endpoint
+ * Descriptions can use a filter like:
+ *
+ * <pre>
+ * (!(org.osgi.framework.uuid=72dc5fd9-5f8f-4f8f-9821-9ebb433a5b72))
+ * </pre>
+ *
+ * Where in both cases, the given UUID is the UUID of the local framework that
+ * can be found in the Framework properties.
+ *
+ * The Endpoint Listener's scope maps very well to the service hooks. A manager
+ * can just register all filters found from the Listener Hook as its scope. This
+ * will automatically provide it with all known endpoints that match the given
+ * scope, without having to inspect the filter string.
+ *
+ * In general, when an Endpoint Description is discovered, it should be
+ * dispatched to all registered Endpoint Listener services. If a new Endpoint
+ * Listener is registered, it should be informed about all currently known
+ * Endpoints that match its scope. If a getter of the Endpoint Listener service
+ * is unregistered, then all its registered Endpoint Description objects must be
+ * removed.
+ *
+ * The Endpoint Listener models a <i>best effort</i> approach. Participating
+ * bundles should do their utmost to keep the listeners up to date, but
+ * implementers should realize that many endpoints come through unreliable
+ * discovery processes.
+ *
+ * @ThreadSafe
+ * @deprecated As of 1.1. Replaced by EndpointEventListener.
+ * @author $Id$
+ */
+@ConsumerType
+public interface EndpointListener {
+ /**
+ * Specifies the interest of this listener with filters. This listener is
+ * only interested in Endpoint Descriptions where its properties match the
+ * given filter. The type of this property must be {@code String+}.
+ */
+ String ENDPOINT_LISTENER_SCOPE = "endpoint.listener.scope";
+
+ /**
+ * Register an endpoint with this listener.
+ *
+ * If the endpoint matches one of the filters registered with the
+ * {@link #ENDPOINT_LISTENER_SCOPE} service property then this filter should
+ * be given as the {@code matchedFilter} parameter.
+ *
+ * When this service is first registered or it is modified, it should
+ * receive all known endpoints matching the filter.
+ *
+ * @param endpoint The Endpoint Description to be published
+ * @param matchedFilter The filter from the {@link #ENDPOINT_LISTENER_SCOPE}
+ * that matched the endpoint, must not be {@code null}.
+ */
+ void endpointAdded(EndpointDescription endpoint, String matchedFilter);
+
+ /**
+ * Remove the registration of an endpoint.
+ *
+ * If an endpoint that was registered with the
+ * {@link #endpointAdded(EndpointDescription, String)} method is no longer
+ * available then this method should be called. This will remove the
+ * endpoint from the listener.
+ *
+ * It is not necessary to remove endpoints when the service is unregistered
+ * or modified in such a way that not all endpoints match the interest
+ * filter anymore.
+ *
+ * @param endpoint The Endpoint Description that is no longer valid.
+ * @param matchedFilter The filter from the {@link #ENDPOINT_LISTENER_SCOPE}
+ * that matched the endpoint, must not be {@code null}.
+ */
+ void endpointRemoved(EndpointDescription endpoint, String matchedFilter);
+}
diff --git a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/EndpointPermission.java b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/EndpointPermission.java
new file mode 100644
index 000000000..bce27511e
--- /dev/null
+++ b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/EndpointPermission.java
@@ -0,0 +1,653 @@
+/*
+ * Copyright (c) OSGi Alliance (2000, 2013). All Rights Reserved.
+ *
+ * Licensed 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.osgi.service.remoteserviceadmin;
+
+import static org.osgi.service.remoteserviceadmin.RemoteConstants.*;
+import java.io.IOException;
+import java.io.NotSerializableException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamField;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
+
+/**
+ * A bundle's authority to export, import or read an Endpoint.
+ * <ul>
+ * <li>The {@code export} action allows a bundle to export a service as an
+ * Endpoint.</li>
+ * <li>The {@code import} action allows a bundle to import a service from an
+ * Endpoint.</li>
+ * <li>The {@code read} action allows a bundle to read references to an
+ * Endpoint.</li>
+ * </ul>
+ * Permission to read an Endpoint is required in order to detect events
+ * regarding an Endpoint. Untrusted bundles should not be able to detect the
+ * presence of certain Endpoints unless they have the appropriate
+ * {@code EndpointPermission} to read the specific service.
+ *
+ * @ThreadSafe
+ * @author $Id$
+ */
+
+public final class EndpointPermission extends Permission {
+ static final long serialVersionUID = -7662148639076511574L;
+ /**
+ * The action string {@code read}.
+ */
+ public final static String READ = "read";
+ /**
+ * The action string {@code import}. The {@code import} action implies the
+ * {@code read} action.
+ */
+ public final static String IMPORT = "import";
+ /**
+ * The action string {@code export}. The {@code export} action implies the
+ * {@code read} action.
+ */
+ public final static String EXPORT = "export";
+
+ private final static int ACTION_READ = 0x00000001;
+ private final static int ACTION_IMPORT = 0x00000002;
+ private final static int ACTION_EXPORT = 0x00000004;
+ private final static int ACTION_ALL = ACTION_EXPORT | ACTION_IMPORT | ACTION_READ;
+ final static int ACTION_NONE = 0;
+
+ /**
+ * The actions mask.
+ */
+ transient int action_mask;
+
+ /**
+ * The actions in canonical form.
+ *
+ * @serial
+ */
+ private volatile String actions = null;
+
+ /**
+ * The endpoint used by this EndpointPermission. Must be {@code null} if not
+ * constructed with a endpoint.
+ */
+ transient final EndpointDescription endpoint;
+
+ /**
+ * This dictionary holds the properties of the permission, used to match a
+ * filter in implies.
+ */
+ private transient final Dictionary<String, Object> properties;
+
+ /**
+ * If this EndpointPermission was not constructed with an
+ * EndpointDescription, this holds a Filter matching object used to evaluate
+ * the filter in implies or {@code null} for wildcard.
+ */
+ transient Filter filter;
+
+ /**
+ * Create a new EndpointPermission with the specified filter.
+ *
+ * <p>
+ * The filter will be evaluated against the endpoint properties of a
+ * requested EndpointPermission.
+ *
+ * <p>
+ * There are three possible actions: {@code read}, {@code import} and
+ * {@code export}. The {@code read} action allows the owner of this
+ * permission to see the presence of distributed services. The
+ * {@code import} action allows the owner of this permission to import an
+ * endpoint. The {@code export} action allows the owner of this permission
+ * to export a service.
+ *
+ * @param filterString The filter string or &quot;*&quot; to match all
+ * endpoints.
+ * @param actions The actions {@code read}, {@code import}, or
+ * {@code export}.
+ * @throws IllegalArgumentException If the filter has an invalid syntax or
+ * the actions are not valid.
+ */
+ public EndpointPermission(String filterString, String actions) {
+ this(filterString, parseActions(actions));
+ }
+
+ /**
+ * Creates a new requested {@code EndpointPermission} object to be used by
+ * code that must perform {@code checkPermission}.
+ * {@code EndpointPermission} objects created with this constructor cannot
+ * be added to an {@code EndpointPermission} permission collection.
+ *
+ * @param endpoint The requested endpoint.
+ * @param localFrameworkUUID The UUID of the local framework. This is used
+ * to support matching the
+ * {@link RemoteConstants#ENDPOINT_FRAMEWORK_UUID
+ * endpoint.framework.uuid} endpoint property to the
+ * {@code <<LOCAL>>} value in the filter expression.
+ * @param actions The actions {@code read}, {@code import}, or
+ * {@code export}.
+ * @throws IllegalArgumentException If the endpoint is {@code null} or the
+ * actions are not valid.
+ */
+ public EndpointPermission(EndpointDescription endpoint, String localFrameworkUUID, String actions) {
+ super(createName(endpoint));
+ setTransients(null, parseActions(actions));
+ Map<String, Object> props;
+ if ((localFrameworkUUID != null) && localFrameworkUUID.equals(endpoint.getFrameworkUUID())) {
+ props = new TreeMap<String, Object>(String.CASE_INSENSITIVE_ORDER);
+ props.putAll(endpoint.getProperties());
+ props.put(ENDPOINT_FRAMEWORK_UUID, new String[] {endpoint.getFrameworkUUID(), "<<LOCAL>>"});
+ } else {
+ props = endpoint.getProperties();
+ }
+ this.endpoint = endpoint;
+ this.properties = new EndpointDescription.UnmodifiableDictionary<String, Object>(props);
+ }
+
+ /**
+ * Create a permission name from a EndpointDescription.
+ *
+ * @param endpoint EndpointDescription to use to create permission name.
+ * @return permission name.
+ */
+ private static String createName(EndpointDescription endpoint) {
+ if (endpoint == null) {
+ throw new IllegalArgumentException("invalid endpoint: null");
+ }
+ StringBuffer sb = new StringBuffer("(" + ENDPOINT_ID + "=");
+ sb.append(endpoint.getId());
+ sb.append(")");
+ return sb.toString();
+ }
+
+ /**
+ * Package private constructor used by EndpointPermissionCollection.
+ *
+ * @param name class name
+ * @param mask action mask
+ */
+ EndpointPermission(String name, int mask) {
+ super(name);
+ setTransients(parseFilter(name), mask);
+ this.endpoint = null;
+ this.properties = null;
+ }
+
+ /**
+ * Called by constructors and when deserialized.
+ *
+ * @param mask action mask
+ */
+ private void setTransients(Filter f, int mask) {
+ if ((mask == ACTION_NONE) || ((mask & ACTION_ALL) != mask)) {
+ throw new IllegalArgumentException("invalid action string");
+ }
+ action_mask = mask;
+ filter = f;
+ }
+
+ /**
+ * Parse action string into action mask.
+ *
+ * @param actions Action string.
+ * @return action mask.
+ */
+ private static int parseActions(String actions) {
+ boolean seencomma = false;
+
+ int mask = ACTION_NONE;
+
+ if (actions == null) {
+ return mask;
+ }
+
+ char[] a = actions.toCharArray();
+
+ int i = a.length - 1;
+ if (i < 0)
+ return mask;
+
+ while (i != -1) {
+ char c;
+
+ // skip whitespace
+ while ((i != -1) && ((c = a[i]) == ' ' || c == '\r' || c == '\n' || c == '\f' || c == '\t'))
+ i--;
+
+ // check for the known strings
+ int matchlen;
+
+ if (i >= 5 && (a[i - 5] == 'i' || a[i - 5] == 'I') && (a[i - 4] == 'm' || a[i - 4] == 'M') && (a[i - 3] == 'p' || a[i - 3] == 'P') && (a[i - 2] == 'o' || a[i - 2] == 'O')
+ && (a[i - 1] == 'r' || a[i - 1] == 'R') && (a[i] == 't' || a[i] == 'T')) {
+ matchlen = 6;
+ mask |= ACTION_IMPORT | ACTION_READ;
+
+ } else
+ if (i >= 5 && (a[i - 5] == 'e' || a[i - 5] == 'E') && (a[i - 4] == 'x' || a[i - 4] == 'X') && (a[i - 3] == 'p' || a[i - 3] == 'P') && (a[i - 2] == 'o' || a[i - 2] == 'O')
+ && (a[i - 1] == 'r' || a[i - 1] == 'R') && (a[i] == 't' || a[i] == 'T')) {
+ matchlen = 6;
+ mask |= ACTION_EXPORT | ACTION_READ;
+
+ } else {
+ if (i >= 3 && (a[i - 3] == 'r' || a[i - 3] == 'R') && (a[i - 2] == 'e' || a[i - 2] == 'E') && (a[i - 1] == 'a' || a[i - 1] == 'A') && (a[i] == 'd' || a[i] == 'D')) {
+ matchlen = 4;
+ mask |= ACTION_READ;
+
+ } else {
+ // parse error
+ throw new IllegalArgumentException("invalid permission: " + actions);
+ }
+ }
+
+ // make sure we didn't just match the tail of a word
+ // like "ackbarfread". Also, skip to the comma.
+ seencomma = false;
+ while (i >= matchlen && !seencomma) {
+ switch (a[i - matchlen]) {
+ case ',' :
+ seencomma = true;
+ /* FALLTHROUGH */
+ case ' ' :
+ case '\r' :
+ case '\n' :
+ case '\f' :
+ case '\t' :
+ break;
+ default :
+ throw new IllegalArgumentException("invalid permission: " + actions);
+ }
+ i--;
+ }
+
+ // point i at the location of the comma minus one (or -1).
+ i -= matchlen;
+ }
+
+ if (seencomma) {
+ throw new IllegalArgumentException("invalid permission: " + actions);
+ }
+
+ return mask;
+ }
+
+ /**
+ * Parse filter string into a Filter object.
+ *
+ * @param filterString The filter string to parse.
+ * @return a Filter for this bundle.
+ * @throws IllegalArgumentException If the filter syntax is invalid.
+ */
+ private static Filter parseFilter(String filterString) {
+ if (filterString == null) {
+ throw new IllegalArgumentException("invalid filter: null");
+ }
+ filterString = filterString.trim();
+ if (filterString.equals("*")) {
+ return null; // wildcard
+ }
+ try {
+ return FrameworkUtil.createFilter(filterString);
+ } catch (InvalidSyntaxException e) {
+ IllegalArgumentException iae = new IllegalArgumentException("invalid filter");
+ iae.initCause(e);
+ throw iae;
+ }
+ }
+
+ /**
+ * Determines if a {@code EndpointPermission} object "implies" the specified
+ * permission.
+ *
+ * @param p The target permission to check.
+ * @return {@code true} if the specified permission is implied by this
+ * object; {@code false} otherwise.
+ */
+ @Override
+ public boolean implies(Permission p) {
+ if (!(p instanceof EndpointPermission)) {
+ return false;
+ }
+ EndpointPermission requested = (EndpointPermission) p;
+ if (endpoint != null) {
+ return false;
+ }
+ // if requested permission has a filter, then it is an invalid argument
+ if (requested.filter != null) {
+ return false;
+ }
+ return implies0(requested, ACTION_NONE);
+ }
+
+ /**
+ * Internal implies method. Used by the implies and the permission
+ * collection implies methods.
+ *
+ * @param requested The requested EndpointPermission which has already be
+ * validated as a proper argument. The requested EndpointPermission
+ * must not have a filter expression.
+ * @param effective The effective actions with which to start.
+ * @return {@code true} if the specified permission is implied by this
+ * object; {@code false} otherwise.
+ */
+ boolean implies0(EndpointPermission requested, int effective) {
+ /* check actions first - much faster */
+ effective |= action_mask;
+ final int desired = requested.action_mask;
+ if ((effective & desired) != desired) {
+ return false;
+ }
+ /* if we have no filter */
+ Filter f = filter;
+ if (f == null) {
+ // it's "*"
+ return true;
+ }
+ return f.matchCase(requested.getProperties());
+ }
+
+ /**
+ * Returns the canonical string representation of the actions. Always
+ * returns present actions in the following canonical order: {@code read},
+ * {@code import}, {@code export}.
+ *
+ * @return The canonical string representation of the actions.
+ */
+ @Override
+ public String getActions() {
+ String result = actions;
+ if (result == null) {
+ StringBuffer sb = new StringBuffer();
+ boolean comma = false;
+
+ int mask = action_mask;
+ if ((mask & ACTION_READ) == ACTION_READ) {
+ sb.append(READ);
+ comma = true;
+ }
+
+ if ((mask & ACTION_IMPORT) == ACTION_IMPORT) {
+ if (comma)
+ sb.append(',');
+ sb.append(IMPORT);
+ }
+
+ if ((mask & ACTION_EXPORT) == ACTION_EXPORT) {
+ if (comma)
+ sb.append(',');
+ sb.append(EXPORT);
+ }
+
+ actions = result = sb.toString();
+ }
+
+ return result;
+ }
+
+ /**
+ * Returns a new {@code PermissionCollection} object for storing
+ * {@code EndpointPermission} objects.
+ *
+ * @return A new {@code PermissionCollection} object suitable for storing
+ * {@code EndpointPermission} objects.
+ */
+ @Override
+ public PermissionCollection newPermissionCollection() {
+ return new EndpointPermissionCollection();
+ }
+
+ /**
+ * Determines the equality of two EndpointPermission objects.
+ *
+ * Checks that specified object has the same name, actions and endpoint as
+ * this {@code EndpointPermission}.
+ *
+ * @param obj The object to test for equality.
+ * @return true If obj is a {@code EndpointPermission}, and has the same
+ * name, actions and endpoint as this {@code EndpointPermission}
+ * object; {@code false} otherwise.
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+
+ if (!(obj instanceof EndpointPermission)) {
+ return false;
+ }
+
+ EndpointPermission ep = (EndpointPermission) obj;
+
+ return (action_mask == ep.action_mask) && getName().equals(ep.getName()) && ((endpoint == ep.endpoint) || ((endpoint != null) && (ep.endpoint != null) && endpoint.equals(ep.endpoint)));
+ }
+
+ /**
+ * Returns the hash code value for this object.
+ *
+ * @return Hash code value for this object.
+ */
+ @Override
+ public int hashCode() {
+ int h = 31 * 17 + getName().hashCode();
+ h = 31 * h + getActions().hashCode();
+ if (endpoint != null) {
+ h = 31 * h + endpoint.hashCode();
+ }
+ return h;
+ }
+
+ /**
+ * WriteObject is called to save the state of this permission to a stream.
+ * The actions are serialized, and the superclass takes care of the name.
+ */
+ private synchronized void writeObject(java.io.ObjectOutputStream s) throws IOException {
+ if (endpoint != null) {
+ throw new NotSerializableException("cannot serialize");
+ }
+ // Write out the actions. The superclass takes care of the name
+ // call getActions to make sure actions field is initialized
+ if (actions == null) {
+ getActions();
+ }
+ s.defaultWriteObject();
+ }
+
+ /**
+ * readObject is called to restore the state of this permission from a
+ * stream.
+ */
+ private synchronized void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException {
+ // Read in the action, then initialize the rest
+ s.defaultReadObject();
+ setTransients(parseFilter(getName()), parseActions(actions));
+ }
+
+ /**
+ * Called by {@link EndpointPermission#implies(Permission)}.
+ *
+ * @return a dictionary of properties for this permission.
+ */
+ private Dictionary<String, Object> getProperties() {
+ return properties;
+ }
+}
+
+/**
+ * Stores a set of EndpointPermission permissions.
+ *
+ * @see java.security.Permission
+ * @see java.security.Permissions
+ * @see java.security.PermissionCollection
+ */
+final class EndpointPermissionCollection extends PermissionCollection {
+ static final long serialVersionUID = 662615640374640621L;
+ /**
+ * Table of permissions.
+ *
+ * @serial
+ * @GuardedBy this
+ */
+ private Map<String, EndpointPermission> permissions;
+
+ /**
+ * Boolean saying if "*" is in the collection.
+ *
+ * @serial
+ * @GuardedBy this
+ */
+ private boolean all_allowed;
+
+ /**
+ * Creates an empty EndpointPermissions object.
+ */
+ public EndpointPermissionCollection() {
+ permissions = new HashMap<String, EndpointPermission>();
+ all_allowed = false;
+ }
+
+ /**
+ * Adds a permission to this permission collection.
+ *
+ * @param permission The Permission object to add.
+ * @throws IllegalArgumentException If the specified permission is not a
+ * EndpointPermission object.
+ * @throws SecurityException If this {@code EndpointPermissionCollection}
+ * object has been marked read-only.
+ */
+ @Override
+ public void add(final Permission permission) {
+ if (!(permission instanceof EndpointPermission)) {
+ throw new IllegalArgumentException("invalid permission: " + permission);
+ }
+ if (isReadOnly()) {
+ throw new SecurityException("attempt to add a Permission to a " + "readonly PermissionCollection");
+ }
+
+ final EndpointPermission ep = (EndpointPermission) permission;
+ if (ep.endpoint != null) {
+ throw new IllegalArgumentException("cannot add to collection: " + ep);
+ }
+
+ final String name = ep.getName();
+ synchronized (this) {
+ /* select the bucket for the permission */
+ Map<String, EndpointPermission> pc = permissions;
+ final EndpointPermission existing = pc.get(name);
+
+ if (existing != null) {
+ final int oldMask = existing.action_mask;
+ final int newMask = ep.action_mask;
+ if (oldMask != newMask) {
+ pc.put(name, new EndpointPermission(name, oldMask | newMask));
+ }
+ } else {
+ pc.put(name, ep);
+ }
+
+ if (!all_allowed) {
+ if (name.equals("*")) {
+ all_allowed = true;
+ }
+ }
+ }
+ }
+
+ /**
+ * Determines if a set of permissions implies the permissions expressed in
+ * {@code permission}.
+ *
+ * @param permission The Permission object to compare.
+ * @return {@code true} if {@code permission} is a proper subset of a
+ * permission in the set; {@code false} otherwise.
+ */
+ @Override
+ public boolean implies(final Permission permission) {
+ if (!(permission instanceof EndpointPermission)) {
+ return false;
+ }
+ final EndpointPermission requested = (EndpointPermission) permission;
+ /* if requested permission has a filter, then it is an invalid argument */
+ if (requested.filter != null) {
+ return false;
+ }
+ int effective = EndpointPermission.ACTION_NONE;
+ Collection<EndpointPermission> perms;
+ synchronized (this) {
+ final int desired = requested.action_mask;
+ /* short circuit if the "*" Permission was added */
+ if (all_allowed) {
+ EndpointPermission ep = permissions.get("*");
+ if (ep != null) {
+ effective |= ep.action_mask;
+ if ((effective & desired) == desired) {
+ return true;
+ }
+ }
+ }
+ perms = permissions.values();
+ }
+
+ /* iterate one by one over permissions */
+ for (Iterator<EndpointPermission> iter = perms.iterator(); iter.hasNext();) {
+ if (iter.next().implies0(requested, effective)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns an enumeration of all the {@code EndpointPermission} objects in
+ * the container.
+ *
+ * @return Enumeration of all the EndpointPermission objects.
+ */
+ @Override
+ public synchronized Enumeration<Permission> elements() {
+ List<Permission> all = new ArrayList<Permission>(permissions.values());
+ return Collections.enumeration(all);
+ }
+
+ /* serialization logic */
+ private static final ObjectStreamField[] serialPersistentFields = {new ObjectStreamField("permissions", HashMap.class), new ObjectStreamField("all_allowed", Boolean.TYPE)};
+
+ private synchronized void writeObject(ObjectOutputStream out) throws IOException {
+ ObjectOutputStream.PutField pfields = out.putFields();
+ pfields.put("permissions", permissions);
+ pfields.put("all_allowed", all_allowed);
+ out.writeFields();
+ }
+
+ private synchronized void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
+ ObjectInputStream.GetField gfields = in.readFields();
+ @SuppressWarnings("unchecked")
+ HashMap<String, EndpointPermission> p = (HashMap<String, EndpointPermission>) gfields.get("permissions", new HashMap<String, EndpointPermission>());
+ permissions = p;
+ all_allowed = gfields.get("all_allowed", false);
+ }
+}
diff --git a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/ExportReference.java b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/ExportReference.java
new file mode 100644
index 000000000..c6b452b40
--- /dev/null
+++ b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/ExportReference.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) OSGi Alliance (2009, 2013). All Rights Reserved.
+ *
+ * Licensed 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.osgi.service.remoteserviceadmin;
+
+import org.osgi.annotation.versioning.ProviderType;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * An Export Reference associates a service with a local endpoint.
+ *
+ * The Export Reference can be used to reference an exported service. When the
+ * service is no longer exported, all methods must return {@code null}.
+ *
+ * @ThreadSafe
+ * @author $Id$
+ */
+@ProviderType
+public interface ExportReference {
+ /**
+ * Return the service being exported.
+ *
+ * @return The service being exported. Must be {@code null} when the service
+ * is no longer exported.
+ */
+ ServiceReference<?> getExportedService();
+
+ /**
+ * Return the Endpoint Description for the local endpoint.
+ *
+ * @return The Endpoint Description for the local endpoint. Must be
+ * {@code null} when the service is no longer exported.
+ */
+ EndpointDescription getExportedEndpoint();
+}
diff --git a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/ExportRegistration.java b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/ExportRegistration.java
new file mode 100644
index 000000000..885dc4442
--- /dev/null
+++ b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/ExportRegistration.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) OSGi Alliance (2009, 2013). All Rights Reserved.
+ *
+ * Licensed 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.osgi.service.remoteserviceadmin;
+
+import java.util.Map;
+import org.osgi.annotation.versioning.ProviderType;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * An Export Registration associates a service to a local endpoint.
+ *
+ * The Export Registration can be used to delete the endpoint associated with an
+ * this registration. It is created with the
+ * {@link RemoteServiceAdmin#exportService(ServiceReference,Map)} method.
+ *
+ * When this Export Registration has been closed, all methods must return
+ * {@code null}.
+ *
+ * @ThreadSafe
+ * @author $Id$
+ */
+@ProviderType
+public interface ExportRegistration {
+ /**
+ * Return the Export Reference for the exported service.
+ *
+ * @return The Export Reference for this registration, or <code>null</code>
+ * if this Import Registration is closed.
+ * @throws IllegalStateException When this registration was not properly
+ * initialized. See {@link #getException()}.
+ */
+ ExportReference getExportReference();
+
+ /**
+ * Update the endpoint represented by this {@link ExportRegistration} and
+ * return an updated {@link EndpointDescription}. If this method returns an
+ * updated {@link EndpointDescription}, then the object returned via
+ * {@link #getExportReference()} must also have been updated to return this
+ * new object. If this method does not return an updated
+ * {@link EndpointDescription} then the object returned via
+ * {@link #getExportReference()} should remain unchanged.
+ *
+ * When creating the updated {@link EndpointDescription} the
+ * {@link ServiceReference} originally passed to
+ * {@link RemoteServiceAdmin#exportService(ServiceReference, Map)} must be
+ * queried to pick up any changes to its service properties.
+ *
+ * If this argument is null then the original properties passed when
+ * creating this ExportRegistration should be used when constructing the
+ * updated {@link EndpointDescription}. Otherwise the new properties should
+ * be used, and replace the original properties for subsequent calls to the
+ * update method.
+ *
+ * @param properties properties to be merged with the current service
+ * properties for the {@link ServiceReference} represented by this
+ * {@link ExportRegistration}. If null is passed then the original
+ * properties passed to
+ * {@link RemoteServiceAdmin#exportService(ServiceReference, Map)}
+ * will be used.
+ * @return The updated {@link EndpointDescription} for this registration or
+ * null if there was a failure updating the endpoint. If a failure
+ * occurs then it can be accessed using {@link #getException()}.
+ * @throws IllegalStateException If this registration is closed, or when
+ * this registration was not properly initialized. See
+ * {@link #getException()}.
+ *
+ * @since 1.1
+ */
+ EndpointDescription update(Map<String, ?> properties);
+
+ /**
+ * Delete the local endpoint and disconnect any remote distribution
+ * providers. After this method returns, all methods must return
+ * {@code null}.
+ *
+ * This method has no effect when this registration has already been closed
+ * or is being closed.
+ */
+ void close();
+
+ /**
+ * Return the exception for any error during the export process.
+ *
+ * If the Remote Service Admin for some reasons is unable to properly
+ * initialize this registration, then it must return an exception from this
+ * method. If no error occurred, this method must return {@code null}.
+ *
+ * The error must be set before this Export Registration is returned.
+ * Asynchronously occurring errors must be reported to the log.
+ *
+ * @return The exception that occurred during the initialization of this
+ * registration or {@code null} if no exception occurred.
+ */
+ Throwable getException();
+}
diff --git a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/ImportReference.java b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/ImportReference.java
new file mode 100644
index 000000000..e94afd28c
--- /dev/null
+++ b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/ImportReference.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) OSGi Alliance (2009, 2013). All Rights Reserved.
+ *
+ * Licensed 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.osgi.service.remoteserviceadmin;
+
+import org.osgi.annotation.versioning.ProviderType;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * An Import Reference associates an active proxy service to a remote endpoint.
+ *
+ * The Import Reference can be used to reference an imported service. When the
+ * service is no longer imported, all methods must return {@code null}.
+ *
+ * @ThreadSafe
+ * @author $Id$
+ */
+@ProviderType
+public interface ImportReference {
+ /**
+ * Return the Service Reference for the proxy for the endpoint.
+ *
+ * @return The Service Reference to the proxy for the endpoint. Must be
+ * {@code null} when the service is no longer imported.
+ */
+ ServiceReference<?> getImportedService();
+
+ /**
+ * Return the Endpoint Description for the remote endpoint.
+ *
+ * @return The Endpoint Description for the remote endpoint. Must be
+ * {@code null} when the service is no longer imported.
+ */
+ EndpointDescription getImportedEndpoint();
+}
diff --git a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/ImportRegistration.java b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/ImportRegistration.java
new file mode 100644
index 000000000..18fbfc379
--- /dev/null
+++ b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/ImportRegistration.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) OSGi Alliance (2009, 2013). All Rights Reserved.
+ *
+ * Licensed 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.osgi.service.remoteserviceadmin;
+
+import org.osgi.annotation.versioning.ProviderType;
+
+/**
+ * An Import Registration associates an active proxy service to a remote
+ * endpoint.
+ *
+ * The Import Registration can be used to delete the proxy associated with an
+ * endpoint. It is created with the
+ * {@link RemoteServiceAdmin#importService(EndpointDescription)} method.
+ *
+ * When this Import Registration has been closed, all methods must return
+ * {@code null}.
+ *
+ * @ThreadSafe
+ * @author $Id$
+ */
+@ProviderType
+public interface ImportRegistration {
+ /**
+ * Return the Import Reference for the imported service.
+ *
+ * @return The Import Reference for this registration, or <code>null</code>
+ * if this Import Registration is closed.
+ * @throws IllegalStateException When this registration was not properly
+ * initialized. See {@link #getException()}.
+ */
+ ImportReference getImportReference();
+
+ /**
+ * Update the local service represented by this {@link ImportRegistration}.
+ * After this method returns the {@link EndpointDescription} returned via
+ * {@link #getImportReference()} must have been updated.
+ *
+ * @param endpoint The updated endpoint
+ *
+ * @return <code>true</code> if the endpoint was successfully updated,
+ * <code>false</code> otherwise. If the update fails then the
+ * failure can be retrieved from {@link #getException()}.
+ *
+ * @throws IllegalStateException When this registration is closed, or if it
+ * was not properly initialized. See {@link #getException()}.
+ * @throws IllegalArgumentException When the supplied
+ * {@link EndpointDescription} does not represent the same endpoint
+ * as this {@link ImportRegistration}.
+ *
+ * @since 1.1
+ */
+ boolean update(EndpointDescription endpoint);
+
+ /**
+ * Close this Import Registration. This must close the connection to the
+ * endpoint and unregister the proxy. After this method returns, all other
+ * methods must return {@code null}.
+ *
+ * This method has no effect when this registration has already been closed
+ * or is being closed.
+ */
+ void close();
+
+ /**
+ * Return the exception for any error during the import process.
+ *
+ * If the Remote Service Admin for some reasons is unable to properly
+ * initialize this registration, then it must return an exception from this
+ * method. If no error occurred, this method must return {@code null}.
+ *
+ * The error must be set before this Import Registration is returned.
+ * Asynchronously occurring errors must be reported to the log.
+ *
+ * @return The exception that occurred during the initialization of this
+ * registration or {@code null} if no exception occurred.
+ */
+ Throwable getException();
+}
diff --git a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/RemoteConstants.java b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/RemoteConstants.java
new file mode 100644
index 000000000..deb46d4f5
--- /dev/null
+++ b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/RemoteConstants.java
@@ -0,0 +1,237 @@
+/*
+ * Copyright (c) OSGi Alliance (2009, 2013). All Rights Reserved.
+ *
+ * Licensed 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.osgi.service.remoteserviceadmin;
+
+import org.osgi.framework.Constants;
+
+/**
+ * Provide the definition of the constants used in the Remote Service Admin
+ * specification.
+ *
+ * @Immutable
+ * @author $Id$
+ */
+public class RemoteConstants {
+ private RemoteConstants() {
+ // non-instantiable
+ }
+
+ /**
+ * Service property identifying the configuration types supported by a
+ * distribution provider. Registered by the distribution provider on one of
+ * its services to indicate the supported configuration types.
+ *
+ * <p>
+ * The value of this property must be of type {@code String},
+ * {@code String[]}, or {@code Collection} of {@code String}.
+ *
+ * @see "Remote Services Specification"
+ */
+ public static final String REMOTE_CONFIGS_SUPPORTED = Constants.REMOTE_CONFIGS_SUPPORTED;
+
+ /**
+ * Service property identifying the intents supported by a distribution
+ * provider. Registered by the distribution provider on one of its services
+ * to indicate the vocabulary of implemented intents.
+ *
+ * <p>
+ * The value of this property must be of type {@code String},
+ * {@code String[]}, or {@code Collection} of {@code String}.
+ *
+ * @see "Remote Services Specification"
+ */
+ public static final String REMOTE_INTENTS_SUPPORTED = Constants.REMOTE_INTENTS_SUPPORTED;
+
+ /**
+ * Service property identifying the configuration types that should be used
+ * to export the service. Each configuration type represents the
+ * configuration parameters for an endpoint. A distribution provider should
+ * create an endpoint for each configuration type that it supports.
+ *
+ * <p>
+ * This property may be supplied in the {@code properties}
+ * {@code Dictionary} object passed to the
+ * {@code BundleContext.registerService} method. The value of this property
+ * must be of type {@code String}, {@code String[]}, or {@code Collection}
+ * of {@code String}.
+ *
+ * @see "Remote Services Specification"
+ */
+ public static final String SERVICE_EXPORTED_CONFIGS = Constants.SERVICE_EXPORTED_CONFIGS;
+
+ /**
+ * Service property identifying the intents that the distribution provider
+ * must implement to distribute the service. Intents listed in this property
+ * are reserved for intents that are critical for the code to function
+ * correctly, for example, ordering of messages. These intents should not be
+ * configurable.
+ *
+ * <p>
+ * This property may be supplied in the {@code properties}
+ * {@code Dictionary} object passed to the
+ * {@code BundleContext.registerService} method. The value of this property
+ * must be of type {@code String}, {@code String[]}, or {@code Collection}
+ * of {@code String}.
+ *
+ * @see "Remote Services Specification"
+ */
+ public static final String SERVICE_EXPORTED_INTENTS = Constants.SERVICE_EXPORTED_INTENTS;
+
+ /**
+ * Service property identifying the extra intents that the distribution
+ * provider must implement to distribute the service. This property is
+ * merged with the {@code service.exported.intents} property before the
+ * distribution provider interprets the listed intents; it has therefore the
+ * same semantics but the property should be configurable so the
+ * administrator can choose the intents based on the topology. Bundles
+ * should therefore make this property configurable, for example through the
+ * Configuration Admin service.
+ *
+ * <p>
+ * This property may be supplied in the {@code properties}
+ * {@code Dictionary} object passed to the
+ * {@code BundleContext.registerService} method. The value of this property
+ * must be of type {@code String}, {@code String[]}, or {@code Collection}
+ * of {@code String}.
+ *
+ * @see "Remote Services Specification"
+ */
+ public static final String SERVICE_EXPORTED_INTENTS_EXTRA = Constants.SERVICE_EXPORTED_INTENTS_EXTRA;
+
+ /**
+ * Service property marking the service for export. It defines the
+ * interfaces under which this service can be exported. This list must be a
+ * subset of the types under which the service was registered. The single
+ * value of an asterisk ({@code '*'} &#92;u002A) indicates all the interface
+ * types under which the service was registered excluding the non-interface
+ * types. It is strongly recommended to only export interface types and not
+ * concrete classes due to the complexity of creating proxies for some type
+ * of concrete classes.
+ *
+ * <p>
+ * This property may be supplied in the {@code properties}
+ * {@code Dictionary} object passed to the
+ * {@code BundleContext.registerService} method. The value of this property
+ * must be of type {@code String}, {@code String[]}, or {@code Collection}
+ * of {@code String}.
+ *
+ * @see "Remote Services Specification"
+ */
+ public static final String SERVICE_EXPORTED_INTERFACES = Constants.SERVICE_EXPORTED_INTERFACES;
+
+ /**
+ * Service property identifying the service as imported. This service
+ * property must be set by a distribution provider to any value when it
+ * registers the endpoint proxy as an imported service. A bundle can use
+ * this property to filter out imported services.
+ *
+ * <p>
+ * The value of this property may be of any type.
+ *
+ * @see "Remote Services Specification"
+ */
+ public static final String SERVICE_IMPORTED = Constants.SERVICE_IMPORTED;
+
+ /**
+ * Service property identifying the configuration types used to import the
+ * service. Any associated properties for this configuration types must be
+ * properly mapped to the importing system. For example, a URL in these
+ * properties must point to a valid resource when used in the importing
+ * framework. If multiple configuration types are listed in this property,
+ * then they must be synonyms for exactly the same remote endpoint that is
+ * used to export this service.
+ *
+ * <p>
+ * The value of this property must be of type {@code String},
+ * {@code String[]}, or {@code Collection} of {@code String}.
+ *
+ * @see "Remote Services Specification"
+ * @see #SERVICE_EXPORTED_CONFIGS
+ */
+ public static final String SERVICE_IMPORTED_CONFIGS = Constants.SERVICE_IMPORTED_CONFIGS;
+
+ /**
+ * Service property identifying the intents that this service implement.
+ * This property has a dual purpose:
+ * <ul>
+ * <li>A bundle can use this service property to notify the distribution
+ * provider that these intents are already implemented by the exported
+ * service object.</li>
+ * <li>A distribution provider must use this property to convey the combined
+ * intents of: The exporting service, and the intents that the exporting
+ * distribution provider adds, and the intents that the importing
+ * distribution provider adds.</li>
+ * </ul>
+ *
+ * To export a service, a distribution provider must expand any qualified
+ * intents. Both the exporting and importing distribution providers must
+ * recognize all intents before a service can be distributed.
+ *
+ * The value of this property must be of type {@code String},
+ * {@code String[]}, or {@code Collection} of {@code String}.
+ *
+ * @see "Remote Services Specification"
+ */
+ public static final String SERVICE_INTENTS = Constants.SERVICE_INTENTS;
+
+ /* The above are from Ch. 13 Remote Services specification. */
+
+ /**
+ * Endpoint property identifying the id for this endpoint. This service
+ * property must always be set.
+ *
+ * <p>
+ * The value of this property must be of type {@code String}.
+ */
+ public final static String ENDPOINT_ID = "endpoint.id";
+
+ /**
+ * Endpoint property identifying the service id of the exported service. Can
+ * be absent or 0 if the corresponding endpoint is not for an OSGi service.
+ *
+ * <p>
+ * The value of this property must be of type {@code Long}.
+ */
+ public final static String ENDPOINT_SERVICE_ID = "endpoint.service.id";
+
+ /**
+ * Endpoint property identifying the universally unique id of the exporting
+ * framework. Can be absent if the corresponding endpoint is not for an OSGi
+ * service.
+ *
+ * <p>
+ * The value of this property must be of type {@code String}.
+ */
+ public final static String ENDPOINT_FRAMEWORK_UUID = "endpoint.framework.uuid";
+
+ /**
+ * Prefix for an endpoint property identifying the interface Java package
+ * version for an interface. For example, the property
+ * {@code endpoint.package.version.com.acme=1.3} describes the version of
+ * the package for the {@code com.acme.Foo} interface. This endpoint
+ * property for an interface package does not have to be set. If not set,
+ * the value must be assumed to be 0.
+ *
+ * <p>
+ * Since endpoint properties are stored in a case insensitive map, case
+ * variants of a package name are folded together.
+ *
+ * <p>
+ * The value of properties having this prefix must be of type {@code String}.
+ */
+ public final static String ENDPOINT_PACKAGE_VERSION_ = "endpoint.package.version.";
+}
diff --git a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/RemoteServiceAdmin.java b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/RemoteServiceAdmin.java
new file mode 100644
index 000000000..92eba8188
--- /dev/null
+++ b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/RemoteServiceAdmin.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) OSGi Alliance (2009, 2013). All Rights Reserved.
+ *
+ * Licensed 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.osgi.service.remoteserviceadmin;
+
+import java.util.Collection;
+import java.util.Map;
+import org.osgi.annotation.versioning.ProviderType;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * A Remote Service Admin manages the import and export of services.
+ *
+ * A Distribution Provider can expose a control interface. This interface allows
+ * a Topology Manager to control the export and import of services.
+ *
+ * The API allows a Topology Manager to export a service, to import a service,
+ * and find out about the current imports and exports.
+ *
+ * @ThreadSafe
+ * @author $Id$
+ */
+@ProviderType
+public interface RemoteServiceAdmin {
+
+ /**
+ * Export a service to a given Endpoint. The Remote Service Admin must
+ * create an Endpoint from the given description that can be used by other
+ * Distribution Providers to connect to this Remote Service Admin and use
+ * the exported service.
+ *
+ * The property keys of a Service Reference are case insensitive while the
+ * property keys of the specified {@code properties} map are case sensitive.
+ * A property key in the specified {@code properties} map must therefore
+ * override any case variant property key in the properties of the specified
+ * Service Reference.
+ *
+ * <p>
+ * If the caller does not have the appropriate
+ * {@code EndpointPermission[endpoint,EXPORT]} for an Endpoint, and the Java
+ * Runtime Environment supports permissions, then the
+ * {@link ExportRegistration#getException() getException} method on the
+ * corresponding returned {@link ExportRegistration} will return a
+ * {@code SecurityException}.
+ *
+ * @param reference The Service Reference to export.
+ * @param properties The properties to create a local Endpoint that can be
+ * implemented by this Remote Service Admin. If this is {@code null},
+ * the Endpoint will be determined by the properties on the service.
+ * The properties are the same as given for an exported service. They
+ * override any properties in the specified Service Reference (case
+ * insensitive). The properties {@code objectClass} and
+ * {@code service.id}, in any case variant, are ignored. Those
+ * properties in the Service Reference cannot be overridden. This
+ * parameter can be {@code null}, this should be treated as an empty
+ * map.
+ * @return A {@code Collection} of {@link ExportRegistration}s for the
+ * specified Service Reference and properties. Multiple Export
+ * Registrations may be returned because a single service can be
+ * exported to multiple Endpoints depending on the available
+ * configuration type properties and the intents that they support.
+ * The result is never {@code null} but may be empty if this Remove
+ * Service Admin does not recognize any of the configuration types,
+ * or if they Remote Service Admin cannot support the relevant
+ * intents.
+ * @throws IllegalArgumentException If any of the properties for this
+ * configuration type has a value that is not syntactically correct,
+ * or if the service properties and the overlaid properties do not
+ * contain a {@link RemoteConstants#SERVICE_EXPORTED_INTERFACES}
+ * entry. This means that implementations must not ignore invalid
+ * values for property names that they recognise.
+ */
+ Collection<ExportRegistration> exportService(ServiceReference<?> reference, Map<String, ?> properties);
+
+ /**
+ * Import a service from an Endpoint. The Remote Service Admin must use the
+ * given Endpoint to create a proxy. This method can return {@code null} if
+ * the service could not be imported.
+ *
+ * @param endpoint The Endpoint Description to be used for import.
+ * @return An Import Registration that combines the Endpoint Description and
+ * the Service Reference or {@code null} if the Endpoint could not
+ * be imported.
+ * @throws SecurityException If the caller does not have the appropriate
+ * {@code EndpointPermission[endpoint,IMPORT]} for the Endpoint, and
+ * the Java Runtime Environment supports permissions.
+ */
+ ImportRegistration importService(EndpointDescription endpoint);
+
+ /**
+ * Return the currently active Export References.
+ *
+ * <p>
+ * If the caller does not have the appropriate
+ * {@code EndpointPermission[endpoint,READ]} for an Endpoint, and the Java
+ * Runtime Environment supports permissions, then returned collection will
+ * not contain a reference to the exported Endpoint.
+ *
+ * @return A {@code Collection} of {@link ExportReference}s that are
+ * currently active.
+ */
+ Collection<ExportReference> getExportedServices();
+
+ /**
+ * Return the currently active Import References.
+ *
+ * <p>
+ * If the caller does not have the appropriate
+ * {@code EndpointPermission[endpoint,READ]} for an Endpoint, and the Java
+ * Runtime Environment supports permissions, then returned collection will
+ * not contain a reference to the imported Endpoint.
+ *
+ * @return A {@code Collection} of {@link ImportReference}s that are
+ * currently active.
+ */
+ Collection<ImportReference> getImportedEndpoints();
+
+}
diff --git a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/RemoteServiceAdminEvent.java b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/RemoteServiceAdminEvent.java
new file mode 100644
index 000000000..4ae002bdc
--- /dev/null
+++ b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/RemoteServiceAdminEvent.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) OSGi Alliance (2009, 2013). All Rights Reserved.
+ *
+ * Licensed 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.osgi.service.remoteserviceadmin;
+
+import org.osgi.framework.Bundle;
+
+/**
+ * Provides the event information for a Remote Service Admin event.
+ *
+ * @Immutable
+ * @author $Id$
+ */
+public class RemoteServiceAdminEvent {
+ /**
+ * Add an import registration. The Remote Service Admin will send this event
+ * when it imports a service. When the {@link RemoteServiceAdminListener}
+ * service is registered, the Remote Service Admin must notify the listener
+ * of all existing Import Registrations.
+ *
+ */
+ public static final int IMPORT_REGISTRATION = 1;
+
+ /**
+ * Add an export registration. The Remote Service Admin will send this event
+ * when it exports a service. When the {@link RemoteServiceAdminListener}
+ * service is registered, the Remote Service Admin must notify the listener
+ * of all existing Export Registrations.
+ */
+ public static final int EXPORT_REGISTRATION = 2;
+
+ /**
+ * Remove an export registration. The Remote Service Admin will send this
+ * event when it removes the export of a service.
+ *
+ */
+ public static final int EXPORT_UNREGISTRATION = 3;
+
+ /**
+ * Remove an import registration. The Remote Service Admin will send this
+ * event when it removes the import of a service.
+ *
+ */
+ public static final int IMPORT_UNREGISTRATION = 4;
+
+ /**
+ * A fatal importing error occurred. The Import Registration has been
+ * closed.
+ */
+ public static final int IMPORT_ERROR = 5;
+
+ /**
+ * A fatal exporting error occurred. The Export Registration has been
+ * closed.
+ */
+ public static final int EXPORT_ERROR = 6;
+
+ /**
+ * A problematic situation occurred, the export is still active.
+ */
+ public static final int EXPORT_WARNING = 7;
+ /**
+ * A problematic situation occurred, the import is still active.
+ */
+ public static final int IMPORT_WARNING = 8;
+
+ /**
+ * Update an import registration. The Remote Service Admin will send this
+ * event when it updates a service.
+ */
+ public static final int IMPORT_UPDATE = 9;
+
+ /**
+ * Update an export registration. The Remote Service Admin will send this
+ * event when it exports a service.
+ */
+ public static final int EXPORT_UPDATE = 10;
+
+ private final ImportReference importReference;
+ private final ExportReference exportReference;
+ private final Throwable exception;
+ private final int type;
+ private final Bundle source;
+
+ /**
+ * Private constructor.
+ *
+ * @param type The event type
+ * @param source The source bundle, must not be {@code null}.
+ * @param importReference The importReference, can be {@code null}.
+ * @param exportReference The exportReference, can be {@code null}.
+ * @param exception Any exceptions encountered, can be {@code null}
+ */
+ private RemoteServiceAdminEvent(int type, Bundle source, ImportReference importReference, ExportReference exportReference, Throwable exception) {
+ if (source == null) {
+ throw new NullPointerException("source must not be null");
+ }
+ this.type = type;
+ this.source = source;
+ this.importReference = importReference;
+ this.exportReference = exportReference;
+ this.exception = exception;
+ }
+
+ /**
+ * Create a Remote Service Admin Event for an export notification.
+ *
+ * @param type The event type.
+ * @param source The source bundle, must not be {@code null}.
+ * @param exportReference The exportReference, can not be {@code null}.
+ * @param exception Any exceptions encountered, can be {@code null}.
+ */
+ public RemoteServiceAdminEvent(int type, Bundle source, ExportReference exportReference, Throwable exception) {
+ this(type, source, null, exportReference, exception);
+ }
+
+ /**
+ * Create a Remote Service Admin Event for an import notification.
+ *
+ * @param type The event type.
+ * @param source The source bundle, must not be {@code null}.
+ * @param importReference The importReference, can not be {@code null}.
+ * @param exception Any exceptions encountered, can be {@code null}.
+ */
+ public RemoteServiceAdminEvent(int type, Bundle source, ImportReference importReference, Throwable exception) {
+ this(type, source, importReference, null, exception);
+ }
+
+ /**
+ * Return the Import Reference for this event.
+ *
+ * @return The Import Reference or {@code null}.
+ */
+ public ImportReference getImportReference() {
+ return importReference;
+ }
+
+ /**
+ * Return the Export Reference for this event.
+ *
+ * @return The Export Reference or {@code null}.
+ */
+ public ExportReference getExportReference() {
+ return exportReference;
+ }
+
+ /**
+ * Return the exception for this event.
+ *
+ * @return The exception or {@code null}.
+ */
+ public Throwable getException() {
+ return exception;
+ }
+
+ /**
+ * Return the type of this event.
+ *
+ * @return The type of this event.
+ */
+ public int getType() {
+ return type;
+ }
+
+ /**
+ * Return the bundle source of this event.
+ *
+ * @return The bundle source of this event.
+ */
+ public Bundle getSource() {
+ return source;
+ }
+}
diff --git a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/RemoteServiceAdminListener.java b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/RemoteServiceAdminListener.java
new file mode 100644
index 000000000..c5c7ce06a
--- /dev/null
+++ b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/RemoteServiceAdminListener.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) OSGi Alliance (2009, 2013). All Rights Reserved.
+ *
+ * Licensed 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.osgi.service.remoteserviceadmin;
+
+import org.osgi.annotation.versioning.ConsumerType;
+
+/**
+ * A {@link RemoteServiceAdminEvent} listener is notified synchronously of any
+ * export or import registrations and unregistrations.
+ *
+ * <p>
+ * If the Java Runtime Environment supports permissions, then filtering is done.
+ * {@code RemoteServiceAdminEvent} objects are only delivered to the listener if
+ * the bundle which defines the listener object's class has the appropriate
+ * {@code EndpointPermission[endpoint,READ]} for the endpoint referenced by the
+ * event.
+ *
+ *
+ * @see RemoteServiceAdminEvent
+ * @ThreadSafe
+ * @author $Id$
+ */
+@ConsumerType
+public interface RemoteServiceAdminListener {
+ /**
+ * Receive notification of any export or import registrations and
+ * unregistrations as well as errors and warnings.
+ *
+ * @param event The {@link RemoteServiceAdminEvent} object.
+ */
+ void remoteAdminEvent(RemoteServiceAdminEvent event);
+}
diff --git a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/namespace/DiscoveryNamespace.java b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/namespace/DiscoveryNamespace.java
new file mode 100644
index 000000000..f6542b65b
--- /dev/null
+++ b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/namespace/DiscoveryNamespace.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) OSGi Alliance (2014). All Rights Reserved.
+ *
+ * Licensed 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.osgi.service.remoteserviceadmin.namespace;
+
+import org.osgi.resource.Namespace;
+
+/**
+ * Remote Services Discovery Provider Capability and Requirement Namespace.
+ *
+ * <p>
+ * This class defines the names for the attributes and directives for this
+ * namespace.
+ *
+ * @Immutable
+ * @author $Id$
+ */
+public final class DiscoveryNamespace extends Namespace {
+
+ /**
+ * Namespace name for Remote Services discovery provider capabilities and
+ * requirements.
+ */
+ public static final String DISCOVERY_NAMESPACE = "osgi.remoteserviceadmin.discovery";
+
+ /**
+ * The capability attribute used to specify the discovery protocols
+ * supported by this discovery provider. The value of this attribute must be
+ * of type {@code String} or {@code List<String>}.
+ */
+ public static final String CAPABILITY_PROTOCOLS_ATTRIBUTE = "protocols";
+
+ private DiscoveryNamespace() {
+ // empty
+ }
+}
diff --git a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/namespace/DistributionNamespace.java b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/namespace/DistributionNamespace.java
new file mode 100644
index 000000000..e87df13b4
--- /dev/null
+++ b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/namespace/DistributionNamespace.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) OSGi Alliance (2014). All Rights Reserved.
+ *
+ * Licensed 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.osgi.service.remoteserviceadmin.namespace;
+
+import org.osgi.resource.Namespace;
+
+/**
+ * Remote Services Distribution Provider Capability and Requirement Namespace.
+ *
+ * <p>
+ * This class defines the names for the attributes and directives for this
+ * namespace.
+ *
+ * @Immutable
+ * @author $Id$
+ */
+public final class DistributionNamespace extends Namespace {
+
+ /**
+ * Namespace name for Remote Services distribution provider capabilities and
+ * requirements.
+ */
+ public static final String DISTRIBUTION_NAMESPACE = "osgi.remoteserviceadmin.distribution";
+
+ /**
+ * The capability attribute used to specify the config types supported by
+ * this distribution provider. The value of this attribute must be of type
+ * {@code String} or {@code List<String>}.
+ */
+ public static final String CAPABILITY_CONFIGS_ATTRIBUTE = "configs";
+
+ private DistributionNamespace() {
+ // empty
+ }
+}
diff --git a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/namespace/TopologyNamespace.java b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/namespace/TopologyNamespace.java
new file mode 100644
index 000000000..de8a882b8
--- /dev/null
+++ b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/namespace/TopologyNamespace.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) OSGi Alliance (2014). All Rights Reserved.
+ *
+ * Licensed 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.osgi.service.remoteserviceadmin.namespace;
+
+import org.osgi.resource.Namespace;
+
+/**
+ * Remote Services Topology Manager Capability and Requirement Namespace.
+ *
+ * <p>
+ * This class defines the names for the attributes and directives for this
+ * namespace.
+ *
+ * @Immutable
+ * @author $Id$
+ */
+public final class TopologyNamespace extends Namespace {
+
+ /**
+ * Namespace name for Remote Services topology manager capabilities and
+ * requirements.
+ */
+ public static final String TOPOLOGY_NAMESPACE = "osgi.remoteserviceadmin.topology";
+
+ /**
+ * The capability attribute used to specify the policy or policies supported
+ * by this topology manager. The value of this attribute must be of type
+ * {@code String} or {@code List<String>}. Policy names are typically
+ * implementation specific, however the Remote Services Specification
+ * defines the <em>promiscuous</em> and <em>fail-over</em> policies for
+ * common use cases.
+ */
+ public static final String CAPABILITY_POLICY_ATTRIBUTE = "policy";
+
+ /**
+ * The attribute value for Topology managers with a promiscuous policy
+ *
+ * @see TopologyNamespace#CAPABILITY_POLICY_ATTRIBUTE
+ */
+ public static final String PROMISCUOUS_POLICY = "promiscuous";
+
+ /**
+ * The attribute value for Topology managers with a fail-over policy
+ *
+ * @see TopologyNamespace#CAPABILITY_POLICY_ATTRIBUTE
+ */
+ public static final String FAIL_OVER_POLICY = "fail-over";
+
+ private TopologyNamespace() {
+ // empty
+ }
+}
diff --git a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/namespace/package-info.java b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/namespace/package-info.java
new file mode 100644
index 000000000..5318b11c8
--- /dev/null
+++ b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/namespace/package-info.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) OSGi Alliance (2014). All Rights Reserved.
+ *
+ * Licensed 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.
+ */
+
+/**
+ * Remote Service Admin Namespaces Version 1.0.
+ *
+ * <p>
+ * Bundles should not need to import this package at runtime since all
+ * the types in this package just contain constants for capability and
+ * requirement namespaces specified by the OSGi Alliance.
+ *
+ * @version 1.0
+ * @author $Id$
+ */
+
+@Version("1.0.0")
+package org.osgi.service.remoteserviceadmin.namespace;
+
+import org.osgi.annotation.versioning.Version;
+
diff --git a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/namespace/packageinfo b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/namespace/packageinfo
new file mode 100644
index 000000000..9ad81f6fa
--- /dev/null
+++ b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/namespace/packageinfo
@@ -0,0 +1 @@
+version 1.0.0
diff --git a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/package-info.java b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/package-info.java
new file mode 100644
index 000000000..0581bb37a
--- /dev/null
+++ b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/package-info.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) OSGi Alliance (2010, 2013). All Rights Reserved.
+ *
+ * Licensed 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.
+ */
+
+/**
+ * Remote Service Admin Package Version 1.1.
+ *
+ * <p>
+ * Bundles wishing to use this package must list the package in the
+ * Import-Package header of the bundle's manifest. This package has two types of
+ * users: the consumers that use the API in this package and the providers that
+ * implement the API in this package.
+ *
+ * <p>
+ * Example import for consumers using the API in this package:
+ * <p>
+ * {@code Import-Package: org.osgi.service.remoteserviceadmin; version="[1.1,2.0)"}
+ * <p>
+ * Example import for providers implementing the API in this package:
+ * <p>
+ * {@code Import-Package: org.osgi.service.remoteserviceadmin; version="[1.1,1.2)"}
+ *
+ * @version 1.1
+ * @author $Id$
+ */
+
+@Version("1.1.0")
+package org.osgi.service.remoteserviceadmin;
+
+import org.osgi.annotation.versioning.Version;
+
diff --git a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/packageinfo b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/packageinfo
index e39f61624..e39f61624 100644
--- a/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/org/osgi/service/remoteserviceadmin/packageinfo
+++ b/osgi/bundles/org.eclipse.osgi.services.remoteserviceadmin/src/org/osgi/service/remoteserviceadmin/packageinfo

Back to the top