// This file is part of TagSoup and is Copyright 2002-2008 by John Cowan. // // TagSoup is licensed under the Apache License, // Version 2.0. You may obtain a copy of this license at // http://www.apache.org/licenses/LICENSE-2.0 . You may also have // additional legal rights not granted by this license. // // TagSoup is distributed in the hope that it will be useful, but // unless required by applicable law or agreed to in writing, TagSoup // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS // OF ANY KIND, either express or implied; not even the implied warranty // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. package org.ccil.cowan.tagsoup.jaxp; import java.util.*; import javax.xml.parsers.*; import org.xml.sax.*; /** * This is a simple implementation of JAXP {@link SAXParserFactory}, * to allow easier integration of TagSoup with the default JDK * xml processing stack. * * @author Tatu Saloranta (cowtowncoder@yahoo.com) */ public class SAXFactoryImpl extends SAXParserFactory { /** * The easiest way to test validity of features to set is to use * a prototype object. Currently this is actually not a real prototype, * in the sense that the configuration is actually passed separately * (as opposed to instantiating new readers from this prototype), but * this could be changed in future, if TagSoup parser object allowed * cloning. */ private SAXParserImpl prototypeParser = null; /** * This Map contains explicitly set features that can be succesfully * set for XMLReader instances. Temporary storage is needed due to * JAXP design: multiple readers can be instantiated from a single * factory, and settings can be changed between instantiations. *<p> * Note that we wouldn't need this map if we could create instances * directly using the prototype instance. */ private HashMap features = null; public SAXFactoryImpl() { super(); } // // // JAXP API implementation: /** * Creates a new instance of <code>SAXParser</code> using the currently * configured factory parameters. */ public SAXParser newSAXParser() throws ParserConfigurationException { try { return SAXParserImpl.newInstance(features); } catch (SAXException se) { // Translate to ParserConfigurationException throw new ParserConfigurationException(se.getMessage()); } } /** * Defines that the specified feature is to enabled/disabled (as * per second argument) on reader instances created by this * factory. */ public void setFeature(String name, boolean value) throws ParserConfigurationException, SAXNotRecognizedException, SAXNotSupportedException { // First, let's see if it's a valid call getPrototype().setFeature(name, value); // If not, exception was thrown: so we are good now: if (features == null) { // Let's retain the ordering as well features = new LinkedHashMap(); } features.put(name, value ? Boolean.TRUE : Boolean.FALSE); } /** * Returns whether the specified property will be enabled or disabled * on reader instances constructed by this factory. */ public boolean getFeature(String name) throws ParserConfigurationException, SAXNotRecognizedException, SAXNotSupportedException { return getPrototype().getFeature(name); } // // // Internal methods private SAXParserImpl getPrototype() { if (prototypeParser == null) { prototypeParser = new SAXParserImpl(); } return prototypeParser; } }