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

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