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 Project//
1541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project// The TagSoup parser
1641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
1741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Projectpackage org.ccil.cowan.tagsoup;
1841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Projectimport java.util.HashMap;
1941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Projectimport java.util.ArrayList;
2041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Projectimport java.io.*;
2141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Projectimport java.net.URL;
2241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Projectimport java.net.URLConnection;
2341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Projectimport org.xml.sax.*;
2441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Projectimport org.xml.sax.helpers.DefaultHandler;
2541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Projectimport org.xml.sax.ext.LexicalHandler;
2641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
2741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
2841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project/**
2941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source ProjectThe SAX parser class.
3041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project**/
3141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Projectpublic class Parser extends DefaultHandler implements ScanHandler, XMLReader, LexicalHandler {
3241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
3341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	// XMLReader implementation
3441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
3541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private ContentHandler theContentHandler = this;
3641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private LexicalHandler theLexicalHandler = this;
3741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private DTDHandler theDTDHandler = this;
3841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private ErrorHandler theErrorHandler = this;
3941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private EntityResolver theEntityResolver = this;
4041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private Schema theSchema;
4141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private Scanner theScanner;
4241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private AutoDetector theAutoDetector;
4341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
4441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	// Default values for feature flags
4541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
4641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static boolean DEFAULT_NAMESPACES = true;
4741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static boolean DEFAULT_IGNORE_BOGONS = false;
4841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static boolean DEFAULT_BOGONS_EMPTY = false;
4941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project        private static boolean DEFAULT_ROOT_BOGONS = true;
5041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static boolean DEFAULT_DEFAULT_ATTRIBUTES = true;
5141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static boolean DEFAULT_TRANSLATE_COLONS = false;
5241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static boolean DEFAULT_RESTART_ELEMENTS = true;
5341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static boolean DEFAULT_IGNORABLE_WHITESPACE = false;
5441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static boolean DEFAULT_CDATA_ELEMENTS = true;
5541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
5641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	// Feature flags.
5741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
5841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private boolean namespaces = DEFAULT_NAMESPACES;
5941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private boolean ignoreBogons = DEFAULT_IGNORE_BOGONS;
6041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private boolean bogonsEmpty = DEFAULT_BOGONS_EMPTY;
6141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project        private boolean rootBogons = DEFAULT_ROOT_BOGONS;
6241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private boolean defaultAttributes = DEFAULT_DEFAULT_ATTRIBUTES;
6341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private boolean translateColons = DEFAULT_TRANSLATE_COLONS;
6441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private boolean restartElements = DEFAULT_RESTART_ELEMENTS;
6541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private boolean ignorableWhitespace = DEFAULT_IGNORABLE_WHITESPACE;
6641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private boolean CDATAElements = DEFAULT_CDATA_ELEMENTS;
6741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
6841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	/**
6941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	A value of "true" indicates namespace URIs and unprefixed local
7041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	names for element and attribute names will be available.
7141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	**/
7241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public final static String namespacesFeature =
7341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		"http://xml.org/sax/features/namespaces";
7441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
7541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	/**
7641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	A value of "true" indicates that XML qualified names (with prefixes)
7741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	and attributes (including xmlns* attributes) will be available.
7841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	We don't support this value.
7941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	**/
8041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public final static String namespacePrefixesFeature =
8141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		"http://xml.org/sax/features/namespace-prefixes";
8241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
8341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	/**
8441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	Reports whether this parser processes external general entities
8541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	(it doesn't).
8641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	**/
8741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public final static String externalGeneralEntitiesFeature =
8841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		"http://xml.org/sax/features/external-general-entities";
8941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
9041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	/**
9141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	Reports whether this parser processes external parameter entities
9241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	(it doesn't).
9341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	**/
9441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public final static String externalParameterEntitiesFeature =
9541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		"http://xml.org/sax/features/external-parameter-entities";
9641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
9741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	/**
9841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	May be examined only during a parse, after the startDocument()
9941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	callback has been completed; read-only. The value is true if
10041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	the document specified standalone="yes" in its XML declaration,
10141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	and otherwise is false.  (It's always false.)
10241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	**/
10341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public final static String isStandaloneFeature =
10441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		"http://xml.org/sax/features/is-standalone";
10541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
10641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	/**
10741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	A value of "true" indicates that the LexicalHandler will report
10841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	the beginning and end of parameter entities (it won't).
10941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	**/
11041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public final static String lexicalHandlerParameterEntitiesFeature =
11141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		"http://xml.org/sax/features/lexical-handler/parameter-entities";
11241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
11341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	/**
11441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	A value of "true" indicates that system IDs in declarations will
11541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	be absolutized (relative to their base URIs) before reporting.
11641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	(This returns true but doesn't actually do anything.)
11741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	**/
11841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public final static String resolveDTDURIsFeature =
11941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		"http://xml.org/sax/features/resolve-dtd-uris";
12041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
12141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	/**
12241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	Has a value of "true" if all XML names (for elements,
12341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	prefixes, attributes, entities, notations, and local
12441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	names), as well as Namespace URIs, will have been interned
12541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	using java.lang.String.intern. This supports fast testing of
12641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	equality/inequality against string constants, rather than forcing
12741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	slower calls to String.equals().  (We always intern.)
12841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	**/
12941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public final static String stringInterningFeature =
13041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		"http://xml.org/sax/features/string-interning";
13141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
13241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	/**
13341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	Returns "true" if the Attributes objects passed by this
13441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	parser in ContentHandler.startElement() implement the
13541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	org.xml.sax.ext.Attributes2 interface.	(They don't.)
13641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	**/
13741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
13841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public final static String useAttributes2Feature =
13941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		"http://xml.org/sax/features/use-attributes2";
14041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
14141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	/**
14241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	Returns "true" if the Locator objects passed by this parser
14341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	in ContentHandler.setDocumentLocator() implement the
14441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	org.xml.sax.ext.Locator2 interface.  (They don't.)
14541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	**/
14641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public final static String useLocator2Feature =
14741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		"http://xml.org/sax/features/use-locator2";
14841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
14941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	/**
15041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	Returns "true" if, when setEntityResolver is given an object
15141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	implementing the org.xml.sax.ext.EntityResolver2 interface,
15241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	those new methods will be used.  (They won't be.)
15341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	**/
15441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public final static String useEntityResolver2Feature =
15541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		"http://xml.org/sax/features/use-entity-resolver2";
15641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
15741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	/**
15841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	Controls whether the parser is reporting all validity errors
15941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	(We don't report any validity errors.)
16041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	**/
16141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public final static String validationFeature =
16241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		"http://xml.org/sax/features/validation";
16341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
16441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	/**
16541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	Controls whether the parser reports Unicode normalization
16641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	errors as described in section 2.13 and Appendix B of the XML
16741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	1.1 Recommendation.  (We don't normalize.)
16841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	**/
16941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public final static String unicodeNormalizationCheckingFeature =
17041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project"http://xml.org/sax/features/unicode-normalization-checking";
17141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
17241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	/**
17341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	Controls whether, when the namespace-prefixes feature is set,
17441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	the parser treats namespace declaration attributes as being in
17541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	the http://www.w3.org/2000/xmlns/ namespace.  (It doesn't.)
17641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	**/
17741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public final static String xmlnsURIsFeature =
17841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		"http://xml.org/sax/features/xmlns-uris";
17941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
18041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	/**
18141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	Returns "true" if the parser supports both XML 1.1 and XML 1.0.
18241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	(Always false.)
18341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	**/
18441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public final static String XML11Feature =
18541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		"http://xml.org/sax/features/xml-1.1";
18641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
18741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	/**
18841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	A value of "true" indicates that the parser will ignore
18941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	unknown elements.
19041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	**/
19141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public final static String ignoreBogonsFeature =
19241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		"http://www.ccil.org/~cowan/tagsoup/features/ignore-bogons";
19341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
19441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	/**
19541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	A value of "true" indicates that the parser will give unknown
19641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	elements a content model of EMPTY; a value of "false", a
19741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	content model of ANY.
19841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	**/
19941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public final static String bogonsEmptyFeature =
20041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		"http://www.ccil.org/~cowan/tagsoup/features/bogons-empty";
20141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
20241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	/**
20341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	A value of "true" indicates that the parser will allow unknown
20441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	elements to be the root element.
20541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	**/
20641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public final static String rootBogonsFeature =
20741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		"http://www.ccil.org/~cowan/tagsoup/features/root-bogons";
20841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
20941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	/**
21041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	A value of "true" indicates that the parser will return default
21141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	attribute values for missing attributes that have default values.
21241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	**/
21341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public final static String defaultAttributesFeature =
21441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		"http://www.ccil.org/~cowan/tagsoup/features/default-attributes";
21541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
21641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	/**
21741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	A value of "true" indicates that the parser will
21841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	translate colons into underscores in names.
21941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	**/
22041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public final static String translateColonsFeature =
22141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		"http://www.ccil.org/~cowan/tagsoup/features/translate-colons";
22241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
22341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	/**
22441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	A value of "true" indicates that the parser will
22541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	attempt to restart the restartable elements.
22641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	**/
22741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public final static String restartElementsFeature =
22841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		"http://www.ccil.org/~cowan/tagsoup/features/restart-elements";
22941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
23041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	/**
23141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	A value of "true" indicates that the parser will
23241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	transmit whitespace in element-only content via the SAX
23341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	ignorableWhitespace callback.  Normally this is not done,
23441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	because HTML is an SGML application and SGML suppresses
23541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	such whitespace.
23641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	**/
23741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public final static String ignorableWhitespaceFeature =
23841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		"http://www.ccil.org/~cowan/tagsoup/features/ignorable-whitespace";
23941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
24041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	/**
24141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	A value of "true" indicates that the parser will treat CDATA
24241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	elements specially.  Normally true, since the input is by
24341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	default HTML.
24441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	**/
24541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public final static String CDATAElementsFeature =
24641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		"http://www.ccil.org/~cowan/tagsoup/features/cdata-elements";
24741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
24841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	/**
24941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	Used to see some syntax events that are essential in some
25041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	applications: comments, CDATA delimiters, selected general
25141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	entity inclusions, and the start and end of the DTD (and
25241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	declaration of document element name). The Object must implement
25341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	org.xml.sax.ext.LexicalHandler.
25441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	**/
25541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public final static String lexicalHandlerProperty =
25641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		"http://xml.org/sax/properties/lexical-handler";
25741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
25841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	/**
25941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	Specifies the Scanner object this Parser uses.
26041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	**/
26141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public final static String scannerProperty =
26241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		"http://www.ccil.org/~cowan/tagsoup/properties/scanner";
26341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
26441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	/**
26541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	Specifies the Schema object this Parser uses.
26641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	**/
26741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public final static String schemaProperty =
26841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		"http://www.ccil.org/~cowan/tagsoup/properties/schema";
26941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
27041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	/**
27141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	Specifies the AutoDetector (for encoding detection) this Parser uses.
27241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	**/
27341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public final static String autoDetectorProperty =
27441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		"http://www.ccil.org/~cowan/tagsoup/properties/auto-detector";
27541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
27641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	// Due to sucky Java order of initialization issues, these
27741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	// entries are maintained separately from the initial values of
27841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	// the corresponding instance variables, but care must be taken
27941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	// to keep them in sync.
28041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
28141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private HashMap theFeatures = new HashMap();
28241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	{
28341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theFeatures.put(namespacesFeature, truthValue(DEFAULT_NAMESPACES));
28441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theFeatures.put(namespacePrefixesFeature, Boolean.FALSE);
28541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theFeatures.put(externalGeneralEntitiesFeature, Boolean.FALSE);
28641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theFeatures.put(externalParameterEntitiesFeature, Boolean.FALSE);
28741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theFeatures.put(isStandaloneFeature, Boolean.FALSE);
28841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theFeatures.put(lexicalHandlerParameterEntitiesFeature,
28941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			Boolean.FALSE);
29041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theFeatures.put(resolveDTDURIsFeature, Boolean.TRUE);
29141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theFeatures.put(stringInterningFeature, Boolean.TRUE);
29241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theFeatures.put(useAttributes2Feature, Boolean.FALSE);
29341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theFeatures.put(useLocator2Feature, Boolean.FALSE);
29441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theFeatures.put(useEntityResolver2Feature, Boolean.FALSE);
29541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theFeatures.put(validationFeature, Boolean.FALSE);
29641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theFeatures.put(xmlnsURIsFeature, Boolean.FALSE);
29741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theFeatures.put(xmlnsURIsFeature, Boolean.FALSE);
29841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theFeatures.put(XML11Feature, Boolean.FALSE);
29941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theFeatures.put(ignoreBogonsFeature, truthValue(DEFAULT_IGNORE_BOGONS));
30041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theFeatures.put(bogonsEmptyFeature, truthValue(DEFAULT_BOGONS_EMPTY));
30141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theFeatures.put(rootBogonsFeature, truthValue(DEFAULT_ROOT_BOGONS));
30241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theFeatures.put(defaultAttributesFeature, truthValue(DEFAULT_DEFAULT_ATTRIBUTES));
30341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theFeatures.put(translateColonsFeature, truthValue(DEFAULT_TRANSLATE_COLONS));
30441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theFeatures.put(restartElementsFeature, truthValue(DEFAULT_RESTART_ELEMENTS));
30541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theFeatures.put(ignorableWhitespaceFeature, truthValue(DEFAULT_IGNORABLE_WHITESPACE));
30641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theFeatures.put(CDATAElementsFeature, truthValue(DEFAULT_CDATA_ELEMENTS));
30741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
30841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
30941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	// Private clone of Boolean.valueOf that is guaranteed to return
31041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	// Boolean.TRUE or Boolean.FALSE
31141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static Boolean truthValue(boolean b) {
31241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		return b ? Boolean.TRUE : Boolean.FALSE;
31341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
31441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
31541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
31641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public boolean getFeature (String name)
31741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		throws SAXNotRecognizedException, SAXNotSupportedException {
31841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		Boolean b = (Boolean)theFeatures.get(name);
31941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (b == null) {
32041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			throw new SAXNotRecognizedException("Unknown feature " + name);
32141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
32241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		return b.booleanValue();
32341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
32441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
32541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public void setFeature (String name, boolean value)
32641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	throws SAXNotRecognizedException, SAXNotSupportedException {
32741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		Boolean b = (Boolean)theFeatures.get(name);
32841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (b == null) {
32941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			throw new SAXNotRecognizedException("Unknown feature " + name);
33041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
33141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (value) theFeatures.put(name, Boolean.TRUE);
33241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		else theFeatures.put(name, Boolean.FALSE);
33341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
33441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (name.equals(namespacesFeature)) namespaces = value;
33541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		else if (name.equals(ignoreBogonsFeature)) ignoreBogons = value;
33641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		else if (name.equals(bogonsEmptyFeature)) bogonsEmpty = value;
33741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		else if (name.equals(rootBogonsFeature)) rootBogons = value;
33841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		else if (name.equals(defaultAttributesFeature)) defaultAttributes = value;
33941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		else if (name.equals(translateColonsFeature)) translateColons = value;
34041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		else if (name.equals(restartElementsFeature)) restartElements = value;
34141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		else if (name.equals(ignorableWhitespaceFeature)) ignorableWhitespace = value;
34241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		else if (name.equals(CDATAElementsFeature)) CDATAElements = value;
34341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
34441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
34541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public Object getProperty (String name)
34641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	throws SAXNotRecognizedException, SAXNotSupportedException {
34741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (name.equals(lexicalHandlerProperty)) {
34841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			return theLexicalHandler == this ? null : theLexicalHandler;
34941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
35041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		else if (name.equals(scannerProperty)) {
35141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			return theScanner;
35241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
35341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		else if (name.equals(schemaProperty)) {
35441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			return theSchema;
35541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
35641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		else if (name.equals(autoDetectorProperty)) {
35741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			return theAutoDetector;
35841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
35941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		else {
36041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			throw new SAXNotRecognizedException("Unknown property " + name);
36141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
36241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
36341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
36441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public void setProperty (String name, Object value)
36541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	throws SAXNotRecognizedException, SAXNotSupportedException {
36641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (name.equals(lexicalHandlerProperty)) {
36741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			if (value == null) {
36841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				theLexicalHandler = this;
36941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				}
37041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			else if (value instanceof LexicalHandler) {
37141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				theLexicalHandler = (LexicalHandler)value;
37241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				}
37341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			else {
37441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				throw new SAXNotSupportedException("Your lexical handler is not a LexicalHandler");
37541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				}
37641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
37741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		else if (name.equals(scannerProperty)) {
37841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			if (value instanceof Scanner) {
37941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				theScanner = (Scanner)value;
38041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				}
38141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			else {
38241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				throw new SAXNotSupportedException("Your scanner is not a Scanner");
38341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				}
38441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
38541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		else if (name.equals(schemaProperty)) {
38641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			if (value instanceof Schema) {
38741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				theSchema = (Schema)value;
38841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				}
38941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			else {
39041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				 throw new SAXNotSupportedException("Your schema is not a Schema");
39141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				}
39241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
39341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		else if (name.equals(autoDetectorProperty)) {
39441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			if (value instanceof AutoDetector) {
39541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				theAutoDetector = (AutoDetector)value;
39641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				}
39741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			else {
39841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				throw new SAXNotSupportedException("Your auto-detector is not an AutoDetector");
39941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				}
40041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
40141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		else {
40241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			throw new SAXNotRecognizedException("Unknown property " + name);
40341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
40441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
40541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
40641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public void setEntityResolver (EntityResolver resolver) {
40741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theEntityResolver = (resolver == null) ? this : resolver;
40841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
40941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
41041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public EntityResolver getEntityResolver () {
41141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		return (theEntityResolver == this) ? null : theEntityResolver;
41241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
41341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
41441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public void setDTDHandler (DTDHandler handler) {
41541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theDTDHandler = (handler == null) ? this : handler;
41641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
41741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
41841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public DTDHandler getDTDHandler () {
41941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		return (theDTDHandler == this) ? null : theDTDHandler;
42041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
42141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
42241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public void setContentHandler (ContentHandler handler) {
42341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theContentHandler = (handler == null) ? this : handler;
42441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
42541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
42641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public ContentHandler getContentHandler () {
42741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		return (theContentHandler == this) ? null : theContentHandler;
42841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
42941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
43041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public void setErrorHandler (ErrorHandler handler) {
43141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theErrorHandler = (handler == null) ? this : handler;
43241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
43341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
43441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public ErrorHandler getErrorHandler () {
43541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		return (theErrorHandler == this) ? null : theErrorHandler;
43641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
43741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
43841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public void parse (InputSource input) throws IOException, SAXException {
43941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		setup();
44041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		Reader r = getReader(input);
44141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theContentHandler.startDocument();
44241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theScanner.resetDocumentLocator(input.getPublicId(), input.getSystemId());
44341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (theScanner instanceof Locator) {
44441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			theContentHandler.setDocumentLocator((Locator)theScanner);
44541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
44641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (!(theSchema.getURI().equals("")))
44741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			theContentHandler.startPrefixMapping(theSchema.getPrefix(),
44841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				theSchema.getURI());
44941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theScanner.scan(r, this);
45041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
45141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
45241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public void parse (String systemid) throws IOException, SAXException {
45341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		parse(new InputSource(systemid));
45441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
45541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
45641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	// Sets up instance variables that haven't been set by setFeature
45741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private void setup() {
45841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (theSchema == null) theSchema = new HTMLSchema();
45941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (theScanner == null) theScanner = new HTMLScanner();
46041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (theAutoDetector == null) {
46141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			theAutoDetector = new AutoDetector() {
46241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				public Reader autoDetectingReader(InputStream i) {
46341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					return new InputStreamReader(i);
46441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					}
46541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				};
46641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
46741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theStack = new Element(theSchema.getElementType("<root>"), defaultAttributes);
46841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		thePCDATA = new Element(theSchema.getElementType("<pcdata>"), defaultAttributes);
46941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theNewElement = null;
47041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theAttributeName = null;
47141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		thePITarget = null;
47241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theSaved = null;
47341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theEntity = 0;
47441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		virginStack = true;
47541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project                theDoctypeName = theDoctypePublicId = theDoctypeSystemId = null;
47641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
47741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
47841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	// Return a Reader based on the contents of an InputSource
47941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	// Buffer both the InputStream and the Reader
48041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private Reader getReader(InputSource s) throws SAXException, IOException {
48141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		Reader r = s.getCharacterStream();
48241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		InputStream i = s.getByteStream();
48341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		String encoding = s.getEncoding();
48441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		String publicid = s.getPublicId();
48541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		String systemid = s.getSystemId();
48641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (r == null) {
48741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			if (i == null) i = getInputStream(publicid, systemid);
48841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project//			i = new BufferedInputStream(i);
48941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			if (encoding == null) {
49041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				r = theAutoDetector.autoDetectingReader(i);
49141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				}
49241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			else {
49341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				try {
49441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					r = new InputStreamReader(i, encoding);
49541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					}
49641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				catch (UnsupportedEncodingException e) {
49741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					r = new InputStreamReader(i);
49841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					}
49941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				}
50041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
50141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project//		r = new BufferedReader(r);
50241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		return r;
50341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
50441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
50541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	// Get an InputStream based on a publicid and a systemid
50641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private InputStream getInputStream(String publicid, String systemid) throws IOException, SAXException {
50741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		URL basis = new URL("file", "", System.getProperty("user.dir") + "/.");
50841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		URL url = new URL(basis, systemid);
50941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		URLConnection c = url.openConnection();
51041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		return c.getInputStream();
51141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
51241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		// We don't process publicids (who uses them anyhow?)
51341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
51441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	// ScanHandler implementation
51541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
51641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private Element theNewElement = null;
51741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private String theAttributeName = null;
51841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private boolean theDoctypeIsPresent = false;
51941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private String theDoctypePublicId = null;
52041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private String theDoctypeSystemId = null;
52141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private String theDoctypeName = null;
52241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private String thePITarget = null;
52341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private Element theStack = null;
52441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private Element theSaved = null;
52541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private Element thePCDATA = null;
52641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private int theEntity = 0;	// needs to support chars past U+FFFF
52741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
52841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public void adup(char[] buff, int offset, int length) throws SAXException {
52941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (theNewElement == null || theAttributeName == null) return;
53041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theNewElement.setAttribute(theAttributeName, null, theAttributeName);
53141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theAttributeName = null;
53241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
53341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
53441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public void aname(char[] buff, int offset, int length) throws SAXException {
53541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (theNewElement == null) return;
53641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		// Currently we don't rely on Schema to canonicalize
53741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		// attribute names.
53841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theAttributeName = makeName(buff, offset, length).toLowerCase();
53941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project//		System.err.println("%% Attribute name " + theAttributeName);
54041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
54141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
54241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public void aval(char[] buff, int offset, int length) throws SAXException {
54341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (theNewElement == null || theAttributeName == null) return;
54441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		String value = new String(buff, offset, length);
54541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project//		System.err.println("%% Attribute value [" + value + "]");
54641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		value = expandEntities(value);
54741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theNewElement.setAttribute(theAttributeName, null, value);
54841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theAttributeName = null;
54941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project//		System.err.println("%% Aval done");
55041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
55141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
55241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	// Expand entity references in attribute values selectively.
55341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	// Currently we expand a reference iff it is properly terminated
55441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	// with a semicolon.
55541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private String expandEntities(String src) {
55641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		int refStart = -1;
55741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		int len = src.length();
55841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		char[] dst = new char[len];
55941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		int dstlen = 0;
56041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		for (int i = 0; i < len; i++) {
56141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			char ch = src.charAt(i);
56241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			dst[dstlen++] = ch;
56341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project//			System.err.print("i = " + i + ", d = " + dstlen + ", ch = [" + ch + "] ");
56441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			if (ch == '&' && refStart == -1) {
56541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				// start of a ref excluding &
56641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				refStart = dstlen;
56741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project//				System.err.println("start of ref");
56841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				}
56941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			else if (refStart == -1) {
57041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				// not in a ref
57141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project//				System.err.println("not in ref");
57241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				}
57341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			else if (Character.isLetter(ch) ||
57441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					Character.isDigit(ch) ||
57541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					ch == '#') {
57641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				// valid entity char
57741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project//				System.err.println("valid");
57841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				}
57941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			else if (ch == ';') {
58041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				// properly terminated ref
58141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project//				System.err.print("got [" + new String(dst, refStart, dstlen-refStart-1) + "]");
58241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				int ent = lookupEntity(dst, refStart, dstlen - refStart - 1);
58341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project//				System.err.println(" = " + ent);
58441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				if (ent > 0xFFFF) {
58541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					ent -= 0x10000;
58641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					dst[refStart - 1] = (char)((ent>>10) + 0xD800);
58741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					dst[refStart] = (char)((ent&0x3FF) + 0xDC00);
58841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					dstlen = refStart + 1;
58941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					}
59041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				else if (ent != 0) {
59141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					dst[refStart - 1] = (char)ent;
59241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					dstlen = refStart;
59341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					}
59441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				refStart = -1;
59541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				}
59641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			else {
59741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				// improperly terminated ref
59841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project//				System.err.println("end of ref");
59941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				refStart = -1;
60041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				}
60141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
60241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		return new String(dst, 0, dstlen);
60341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
60441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
60541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public void entity(char[] buff, int offset, int length) throws SAXException {
60641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theEntity = lookupEntity(buff, offset, length);
60741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
60841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
60941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	// Process numeric character references,
61041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	// deferring to the schema for named ones.
61141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private int lookupEntity(char[] buff, int offset, int length) {
61241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		int result = 0;
61341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (length < 1) return result;
61441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project//		System.err.println("%% Entity at " + offset + " " + length);
61541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project//		System.err.println("%% Got entity [" + new String(buff, offset, length) + "]");
61641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (buff[offset] == '#') {
61741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project                        if (length > 1 && (buff[offset+1] == 'x'
61841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project                                        || buff[offset+1] == 'X')) {
61941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project                                try {
62041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project                                        return Integer.parseInt(new String(buff, offset + 2, length - 2), 16);
62141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project                                        }
62241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project                                catch (NumberFormatException e) { return 0; }
62341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project                                }
62441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project                        try {
62541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project                                return Integer.parseInt(new String(buff, offset + 1, length - 1), 10);
62641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project                                }
62741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project                        catch (NumberFormatException e) { return 0; }
62841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project                        }
62941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		return theSchema.getEntity(new String(buff, offset, length));
63041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
63141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
63241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public void eof(char[] buff, int offset, int length) throws SAXException {
63341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (virginStack) rectify(thePCDATA);
63441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		while (theStack.next() != null) {
63541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			pop();
63641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
63741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (!(theSchema.getURI().equals("")))
63841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			theContentHandler.endPrefixMapping(theSchema.getPrefix());
63941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theContentHandler.endDocument();
64041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
64141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
64241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public void etag(char[] buff, int offset, int length) throws SAXException {
64341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (etag_cdata(buff, offset, length)) return;
64441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		etag_basic(buff, offset, length);
64541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
64641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
64741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static char[] etagchars = {'<', '/', '>'};
64841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public boolean etag_cdata(char[] buff, int offset, int length) throws SAXException {
64941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		String currentName = theStack.name();
65041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		// If this is a CDATA element and the tag doesn't match,
65141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		// or isn't properly formed (junk after the name),
65241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		// restart CDATA mode and process the tag as characters.
65341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (CDATAElements && (theStack.flags() & Schema.F_CDATA) != 0) {
65441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			boolean realTag = (length == currentName.length());
65541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			if (realTag) {
65641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				for (int i = 0; i < length; i++) {
65741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					if (Character.toLowerCase(buff[offset + i]) != Character.toLowerCase(currentName.charAt(i))) {
65841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project						realTag = false;
65941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project						break;
66041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project						}
66141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					}
66241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				}
66341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			if (!realTag) {
66441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				theContentHandler.characters(etagchars, 0, 2);
66541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				theContentHandler.characters(buff, offset, length);
66641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				theContentHandler.characters(etagchars, 2, 1);
66741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				theScanner.startCDATA();
66841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				return true;
66941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				}
67041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
67141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		return false;
67241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
67341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
67441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public void etag_basic(char[] buff, int offset, int length) throws SAXException {
67541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theNewElement = null;
67641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		String name;
67741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (length != 0) {
67841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			// Canonicalize case of name
67941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			name = makeName(buff, offset, length);
68041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project//			System.err.println("got etag [" + name + "]");
68141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			ElementType type = theSchema.getElementType(name);
68241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			if (type == null) return;	// mysterious end-tag
68341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			name = type.name();
68441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
68541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		else {
68641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			name = theStack.name();
68741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
68841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project//		System.err.println("%% Got end of " + name);
68941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
69041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		Element sp;
69141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		boolean inNoforce = false;
69241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		for (sp = theStack; sp != null; sp = sp.next()) {
69341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			if (sp.name().equals(name)) break;
69441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			if ((sp.flags() & Schema.F_NOFORCE) != 0) inNoforce = true;
69541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
69641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
69741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (sp == null) return;		// Ignore unknown etags
69841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (sp.next() == null || sp.next().next() == null) return;
69941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (inNoforce) {		// inside an F_NOFORCE element?
70041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			sp.preclose();		// preclose the matching element
70141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
70241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		else {			// restartably pop everything above us
70341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			while (theStack != sp) {
70441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				restartablyPop();
70541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				}
70641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			pop();
70741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
70841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		// pop any preclosed elements now at the top
70941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		while (theStack.isPreclosed()) {
71041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			pop();
71141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
71241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		restart(null);
71341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
71441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
71541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	// Push restartables on the stack if possible
71641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	// e is the next element to be started, if we know what it is
71741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private void restart(Element e) throws SAXException {
71841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		while (theSaved != null && theStack.canContain(theSaved) &&
71941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				(e == null || theSaved.canContain(e))) {
72041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			Element next = theSaved.next();
72141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			push(theSaved);
72241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			theSaved = next;
72341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
72441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
72541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
72641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	// Pop the stack irrevocably
72741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private void pop() throws SAXException {
72841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (theStack == null) return;		// empty stack
72941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		String name = theStack.name();
73041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		String localName = theStack.localName();
73141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		String namespace = theStack.namespace();
73241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		String prefix = prefixOf(name);
73341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
73441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project//		System.err.println("%% Popping " + name);
73541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (!namespaces) namespace = localName = "";
73641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theContentHandler.endElement(namespace, localName, name);
73741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (foreign(prefix, namespace)) {
73841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			theContentHandler.endPrefixMapping(prefix);
73941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project//			System.err.println("%% Unmapping [" + prefix + "] for elements to " + namespace);
74041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
74141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		Attributes atts = theStack.atts();
74241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		for (int i = atts.getLength() - 1; i >= 0; i--) {
74341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			String attNamespace = atts.getURI(i);
74441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			String attPrefix = prefixOf(atts.getQName(i));
74541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			if (foreign(attPrefix, attNamespace)) {
74641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				theContentHandler.endPrefixMapping(attPrefix);
74741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project//			System.err.println("%% Unmapping [" + attPrefix + "] for attributes to " + attNamespace);
74841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				}
74941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
75041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theStack = theStack.next();
75141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
75241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
75341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	// Pop the stack restartably
75441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private void restartablyPop() throws SAXException {
75541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		Element popped = theStack;
75641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		pop();
75741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (restartElements && (popped.flags() & Schema.F_RESTART) != 0) {
75841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			popped.anonymize();
75941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			popped.setNext(theSaved);
76041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			theSaved = popped;
76141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
76241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
76341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
76441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	// Push element onto stack
76541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private boolean virginStack = true;
76641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private void push(Element e) throws SAXException {
76741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		String name = e.name();
76841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		String localName = e.localName();
76941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		String namespace = e.namespace();
77041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		String prefix = prefixOf(name);
77141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
77241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project//		System.err.println("%% Pushing " + name);
77341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		e.clean();
77441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (!namespaces) namespace = localName = "";
77541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project                if (virginStack && localName.equalsIgnoreCase(theDoctypeName)) {
77641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project                    try {
77741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project                        theEntityResolver.resolveEntity(theDoctypePublicId, theDoctypeSystemId);
77841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project                    } catch (IOException ew) { }   // Can't be thrown for root I believe.
77941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project                }
78041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (foreign(prefix, namespace)) {
78141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			theContentHandler.startPrefixMapping(prefix, namespace);
78241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project//			System.err.println("%% Mapping [" + prefix + "] for elements to " + namespace);
78341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
78441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		Attributes atts = e.atts();
78541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		int len = atts.getLength();
78641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		for (int i = 0; i < len; i++) {
78741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			String attNamespace = atts.getURI(i);
78841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			String attPrefix = prefixOf(atts.getQName(i));
78941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			if (foreign(attPrefix, attNamespace)) {
79041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				theContentHandler.startPrefixMapping(attPrefix, attNamespace);
79141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project//				System.err.println("%% Mapping [" + attPrefix + "] for attributes to " + attNamespace);
79241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				}
79341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
79441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theContentHandler.startElement(namespace, localName, name, e.atts());
79541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		e.setNext(theStack);
79641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theStack = e;
79741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		virginStack = false;
79841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (CDATAElements && (theStack.flags() & Schema.F_CDATA) != 0) {
79941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			theScanner.startCDATA();
80041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
80141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
80241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
80341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	// Get the prefix from a QName
80441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private String prefixOf(String name) {
80541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		int i = name.indexOf(':');
80641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		String prefix = "";
80741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (i != -1) prefix = name.substring(0, i);
80841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project//		System.err.println("%% " + prefix + " is prefix of " + name);
80941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		return prefix;
81041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
81141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
81241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	// Return true if we have a foreign name
81341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private boolean foreign(String prefix, String namespace) {
81441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project//		System.err.print("%% Testing " + prefix + " and " + namespace + " for foreignness -- ");
81541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		boolean foreign = !(prefix.equals("") || namespace.equals("") ||
81641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			namespace.equals(theSchema.getURI()));
81741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project//		System.err.println(foreign);
81841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		return foreign;
81941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
82041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
82141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project        /**
82241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project         * Parsing the complete XML Document Type Definition is way too complex,
82341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project         * but for many simple cases we can extract something useful from it.
82441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project         *
82541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project         * doctypedecl  ::= '<!DOCTYPE' S Name (S ExternalID)? S? ('[' intSubset ']' S?)? '>'
82641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project         *  DeclSep     ::= PEReference | S
82741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project         *  intSubset   ::= (markupdecl | DeclSep)*
82841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project         *  markupdecl  ::= elementdecl | AttlistDecl | EntityDecl | NotationDecl | PI | Comment
82941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project         *  ExternalID  ::= 'SYSTEM' S SystemLiteral | 'PUBLIC' S PubidLiteral S SystemLiteral
83041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project         */
83141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public void decl(char[] buff, int offset, int length) throws SAXException {
83241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		String s = new String(buff, offset, length);
83341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		String name = null;
83441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		String systemid = null;
83541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		String publicid = null;
83641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		String[] v = split(s);
83770dce01b47b7ef16f67b6bd17ee66fca72b42ef1Narayan Kamath		if (v.length > 0 && "DOCTYPE".equalsIgnoreCase(v[0])) {
83841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			if (theDoctypeIsPresent) return;		// one doctype only!
83941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			theDoctypeIsPresent = true;
84041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			if (v.length > 1) {
84141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				name = v[1];
84241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				if (v.length>3 && "SYSTEM".equals(v[2])) {
84341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				systemid = v[3];
84441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				}
84541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			else if (v.length > 3 && "PUBLIC".equals(v[2])) {
84641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				publicid = v[3];
84741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				if (v.length > 4) {
84841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					systemid = v[4];
84941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					}
85041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				else {
85141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					systemid = "";
85241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					}
85341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project                    }
85441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project                }
85541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project            }
85641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		publicid = trimquotes(publicid);
85741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		systemid = trimquotes(systemid);
85841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (name != null) {
85941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			publicid = cleanPublicid(publicid);
86041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			theLexicalHandler.startDTD(name, publicid, systemid);
86141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			theLexicalHandler.endDTD();
86241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			theDoctypeName = name;
86341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			theDoctypePublicId = publicid;
86441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (theScanner instanceof Locator) {    // Must resolve systemid
86541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project                    theDoctypeSystemId  = ((Locator)theScanner).getSystemId();
86641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project                    try {
86741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project                        theDoctypeSystemId = new URL(new URL(theDoctypeSystemId), systemid).toString();
86841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project                    } catch (Exception e) {}
86941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project                }
87041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project            }
87141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project        }
87241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
87341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	// If the String is quoted, trim the quotes.
87441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static String trimquotes(String in) {
87541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (in == null) return in;
87641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		int length = in.length();
87741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (length == 0) return in;
87841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		char s = in.charAt(0);
87941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		char e = in.charAt(length - 1);
88041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (s == e && (s == '\'' || s == '"')) {
88141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			in = in.substring(1, in.length() - 1);
88241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
88341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		return in;
88441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
88541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
88641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	// Split the supplied String into words or phrases seperated by spaces.
88741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	// Recognises quotes around a phrase and doesn't split it.
88841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static String[] split(String val) throws IllegalArgumentException {
88941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		val = val.trim();
89041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (val.length() == 0) {
89141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			return new String[0];
89241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
89341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		else {
89441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			ArrayList l = new ArrayList();
89541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			int s = 0;
89641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			int e = 0;
89741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			boolean sq = false;	// single quote
89841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			boolean dq = false;	// double quote
89941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			char lastc = 0;
90041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			int len = val.length();
90141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			for (e=0; e < len; e++) {
90241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				char c = val.charAt(e);
90341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				if (!dq && c == '\'' && lastc != '\\') {
90441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				sq = !sq;
90541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				if (s < 0) s = e;
90641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				}
90741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			else if (!sq && c == '\"' && lastc != '\\') {
90841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				dq = !dq;
90941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				if (s < 0) s = e;
91041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				}
91141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			else if (!sq && !dq) {
91241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				if (Character.isWhitespace(c)) {
91341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					if (s >= 0) l.add(val.substring(s, e));
91441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					s = -1;
91541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					}
91641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				else if (s < 0 && c != ' ') {
91741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					s = e;
91841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project					}
91941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				}
92041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			lastc = c;
92141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
92241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		l.add(val.substring(s, e));
92341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		return (String[])l.toArray(new String[0]);
92441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
92541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project        }
92641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
92741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	// Replace junk in publicids with spaces
92841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private static String legal =
92941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-'()+,./:=?;!*#@$_%";
93041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
93141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private String cleanPublicid(String src) {
93241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (src == null) return null;
93341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		int len = src.length();
93441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		StringBuffer dst = new StringBuffer(len);
93541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		boolean suppressSpace = true;
93641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		for (int i = 0; i < len; i++) {
93741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			char ch = src.charAt(i);
93841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			if (legal.indexOf(ch) != -1) { 	// legal but not whitespace
93941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				dst.append(ch);
94041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				suppressSpace = false;
94141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				}
94241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			else if (suppressSpace) {	// normalizable whitespace or junk
94341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				;
94441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				}
94541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			else {
94641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				dst.append(' ');
94741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				suppressSpace = true;
94841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				}
94941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
95041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project//		System.err.println("%% Publicid [" + dst.toString().trim() + "]");
95141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		return dst.toString().trim();	// trim any final junk whitespace
95241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
95341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
95441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
95541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public void gi(char[] buff, int offset, int length) throws SAXException {
95641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (theNewElement != null) return;
95741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		String name = makeName(buff, offset, length);
95841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (name == null) return;
95941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		ElementType type = theSchema.getElementType(name);
96041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (type == null) {
96141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			// Suppress unknown elements if ignore-bogons is on
96241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			if (ignoreBogons) return;
96341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			int bogonModel = bogonsEmpty ? Schema.M_EMPTY : Schema.M_ANY;
96441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			int bogonMemberOf = rootBogons ? Schema.M_ANY : (Schema.M_ANY & ~ Schema.M_ROOT);
96541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			theSchema.elementType(name, bogonModel, bogonMemberOf, 0);
96641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			if (!rootBogons) theSchema.parent(name, theSchema.rootElementType().name());
96741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			type = theSchema.getElementType(name);
96841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
96941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
97041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theNewElement = new Element(type, defaultAttributes);
97141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project//		System.err.println("%% Got GI " + theNewElement.name());
97241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
97341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
97441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public void cdsect(char[] buff, int offset, int length) throws SAXException {
97541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theLexicalHandler.startCDATA();
97641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		pcdata(buff, offset, length);
97741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theLexicalHandler.endCDATA();
97841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
97941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public void pcdata(char[] buff, int offset, int length) throws SAXException {
98041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (length == 0) return;
98141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		boolean allWhite = true;
98241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		for (int i = 0; i < length; i++) {
98341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			if (!Character.isWhitespace(buff[offset+i])) {
98441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				allWhite = false;
98541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				}
98641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
98741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (allWhite && !theStack.canContain(thePCDATA)) {
98841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			if (ignorableWhitespace) {
98941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				theContentHandler.ignorableWhitespace(buff, offset, length);
99041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				}
99141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
99241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		else {
99341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			rectify(thePCDATA);
99441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			theContentHandler.characters(buff, offset, length);
99541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
99641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
99741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
99841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public void pitarget(char[] buff, int offset, int length) throws SAXException {
99941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (theNewElement != null) return;
100041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		thePITarget = makeName(buff, offset, length).replace(':', '_');
100141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
100241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
100341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public void pi(char[] buff, int offset, int length) throws SAXException {
100441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (theNewElement != null || thePITarget == null) return;
100541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if ("xml".equalsIgnoreCase(thePITarget)) return;
100641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project//		if (length > 0 && buff[length - 1] == '?') System.err.println("%% Removing ? from PI");
100741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (length > 0 && buff[length - 1] == '?') length--;	// remove trailing ?
100841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theContentHandler.processingInstruction(thePITarget,
100941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			new String(buff, offset, length));
101041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		thePITarget = null;
101141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
101241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
101341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public void stagc(char[] buff, int offset, int length) throws SAXException {
101441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project//		System.err.println("%% Start-tag");
101541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (theNewElement == null) return;
101641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		rectify(theNewElement);
101741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (theStack.model() == Schema.M_EMPTY) {
101841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			// Force an immediate end tag
101941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			etag_basic(buff, offset, length);
102041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
102141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
102241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
102341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public void stage(char[] buff, int offset, int length) throws SAXException {
102441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project//		System.err.println("%% Empty-tag");
102541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (theNewElement == null) return;
102641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		rectify(theNewElement);
102741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		// Force an immediate end tag
102841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		etag_basic(buff, offset, length);
102941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
103041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
103141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	// Comment buffer is twice the size of the output buffer
103241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private char[] theCommentBuffer = new char[2000];
103341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public void cmnt(char[] buff, int offset, int length) throws SAXException {
103441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theLexicalHandler.comment(buff, offset, length);
103541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
103641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
103741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	// Rectify the stack, pushing and popping as needed
103841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	// so that the argument can be safely pushed
103941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private void rectify(Element e) throws SAXException {
104041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		Element sp;
104141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		while (true) {
104241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			for (sp = theStack; sp != null; sp = sp.next()) {
104341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				if (sp.canContain(e)) break;
104441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				}
104541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			if (sp != null) break;
104641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			ElementType parentType = e.parent();
104741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			if (parentType == null) break;
104841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			Element parent = new Element(parentType, defaultAttributes);
104941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project//			System.err.println("%% Ascending from " + e.name() + " to " + parent.name());
105041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			parent.setNext(e);
105141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			e = parent;
105241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
105341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (sp == null) return;		// don't know what to do
105441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		while (theStack != sp) {
105541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			if (theStack == null || theStack.next() == null ||
105641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				theStack.next().next() == null) break;
105741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			restartablyPop();
105841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
105941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		while (e != null) {
106041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			Element nexte = e.next();
106141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			if (!e.name().equals("<pcdata>")) push(e);
106241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			e = nexte;
106341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			restart(e);
106441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
106541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		theNewElement = null;
106641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
106741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
106841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public int getEntity() {
106941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		return theEntity;
107041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
107141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
107241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	// Return the argument as a valid XML name
107341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	// This no longer lowercases the result: we depend on Schema to
107441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	// canonicalize case.
107541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	private String makeName(char[] buff, int offset, int length) {
107641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		StringBuffer dst = new StringBuffer(length + 2);
107741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		boolean seenColon = false;
107841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		boolean start = true;
107941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project//		String src = new String(buff, offset, length); // DEBUG
108041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		for (; length-- > 0; offset++) {
108141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			char ch = buff[offset];
108241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			if (Character.isLetter(ch) || ch == '_') {
108341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				start = false;
108441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				dst.append(ch);
108541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				}
108641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			else if (Character.isDigit(ch) || ch == '-' || ch == '.') {
108741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				if (start) dst.append('_');
108841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				start = false;
108941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				dst.append(ch);
109041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				}
109141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			else if (ch == ':' && !seenColon) {
109241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				seenColon = true;
109341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				if (start) dst.append('_');
109441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				start = true;
109541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				dst.append(translateColons ? '_' : ch);
109641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project				}
109741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project			}
109841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		int dstLength = dst.length();
109941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		if (dstLength == 0 || dst.charAt(dstLength - 1) == ':') dst.append('_');
110041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project//		System.err.println("Made name \"" + dst + "\" from \"" + src + "\"");
110141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		return dst.toString().intern();
110241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project		}
110341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
110441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	// Default LexicalHandler implementation
110541cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
110641cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public void comment(char[] ch, int start, int length) throws SAXException { }
110741cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public void endCDATA() throws SAXException { }
110841cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public void endDTD() throws SAXException { }
110941cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public void endEntity(String name) throws SAXException { }
111041cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public void startCDATA() throws SAXException { }
111141cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public void startDTD(String name, String publicid, String systemid) throws SAXException { }
111241cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	public void startEntity(String name) throws SAXException { }
111341cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project
111441cdf40d933f4029c37cf844f8cf3314114e4e0aThe Android Open Source Project	}
1115