You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by da...@apache.org on 2009/12/23 10:10:33 UTC

svn commit: r893440 - in /cxf/dosgi/trunk/discovery/local/src: main/java/org/apache/cxf/dosgi/discovery/local/LocalDiscoveryUtils.java test/java/org/apache/cxf/dosgi/discovery/local/LocalDiscoveryUtilsTest.java test/resources/ed2.xml

Author: davidb
Date: Wed Dec 23 09:10:32 2009
New Revision: 893440

URL: http://svn.apache.org/viewvc?rev=893440&view=rev
Log:
More support of the Endpoint Description XML file format.

Added:
    cxf/dosgi/trunk/discovery/local/src/test/resources/ed2.xml   (with props)
Modified:
    cxf/dosgi/trunk/discovery/local/src/main/java/org/apache/cxf/dosgi/discovery/local/LocalDiscoveryUtils.java
    cxf/dosgi/trunk/discovery/local/src/test/java/org/apache/cxf/dosgi/discovery/local/LocalDiscoveryUtilsTest.java

Modified: cxf/dosgi/trunk/discovery/local/src/main/java/org/apache/cxf/dosgi/discovery/local/LocalDiscoveryUtils.java
URL: http://svn.apache.org/viewvc/cxf/dosgi/trunk/discovery/local/src/main/java/org/apache/cxf/dosgi/discovery/local/LocalDiscoveryUtils.java?rev=893440&r1=893439&r2=893440&view=diff
==============================================================================
--- cxf/dosgi/trunk/discovery/local/src/main/java/org/apache/cxf/dosgi/discovery/local/LocalDiscoveryUtils.java (original)
+++ cxf/dosgi/trunk/discovery/local/src/main/java/org/apache/cxf/dosgi/discovery/local/LocalDiscoveryUtils.java Wed Dec 23 09:10:32 2009
@@ -38,6 +38,8 @@
 import org.jdom.Element;
 import org.jdom.Namespace;
 import org.jdom.input.SAXBuilder;
+import org.jdom.output.Format;
+import org.jdom.output.XMLOutputter;
 import org.osgi.framework.Bundle;
 import org.osgi.service.discovery.ServiceEndpointDescription;
 import org.osgi.service.discovery.ServicePublication;
@@ -66,6 +68,7 @@
     private static final String PROPERTY_ELEMENT = "property";
     private static final String PROPERTY_NAME_ATTRIBUTE = "name";
     private static final String PROPERTY_VALUE_ATTRIBUTE = "value";
+    private static final String PROPERTY_VALUE_TYPE_ATTRIBUTE = "value-type";
     private static final String PROPERTY_INTERFACE_ATTRIBUTE = "interface";
 
     private static final String INTERFACE_SEPARATOR = ":";
@@ -135,7 +138,11 @@
             if (handled) {
                 continue;
             }
-            handled = handleList(prop, map);
+            handled = handleCollection(prop, map);
+            if (handled) {
+                continue;
+            }
+            handled = handleXML(prop, map);
             if (handled) {
                 continue;
             }
@@ -184,16 +191,16 @@
         } else if ("short".equals(type)) {
             cls = short.class;
         }            
-        
+
         try {
             if (cls == null) {
-                cls = Class.forName("java.lang." + type, true, String.class.getClassLoader());
+                cls = ClassLoader.getSystemClassLoader().loadClass("java.lang." + type);
             }
             Object array = Array.newInstance(cls, values.size());
             
             for (int i=0; i < values.size(); i++) {
                 Element vEl = values.get(i);
-                Object val = instantiate(type, vEl.getText());
+                Object val = handleValue(vEl, type);
                 Array.set(array, i, val);
             }
             
@@ -207,7 +214,7 @@
     }
 
     @SuppressWarnings("unchecked")
-    private static boolean handleList(Element prop, Map<String, Object> map) {
+    private static boolean handleCollection(Element prop, Map<String, Object> map) {
         Collection<Object> col = null;        
         Element el = prop.getChild("list");
         if (el != null) {
@@ -226,7 +233,8 @@
         String type = getTypeName(prop);
         List<Element> values = el.getChildren("value");
         for (Element val : values) {
-            col.add(instantiate(type, val.getText()));
+            Object obj = handleValue(val, type);
+            col.add(obj);
         }
         
         String name = prop.getAttributeValue("name");
@@ -234,6 +242,48 @@
         return true;
     }
 
+    private static boolean handleXML(Element prop, Map<String, Object> map) {
+        String sb = readXML(prop);
+        if (sb == null) {
+            return false;
+        }
+
+        String name = prop.getAttributeValue("name");
+        map.put(name, sb);
+        return true;
+    }
+
+    @SuppressWarnings("unchecked")
+    private static String readXML(Element prop) {
+        Element el = prop.getChild("xml");
+        if (el == null) {
+            return null;
+        }
+        
+        String type = getTypeName(prop);
+        if (!"String".equals(type)) {
+            LOG.warning("Embedded XML must be of type String, found: " + type);
+            return null;
+        }
+        
+        XMLOutputter outputter = new XMLOutputter(Format.getCompactFormat());
+        StringBuilder sb = new StringBuilder();    
+        List<Element> children = el.getChildren();
+        for (Element child : children) {
+            sb.append(outputter.outputString(child));
+        }
+        return sb.toString();
+    }
+
+    private static Object handleValue(Element val, String type) {
+        String xml = readXML(val);
+        if (xml != null) {
+            return xml;
+        } else {
+            return instantiate(type, val.getText());
+        }
+    }
+
     private static Object instantiate(String type, String value) {
         if ("String".equals(type)) {
             return value;
@@ -264,8 +314,8 @@
         }
         String javaType = "java.lang." + boxedType;
         
-        try {
-            Class<?> cls = String.class.getClassLoader().loadClass(javaType);
+        try {            
+            Class<?> cls = ClassLoader.getSystemClassLoader().loadClass(javaType);
             Constructor<?> ctor = cls.getConstructor(String.class);
             return ctor.newInstance(value);
         } catch (Exception e) {

Modified: cxf/dosgi/trunk/discovery/local/src/test/java/org/apache/cxf/dosgi/discovery/local/LocalDiscoveryUtilsTest.java
URL: http://svn.apache.org/viewvc/cxf/dosgi/trunk/discovery/local/src/test/java/org/apache/cxf/dosgi/discovery/local/LocalDiscoveryUtilsTest.java?rev=893440&r1=893439&r2=893440&view=diff
==============================================================================
--- cxf/dosgi/trunk/discovery/local/src/test/java/org/apache/cxf/dosgi/discovery/local/LocalDiscoveryUtilsTest.java (original)
+++ cxf/dosgi/trunk/discovery/local/src/test/java/org/apache/cxf/dosgi/discovery/local/LocalDiscoveryUtilsTest.java Wed Dec 23 09:10:32 2009
@@ -18,6 +18,8 @@
  */
 package org.apache.cxf.dosgi.discovery.local;
 
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
 import java.net.URL;
 import java.util.Arrays;
 import java.util.Collection;
@@ -32,8 +34,13 @@
 import junit.framework.TestCase;
 
 import org.easymock.EasyMock;
+import org.jdom.Document;
 import org.jdom.Element;
+import org.jdom.JDOMException;
 import org.jdom.Namespace;
+import org.jdom.input.SAXBuilder;
+import org.jdom.output.Format;
+import org.jdom.output.XMLOutputter;
 import org.osgi.framework.Bundle;
 import org.osgi.service.discovery.ServiceEndpointDescription;
 import org.osgi.service.discovery.ServicePublication;
@@ -164,7 +171,7 @@
         assertEquals(4, edElements.size());
     }
     
-    public void testAllEndpoints() {
+    public void testAllEndpoints1() {
         URL ed1URL = getClass().getResource("/ed1.xml");
         
         Bundle b = EasyMock.createNiceMock(Bundle.class);
@@ -195,4 +202,79 @@
         assertEquals("http://somewhere:1/2/3/4?5", ed3.getRemoteURI());
         assertEquals(Arrays.asList("SomeOtherService", "WithSomeSecondInterface"), ed3.getInterfaces());
     }
+    
+    @SuppressWarnings("unchecked")
+    public void testAllEndpoints2() throws Exception {
+        URL ed1URL = getClass().getResource("/ed2.xml");
+        
+        Bundle b = EasyMock.createNiceMock(Bundle.class);
+        EasyMock.expect(b.findEntries(
+            EasyMock.eq("OSGI-INF/remote-service"), 
+            EasyMock.eq("*.xml"), EasyMock.anyBoolean())).andReturn(
+                Collections.enumeration(Arrays.asList(ed1URL))).anyTimes();
+        EasyMock.replay(b);
+        
+        List<EndpointDescription> eds = LocalDiscoveryUtils.getAllEndpointDescriptions(b);
+        assertEquals(2, eds.size());
+        EndpointDescription ed0 = eds.get(0);
+        assertEquals("foo:bar", ed0.getRemoteURI());
+        assertEquals(Arrays.asList("com.acme.HelloService"), ed0.getInterfaces());
+        assertEquals(Arrays.asList("SOAP"), ed0.getIntents());
+        assertEquals("org.apache.cxf.ws", ed0.getProperties().get("service.exported.configs"));
+        
+        EndpointDescription ed1 = eds.get(1);
+        Map<String, Object> props = ed1.getProperties();
+        assertEquals(Arrays.asList("com.acme.HelloService", "some.other.Service"), ed1.getInterfaces());
+        assertFalse("Should not be exactly the same. The value should contain a bunch of newlines", 
+            "org.apache.cxf.ws".equals(props.get("service.exported.configs")));
+        assertEquals("org.apache.cxf.ws", props.get("service.exported.configs").toString().trim());
+        
+        assertEquals(normXML("<other:t1 xmlns:other='http://www.acme.org/xmlns/other/v1.0.0'><foo type='bar'>haha</foo></other:t1>"), 
+            normXML((String) props.get("someXML")));
+        
+        assertEquals(Long.MAX_VALUE, props.get("long"));
+        assertEquals(new Long(-1), props.get("long2"));
+        assertEquals(Double.MAX_VALUE, props.get("double"));
+        assertEquals(new Double(1.0d), props.get("Double2"));
+        assertEquals(new Float(42.24f), props.get("float"));
+        assertEquals(new Float(1.0f), props.get("Float2"));
+        assertEquals(new Integer(17), props.get("int"));
+        assertEquals(new Integer(42), props.get("Integer2"));
+        assertEquals(new Byte((byte) 127), props.get("byte"));
+        assertEquals(new Byte((byte) -128), props.get("Byte2"));
+        assertEquals(new Boolean(true), props.get("boolean"));
+        assertEquals(new Boolean(true), props.get("Boolean2"));
+        assertEquals(new Short((short) 99), props.get("short"));
+        assertEquals(new Short((short) -99), props.get("Short2"));
+        int [] intArray = (int []) props.get("int-array");
+        assertTrue(Arrays.equals(new int[] {1, 2}, intArray));
+        
+        Integer [] integerArray = (Integer []) props.get("Integer-array");
+        assertTrue(Arrays.equals(new Integer[] {2, 1}, integerArray));
+        
+        assertEquals(Arrays.asList(true, false), props.get("bool-list"));
+        assertEquals(new HashSet<Object>(), props.get("long-set"));
+        assertEquals("Hello", props.get("other1").toString().trim());
+        
+        List l = (List) props.get("other2");
+        assertEquals(1, l.size());
+        assertEquals(normXML("<other:t2 xmlns:other='http://www.acme.org/xmlns/other/v1.0.0'/>"),
+            normXML((String) l.get(0)));
+    }
+    
+    private static String normXML(String s) throws JDOMException, IOException {
+        String s2 = stripComment(s);
+        String s3 = stripProlog(s2);
+        Document d = new SAXBuilder().build(new ByteArrayInputStream(s3.getBytes()));
+        XMLOutputter outputter  = new XMLOutputter(Format.getPrettyFormat());
+        return outputter.outputString(d);
+    }
+    
+    private static String stripComment(String s) { 
+        return s.replaceAll("<!--(.*?)-->", "");
+    }
+    
+    private static String stripProlog(String s) {
+        return s.replaceAll("<\\?(.*?)\\?>", "");
+    }         
 }

Added: cxf/dosgi/trunk/discovery/local/src/test/resources/ed2.xml
URL: http://svn.apache.org/viewvc/cxf/dosgi/trunk/discovery/local/src/test/resources/ed2.xml?rev=893440&view=auto
==============================================================================
--- cxf/dosgi/trunk/discovery/local/src/test/resources/ed2.xml (added)
+++ cxf/dosgi/trunk/discovery/local/src/test/resources/ed2.xml Wed Dec 23 09:10:32 2009
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<rsa:endpoint-descriptions xmlns:rsa="http://www.osgi.org/xmlns/rsa/v1.0.0"
+  xmlns:other="http://www.acme.org/xmlns/other/v1.0.0">
+  <endpoint-description>
+    <property name="objectClass">
+      <array>
+        <value>com.acme.HelloService</value>
+      </array>
+    </property>
+    <property name="service.intents">SOAP</property>
+    <property name="service.exported.configs" value="org.apache.cxf.ws"/>
+    <property name="endpoint.uri">foo:bar</property>
+  </endpoint-description>
+  <endpoint-description>
+    <property name="endpoint.uri">foo:bar</property>
+    <property name="objectClass" value-type="String">
+      <array>
+        <value>com.acme.HelloService</value>
+        <value>some.other.Service</value>
+      </array>
+    </property>
+    
+    <property name="someXML" value-type="String">
+      <!-- Literal XML to be parsed into the String -->
+      <xml>
+        <other:t1>
+          <foo type="bar">haha</foo>
+        </other:t1>
+      </xml>
+    </property>
+
+    <property name="long" value-type="long">9223372036854775807</property>
+    <property name="Long2" value-type="Long" value="-1"/>
+    <property name="double" value-type="double">1.7976931348623157E308</property>
+    <property name="Double2" value-type="Double">1.0</property>
+    <property name="float" value-type="float">42.24</property>
+    <property name="Float2" value-type="Float" value="1.0"/>
+    <property name="int" value-type="int">17</property>
+    <property name="Integer2" value-type="Integer" value="42"/>
+    <property name="byte" value-type="byte">127</property>
+    <property name="Byte2" value-type="Byte" value="-128"/>
+    <property name="boolean" value-type="boolean">true</property>
+    <property name="Boolean2" value-type="Boolean" value="true"/>
+    <property name="short" value-type="short">99</property>
+    <property name="Short2" value-type="Short" value="-99"/>
+    
+    <property name="bool-list" value-type="boolean">
+      <list>
+        <value>true</value>
+        <value>false</value>
+      </list>
+    </property>
+    <property name="long-set" value-type="long">
+      <set/> <!-- empty set -->
+    </property>
+    <property name="int-array" value-type="int">
+      <array>
+        <value>1</value>
+        <value>2</value>
+      </array>
+    </property>
+    <property name="Integer-array" value-type="Integer">
+      <array>
+        <value>2</value>
+        <value>1</value>
+      </array>
+    </property>
+    <property name="service.exported.configs">
+      org.apache.cxf.ws
+    </property>
+
+    <property name="other1">
+        Hello
+      <other:t1/>        
+      <!-- the above tag is a custom extension -->
+    </property>
+    <property name="other2">
+      <list>
+        <value>
+          <!-- A value specified as literal XML -->
+          <xml>
+            <other:t2/>
+          </xml>        
+        </value>
+      </list>
+      <!-- This is a custom extension -->
+      <other:t1/>                    
+    </property>
+  </endpoint-description>
+</rsa:endpoint-descriptions>

Propchange: cxf/dosgi/trunk/discovery/local/src/test/resources/ed2.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/dosgi/trunk/discovery/local/src/test/resources/ed2.xml
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Propchange: cxf/dosgi/trunk/discovery/local/src/test/resources/ed2.xml
------------------------------------------------------------------------------
    svn:mime-type = text/xml