Show XPath location of an error
git-svn-id: https://svn.apache.org/repos/asf/maven/maven-1/plugins/trunk@306542 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
1 parent
652d1a563d
commit
f0167d57a5
2 files changed
+311
-73
No files matched your search
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user