cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From egl...@apache.org
Subject svn commit: r738547 [1/2] - in /cxf/sandbox/dosgi: discovery/local/ discovery/local/src/main/java/org/apache/cxf/dosgi/discovery/local/ discovery/local/src/main/java/org/osgi/service/discovery/ dsw/cxf-dsw/ dsw/cxf-dsw/src/main/java/org/apache/cxf/dosg...
Date Wed, 28 Jan 2009 17:16:21 GMT
Author: eglynn
Date: Wed Jan 28 17:16:16 2009
New Revision: 738547

URL: http://svn.apache.org/viewvc?rev=738547&view=rev
Log:
[dOSGi] add support for interaction with Discovery via white-board pattern

Added:
    cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/DiscoveredServiceNotification.java
    cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/DiscoveredServiceTracker.java
    cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/ServicePublication.java
    cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/osgi/service/discovery/DiscoveredServiceNotification.java
    cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/osgi/service/discovery/DiscoveredServiceTracker.java
    cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/osgi/service/discovery/ServicePublication.java
Removed:
    cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/FindServiceCallback.java
    cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/ServiceListener.java
Modified:
    cxf/sandbox/dosgi/discovery/local/pom.xml
    cxf/sandbox/dosgi/discovery/local/src/main/java/org/apache/cxf/dosgi/discovery/local/LocalDiscoveryService.java
    cxf/sandbox/dosgi/discovery/local/src/main/java/org/apache/cxf/dosgi/discovery/local/ServiceEndpointDescriptionImpl.java
    cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/Discovery.java
    cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/ServiceEndpointDescription.java
    cxf/sandbox/dosgi/dsw/cxf-dsw/pom.xml
    cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/OsgiUtils.java
    cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/AbstractPojoConfigurationTypeHandler.java
    cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/ClientServiceFactory.java
    cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/HttpServiceConfigurationTypeHandler.java
    cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/PojoConfigurationTypeHandler.java
    cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/WsdlConfigurationTypeHandler.java
    cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/hooks/AbstractClientHook.java
    cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/hooks/AbstractHook.java
    cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/hooks/CxfListenerHook.java
    cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/hooks/CxfPublishHook.java
    cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/hooks/ServiceHookUtils.java
    cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/ServiceEndpointDescriptionImpl.java
    cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/osgi/service/discovery/Discovery.java
    cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/osgi/service/discovery/ServiceEndpointDescription.java
    cxf/sandbox/dosgi/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/ActivatorTest.java
    cxf/sandbox/dosgi/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/TestUtils.java
    cxf/sandbox/dosgi/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/hooks/BundleTestContext.java
    cxf/sandbox/dosgi/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/hooks/CxfListenerHookTest.java
    cxf/sandbox/dosgi/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/hooks/CxfPublishHookTest.java
    cxf/sandbox/dosgi/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/hooks/ServiceHookUtilsTest.java

Modified: cxf/sandbox/dosgi/discovery/local/pom.xml
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/discovery/local/pom.xml?rev=738547&r1=738546&r2=738547&view=diff
==============================================================================
--- cxf/sandbox/dosgi/discovery/local/pom.xml (original)
+++ cxf/sandbox/dosgi/discovery/local/pom.xml Wed Jan 28 17:16:16 2009
@@ -38,7 +38,7 @@
         <bundle.import.package>*</bundle.import.package>
         <bundle.export.package>
           org.apache.cxf.dosgi.discovery.local.*;version="${pom.version}",
-          org.osgi.service.discovery;version="4.2.0";-split-package:=merge-first
+          org.osgi.service.discovery;version="1.0";-split-package:=merge-first
         </bundle.export.package>
     </properties>
     

Modified: cxf/sandbox/dosgi/discovery/local/src/main/java/org/apache/cxf/dosgi/discovery/local/LocalDiscoveryService.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/discovery/local/src/main/java/org/apache/cxf/dosgi/discovery/local/LocalDiscoveryService.java?rev=738547&r1=738546&r2=738547&view=diff
==============================================================================
--- cxf/sandbox/dosgi/discovery/local/src/main/java/org/apache/cxf/dosgi/discovery/local/LocalDiscoveryService.java (original)
+++ cxf/sandbox/dosgi/discovery/local/src/main/java/org/apache/cxf/dosgi/discovery/local/LocalDiscoveryService.java Wed Jan 28 17:16:16 2009
@@ -32,6 +32,7 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ConcurrentHashMap;
@@ -45,11 +46,18 @@
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
 import org.osgi.framework.Filter;
+import org.osgi.framework.ServiceReference;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.service.discovery.Discovery;
-import org.osgi.service.discovery.FindServiceCallback;
+import org.osgi.service.discovery.DiscoveredServiceNotification;
+import org.osgi.service.discovery.DiscoveredServiceTracker;
 import org.osgi.service.discovery.ServiceEndpointDescription;
-import org.osgi.service.discovery.ServiceListener;
+import org.osgi.util.tracker.ServiceTracker;
+
+import static org.osgi.service.discovery.DiscoveredServiceNotification.AVAILABLE;
+import static org.osgi.service.discovery.DiscoveredServiceNotification.UNAVAILABLE;
+import static org.osgi.service.discovery.DiscoveredServiceTracker.PROP_KEY_MATCH_CRITERIA_FILTERS;
+import static org.osgi.service.discovery.DiscoveredServiceTracker.PROP_KEY_MATCH_CRITERIA_INTERFACES;
 
 public class LocalDiscoveryService implements Discovery {
     
@@ -71,30 +79,64 @@
     private static final String PROPERTY_ELEMENT = "property";
     private static final String PROPERTY_KEY_ATTRIBUTE = "name";
     
-    // TODO : these properties should be configurable
-    private static final long ASYNC_WAIT_TIME = 5000L;
+    // TODO : this property should be configurable
     private static final long CONFIG_CHECK_TIME = 5000L;
     
     // this is effectively a set which allows for multiple service descriptions with the
     // same interface name but different properties and takes care of itself with respect to concurrency 
     private ConcurrentHashMap<ServiceEndpointDescription, ServiceEndpointDescription> servicesInfo = 
         new ConcurrentHashMap<ServiceEndpointDescription, ServiceEndpointDescription>();
-    private ConcurrentHashMap<ServiceListener, Filter> listeners = 
-        new ConcurrentHashMap<ServiceListener, Filter>();
+    private Map<ServiceEndpointDescription, ServiceEndpointDescription> oldServicesInfo =
+        new HashMap<ServiceEndpointDescription, ServiceEndpointDescription>();
+    private Map<ServiceEndpointDescription, ServiceEndpointDescription> newServicesInfo =
+        new HashMap<ServiceEndpointDescription, ServiceEndpointDescription>();
+    private Map<String, List<DiscoveredServiceTracker>> interfacesToTrackers = 
+        new HashMap<String, List<DiscoveredServiceTracker>>();
+    private Map<String, List<DiscoveredServiceTracker>> filtersToTrackers = 
+        new HashMap<String, List<DiscoveredServiceTracker>>();
+    private Map<DiscoveredServiceTracker, Collection> trackersToInterfaces = 
+        new HashMap<DiscoveredServiceTracker, Collection>();
+    private Map<DiscoveredServiceTracker, Collection> trackersToFilters = 
+        new HashMap<DiscoveredServiceTracker, Collection>();
     private BundleContext bc;
     
     private boolean attachedToBundle;
     private boolean isShutdown;
     
-    private BlockingQueue<Callable<Boolean>> asyncChecks 
-        = new LinkedBlockingQueue<Callable<Boolean>>();
-    private Thread asyncChecksThread;
     private Thread configChecksThread;
     private long lastConfigModification;
+    private ServiceTracker trackerTracker;
     
     public LocalDiscoveryService(BundleContext bc) {
         this.bc = bc;
         readMetadata();
+
+        // track the registration of DiscoveredServiceTrackers
+        trackerTracker = 
+            new ServiceTracker(bc,
+                               DiscoveredServiceTracker.class.getName(),
+                               null) {
+                public Object addingService(ServiceReference reference) {
+                    Object result = super.addingService(reference);
+                    cacheTracker(reference, result);
+                    return result;
+                }
+
+                public void modifiedService(ServiceReference reference,
+                                            Object service) {
+                    super.modifiedService(reference, service);
+                    updateTracker(reference, service);
+                }
+
+                public void removedService(ServiceReference reference,
+                                           Object service) {
+                    super.removedService(reference, service);
+                    clearTracker(service);
+                }
+            };
+
+        trackerTracker.open();
+
         if (!attachedToBundle) {
             configChecksThread = new Thread(new ConfigCheckRunnable());
             configChecksThread.start();
@@ -103,119 +145,186 @@
 
     public void updateProperties(Dictionary props) {
     }
-    
-    public void addServiceListener(ServiceListener sl, String filter) {
-        listeners.put(sl, createFilter(filter));
-    }
-    
-    public void addServiceListener(ServiceListener sl) {
-        listeners.put(sl, null);
-    }
 
-    public void removeServiceListener(ServiceListener sl) {
-        listeners.remove(sl);
-    }
-    
-    public Collection /*<ServiceEndpointDescription>*/ findService(String interfaceName, String filter) {
-        return findServiceWithFilter(interfaceName, createFilter(filter));
-    }
-    
-    public void findService(String interfaceName, String filter, FindServiceCallback listener) {
-        Filter f = createFilter(filter); 
-        if (f != null) {
-            doFindService(interfaceName, f, listener);
+    private synchronized void cacheTracker(ServiceReference reference, 
+                                           Object service) {
+        if (service instanceof DiscoveredServiceTracker) {
+            DiscoveredServiceTracker tracker = 
+                (DiscoveredServiceTracker)service;
+            Collection interfaces =            
+                addTracker(reference, 
+                           tracker, 
+                           PROP_KEY_MATCH_CRITERIA_INTERFACES, 
+                           interfacesToTrackers,
+                           trackersToInterfaces);
+            Collection filters = 
+                addTracker(reference,
+                           tracker, 
+                           PROP_KEY_MATCH_CRITERIA_FILTERS, 
+                           filtersToTrackers,
+                           trackersToFilters);
+
+           triggerCallbacks(null, interfaces, tracker, false);
+           triggerCallbacks(null, filters, tracker, true);
+        }        
+    }
+
+    private synchronized void updateTracker(ServiceReference reference, 
+                                            Object service) {
+        if (service instanceof DiscoveredServiceTracker) {
+            DiscoveredServiceTracker tracker = 
+                (DiscoveredServiceTracker)service;
+            LOG.info("updating tracker: " + tracker);
+            Collection oldInterfaces = removeTracker(tracker, 
+                                                     interfacesToTrackers,
+                                                     trackersToInterfaces);
+            Collection oldFilters = removeTracker(tracker, 
+                                                  filtersToTrackers,
+                                                  trackersToFilters);
+
+            Collection newInterfaces = 
+                addTracker(reference, 
+                           tracker, 
+                           PROP_KEY_MATCH_CRITERIA_INTERFACES, 
+                           interfacesToTrackers,
+                           trackersToInterfaces);
+            Collection newFilters = 
+                addTracker(reference,
+                           tracker, 
+                           PROP_KEY_MATCH_CRITERIA_FILTERS, 
+                           filtersToTrackers,
+                           trackersToFilters);
+
+            triggerCallbacks(oldInterfaces, newInterfaces, tracker, false);
+            triggerCallbacks(oldFilters, newFilters, tracker, true);
+        }
+    }
+
+    private synchronized void clearTracker(Object service) {
+        if (service instanceof DiscoveredServiceTracker) {
+            removeTracker((DiscoveredServiceTracker)service, 
+                          interfacesToTrackers,
+                          trackersToInterfaces);
+            removeTracker((DiscoveredServiceTracker)service, 
+                          filtersToTrackers,
+                          trackersToFilters);
+        }
+    }
+
+    private Collection addTracker(
+                      ServiceReference reference, 
+                      DiscoveredServiceTracker tracker,
+                      String property,
+                      Map<String, List<DiscoveredServiceTracker>> forwardMap,
+                      Map<DiscoveredServiceTracker, Collection> reverseMap) {
+        Collection collection = 
+            (Collection)reference.getProperty(property);
+        LOG.info("adding tracker: " + tracker + " collection: " + collection + " registered against prop: " + property);
+        if (nonEmpty(collection)) {
+            reverseMap.put(tracker, collection);
+            Iterator i = collection.iterator();
+            while (i.hasNext()) {
+                String element = (String)i.next();
+                if (forwardMap.containsKey(element)) {
+                    forwardMap.get(element).add(tracker);
+                } else {
+                    List<DiscoveredServiceTracker> trackerList = 
+                        new ArrayList<DiscoveredServiceTracker>();
+                    trackerList.add(tracker);
+                    forwardMap.put(element, trackerList);
+                }
+            }
         }
+        return collection;
     }
-    
-    @SuppressWarnings("unchecked")
-    private Collection<ServiceEndpointDescription> findServiceWithFilter(
-        String interfaceName, Filter f) {
-        if (f == null) {
-            return Collections.emptyList();    
-        }
-        
-        List<ServiceEndpointDescription> sds = new ArrayList<ServiceEndpointDescription>();
-        
-        for (ServiceEndpointDescription sd : servicesInfo.values()) {
-            if (f.match(getServiceProperties(interfaceName, sd))) {
-                sds.add(sd);
+
+    private Collection removeTracker(
+                      DiscoveredServiceTracker tracker,
+                      Map<String, List<DiscoveredServiceTracker>> forwardMap,
+                      Map<DiscoveredServiceTracker, Collection> reverseMap) {
+        Collection collection = reverseMap.get(tracker);
+        if (nonEmpty(collection)) {
+            reverseMap.remove(tracker);
+            Iterator i = collection.iterator();
+            while (i.hasNext()) {
+                String element = (String)i.next();
+                if (forwardMap.containsKey(element)) {
+                    forwardMap.get(element).remove(tracker);
+                }
             }
         }
-        return sds;
+        return collection;
     }
-    
-    
-    private void doFindService(final String interfaceName, final Filter f, 
-                               final FindServiceCallback listener) {
-        if (attachedToBundle) {
-            checkServices(interfaceName, f, listener);
-            return;
-        }
-        
-        synchronized (this) {
-            if (isShutdown) {
-                return;
-            }
-            if (asyncChecksThread == null) {
-                asyncChecksThread = new Thread(new AsyncCheckRunnable());
-                asyncChecksThread.start();
+
+    private void triggerCallbacks(Collection oldInterest, 
+                                  Collection newInterest, 
+                                  DiscoveredServiceTracker tracker,
+                                  boolean isFilter) {
+        // compute delta between old & new interfaces/filters and
+        // trigger callbacks for any entries in servicesInfo that
+        // match any *additional* interface/filters  
+        Collection deltaInterest = new ArrayList();
+        if (nonEmpty(newInterest)) {
+            if (isEmpty(oldInterest)) {
+                deltaInterest.addAll(newInterest);
+            } else {
+                Iterator i = newInterest.iterator();
+                while (i.hasNext()) {
+                    String next = (String)i.next();
+                    if (!oldInterest.contains(next)) {
+                        deltaInterest.add(next);
+                    }
+                }
             }
         }
-        asyncChecks.add(new Callable<Boolean>() {
 
-            public Boolean call() throws Exception {
-                return checkServices(interfaceName, f, listener); 
-            }
-            
-        });
-    }
-    
-    private boolean checkServices(String interfaceName, Filter f, FindServiceCallback listener) {
-        Collection<ServiceEndpointDescription> sds = 
-            findServiceWithFilter(interfaceName, f);
-        if (sds.isEmpty()) {
-            return false;
+        if (servicesInfo.size() > 0) {
+            LOG.info("search for matches to trigger callbacks with delta: " + deltaInterest);
         } else {
-            listener.servicesFound(sds);
-            return true;
+            LOG.info("nothing to search for matches to trigger callbacks with delta: " + deltaInterest);
+        }
+        Iterator i = deltaInterest.iterator();
+        while (i.hasNext()) {
+            String next = (String)i.next();
+            for (ServiceEndpointDescription sd : servicesInfo.values()) {
+                LOG.info("check if next: " + next + (isFilter ? " matches " : " contained by ") +  sd.getProvidedInterfaces());
+                if ((isFilter && filterMatches(next, sd))
+                    || sd.getProvidedInterfaces().contains(next)) {
+                    tracker.serviceChanged(new TrackerNotification(sd, 
+                                                                   AVAILABLE));
+                }
+            }
         }
     }
-    
-    public ServiceEndpointDescription publishService(Map javaInterfaces,
-                                                     Map endpointInterfaces,
-                                                     Map properties) {
-        return publishService(javaInterfaces, endpointInterfaces, properties, true);
-        
+
+    private static boolean nonEmpty(Collection c) {
+        return c != null && c.size() > 0;
     }
-    
-    @SuppressWarnings("unchecked")
-    public ServiceEndpointDescription publishService(Map javaInterfaces,
-                                                     Map endpointInterfaces,
-                                                     Map properties, 
-                                                     boolean autoPublish) {
-        ServiceEndpointDescriptionImpl sd = new ServiceEndpointDescriptionImpl(javaInterfaces,
-                                                                               endpointInterfaces,
-                                                                               properties);
-        servicesInfo.putIfAbsent(sd, sd);
-        for (Map.Entry<ServiceListener, Filter> entry : listeners.entrySet()) {
-            if (entry.getValue() == null 
-                || entry.getValue().match(getServiceProperties(null, sd))) {
-                entry.getKey().serviceAvailable(sd);
-            }
-        }
-        return sd;
-    }
-    
-    public void unpublishService(ServiceEndpointDescription sd) {
-        servicesInfo.remove(sd);
-        for (Map.Entry<ServiceListener, Filter> entry : listeners.entrySet()) {
-            if (entry.getValue() == null 
-                || entry.getValue().match(getServiceProperties(null, sd))) {
-                entry.getKey().serviceUnavailable(sd);
-            }
+
+    private static boolean isEmpty(Collection c) {
+        return c == null || c.size() == 0;
+    }
+
+    private static class TrackerNotification 
+        implements DiscoveredServiceNotification {
+
+        private ServiceEndpointDescription sd;
+        private int type;
+
+        TrackerNotification(ServiceEndpointDescription sd, int type) {
+            this.sd = sd;
+            this.type = type;
+        }
+
+        public ServiceEndpointDescription getServiceEndpointDescription() {
+            return sd;
         }
-    }        
 
+        public int getType() {
+            return type;
+        }
+    }
+    
     private void readMetadata() {
         
         InputStream is = getRemoteServicesStream();
@@ -236,8 +345,7 @@
     }
     
     private InputStream getRemoteServicesStream() {
-        
-        
+   
         // check default location
         File f = new File(System.getProperty("user.dir") + DEFAULT_SERVICES_LOCATION);
         if (f.exists()) {
@@ -270,8 +378,6 @@
         return null;
     }
     
-    
-    
     @SuppressWarnings("unchecked")
     private void readRemoteServices(InputStream is) throws Exception {
 
@@ -279,20 +385,81 @@
         Namespace ns = Namespace.getNamespace(REMOTE_SERVICES_NS);
         List<Element> references = d.getRootElement().getChildren(SERVICE_DESCRIPTION_ELEMENT, ns);
         
+        Set<ServiceEndpointDescription> keys = servicesInfo.keySet();
+        for (ServiceEndpointDescription sd : keys) {
+            oldServicesInfo.put(sd, sd);
+        }
         servicesInfo.clear();
         
         for (Element ref : references) {
-            List<String> iNames = getInterfaceNames(ref.getChildren(PROVIDE_INTERFACE_ELEMENT, ns));
+            List<String> iNames = getProvidedInterfaces(ref.getChildren(PROVIDE_INTERFACE_ELEMENT, ns));
             if (iNames.isEmpty()) {
                 continue;
             }
             
             ServiceEndpointDescription sd = new ServiceEndpointDescriptionImpl(iNames,  
                           getProperties(ref.getChildren(PROPERTY_ELEMENT, ns)));
+            LOG.info("retrieved remote-service info for: " + sd.getProvidedInterfaces());
             servicesInfo.putIfAbsent(sd, sd);
+            if (!oldServicesInfo.containsKey(sd)) {
+                newServicesInfo.put(sd, sd);
+            } else {
+                oldServicesInfo.remove(sd);
+            }
         }
         
-    }
+        triggerCallbacks();
+    }
+
+    private void triggerCallbacks() {
+        // REVISIT: generating modified callbacks for interface elements with
+        // modified properties is problematic since multiple interface elements
+        // with the same provides attribute are currently considered to 
+        // represent distinct service instances
+
+        // iterate over oldServicesInfo generating unavailable callbacks for
+        // completely removed service instances
+        triggerNotificationsFor(oldServicesInfo, UNAVAILABLE);
+
+
+        // iterate over newServicesInfo generating added callbacks for
+        // new services
+        triggerNotificationsFor(newServicesInfo, AVAILABLE);
+    }
+
+    private void triggerNotificationsFor(Map<ServiceEndpointDescription, ServiceEndpointDescription> sds, int type) {
+        Set<ServiceEndpointDescription> keys = sds.keySet();
+        for (ServiceEndpointDescription sd : keys) {
+            Iterator interfaces = interfacesToTrackers.keySet().iterator();
+            while (interfaces.hasNext()) {
+                String next = (String)interfaces.next();
+                // REVISIT: shouldn't the notification include some indication
+                // of which interface name (or filter) fired the match?
+                if (sd.getProvidedInterfaces().contains(next)) {
+                    List<DiscoveredServiceTracker> trackers = 
+                        interfacesToTrackers.get(next);
+                    for (DiscoveredServiceTracker tracker : trackers) {
+                        tracker.serviceChanged(new TrackerNotification(sd, 
+                                                                       type));
+                    }
+                }
+            }
+
+            Iterator filters = filtersToTrackers.keySet().iterator();
+            while (filters.hasNext()) {
+                String next = (String)filters.next();
+                if (filterMatches(next, sd)) {
+                    List<DiscoveredServiceTracker> trackers = 
+                        filtersToTrackers.get(next);
+                    for (DiscoveredServiceTracker tracker : trackers) {
+                        tracker.serviceChanged(new TrackerNotification(sd, 
+                                                                       type));
+                    }
+                }
+            }
+        }
+        sds.clear();
+   }
     
     private Map<String, Object> getProperties(List<Element> elementProps) {
         
@@ -308,7 +475,7 @@
         return props;
     }
  
-    private static List<String> getInterfaceNames(List<Element> elements) {
+    private static List<String> getProvidedInterfaces(List<Element> elements) {
         
         List<String> names = new ArrayList<String>();
         
@@ -325,59 +492,12 @@
     public void shutdown() {
         synchronized (this) {
             isShutdown = true;
-            if (asyncChecksThread != null) {
-                asyncChecksThread.interrupt();
-            }
         }    
         if (configChecksThread != null) {
             configChecksThread.interrupt();
         }
     }
     
-    private class AsyncCheckRunnable implements Runnable {
-
-        public void run() {
-            while (!Thread.currentThread().isInterrupted()) {
-                try {
-                    // wait untill we have at least one task
-                    Callable<Boolean> task = asyncChecks.take();
-                    Collection<Callable<Boolean>> remainingTasks = null;
-                    if (asyncChecks.size() > 0) {
-                        remainingTasks = 
-                            new ArrayList<Callable<Boolean>>(asyncChecks);
-                    } else {
-                        remainingTasks = Collections.emptyList();
-                    }
-                    // try the first task
-                    if (!tryTask(task)) {
-                        asyncChecks.add(task);
-                    }
-                    
-                    // try the rest
-                    for (Callable<Boolean> c : remainingTasks) {
-                        if (tryTask(c)) {
-                            asyncChecks.remove(c);
-                        } 
-                    }
-                    
-                    Thread.sleep(ASYNC_WAIT_TIME);
-                } catch (InterruptedException ex) {
-                    Thread.currentThread().interrupt();
-                }
-            }
-            
-        }
-        
-        
-        private boolean tryTask(Callable<Boolean> task) {
-            try {
-                return task.call();
-            } catch (Exception ex) {
-                return false;
-            }
-        }
-    }
-    
     private class ConfigCheckRunnable implements Runnable {
 
         public void run() {
@@ -410,26 +530,34 @@
         return null;
     }
 
+    private boolean filterMatches(String filterValue, 
+                                  ServiceEndpointDescription sd) {
+        Filter filter = createFilter(filterValue);
+        return filter != null
+               ? filter.match(getServiceProperties(null, sd))
+               : false;
+    }
+
     @SuppressWarnings("unchecked")
     private Dictionary<String, Object> getServiceProperties(String interfaceName,
                                                             ServiceEndpointDescription sd) {
         Dictionary<String, Object> d = new Hashtable<String, Object>(sd.getProperties());
         
-        String[] interfaceNames = getInterfaceNames(sd, interfaceName);
+        String[] interfaceNames = getProvidedInterfaces(sd, interfaceName);
         if (interfaceNames != null) {
             d.put(Constants.OBJECTCLASS, interfaceNames);
         }
         return d;
     }
     
-    private static String[] getInterfaceNames(ServiceEndpointDescription sd, String interfaceName) {
+    private static String[] getProvidedInterfaces(ServiceEndpointDescription sd, String interfaceName) {
         
-        Collection interfaceNames = sd.getInterfaceNames();
+        Collection interfaceNames = sd.getProvidedInterfaces();
         if (interfaceName == null) {
             return null;
         }
         
-	Iterator iNames = interfaceNames.iterator();
+        Iterator iNames = interfaceNames.iterator();
         while (iNames.hasNext()) {
             if (iNames.next().equals(interfaceName)) {
                 return new String[]{interfaceName};

Modified: cxf/sandbox/dosgi/discovery/local/src/main/java/org/apache/cxf/dosgi/discovery/local/ServiceEndpointDescriptionImpl.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/discovery/local/src/main/java/org/apache/cxf/dosgi/discovery/local/ServiceEndpointDescriptionImpl.java?rev=738547&r1=738546&r2=738547&view=diff
==============================================================================
--- cxf/sandbox/dosgi/discovery/local/src/main/java/org/apache/cxf/dosgi/discovery/local/ServiceEndpointDescriptionImpl.java (original)
+++ cxf/sandbox/dosgi/discovery/local/src/main/java/org/apache/cxf/dosgi/discovery/local/ServiceEndpointDescriptionImpl.java Wed Jan 28 17:16:16 2009
@@ -30,6 +30,8 @@
 
 import org.osgi.service.discovery.ServiceEndpointDescription;
 
+import static org.osgi.service.discovery.ServicePublication.PROP_KEY_ENDPOINT_LOCATION;
+
 public class ServiceEndpointDescriptionImpl implements ServiceEndpointDescription {
 
     private static final Logger LOG = 
@@ -54,13 +56,6 @@
         properties = remoteProperties;
     }
     
-    public ServiceEndpointDescriptionImpl(Map<String, String> javaInterfaces,
-                                          Map<String, String> endpointInterfaces,
-                                          Map<String, Object> remoteProperties) {
-        this.interfaceNames = new HashSet<String>(javaInterfaces.keySet());
-        properties = remoteProperties;
-    }
-    
     public Object getProperty(String key) {
         return properties.get(key);
     }
@@ -86,12 +81,12 @@
         }
         ServiceEndpointDescription other = (ServiceEndpointDescription)obj;
         
-        return interfaceNames.equals(other.getInterfaceNames())
+        return interfaceNames.equals(other.getProvidedInterfaces())
                && properties.equals(other.getProperties());
     }
 
     public URL getLocation() {
-        Object value = properties.get(ServiceEndpointDescription.PROP_KEY_SERVICE_LOCATION);
+        Object value = properties.get(PROP_KEY_ENDPOINT_LOCATION);
         if (value == null) {
             return null;
         }
@@ -105,15 +100,19 @@
         return null;
     }
 
-    public Collection /*<String>*/ getInterfaceNames() {
+    public Collection /*<String>*/ getProvidedInterfaces() {
         return interfaceNames;
     }
 
-    public String getProtocolSpecificInterfaceName(String interfaceName) {
+    public String getVersion(String interfaceName) {
+        return "0.0";
+    }
+
+    public String getEndpointInterfaceName(String interfaceName) {
         return interfaceName;
     }
 
-    public String getVersion(String interfaceName) {
-        return "0.0";
+    public String getEndpointID() {
+        return null;
     }
 }

Added: cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/DiscoveredServiceNotification.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/DiscoveredServiceNotification.java?rev=738547&view=auto
==============================================================================
--- cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/DiscoveredServiceNotification.java (added)
+++ cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/DiscoveredServiceNotification.java Wed Jan 28 17:16:16 2009
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) OSGi Alliance (2008). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.service.discovery;
+
+/**
+ * Interface for notification on discovered services.
+ * 
+ * @version $Revision$
+ */
+public interface DiscoveredServiceNotification {
+
+	/**
+	 * Notification indicating that a service matching the listening criteria has been
+	 * discovered.
+	 * <p>
+	 * The value of <code>AVAILABLE</code> is 0x00000001.
+	 */
+	public final static int AVAILABLE = 0x00000001;
+
+	/**
+	 * Notification indicating that the properties of a previously discovered service
+	 * have changed.
+	 * <p>
+	 * The value of <code>MODIFIED</code> is 0x00000002.
+	 */
+	public final static int MODIFIED = 0x00000002;
+
+	/**
+	 * Notification indicating that a previously discovered service is no longer known
+	 * to discovery.
+	 * <p>
+	 * The value of <code>UNAVAILABLE</code> is 0x00000004.
+	 */
+	public final static int UNAVAILABLE = 0x00000004;
+
+	/**
+	 * Notification indicating that the properties of a previously discovered service
+	 * have changed and the new properties no longer match the listener's
+	 * filter.
+	 * <p>
+	 * The value of <code>MODIFIED_ENDMATCH</code> is 0x00000008.
+	 */
+	public final static int MODIFIED_ENDMATCH = 0x00000008;
+
+	/**
+	 * Returns information currently known to Discovery regarding the service
+	 * endpoint.
+	 * <p>
+	 * 
+	 * @return metadata of the service this Discovery notifies about.
+	 */
+	ServiceEndpointDescription getServiceEndpointDescription();
+
+	/**
+	 * Returns the type of notification. The type values are:
+	 * <ul>
+	 * <li>{@link #AVAILABLE} </li> <li>{@link #MODIFIED} </li> <li>
+	 * {@link #MODIFIED_ENDMATCH} </li> <li>{@link #UNAVAILABLE} </li>
+	 * </ul>
+	 * 
+	 * @return Type of notification regarding known service metadata.
+	 */
+	int getType();
+}

Added: cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/DiscoveredServiceTracker.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/DiscoveredServiceTracker.java?rev=738547&view=auto
==============================================================================
--- cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/DiscoveredServiceTracker.java (added)
+++ cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/DiscoveredServiceTracker.java Wed Jan 28 17:16:16 2009
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) OSGi Alliance (2008). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.service.discovery;
+
+/**
+ * Interface of trackers for discovered remote services. <br>
+ * When such a service is registered with the framework, then {@link Discovery}
+ * will notify it about remote services matching one of the provided criteria
+ * and will keep notifying it on changes of information known to Discovery
+ * regarding this services.
+ * 
+ * <code>Discovery</code> may deliver notifications on discovered services to a
+ * <code>DiscoveredServiceTracker</code> out of order and may concurrently call
+ * and/or reenter a <code>DiscoveredServiceTracker</code>.
+ * 
+ * @version $Revision$
+ */
+public interface DiscoveredServiceTracker {
+
+	/**
+	 * Property describing service interfaces this tracker is interested in.
+	 * Value of this property is of type Collection (<? extends String>).<br>
+	 * Property is optional, may be null.
+	 */
+	public static final String PROP_KEY_MATCH_CRITERIA_INTERFACES = "osgi.discovery.interest.interfaces";
+
+	/**
+	 * Property describing filters for services this tracker is interested in.
+	 * Value of this property is of type Collection (<? extends String>). See
+	 * {@link ServicePublication} for some standard property keys used to
+	 * publish service metadata. <br>
+	 * Property is optional, may be null.
+	 */
+	public static final String PROP_KEY_MATCH_CRITERIA_FILTERS = "osgi.discovery.interest.filters";
+
+	/**
+	 * Receives notification that information known to Discovery regarding a
+	 * remote service has changed. <br>
+	 * The tracker is only notified about remote services which fulfill the
+	 * matching criteria, either one of the interfaces or one of the filters,
+	 * provided as properties of this service.
+	 * 
+	 * @param notification
+	 *            the <code>DiscoveredServiceNotification</code> object
+	 *            describing the change.
+	 */
+	void serviceChanged(DiscoveredServiceNotification notification);
+}

Modified: cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/Discovery.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/Discovery.java?rev=738547&r1=738546&r2=738547&view=diff
==============================================================================
--- cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/Discovery.java (original)
+++ cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/Discovery.java Wed Jan 28 17:16:16 2009
@@ -16,187 +16,42 @@
 
 package org.osgi.service.discovery;
 
-import java.util.Collection;
-import java.util.Map;
-
 /**
- * Interface of the Discovery service. This service allows to publish services
- * exposed for remote access as well as search for remote services. <BR>
+ * Discovery registers a service implementing this interface. This service is
+ * registered with extra properties identified at the beginning of this
+ * interface to denote the name of the product providing Discovery
+ * functionality, its version, vendor, used protocols etc.. 
+ * 
+ * Discovery allows to publish services exposed for remote access as well as to
+ * search for remote services. Register a {@link ServicePublication} service in
+ * order to publish service metadata and or a {@link DiscoveredServiceTracker}
+ * service in order to search for remote services.<BR>
  * Discovery service implementations usually rely on some discovery protocols or
  * other information distribution means.
  * 
  * @version $Revision$
  */
 public interface Discovery {
-    /**
-     * 
-     */
-    final String OSGI_DISCOVERY = "osgi.discovery";
-
-    /**
-     * 
-     */
-    final String OSGI_DISCOVERY_NONE = "none";
-
-    /**
-     * 
-     */
-    final String OSGI_DISCOVERY_AUTO_PUBLISH = "auto-publish";
-
-    /**
-     * Add a ServiceListener for a particular service description.
-     * 
-     * @param filter
-     *            a filter to services to listen for. If filter is
-     *            <code>null</code> then all services are considered.
-     * @param listener
-     *            which is to call when discovery detects changes in
-     *            availability or description of a service. The same listener
-     *            object may be used to listen on multiple service filters.
-     * @throws IllegalArgumentException
-     *             if listener is null or if filter is invalid
-     */
-    void addServiceListener(ServiceListener listener, String filter);
-
-    /**
-     * This method is the same as calling
-     * <code>Discovery.addServiceListener(ServiceListener listener, String filter)</code>
-     * with <code>filter</code> set to <code>null</code>.
-     * 
-     * @param listener
-     *            which is to call when discovery detects changes in
-     *            availability or description of a service. The same listener
-     *            object may be used to listen on multiple service filters.
-     * @throws IllegalArgumentException
-     *             if listener is null
-     * @see #addServiceListener(ServiceListener, String)
-     */
-    void addServiceListener(ServiceListener listener);
-
-    /**
-     * Removes a ServiceListener.
-     * 
-     * @param listener
-     *            ServiceListener which should be removed. If that listener
-     *            object was registered several times then all registrations
-     *            will be removed. If that listener object haven't been added
-     *            before, then the method returns without throwing exceptions.
-     */
-    void removeServiceListener(ServiceListener listener);
-
-    /**
-     * Searches for services matching the provided interface name and filter.
-     * 
-     * @param interfaceName
-     *            name of the interface that returned services have to provide.
-     *            If name is null then all services are considered to match.
-     * @param filter
-     *            an LDAP filter which the service has to satisfy. If filter is
-     *            null all services are considered to match.
-     * @return Collection of <code>ServiceEndpointDescription</code> objects
-     *         which were found to match interface name and filter. The
-     *         collection is empty if none was found. The collection represents
-     *         a snapshot and as such is not going to be updated in case other matching
-     *         services become available at a later point of time.
-     */
-    Collection /* <? extends ServiceEndpointDescription> */findService(
-            String interfaceName, String filter);
-
-    /**
-     * Asynchronous version of <code>Discovery.findService(String interfaceName,
-     * String filter)</code> method.
-     * 
-     * @param interfaceName
-     *            name of the interface returned services have to provide. If
-     *            name is null then all services are considered to match.
-     * @param filter
-     *            an LDAP filter which the service has to satisfy. Note that
-     *            <code>ServiceEndpointDescription</code> defines some
-     *            properties for service url, interface version etc.. If filter
-     *            is null all services are considered to match.
-     * @param callback
-     *            to notify about the asynchronous response of the find
-     *            operation
-     * @throws IllegalArgumentException
-     *             if callback is null
-     * @see #findService(String, String)
-     */
-    void findService(String interfaceName, String filter,
-            FindServiceCallback callback);
-
-    /**
-     * Publish the provided service meta-data.
-     * 
-     * @param javaInterfacesAndVersions
-     *            names of java interfaces offered by the service and their
-     *            version. For every interface to publish you have to define its
-     *            version. If you don't have a version, put "0.0.0" in it.
-     * @param javaInterfacesAndEndpointInterfaces
-     *            associates java interfaces to general end point interface
-     *            names. It is not needed to to have and end point interface for
-     *            a java interface. The map may be null.
-     * @param properties
-     *            a bag of service properties (key-value pairs) to be published.
-     *            It may be null. Note that Discovery might make use of certain
-     *            standard properties like the ones defined by
-     *            {@link ServiceEndpointDescription} for the publication process
-     *            if they are provided.
-     * 
-     * @return an instance of {@link ServiceEndpointDescription} or null if the
-     *         publishing failed
-     * 
-     * @throws IllegalArgumentException
-     *             if javaInterfacesAndVersions is null or empty
-     */
-    ServiceEndpointDescription publishService(
-            Map/* <String, String> */javaInterfacesAndVersions,
-            Map/* <String, String> */javaInterfacesAndEndpointInterfaces,
-            Map/* <String, Object> */properties);
-
-    /**
-     * Publish the provided service. The information is published by the
-     * Discovery implementation.<b> If the parameter autopublish=true, the
-     * Discovery implementation actively pushes the information about the
-     * service to the network. Otherwise, it is just available upon request from
-     * other Discovery implementations. The ServiceEndpointDescription is
-     * matched using the Comparable interface.
-     * 
-     * @param javaInterfacesAndVersions
-     *            its an association between interfaces and versions. For every
-     *            interface to publish you have to define its version. If you
-     *            don't have a version, put "0.0.0" in it.
-     * @param javaInterfacesAndEndpointInterfaces
-     *            associates java interfaces to general end point interface
-     *            names. It is not needed to to have and end point interface for
-     *            a java interface. The map can be null.
-     * @param properties
-     *            a bag of properties to be published; can be null
-     * @param autopublish
-     *            if true, service information is actively pushed to the network
-     *            for discovery
-     * 
-     * @return an instance of {@link ServiceEndpointDescription} or null if the
-     *         publishing failed
-     * 
-     * @throws IllegalArgumentException
-     *             if javaInterfacesAndVersions is null or empty
-     */
-    ServiceEndpointDescription publishService(
-            Map/* <String, String> */javaInterfacesAndVersions,
-            Map/* <String, String> */javaInterfacesAndEndpointInterfaces,
-            Map/* <String, Object> */properties, boolean autopublish);
-
-    /**
-     * Make the given service un-discoverable. The previous publish request for
-     * a service is undone. The service information is also removed from the
-     * local or global cache if cached before.
-     * 
-     * @param serviceEndpointDescription
-     *            ServiceEndpointDescription of the service to unpublish. If
-     *            this ServiceEndpointDescription haven't been published before,
-     *            then the method returns without throwing exceptions.
-     * @throws IllegalArgumentException
-     *             if serviceEndpointDescription is null or incomplete
-     */
-    void unpublishService(ServiceEndpointDescription serviceEndpointDescription);
+
+	/**
+	 * Service Registration property for the name of the Discovery product.
+	 */
+	static final String PROP_KEY_PRODUCT_NAME = "osgi.remote.discovery.product";
+
+	/**
+	 * Service Registration property for the version of the Discovery product.
+	 */
+	static final String PROP_KEY_PRODUCT_VERSION = "osgi.remote.discovery.product.version";
+
+	/**
+	 * Service Registration property for the Discovery product vendor name.
+	 */
+	static final String PROP_KEY_VENDOR_NAME = "osgi.remote.discovery.vendor";
+
+	/**
+	 * Service Registration property that lists the discovery protocols used by
+	 * this Discovery service. Value of this property is of type Collection (<?
+	 * extends String>).
+	 */
+	static final String PROP_KEY_SUPPORTED_PROTOCOLS = "osgi.remote.discovery.supported_protocols";
 }

Modified: cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/ServiceEndpointDescription.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/ServiceEndpointDescription.java?rev=738547&r1=738546&r2=738547&view=diff
==============================================================================
--- cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/ServiceEndpointDescription.java (original)
+++ cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/ServiceEndpointDescription.java Wed Jan 28 17:16:16 2009
@@ -21,96 +21,95 @@
 import java.util.Map;
 
 /**
- * The ServiceEndpointDescription interface describes an endpoint of a service.
- * This class can be considered as a wrapper around the property map associated
- * with a service and its endpoint. It provides an API to conveniently access
- * the most important properties of the service.
+ * This interface describes an endpoint of a service. This class can be
+ * considered as a wrapper around the property map of a published service and
+ * its endpoint. It provides an API to conveniently access the most important
+ * properties of the service.
  * 
  * @version $Revision$
  */
 public interface ServiceEndpointDescription {
-    /**
-     * If value of <code>getProtocolSpecificInterfaceName</code> needs to be
-     * described as a key-value pair e.g. by the discovery protocol, filter for
-     * discovery etc. and there is no other key standardized for that purpose
-     * yet, then this is the recommended property key to use.
-     */
-    public final String PROP_KEY_PROTOCOL_SPECIFIC_INTERFACE_NAME = "protocol-specific-interface-name";
-
-    /**
-     * If value of <code>getVersion</code> needs to be described as a key-value
-     * pair e.g. by the discovery protocol, filter for discovery etc. and there
-     * is no other key standardized for that purpose yet, then this is the
-     * recommended property key to use.
-     */
-    public final String PROP_KEY_VERSION = "version";
-
-    /**
-     * If value of <code>getServiceLocation</code> needs to be described as a
-     * key-value pair e.g. by the discovery protocol, filter for discovery etc.
-     * and there is no other key standardized for that purpose yet, then this is
-     * the recommended property key to use.
-     */
-    public final String PROP_KEY_SERVICE_LOCATION = "location";
-
-    /**
-     * @return full qualified service interface names provided by the advertised
-     *         service (endpoint). The collection is never null or
-     *         empty but contains at least one service interface. 
-     */
-    Collection /* <? extends String> */getInterfaceNames();
-
-    /**
-     * @param interfaceName
-     *            for which its communication protocol specific version should
-     *            be returned. It might be for instance a web service interface
-     *            name. Though this information is usually contained in
-     *            according interface descriptions, e.g. a wsdl file, it can
-     *            optionally be provided here as well since discovery usually
-     *            doesn't read and interprets such accompanying descriptions.
-     * 
-     * @return The protocol specific service interface name.
-     */
-    String getProtocolSpecificInterfaceName(String interfaceName);
-
-    /**
-     * @param interfaceName
-     *            for which its version should be returned.
-     * @return The service interface/implementation version.
-     */
-    String getVersion(String interfaceName);
-
-    /**
-     * @return The URL of the service location.
-     */
-    URL getLocation();
-
-    /**
-     * Getter method for the property value of a given key.
-     * 
-     * @param key
-     *            Name of the property
-     * @return The property value, null if none is found for the given key
-     */
-    Object getProperty(String key);
-
-    /**
-     * @return <code>java.util.Collection</code> of property names available in
-     *         the ServiceEndpointDescription. The collection is never null or
-     *         empty but contains at least basic properties like objectClass for
-     *         the service interface. The collection represents a snapshot and
-     *         as such is not going to be updated in case properties were added
-     *         or removed at a later point of time.
-     */
-    Collection/* <? extends String> */getPropertyKeys();
-
-    /**
-     * @return Returns all properties of the service as a
-     *         <code>java.util.Map</code>. The map is never null or empty but
-     *         contains at least basic properties like objectClass for the
-     *         service interface. The collection represents a snapshot and as
-     *         such is not going to be updated in case properties were added or
-     *         removed at a later point of time.
-     */
-    Map/* <String, Object> */getProperties();
+
+	/**
+	 * Returns the value of the property with key
+	 * {@link ServicePublication#PROP_KEY_SERVICE_INTERFACE_NAME}.
+	 * 
+	 * @return service interface names provided by the advertised service
+	 *         (endpoint). The collection is never null or empty but contains at
+	 *         least one service interface.
+	 */
+	Collection /* <? extends String> */getProvidedInterfaces();
+
+	/**
+	 * Returns non-Java endpoint interface name associated with the given
+	 * interface. Value of the property with key
+	 * {@link ServicePublication#PROP_KEY_ENDPOINT_INTERFACE_NAME} is used by
+	 * this operation.
+	 * 
+	 * @param interfaceName
+	 *            for which its non-Java endpoint interface name should be
+	 *            returned. 
+	 *            
+	 * @return non-Java endpoint interface name. Null, if it hasn't been
+	 *         provided.
+	 */
+	String getEndpointInterfaceName(String interfaceName);
+
+	/**
+	 * Returns version of the given interface. Value of the property with key
+	 * {@link ServicePublication#PROP_KEY_SERVICE_INTERFACE_VERSION} is used by
+	 * this operation.
+	 * 
+	 * @param interfaceName
+	 *            for which its version should be returned.
+	 * @return Version of given service interface. Null, if it hasn't been
+	 *         provided.
+	 */
+	String getVersion(String interfaceName);
+
+	/**
+	 * Returns the value of the property with key
+	 * {@link ServicePublication#PROP_KEY_ENDPOINT_LOCATION}.
+	 * 
+	 * @return The URL of the service location. Null, if it hasn't been
+	 *         provided.
+	 */
+	URL getLocation();
+
+	/**
+	 * Returns the value of the property with key
+	 * {@link ServicePublication#PROP_KEY_ENDPOINT_ID}.
+	 * 
+	 * @return Unique id of service endpoint. Null, if it hasn't been provided.
+	 */
+	String getEndpointID();
+
+	/**
+	 * Getter method for the property value of a given key.
+	 * 
+	 * @param key
+	 *            Name of the property
+	 * @return The property value, null if none is found for the given key
+	 */
+	Object getProperty(String key);
+
+	/**
+	 * @return <code>java.util.Collection</code> of property names available in
+	 *         the ServiceEndpointDescription. The collection is never null or
+	 *         empty but contains at least basic properties like objectClass for
+	 *         the service interface. The collection represents a snapshot and
+	 *         as such is not going to be updated in case properties were added
+	 *         or removed at a later point of time.
+	 */
+	Collection/* <? extends String> */getPropertyKeys();
+
+	/**
+	 * @return Returns all properties of the service as a
+	 *         <code>java.util.Map</code>. The map is never null or empty but
+	 *         contains at least basic properties like objectClass for the
+	 *         service interface. The collection represents a snapshot and as
+	 *         such is not going to be updated in case properties were added or
+	 *         removed at a later point of time.
+	 */
+	Map/* <String, Object> */getProperties();
 }

Added: cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/ServicePublication.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/ServicePublication.java?rev=738547&view=auto
==============================================================================
--- cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/ServicePublication.java (added)
+++ cxf/sandbox/dosgi/discovery/local/src/main/java/org/osgi/service/discovery/ServicePublication.java Wed Jan 28 17:16:16 2009
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) OSGi Alliance (2008). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.service.discovery;
+
+/**
+ * Register a service implementing the <code>ServicePublication</code> interface
+ * in order to publish metadata of a particular service (endpoint) via
+ * Discovery. Metadata which has to be published is given in form of properties
+ * at registration. <br>
+ * In order to update published service metadata, update the properties
+ * registered with the <code>ServicePublication</code> service. Depending on
+ * Discovery's implementation and underlying protocol it may result in an update
+ * or new re-publication of the service. <br>
+ * In order to unpublish the previously published service metadata, unregister
+ * the <code>ServicePublication</code> service.<br>
+ * 
+ * Please note that providing the {@link #PROP_KEY_SERVICE_INTERFACE_NAME}
+ * property is mandatory when a <code>ServicePublication</code> service is
+ * registered.<br>
+ * 
+ * Also important is that it's not guaranteed that after registering a
+ * <code>ServicePublication</code> object its service metadata is actually
+ * published. Beside the fact that at least one Discovery service has to be
+ * present, the provided properties have to be valid, e.g. shouldn't contain
+ * case variants of the same key name, a supported publication strategy used and
+ * the actual publication via Discovery mechanisms has to succeed.
+ * 
+ * @version $Revision$
+ */
+public interface ServicePublication {
+
+	/**
+	 * Mandatory ServiceRegistration property which contains a collection of
+	 * full qualified interface names offered by the advertised service
+	 * endpoint. Value of this property is of type Collection (<? extends
+	 * String>).
+	 */
+	public static final String PROP_KEY_SERVICE_INTERFACE_NAME = "service.interface";
+
+	/**
+	 * Optional ServiceRegistration property which contains a collection of
+	 * interface names with their associated version attributes separated by
+	 * {@link #SEPARATOR} e.g. 'my.company.foo:1.3.5 my.company.zoo:2.3.5'. In
+	 * case no version has been provided for an interface, Discovery may use the
+	 * String-value of <code>org.osgi.framework.Version.emptyVersion</code>
+	 * constant. <br>
+	 * Value of this property is of type Collection (<? extends String>).
+	 */
+	public static final String PROP_KEY_SERVICE_INTERFACE_VERSION = "service.interface.version";
+
+	/**
+	 * Optional ServiceRegistration property which contains a collection of
+	 * interface names with their associated (non-Java) endpoint interface names
+	 * separated by {@link #SEPARATOR} e.g.:<br>
+	 * 'my.company.foo:MyWebService my.company.zoo:MyWebService'.<br>
+	 * This (non-Java) endpoint interface name is usually a communication
+	 * protocol specific interface, for instance a web service interface name.
+	 * Though this information is usually contained in accompanying properties
+	 * e.g. a wsdl file, Discovery usually doesn't read and interprets such
+	 * service meta-data. Providing this information explicitly, might allow
+	 * external non-Java applications find services based on this endpoint
+	 * interface.
+	 * 
+	 * Value of this property is of type Collection (<? extends String>).
+	 */
+	public static final String PROP_KEY_ENDPOINT_INTERFACE_NAME = "osgi.remote.endpoint.interface";
+
+	/**
+	 * Optional ServiceRegistration property which contains a map of properties
+	 * of the published service. <br>
+	 * Property keys are handled in a case insensitive manner (as OSGi Framework
+	 * does). Note that Discovery might make use of certain standard properties
+	 * e.g. defined by {@link ServiceEndpointDescription} for the publication
+	 * process if they are provided.<br>
+	 * Value of this property is of type <code>java.util.Map<code>.
+	 */
+	public static final String PROP_KEY_SERVICE_PROPERTIES = "service.properties";
+
+	/**
+	 * Optional property of the published service identifying its location.
+	 * Value of this property is of type <code>java.net.URL<code>.
+	 */
+	public static final String PROP_KEY_ENDPOINT_LOCATION = "osgi.remote.endpoint.location";
+
+	/**
+	 * Optional property of the published service uniquely identifying its
+	 * endpoint. Value of this property is of type <code>String<code>.
+	 */
+	public static final String PROP_KEY_ENDPOINT_ID = "osgi.remote.endpoint.id";
+
+	/**
+	 * Separator for key value pairs.
+	 */
+	public static final String SEPARATOR = ":";
+}

Modified: cxf/sandbox/dosgi/dsw/cxf-dsw/pom.xml
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/dsw/cxf-dsw/pom.xml?rev=738547&r1=738546&r2=738547&view=diff
==============================================================================
--- cxf/sandbox/dosgi/dsw/cxf-dsw/pom.xml (original)
+++ cxf/sandbox/dosgi/dsw/cxf-dsw/pom.xml Wed Jan 28 17:16:16 2009
@@ -38,7 +38,7 @@
         <bundle.export.package>
           org.apache.cxf.dosgi.*;version="${pom.version}",
           org.osgi.service.distribution;version="4.2.0";-split-package:=merge-first,
-          org.osgi.service.discovery;version="4.2.0";-split-package:=merge-first 
+          org.osgi.service.discovery;version="1.0";-split-package:=merge-first 
         </bundle.export.package>
     </properties>
     

Modified: cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/OsgiUtils.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/OsgiUtils.java?rev=738547&r1=738546&r2=738547&view=diff
==============================================================================
--- cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/OsgiUtils.java (original)
+++ cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/OsgiUtils.java Wed Jan 28 17:16:16 2009
@@ -113,7 +113,7 @@
         List<ServiceEndpointDescription> srefs = new ArrayList<ServiceEndpointDescription>();
         Namespace ns = Namespace.getNamespace(REMOTE_SERVICES_NS);
         for (Element ref : references) {
-            List<String> iNames = getInterfaceNames(ref.getChildren(PROVIDE_INTERFACE_ELEMENT, ns));
+            List<String> iNames = getProvidedInterfaces(ref.getChildren(PROVIDE_INTERFACE_ELEMENT, ns));
             if (!serviceNamesMatch(names, iNames, matchAllNames)) {
                 continue;
             }
@@ -134,7 +134,7 @@
         List<ServiceEndpointDescription> srefs = new ArrayList<ServiceEndpointDescription>();
         Namespace ns = Namespace.getNamespace(REMOTE_SERVICES_NS);
         for (Element ref : references) {
-            List<String> iNames = getInterfaceNames(ref.getChildren(PROVIDE_INTERFACE_ELEMENT, ns));
+            List<String> iNames = getProvidedInterfaces(ref.getChildren(PROVIDE_INTERFACE_ELEMENT, ns));
             Map<String, Object> remoteProps = getProperties(ref.getChildren(PROPERTY_ELEMENT, ns));
             srefs.add(new ServiceEndpointDescriptionImpl(iNames, remoteProps));
         }
@@ -144,12 +144,12 @@
 
     public static ServiceEndpointDescription[] flattenServiceDescription(ServiceEndpointDescription sd) {
         ServiceEndpointDescription[] list = null;
-	int interfaceNameCount = sd.getInterfaceNames().size();
-        if (sd.getInterfaceNames() == null || interfaceNameCount <= 1) {
+	int interfaceNameCount = sd.getProvidedInterfaces().size();
+        if (sd.getProvidedInterfaces() == null || interfaceNameCount <= 1) {
             list = new ServiceEndpointDescription[] {sd};
         } else {
             String[] iNames = (String[])
-                sd.getInterfaceNames().toArray(new String[interfaceNameCount]);
+                sd.getProvidedInterfaces().toArray(new String[interfaceNameCount]);
             list = new ServiceEndpointDescription[iNames.length];
             for (int i = 0; i < iNames.length; i++) {
                 Map<String, Object> props =  
@@ -177,10 +177,10 @@
     }
 
     private static Map<String, Object> excludeProperty(Map properties, 
-                                                       String exlcude) {
+                                                       String exclude) {
         Map<String, Object> pruned = new HashMap<String, Object>();
         for (Object key : properties.keySet()) {
-            if (key.equals(exlcude)) {
+            if (key.equals(exclude)) {
             } else {
                 pruned.put((String)key, properties.get(key));
             }
@@ -266,7 +266,7 @@
                 props.put(key, sd.getProperty(key.toString()));
             }
         }
-        String[] interfaceNames = getInterfaceNames(sd, interfaceName);
+        String[] interfaceNames = getProvidedInterfaces(sd, interfaceName);
         if (interfaceNames != null) {
             props.put(org.osgi.framework.Constants.OBJECTCLASS, 
                       interfaceNames);
@@ -274,11 +274,11 @@
         return filter.match(props);
     }
     
-    public static String[] getInterfaceNames(ServiceEndpointDescription sd, String interfaceName) {
+    public static String[] getProvidedInterfaces(ServiceEndpointDescription sd, String interfaceName) {
         
-	int interfaceNameCount = sd.getInterfaceNames().size();
+	int interfaceNameCount = sd.getProvidedInterfaces().size();
         String[] interfaceNames = (String[])
-            sd.getInterfaceNames().toArray(new String[interfaceNameCount]);
+            sd.getProvidedInterfaces().toArray(new String[interfaceNameCount]);
         if (interfaceName == null) {
             return interfaceNames;
         }
@@ -342,7 +342,7 @@
         return props;
     }
     
-    private static List<String> getInterfaceNames(List<Element> elements) {
+    private static List<String> getProvidedInterfaces(List<Element> elements) {
         
         List<String> names = new ArrayList<String>();
         

Modified: cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/AbstractPojoConfigurationTypeHandler.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/AbstractPojoConfigurationTypeHandler.java?rev=738547&r1=738546&r2=738547&view=diff
==============================================================================
--- cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/AbstractPojoConfigurationTypeHandler.java (original)
+++ cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/AbstractPojoConfigurationTypeHandler.java Wed Jan 28 17:16:16 2009
@@ -43,6 +43,8 @@
 import org.osgi.framework.BundleContext;
 import org.osgi.service.discovery.ServiceEndpointDescription;
 
+import static org.osgi.service.discovery.ServicePublication.PROP_KEY_ENDPOINT_LOCATION;
+
 public abstract class AbstractPojoConfigurationTypeHandler extends AbstractConfigurationHandler {
     private static final Logger LOG = Logger.getLogger(AbstractPojoConfigurationTypeHandler.class.getName());
     private static final String PROVIDED_INTENT_VALUE = "PROVIDED";
@@ -204,4 +206,10 @@
         }
         return intentMap;
     }    
+
+    protected void addAddressProperty(Map props, String address) {
+        if (props != null) {
+            props.put(PROP_KEY_ENDPOINT_LOCATION, address);
+        }
+    }
 }

Modified: cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/ClientServiceFactory.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/ClientServiceFactory.java?rev=738547&r1=738546&r2=738547&view=diff
==============================================================================
--- cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/ClientServiceFactory.java (original)
+++ cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/ClientServiceFactory.java Wed Jan 28 17:16:16 2009
@@ -46,8 +46,8 @@
     }
     
     public Object getService(Bundle requestingBundle, ServiceRegistration sreg) {        
-        String interfaceName = sd.getInterfaceNames() != null && sd.getInterfaceNames().size() > 0
-	                       ? (String)sd.getInterfaceNames().toArray()[0]
+        String interfaceName = sd.getProvidedInterfaces() != null && sd.getProvidedInterfaces().size() > 0
+	                       ? (String)sd.getProvidedInterfaces().toArray()[0]
 			       : null;
         try {
             return handler.createProxy(sreg.getReference(), 

Modified: cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/HttpServiceConfigurationTypeHandler.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/HttpServiceConfigurationTypeHandler.java?rev=738547&r1=738546&r2=738547&view=diff
==============================================================================
--- cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/HttpServiceConfigurationTypeHandler.java (original)
+++ cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/HttpServiceConfigurationTypeHandler.java Wed Jan 28 17:16:16 2009
@@ -96,10 +96,11 @@
         }        
         Bus bus = cxf.getBus();
         
+        String address = constructAddress(contextRoot);
         ServerFactoryBean factory = createServerFactoryBean();
         factory.setBus(bus);
         factory.setServiceClass(iClass);
-        factory.setAddress("/");
+        factory.setAddress(address);
         factory.getServiceFactory().setDataBinding(new AegisDatabinding());
         factory.setServiceBean(serviceBean);
 
@@ -108,7 +109,8 @@
                 applyIntents(dswContext, callingContext, factory.getFeatures(), factory, sd);
 
             Server server = factory.create();
-            getDistributionProvider().addExposedService(serviceReference, registerPublication(server, intents, contextRoot));
+            getDistributionProvider().addExposedService(serviceReference, registerPublication(server, intents, address));
+            addAddressProperty(sd.getProperties(), address);
             return server;
         } catch (IntentUnsatifiedException iue) {
             getDistributionProvider().intentsUnsatisfied(serviceReference);
@@ -116,9 +118,16 @@
         }       
     }
     
-    private Map<String, String> registerPublication(Server server, String[] intents, String contextRoot) {
+    private Map<String, String> registerPublication(Server server, String[] intents, String address) {
         Map<String, String> publicationProperties = super.registerPublication(server, intents);
+
         
+        publicationProperties.put(Constants.POJO_ADDRESS_PROPERTY, address);
+
+        return publicationProperties;
+    }    
+
+    private String constructAddress(String contextRoot) {
         String port = null;
         boolean https = false;
         if ("true".equalsIgnoreCase(System.getProperty("org.osgi.service.http.secure.enabled"))) {
@@ -137,12 +146,9 @@
         } catch (UnknownHostException e) {
             hostName = "localhost";
         }
-        
-        publicationProperties.put(Constants.POJO_ADDRESS_PROPERTY,
-            getAddress(https ? "https" : "http", hostName, port, contextRoot));
 
-        return publicationProperties;
-    }    
+        return getAddress(https ? "https" : "http", hostName, port, contextRoot);
+    }
 
     private HttpService getHttpService() {
         for (ServiceReference sr : httpServiceReferences) {

Modified: cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/PojoConfigurationTypeHandler.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/PojoConfigurationTypeHandler.java?rev=738547&r1=738546&r2=738547&view=diff
==============================================================================
--- cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/PojoConfigurationTypeHandler.java (original)
+++ cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/PojoConfigurationTypeHandler.java Wed Jan 28 17:16:16 2009
@@ -55,7 +55,7 @@
             return null;
         }
 
-        LOG.info("Creating a " + sd.getInterfaceNames().toArray()[0]
+        LOG.info("Creating a " + sd.getProvidedInterfaces().toArray()[0]
                 + " client, endpoint address is " + address);
 
         try {
@@ -91,7 +91,7 @@
             return null;
         }
         
-        LOG.info("Creating a " + sd.getInterfaceNames().toArray()[0]
+        LOG.info("Creating a " + sd.getProvidedInterfaces().toArray()[0]
             + " endpoint from CXF PublishHook, address is " + address);
         
         ServerFactoryBean factory = createServerFactoryBean();
@@ -106,6 +106,7 @@
         
             Server server = factory.create();
             getDistributionProvider().addExposedService(serviceReference, registerPublication(server, intents));
+            addAddressProperty(sd.getProperties(), address);
             return server;
         } catch (IntentUnsatifiedException iue) {
             getDistributionProvider().intentsUnsatisfied(serviceReference);

Modified: cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/WsdlConfigurationTypeHandler.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/WsdlConfigurationTypeHandler.java?rev=738547&r1=738546&r2=738547&view=diff
==============================================================================
--- cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/WsdlConfigurationTypeHandler.java (original)
+++ cxf/sandbox/dosgi/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/WsdlConfigurationTypeHandler.java Wed Jan 28 17:16:16 2009
@@ -65,7 +65,7 @@
             return null;
         }
         
-        LOG.info("Creating a " + sd.getInterfaceNames().toArray()[0] + " client, wsdl address is "
+        LOG.info("Creating a " + sd.getProvidedInterfaces().toArray()[0] + " client, wsdl address is "
                  + OsgiUtils.getProperty(sd, Constants.WSDL_CONFIG_PREFIX));
         
         String serviceNs = OsgiUtils.getProperty(sd, Constants.SERVICE_NAMESPACE);



Mime
View raw message