Commits

Anonymous committed b138ed9

support for custom XML parser as requested by Jive (due to lame bugs in the Resin XML parser)

git-svn-id: http://svn.opensymphony.com/svn/xwork/branches/xwork_1-2@1088e221344d-f017-0410-9bd5-d282ab1896d7

Comments (0)

Files changed (1)

src/java/com/opensymphony/xwork/util/DomHelper.java

 /*
  * 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.
 import com.opensymphony.xwork.util.location.Location;
 import com.opensymphony.xwork.util.location.LocationAttributes;
 import com.opensymphony.xwork.XworkException;
+import com.opensymphony.xwork.ObjectFactory;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 public class DomHelper {
 
     private static final Log LOG = LogFactory.getLog(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
     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
      * @param dtdMappings a map of DTD names and public ids
      */
     public static Document parse(InputSource inputSource, Map dtdMappings) {
-                
-        SAXParserFactory factory = SAXParserFactory.newInstance();
+        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 <code>DOMBuilder</code> is a utility class that will generate a W3C
      * DOM Document from SAX events.
      * @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
      */
     static public class DOMBuilder implements ContentHandler {
-    
+
         /** The default transformer factory shared by all instances */
-        protected static final SAXTransformerFactory FACTORY = (SAXTransformerFactory) TransformerFactory.newInstance();
-    
+        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.
          */
             this.parentNode = parentNode;
             setup();
         }
-    
+
         /**
          * Setup this instance transformer and result objects.
          */
                 throw new XworkException("Fatal-Error: Unable to get transformer handler", local);
             }
         }
-    
+
         /**
          * Return the newly built Document.
          */
                 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 void setDocumentLocator(Locator locator) {
             nextHandler.setDocumentLocator(locator);
         }
-        
+
         public void startDocument() throws SAXException {
             nextHandler.startDocument();
         }
-        
+
         public void endDocument() throws SAXException {
             nextHandler.endDocument();
         }
         public void skippedEntity(String arg0) throws SAXException {
             nextHandler.skippedEntity(arg0);
         }
-        
+
         public InputSource resolveEntity(String publicId, String systemId) {
             if (dtdMappings != null && dtdMappings.containsKey(publicId)) {
                 String val = dtdMappings.get(publicId).toString();
             }
             return null;
         }
-        
+
         public void warning(SAXParseException exception) {
         }
 
         public void error(SAXParseException exception) throws SAXException {
-            LOG.error(exception.getMessage() + " at (" + exception.getPublicId() + ":" + 
+            LOG.error(exception.getMessage() + " at (" + exception.getPublicId() + ":" +
                 exception.getLineNumber() + ":" + exception.getColumnNumber() + ")");
             throw exception;
         }
 
         public void fatalError(SAXParseException exception) throws SAXException {
-            LOG.fatal(exception.getMessage() + " at (" + exception.getPublicId() + ":" + 
+            LOG.fatal(exception.getMessage() + " at (" + exception.getPublicId() + ":" +
                 exception.getLineNumber() + ":" + exception.getColumnNumber() + ")");
             throw exception;
         }
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.