diff --git a/src/main/org/apache/tools/ant/helper/ProjectHelperImpl.java b/src/main/org/apache/tools/ant/helper/ProjectHelperImpl.java index e8eece490..a611374c0 100644 --- a/src/main/org/apache/tools/ant/helper/ProjectHelperImpl.java +++ b/src/main/org/apache/tools/ant/helper/ProjectHelperImpl.java @@ -63,15 +63,11 @@ import java.util.Locale; import org.xml.sax.Locator; import org.xml.sax.InputSource; import org.xml.sax.HandlerBase; -import org.xml.sax.SAXParseException; import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; import org.xml.sax.DocumentHandler; import org.xml.sax.AttributeList; import org.xml.sax.helpers.XMLReaderAdapter; -import javax.xml.parsers.SAXParserFactory; -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.FactoryConfigurationError; import org.apache.tools.ant.ProjectHelper; import org.apache.tools.ant.UnknownElement; import org.apache.tools.ant.Project; @@ -83,6 +79,7 @@ import org.apache.tools.ant.IntrospectionHelper; import org.apache.tools.ant.TaskContainer; import org.apache.tools.ant.Location; import org.apache.tools.ant.TaskAdapter; +import org.apache.tools.ant.util.JAXPUtils; /** * Original helper. @@ -91,12 +88,6 @@ import org.apache.tools.ant.TaskAdapter; */ public class ProjectHelperImpl extends ProjectHelper { - /** - * Parser factory to use to create parsers. - * @see #getParserFactory - */ - private static SAXParserFactory parserFactory = null; - /** * SAX 1 style parser used to parse the given file. This may * in fact be a SAX 2 XMLReader wrapped in an XMLReaderAdapter. @@ -139,11 +130,10 @@ public class ProjectHelperImpl extends ProjectHelper { buildFileParent = new File(this.buildFile.getParent()); try { - SAXParser saxParser = getParserFactory().newSAXParser(); try { - parser = saxParser.getParser(); - } catch (SAXException exc) { - parser = new XMLReaderAdapter(saxParser.getXMLReader()); + parser = JAXPUtils.getParser(); + } catch (BuildException e) { + parser = new XMLReaderAdapter(JAXPUtils.getXMLReader()); } @@ -163,11 +153,6 @@ public class ProjectHelperImpl extends ProjectHelper { parser.setErrorHandler(hb); parser.setDTDHandler(hb); parser.parse(inputSource); - } catch (ParserConfigurationException exc) { - throw new BuildException("Parser has not been configured correctly", exc); - } catch (FactoryConfigurationError e) { - throw new BuildException("XML parser has not been configured " - + "correctly: " + e.getMessage(), e); } catch (SAXParseException exc) { Location location = new Location(buildFile.toString(), exc.getLineNumber(), @@ -1151,21 +1136,6 @@ public class ProjectHelperImpl extends ProjectHelper { } } - /** - * Returns the parser factory to use. Only one parser - * factory is ever created by this method (multi-threading - * issues aside) and is then cached for future use. - * - * @return a SAXParserFactory to use within this class - */ - private static SAXParserFactory getParserFactory() { - if (parserFactory == null) { - parserFactory = SAXParserFactory.newInstance(); - } - - return parserFactory; - } - /** * Scans an attribute list for the id attribute and * stores a reference to the target object in the project if an diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/XMLValidateTask.java b/src/main/org/apache/tools/ant/taskdefs/optional/XMLValidateTask.java index 22cd3dcdb..63c176265 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/XMLValidateTask.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/XMLValidateTask.java @@ -64,10 +64,6 @@ import java.net.URL; import java.util.Vector; import java.util.Hashtable; import java.util.Enumeration; -import javax.xml.parsers.SAXParserFactory; -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.FactoryConfigurationError; import org.apache.tools.ant.AntClassLoader; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.DirectoryScanner; @@ -78,6 +74,7 @@ import org.apache.tools.ant.types.Path; import org.apache.tools.ant.types.Reference; import org.apache.tools.ant.types.XMLCatalog; import org.apache.tools.ant.types.DTDLocation; +import org.apache.tools.ant.util.JAXPUtils; import org.xml.sax.XMLReader; import org.xml.sax.EntityResolver; import org.xml.sax.Parser; @@ -96,12 +93,6 @@ import org.xml.sax.helpers.ParserAdapter; */ public class XMLValidateTask extends Task { - /** - * Parser factory to use to create parsers. - * @see #getParserFactory - */ - private static SAXParserFactory parserFactory = null; - protected static String INIT_FAILED_MSG = "Could not start xml validation: "; @@ -294,20 +285,10 @@ public class XMLValidateTask extends Task { Object reader = null; if (readerClassName == null) { - // use JAXP try { - SAXParser saxParser = getParserFactory().newSAXParser(); - try { - reader = saxParser.getXMLReader(); - } catch (SAXException exc) { - reader = saxParser.getParser(); - } - } catch (ParserConfigurationException e) { - throw new BuildException(INIT_FAILED_MSG + e.getMessage(), - e, getLocation()); - } catch (SAXException e) { - throw new BuildException(INIT_FAILED_MSG + e.getMessage(), - e, getLocation()); + reader = JAXPUtils.getXMLReader(); + } catch (BuildException exc) { + reader = JAXPUtils.getParser(); } } else { @@ -372,21 +353,6 @@ public class XMLValidateTask extends Task { } } - /** - * Returns the parser factory to use. Only one parser - * factory is ever created by this method (multi-threading - * issues aside) and is then cached for future use. - * - * @return a SAXParserFactory to use within this class - */ - private static SAXParserFactory getParserFactory() { - if (parserFactory == null) { - parserFactory = SAXParserFactory.newInstance(); - } - - return parserFactory; - } - /* * set a feature on the parser. * TODO: find a way to set any feature from build.xml diff --git a/src/main/org/apache/tools/ant/util/JAXPUtils.java b/src/main/org/apache/tools/ant/util/JAXPUtils.java new file mode 100644 index 000000000..840daa566 --- /dev/null +++ b/src/main/org/apache/tools/ant/util/JAXPUtils.java @@ -0,0 +1,183 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Ant", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.tools.ant.util; + +import org.apache.tools.ant.BuildException; + +import org.xml.sax.Parser; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; + +import javax.xml.parsers.SAXParserFactory; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.FactoryConfigurationError; + +/** + * Collection of helper methods that retrieve a ParserFactory or + * Parsers and Readers. + * + *

This class will create only a single factory instance.

+ * + * @author Stefan Bodewig + * + * @since Ant 1.5 + */ +public class JAXPUtils { + + /** + * Parser factory to use to create parsers. + * @see #getParserFactory + * + * @since Ant 1.5 + */ + private static SAXParserFactory parserFactory = null; + + /** + * Returns the parser factory to use. Only one parser factory is + * ever created by this method and is then cached for future use. + * + * @return a SAXParserFactory to use + * + * @since Ant 1.5 + */ + public synchronized static SAXParserFactory getParserFactory() + throws BuildException { + + if (parserFactory == null) { + parserFactory = newParserFactory(); + } + return parserFactory; + } + + /** + * Returns a new parser factory instance. + * + * @since Ant 1.5 + */ + public static SAXParserFactory newParserFactory() throws BuildException { + + try { + return SAXParserFactory.newInstance(); + } catch (FactoryConfigurationError e) { + throw new BuildException("XML parser factory has not been " + + "configured correctly: " + + e.getMessage(), e); + } + } + + /** + * Returns a newly created SAX 1 Parser, using the default parser + * factory. + * + * @return a SAX 1 Parser. + * @see #getParserFactory + * @since Ant 1.5 + */ + public static Parser getParser() throws BuildException { + try { + return newSAXParser().getParser(); + } catch (SAXException e) { + throw convertToBuildException(e); + } + } + + /** + * Returns a newly created SAX 2 XMLReader, using the default parser + * factory. + * + * @return a SAX 2 XMLReader. + * @see #getParserFactory + * @since Ant 1.5 + */ + public static XMLReader getXMLReader() throws BuildException { + try { + return newSAXParser().getXMLReader(); + } catch (SAXException e) { + throw convertToBuildException(e); + } + } + + /** + * @return a new SAXParser instance as helper for getParser and + * getXMLReader. + * + * @since Ant 1.5 + */ + private static SAXParser newSAXParser() throws BuildException { + try { + return getParserFactory().newSAXParser(); + } catch (ParserConfigurationException e) { + throw new BuildException("Cannot create parser for the given " + + "configuration: " + e.getMessage(), e); + } catch (SAXException e) { + throw convertToBuildException(e); + } + } + + /** + * Translate a SAXException into a BuildException + * + * @since Ant 1.5 + */ + private static BuildException convertToBuildException(SAXException e) { + Exception nested = e.getException(); + if (nested != null) { + return new BuildException(nested); + } else { + return new BuildException(e); + } + } + +}