141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project// This file is part of TagSoup and is Copyright 2002-2008 by John Cowan.
241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project//
341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project// TagSoup is licensed under the Apache License,
441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project// Version 2.0.  You may obtain a copy of this license at
541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project// http://www.apache.org/licenses/LICENSE-2.0 .  You may also have
641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project// additional legal rights not granted by this license.
741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project//
841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project// TagSoup is distributed in the hope that it will be useful, but
941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project// unless required by applicable law or agreed to in writing, TagSoup
1041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
1141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project// OF ANY KIND, either express or implied; not even the implied warranty
1241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
1441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Projectpackage org.ccil.cowan.tagsoup.jaxp;
1541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
1641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Projectimport java.util.*;
1741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Projectimport javax.xml.parsers.*;
1841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
1941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Projectimport org.xml.sax.*;
2041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
2141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project/**
2241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project * This is a simple implementation of JAXP {@link SAXParserFactory},
2341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project * to allow easier integration of TagSoup with the default JDK
2441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project * xml processing stack.
2541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project *
2641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project * @author Tatu Saloranta (cowtowncoder@yahoo.com)
2741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project */
2841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Projectpublic class SAXFactoryImpl
2941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project    extends SAXParserFactory
3041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project{
3141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project    /**
3241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project     * The easiest way to test validity of features to set is to use
3341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project     * a prototype object. Currently this is actually not a real prototype,
3441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project     * in the sense that the configuration is actually passed separately
3541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project     * (as opposed to instantiating new readers from this prototype), but
3641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project     * this could be changed in future, if TagSoup parser object allowed
3741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project     * cloning.
3841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project     */
3941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project    private SAXParserImpl prototypeParser = null;
4041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
4141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project    /**
4241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project     * This Map contains explicitly set features that can be succesfully
4341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project     * set for XMLReader instances. Temporary storage is needed due to
4441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project     * JAXP design: multiple readers can be instantiated from a single
4541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project     * factory, and settings can be changed between instantiations.
4641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project     *<p>
4741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project     * Note that we wouldn't need this map if we could create instances
4841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project     * directly using the prototype instance.
4941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project     */
5041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project    private HashMap features = null;
5141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
5241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project    public SAXFactoryImpl()
5341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project    {
5441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project        super();
5541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project    }
5641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
5741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project    // // // JAXP API implementation:
5841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
5941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project    /**
6041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project     * Creates a new instance of <code>SAXParser</code> using the currently
6141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project     * configured factory parameters.
6241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project     */
6341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project    public SAXParser newSAXParser()
6441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project        throws ParserConfigurationException
6541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project    {
6641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project        try {
6741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project            return SAXParserImpl.newInstance(features);
6841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project        } catch (SAXException se) {
6941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project            // Translate to ParserConfigurationException
7041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project            throw new ParserConfigurationException(se.getMessage());
7141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project        }
7241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project    }
7341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
7441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project    /**
7541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project     * Defines that the specified feature is to enabled/disabled (as
7641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project     * per second argument) on reader instances created by this
7741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project     * factory.
7841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project     */
7941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project    public void setFeature(String name, boolean value)
8041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project        throws ParserConfigurationException, SAXNotRecognizedException,
8141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		SAXNotSupportedException
8241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project    {
8341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project        // First, let's see if it's a valid call
8441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project        getPrototype().setFeature(name, value);
8541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
8641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project        // If not, exception was thrown: so we are good now:
8741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project        if (features == null) {
8841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project            // Let's retain the ordering as well
8941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project            features = new LinkedHashMap();
9041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project        }
9141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project        features.put(name, value ? Boolean.TRUE : Boolean.FALSE);
9241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project    }
9341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
9441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project    /**
9541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project     * Returns whether the specified property will be enabled or disabled
9641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project     * on reader instances constructed by this factory.
9741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project     */
9841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project    public boolean getFeature(String name)
9941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project        throws ParserConfigurationException, SAXNotRecognizedException,
10041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		SAXNotSupportedException
10141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project    {
10241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project        return getPrototype().getFeature(name);
10341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project    }
10441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
10541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project    // // // Internal methods
10641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
10741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project    private SAXParserImpl getPrototype()
10841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project    {
10941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project        if (prototypeParser == null) {
11041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project            prototypeParser = new SAXParserImpl();
11141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project        }
11241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project        return prototypeParser;
11341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project    }
11441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project}
115