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