com.opensymphony.xwork2.util.DomHelper Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of xwork Show documentation
Show all versions of xwork Show documentation
XWork is an command-pattern framework that is used to power WebWork
as well as other applications. XWork provides an Inversion of Control
container, a powerful expression language, data type conversion,
validation, and pluggable configuration.
/*
* Copyright 1999-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.
*/
package com.opensymphony.xwork2.util;
import com.opensymphony.xwork2.ObjectFactory;
import com.opensymphony.xwork2.XWorkException;
import com.opensymphony.xwork2.util.location.Location;
import com.opensymphony.xwork2.util.location.LocationAttributes;
import com.opensymphony.xwork2.util.logging.Logger;
import com.opensymphony.xwork2.util.logging.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import java.util.Map;
/**
* Helper class to create and retrieve information from location-enabled
* DOM-trees.
*
* @since 1.2
*/
public class DomHelper {
private static final Logger LOG = LoggerFactory.getLogger(DomHelper.class);
public static final String XMLNS_URI = "http://www.w3.org/2000/xmlns/";
public static Location getLocationObject(Element element) {
return LocationAttributes.getLocation(element);
}
/**
* Creates a W3C Document that remembers the location of each element in
* the source file. The location of element nodes can then be retrieved
* using the {@link #getLocationObject(Element)} method.
*
* @param inputSource the inputSource to read the document from
*/
public static Document parse(InputSource inputSource) {
return parse(inputSource, null);
}
/**
* Creates a W3C Document that remembers the location of each element in
* the source file. The location of element nodes can then be retrieved
* using the {@link #getLocationObject(Element)} method.
*
* @param inputSource the inputSource to read the document from
* @param dtdMappings a map of DTD names and public ids
*/
public static Document parse(InputSource inputSource, Map dtdMappings) {
SAXParserFactory factory = null;
String parserProp = System.getProperty("xwork.saxParserFactory");
if (parserProp != null) {
try {
Class clazz = ObjectFactory.getObjectFactory().getClassInstance(parserProp);
factory = (SAXParserFactory) clazz.newInstance();
}
catch (ClassNotFoundException e) {
LOG.error("Unable to load saxParserFactory set by system property 'xwork.saxParserFactory': " + parserProp, e);
}
catch (Exception e) {
LOG.error("Unable to load saxParserFactory set by system property 'xwork.saxParserFactory': " + parserProp, e);
}
}
if (factory == null) {
factory = SAXParserFactory.newInstance();
}
factory.setValidating((dtdMappings != null));
factory.setNamespaceAware(true);
SAXParser parser = null;
try {
parser = factory.newSAXParser();
} catch (Exception ex) {
throw new XWorkException("Unable to create SAX parser", ex);
}
DOMBuilder builder = new DOMBuilder();
// Enhance the sax stream with location information
ContentHandler locationHandler = new LocationAttributes.Pipe(builder);
try {
parser.parse(inputSource, new StartHandler(locationHandler, dtdMappings));
} catch (Exception ex) {
throw new XWorkException(ex);
}
return builder.getDocument();
}
/**
* The DOMBuilder
is a utility class that will generate a W3C
* DOM Document from SAX events.
*
* @author Carsten Ziegeler
*/
static public class DOMBuilder implements ContentHandler {
/** The default transformer factory shared by all instances */
protected static SAXTransformerFactory FACTORY;
/** The transformer factory */
protected SAXTransformerFactory factory;
/** The result */
protected DOMResult result;
/** The parentNode */
protected Node parentNode;
protected ContentHandler nextHandler;
static {
String parserProp = System.getProperty("xwork.saxTransformerFactory");
if (parserProp != null) {
try {
Class clazz = ObjectFactory.getObjectFactory().getClassInstance(parserProp);
FACTORY = (SAXTransformerFactory) clazz.newInstance();
}
catch (ClassNotFoundException e) {
LOG.error("Unable to load SAXTransformerFactory set by system property 'xwork.saxTransformerFactory': " + parserProp, e);
}
catch (Exception e) {
LOG.error("Unable to load SAXTransformerFactory set by system property 'xwork.saxTransformerFactory': " + parserProp, e);
}
}
if (FACTORY == null) {
FACTORY = (SAXTransformerFactory) TransformerFactory.newInstance();
}
}
/**
* Construct a new instance of this DOMBuilder.
*/
public DOMBuilder() {
this((Node) null);
}
/**
* Construct a new instance of this DOMBuilder.
*/
public DOMBuilder(SAXTransformerFactory factory) {
this(factory, null);
}
/**
* Constructs a new instance that appends nodes to the given parent node.
*/
public DOMBuilder(Node parentNode) {
this(null, parentNode);
}
/**
* Construct a new instance of this DOMBuilder.
*/
public DOMBuilder(SAXTransformerFactory factory, Node parentNode) {
this.factory = factory == null? FACTORY: factory;
this.parentNode = parentNode;
setup();
}
/**
* Setup this instance transformer and result objects.
*/
private void setup() {
try {
TransformerHandler handler = this.factory.newTransformerHandler();
nextHandler = handler;
if (this.parentNode != null) {
this.result = new DOMResult(this.parentNode);
} else {
this.result = new DOMResult();
}
handler.setResult(this.result);
} catch (javax.xml.transform.TransformerException local) {
throw new XWorkException("Fatal-Error: Unable to get transformer handler", local);
}
}
/**
* Return the newly built Document.
*/
public Document getDocument() {
if (this.result == null || this.result.getNode() == null) {
return null;
} else if (this.result.getNode().getNodeType() == Node.DOCUMENT_NODE) {
return (Document) this.result.getNode();
} else {
return this.result.getNode().getOwnerDocument();
}
}
public void setDocumentLocator(Locator locator) {
nextHandler.setDocumentLocator(locator);
}
public void startDocument() throws SAXException {
nextHandler.startDocument();
}
public void endDocument() throws SAXException {
nextHandler.endDocument();
}
public void startElement(String uri, String loc, String raw, Attributes attrs) throws SAXException {
nextHandler.startElement(uri, loc, raw, attrs);
}
public void endElement(String arg0, String arg1, String arg2) throws SAXException {
nextHandler.endElement(arg0, arg1, arg2);
}
public void startPrefixMapping(String arg0, String arg1) throws SAXException {
nextHandler.startPrefixMapping(arg0, arg1);
}
public void endPrefixMapping(String arg0) throws SAXException {
nextHandler.endPrefixMapping(arg0);
}
public void characters(char[] arg0, int arg1, int arg2) throws SAXException {
nextHandler.characters(arg0, arg1, arg2);
}
public void ignorableWhitespace(char[] arg0, int arg1, int arg2) throws SAXException {
nextHandler.ignorableWhitespace(arg0, arg1, arg2);
}
public void processingInstruction(String arg0, String arg1) throws SAXException {
nextHandler.processingInstruction(arg0, arg1);
}
public void skippedEntity(String arg0) throws SAXException {
nextHandler.skippedEntity(arg0);
}
}
public static class StartHandler extends DefaultHandler {
private ContentHandler nextHandler;
private Map dtdMappings;
/**
* Create a filter that is chained to another handler.
* @param next the next handler in the chain.
*/
public StartHandler(ContentHandler next, Map dtdMappings) {
nextHandler = next;
this.dtdMappings = dtdMappings;
}
@Override
public void setDocumentLocator(Locator locator) {
nextHandler.setDocumentLocator(locator);
}
@Override
public void startDocument() throws SAXException {
nextHandler.startDocument();
}
@Override
public void endDocument() throws SAXException {
nextHandler.endDocument();
}
@Override
public void startElement(String uri, String loc, String raw, Attributes attrs) throws SAXException {
nextHandler.startElement(uri, loc, raw, attrs);
}
@Override
public void endElement(String arg0, String arg1, String arg2) throws SAXException {
nextHandler.endElement(arg0, arg1, arg2);
}
@Override
public void startPrefixMapping(String arg0, String arg1) throws SAXException {
nextHandler.startPrefixMapping(arg0, arg1);
}
@Override
public void endPrefixMapping(String arg0) throws SAXException {
nextHandler.endPrefixMapping(arg0);
}
@Override
public void characters(char[] arg0, int arg1, int arg2) throws SAXException {
nextHandler.characters(arg0, arg1, arg2);
}
@Override
public void ignorableWhitespace(char[] arg0, int arg1, int arg2) throws SAXException {
nextHandler.ignorableWhitespace(arg0, arg1, arg2);
}
@Override
public void processingInstruction(String arg0, String arg1) throws SAXException {
nextHandler.processingInstruction(arg0, arg1);
}
@Override
public void skippedEntity(String arg0) throws SAXException {
nextHandler.skippedEntity(arg0);
}
@Override
public InputSource resolveEntity(String publicId, String systemId) {
if (dtdMappings != null && dtdMappings.containsKey(publicId)) {
String val = dtdMappings.get(publicId).toString();
return new InputSource(ClassLoaderUtil.getResourceAsStream(val, DomHelper.class));
}
return null;
}
@Override
public void warning(SAXParseException exception) {
}
@Override
public void error(SAXParseException exception) throws SAXException {
LOG.error(exception.getMessage() + " at (" + exception.getPublicId() + ":" +
exception.getLineNumber() + ":" + exception.getColumnNumber() + ")", exception);
throw exception;
}
@Override
public void fatalError(SAXParseException exception) throws SAXException {
LOG.fatal(exception.getMessage() + " at (" + exception.getPublicId() + ":" +
exception.getLineNumber() + ":" + exception.getColumnNumber() + ")", exception);
throw exception;
}
}
}