summaryrefslogtreecommitdiffstats
path: root/sca-java-2.x/trunk/modules/node-impl-osgi
diff options
context:
space:
mode:
authorrfeng <rfeng@13f79535-47bb-0310-9956-ffa450edef68>2010-01-09 18:00:24 +0000
committerrfeng <rfeng@13f79535-47bb-0310-9956-ffa450edef68>2010-01-09 18:00:24 +0000
commitde3ec14e972052db72a3fd9589c898cf3ae0ae26 (patch)
tree12bc5ebe1034ca71a59e0faf1596f8b76cb5948b /sca-java-2.x/trunk/modules/node-impl-osgi
parent9c79f7307e589f0e4921f7ec1505fd0bff3eb9f1 (diff)
Update to the latest version of OSGi enterprise draft specs
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@897502 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'sca-java-2.x/trunk/modules/node-impl-osgi')
-rw-r--r--sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/osgi/remoteserviceadmin/impl/EndpointHelper.java6
-rw-r--r--sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/osgi/remoteserviceadmin/impl/EndpointIntrospector.java7
-rw-r--r--sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/osgi/remoteserviceadmin/impl/ExportRegistrationImpl.java17
-rw-r--r--sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/osgi/remoteserviceadmin/impl/ImportRegistrationImpl.java2
-rw-r--r--sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/osgi/remoteserviceadmin/impl/OSGiServiceExporter.java4
-rw-r--r--sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/osgi/remoteserviceadmin/impl/RemoteServiceAdminImpl.java20
-rw-r--r--sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/osgi/service/discovery/impl/DomainDiscoveryService.java19
-rw-r--r--sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/osgi/service/discovery/impl/LocalDiscoveryService.java16
-rw-r--r--sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/osgi/service/remoteserviceadmin/EndpointDescription.java153
-rw-r--r--sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/osgi/service/remoteserviceadmin/EndpointPermission.java624
-rw-r--r--sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/osgi/service/remoteserviceadmin/RemoteConstants.java41
-rw-r--r--sca-java-2.x/trunk/modules/node-impl-osgi/src/test/resources/calculator/dosgi/OSGI-INF/remote-service/calculator-service-descriptions.xml82
12 files changed, 394 insertions, 597 deletions
diff --git a/sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/osgi/remoteserviceadmin/impl/EndpointHelper.java b/sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/osgi/remoteserviceadmin/impl/EndpointHelper.java
index 3a21674139..949d2d8af7 100644
--- a/sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/osgi/remoteserviceadmin/impl/EndpointHelper.java
+++ b/sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/osgi/remoteserviceadmin/impl/EndpointHelper.java
@@ -67,11 +67,11 @@ public class EndpointHelper {
String serviceID = (String)props.get(Constants.SERVICE_ID);
if (serviceID != null) {
- props.put(RemoteConstants.ENDPOINT_ID, Long.parseLong(serviceID));
+ props.put(RemoteConstants.ENDPOINT_SERVICE_ID, Long.parseLong(serviceID));
}
- props.put(RemoteConstants.ENDPOINT_URI, endpoint.getURI());
+ props.put(RemoteConstants.ENDPOINT_ID, endpoint.getURI());
// FIXME: [rfeng] How to pass in the remote service id from the endpoint XML
- props.put(RemoteConstants.SERVICE_EXPORTED_CONFIGS, new String[] {"org.osgi.sca"});
+ props.put(RemoteConstants.SERVICE_IMPORTED_CONFIGS, new String[] {"org.osgi.sca"});
props.put(Endpoint.class.getName(), endpoint);
List<String> interfaces = getInterfaces(endpoint);
props.put(Constants.OBJECTCLASS, interfaces.toArray(new String[interfaces.size()]));
diff --git a/sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/osgi/remoteserviceadmin/impl/EndpointIntrospector.java b/sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/osgi/remoteserviceadmin/impl/EndpointIntrospector.java
index bfc5b97ee8..916761f129 100644
--- a/sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/osgi/remoteserviceadmin/impl/EndpointIntrospector.java
+++ b/sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/osgi/remoteserviceadmin/impl/EndpointIntrospector.java
@@ -425,10 +425,13 @@ public class EndpointIntrospector {
JavaInterfaceContract interfaceContract = javaInterfaceFactory.createJavaInterfaceContract();
Class<?> interfaceClass = bundle.loadClass(intf);
JavaInterface javaInterface = javaInterfaceFactory.createJavaInterface(interfaceClass);
+ // [rfeng] For OSGi, the interfaces should be marked as remote
+ javaInterface.setRemotable(true);
interfaceContract.setInterface(javaInterface);
if (javaInterface.getCallbackClass() != null) {
- interfaceContract.setCallbackInterface(javaInterfaceFactory.createJavaInterface(javaInterface
- .getCallbackClass()));
+ JavaInterface callbackInterface = javaInterfaceFactory.createJavaInterface(javaInterface.getCallbackClass());
+ callbackInterface.setRemotable(true);
+ interfaceContract.setCallbackInterface(callbackInterface);
}
return interfaceContract;
}
diff --git a/sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/osgi/remoteserviceadmin/impl/ExportRegistrationImpl.java b/sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/osgi/remoteserviceadmin/impl/ExportRegistrationImpl.java
index 9b31931b6c..2335d31020 100644
--- a/sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/osgi/remoteserviceadmin/impl/ExportRegistrationImpl.java
+++ b/sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/osgi/remoteserviceadmin/impl/ExportRegistrationImpl.java
@@ -30,10 +30,8 @@ import org.osgi.service.remoteserviceadmin.ExportRegistration;
*/
public class ExportRegistrationImpl implements ExportRegistration {
private Node node;
- private ServiceReference exportedService;
- private EndpointDescription endpointDescription;
- private Throwable exception;
private ExportReference exportReference;
+ private Throwable exception;
/**
* @param exportedService
@@ -46,8 +44,7 @@ public class ExportRegistrationImpl implements ExportRegistration {
Throwable exception) {
super();
this.node = node;
- this.exportedService = exportedService;
- this.endpointDescription = endpointDescription;
+ this.exportReference = new ExportReferenceImpl(exportedService, endpointDescription);
this.exception = exception;
}
@@ -68,16 +65,15 @@ public class ExportRegistrationImpl implements ExportRegistration {
node = null;
}
exception = null;
- endpointDescription = null;
- exportedService = null;
+ exportReference = new ExportReferenceImpl(null, null);
}
public ServiceReference getExportedService() {
- return exportedService;
+ return exportReference.getExportedService();
}
public EndpointDescription getEndpointDescription() {
- return endpointDescription;
+ return exportReference.getExportedEndpoint();
}
public Throwable getException() {
@@ -89,8 +85,7 @@ public class ExportRegistrationImpl implements ExportRegistration {
}
public ExportReference getExportReference() throws IllegalStateException {
- // TODO Auto-generated method stub
- return null;
+ return exportReference;
}
}
diff --git a/sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/osgi/remoteserviceadmin/impl/ImportRegistrationImpl.java b/sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/osgi/remoteserviceadmin/impl/ImportRegistrationImpl.java
index 2526f70a6b..8961d031cc 100644
--- a/sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/osgi/remoteserviceadmin/impl/ImportRegistrationImpl.java
+++ b/sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/osgi/remoteserviceadmin/impl/ImportRegistrationImpl.java
@@ -67,7 +67,7 @@ public class ImportRegistrationImpl implements ImportRegistration {
node = null;
}
exception = null;
- importReference = null;
+ importReference = new ImportReferenceImpl(null, null);
}
public Throwable getException() {
diff --git a/sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/osgi/remoteserviceadmin/impl/OSGiServiceExporter.java b/sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/osgi/remoteserviceadmin/impl/OSGiServiceExporter.java
index 49dc8c7461..b644ca14c9 100644
--- a/sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/osgi/remoteserviceadmin/impl/OSGiServiceExporter.java
+++ b/sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/osgi/remoteserviceadmin/impl/OSGiServiceExporter.java
@@ -25,7 +25,7 @@ import static org.apache.tuscany.sca.osgi.remoteserviceadmin.impl.OSGiHelper.get
import static org.apache.tuscany.sca.osgi.remoteserviceadmin.impl.OSGiHelper.getOSGiProperties;
import static org.osgi.framework.Constants.SERVICE_ID;
import static org.osgi.service.remoteserviceadmin.RemoteConstants.ENDPOINT_FRAMEWORK_UUID;
-import static org.osgi.service.remoteserviceadmin.RemoteConstants.ENDPOINT_ID;
+import static org.osgi.service.remoteserviceadmin.RemoteConstants.ENDPOINT_SERVICE_ID;
import java.util.ArrayList;
import java.util.Collections;
@@ -88,7 +88,7 @@ public class OSGiServiceExporter extends AbstractOSGiServiceHandler implements S
ENDPOINT_FRAMEWORK_UUID,
getFrameworkUUID(reference.getBundle()
.getBundleContext())));
- service.getExtensions().add(createOSGiProperty(registry, ENDPOINT_ID, reference
+ service.getExtensions().add(createOSGiProperty(registry, ENDPOINT_SERVICE_ID, reference
.getProperty(SERVICE_ID)));
// FIXME: Configure the domain and node URI
diff --git a/sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/osgi/remoteserviceadmin/impl/RemoteServiceAdminImpl.java b/sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/osgi/remoteserviceadmin/impl/RemoteServiceAdminImpl.java
index 994fb29e9b..608c74bcfc 100644
--- a/sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/osgi/remoteserviceadmin/impl/RemoteServiceAdminImpl.java
+++ b/sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/osgi/remoteserviceadmin/impl/RemoteServiceAdminImpl.java
@@ -41,6 +41,7 @@ import org.osgi.service.remoteserviceadmin.ExportReference;
import org.osgi.service.remoteserviceadmin.ExportRegistration;
import org.osgi.service.remoteserviceadmin.ImportReference;
import org.osgi.service.remoteserviceadmin.ImportRegistration;
+import org.osgi.service.remoteserviceadmin.RemoteConstants;
import org.osgi.service.remoteserviceadmin.RemoteServiceAdmin;
import org.osgi.service.remoteserviceadmin.RemoteServiceAdminEvent;
import org.osgi.service.remoteserviceadmin.RemoteServiceAdminListener;
@@ -70,8 +71,15 @@ public class RemoteServiceAdminImpl implements RemoteServiceAdmin, ManagedServic
this.importer = new OSGiServiceImporter(context);
exporter.start();
importer.start();
- registration = context.registerService(RemoteServiceAdmin.class.getName(), this, null);
Hashtable<String, Object> props = new Hashtable<String, Object>();
+ props.put(RemoteConstants.REMOTE_CONFIGS_SUPPORTED, new String[] {"org.osgi.sca"});
+ // FIXME: We should ask SCA domain for the supported intents
+ props.put(RemoteConstants.REMOTE_INTENTS_SUPPORTED, new String[] {});
+ // FIXME: We should ask SCA domain for the supported binding types
+ props.put("org.osgi.sca.binding.types", new String[] {});
+ registration = context.registerService(RemoteServiceAdmin.class.getName(), this, props);
+
+ props = new Hashtable<String, Object>();
props.put(Constants.SERVICE_PID, RemoteServiceAdminImpl.class.getName());
managedService = context.registerService(ManagedService.class.getName(), this, props);
listeners = new ServiceTracker(this.context, RemoteServiceAdminListener.class.getName(), null);
@@ -213,17 +221,17 @@ public class RemoteServiceAdminImpl implements RemoteServiceAdmin, ManagedServic
props.put("bundle-symbolicname", rsaBundle.getSymbolicName());
props.put("bundle-version", rsaBundle.getHeaders().get(Constants.BUNDLE_VERSION));
props.put("cause", rsaEvent.getException());
- props.put("import.reference", rsaEvent.getImportReference());
- props.put("export.reference", rsaEvent.getExportReference());
+ props.put("import.registration", rsaEvent.getImportReference());
+ props.put("export.registration", rsaEvent.getExportReference());
EndpointDescription ep = null;
if (rsaEvent.getImportReference() != null) {
ep = rsaEvent.getImportReference().getImportedEndpoint();
} else {
ep = rsaEvent.getExportReference().getExportedEndpoint();
}
- props.put("service.remote.id", ep.getRemoteServiceID());
- props.put("service.remote.uuid", ep.getRemoteFrameworkUUID());
- props.put("service.remote.uri", ep.getRemoteURI());
+ props.put("endpoint.service.id", ep.getRemoteServiceID());
+ props.put("endpoint.framework.uuid", ep.getRemoteFrameworkUUID());
+ props.put("endpoint.id", ep.getRemoteID());
props.put("objectClass", ep.getInterfaces());
props.put("service.imported.configs", ep.getConfigurationTypes());
props.put("timestamp", new Long(System.currentTimeMillis()));
diff --git a/sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/osgi/service/discovery/impl/DomainDiscoveryService.java b/sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/osgi/service/discovery/impl/DomainDiscoveryService.java
index 0efa0cd20b..f6e9855556 100644
--- a/sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/osgi/service/discovery/impl/DomainDiscoveryService.java
+++ b/sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/osgi/service/discovery/impl/DomainDiscoveryService.java
@@ -25,10 +25,13 @@ import java.util.Dictionary;
import org.apache.tuscany.sca.assembly.Endpoint;
import org.apache.tuscany.sca.assembly.Implementation;
+import org.apache.tuscany.sca.core.LifeCycleListener;
import org.apache.tuscany.sca.core.UtilityExtensionPoint;
import org.apache.tuscany.sca.implementation.osgi.OSGiImplementation;
+import org.apache.tuscany.sca.node.configuration.NodeConfiguration;
import org.apache.tuscany.sca.runtime.DomainRegistryFactory;
import org.apache.tuscany.sca.runtime.EndpointListener;
+import org.apache.tuscany.sca.runtime.EndpointRegistry;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.service.remoteserviceadmin.EndpointDescription;
@@ -38,6 +41,7 @@ import org.osgi.service.remoteserviceadmin.EndpointDescription;
*/
public class DomainDiscoveryService extends AbstractDiscoveryService implements EndpointListener {
private DomainRegistryFactory domainRegistryFactory;
+ private EndpointRegistry endpointRegistry;
public DomainDiscoveryService(BundleContext context) {
super(context);
@@ -49,6 +53,18 @@ public class DomainDiscoveryService extends AbstractDiscoveryService implements
this.domainRegistryFactory =
registry.getExtensionPoint(UtilityExtensionPoint.class).getUtility(DomainRegistryFactory.class);
domainRegistryFactory.addListener(this);
+ // The following code forced the start() of the domain registry in absense of services
+ String domainRegistry = context.getProperty("org.osgi.sca.domain.registry");
+ if (domainRegistry == null) {
+ domainRegistry = NodeConfiguration.DEFAULT_DOMAIN_REGISTRY_URI;
+ }
+ String domainURI = context.getProperty("org.osgi.sca.domain.uri");
+ if (domainURI == null) {
+ domainURI = NodeConfiguration.DEFAULT_DOMAIN_URI;
+ }
+ if (domainRegistry != null) {
+ endpointRegistry = domainRegistryFactory.getEndpointRegistry(domainRegistry, domainURI);
+ }
}
public void endpointAdded(Endpoint endpoint) {
@@ -111,6 +127,9 @@ public class DomainDiscoveryService extends AbstractDiscoveryService implements
public void stop() {
domainRegistryFactory.removeListener(this);
+ if (endpointRegistry instanceof LifeCycleListener) {
+ ((LifeCycleListener)endpointRegistry).stop();
+ }
super.stop();
}
diff --git a/sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/osgi/service/discovery/impl/LocalDiscoveryService.java b/sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/osgi/service/discovery/impl/LocalDiscoveryService.java
index 45c563dc21..a4c9414b92 100644
--- a/sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/osgi/service/discovery/impl/LocalDiscoveryService.java
+++ b/sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/apache/tuscany/sca/osgi/service/discovery/impl/LocalDiscoveryService.java
@@ -19,6 +19,9 @@
package org.apache.tuscany.sca.osgi.service.discovery.impl;
import static org.apache.tuscany.sca.osgi.remoteserviceadmin.impl.OSGiHelper.getConfiguration;
+import static org.osgi.service.remoteserviceadmin.RemoteConstants.ENDPOINT_FRAMEWORK_UUID;
+import static org.osgi.service.remoteserviceadmin.RemoteConstants.ENDPOINT_ID;
+import static org.osgi.service.remoteserviceadmin.RemoteConstants.ENDPOINT_SERVICE_ID;
import java.net.URL;
import java.util.ArrayList;
@@ -45,7 +48,6 @@ import org.osgi.framework.Constants;
import org.osgi.framework.Filter;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.service.remoteserviceadmin.EndpointDescription;
-import org.osgi.service.remoteserviceadmin.RemoteConstants;
import org.osgi.util.tracker.BundleTracker;
import org.osgi.util.tracker.BundleTrackerCustomizer;
import org.osgi.util.tracker.ServiceTracker;
@@ -88,14 +90,14 @@ public class LocalDiscoveryService extends AbstractDiscoveryService implements B
private EndpointDescription createEndpointDescription(ServiceDescription sd) {
Map<String, Object> props = new HashMap<String, Object>(sd.getProperties());
props.put(Constants.OBJECTCLASS, sd.getInterfaces().toArray(new String[sd.getInterfaces().size()]));
- if (!props.containsKey(RemoteConstants.ENDPOINT_ID)) {
- props.put(RemoteConstants.ENDPOINT_ID, new Long(System.currentTimeMillis()));
+ if (!props.containsKey(ENDPOINT_SERVICE_ID)) {
+ props.put(ENDPOINT_SERVICE_ID, new Long(System.currentTimeMillis()));
}
- if (!props.containsKey(RemoteConstants.ENDPOINT_FRAMEWORK_UUID)) {
- props.put(RemoteConstants.ENDPOINT_FRAMEWORK_UUID, OSGiHelper.getFrameworkUUID(context));
+ if (!props.containsKey(ENDPOINT_FRAMEWORK_UUID)) {
+ props.put(ENDPOINT_FRAMEWORK_UUID, OSGiHelper.getFrameworkUUID(context));
}
- if (!props.containsKey(RemoteConstants.ENDPOINT_URI)) {
- props.put(RemoteConstants.ENDPOINT_URI, UUID.randomUUID().toString());
+ if (!props.containsKey(ENDPOINT_ID)) {
+ props.put(ENDPOINT_ID, UUID.randomUUID().toString());
}
EndpointDescription sed = new EndpointDescription(props);
diff --git a/sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/osgi/service/remoteserviceadmin/EndpointDescription.java b/sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/osgi/service/remoteserviceadmin/EndpointDescription.java
index 4bc3b34c7c..65f1000265 100644
--- a/sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/osgi/service/remoteserviceadmin/EndpointDescription.java
+++ b/sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/osgi/service/remoteserviceadmin/EndpointDescription.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2008, 2009). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2008, 2010). 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.
@@ -42,18 +42,21 @@ 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. This
- * allows it to be used as a communications device to convey available endpoint
- * information to nodes in a network.
+ * 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 importer. 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
- * service.exported.* property and must contain the service.imported.* ones.
+ * 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.*</code> property and must contain the corresponding
+ * <code>service.imported.*</code> ones.
*
- * The service.intents property contains the intents provided by the service
- * itself combined with the intents added by the exporting distribution
- * provider. Qualified intents appear expanded on this property.
+ * The <code>service.intents</code> 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
* @version $Revision$
@@ -62,15 +65,17 @@ import org.osgi.framework.Version;
public class EndpointDescription {
private final Map<String, Object> properties;
private final List<String> interfaces;
- private final long remoteServiceId;
+ private final long remoteServiceID;
private final String remoteFrameworkUUID;
- private final String remoteUri;
+ private final String remoteID;
/**
- * Create an Endpoint Description based on a Map.
+ * Create an Endpoint Description from a Map.
*
* <p>
- * The {@link RemoteConstants#ENDPOINT_URI} property must be set.
+ * The {@link RemoteConstants#ENDPOINT_ID endpoint.id},
+ * {@link RemoteConstants#SERVICE_IMPORTED_CONFIGS service.imported.configs}
+ * and <code>objectClass</code> 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</code> and, since
@@ -94,28 +99,46 @@ public class EndpointDescription {
}
if (props.size() < properties.size()) {
throw new IllegalArgumentException(
- "duplicate keys with different cases in properties");
+ "duplicate keys with different cases in properties: "
+ + new ArrayList<String>(props.keySet())
+ .removeAll(properties.keySet()));
}
+ if (!props.containsKey(SERVICE_IMPORTED)) {
+ props.put(SERVICE_IMPORTED, Boolean.toString(true));
+ }
this.properties = Collections.unmodifiableMap(props);
/* properties must be initialized before calling the following methods */
interfaces = verifyObjectClassProperty();
- remoteServiceId = verifyLongProperty(ENDPOINT_ID);
+ remoteServiceID = verifyLongProperty(ENDPOINT_SERVICE_ID);
remoteFrameworkUUID = verifyStringProperty(ENDPOINT_FRAMEWORK_UUID);
- remoteUri = verifyStringProperty(ENDPOINT_URI);
- if (remoteUri == null) {
- throw new IllegalArgumentException(ENDPOINT_URI
+ remoteID = verifyStringProperty(ENDPOINT_ID);
+ if (remoteID == 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
+ * 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.
+ * in the Service Reference.
*
* <p>
- * The {@link RemoteConstants#ENDPOINT_URI} property must be set.
+ * 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</code> properties must be set.
*
* @param reference A service reference that can be exported.
* @param properties Map of properties. This argument can be
@@ -142,7 +165,9 @@ public class EndpointDescription {
}
if (props.size() < properties.size()) {
throw new IllegalArgumentException(
- "duplicate keys with different cases in properties");
+ "duplicate keys with different cases in properties: "
+ + new ArrayList<String>(props.keySet())
+ .removeAll(properties.keySet()));
}
}
@@ -152,8 +177,8 @@ public class EndpointDescription {
}
}
- if (!props.containsKey(ENDPOINT_ID)) {
- props.put(ENDPOINT_ID, reference.getProperty(Constants.SERVICE_ID));
+ 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;
@@ -173,36 +198,43 @@ public class EndpointDescription {
props.put(ENDPOINT_FRAMEWORK_UUID, uuid);
}
}
+ if (!props.containsKey(SERVICE_IMPORTED)) {
+ props.put(SERVICE_IMPORTED, Boolean.toString(true));
+ }
this.properties = Collections.unmodifiableMap(props);
/* properties must be initialized before calling the following methods */
interfaces = verifyObjectClassProperty();
- remoteServiceId = verifyLongProperty(ENDPOINT_ID);
+ remoteServiceID = verifyLongProperty(ENDPOINT_SERVICE_ID);
remoteFrameworkUUID = verifyStringProperty(ENDPOINT_FRAMEWORK_UUID);
- remoteUri = verifyStringProperty(ENDPOINT_URI);
- if (remoteUri == null) {
- throw new IllegalArgumentException(ENDPOINT_URI
+ remoteID = verifyStringProperty(ENDPOINT_ID);
+ if (remoteID == 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");
+ }
}
/**
* Verify and obtain the interface list from the properties.
*
* @return A list with the interface names.
- * @throws IllegalArgumentException When the properties do not contain the
- * right values for and interface list.
- *
+ * @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 == null) {
- return Collections.EMPTY_LIST;
- }
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) {
@@ -269,19 +301,19 @@ public class EndpointDescription {
}
/**
- * Returns the endpoint's URI.
+ * Returns the endpoint's id.
*
- * The URI is an opaque id for an endpoint in URI form. No two different
- * endpoints must have the same URI, two Endpoint Descriptions with the same
- * URI must represent the same endpoint.
+ * 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 URI is stored in the
- * {@link RemoteConstants#ENDPOINT_URI} property.
+ * The value of the id is stored in the
+ * {@link RemoteConstants#ENDPOINT_ID} property.
*
- * @return The URI of the endpoint, never <code>null</code>.
+ * @return The id of the endpoint, never <code>null</code>.
*/
- public String getRemoteURI() {
- return remoteUri;
+ public String getRemoteID() {
+ return remoteID;
}
/**
@@ -344,14 +376,14 @@ public class EndpointDescription {
* id for a service.
*
* The value of the remote service id is stored in the
- * {@link RemoteConstants#ENDPOINT_ID} endpoint property.
+ * {@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
+ * not relate to an OSGi service.
*
*/
public long getRemoteServiceID() {
- return remoteServiceId;
+ return remoteServiceID;
}
/**
@@ -426,7 +458,7 @@ public class EndpointDescription {
List<String> result = new ArrayList<String>(values.size());
for (Iterator< ? > iter = values.iterator(); iter.hasNext();) {
Object v = iter.next();
- if ((v != null) && (v instanceof String)) {
+ if (v instanceof String) {
result.add((String) v);
}
}
@@ -464,7 +496,7 @@ public class EndpointDescription {
* as the given Endpoint Description.
*
* Two Endpoint Descriptions point to the same service if they have the same
- * URI or their framework UUIDs and remote service ids are equal.
+ * 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
@@ -490,7 +522,7 @@ public class EndpointDescription {
* @return An integer which is a hash code value for this object.
*/
public int hashCode() {
- return getRemoteURI().hashCode();
+ return getRemoteID().hashCode();
}
/**
@@ -498,7 +530,7 @@ public class EndpointDescription {
*
* <p>
* An Endpoint Description is considered to be <b>equal to</b> another
- * Endpoint Description if their URIs are equal.
+ * Endpoint Description if their ids are equal.
*
* @param other The <code>EndpointDescription</code> object to be compared.
* @return <code>true</code> if <code>object</code> is a
@@ -512,13 +544,13 @@ public class EndpointDescription {
if (!(other instanceof EndpointDescription)) {
return false;
}
- return getRemoteURI().equals(
- ((EndpointDescription) other).getRemoteURI());
+ return getRemoteID().equals(
+ ((EndpointDescription) other).getRemoteID());
}
/**
- * Tests the properties of this <code>EndpointDescription</code> against the
- * given filter using a case insensitive match.
+ * Tests the properties of this <code>EndpointDescription</code> against
+ * the given filter using a case insensitive match.
*
* @param filter The filter to test.
* @return <code>true</code> If the properties of this
@@ -548,9 +580,10 @@ public class EndpointDescription {
}
/**
- * Unmodifiable Dictionary wrapper for a Map.
+ * Unmodifiable Dictionary wrapper for a Map. This class is also used by
+ * EndpointPermission.
*/
- private static class UnmodifiableDictionary<K, V> extends Dictionary<K, V> {
+ static class UnmodifiableDictionary<K, V> extends Dictionary<K, V> {
private final Map<K, V> wrapped;
UnmodifiableDictionary(Map<K, V> wrapped) {
@@ -584,5 +617,9 @@ public class EndpointDescription {
public int size() {
return wrapped.size();
}
+
+ public String toString() {
+ return wrapped.toString();
+ }
}
}
diff --git a/sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/osgi/service/remoteserviceadmin/EndpointPermission.java b/sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/osgi/service/remoteserviceadmin/EndpointPermission.java
index 0bfdcd334b..84a7ba512e 100644
--- a/sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/osgi/service/remoteserviceadmin/EndpointPermission.java
+++ b/sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/osgi/service/remoteserviceadmin/EndpointPermission.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2000, 2009). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2010). 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.
@@ -16,14 +16,13 @@
package org.osgi.service.remoteserviceadmin;
-// TODO Hacked from ServiePermission
+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.BasicPermission;
import java.security.Permission;
import java.security.PermissionCollection;
import java.util.ArrayList;
@@ -32,205 +31,166 @@ import java.util.Collections;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.HashMap;
-import java.util.Hashtable;
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;
/**
- * <pre>
- * -------------------------------------------------------------
- * THIS CLASS IS A PLACEHOLDER (COPIED FROM SERVICE PERMISSION)!
- * -------------------------------------------------------------
- * </pre>
- *
- * A bundle's authority to register or get a service.
+ * A bundle's authority to export, import or read an Endpoint.
* <ul>
- * <li>The <code>register</code> action allows a bundle to register a service on
- * the specified names.
- * <li>The <code>get</code> action allows a bundle to detect a service and get
- * it.
+ * <li>The <code>export</code> action allows a bundle to export a service as an
+ * Endpoint.</li>
+ * <li>The <code>import</code> action allows a bundle to import a service from
+ * an Endpoint.</li>
+ * <li>The <code>read</code> action allows a bundle to read references to an
+ * Endpoint.</li>
* </ul>
- * Permission to get a service is required in order to detect events regarding
- * the service. Untrusted bundles should not be able to detect the presence of
- * certain services unless they have the appropriate
- * <code>EndpointPermission</code> to get the specific service.
+ * 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</code> to read the specific service.
*
* @ThreadSafe
* @version $Revision$
*/
-public final class EndpointPermission extends BasicPermission {
- static final long serialVersionUID = -7662148639076511574L;
+public final class EndpointPermission extends Permission {
+ static final long serialVersionUID = -7662148639076511574L;
/**
- * The action string <code>export</code>.
+ * The action string <code>read</code>.
*/
- public final static String EXPORT = "export";
+ public final static String READ = "read";
/**
- * The action string <code>import</code>.
+ * The action string <code>import</code>. The <code>import</code> action
+ * implies the <code>read</code> action.
*/
- public final static String IMPORT = "import";
+ public final static String IMPORT = "import";
/**
- * The action string <code>read</code>.
+ * The action string <code>export</code>. The <code>export</code> action
+ * implies the <code>read</code> action.
*/
- public final static String READ = "read";
+ public final static String EXPORT = "export";
- private final static int ACTION_EXPORT = 0x00000001;
- private final static int ACTION_IMPORT = 0x00000002;
- private final static int ACTION_READ = 0x00000004;
- private final static int ACTION_ALL = ACTION_EXPORT
- | ACTION_IMPORT
- | ACTION_READ;
- final static int ACTION_NONE = 0;
+ 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;
+ transient int action_mask;
/**
* The actions in canonical form.
*
* @serial
*/
- private volatile String actions = null;
-
- /**
- * The service used by this EndpointPermission. Must be null if not
- * constructed with a service.
- */
- transient final EndpointDescription endpoint;
-
- /**
- * The object classes for this EndpointPermission. Must be null if not
- * constructed with a service.
- */
- transient final String[] objectClass;
+ private volatile String actions = null;
/**
- * If this EndpointPermission was constructed with a filter, this holds a
- * Filter matching object used to evaluate the filter in implies.
+ * The endpoint used by this EndpointPermission. Must be null if not
+ * constructed with a endpoint.
*/
- transient Filter filter;
-
+ transient final EndpointDescription endpoint;
+
/**
* This dictionary holds the properties of the permission, used to match a
- * filter in implies. This is not initialized until necessary, and then
- * cached in this object.
- */
- private transient volatile Dictionary properties;
-
- /**
- * True if constructed with a name and the name is "*" or ends with ".*".
+ * filter in implies.
*/
- private transient boolean wildcard;
+ private transient final Dictionary<String, Object> properties;
/**
- * If constructed with a name and the name ends with ".*", this contains the
- * name without the final "*".
+ * If this EndpointPermission was not constructed with an
+ * EndpointDescription, this holds a Filter matching object used to evaluate
+ * the filter in implies or null for wildcard.
*/
- private transient String prefix;
+ transient Filter filter;
/**
- * Create a new EndpointPermission.
+ * Create a new EndpointPermission with the specified filter.
*
* <p>
- * The name of the service is specified as a fully qualified class name.
- * Wildcards may be used.
- *
- * <pre>
- * name ::= &lt;class name&gt; | &lt;class name ending in &quot;.*&quot;&gt; | *
- * </pre>
- *
- * Examples:
- *
- * <pre>
- * org.osgi.service.http.HttpService
- * org.osgi.service.http.*
- * *
- * </pre>
- *
- * For the <code>get</code> action, the name can also be a filter
- * expression. The filter gives access to the service properties as well as
- * the following attributes:
- * <ul>
- * <li>signer - A Distinguished Name chain used to sign the bundle
- * publishing the service. Wildcards in a DN are not matched according to
- * the filter string rules, but according to the rules defined for a DN
- * chain.</li>
- * <li>location - The location of the bundle publishing the service.</li>
- * <li>id - The bundle ID of the bundle publishing the service.</li>
- * <li>name - The symbolic name of the bundle publishing the service.</li>
- * </ul>
- * Since the above attribute names may conflict with service property names
- * used by a service, you can prefix an attribute name with '@' in the
- * filter expression to match against the service property and not one of
- * the above attributes. Filter attribute names are processed in a case
- * sensitive manner unless the attribute references a service property.
- * Service properties names are case insensitive.
+ * The filter will be evaluated against the endpoint properties of a
+ * requested EndpointPermission.
*
* <p>
- * There are two possible actions: <code>get</code> and
- * <code>register</code>. The <code>get</code> permission allows the owner
- * of this permission to obtain a service with this name. The
- * <code>register</code> permission allows the bundle to register a service
- * under that name.
+ * There are three possible actions: <code>read</code>, <code>import</code>
+ * and <code>export</code>. The <code>read</code> action allows the owner of
+ * this permission to see the presence of distributed services. The
+ * <code>import</code> action allows the owner of this permission to import
+ * an endpoint. The <code>export</code> action allows the owner of this
+ * permission to export a service.
*
- * @param name The service class name
- * @param actions <code>get</code>,<code>register</code> (canonical order)
- * @throws IllegalArgumentException If the specified name is a filter
- * expression and either the specified action is not
- * <code>get</code> or the filter has an invalid syntax.
- */
- public EndpointPermission(String name, String actions) {
- this(name, parseActions(actions));
- if ((filter != null) && ((action_mask & ACTION_ALL) != ACTION_EXPORT)) {
- throw new IllegalArgumentException(
- "invalid action string for filter expression");
- }
+ * @param filterString The filter string or &quot;*&quot; to match all
+ * endpoints.
+ * @param actions The actions <code>read</code>, <code>import</code>, or
+ * <code>export</code>.
+ * @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</code> object to be used
- * by code that must perform <code>checkPermission</code> for the
- * <code>get</code> action. <code>EndpointPermission</code> objects created
- * with this constructor cannot be added to a
- * <code>EndpointPermission</code> permission collection.
+ * by code that must perform <code>checkPermission</code>.
+ * <code>EndpointPermission</code> objects created with this constructor
+ * cannot be added to an <code>EndpointPermission</code> permission
+ * collection.
*
- * @param endpoint The requested service.
- * @param actions The action <code>get</code>.
- * @throws IllegalArgumentException If the specified action is not
- * <code>get</code> or reference is <code>null</code>.
- * @since 1.5
- */
- public EndpointPermission(EndpointDescription endpoint, String actions) {
+ * @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>&lt;&lt;LOCAL&gt;&gt;</code> value in the filter expression.
+ * @param actions The actions <code>read</code>, <code>import</code>, or
+ * <code>export</code>.
+ * @throws IllegalArgumentException If the endpoint is <code>null</code> or
+ * the actions are not valid.
+ */
+ public EndpointPermission(EndpointDescription endpoint,
+ String localFrameworkUUID, String actions) {
super(createName(endpoint));
setTransients(null, parseActions(actions));
- this.endpoint = endpoint;
- this.objectClass = (String[]) endpoint.getProperties().get(
- Constants.OBJECTCLASS);
- if ((action_mask & ACTION_ALL) != ACTION_EXPORT) {
- throw new IllegalArgumentException("invalid action string");
+ Map<String, Object> props;
+ if ((localFrameworkUUID != null)
+ && localFrameworkUUID.equals(endpoint.getRemoteFrameworkUUID())) {
+ props = new TreeMap<String, Object>(String.CASE_INSENSITIVE_ORDER);
+ props.putAll(endpoint.getProperties());
+ props.put(ENDPOINT_FRAMEWORK_UUID, new String[] {
+ endpoint.getRemoteFrameworkUUID(), "<<LOCAL>>"});
+ }
+ else {
+ props = endpoint.getProperties();
}
+ this.endpoint = endpoint;
+ this.properties = new EndpointDescription.UnmodifiableDictionary<String, Object>(
+ props);
}
/**
- * Create a permission name from a EndpointDescription TODO Needs work
+ * 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("reference must not be null");
+ throw new IllegalArgumentException("invalid endpoint: null");
}
- StringBuffer sb = new StringBuffer("(service.id=");
- // TODO sb.append(endpoint.getProperty(Constants.SERVICE_ID));
+ StringBuffer sb = new StringBuffer("(" + ENDPOINT_ID + "=");
+ sb.append(endpoint.getRemoteID());
sb.append(")");
return sb.toString();
}
@@ -245,7 +205,7 @@ public final class EndpointPermission extends BasicPermission {
super(name);
setTransients(parseFilter(name), mask);
this.endpoint = null;
- this.objectClass = null;
+ this.properties = null;
}
/**
@@ -259,16 +219,6 @@ public final class EndpointPermission extends BasicPermission {
}
action_mask = mask;
filter = f;
- if (f == null) {
- String name = getName();
- int l = name.length();
- /* if "*" or endsWith ".*" */
- wildcard = ((name.charAt(l - 1) == '*') && ((l == 1) || (name
- .charAt(l - 2) == '.')));
- if (wildcard && (l > 1)) {
- prefix = name.substring(0, l - 1);
- }
- }
}
/**
@@ -304,34 +254,45 @@ public final class EndpointPermission extends BasicPermission {
// check for the known strings
int matchlen;
- if (i >= 2 && (a[i - 2] == 'g' || a[i - 2] == 'G')
- && (a[i - 1] == 'e' || a[i - 1] == 'E')
+ 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 = 3;
- mask |= ACTION_EXPORT;
+ matchlen = 6;
+ mask |= ACTION_IMPORT | ACTION_READ;
}
else
- if (i >= 7 && (a[i - 7] == 'r' || a[i - 7] == 'R')
- && (a[i - 6] == 'e' || a[i - 6] == 'E')
- && (a[i - 5] == 'g' || a[i - 5] == 'G')
- && (a[i - 4] == 'i' || a[i - 4] == 'I')
- && (a[i - 3] == 's' || a[i - 3] == 'S')
- && (a[i - 2] == 't' || a[i - 2] == 'T')
- && (a[i - 1] == 'e' || a[i - 1] == 'E')
- && (a[i] == 'r' || a[i] == 'R')) {
- matchlen = 8;
- mask |= ACTION_IMPORT;
+ 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 {
- // parse error
- throw new IllegalArgumentException("invalid permission: "
- + actions);
+ 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 "ackbarfregister". Also, skip to the comma.
+ // like "ackbarfread". Also, skip to the comma.
seencomma = false;
while (i >= matchlen && !seencomma) {
switch (a[i - matchlen]) {
@@ -366,16 +327,17 @@ public final class EndpointPermission extends BasicPermission {
* Parse filter string into a Filter object.
*
* @param filterString The filter string to parse.
- * @return a Filter for this bundle. If the specified filterString is not a
- * filter expression, then <code>null</code> is returned.
+ * @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.charAt(0) != '(') {
- return null;
+ if (filterString.equals("*")) {
+ return null; // wildcard
}
-
try {
return FrameworkUtil.createFilter(filterString);
}
@@ -428,46 +390,19 @@ public final class EndpointPermission extends BasicPermission {
if ((effective & desired) != desired) {
return false;
}
- /* we have name of "*" */
- if (wildcard && (prefix == null)) {
- return true;
- }
- /* if we have a filter */
+ /* if we have no filter */
Filter f = filter;
- if (f != null) {
- return f.matchCase(requested.getProperties());
- }
- /* if requested permission not created with EndpointDescription */
- String[] requestedNames = requested.objectClass;
- if (requestedNames == null) {
- return super.implies(requested);
- }
- /* requested permission created with EndpointDescription */
- if (wildcard) {
- int pl = prefix.length();
- for (int i = 0, l = requestedNames.length; i < l; i++) {
- String requestedName = requestedNames[i];
- if ((requestedName.length() > pl)
- && requestedName.startsWith(prefix)) {
- return true;
- }
- }
- }
- else {
- String name = getName();
- for (int i = 0, l = requestedNames.length; i < l; i++) {
- if (requestedNames[i].equals(name)) {
- return true;
- }
- }
+ if (f == null) {
+ // it's "*"
+ return true;
}
- return false;
+ return f.matchCase(requested.getProperties());
}
/**
* Returns the canonical string representation of the actions. Always
- * returns present actions in the following order: <code>get</code>,
- * <code>register</code>.
+ * returns present actions in the following canonical order:
+ * <code>read</code>, <code>import</code>, <code>export</code>.
*
* @return The canonical string representation of the actions.
*/
@@ -478,8 +413,8 @@ public final class EndpointPermission extends BasicPermission {
boolean comma = false;
int mask = action_mask;
- if ((mask & ACTION_EXPORT) == ACTION_EXPORT) {
- sb.append(EXPORT);
+ if ((mask & ACTION_READ) == ACTION_READ) {
+ sb.append(READ);
comma = true;
}
@@ -489,6 +424,12 @@ public final class EndpointPermission extends BasicPermission {
sb.append(IMPORT);
}
+ if ((mask & ACTION_EXPORT) == ACTION_EXPORT) {
+ if (comma)
+ sb.append(',');
+ sb.append(EXPORT);
+ }
+
actions = result = sb.toString();
}
@@ -509,12 +450,12 @@ public final class EndpointPermission extends BasicPermission {
/**
* Determines the equality of two EndpointPermission objects.
*
- * Checks that specified object has the same class name and action as this
- * <code>EndpointPermission</code>.
+ * Checks that specified object has the same name, actions and endpoint as
+ * this <code>EndpointPermission</code>.
*
* @param obj The object to test for equality.
* @return true if obj is a <code>EndpointPermission</code>, and has the
- * same class name and actions as this
+ * same name, actions and endpoint as this
* <code>EndpointPermission</code> object; <code>false</code>
* otherwise.
*/
@@ -527,13 +468,13 @@ public final class EndpointPermission extends BasicPermission {
return false;
}
- EndpointPermission sp = (EndpointPermission) obj;
+ EndpointPermission ep = (EndpointPermission) obj;
- return (action_mask == sp.action_mask)
- && getName().equals(sp.getName())
- && ((endpoint == sp.endpoint) || ((endpoint != null)
- && (sp.endpoint != null) && endpoint
- .equals(sp.endpoint)));
+ return (action_mask == ep.action_mask)
+ && getName().equals(ep.getName())
+ && ((endpoint == ep.endpoint) || ((endpoint != null)
+ && (ep.endpoint != null) && endpoint
+ .equals(ep.endpoint)));
}
/**
@@ -561,8 +502,9 @@ public final class EndpointPermission extends BasicPermission {
}
// Write out the actions. The superclass takes care of the name
// call getActions to make sure actions field is initialized
- if (actions == null)
+ if (actions == null) {
getActions();
+ }
s.defaultWriteObject();
}
@@ -582,109 +524,8 @@ public final class EndpointPermission extends BasicPermission {
*
* @return a dictionary of properties for this permission.
*/
- private Dictionary/* <String,Object> */getProperties() {
- Dictionary/* <String, Object> */result = properties;
- if (result != null) {
- return result;
- }
- if (endpoint == null) {
- result = new Hashtable/* <String, Object> */(1);
- if (filter == null) {
- result.put(Constants.OBJECTCLASS, new String[] {getName()});
- }
- return properties = result;
- }
- final Map props = new HashMap(4);
- // TODO needs work
- /*
- * final Bundle bundle = endpoint.getBundle(); if (bundle != null) {
- * AccessController.doPrivileged(new PrivilegedAction() { public Object
- * run() { props.put("id", new Long(bundle.getBundleId()));
- * props.put("location", bundle.getLocation()); String name =
- * bundle.getSymbolicName(); if (name != null) { props.put("name",
- * name); } SignerProperty signer = new SignerProperty(bundle); if
- * (signer.isBundleSigned()) { props.put("signer", signer); } return
- * null; } }); }
- */
- return properties = new Properties(props, endpoint);
- }
-
- private static class Properties extends Dictionary {
- private final Map properties;
- private final EndpointDescription service;
-
- Properties(Map properties, EndpointDescription service) {
- this.properties = properties;
- this.service = service;
- }
-
- public Object get(Object k) {
- if (!(k instanceof String)) {
- return null;
- }
- String key = (String) k;
- if (key.charAt(0) == '@') {
- return service.getProperties().get(key.substring(1));
- }
- Object value = properties.get(key);
- if (value != null) { // fall back to service properties
- return value;
- }
- return service.getProperties().get(key);
- }
-
- public int size() {
- return properties.size() + service.getProperties().size();
- }
-
- public boolean isEmpty() {
- // we can return false because this must never be empty
- return false;
- }
-
- public Enumeration keys() {
- Collection pk = properties.keySet();
- String spk[] = (String[]) service.getProperties().keySet().toArray(
- new String[service.getProperties().size()]);
- List all = new ArrayList(pk.size() + spk.length);
- all.addAll(pk);
- add: for (int i = 0, length = spk.length; i < length; i++) {
- String key = spk[i];
- for (Iterator iter = pk.iterator(); iter.hasNext();) {
- if (key.equalsIgnoreCase((String) iter.next())) {
- continue add;
- }
- }
- all.add(key);
- }
- return Collections.enumeration(all);
- }
-
- public Enumeration elements() {
- Collection pk = properties.keySet();
- String spk[] = (String[]) service.getProperties().keySet().toArray(
- new String[service.getProperties().size()]);
- List all = new ArrayList(pk.size() + spk.length);
- all.addAll(properties.values());
- add: for (int i = 0, length = spk.length; i < length; i++) {
- String key = spk[i];
- for (Iterator iter = pk.iterator(); iter.hasNext();) {
- if (key.equalsIgnoreCase((String) iter.next())) {
- continue add;
- }
- }
- all.add(service.getProperties().get(key));
- }
- return Collections.enumeration(all);
- }
-
- public Object put(Object key, Object value) {
- throw new UnsupportedOperationException();
- }
-
- public Object remove(Object key) {
- throw new UnsupportedOperationException();
- }
+ private Dictionary<String, Object> getProperties() {
+ return properties;
}
}
@@ -696,35 +537,28 @@ public final class EndpointPermission extends BasicPermission {
* @see java.security.PermissionCollection
*/
final class EndpointPermissionCollection extends PermissionCollection {
- static final long serialVersionUID = 662615640374640621L;
+ static final long serialVersionUID = 662615640374640621L;
/**
* Table of permissions.
*
- * @GuardedBy this
- */
- private transient Map permissions;
-
- /**
- * Boolean saying if "*" is in the collection.
- *
* @serial
* @GuardedBy this
*/
- private boolean all_allowed;
+ private Map<String, EndpointPermission> permissions;
/**
- * Table of permissions with filter expressions.
+ * Boolean saying if "*" is in the collection.
*
* @serial
* @GuardedBy this
*/
- private Map filterPermissions;
+ private boolean all_allowed;
/**
* Creates an empty EndpointPermissions object.
*/
public EndpointPermissionCollection() {
- permissions = new HashMap();
+ permissions = new HashMap<String, EndpointPermission>();
all_allowed = false;
}
@@ -748,39 +582,29 @@ final class EndpointPermissionCollection extends PermissionCollection {
+ "readonly PermissionCollection");
}
- final EndpointPermission sp = (EndpointPermission) permission;
- if (sp.endpoint != null) {
+ final EndpointPermission ep = (EndpointPermission) permission;
+ if (ep.endpoint != null) {
throw new IllegalArgumentException("cannot add to collection: "
- + sp);
+ + ep);
}
- final String name = sp.getName();
- final Filter f = sp.filter;
+ final String name = ep.getName();
synchronized (this) {
/* select the bucket for the permission */
- Map pc;
- if (f != null) {
- pc = filterPermissions;
- if (pc == null) {
- filterPermissions = pc = new HashMap();
- }
- }
- else {
- pc = permissions;
- }
+ Map<String, EndpointPermission> pc = permissions;
final EndpointPermission existing = (EndpointPermission) pc
.get(name);
if (existing != null) {
final int oldMask = existing.action_mask;
- final int newMask = sp.action_mask;
+ final int newMask = ep.action_mask;
if (oldMask != newMask) {
pc.put(name,
new EndpointPermission(name, oldMask | newMask));
}
}
else {
- pc.put(name, sp);
+ pc.put(name, ep);
}
if (!all_allowed) {
@@ -808,50 +632,27 @@ final class EndpointPermissionCollection extends PermissionCollection {
if (requested.filter != null) {
return false;
}
-
int effective = EndpointPermission.ACTION_NONE;
- Collection perms;
+ Collection<EndpointPermission> perms;
synchronized (this) {
final int desired = requested.action_mask;
/* short circuit if the "*" Permission was added */
if (all_allowed) {
- EndpointPermission sp = (EndpointPermission) permissions
- .get("*");
- if (sp != null) {
- effective |= sp.action_mask;
+ EndpointPermission ep = permissions.get("*");
+ if (ep != null) {
+ effective |= ep.action_mask;
if ((effective & desired) == desired) {
return true;
}
}
}
-
- String[] requestedNames = requested.objectClass;
- /* if requested permission not created with EndpointDescription */
- if (requestedNames == null) {
- effective |= effective(requested.getName(), desired, effective);
- if ((effective & desired) == desired) {
- return true;
- }
- }
- /* requested permission created with EndpointDescription */
- else {
- for (int i = 0, l = requestedNames.length; i < l; i++) {
- if ((effective(requestedNames[i], desired, effective) & desired) == desired) {
- return true;
- }
- }
- }
- Map pc = filterPermissions;
- if (pc == null) {
- return false;
- }
- perms = pc.values();
+ perms = permissions.values();
}
- /* iterate one by one over filteredPermissions */
- for (Iterator iter = perms.iterator(); iter.hasNext();) {
- if (((EndpointPermission) iter.next()).implies0(requested,
- effective)) {
+ /* iterate one by one over permissions */
+ for (Iterator<EndpointPermission> iter = perms.iterator(); iter
+ .hasNext();) {
+ if (iter.next().implies0(requested, effective)) {
return true;
}
}
@@ -859,85 +660,34 @@ final class EndpointPermissionCollection extends PermissionCollection {
}
/**
- * Consult permissions map to compute the effective permission for the
- * requested permission name.
- *
- * @param requestedName The requested service name.
- * @param desired The desired actions.
- * @param effective The effective actions.
- * @return The new effective actions.
- */
- private int effective(String requestedName, final int desired, int effective) {
- final Map pc = permissions;
- EndpointPermission sp = (EndpointPermission) pc.get(requestedName);
- // strategy:
- // Check for full match first. Then work our way up the
- // name looking for matches on a.b.*
- if (sp != null) {
- // we have a direct hit!
- effective |= sp.action_mask;
- if ((effective & desired) == desired) {
- return effective;
- }
- }
- // work our way up the tree...
- int last;
- int offset = requestedName.length() - 1;
- while ((last = requestedName.lastIndexOf(".", offset)) != -1) {
- requestedName = requestedName.substring(0, last + 1) + "*";
- sp = (EndpointPermission) pc.get(requestedName);
- if (sp != null) {
- effective |= sp.action_mask;
- if ((effective & desired) == desired) {
- return effective;
- }
- }
- offset = last - 1;
- }
- /*
- * we don't have to check for "*" as it was already checked before we
- * were called.
- */
- return effective;
- }
-
- /**
* Returns an enumeration of all the <code>EndpointPermission</code> objects
* in the container.
*
* @return Enumeration of all the EndpointPermission objects.
*/
- public synchronized Enumeration elements() {
- List all = new ArrayList(permissions.values());
- Map pc = filterPermissions;
- if (pc != null) {
- all.addAll(pc.values());
- }
+ 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", Hashtable.class),
- new ObjectStreamField("all_allowed", Boolean.TYPE),
- new ObjectStreamField("filterPermissions", HashMap.class) };
+ new ObjectStreamField("permissions", HashMap.class),
+ new ObjectStreamField("all_allowed", Boolean.TYPE) };
private synchronized void writeObject(ObjectOutputStream out)
throws IOException {
- Hashtable hashtable = new Hashtable(permissions);
ObjectOutputStream.PutField pfields = out.putFields();
- pfields.put("permissions", hashtable);
+ pfields.put("permissions", permissions);
pfields.put("all_allowed", all_allowed);
- pfields.put("filterPermissions", filterPermissions);
out.writeFields();
}
private synchronized void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException {
ObjectInputStream.GetField gfields = in.readFields();
- Hashtable hashtable = (Hashtable) gfields.get("permissions", null);
- permissions = new HashMap(hashtable);
+ permissions = (HashMap<String, EndpointPermission>) gfields.get(
+ "permissions", new HashMap<String, EndpointPermission>());
all_allowed = gfields.get("all_allowed", false);
- filterPermissions = (HashMap) gfields.get("filterPermissions", null);
}
}
diff --git a/sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/osgi/service/remoteserviceadmin/RemoteConstants.java b/sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/osgi/service/remoteserviceadmin/RemoteConstants.java
index 93e6bb0c24..cf2194ec12 100644
--- a/sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/osgi/service/remoteserviceadmin/RemoteConstants.java
+++ b/sca-java-2.x/trunk/modules/node-impl-osgi/src/main/java/org/osgi/service/remoteserviceadmin/RemoteConstants.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2009). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2009, 2010). 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.
@@ -30,10 +30,9 @@ public class RemoteConstants {
* 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>,
- * <code>String[]</code>, or <code>Collection</code> of <code>String</code>.
+ * <code>String[]</code>, or <code>Collection&lt;String&gt;</code>.
*/
public static final String REMOTE_CONFIGS_SUPPORTED = "remote.configs.supported";
@@ -44,7 +43,7 @@ public class RemoteConstants {
*
* <p>
* The value of this property must be of type <code>String</code>,
- * <code>String[]</code>, or <code>Collection</code> of <code>String</code>.
+ * <code>String[]</code>, or <code>Collection&lt;String&gt;</code>.
*/
public static final String REMOTE_INTENTS_SUPPORTED = "remote.intents.supported";
@@ -59,7 +58,7 @@ public class RemoteConstants {
* <code>Dictionary</code> object passed to the
* <code>BundleContext.registerService</code> method. The value of this
* property must be of type <code>String</code>, <code>String[]</code>, or
- * <code>Collection</code> of <code>String</code>.
+ * <code>Collection&lt;String&gt;</code>.
*/
public static final String SERVICE_EXPORTED_CONFIGS = "service.exported.configs";
@@ -75,7 +74,7 @@ public class RemoteConstants {
* <code>Dictionary</code> object passed to the
* <code>BundleContext.registerService</code> method. The value of this
* property must be of type <code>String</code>, <code>String[]</code>, or
- * <code>Collection</code> of <code>String</code>.
+ * <code>Collection&lt;String&gt;</code>.
*/
public static final String SERVICE_EXPORTED_INTENTS = "service.exported.intents";
@@ -94,7 +93,7 @@ public class RemoteConstants {
* <code>Dictionary</code> object passed to the
* <code>BundleContext.registerService</code> method. The value of this
* property must be of type <code>String</code>, <code>String[]</code>, or
- * <code>Collection</code> of <code>String</code>.
+ * <code>Collection&lt;String&gt;</code>.
*/
public static final String SERVICE_EXPORTED_INTENTS_EXTRA = "service.exported.intents.extra";
@@ -113,7 +112,7 @@ public class RemoteConstants {
* <code>Dictionary</code> object passed to the
* <code>BundleContext.registerService</code> method. The value of this
* property must be of type <code>String</code>, <code>String[]</code>, or
- * <code>Collection</code> of <code>String</code>.
+ * <code>Collection&lt;String&gt;</code>.
*/
public static final String SERVICE_EXPORTED_INTERFACES = "service.exported.interfaces";
@@ -139,7 +138,7 @@ public class RemoteConstants {
*
* <p>
* The value of this property must be of type <code>String</code>,
- * <code>String[]</code>, or <code>Collection</code> of <code>String</code>.
+ * <code>String[]</code>, or <code>Collection&lt;String&gt;</code>.
*
* @see #SERVICE_EXPORTED_CONFIGS
*/
@@ -153,34 +152,30 @@ public class RemoteConstants {
* 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:</li>
- * <ul>
- * <li>The exporting service, and</li>
- * <li>the intents that the exporting distribution provider adds, and</li>
- * <li>the intents that the importing distribution provider adds.</li>
+ * 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>
- * <i></i>
- *
- * </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.
+ * 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.
*
* <p>
* The value of this property must be of type <code>String</code>,
- * <code>String[]</code>, or <code>Collection</code> of <code>String</code>.
+ * <code>String[]</code>, or <code>Collection&lt;String&gt;</code>.
*/
public static final String SERVICE_INTENTS = "service.intents";
/* above are from Ch 13 Remote Service spec. */
/**
- * Endpoint property identifying the URI for this endpoint. This service
+ * 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</code>.
*/
- public final static String ENDPOINT_URI = "endpoint.uri";
+ public final static String ENDPOINT_ID = "endpoint.id";
/**
* Endpoint property identifying the service id of the exported service. Can
@@ -189,7 +184,7 @@ public class RemoteConstants {
* <p>
* The value of this property must be of type <code>Long</code>.
*/
- public final static String ENDPOINT_ID = "endpoint.id";
+ public final static String ENDPOINT_SERVICE_ID = "endpoint.service.id";
/**
* Endpoint property identifying the universally unique id of the exporting
diff --git a/sca-java-2.x/trunk/modules/node-impl-osgi/src/test/resources/calculator/dosgi/OSGI-INF/remote-service/calculator-service-descriptions.xml b/sca-java-2.x/trunk/modules/node-impl-osgi/src/test/resources/calculator/dosgi/OSGI-INF/remote-service/calculator-service-descriptions.xml
index e7369833f9..8306fa9834 100644
--- a/sca-java-2.x/trunk/modules/node-impl-osgi/src/test/resources/calculator/dosgi/OSGI-INF/remote-service/calculator-service-descriptions.xml
+++ b/sca-java-2.x/trunk/modules/node-impl-osgi/src/test/resources/calculator/dosgi/OSGI-INF/remote-service/calculator-service-descriptions.xml
@@ -17,51 +17,39 @@
* specific language governing permissions and limitations
* under the License.
-->
-<!-- A consumer-side service description file for RFC 119 -->
-<service-descriptions xmlns="http://www.osgi.org/xmlns/sd/v1.0.0" xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912">
+<!-- A consumer-side service description file for OSGi Remote Service Admin -->
+<endpoint-descriptions xmlns="http://www.osgi.org/xmlns/rsa/v1.0.0" xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912">
<!-- Describe a remote OSGi service -->
- <service-description>
- <provide interface="calculator.dosgi.operations.AddService" />
- <property name="service.intents">sca:SOAP sca:HTTP</property>
- <property name="osgi.remote.configuration.type">org.osgi.sca</property>
- <property name="osgi.remote.configuration.sca.componentType">
- OSGI-INF/sca/bundle.componentType
- </property>
- <property name="osgi.remote.configuration.sca.reference">
- addService
- </property>
- </service-description>
- <service-description>
- <provide interface="calculator.dosgi.operations.SubtractService" />
- <property name="service.intents">sca:SOAP sca:HTTP</property>
- <property name="osgi.remote.configuration.type">org.osgi.sca</property>
- <property name="osgi.remote.configuration.sca.componentType">
- OSGI-INF/sca/bundle.componentType
- </property>
- <property name="osgi.remote.configuration.sca.reference">
- subtractService
- </property>
- </service-description>
- <service-description>
- <provide interface="calculator.dosgi.operations.MultiplyService" />
- <property name="service.intents">sca:SOAP sca:HTTP</property>
- <property name="osgi.remote.configuration.type">org.osgi.sca</property>
- <property name="osgi.remote.configuration.sca.componentType">
- OSGI-INF/sca/bundle.componentType
- </property>
- <property name="osgi.remote.configuration.sca.reference">
- multiplyService
- </property>
- </service-description>
- <service-description>
- <provide interface="calculator.dosgi.operations.DivideService" />
- <property name="service.intents">sca:SOAP sca:HTTP</property>
- <property name="osgi.remote.configuration.type">org.osgi.sca</property>
- <property name="osgi.remote.configuration.sca.componentType">
- OSGI-INF/sca/bundle.componentType
- </property>
- <property name="osgi.remote.configuration.sca.reference">
- divideService
- </property>
- </service-description>
-</service-descriptions> \ No newline at end of file
+ <endpoint-description>
+ <property name="objectClass" value="calculator.dosgi.operations.AddService" />
+ <property name="service.intents" value="sca:SOAP sca:HTTP" />
+ <property name="service.imported.configs" value="org.osgi.sca"/>
+ <property name="osgi.remote.configuration.type" value="org.osgi.sca" />
+ <property name="osgi.remote.configuration.sca.componentType" value="OSGI-INF/sca/bundle.componentType" />
+ <property name="osgi.remote.configuration.sca.reference" value="addService" />
+ </endpoint-description>
+ <endpoint-description>
+ <property name="objectClass" value="calculator.dosgi.operations.SubtractService" />
+ <property name="service.imported.configs" value="org.osgi.sca"/>
+ <property name="service.intents" value="sca:SOAP sca:HTTP" />
+ <property name="osgi.remote.configuration.type" value="org.osgi.sca" />
+ <property name="osgi.remote.configuration.sca.componentType" value="OSGI-INF/sca/bundle.componentType" />
+ <property name="osgi.remote.configuration.sca.reference" value="subtractService" />
+ </endpoint-description>
+ <endpoint-description>
+ <property name="objectClass" value="calculator.dosgi.operations.MultiplyService" />
+ <property name="service.intents" value="sca:SOAP sca:HTTP" />
+ <property name="service.imported.configs" value="org.osgi.sca"/>
+ <property name="osgi.remote.configuration.type" value="org.osgi.sca" />
+ <property name="osgi.remote.configuration.sca.componentType" value="OSGI-INF/sca/bundle.componentType" />
+ <property name="osgi.remote.configuration.sca.reference" value="multiplyService" />
+ </endpoint-description>
+ <endpoint-description>
+ <property name="objectClass" value="calculator.dosgi.operations.DivideService" />
+ <property name="service.imported.configs" value="org.osgi.sca"/>
+ <property name="service.intents" value="sca:SOAP sca:HTTP" />
+ <property name="osgi.remote.configuration.type" value="org.osgi.sca" />
+ <property name="osgi.remote.configuration.sca.componentType" value="OSGI-INF/sca/bundle.componentType" />
+ <property name="osgi.remote.configuration.sca.reference" value="divideService" />
+ </endpoint-description>
+</endpoint-descriptions> \ No newline at end of file