Author: davidb
Date: Thu Jul  2 10:01:39 2009
New Revision: 790533

URL: http://svn.apache.org/viewvc?rev=790533&view=rev
Log:
New mechanism that allows externally adding properties to existing services for 
remoting.
The additional properties should be in an XML file a bundle in the 
OSGI-INF/remote-service directory. They can be in any bundle, so they can be 
separate to the service(s) they apply to.

Here's an example OSGI-INF/remote-service/sd.xml
<service-decorations 
xmlns="http://cxf.apache.org/xmlns/service-decoration/1.0.0";>
  <service-decoration>
    <match interface="org.apache.F(.*)">
      <match-property name="test.prop" value="xyz"/>
      <add-property name="service.exported.interfaces" value="*"/>
    </match>
  </service-decoration>
</service-decorations>

The above file adds the service.exported.interfaces="*" property to any service 
that is registered under an interface that matches the org.apache.F(.*) regex, 
so org.apache.Foo and org.apache.Faa match, but org.apache.Boo doesn't.
The property is only added to services that also have the test.prop=xyz set.

Note that the property isn't added to the original local service registration, 
but it is added to the remote service. Effectively the above example will 
remote any of the services that satisfy the critera.

Added:
    
cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/decorator/
    
cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/decorator/InterfaceRule.java
   (with props)
    
cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/decorator/Rule.java
   (with props)
    
cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/decorator/ServiceDecorator.java
   (with props)
    
cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/decorator/ServiceDecoratorImpl.java
   (with props)
    
cxf/dosgi/trunk/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/decorator/
    
cxf/dosgi/trunk/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/decorator/InterfaceRuleTest.java
   (with props)
    
cxf/dosgi/trunk/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/decorator/ServiceDecoratorImplTest.java
   (with props)
    cxf/dosgi/trunk/dsw/cxf-dsw/src/test/resources/test-resources/sd.xml   
(with props)
Modified:
    
cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/Activator.java
    
cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/OsgiUtils.java
    
cxf/dosgi/trunk/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/ActivatorTest.java
    
cxf/dosgi/trunk/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/OsgiUtilsTest.java

Modified: 
cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/Activator.java
URL: 
http://svn.apache.org/viewvc/cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/Activator.java?rev=790533&r1=790532&r2=790533&view=diff
==============================================================================
--- 
cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/Activator.java
 (original)
+++ 
cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/Activator.java
 Thu Jul  2 10:01:39 2009
@@ -25,6 +25,8 @@
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
 
+import org.apache.cxf.dosgi.dsw.decorator.ServiceDecorator;
+import org.apache.cxf.dosgi.dsw.decorator.ServiceDecoratorImpl;
 import org.apache.cxf.dosgi.dsw.hooks.CxfFindListenerHook;
 import org.apache.cxf.dosgi.dsw.hooks.CxfPublishHook;
 import org.apache.cxf.dosgi.dsw.qos.IntentMap;
@@ -37,6 +39,7 @@
 import org.osgi.framework.ServiceEvent;
 import org.osgi.framework.ServiceListener;
 import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
 import org.osgi.framework.hooks.service.FindHook;
 import org.osgi.framework.hooks.service.ListenerHook;
 import org.osgi.service.cm.ConfigurationException;
@@ -54,6 +57,7 @@
     CxfDistributionProvider dpService;
     CxfFindListenerHook lHook;
     CxfPublishHook pHook;
+    ServiceRegistration decoratorReg;
     
     public void start(BundleContext context) throws Exception {
         // Disable the fast infoset as it's not compatible (yet) with OSGi
@@ -63,8 +67,11 @@
         // should we have a seperate PID for a find and publish hook ? 
         context.registerService(ManagedService.class.getName(), 
                                 this, getDefaults());
+    
+        decoratorReg = 
context.registerService(ServiceDecorator.class.getName(), 
+            new ServiceDecoratorImpl(context), null);
         
-        dpService = registerDistributionProviderService();
+        dpService = registerDistributionProviderService();        
 
         pHook = new CxfPublishHook(context, dpService);        
         lHook = new CxfFindListenerHook(context, dpService);
@@ -107,6 +114,9 @@
         dpService.shutdown();
         execService.shutdown();
         pHook.removeEndpoints();
+
+        decoratorReg.unregister();        
+        // unregister other registered services (ManagedService + Hooks)
     }
 
     private Dictionary<String, String> getDefaults() {

Modified: 
cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/OsgiUtils.java
URL: 
http://svn.apache.org/viewvc/cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/OsgiUtils.java?rev=790533&r1=790532&r2=790533&view=diff
==============================================================================
--- 
cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/OsgiUtils.java
 (original)
+++ 
cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/OsgiUtils.java
 Thu Jul  2 10:01:39 2009
@@ -32,6 +32,7 @@
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import org.apache.cxf.dosgi.dsw.decorator.ServiceDecorator;
 import org.apache.cxf.dosgi.dsw.qos.IntentMap;
 import org.apache.cxf.dosgi.dsw.service.ServiceEndpointDescriptionImpl;
 import org.jdom.Document;
@@ -93,6 +94,7 @@
                                                              names, 
                                                              userProperties,
                                                              matchAllNames);
+        setAdditionalProperties(sref, userProperties);
         
         if (srefs.isEmpty()) {
             return new ServiceEndpointDescriptionImpl(Arrays.asList(names), 
userProperties);
@@ -123,21 +125,6 @@
         
     }
     
-    @SuppressWarnings("unchecked")
-    public static List<ServiceEndpointDescription> 
getAllRemoteReferences(Bundle b) {
-        List<Element> references = getAllDescriptionElements(b);
-        
-        List<ServiceEndpointDescription> srefs = new 
ArrayList<ServiceEndpointDescription>();
-        Namespace ns = Namespace.getNamespace(REMOTE_SERVICES_NS);
-        for (Element ref : references) {
-            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));
-        }
-        return srefs;
-        
-    }
-
     public static ServiceEndpointDescription[] 
flattenServiceDescription(ServiceEndpointDescription sd) {
         ServiceEndpointDescription[] list = null;
         int interfaceNameCount = sd.getProvidedInterfaces().size();
@@ -219,6 +206,27 @@
         return elements; 
     }
     
+    private static void setAdditionalProperties(ServiceReference sref, 
Map<String, Object> props) {        
+        BundleContext bc = sref.getBundle().getBundleContext();
+        ServiceReference [] refs;
+            try {
+                refs = 
bc.getServiceReferences(ServiceDecorator.class.getName(), null);
+            } catch (InvalidSyntaxException e) {
+                // should never happen, filter is null
+                return;
+            }
+        if (refs == null) {
+            return;
+        }
+        
+        for (ServiceReference ref : refs) {
+            Object svc = bc.getService(ref);
+            if (svc instanceof ServiceDecorator) {
+                ((ServiceDecorator) svc).decorate(sref, props);
+            }            
+        }
+    }
+    
     private static boolean serviceNamesMatch(
         String[] names, List<String> iNames, boolean matchAllNames) {
         if (names == null || names.length == 0) {

Added: 
cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/decorator/InterfaceRule.java
URL: 
http://svn.apache.org/viewvc/cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/decorator/InterfaceRule.java?rev=790533&view=auto
==============================================================================
--- 
cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/decorator/InterfaceRule.java
 (added)
+++ 
cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/decorator/InterfaceRule.java
 Thu Jul  2 10:01:39 2009
@@ -0,0 +1,99 @@
+/** 
+  * Licensed to the Apache Software Foundation (ASF) under one 
+  * or more contributor license agreements. See the NOTICE file 
+  * distributed with this work for additional information 
+  * regarding copyright ownership. The ASF licenses this file 
+  * to you under the Apache License, Version 2.0 (the 
+  * "License"); you may not use this file except in compliance 
+  * with the License. You may obtain a copy of the License at 
+  * 
+  * http://www.apache.org/licenses/LICENSE-2.0 
+  * 
+  * Unless required by applicable law or agreed to in writing, 
+  * software distributed under the License is distributed on an 
+  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
+  * KIND, either express or implied. See the License for the 
+  * specific language governing permissions and limitations 
+  * under the License. 
+  */
+package org.apache.cxf.dosgi.dsw.decorator;
+
+import java.lang.reflect.Constructor;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+
+public class InterfaceRule implements Rule {
+    private static final Logger LOG = 
Logger.getLogger(InterfaceRule.class.getName());
+    
+    private final Bundle bundle;
+    private final Pattern matchPattern;
+    private final Map<String, String> propMatches = new HashMap<String, 
String>();
+    private final Map<String, Object> addProps = new HashMap<String, Object>();
+    
+    public InterfaceRule(Bundle b, String im) {
+        bundle = b;
+        matchPattern = Pattern.compile(im);
+    }
+
+    public synchronized void addPropMatch(String name, String value) {
+        propMatches.put(name, value);
+    }
+
+    public synchronized void addProperty(String name, String value, String 
type) {
+        Object obj = value;
+        
+        if (!String.class.getName().equals(type)) {
+            try {
+                Class<?> cls = getClass().getClassLoader().loadClass(type);
+                Constructor<?> ctor = cls.getConstructor(new Class [] 
{String.class});
+                obj = ctor.newInstance(value);
+            } catch (Throwable th) {
+                LOG.log(Level.WARNING, "Could not handle property '" + name +
+                    "' with value '" + value + "' of type: " + type, th);
+                return;
+            }
+        }
+        
+        addProps.put(name, obj);
+    }
+
+    public synchronized void apply(ServiceReference sref, Map<String, Object> 
target) {
+        String [] objectClass = (String[]) 
sref.getProperty(Constants.OBJECTCLASS);
+        boolean matches = false;
+        for (String cls : objectClass) {            
+            Matcher m = matchPattern.matcher(cls);
+            if (m.matches()) {
+                for (Map.Entry<String, String> pm : propMatches.entrySet()) {
+                    Object value = sref.getProperty(pm.getKey());
+                    if (value == null) {
+                        return;
+                    }
+                    if (!Pattern.matches(pm.getValue(), value.toString())) {
+                        return;
+                    }
+                }
+                matches = true;
+                break;
+            }
+        }
+        if (!matches) {
+            return;
+        }
+        
+        LOG.info("Adding the following properties to " + sref + ": " + 
addProps);
+        System.out.println("*** Adding the following properties to " + sref + 
": " + addProps);
+        target.putAll(addProps);
+    }
+
+    public Bundle getBundle() {
+        return bundle;
+    }    
+}

Propchange: 
cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/decorator/InterfaceRule.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/decorator/InterfaceRule.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: 
cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/decorator/Rule.java
URL: 
http://svn.apache.org/viewvc/cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/decorator/Rule.java?rev=790533&view=auto
==============================================================================
--- 
cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/decorator/Rule.java
 (added)
+++ 
cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/decorator/Rule.java
 Thu Jul  2 10:01:39 2009
@@ -0,0 +1,38 @@
+/** 
+  * Licensed to the Apache Software Foundation (ASF) under one 
+  * or more contributor license agreements. See the NOTICE file 
+  * distributed with this work for additional information 
+  * regarding copyright ownership. The ASF licenses this file 
+  * to you under the Apache License, Version 2.0 (the 
+  * "License"); you may not use this file except in compliance 
+  * with the License. You may obtain a copy of the License at 
+  * 
+  * http://www.apache.org/licenses/LICENSE-2.0 
+  * 
+  * Unless required by applicable law or agreed to in writing, 
+  * software distributed under the License is distributed on an 
+  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
+  * KIND, either express or implied. See the License for the 
+  * specific language governing permissions and limitations 
+  * under the License. 
+  */
+package org.apache.cxf.dosgi.dsw.decorator;
+
+import java.util.Map;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceReference;
+
+public interface Rule {
+    /** When the ServiceReference passed in matches the rule's condition,
+     * set the additional properties in the target.
+     * @param sref The Service Reference to be checked.
+     * @param target Any additional properties are to be set in this map.
+     */
+    void apply(ServiceReference sref, Map<String, Object> target);
+    
+    /** Returns the bundle that provided this rule.
+     * @return The Bundle where the Rule was defined.
+     */
+    Bundle getBundle();
+}

Propchange: 
cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/decorator/Rule.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/decorator/Rule.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: 
cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/decorator/ServiceDecorator.java
URL: 
http://svn.apache.org/viewvc/cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/decorator/ServiceDecorator.java?rev=790533&view=auto
==============================================================================
--- 
cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/decorator/ServiceDecorator.java
 (added)
+++ 
cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/decorator/ServiceDecorator.java
 Thu Jul  2 10:01:39 2009
@@ -0,0 +1,27 @@
+/** 
+  * Licensed to the Apache Software Foundation (ASF) under one 
+  * or more contributor license agreements. See the NOTICE file 
+  * distributed with this work for additional information 
+  * regarding copyright ownership. The ASF licenses this file 
+  * to you under the Apache License, Version 2.0 (the 
+  * "License"); you may not use this file except in compliance 
+  * with the License. You may obtain a copy of the License at 
+  * 
+  * http://www.apache.org/licenses/LICENSE-2.0 
+  * 
+  * Unless required by applicable law or agreed to in writing, 
+  * software distributed under the License is distributed on an 
+  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
+  * KIND, either express or implied. See the License for the 
+  * specific language governing permissions and limitations 
+  * under the License. 
+  */
+package org.apache.cxf.dosgi.dsw.decorator;
+
+import java.util.Map;
+
+import org.osgi.framework.ServiceReference;
+
+public interface ServiceDecorator {
+    void decorate(ServiceReference sref, Map<String, Object> properties);
+}

Propchange: 
cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/decorator/ServiceDecorator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/decorator/ServiceDecorator.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: 
cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/decorator/ServiceDecoratorImpl.java
URL: 
http://svn.apache.org/viewvc/cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/decorator/ServiceDecoratorImpl.java?rev=790533&view=auto
==============================================================================
--- 
cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/decorator/ServiceDecoratorImpl.java
 (added)
+++ 
cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/decorator/ServiceDecoratorImpl.java
 Thu Jul  2 10:01:39 2009
@@ -0,0 +1,123 @@
+/** 
+  * Licensed to the Apache Software Foundation (ASF) under one 
+  * or more contributor license agreements. See the NOTICE file 
+  * distributed with this work for additional information 
+  * regarding copyright ownership. The ASF licenses this file 
+  * to you under the Apache License, Version 2.0 (the 
+  * "License"); you may not use this file except in compliance 
+  * with the License. You may obtain a copy of the License at 
+  * 
+  * http://www.apache.org/licenses/LICENSE-2.0 
+  * 
+  * Unless required by applicable law or agreed to in writing, 
+  * software distributed under the License is distributed on an 
+  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
+  * KIND, either express or implied. See the License for the 
+  * specific language governing permissions and limitations 
+  * under the License. 
+  */
+package org.apache.cxf.dosgi.dsw.decorator;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jdom.Namespace;
+import org.jdom.input.SAXBuilder;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.BundleListener;
+import org.osgi.framework.ServiceReference;
+
+public class ServiceDecoratorImpl implements ServiceDecorator {
+    private static final Logger LOG = 
Logger.getLogger(ServiceDecoratorImpl.class.getName());
+    
+    private final BundleContext bundleContext;
+    private final BundleListenerImpl bundleListener;
+    private final List<Rule> decorations = new CopyOnWriteArrayList<Rule>();
+
+    public ServiceDecoratorImpl(BundleContext bc) {
+        bundleContext = bc;
+        bundleListener = new BundleListenerImpl();
+        bc.addBundleListener(bundleListener);
+    }
+    
+    public void shutdown() {
+        bundleContext.removeBundleListener(bundleListener);
+    }
+
+    public void decorate(ServiceReference sref, Map<String, Object> target) {
+        for (Rule matcher : decorations) {
+            matcher.apply(sref, target);
+        }
+    }
+    
+    @SuppressWarnings("unchecked")
+    public void addDecorations(Bundle bundle) {
+        Namespace ns = 
Namespace.getNamespace("http://cxf.apache.org/xmlns/service-decoration/1.0.0";);
+        for (Element decoration : getDecorationElements(bundle)) {
+            for (Element match : (List<Element>) 
decoration.getChildren("match", ns)) {
+                InterfaceRule m = new InterfaceRule(bundle, 
match.getAttributeValue("interface"));
+                for (Element propMatch : (List<Element>) 
match.getChildren("match-property", ns)) {
+                    m.addPropMatch(propMatch.getAttributeValue("name"), 
propMatch.getAttributeValue("value"));
+                }
+                for (Element addProp : (List<Element>) 
match.getChildren("add-property", ns)) {
+                    m.addProperty(addProp.getAttributeValue("name"), 
addProp.getAttributeValue("value"), addProp.getAttributeValue("type", 
String.class.getName()));
+                }
+                decorations.add(m);
+            }
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    static List<Element> getDecorationElements(Bundle bundle) {
+        Enumeration entries = bundle.findEntries("OSGI-INF/remote-service", 
"*.xml", false);
+        if (entries == null) {
+            return Collections.emptyList();
+        }
+        
+        List<Element> elements = new ArrayList<Element>();
+        while (entries.hasMoreElements()) {
+            URL resourceURL = (URL) entries.nextElement();
+            try {
+                Document d = new SAXBuilder().build(resourceURL.openStream());
+                Namespace ns = 
Namespace.getNamespace("http://cxf.apache.org/xmlns/service-decoration/1.0.0";);
+                
elements.addAll(d.getRootElement().getChildren("service-decoration", ns));
+            } catch (Exception ex) {
+                LOG.log(Level.WARNING, "Problem parsing: " + resourceURL, ex);
+            }
+        }
+        return elements;
+    }
+    
+    public void removeDecorations(Bundle bundle) {
+        for (Iterator<Rule> i = decorations.iterator(); i.hasNext(); ) {
+            if (bundle.equals(i.next().getBundle())) {
+                i.remove();
+            }
+        }
+    }
+
+    private class BundleListenerImpl implements BundleListener {
+        public void bundleChanged(BundleEvent be) {
+            switch(be.getType()) {
+            case BundleEvent.STARTED:
+                addDecorations(be.getBundle());
+                break;
+            case BundleEvent.STOPPING:
+                removeDecorations(be.getBundle());
+                break;
+            }
+        }        
+    }
+}

Propchange: 
cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/decorator/ServiceDecoratorImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
cxf/dosgi/trunk/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/decorator/ServiceDecoratorImpl.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: 
cxf/dosgi/trunk/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/ActivatorTest.java
URL: 
http://svn.apache.org/viewvc/cxf/dosgi/trunk/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/ActivatorTest.java?rev=790533&r1=790532&r2=790533&view=diff
==============================================================================
--- 
cxf/dosgi/trunk/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/ActivatorTest.java
 (original)
+++ 
cxf/dosgi/trunk/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/ActivatorTest.java
 Thu Jul  2 10:01:39 2009
@@ -37,6 +37,15 @@
 
         EasyMock.expect(b.getBundleContext()).andReturn(bc).anyTimes();
         EasyMock.expect(bc.getBundle()).andReturn(b).anyTimes();
+        EasyMock.expect(bc.registerService(
+            (String) EasyMock.anyObject(), EasyMock.anyObject(), 
+            (Dictionary) EasyMock.anyObject())).andAnswer(new 
IAnswer<ServiceRegistration>() {
+                public ServiceRegistration answer() throws Throwable {
+                    ServiceRegistration sr = 
EasyMock.createNiceMock(ServiceRegistration.class);
+                    EasyMock.replay(sr);
+                    return sr;
+                }                
+            }).anyTimes();
         control.replay();
         return bc;
     }

Modified: 
cxf/dosgi/trunk/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/OsgiUtilsTest.java
URL: 
http://svn.apache.org/viewvc/cxf/dosgi/trunk/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/OsgiUtilsTest.java?rev=790533&r1=790532&r2=790533&view=diff
==============================================================================
--- 
cxf/dosgi/trunk/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/OsgiUtilsTest.java
 (original)
+++ 
cxf/dosgi/trunk/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/OsgiUtilsTest.java
 Thu Jul  2 10:01:39 2009
@@ -12,12 +12,14 @@
 
 import junit.framework.TestCase;
 
+import org.apache.cxf.dosgi.dsw.decorator.ServiceDecorator;
 import org.easymock.EasyMock;
 import org.easymock.IAnswer;
 import org.jdom.Element;
 import org.jdom.Namespace;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
 import org.osgi.service.discovery.ServiceEndpointDescription;
 
@@ -131,13 +133,19 @@
         EasyMock.verify();
     }
 
-    public void testGetRemoteReferencesFromRegistrationProperties() {
+    public void testGetRemoteReferencesFromRegistrationProperties() throws 
Exception {
         final Map<String, Object> props = new HashMap<String, Object>();
         props.put(org.osgi.framework.Constants.OBJECTCLASS, new String [] 
{"myClass"});
         props.put("osgi.remote.interfaces", "*");
         props.put(Constants.WS_DATABINDING_PROP_KEY, "jaxb");
         
-        Bundle b = EasyMock.createNiceMock(Bundle.class);        
+        BundleContext bc = EasyMock.createNiceMock(BundleContext.class);
+        
EasyMock.expect(bc.getServiceReferences(ServiceDecorator.class.getName(), 
null)).
+            andReturn(null).anyTimes();
+        EasyMock.replay(bc);
+        
+        Bundle b = EasyMock.createNiceMock(Bundle.class);
+        EasyMock.expect(b.getBundleContext()).andReturn(bc).anyTimes();
         EasyMock.replay(b);
         
         ServiceReference sr = EasyMock.createMock(ServiceReference.class);
@@ -161,6 +169,49 @@
         EasyMock.verify(sr);
     }
     
+    public void testSetAdditionalDecoratorProperties() throws Exception {
+        final Map<String, Object> props = new HashMap<String, Object>();
+        props.put(org.osgi.framework.Constants.OBJECTCLASS, new String [] 
{"myClass"});
+        
+        ServiceDecorator decorator = new ServiceDecorator() {            
+            public void decorate(ServiceReference sref, Map<String, Object> 
properties) {
+                properties.put("osgi.remote.interfaces", "*");               
+            }
+        };
+        
+        ServiceReference decoratorRef = 
EasyMock.createMock(ServiceReference.class);
+        EasyMock.replay(decoratorRef);
+        
+        BundleContext bc = EasyMock.createNiceMock(BundleContext.class);
+        
EasyMock.expect(bc.getServiceReferences(ServiceDecorator.class.getName(), 
null)).
+            andReturn(new ServiceReference [] {decoratorRef}).anyTimes();
+        
EasyMock.expect(bc.getService(decoratorRef)).andReturn(decorator).anyTimes();
+        EasyMock.replay(bc);
+        
+        Bundle b = EasyMock.createNiceMock(Bundle.class);
+        EasyMock.expect(b.getBundleContext()).andReturn(bc).anyTimes();
+        EasyMock.replay(b);
+        
+        ServiceReference sr = EasyMock.createMock(ServiceReference.class);
+        // set behaviour for getPropertyKeys() and getProperty() based on the 
map above.
+        EasyMock.expect(sr.getPropertyKeys()).
+            andReturn(props.keySet().toArray(new String [] {})).anyTimes();
+        EasyMock.expect(sr.getProperty((String) EasyMock.anyObject())).
+            andAnswer(new IAnswer<Object>() {
+                public Object answer() throws Throwable {
+                    return props.get(EasyMock.getCurrentArguments()[0]);
+                }                
+            }).anyTimes();
+        EasyMock.expect(sr.getBundle()).andReturn(b).anyTimes();
+        EasyMock.replay(sr);
+        
+        // Actual test starts here
+        ServiceEndpointDescription sd = OsgiUtils.getRemoteReference(sr, true);
+        assertEquals("*", sd.getProperties().get("osgi.remote.interfaces"));
+        
+        EasyMock.verify(sr);
+    }
+
     public void testNoIntentMap() {
         Bundle b = EasyMock.createNiceMock(Bundle.class);
         EasyMock.replay(b);

Added: 
cxf/dosgi/trunk/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/decorator/InterfaceRuleTest.java
URL: 
http://svn.apache.org/viewvc/cxf/dosgi/trunk/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/decorator/InterfaceRuleTest.java?rev=790533&view=auto
==============================================================================
--- 
cxf/dosgi/trunk/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/decorator/InterfaceRuleTest.java
 (added)
+++ 
cxf/dosgi/trunk/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/decorator/InterfaceRuleTest.java
 Thu Jul  2 10:01:39 2009
@@ -0,0 +1,157 @@
+/** 
+  * Licensed to the Apache Software Foundation (ASF) under one 
+  * or more contributor license agreements. See the NOTICE file 
+  * distributed with this work for additional information 
+  * regarding copyright ownership. The ASF licenses this file 
+  * to you under the Apache License, Version 2.0 (the 
+  * "License"); you may not use this file except in compliance 
+  * with the License. You may obtain a copy of the License at 
+  * 
+  * http://www.apache.org/licenses/LICENSE-2.0 
+  * 
+  * Unless required by applicable law or agreed to in writing, 
+  * software distributed under the License is distributed on an 
+  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
+  * KIND, either express or implied. See the License for the 
+  * specific language governing permissions and limitations 
+  * under the License. 
+  */
+package org.apache.cxf.dosgi.dsw.decorator;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+import org.easymock.EasyMock;
+import org.easymock.IAnswer;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+
+public class InterfaceRuleTest extends TestCase {
+    public void testInterfaceRuleGetBundle() {
+        Bundle b = EasyMock.createMock(Bundle.class);
+        EasyMock.replay(b);
+        InterfaceRule ir = new InterfaceRule(b, "org.apache.Foo");
+        assertSame(b, ir.getBundle());
+    }
+    
+    public void testInterfaceRule1() {
+        InterfaceRule ir = new InterfaceRule(null, "org.apache.Foo");
+        ir.addProperty("x", "y", String.class.getName());        
+        
+        final Map<String, Object> serviceProps = new HashMap<String, Object>();
+        serviceProps.put(Constants.OBJECTCLASS, new String [] {"a.b.C", 
"org.apache.Foo"});
+        ServiceReference sref = mockServiceReference(serviceProps);
+
+        Map<String, Object> m = new HashMap<String, Object>();
+        m.put("a", "b");
+        ir.apply(sref, m);
+        Map<String, Object> expected = new HashMap<String, Object>();
+        expected.put("a", "b");
+        expected.put("x", "y");
+        assertEquals(expected, m);
+    }
+    
+    public void testInterfaceRule2() {
+        InterfaceRule ir = new InterfaceRule(null, "org.apache.F(.*)");
+        ir.addPropMatch("boo", "baah");
+        ir.addProperty("x", "1", Integer.class.getName());        
+        ir.addProperty("aaa.bbb", "true", Boolean.class.getName());        
+        
+        final Map<String, Object> serviceProps = new HashMap<String, Object>();
+        serviceProps.put("boo", "baah");
+        serviceProps.put(Constants.OBJECTCLASS, new String [] {"a.b.C", 
"org.apache.Foo"});
+        ServiceReference sref = mockServiceReference(serviceProps);
+
+        Map<String, Object> m = new HashMap<String, Object>();
+        ir.apply(sref, m);
+        Map<String, Object> expected = new HashMap<String, Object>();
+        expected.put("x", new Integer(1));
+        expected.put("aaa.bbb", Boolean.TRUE);
+        assertEquals(expected, m);
+    }
+
+    public void testInterfaceRule3() {
+        InterfaceRule ir = new InterfaceRule(null, "org.apache.F(.*)");
+        ir.addProperty("x", "y", String.class.getName());        
+        
+        final Map<String, Object> serviceProps = new HashMap<String, Object>();
+        serviceProps.put("boo", "baah");
+        serviceProps.put(Constants.OBJECTCLASS, new String [] 
{"org.apache.Boo"});
+        ServiceReference sref = mockServiceReference(serviceProps);
+
+        Map<String, Object> m = new HashMap<String, Object>();
+        ir.apply(sref, m);
+        assertEquals(0, m.size());
+    }
+
+    public void testInterfaceRule4() {
+        InterfaceRule ir = new InterfaceRule(null, "org.apache.F(.*)");
+        ir.addPropMatch("boo", "baah");
+        ir.addProperty("x", "y", String.class.getName());        
+        
+        final Map<String, Object> serviceProps = new HashMap<String, Object>();
+        serviceProps.put(Constants.OBJECTCLASS, new String [] 
{"org.apache.Foo"});
+        ServiceReference sref = mockServiceReference(serviceProps);
+
+        Map<String, Object> m = new HashMap<String, Object>();
+        ir.apply(sref, m);
+        assertEquals(0, m.size());
+    }
+
+    public void testInterfaceRule5() {
+        InterfaceRule ir = new InterfaceRule(null, "org.apache.Foo");
+        ir.addPropMatch("test.int", "42");
+        ir.addProperty("x", "1", Long.class.getName());        
+        
+        final Map<String, Object> serviceProps = new HashMap<String, Object>();
+        serviceProps.put("test.int", new Integer(42));
+        serviceProps.put(Constants.OBJECTCLASS, new String [] 
{"org.apache.Foo"});
+        ServiceReference sref = mockServiceReference(serviceProps);
+
+        Map<String, Object> m = new HashMap<String, Object>();
+        m.put("x", "foo");
+        m.put("aaa.bbb", Boolean.TRUE);
+        ir.apply(sref, m);
+        Map<String, Object> expected = new HashMap<String, Object>();
+        expected.put("x", new Long(1));
+        expected.put("aaa.bbb", Boolean.TRUE);
+        assertEquals(expected, m);
+    }
+    
+    public void testInterfaceRule6() {
+        InterfaceRule ir = new InterfaceRule(null, "org.apache.Foo");
+        ir.addPropMatch("test.int", "42");
+        ir.addProperty("x", "1", Long.class.getName());        
+        
+        final Map<String, Object> serviceProps = new HashMap<String, Object>();
+        serviceProps.put("test.int", new Integer(51));
+        serviceProps.put(Constants.OBJECTCLASS, new String [] 
{"org.apache.Foo"});
+        ServiceReference sref = mockServiceReference(serviceProps);
+
+        Map<String, Object> m = new HashMap<String, Object>();
+        m.put("x", "foo");
+        m.put("aaa.bbb", Boolean.TRUE);
+        ir.apply(sref, m);
+        Map<String, Object> expected = new HashMap<String, Object>();
+        expected.put("x", "foo");
+        expected.put("aaa.bbb", Boolean.TRUE);
+        assertEquals(expected, m);
+    }
+
+    private ServiceReference mockServiceReference(final Map<String, Object> 
serviceProps) {
+        ServiceReference sref = EasyMock.createMock(ServiceReference.class);
+        EasyMock.expect(sref.getProperty((String) 
EasyMock.anyObject())).andAnswer(new IAnswer<Object>() {            
+            public Object answer() throws Throwable {
+                return serviceProps.get(EasyMock.getCurrentArguments()[0]);
+            }
+        }).anyTimes();
+        EasyMock.expect(sref.getPropertyKeys()).
+            andReturn(serviceProps.keySet().toArray(new String [] 
{})).anyTimes();
+        
+        EasyMock.replay(sref);
+        return sref;
+    }
+}

Propchange: 
cxf/dosgi/trunk/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/decorator/InterfaceRuleTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
cxf/dosgi/trunk/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/decorator/InterfaceRuleTest.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: 
cxf/dosgi/trunk/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/decorator/ServiceDecoratorImplTest.java
URL: 
http://svn.apache.org/viewvc/cxf/dosgi/trunk/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/decorator/ServiceDecoratorImplTest.java?rev=790533&view=auto
==============================================================================
--- 
cxf/dosgi/trunk/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/decorator/ServiceDecoratorImplTest.java
 (added)
+++ 
cxf/dosgi/trunk/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/decorator/ServiceDecoratorImplTest.java
 Thu Jul  2 10:01:39 2009
@@ -0,0 +1,56 @@
+/** 
+  * Licensed to the Apache Software Foundation (ASF) under one 
+  * or more contributor license agreements. See the NOTICE file 
+  * distributed with this work for additional information 
+  * regarding copyright ownership. The ASF licenses this file 
+  * to you under the Apache License, Version 2.0 (the 
+  * "License"); you may not use this file except in compliance 
+  * with the License. You may obtain a copy of the License at 
+  * 
+  * http://www.apache.org/licenses/LICENSE-2.0 
+  * 
+  * Unless required by applicable law or agreed to in writing, 
+  * software distributed under the License is distributed on an 
+  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
+  * KIND, either express or implied. See the License for the 
+  * specific language governing permissions and limitations 
+  * under the License. 
+  */
+package org.apache.cxf.dosgi.dsw.decorator;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.easymock.EasyMock;
+import org.jdom.Element;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+
+public class ServiceDecoratorImplTest extends TestCase {
+    public void testServiceDecorator() {
+        BundleContext bc = EasyMock.createNiceMock(BundleContext.class);
+        EasyMock.replay(bc);
+        
+        ServiceDecoratorImpl sd = new ServiceDecoratorImpl(bc);
+        
+        Bundle b = EasyMock.createMock(Bundle.class);
+        EasyMock.expect(b.findEntries("OSGI-INF/remote-service", "*.xml", 
false)).andReturn(
+            
Collections.enumeration(Arrays.asList(getClass().getResource("/test-resources/sd.xml")))).anyTimes();
+        EasyMock.replay(b);
+    }
+    
+    public void testGetDecoratorElements() {
+        Bundle b = EasyMock.createMock(Bundle.class);
+        EasyMock.expect(b.findEntries("OSGI-INF/remote-service", "*.xml", 
false)).andReturn(
+            
Collections.enumeration(Arrays.asList(getClass().getResource("/test-resources/sd.xml")))).anyTimes();
+        EasyMock.replay(b);
+
+        List<Element> elements = ServiceDecoratorImpl.getDecorationElements(b);
+        assertEquals(1, elements.size());
+        assertEquals("service-decoration", elements.get(0).getName());
+        assertEquals("http://cxf.apache.org/xmlns/service-decoration/1.0.0";, 
elements.get(0).getNamespaceURI());
+    }
+}

Propchange: 
cxf/dosgi/trunk/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/decorator/ServiceDecoratorImplTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
cxf/dosgi/trunk/dsw/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/decorator/ServiceDecoratorImplTest.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/dosgi/trunk/dsw/cxf-dsw/src/test/resources/test-resources/sd.xml
URL: 
http://svn.apache.org/viewvc/cxf/dosgi/trunk/dsw/cxf-dsw/src/test/resources/test-resources/sd.xml?rev=790533&view=auto
==============================================================================
--- cxf/dosgi/trunk/dsw/cxf-dsw/src/test/resources/test-resources/sd.xml (added)
+++ cxf/dosgi/trunk/dsw/cxf-dsw/src/test/resources/test-resources/sd.xml Thu 
Jul  2 10:01:39 2009
@@ -0,0 +1,8 @@
+<service-decorations 
xmlns="http://cxf.apache.org/xmlns/service-decoration/1.0.0";>
+  <service-decoration>
+    <match interface="org.acme.foo.*">
+      <match-property name="test.prop" value="xyz"/>
+      <add-property name="test.too" value="ahaha" type="java.lang.String"/>
+    </match>
+  </service-decoration>
+</service-decorations>
\ No newline at end of file

Propchange: cxf/dosgi/trunk/dsw/cxf-dsw/src/test/resources/test-resources/sd.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/dosgi/trunk/dsw/cxf-dsw/src/test/resources/test-resources/sd.xml
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Propchange: cxf/dosgi/trunk/dsw/cxf-dsw/src/test/resources/test-resources/sd.xml
------------------------------------------------------------------------------
    svn:mime-type = text/xml


Reply via email to