You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by lt...@apache.org on 2005/10/06 08:23:54 UTC

svn commit: r306542 - in /maven/maven-1/plugins/trunk/plugin/src/main/org/apache/maven: JaxpMsvBean.java XPathLocationTracker.java

Author: ltheussl
Date: Wed Oct  5 23:23:52 2005
New Revision: 306542

URL: http://svn.apache.org/viewcvs?rev=306542&view=rev
Log:
Show XPath location of an error

Added:
    maven/maven-1/plugins/trunk/plugin/src/main/org/apache/maven/XPathLocationTracker.java
Modified:
    maven/maven-1/plugins/trunk/plugin/src/main/org/apache/maven/JaxpMsvBean.java

Modified: maven/maven-1/plugins/trunk/plugin/src/main/org/apache/maven/JaxpMsvBean.java
URL: http://svn.apache.org/viewcvs/maven/maven-1/plugins/trunk/plugin/src/main/org/apache/maven/JaxpMsvBean.java?rev=306542&r1=306541&r2=306542&view=diff
==============================================================================
--- maven/maven-1/plugins/trunk/plugin/src/main/org/apache/maven/JaxpMsvBean.java (original)
+++ maven/maven-1/plugins/trunk/plugin/src/main/org/apache/maven/JaxpMsvBean.java Wed Oct  5 23:23:52 2005
@@ -17,22 +17,25 @@
  * ====================================================================
  */
 
-
-import com.sun.msv.verifier.jaxp.SAXParserFactoryImpl;
-
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.ByteArrayInputStream;
 
-import javax.xml.parsers.*;
+import javax.xml.parsers.SAXParserFactory;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
-import org.xml.sax.helpers.DefaultHandler;
+import org.iso_relax.verifier.Verifier;
+import org.iso_relax.verifier.VerifierFactory;
+import org.iso_relax.verifier.VerifierHandler;
+
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.EntityResolver;
 import org.xml.sax.SAXParseException;
 import org.xml.sax.SAXException;
 import org.xml.sax.InputSource;
-
+import org.xml.sax.XMLReader;
 
 /**
  * JaxpMsvBean Bean: Uses JAXP implementation of MSV.
@@ -52,86 +55,47 @@
     /** For debug output. */
     private Log log = LogFactory.getLog(JaxpMsvBean.class);
 
-    private static String EMPTY = "";
-    private static ByteArrayInputStream EMPTY_STREAM =
+    private static final String EMPTY = "";
+    private static final ByteArrayInputStream EMPTY_STREAM =
         new ByteArrayInputStream(EMPTY.getBytes());
 
-    private static int MSV_WARNING = 0;
-    private static int MSV_ERROR = 1;
-    private static int MSV_FATAL_ERROR = 2;
+    private static final int MSV_WARNING = 0;
+    private static final int MSV_ERROR = 1;
+    private static final int MSV_FATAL_ERROR = 2;
+
+    private boolean isValid = true;
+    private XPathLocationTracker tracker;
 
     //~ Methods --------------------------------------------------------------
 
     /**
      * Performs validation.
+     * @throws Exception Exception
      */
-    public void validate() throws Exception 
+    public void validate() throws Exception
     {
-        SAXParserFactory factory =
-            new SAXParserFactoryImpl(new File(schema));
+
+        VerifierFactory verifierFactory =
+            new com.sun.msv.verifier.jarv.TheFactoryImpl();
+        Verifier verifier = verifierFactory.newVerifier(new File(schema));
+
+
+        SAXParserFactory factory = SAXParserFactory.newInstance();
         factory.setNamespaceAware(true);
-        SAXParser parser = factory.newSAXParser();
-        parser.parse(new File(file), new DefaultHandler()
-        {
-            boolean isValid = true;
-            public void warning(SAXParseException e) throws SAXException
-            {
-                errorMessage(e, MSV_WARNING);
-            }
-            public void error(SAXParseException e) throws SAXException
-            {
-                errorMessage(e, MSV_ERROR);
-                isValid = false;
-            }
-            public void fatalError(SAXParseException e) throws SAXException
-            {
-                errorMessage(e, MSV_FATAL_ERROR);
-                isValid = false;
-            }
-            public InputSource resolveEntity(String publicId,
-                                 String systemId) throws SAXException
-            {
-                log.warn("WARNING: External entity " + systemId
-                    + " won't be resolved!");
-                return new InputSource(EMPTY_STREAM);
-            }
-            public void endDocument()
-            {
-                if(isValid)
-                {
-                    log.info(file + " verified: OK");
-                } else {
-                    log.info("WARNING: " + file + " is NOT valid");
-                }
-            }
-        });
-    }
+        XMLReader reader = factory.newSAXParser().getXMLReader();
 
-    private void errorMessage(SAXParseException e, int type)
-    {
-        File xmlFile = new File(file);
+        VerifierHandler handler = verifier.getVerifierHandler();
+        tracker = new XPathLocationTracker(handler);
+        reader.setContentHandler(tracker);
+        reader.setEntityResolver( new EntityResolverImpl() );
+        verifier.setErrorHandler( new ErrorHandlerImpl() );
 
-        if (type == MSV_ERROR)
-        {
-            log.error( "com.sun.msv.verifier.ValidityViolation on line "
-                + e.getLineNumber() + " of " + xmlFile.getName() + ":" );
-            log.error( e.getMessage() );
-        } else if (type == MSV_FATAL_ERROR)
-        {
-            log.error( "Non-recoverable parsing error on line "
-                + e.getLineNumber() + " of " + xmlFile.getName() + ":" );
-            log.error( e.getMessage() );
-        } else if (type == MSV_WARNING)
-        {
-            log.warn( "Warning on line "
-                + e.getLineNumber() + " of " + xmlFile.getName() + ":" );
-            log.warn( e.getMessage() );
-        }
+        reader.parse(new InputSource(new FileInputStream(file)));
+        endMessage();
     }
 
     /**
      * Sets the schema.
-     *
      * @param newSchema The schema to set
      */
     public void setSchema(String newSchema)
@@ -141,7 +105,6 @@
 
     /**
      * Sets the file.
-     *
      * @param newFile The file to set
      */
     public void setFile(String newFile)
@@ -151,7 +114,6 @@
 
     /**
      * Gets the schema.
-     *
      * @return The schema
      */
     public String getSchema()
@@ -161,7 +123,6 @@
 
     /**
      * Gets the file.
-     *
      * @return The file
      */
     public String getFile()
@@ -169,5 +130,76 @@
       return file;
     }
 
+    private void endMessage()
+    {
+        if ( isValid )
+        {
+            log.info(file + " verified: OK");
+        } else {
+            log.info(file + " is NOT valid!");
+        }
+    }
+
+    private void setValid(boolean valid)
+    {
+        this.isValid = valid;
+    }
+
+    private void errorMessage(SAXParseException e, int type)
+    {
+        File xmlFile = new File(file);
+
+        if (type == MSV_ERROR)
+        {
+            log.error( "    ERROR on line " + e.getLineNumber()
+                + " of file " + xmlFile.getName() + "," );
+            log.error( "    XPath location " + tracker.getXPath() + ":" );
+            log.error( "    " + e.getMessage() );
+        } else if (type == MSV_FATAL_ERROR)
+        {
+            log.error( "    Non-recoverable parsing error on line "
+                + e.getLineNumber() + " of file " + xmlFile.getName() + "," );
+            log.error( "    XPath location " + tracker.getXPath() + ":" );
+            log.error( "    " + e.getMessage() );
+        } else if (type == MSV_WARNING)
+        {
+            log.warn( "    WARNING on line " + e.getLineNumber()
+                + " of file " + xmlFile.getName() + "," );
+            log.warn( "    XPath location " + tracker.getXPath() + ":" );
+            log.warn( e.getMessage() );
+        }
+    }
+
+    private class ErrorHandlerImpl implements ErrorHandler
+    {
+        public void warning(SAXParseException e) throws SAXException
+        {
+            errorMessage(e, MSV_WARNING);
+        }
+
+        public void error(SAXParseException e) throws SAXException
+        {
+            errorMessage(e, MSV_ERROR);
+            setValid(false);
+        }
+
+        public void fatalError(SAXParseException e) throws SAXException
+        {
+            errorMessage(e, MSV_FATAL_ERROR);
+            setValid(false);
+        }
+    }
+
+
+    private class EntityResolverImpl implements EntityResolver
+    {
+        public InputSource resolveEntity(String publicId,
+                             String systemId) throws SAXException
+        {
+            log.warn("    WARNING: External entity " + systemId
+                + " won't be resolved");
+            return new InputSource(EMPTY_STREAM);
+        }
+    }
 
 }

Added: maven/maven-1/plugins/trunk/plugin/src/main/org/apache/maven/XPathLocationTracker.java
URL: http://svn.apache.org/viewcvs/maven/maven-1/plugins/trunk/plugin/src/main/org/apache/maven/XPathLocationTracker.java?rev=306542&view=auto
==============================================================================
--- maven/maven-1/plugins/trunk/plugin/src/main/org/apache/maven/XPathLocationTracker.java (added)
+++ maven/maven-1/plugins/trunk/plugin/src/main/org/apache/maven/XPathLocationTracker.java Wed Oct  5 23:23:52 2005
@@ -0,0 +1,206 @@
+package org.apache.maven;
+
+/* ====================================================================
+ *   Copyright 2001-2005 The Apache Software Foundation.
+ *
+ *   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.
+ * ====================================================================
+ */
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.XMLFilterImpl;
+
+/**
+ * Constructs an XPath expression in the form:
+ *    /root/child[3]/grandchild[2] ...
+ *
+ * @author <a href="mailto:ltheussl@apache.org">Lukas Theussl</a>
+ */
+
+public class XPathLocationTracker extends XMLFilterImpl
+{
+
+    private State state;
+    private static final Integer[] ints = new Integer[]
+    {
+        new Integer(0),
+        new Integer(1),
+        new Integer(2),
+        new Integer(3),
+        new Integer(4)
+    };
+
+    /**
+     * Constructor: sets the ContentHandler.
+     * @param handler The ContentHandler
+     */
+    public XPathLocationTracker( ContentHandler handler )
+    {
+        setContentHandler(handler);
+    }
+
+    /**
+     * Overriding ContentHandler.
+     * @throws SAXException SAXException
+     */
+    public void startDocument() throws SAXException
+    {
+        state = new State(null);
+        super.startDocument();
+    }
+
+    /**
+     * Overriding ContentHandler.
+     * @throws SAXException SAXException
+     */
+    public void endDocument() throws SAXException
+    {
+        super.endDocument();
+        state = null;
+    }
+
+    /**
+     * Overriding ContentHandler.
+     * @param uri uri
+     * @param localName localName
+     * @param qName qName
+     * @param atts atts
+     * @throws SAXException SAXException
+     */
+    public void startElement(String uri, String localName,
+            String qName, Attributes atts) throws SAXException
+    {
+        state = state.push(qName);
+        super.startElement(uri, localName, qName, atts);
+    }
+
+    /**
+     * Overriding ContentHandler.
+     * @param uri uri
+     * @param localName localName
+     * @param qName qName
+     * @throws SAXException SAXException
+     */
+    public void endElement(String uri, String localName, String qName)
+            throws SAXException
+    {
+        super.endElement(uri, localName, qName);
+        state = state.pop();
+    }
+
+    /**
+     * Gets the XPath expression that points to the current location.
+     * Throws a new IllegalStateException if the component is not
+     * parsing a document.
+     * @return The XPath expression
+     */
+    public final String getXPath()
+    {
+        if ( state == null )
+        {
+            throw new IllegalStateException(
+                "startDocument event is not invoked");
+        }
+        return state.getXPath();
+    }
+
+    private static Integer getInt(int i)
+    {
+        if ( i < ints.length )
+        {
+            return ints[i];
+        } else {
+            return new Integer(i);
+        }
+    }
+
+    private static final class State
+    {
+
+        private final Map counter = new HashMap();
+        private final State parent;
+        private State child;
+        private String currentName;
+
+        State( State newParent )
+        {
+            this.parent = newParent;
+        }
+
+        protected State push( String rawName )
+        {
+            count(rawName);
+            currentName = rawName;
+            if ( child == null )
+            {
+                child = new State(this);
+            } else {
+                child.reset();
+            }
+            return child;
+        }
+
+        protected State pop()
+        {
+            parent.currentName = null;
+            return parent;
+        }
+
+        private void count( String rawName )
+        {
+            Integer i = (Integer) counter.get(rawName);
+            if ( i == null )
+            {
+                i = getInt(1);
+            } else {
+                i = getInt(i.intValue() + 1);
+            }
+            counter.put(rawName, i);
+        }
+
+        private void reset()
+        {
+            counter.clear();
+            currentName = null;
+        }
+
+        private String getXPath()
+        {
+            String xPath;
+            if ( parent == null ) // root
+            {
+                xPath = "/";
+                if ( currentName != null)
+                {
+                    xPath += currentName;
+                }
+            } else { // child node
+                xPath = parent.getXPath();
+                if ( currentName != null )
+                {
+                    xPath += '/' + currentName;
+                    Integer i = (Integer) counter.get(currentName);
+                    xPath += '[' + i.toString() + ']';
+                }
+            }
+            return xPath;
+        }
+
+    }
+
+}