CatalogReader.java revision 1060:8c9a2a24752b
155682Smarkm/* 2233294Sstas * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. 3233294Sstas * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4233294Sstas * 555682Smarkm * This code is free software; you can redistribute it and/or modify it 6233294Sstas * under the terms of the GNU General Public License version 2 only, as 755682Smarkm * published by the Free Software Foundation. Oracle designates this 8233294Sstas * particular file as subject to the "Classpath" exception as provided 9233294Sstas * by Oracle in the LICENSE file that accompanied this code. 10233294Sstas * 1155682Smarkm * This code is distributed in the hope that it will be useful, but WITHOUT 12233294Sstas * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13233294Sstas * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1455682Smarkm * version 2 for more details (a copy is included in the LICENSE file that 15233294Sstas * accompanied this code). 16233294Sstas * 17233294Sstas * You should have received a copy of the GNU General Public License version 1855682Smarkm * 2 along with this work; if not, write to the Free Software Foundation, 19233294Sstas * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20233294Sstas * 21233294Sstas * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22233294Sstas * or visit www.oracle.com if you need additional information or have any 23233294Sstas * questions. 24233294Sstas */ 25233294Sstaspackage javax.xml.catalog; 26233294Sstas 27233294Sstasimport java.io.StringReader; 28233294Sstasimport javax.xml.catalog.BaseEntry.CatalogEntryType; 29233294Sstasimport javax.xml.parsers.SAXParser; 30233294Sstasimport javax.xml.transform.Source; 31233294Sstasimport javax.xml.transform.TransformerException; 32233294Sstasimport javax.xml.transform.URIResolver; 33233294Sstasimport javax.xml.transform.sax.SAXSource; 3455682Smarkmimport org.xml.sax.Attributes; 3555682Smarkmimport org.xml.sax.EntityResolver; 3655682Smarkmimport org.xml.sax.InputSource; 37233294Sstasimport org.xml.sax.SAXException; 3855682Smarkmimport org.xml.sax.helpers.DefaultHandler; 3955682Smarkm 4055682Smarkm/** 4155682Smarkm * CatalogReader handles SAX events while parsing through a catalog file to 42178825Sdfr * create a catalog object. 43178825Sdfr * 4455682Smarkm * @since 9 4555682Smarkm */ 4655682Smarkmclass CatalogReader extends DefaultHandler implements EntityResolver, URIResolver { 4755682Smarkm /** URI of the W3C XML Schema for OASIS XML Catalog files. */ 4855682Smarkm public static final String xmlCatalogXSD = "http://www.oasis-open.org/committees/entity/release/1.0/catalog.xsd"; 4955682Smarkm 5055682Smarkm /** Public identifier for OASIS XML Catalog files. */ 51178825Sdfr public static final String xmlCatalogPubId = "-//OASIS//DTD XML Catalogs V1.0//EN"; 5255682Smarkm 5355682Smarkm /** 54178825Sdfr * The namespace name defined by the OASIS Standard 5555682Smarkm */ 5655682Smarkm public static final String NAMESPACE_OASIS = "urn:oasis:names:tc:entity:xmlns:xml:catalog"; 5755682Smarkm 5855682Smarkm //Indicate whether the root element has been found 5955682Smarkm boolean seenRoot; 6072445Sassar 61102644Snectar //Indicate that the parser is in a group entry 6255682Smarkm boolean inGroup; 6355682Smarkm 6455682Smarkm //The Catalog instance 6555682Smarkm CatalogImpl catalog; 6655682Smarkm 6772445Sassar //The parser for reading the catalog 6855682Smarkm SAXParser parser; 6955682Smarkm 7055682Smarkm //The current catalog entry 7155682Smarkm CatalogEntry catalogEntry; 7255682Smarkm 7355682Smarkm //The current group 7455682Smarkm GroupEntry group; 7555682Smarkm 7655682Smarkm //The current entry 7755682Smarkm BaseEntry entry; 7855682Smarkm 7955682Smarkm //remove this variable once 8136778 is committed 8055682Smarkm boolean ignoreTheCatalog = false; 8155682Smarkm 8255682Smarkm /** 8355682Smarkm * Constructs an instance with a Catalog object and parser. 8455682Smarkm * 8555682Smarkm * @param catalog The Catalog object that represents a catalog 8655682Smarkm */ 8755682Smarkm @SuppressWarnings("unchecked") 8855682Smarkm public CatalogReader(Catalog catalog, SAXParser parser) { 8955682Smarkm this.catalog = (CatalogImpl) catalog; 9055682Smarkm this.parser = parser; 9155682Smarkm } 9255682Smarkm 9355682Smarkm @Override 9455682Smarkm public void startElement(String namespaceURI, 9555682Smarkm String localName, 9655682Smarkm String qName, 9755682Smarkm Attributes atts) 9855682Smarkm throws SAXException { 9955682Smarkm 10055682Smarkm //ignore the catalog if it's not compliant. See section 8, item 3 of the spec. 10155682Smarkm if (ignoreTheCatalog) return; 10255682Smarkm if (!NAMESPACE_OASIS.equals(namespaceURI)) { 10355682Smarkm//wait till 8136778 is committed 10455682Smarkm// parser.stop(); 10555682Smarkm ignoreTheCatalog = true; 10655682Smarkm return; 10755682Smarkm } 10855682Smarkm 10955682Smarkm 11055682Smarkm CatalogEntryType type = CatalogEntryType.getType(localName); 11155682Smarkm if (type == null) { 11255682Smarkm CatalogMessages.reportError(CatalogMessages.ERR_INVALID_ENTRY_TYPE, 11355682Smarkm new Object[]{localName}); 11455682Smarkm } 11555682Smarkm if (type != CatalogEntryType.CATALOGENTRY) { 11655682Smarkm if (!seenRoot) { 11755682Smarkm CatalogMessages.reportError(CatalogMessages.ERR_INVALID_CATALOG); 118233294Sstas } 11955682Smarkm } 12055682Smarkm 12155682Smarkm String base = atts.getValue("xml:base"); 12255682Smarkm if (base == null) { 12355682Smarkm if (inGroup) { 12478527Sassar base = group.getBaseURI().toString(); 125233294Sstas } else { 126233294Sstas if (type == CatalogEntryType.CATALOGENTRY) { 12755682Smarkm base = catalog.getBaseURI().toString(); 12878527Sassar } else { 12955682Smarkm base = catalogEntry.getBaseURI().toString(); 13055682Smarkm } 13155682Smarkm } 132233294Sstas } else { 133233294Sstas base = Normalizer.normalizeURI(base); 13455682Smarkm } 13555682Smarkm 13655682Smarkm //parse the catalog and group entries 13755682Smarkm if (type == CatalogEntryType.CATALOGENTRY 13855682Smarkm || type == CatalogEntryType.GROUP) { 13955682Smarkm String prefer = atts.getValue("prefer"); 140233294Sstas if (prefer == null) { 14155682Smarkm if (type == CatalogEntryType.CATALOGENTRY) { 14255682Smarkm //use the general setting 14355682Smarkm prefer = catalog.isPreferPublic() ? 14455682Smarkm CatalogFeatures.PREFER_PUBLIC : CatalogFeatures.PREFER_SYSTEM; 145178825Sdfr } else { 146178825Sdfr //Group inherit from the catalog entry 14755682Smarkm prefer = catalogEntry.isPreferPublic() ? 14855682Smarkm CatalogFeatures.PREFER_PUBLIC : CatalogFeatures.PREFER_SYSTEM; 14955682Smarkm } 15078527Sassar } 151233294Sstas 152233294Sstas if (type == CatalogEntryType.CATALOGENTRY) { 15355682Smarkm seenRoot = true; 15478527Sassar if (catalog.isTop()) { 15555682Smarkm String defer = atts.getValue("defer"); 15655682Smarkm String resolve = atts.getValue("resolve"); 157178825Sdfr if (defer == null) { 158178825Sdfr defer = catalog.isDeferred() ? 15955682Smarkm CatalogFeatures.DEFER_TRUE : CatalogFeatures.DEFER_FALSE; 16055682Smarkm } 16155682Smarkm if (resolve == null) { 16255682Smarkm resolve = catalog.getResolve().literal; 16355682Smarkm } 164102644Snectar //override property settings with those from the catalog file 16555682Smarkm catalog.setResolve(resolve); 16655682Smarkm catalog.setDeferred(defer); 16755682Smarkm catalogEntry = new CatalogEntry(base, prefer, defer, resolve); 168233294Sstas } else { 169178825Sdfr catalogEntry = new CatalogEntry(base, prefer); 17055682Smarkm } 17155682Smarkm catalog.setPrefer(prefer); 172233294Sstas return; 17355682Smarkm } else { 174102644Snectar inGroup = true; 17555682Smarkm group = new GroupEntry(catalog, base, prefer); 17655682Smarkm catalog.addEntry(group); 17755682Smarkm return; 178233294Sstas } 17955682Smarkm } 18055682Smarkm 18155682Smarkm //parse entries other than the catalog and group entries 18255682Smarkm switch (type) { 18355682Smarkm case PUBLIC: 18455682Smarkm entry = new PublicEntry(base, atts.getValue("publicId"), atts.getValue("uri")); 18555682Smarkm break; 18655682Smarkm case SYSTEM: 18755682Smarkm entry = new SystemEntry(base, atts.getValue("systemId"), atts.getValue("uri")); 18855682Smarkm break; 18955682Smarkm case REWRITESYSTEM: 190102644Snectar entry = new RewriteSystem(base, atts.getValue("systemIdStartString"), atts.getValue("rewritePrefix")); 19155682Smarkm break; 19255682Smarkm case SYSTEMSUFFIX: 19378527Sassar entry = new SystemSuffix(base, atts.getValue("systemIdSuffix"), atts.getValue("uri")); 194233294Sstas break; 195233294Sstas case DELEGATEPUBLIC: 19655682Smarkm entry = new DelegatePublic(base, atts.getValue("publicIdStartString"), atts.getValue("catalog")); 19778527Sassar break; 19855682Smarkm case DELEGATESYSTEM: 19955682Smarkm entry = new DelegateSystem(base, atts.getValue("systemIdStartString"), atts.getValue("catalog")); 20055682Smarkm break; 20155682Smarkm case URI: 20255682Smarkm entry = new UriEntry(base, atts.getValue("name"), atts.getValue("uri")); 20355682Smarkm break; 20455682Smarkm case REWRITEURI: 20555682Smarkm entry = new RewriteUri(base, atts.getValue("uriStartString"), atts.getValue("rewritePrefix")); 20655682Smarkm break; 20755682Smarkm case URISUFFIX: 20855682Smarkm entry = new UriSuffix(base, atts.getValue("uriSuffix"), atts.getValue("uri")); 20955682Smarkm break; 21055682Smarkm case DELEGATEURI: 21155682Smarkm entry = new DelegateUri(base, atts.getValue("uriStartString"), atts.getValue("catalog")); 212102644Snectar break; 213102644Snectar case NEXTCATALOG: 21455682Smarkm entry = new NextCatalog(base, atts.getValue("catalog")); 21555682Smarkm break; 21655682Smarkm } 21755682Smarkm 218233294Sstas if (type == CatalogEntryType.NEXTCATALOG) { 219178825Sdfr catalog.addNextCatalog((NextCatalog) entry); 22055682Smarkm } else if (inGroup) { 22155682Smarkm group.addEntry(entry); 22255682Smarkm } else { 22355682Smarkm catalog.addEntry(entry); 224233294Sstas } 225233294Sstas 22655682Smarkm } 22755682Smarkm 22855682Smarkm /** 22955682Smarkm * Handles endElement event 230233294Sstas */ 231233294Sstas @Override 232233294Sstas public void endElement(String namespaceURI, String localName, String qName) 233233294Sstas throws SAXException { 234233294Sstas if (ignoreTheCatalog) return; 235233294Sstas 236233294Sstas CatalogEntryType type = CatalogEntryType.getType(localName); 237233294Sstas if (type == CatalogEntryType.GROUP) { 238178825Sdfr inGroup = false; 23955682Smarkm } 240178825Sdfr } 241178825Sdfr 24255682Smarkm 24355682Smarkm /** 244233294Sstas * Skips external DTD since resolving external DTD is not required 24555682Smarkm * by the specification. 24655682Smarkm */ 24755682Smarkm @Override 24855682Smarkm public InputSource resolveEntity(String publicId, String systemId) { 24955682Smarkm return new InputSource(new StringReader("")); 25055682Smarkm } 25155682Smarkm 25255682Smarkm /** 25355682Smarkm * Skips external references since resolution is not required 25455682Smarkm * by the specification. 255102644Snectar */ 25655682Smarkm @Override 25755682Smarkm public Source resolve(String href, String base) 25878527Sassar throws TransformerException { 259233294Sstas return new SAXSource(new InputSource(new StringReader(""))); 260233294Sstas } 26155682Smarkm 26278527Sassar} 26355682Smarkm