package com.sun.xacml.support; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import org.apache.log4j.Logger; import org.w3c.dom.Node; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import com.sun.org.apache.xerces.internal.parsers.DOMParser; import com.sun.org.apache.xerces.internal.xni.Augmentations; import com.sun.org.apache.xerces.internal.xni.NamespaceContext; import com.sun.org.apache.xerces.internal.xni.QName; import com.sun.org.apache.xerces.internal.xni.XMLAttributes; import com.sun.org.apache.xerces.internal.xni.XMLLocator; import com.sun.org.apache.xerces.internal.xni.XNIException; import com.sun.xacml.Constants; /** * * Class which is able to keep track of the line numbers * * */ public class DOMLinesParser extends DOMParser { private XMLLocator locator; private boolean curEleNodeError = false; private static Logger logger = Logger.getLogger(DOMLinesParser.class); private String currentFile = null; public DOMLinesParser() { } public void parse (File file) throws SAXException, IOException { parse(new InputSource(new FileInputStream(file)), file.getPath()); } public void parse (InputStream input, String fileName) throws SAXException, IOException { parse(new InputSource(input), fileName); } public void parse (InputStream input) throws SAXException, IOException { parse(new InputSource(input), null); } public void parse (InputSource input) throws SAXException, IOException { parse(input, null); } public static boolean checkFeatureAvailable() { try { DOMParser tmpParser = new DOMParser(); tmpParser.setFeature( "http://apache.org/xml/features/dom/defer-node-expansion", false ); return true; } catch (Exception e) { return false; } } public void parse (InputSource input, String fileName) throws SAXException, IOException { logger.debug("Start parsing policy file " + fileName + " with line numbers"); this.currentFile = fileName; try { this.setFeature( "http://apache.org/xml/features/dom/defer-node-expansion", false ); curEleNodeError = false; } catch (Exception e) { logger.error("Could not set feature required for keeping track of line numbers!"); curEleNodeError = true; } super.parse(input); } @Override public void startElement(QName elementQName, XMLAttributes attrList, Augmentations augs) throws XNIException { super.startElement(elementQName, attrList, augs); Node node = null; try { node = (Node) this.getProperty( "http://apache.org/xml/properties/dom/current-element-node" ); } catch( SAXException ex ) { if ( ! curEleNodeError ) { curEleNodeError = true; logger.error("Could not retreive node for setting current start line: " + ex.getMessage(), ex); } } if( node != null ) { node.setUserData( Constants.LINE_NUMBER, new Integer( locator.getLineNumber() ), null ); // Save location String into node if ( this.currentFile != null) { node.setUserData( Constants.SOURCE_FILE, this.currentFile, null); } } } //startElement /* We override startDocument callback from DocumentHandler */ public void startDocument(XMLLocator locator, String encoding, NamespaceContext namespaceContext, Augmentations augs) throws XNIException { super.startDocument(locator, encoding, namespaceContext, augs); this.locator = locator; Node node = null ; try { node = (Node) this.getProperty( "http://apache.org/xml/properties/dom/current-element-node" ); } catch( org.xml.sax.SAXException ex ) { if ( ! curEleNodeError ) { curEleNodeError = true; logger.error("Could not retreive node for setting current start line: " + ex.getMessage(), ex); } } if( node != null ) { node.setUserData( Constants.LINE_NUMBER, new Integer(locator.getLineNumber() ), null ); // Save location String into node if ( this.currentFile != null) { node.setUserData( Constants.SOURCE_FILE, this.currentFile, null); } } } }