Save This Page
Home » xwork-2.1.5 » com.opensymphony » xwork2 » util » [javadoc | source]
    1   /*
    2    * Copyright 1999-2005 The Apache Software Foundation.
    3    * 
    4    * Licensed under the Apache License, Version 2.0 (the "License");
    5    * you may not use this file except in compliance with the License.
    6    * You may obtain a copy of the License at
    7    * 
    8    *      http://www.apache.org/licenses/LICENSE-2.0
    9    * 
   10    * Unless required by applicable law or agreed to in writing, software
   11    * distributed under the License is distributed on an "AS IS" BASIS,
   12    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   13    * See the License for the specific language governing permissions and
   14    * limitations under the License.
   15    */
   16   package com.opensymphony.xwork2.util;
   17   
   18   import com.opensymphony.xwork2.ObjectFactory;
   19   import com.opensymphony.xwork2.XWorkException;
   20   import com.opensymphony.xwork2.util.location.Location;
   21   import com.opensymphony.xwork2.util.location.LocationAttributes;
   22   import com.opensymphony.xwork2.util.logging.Logger;
   23   import com.opensymphony.xwork2.util.logging.LoggerFactory;
   24   import org.w3c.dom.Document;
   25   import org.w3c.dom.Element;
   26   import org.w3c.dom.Node;
   27   import org.xml.sax;
   28   import org.xml.sax.helpers.DefaultHandler;
   29   
   30   import javax.xml.parsers.SAXParser;
   31   import javax.xml.parsers.SAXParserFactory;
   32   import javax.xml.transform.TransformerFactory;
   33   import javax.xml.transform.dom.DOMResult;
   34   import javax.xml.transform.sax.SAXTransformerFactory;
   35   import javax.xml.transform.sax.TransformerHandler;
   36   import java.util.Map;
   37   
   38   /**
   39    * Helper class to create and retrieve information from location-enabled
   40    * DOM-trees.
   41    *
   42    * @since 1.2
   43    */
   44   public class DomHelper {
   45   
   46       private static final Logger LOG = LoggerFactory.getLogger(DomHelper.class);
   47       
   48       public static final String XMLNS_URI = "http://www.w3.org/2000/xmlns/";
   49   
   50       public static Location getLocationObject(Element element) {
   51           return LocationAttributes.getLocation(element);
   52       }
   53   
   54       
   55       /**
   56        * Creates a W3C Document that remembers the location of each element in
   57        * the source file. The location of element nodes can then be retrieved
   58        * using the {@link #getLocationObject(Element)} method.
   59        *
   60        * @param inputSource the inputSource to read the document from
   61        */
   62       public static Document parse(InputSource inputSource) {
   63           return parse(inputSource, null);
   64       }
   65       
   66       
   67       /**
   68        * Creates a W3C Document that remembers the location of each element in
   69        * the source file. The location of element nodes can then be retrieved
   70        * using the {@link #getLocationObject(Element)} method.
   71        *
   72        * @param inputSource the inputSource to read the document from
   73        * @param dtdMappings a map of DTD names and public ids
   74        */
   75       public static Document parse(InputSource inputSource, Map<String, String> dtdMappings) {
   76                   
   77           SAXParserFactory factory = null;
   78           String parserProp = System.getProperty("xwork.saxParserFactory");
   79           if (parserProp != null) {
   80               try {
   81                   Class clazz = ObjectFactory.getObjectFactory().getClassInstance(parserProp);
   82                   factory = (SAXParserFactory) clazz.newInstance();
   83               }
   84               catch (ClassNotFoundException e) {
   85                   LOG.error("Unable to load saxParserFactory set by system property 'xwork.saxParserFactory': " + parserProp, e);
   86               }
   87               catch (Exception e) {
   88                   LOG.error("Unable to load saxParserFactory set by system property 'xwork.saxParserFactory': " + parserProp, e);
   89               }
   90           }
   91   
   92           if (factory == null) {
   93               factory = SAXParserFactory.newInstance();
   94           }
   95   
   96           factory.setValidating((dtdMappings != null));
   97           factory.setNamespaceAware(true);
   98   
   99           SAXParser parser = null;
  100           try {
  101               parser = factory.newSAXParser();
  102           } catch (Exception ex) {
  103               throw new XWorkException("Unable to create SAX parser", ex);
  104           }
  105           
  106           
  107           DOMBuilder builder = new DOMBuilder();
  108   
  109           // Enhance the sax stream with location information
  110           ContentHandler locationHandler = new LocationAttributes.Pipe(builder);
  111           
  112           try {
  113               parser.parse(inputSource, new StartHandler(locationHandler, dtdMappings));
  114           } catch (Exception ex) {
  115               throw new XWorkException(ex);
  116           }
  117           
  118           return builder.getDocument();
  119       }
  120       
  121       /**
  122        * The <code>DOMBuilder</code> is a utility class that will generate a W3C
  123        * DOM Document from SAX events.
  124        *
  125        * @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
  126        */
  127       static public class DOMBuilder implements ContentHandler {
  128       
  129           /** The default transformer factory shared by all instances */
  130           protected static SAXTransformerFactory FACTORY;
  131       
  132           /** The transformer factory */
  133           protected SAXTransformerFactory factory;
  134       
  135           /** The result */
  136           protected DOMResult result;
  137       
  138           /** The parentNode */
  139           protected Node parentNode;
  140           
  141           protected ContentHandler nextHandler;
  142       
  143           static {
  144               String parserProp = System.getProperty("xwork.saxTransformerFactory");
  145               if (parserProp != null) {
  146                   try {
  147                       Class clazz = ObjectFactory.getObjectFactory().getClassInstance(parserProp);
  148                       FACTORY = (SAXTransformerFactory) clazz.newInstance();
  149                   }
  150                   catch (ClassNotFoundException e) {
  151                       LOG.error("Unable to load SAXTransformerFactory set by system property 'xwork.saxTransformerFactory': " + parserProp, e);
  152                   }
  153                   catch (Exception e) {
  154                       LOG.error("Unable to load SAXTransformerFactory set by system property 'xwork.saxTransformerFactory': " + parserProp, e);
  155                   }
  156               }
  157   
  158               if (FACTORY == null) {
  159                    FACTORY = (SAXTransformerFactory) TransformerFactory.newInstance();
  160               }
  161           }
  162   
  163           /**
  164            * Construct a new instance of this DOMBuilder.
  165            */
  166           public DOMBuilder() {
  167               this((Node) null);
  168           }
  169       
  170           /**
  171            * Construct a new instance of this DOMBuilder.
  172            */
  173           public DOMBuilder(SAXTransformerFactory factory) {
  174               this(factory, null);
  175           }
  176       
  177           /**
  178            * Constructs a new instance that appends nodes to the given parent node.
  179            */
  180           public DOMBuilder(Node parentNode) {
  181               this(null, parentNode);
  182           }
  183       
  184           /**
  185            * Construct a new instance of this DOMBuilder.
  186            */
  187           public DOMBuilder(SAXTransformerFactory factory, Node parentNode) {
  188               this.factory = factory == null? FACTORY: factory;
  189               this.parentNode = parentNode;
  190               setup();
  191           }
  192       
  193           /**
  194            * Setup this instance transformer and result objects.
  195            */
  196           private void setup() {
  197               try {
  198                   TransformerHandler handler = this.factory.newTransformerHandler();
  199                   nextHandler = handler;
  200                   if (this.parentNode != null) {
  201                       this.result = new DOMResult(this.parentNode);
  202                   } else {
  203                       this.result = new DOMResult();
  204                   }
  205                   handler.setResult(this.result);
  206               } catch (javax.xml.transform.TransformerException local) {
  207                   throw new XWorkException("Fatal-Error: Unable to get transformer handler", local);
  208               }
  209           }
  210       
  211           /**
  212            * Return the newly built Document.
  213            */
  214           public Document getDocument() {
  215               if (this.result == null || this.result.getNode() == null) {
  216                   return null;
  217               } else if (this.result.getNode().getNodeType() == Node.DOCUMENT_NODE) {
  218                   return (Document) this.result.getNode();
  219               } else {
  220                   return this.result.getNode().getOwnerDocument();
  221               }
  222           }
  223       
  224           public void setDocumentLocator(Locator locator) {
  225               nextHandler.setDocumentLocator(locator);
  226           }
  227           
  228           public void startDocument() throws SAXException {
  229               nextHandler.startDocument();
  230           }
  231           
  232           public void endDocument() throws SAXException {
  233               nextHandler.endDocument();
  234           }
  235       
  236           public void startElement(String uri, String loc, String raw, Attributes attrs) throws SAXException {
  237               nextHandler.startElement(uri, loc, raw, attrs);
  238           }
  239       
  240           public void endElement(String arg0, String arg1, String arg2) throws SAXException {
  241               nextHandler.endElement(arg0, arg1, arg2);
  242           }
  243       
  244           public void startPrefixMapping(String arg0, String arg1) throws SAXException {
  245               nextHandler.startPrefixMapping(arg0, arg1);
  246           }
  247       
  248           public void endPrefixMapping(String arg0) throws SAXException {
  249               nextHandler.endPrefixMapping(arg0);
  250           }
  251       
  252           public void characters(char[] arg0, int arg1, int arg2) throws SAXException {
  253               nextHandler.characters(arg0, arg1, arg2);
  254           }
  255       
  256           public void ignorableWhitespace(char[] arg0, int arg1, int arg2) throws SAXException {
  257               nextHandler.ignorableWhitespace(arg0, arg1, arg2);
  258           }
  259       
  260           public void processingInstruction(String arg0, String arg1) throws SAXException {
  261               nextHandler.processingInstruction(arg0, arg1);
  262           }
  263       
  264           public void skippedEntity(String arg0) throws SAXException {
  265               nextHandler.skippedEntity(arg0);
  266           }
  267       }
  268       
  269       public static class StartHandler extends DefaultHandler {
  270           
  271           private ContentHandler nextHandler;
  272           private Map<String, String> dtdMappings;
  273           
  274           /**
  275            * Create a filter that is chained to another handler.
  276            * @param next the next handler in the chain.
  277            */
  278           public StartHandler(ContentHandler next, Map<String, String> dtdMappings) {
  279               nextHandler = next;
  280               this.dtdMappings = dtdMappings;
  281           }
  282   
  283           @Override
  284           public void setDocumentLocator(Locator locator) {
  285               nextHandler.setDocumentLocator(locator);
  286           }
  287           
  288           @Override
  289           public void startDocument() throws SAXException {
  290               nextHandler.startDocument();
  291           }
  292           
  293           @Override
  294           public void endDocument() throws SAXException {
  295               nextHandler.endDocument();
  296           }
  297   
  298           @Override
  299           public void startElement(String uri, String loc, String raw, Attributes attrs) throws SAXException {
  300               nextHandler.startElement(uri, loc, raw, attrs);
  301           }
  302   
  303           @Override
  304           public void endElement(String arg0, String arg1, String arg2) throws SAXException {
  305               nextHandler.endElement(arg0, arg1, arg2);
  306           }
  307   
  308           @Override
  309           public void startPrefixMapping(String arg0, String arg1) throws SAXException {
  310               nextHandler.startPrefixMapping(arg0, arg1);
  311           }
  312   
  313           @Override
  314           public void endPrefixMapping(String arg0) throws SAXException {
  315               nextHandler.endPrefixMapping(arg0);
  316           }
  317   
  318           @Override
  319           public void characters(char[] arg0, int arg1, int arg2) throws SAXException {
  320               nextHandler.characters(arg0, arg1, arg2);
  321           }
  322   
  323           @Override
  324           public void ignorableWhitespace(char[] arg0, int arg1, int arg2) throws SAXException {
  325               nextHandler.ignorableWhitespace(arg0, arg1, arg2);
  326           }
  327   
  328           @Override
  329           public void processingInstruction(String arg0, String arg1) throws SAXException {
  330               nextHandler.processingInstruction(arg0, arg1);
  331           }
  332   
  333           @Override
  334           public void skippedEntity(String arg0) throws SAXException {
  335               nextHandler.skippedEntity(arg0);
  336           }
  337           
  338           @Override
  339           public InputSource resolveEntity(String publicId, String systemId) {
  340               if (dtdMappings != null && dtdMappings.containsKey(publicId)) {
  341                   String val = dtdMappings.get(publicId).toString();
  342                   return new InputSource(ClassLoaderUtil.getResourceAsStream(val, DomHelper.class));
  343               }
  344               return null;
  345           }
  346           
  347           @Override
  348           public void warning(SAXParseException exception) {
  349           }
  350   
  351           @Override
  352           public void error(SAXParseException exception) throws SAXException {
  353               LOG.error(exception.getMessage() + " at (" + exception.getPublicId() + ":" + 
  354                   exception.getLineNumber() + ":" + exception.getColumnNumber() + ")", exception);
  355               throw exception;
  356           }
  357   
  358           @Override
  359           public void fatalError(SAXParseException exception) throws SAXException {
  360               LOG.fatal(exception.getMessage() + " at (" + exception.getPublicId() + ":" + 
  361                   exception.getLineNumber() + ":" + exception.getColumnNumber() + ")", exception);
  362               throw exception;
  363           }
  364       }
  365   
  366   }

Save This Page
Home » xwork-2.1.5 » com.opensymphony » xwork2 » util » [javadoc | source]