From de3ec14e972052db72a3fd9589c898cf3ae0ae26 Mon Sep 17 00:00:00 2001 From: rfeng Date: Sat, 9 Jan 2010 18:00:24 +0000 Subject: 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 --- .../remoteserviceadmin/impl/EndpointHelper.java | 6 +- .../impl/EndpointIntrospector.java | 7 +- .../impl/ExportRegistrationImpl.java | 17 +- .../impl/ImportRegistrationImpl.java | 2 +- .../impl/OSGiServiceExporter.java | 4 +- .../impl/RemoteServiceAdminImpl.java | 20 +- .../discovery/impl/DomainDiscoveryService.java | 19 + .../discovery/impl/LocalDiscoveryService.java | 16 +- .../remoteserviceadmin/EndpointDescription.java | 153 +++-- .../remoteserviceadmin/EndpointPermission.java | 624 ++++++--------------- .../remoteserviceadmin/RemoteConstants.java | 41 +- .../calculator-service-descriptions.xml | 82 ++- 12 files changed, 394 insertions(+), 597 deletions(-) (limited to 'sca-java-2.x/trunk/modules/node-impl-osgi') 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 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 props = new Hashtable(); + 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(); 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 props = new HashMap(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 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 corresponding + * service.imported.* 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 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 * @version $Revision$ @@ -62,15 +65,17 @@ import org.osgi.framework.Version; public class EndpointDescription { private final Map properties; private final List 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. * *

- * 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 objectClass properties must be set. * * @param properties The map from which to create the Endpoint Description. * The keys in the map must be type String 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(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. * *

- * 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. + *

+ * The {@link RemoteConstants#ENDPOINT_ID endpoint.id}, + * {@link RemoteConstants#SERVICE_IMPORTED_CONFIGS service.imported.configs} + * and objectClass 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(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 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 null. + * @return The id of the endpoint, never null. */ - 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 result = new ArrayList(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 { * *

* An Endpoint Description is considered to be equal to another - * Endpoint Description if their URIs are equal. + * Endpoint Description if their ids are equal. * * @param other The EndpointDescription object to be compared. * @return true if object 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 EndpointDescription against the - * given filter using a case insensitive match. + * Tests the properties of this EndpointDescription against + * the given filter using a case insensitive match. * * @param filter The filter to test. * @return true 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 extends Dictionary { + static class UnmodifiableDictionary extends Dictionary { private final Map wrapped; UnmodifiableDictionary(Map 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; /** - *

- * -------------------------------------------------------------
- * THIS CLASS IS A PLACEHOLDER (COPIED FROM SERVICE PERMISSION)!
- * -------------------------------------------------------------
- * 
- * - * A bundle's authority to register or get a service. + * A bundle's authority to export, import or read an Endpoint. *
    - *
  • The register action allows a bundle to register a service on - * the specified names. - *
  • The get action allows a bundle to detect a service and get - * it. + *
  • The export action allows a bundle to export a service as an + * Endpoint.
  • + *
  • The import action allows a bundle to import a service from + * an Endpoint.
  • + *
  • The read action allows a bundle to read references to an + * Endpoint.
  • *
- * 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 - * EndpointPermission 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 + * EndpointPermission 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 export. + * The action string read. */ - public final static String EXPORT = "export"; + public final static String READ = "read"; /** - * The action string import. + * The action string import. The import action + * implies the read action. */ - public final static String IMPORT = "import"; + public final static String IMPORT = "import"; /** - * The action string read. + * The action string export. The export action + * implies the read 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 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. * *

- * The name of the service is specified as a fully qualified class name. - * Wildcards may be used. - * - *

-	 * name ::= <class name> | <class name ending in ".*"> | *
-	 * 
- * - * Examples: - * - *
-	 * org.osgi.service.http.HttpService
-	 * org.osgi.service.http.*
-	 * *
-	 * 
- * - * For the get action, the name can also be a filter - * expression. The filter gives access to the service properties as well as - * the following attributes: - *
    - *
  • 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.
  • - *
  • location - The location of the bundle publishing the service.
  • - *
  • id - The bundle ID of the bundle publishing the service.
  • - *
  • name - The symbolic name of the bundle publishing the service.
  • - *
- * 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. * *

- * There are two possible actions: get and - * register. The get permission allows the owner - * of this permission to obtain a service with this name. The - * register permission allows the bundle to register a service - * under that name. + * There are three possible actions: read, import + * and export. The read action allows the owner of + * this permission to see the presence of distributed services. The + * import action allows the owner of this permission to import + * an endpoint. The export action allows the owner of this + * permission to export a service. * - * @param name The service class name - * @param actions get,register (canonical order) - * @throws IllegalArgumentException If the specified name is a filter - * expression and either the specified action is not - * get 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 "*" to match all + * endpoints. + * @param actions The actions read, import, or + * 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 EndpointPermission object to be used - * by code that must perform checkPermission for the - * get action. EndpointPermission objects created - * with this constructor cannot be added to a - * EndpointPermission permission collection. + * by code that must perform checkPermission. + * EndpointPermission objects created with this constructor + * cannot be added to an EndpointPermission permission + * collection. * - * @param endpoint The requested service. - * @param actions The action get. - * @throws IllegalArgumentException If the specified action is not - * get or reference is null. - * @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 + * <<LOCAL>> value in the filter expression. + * @param actions The actions read, import, or + * export. + * @throws IllegalArgumentException If the endpoint is null 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 props; + if ((localFrameworkUUID != null) + && localFrameworkUUID.equals(endpoint.getRemoteFrameworkUUID())) { + props = new TreeMap(String.CASE_INSENSITIVE_ORDER); + props.putAll(endpoint.getProperties()); + props.put(ENDPOINT_FRAMEWORK_UUID, new String[] { + endpoint.getRemoteFrameworkUUID(), "<>"}); + } + else { + props = endpoint.getProperties(); } + this.endpoint = endpoint; + this.properties = new EndpointDescription.UnmodifiableDictionary( + 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 null 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: get, - * register. + * returns present actions in the following canonical order: + * read, import, export. * * @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 - * EndpointPermission. + * Checks that specified object has the same name, actions and endpoint as + * this EndpointPermission. * * @param obj The object to test for equality. * @return true if obj is a EndpointPermission, and has the - * same class name and actions as this + * same name, actions and endpoint as this * EndpointPermission object; false * 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/* */getProperties() { - Dictionary/* */result = properties; - if (result != null) { - return result; - } - if (endpoint == null) { - result = new Hashtable/* */(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 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 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(); 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 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,136 +632,62 @@ final class EndpointPermissionCollection extends PermissionCollection { if (requested.filter != null) { return false; } - int effective = EndpointPermission.ACTION_NONE; - Collection perms; + Collection 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 iter = perms.iterator(); iter + .hasNext();) { + if (iter.next().implies0(requested, effective)) { return true; } } return false; } - /** - * 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 EndpointPermission 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 elements() { + List all = new ArrayList(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) gfields.get( + "permissions", new HashMap()); 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. - * *

* The value of this property must be of type String, - * String[], or Collection of String. + * String[], or Collection<String>. */ public static final String REMOTE_CONFIGS_SUPPORTED = "remote.configs.supported"; @@ -44,7 +43,7 @@ public class RemoteConstants { * *

* The value of this property must be of type String, - * String[], or Collection of String. + * String[], or Collection<String>. */ public static final String REMOTE_INTENTS_SUPPORTED = "remote.intents.supported"; @@ -59,7 +58,7 @@ public class RemoteConstants { * Dictionary object passed to the * BundleContext.registerService method. The value of this * property must be of type String, String[], or - * Collection of String. + * Collection<String>. */ public static final String SERVICE_EXPORTED_CONFIGS = "service.exported.configs"; @@ -75,7 +74,7 @@ public class RemoteConstants { * Dictionary object passed to the * BundleContext.registerService method. The value of this * property must be of type String, String[], or - * Collection of String. + * Collection<String>. */ public static final String SERVICE_EXPORTED_INTENTS = "service.exported.intents"; @@ -94,7 +93,7 @@ public class RemoteConstants { * Dictionary object passed to the * BundleContext.registerService method. The value of this * property must be of type String, String[], or - * Collection of String. + * Collection<String>. */ public static final String SERVICE_EXPORTED_INTENTS_EXTRA = "service.exported.intents.extra"; @@ -113,7 +112,7 @@ public class RemoteConstants { * Dictionary object passed to the * BundleContext.registerService method. The value of this * property must be of type String, String[], or - * Collection of String. + * Collection<String>. */ public static final String SERVICE_EXPORTED_INTERFACES = "service.exported.interfaces"; @@ -139,7 +138,7 @@ public class RemoteConstants { * *

* The value of this property must be of type String, - * String[], or Collection of String. + * String[], or Collection<String>. * * @see #SERVICE_EXPORTED_CONFIGS */ @@ -153,34 +152,30 @@ public class RemoteConstants { * provider that these intents are already implemented by the exported * service object. *

  • 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.
    • + * intents of: The exporting service, and, the intents that the exporting + * distribution provider adds, and the intents that the importing + * distribution provider adds. *
    - * - * - * 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. * *

    * The value of this property must be of type String, - * String[], or Collection of String. + * String[], or Collection<String>. */ 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. * *

    * The value of this property must be of type String. */ - 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 { *

    * The value of this property must be of type Long. */ - 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. --> - - + + - - - sca:SOAP sca:HTTP - org.osgi.sca - - OSGI-INF/sca/bundle.componentType - - - addService - - - - - sca:SOAP sca:HTTP - org.osgi.sca - - OSGI-INF/sca/bundle.componentType - - - subtractService - - - - - sca:SOAP sca:HTTP - org.osgi.sca - - OSGI-INF/sca/bundle.componentType - - - multiplyService - - - - - sca:SOAP sca:HTTP - org.osgi.sca - - OSGI-INF/sca/bundle.componentType - - - divideService - - - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file -- cgit v1.2.3