Now using the dom level 3 API for parsing. Also extended the test case
authorErik Brakkee <erik@brakkee.org>
Mon, 21 Feb 2011 23:11:28 +0000 (23:11 +0000)
committerErik Brakkee <erik@brakkee.org>
Mon, 21 Feb 2011 23:11:28 +0000 (23:11 +0000)
to verify namespace awareness.

The readAndValidate() method must still be tested.

Removed the dependencies on dom4j and jaxen entirely from the code.
Turned out that conversion from Dom to Dom4j was not namespace aware.

pom.xml
support/general/pom.xml
support/general/src/main/java/org/wamblee/xml/DomUtils.java
support/general/src/test/java/org/wamblee/xml/DomUtilsTest.java
support/general/src/test/java/org/wamblee/xml/XmlUtils.java
support/general/src/test/resources/org/wamblee/xml/test.xml
support/spring/pom.xml
wicket/components/src/main/resources/org/wamblee/wicket/behavior/wamblee-tooltip.js

diff --git a/pom.xml b/pom.xml
index 89bbb48498b268768f7548abf129af124fd438dc..395775134dd338cc5d7e3ce8b48408dd26aa49e3 100644 (file)
--- a/pom.xml
+++ b/pom.xml
                                <version>${spring.version}</version>
                        </dependency>
 
-                       <dependency>
-                               <groupId>dom4j</groupId>
-                               <artifactId>dom4j</artifactId>
-                               <version>1.6</version>
-                               <exclusions>
-                                       <exclusion>
-                                               <groupId>xml-apis</groupId>
-                                               <artifactId>xml-apis</artifactId>
-                                       </exclusion>
-                               </exclusions>
-                       </dependency>
                        <dependency>
                                <groupId>net.sf.ehcache</groupId>
                                <artifactId>ehcache-core</artifactId>
                                <artifactId>commons-email</artifactId>
                                <version>1.0</version>
                        </dependency>
-                       <dependency>
-                               <groupId>jaxen</groupId>
-                               <artifactId>jaxen</artifactId>
-                               <version>1.1-beta-9</version>
-                               <exclusions>
-                                       <exclusion>
-                                               <groupId>xom</groupId>
-                                               <artifactId>xom</artifactId>
-                                       </exclusion>
-                                       <exclusion>
-                                               <groupId>xerces</groupId>
-                                               <artifactId>xmlParserAPIs</artifactId>
-                                       </exclusion>
-                               </exclusions>
-                       </dependency>
                        <dependency>
                                <groupId>jstl</groupId>
                                <artifactId>jstl</artifactId>
index dbe1ae0219a339edd3d5f0d4c0560ed502f6f85f..c56ad8ac3f9cac56355affbccd2bb17f8e2c50cb 100644 (file)
       <optional>true</optional>
     </dependency>
     
-    <dependency>
-      <groupId>dom4j</groupId>
-      <artifactId>dom4j</artifactId>
-      <scope>test</scope>
-    </dependency>
-   
-    <dependency>
-      <groupId>jaxen</groupId>
-      <artifactId>jaxen</artifactId>
-      <optional>true</optional>
-      <scope>test</scope>
-    </dependency>
-    
   </dependencies>
   
   <distributionManagement>
index 3d1c2d8ffae0cc0b38031627db6b7131becf5d7b..44a9f8ee8268a4cb946d7bc6adb7478e21a84f34 100644 (file)
@@ -39,6 +39,7 @@ import javax.xml.transform.stream.StreamResult;
 import javax.xml.transform.stream.StreamSource;
 import javax.xml.validation.Schema;
 import javax.xml.validation.SchemaFactory;
+import javax.xml.validation.Validator;
 
 import org.w3c.dom.Attr;
 import org.w3c.dom.Document;
@@ -46,6 +47,11 @@ import org.w3c.dom.Element;
 import org.w3c.dom.NamedNodeMap;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
+import org.w3c.dom.bootstrap.DOMImplementationRegistry;
+import org.w3c.dom.ls.DOMImplementationLS;
+import org.w3c.dom.ls.LSException;
+import org.w3c.dom.ls.LSInput;
+import org.w3c.dom.ls.LSParser;
 import org.xml.sax.SAXException;
 
 /**
@@ -91,15 +97,24 @@ public final class DomUtils {
      */
     public static Document read(InputStream aIs) throws XMLException {
         try {
-            DocumentBuilder builder = DocumentBuilderFactory.newInstance()
-                .newDocumentBuilder();
+            DOMImplementationRegistry registry = DOMImplementationRegistry
+                .newInstance();
 
-            return builder.parse(aIs);
-        } catch (SAXException e) {
+            DOMImplementationLS impl = (DOMImplementationLS) registry
+                .getDOMImplementation("LS");
+
+            LSParser builder = impl.createLSParser(
+                DOMImplementationLS.MODE_SYNCHRONOUS, null);
+            LSInput input = impl.createLSInput();
+            input.setByteStream(aIs);
+            return builder.parse(input);
+        } catch (IllegalAccessException e) {
             throw new XMLException(e.getMessage(), e);
-        } catch (IOException e) {
+        } catch (InstantiationException e) {
             throw new XMLException(e.getMessage(), e);
-        } catch (ParserConfigurationException e) {
+        } catch (ClassNotFoundException e) {
+            throw new XMLException(e.getMessage(), e);
+        } catch (LSException e) {
             throw new XMLException(e.getMessage(), e);
         } finally {
             try {
@@ -124,23 +139,18 @@ public final class DomUtils {
     public static Document readAndValidate(InputStream aIs, InputStream aSchema)
         throws XMLException {
         try {
+            Document doc = read(aIs);
             final Schema schema = SchemaFactory.newInstance(
                 XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema(
                 new StreamSource(aSchema));
+            Validator validator = schema.newValidator();
+            validator.validate(new DOMSource(doc));
 
-            final DocumentBuilderFactory factory = DocumentBuilderFactory
-                .newInstance();
-            factory.setValidating(true);
-            factory.setNamespaceAware(true);
-            factory.setSchema(schema);
-
-            return factory.newDocumentBuilder().parse(aIs);
+            return doc;
         } catch (SAXException e) {
             throw new XMLException(e.getMessage(), e);
         } catch (IOException e) {
             throw new XMLException(e.getMessage(), e);
-        } catch (ParserConfigurationException e) {
-            throw new XMLException(e.getMessage(), e);
         } finally {
             try {
                 aSchema.close();
index c777a86947d98a912b2bbe60d09d1bf3a59d6256..86fe91596fa93ae01fb9bdde85ac665b5cfce3a1 100644 (file)
@@ -19,12 +19,17 @@ import java.io.ByteArrayInputStream;
 
 import org.junit.Test;
 import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import static junit.framework.TestCase.*;
 
 public class DomUtilsTest {
 
     @Test
     public void testReadWrite() throws Exception { 
         Document doc = DomUtils.read(getClass().getResourceAsStream("test.xml"));
+        Element element = doc.getDocumentElement();
+        assertEquals("http://wamblee.org/test", element.getNamespaceURI());
         String val = DomUtils.serialize(doc);
         // parse the written document
         Document doc2 = DomUtils.read(new ByteArrayInputStream(val.getBytes()));
index 3888e6f77ba2d3cce1652e95e57cf929a9497cc8..fd49a8a239f9ca858d953bcc58775d69e1132c8d 100644 (file)
@@ -16,6 +16,7 @@
 package org.wamblee.xml;
 
 import java.io.Serializable;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
@@ -24,12 +25,13 @@ import java.util.TreeMap;
 
 import junit.framework.TestCase;
 
-import org.dom4j.Attribute;
-import org.dom4j.Document;
-import org.dom4j.DocumentException;
-import org.dom4j.Element;
-import org.dom4j.io.DOMReader;
-import org.dom4j.io.DOMWriter;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
 
 /**
  * XML test support utilities.
@@ -45,20 +47,6 @@ public final class XmlUtils {
         // Empty
     }
 
-    /**
-     * Checks equality of two XML documents excluding comment and processing
-     * nodes and trimming the text of the elements. In case of problems, it
-     * provides an xpath-like expression describing where the problem is.
-     * 
-     * @param aMsg
-     * @param aExpected
-     * @param aActual
-     */
-    public static void assertEquals(String aMsg,
-        org.w3c.dom.Document aExpected, org.w3c.dom.Document aActual) {
-        assertEquals(aMsg, convert(aExpected), convert(aActual));
-    }
-
     /**
      * Checks equality of two XML documents excluding comment and processing
      * nodes and trimming the text of the elements. In case of problems, it
@@ -70,34 +58,76 @@ public final class XmlUtils {
      */
     public static void assertEquals(String aMsg, Document aExpected,
         Document aActual) {
-        assertEquals(aMsg + "/" + aExpected.getRootElement().getName(),
-            aExpected.getRootElement(), aActual.getRootElement());
+        assertEquals(
+            aMsg + "/" + aExpected.getDocumentElement().getLocalName(),
+            aExpected.getDocumentElement(), aActual.getDocumentElement());
+    }
+
+    private static <T> List<T> convertMap(NamedNodeMap aMap, Class<T> aType) {
+        List<T> result = new ArrayList<T>();
+        for (int i = 0; i < aMap.getLength(); i++) {
+            result.add((T) aMap.item(i));
+        }
+        return result;
+    }
+
+    private static List<Element> getChildElements(Element aElement) {
+        List<Element> result = new ArrayList<Element>();
+        NodeList children = aElement.getChildNodes();
+        for (int i = 0; i < children.getLength(); i++) {
+            Node node = children.item(i);
+            if (node instanceof Element) {
+                result.add((Element) node);
+            }
+        }
+        return result;
+    }
+    
+    private static String getDirectText(Element aElement) { 
+        String res = "";
+        NodeList children = aElement.getChildNodes();
+        for (int i = 0; i < children.getLength(); i++) {
+            Node node = children.item(i);
+            if (node instanceof Text) {
+                res += node.getTextContent() + " ";
+            }
+        }
+        return trim(res); 
+    }
+    
+    private static String trim(String aText) { 
+        return aText.trim().replaceAll("\\n", " ").replaceAll("\\s+", " ");
     }
 
     /**
      * Checks equality of two XML elements excluding comment and processing
-     * nodes and trimming the text of the elements. In case of problems, it
+     * nodes and trimming the text of the elements (including whitespace in the middle). 
+     * In case of problems, it
      * provides an xpath-like expression describing where the problem is.
      * 
      * @param aMsg
      * @param aExpected
      * @param aActual
      */
-    public static void assertEquals(String aMsg, Element aExpected,
+    private static void assertEquals(String aMsg, Element aExpected,
         Element aActual) {
         // Name.
-        TestCase.assertEquals(aMsg + "/name()", aExpected.getName(), aActual
-            .getName());
+        TestCase.assertEquals(aMsg + "/name()", aExpected.getLocalName(),
+            aActual.getLocalName());
+        TestCase.assertEquals(aMsg + "/namespace()",
+            aExpected.getNamespaceURI(), aActual.getNamespaceURI());
 
         // Text
-        TestCase.assertEquals(aMsg + "/text()", aExpected.getTextTrim(),
-            aActual.getTextTrim());
+        TestCase.assertEquals(aMsg + "/text()", getDirectText(aExpected)
+            , getDirectText(aActual));
 
         // Attributes
-        List<Attribute> expectedAttrs = aExpected.attributes();
+        List<Attr> expectedAttrs = convertMap(aExpected.getAttributes(),
+            Attr.class);
+
         Collections.sort(expectedAttrs, new AttributeComparator());
 
-        List<Attribute> actualAttrs = aActual.attributes();
+        List<Attr> actualAttrs = convertMap(aActual.getAttributes(), Attr.class);
         Collections.sort(actualAttrs, new AttributeComparator());
 
         TestCase.assertEquals("count(" + aMsg + "/@*)", expectedAttrs.size(),
@@ -109,8 +139,8 @@ public final class XmlUtils {
         }
 
         // Nested elements.
-        List<Element> expectedElems = aExpected.elements();
-        List<Element> actualElems = aActual.elements();
+        List<Element> expectedElems = getChildElements(aExpected);
+        List<Element> actualElems = getChildElements(aActual);
         TestCase.assertEquals("count(" + aMsg + "/*)", expectedElems.size(),
             actualElems.size());
 
@@ -119,7 +149,7 @@ public final class XmlUtils {
         Map<String, Integer> elementIndex = new TreeMap<String, Integer>();
 
         for (int i = 0; i < expectedElems.size(); i++) {
-            String elemName = expectedElems.get(i).getName();
+            String elemName = expectedElems.get(i).getLocalName();
             Integer index = elementIndex.get(elemName);
 
             if (index == null) {
@@ -130,7 +160,7 @@ public final class XmlUtils {
 
             elementIndex.put(elemName, index);
 
-            String msg = aMsg + "/" + expectedElems.get(i).getName() + "[" +
+            String msg = aMsg + "/" + expectedElems.get(i).getLocalName() + "[" +
                 index + "]";
 
             assertEquals(msg, expectedElems.get(i), actualElems.get(i));
@@ -145,19 +175,18 @@ public final class XmlUtils {
      * @param aExpected
      * @param aActual
      */
-    public static void assertEquals(String aMsg, Attribute aExpected,
-        Attribute aActual) {
-        TestCase.assertEquals(aMsg + ":name", aExpected.getName(), aActual
-            .getName());
-        TestCase.assertEquals(aMsg + ":value", aExpected.getValue(), aActual
-            .getValue());
+    private static void assertEquals(String aMsg, Attr aExpected, Attr aActual) {
+        TestCase.assertEquals(aMsg + ":name", aExpected.getName(),
+            aActual.getName());
+        TestCase.assertEquals(aMsg + ":value", aExpected.getValue(),
+            aActual.getValue());
     }
 
     /**
      * Comparator which compares attributes by name.
      */
-    private static final class AttributeComparator implements
-        Comparator<Attribute>, Serializable {
+    private static final class AttributeComparator implements Comparator<Attr>,
+        Serializable {
 
         private static final long serialVersionUID = 7897287273519886301L;
 
@@ -166,35 +195,8 @@ public final class XmlUtils {
          * 
          * @see java.util.Comparator#compare(T, T)
          */
-        public int compare(Attribute aAttribute1, Attribute aAttribute2) {
+        public int compare(Attr aAttribute1, Attr aAttribute2) {
             return aAttribute1.getName().compareTo(aAttribute2.getName());
         }
     }
-    
-    /**
-     * Converts a dom4j document into a w3c DOM document.
-     * 
-     * @param aDocument
-     *            Document to convert.
-     * 
-     * @return W3C DOM document.
-     * 
-     */
-    public static org.w3c.dom.Document convert(org.dom4j.Document aDocument)
-        throws DocumentException {
-        return new DOMWriter().write(aDocument);
-    } 
-
-    /**
-     * Converts a W3C DOM document into a dom4j document.
-     * 
-     * @param aDocument
-     *            Document to convert.
-     * 
-     * @return Dom4j document.
-     */
-    public static org.dom4j.Document convert(org.w3c.dom.Document aDocument) {
-        return new DOMReader().read(aDocument);
-    }
-    
 }
index 3e56c45f1b66d07a83a84bdc08585343a7277522..27d2e3c18783b578524ae0cc23af24baffbca2cf 100644 (file)
@@ -1,3 +1,3 @@
-<root>
-    <elem attr="5">hallo</elem>
-</root>
\ No newline at end of file
+<x:root xmlns:x="http://wamblee.org/test">
+    <x:elem attr="5">hallo</x:elem>
+</x:root>
\ No newline at end of file
index 2147922a77c3cc62d63864739e7d87e6bf0cdebd..198dee44caf963a60d48f054b348f73719493998 100644 (file)
       <groupId>org.springframework</groupId>
       <artifactId>spring-aop</artifactId>
     </dependency>
-    <dependency>
-      <groupId>dom4j</groupId>
-      <artifactId>dom4j</artifactId>
-    </dependency>
     <dependency>
       <groupId>net.sf.ehcache</groupId>
       <artifactId>ehcache-core</artifactId>
       <artifactId>wamblee-hibernate-jpa</artifactId>
       <version>0.7-SNAPSHOT</version>
     </dependency>
-    <dependency>
-      <groupId>jaxen</groupId>
-      <artifactId>jaxen</artifactId>
-    </dependency>
 
   </dependencies>
 
index 016fa492ce54345e1989c997d8536fb2b1031924..3bdd99d13b218d1469cbc25922ba32cc855bb5f8 100644 (file)
@@ -34,6 +34,9 @@
 
                // Show the tooltip.
                var tooltipShow = function(event) {
+                       timerid = setTimeout(function() {
+                               content.fadeIn(options.fadein);
+                       }, options.delay);
                        var content = $("#tooltipContent").text(text).css({
                                position : "absolute",
                                top : event.pageY + 5,
                                padding : options.padding,
                                background : options.background
                        });
-                       timerid = setTimeout(function() {
-                               content.fadeIn(options.fadein);
-                       }, options.delay);
-
                        // console.log("start");
                };
 
                // Hide the tooltip.
                var tooltipHide = function(event) {
-                       $("#tooltipContent").fadeOut(options.fadeout);
                        if (timerid) {
                                console.log("clear timeout");
                                clearTimeout(timerid);
                                timerid = undefined;
                        }
+                       $("#tooltipContent").fadeOut(options.fadeout);
                }
 
                // Add hover listeners.