FileDocCategorySizeDatePackage
SAXFactoryImpl.javaAPI DocAndroid 1.5 API3776Wed May 06 22:41:42 BST 2009org.ccil.cowan.tagsoup.jaxp

SAXFactoryImpl.java

// 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;
    }
}