8163232: Catalog API: Consolidating CatalogResolver to support all XML Resolvers

Reviewed-by: dfuchs, lancea
This commit is contained in:
Joe Wang 2016-08-26 14:50:00 -07:00
parent 08c97e3e67
commit cdcc5575ac
65 changed files with 1197 additions and 499 deletions

View file

@ -1,13 +1,13 @@
/* /*
* reserved comment block * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT REMOVE OR ALTER!
*/ */
/* /*
* Copyright 2001-2004 The Apache Software Foundation. * Licensed to the Apache Software Foundation (ASF) under one or more
* * contributor license agreements. See the NOTICE file distributed with
* Licensed under the Apache License, Version 2.0 (the "License"); * this work for additional information regarding copyright ownership.
* you may not use this file except in compliance with the License. * The ASF licenses this file to You under the Apache License, Version 2.0
* You may obtain a copy of the License at * (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
@ -169,6 +169,14 @@ public class ErrorMessages extends ListResourceBundle {
{ErrorMsg.INVALID_URI_ERR, {ErrorMsg.INVALID_URI_ERR,
"Invalid URI ''{0}''."}, "Invalid URI ''{0}''."},
/*
* Note to translators: This message is displayed when the URI
* mentioned in the substitution text is not well-formed syntactically.
*/
{ErrorMsg.CATALOG_EXCEPTION,
"JAXP08090001: The CatalogResolver is enabled with the catalog \"{0}\", "
+ "but a CatalogException is returned."},
/* /*
* Note to translators: The file or URI named in the substitution text * Note to translators: The file or URI named in the substitution text
* exists but could not be opened. * exists but could not be opened.

View file

@ -1,13 +1,13 @@
/* /*
* reserved comment block * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT REMOVE OR ALTER!
*/ */
/* /*
* Copyright 2001-2004 The Apache Software Foundation. * Licensed to the Apache Software Foundation (ASF) under one or more
* * contributor license agreements. See the NOTICE file distributed with
* Licensed under the Apache License, Version 2.0 (the "License"); * this work for additional information regarding copyright ownership.
* you may not use this file except in compliance with the License. * The ASF licenses this file to You under the Apache License, Version 2.0
* You may obtain a copy of the License at * (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
@ -17,9 +17,6 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
/*
* $Id: ErrorMsg.java,v 1.2.4.1 2005/09/15 10:18:01 pvedula Exp $
*/
package com.sun.org.apache.xalan.internal.xsltc.compiler.util; package com.sun.org.apache.xalan.internal.xsltc.compiler.util;
@ -60,6 +57,7 @@ public final class ErrorMsg {
public static final String ARGUMENT_CONVERSION_ERR = "ARGUMENT_CONVERSION_ERR"; public static final String ARGUMENT_CONVERSION_ERR = "ARGUMENT_CONVERSION_ERR";
public static final String FILE_NOT_FOUND_ERR = "FILE_NOT_FOUND_ERR"; public static final String FILE_NOT_FOUND_ERR = "FILE_NOT_FOUND_ERR";
public static final String INVALID_URI_ERR = "INVALID_URI_ERR"; public static final String INVALID_URI_ERR = "INVALID_URI_ERR";
public static final String CATALOG_EXCEPTION = "CATALOG_EXCEPTION";
public static final String FILE_ACCESS_ERR = "FILE_ACCESS_ERR"; public static final String FILE_ACCESS_ERR = "FILE_ACCESS_ERR";
public static final String MISSING_ROOT_ERR = "MISSING_ROOT_ERR"; public static final String MISSING_ROOT_ERR = "MISSING_ROOT_ERR";
public static final String NAMESPACE_UNDEF_ERR = "NAMESPACE_UNDEF_ERR"; public static final String NAMESPACE_UNDEF_ERR = "NAMESPACE_UNDEF_ERR";

View file

@ -51,10 +51,11 @@ import java.util.Vector;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipFile; import java.util.zip.ZipFile;
import javax.xml.XMLConstants; import javax.xml.XMLConstants;
import javax.xml.catalog.CatalogException;
import javax.xml.catalog.CatalogFeatures; import javax.xml.catalog.CatalogFeatures;
import javax.xml.catalog.CatalogFeatures.Feature; import javax.xml.catalog.CatalogFeatures.Feature;
import javax.xml.catalog.CatalogManager; import javax.xml.catalog.CatalogManager;
import javax.xml.catalog.CatalogUriResolver; import javax.xml.catalog.CatalogResolver;
import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory; import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.ErrorListener; import javax.xml.transform.ErrorListener;
@ -241,7 +242,7 @@ public class TransformerFactoryImpl
// type checking // type checking
private Map<String, Class> _xsltcExtensionFunctions; private Map<String, Class> _xsltcExtensionFunctions;
CatalogUriResolver _catalogUriResolver; CatalogResolver _catalogUriResolver;
CatalogFeatures _catalogFeatures; CatalogFeatures _catalogFeatures;
CatalogFeatures.Builder cfBuilder = CatalogFeatures.builder(); CatalogFeatures.Builder cfBuilder = CatalogFeatures.builder();
// Catalog features // Catalog features
@ -634,7 +635,7 @@ public class TransformerFactoryImpl
} }
// Inefficient, but array is small // Inefficient, but array is small
for (int i = 0; i < features.length; i++) { for (int i =0; i < features.length; i++) {
if (name.equals(features[i])) { if (name.equals(features[i])) {
return true; return true;
} }
@ -1327,7 +1328,7 @@ public class TransformerFactoryImpl
if (source == null && _catalogFiles != null && if (source == null && _catalogFiles != null &&
_xmlFeatures.getFeature(JdkXmlFeatures.XmlFeature.USE_CATALOG)) { _xmlFeatures.getFeature(JdkXmlFeatures.XmlFeature.USE_CATALOG)) {
if (_catalogUriResolver == null) { if (_catalogUriResolver == null) {
_catalogUriResolver = CatalogManager.catalogUriResolver(_catalogFeatures); _catalogUriResolver = CatalogManager.catalogResolver(_catalogFeatures);
} }
source = _catalogUriResolver.resolve(href, context); source = _catalogUriResolver.resolve(href, context);
} }
@ -1340,6 +1341,10 @@ public class TransformerFactoryImpl
final ErrorMsg msg = new ErrorMsg(ErrorMsg.INVALID_URI_ERR, href + "\n" + e.getMessage(), this); final ErrorMsg msg = new ErrorMsg(ErrorMsg.INVALID_URI_ERR, href + "\n" + e.getMessage(), this);
xsltc.getParser().reportError(Constants.FATAL, msg); xsltc.getParser().reportError(Constants.FATAL, msg);
} }
catch (CatalogException e) {
final ErrorMsg msg = new ErrorMsg(ErrorMsg.CATALOG_EXCEPTION, href + "\n" + e.getMessage(), this);
xsltc.getParser().reportError(Constants.FATAL, msg);
}
return null; return null;
} }

View file

@ -60,9 +60,10 @@ import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import javax.xml.XMLConstants; import javax.xml.XMLConstants;
import javax.xml.catalog.CatalogException;
import javax.xml.catalog.CatalogFeatures; import javax.xml.catalog.CatalogFeatures;
import javax.xml.catalog.CatalogManager; import javax.xml.catalog.CatalogManager;
import javax.xml.catalog.CatalogUriResolver; import javax.xml.catalog.CatalogResolver;
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.ParserConfigurationException;
@ -224,7 +225,7 @@ public final class TransformerImpl extends Transformer
// Catalog features // Catalog features
CatalogFeatures _catalogFeatures; CatalogFeatures _catalogFeatures;
CatalogUriResolver _catalogUriResolver; CatalogResolver _catalogUriResolver;
// Catalog is enabled by default // Catalog is enabled by default
boolean _useCatalog = true; boolean _useCatalog = true;
@ -1337,7 +1338,7 @@ public final class TransformerImpl extends Transformer
if (resolvedSource == null && _useCatalog && if (resolvedSource == null && _useCatalog &&
_catalogFeatures.get(CatalogFeatures.Feature.FILES) != null) { _catalogFeatures.get(CatalogFeatures.Feature.FILES) != null) {
if (_catalogUriResolver == null) { if (_catalogUriResolver == null) {
_catalogUriResolver = CatalogManager.catalogUriResolver(_catalogFeatures); _catalogUriResolver = CatalogManager.catalogResolver(_catalogFeatures);
} }
resolvedSource = _catalogUriResolver.resolve(href, baseURI); resolvedSource = _catalogUriResolver.resolve(href, baseURI);
} }
@ -1350,7 +1351,7 @@ public final class TransformerImpl extends Transformer
return getDOM(resolvedSource); return getDOM(resolvedSource);
} }
catch (TransformerException e) { catch (TransformerException | CatalogException e) {
if (_errorListener != null) if (_errorListener != null)
postErrorToListener("File not found: " + e.getMessage()); postErrorToListener("File not found: " + e.getMessage());
return(null); return(null);

View file

@ -20,8 +20,6 @@
package com.sun.org.apache.xerces.internal.impl ; package com.sun.org.apache.xerces.internal.impl ;
import com.sun.org.apache.xerces.internal.impl.Constants;
import com.sun.org.apache.xerces.internal.impl.XMLEntityHandler;
import com.sun.org.apache.xerces.internal.impl.io.ASCIIReader; import com.sun.org.apache.xerces.internal.impl.io.ASCIIReader;
import com.sun.org.apache.xerces.internal.impl.io.UCSReader; import com.sun.org.apache.xerces.internal.impl.io.UCSReader;
import com.sun.org.apache.xerces.internal.impl.io.UTF8Reader; import com.sun.org.apache.xerces.internal.impl.io.UTF8Reader;
@ -42,7 +40,6 @@ import com.sun.xml.internal.stream.StaxEntityResolverWrapper;
import com.sun.xml.internal.stream.StaxXMLInputSource; import com.sun.xml.internal.stream.StaxXMLInputSource;
import com.sun.xml.internal.stream.XMLEntityStorage; import com.sun.xml.internal.stream.XMLEntityStorage;
import java.io.*; import java.io.*;
import java.lang.reflect.Method;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.net.URL; import java.net.URL;
@ -59,7 +56,6 @@ import javax.xml.catalog.CatalogFeatures;
import javax.xml.catalog.CatalogFeatures.Feature; import javax.xml.catalog.CatalogFeatures.Feature;
import javax.xml.catalog.CatalogManager; import javax.xml.catalog.CatalogManager;
import javax.xml.catalog.CatalogResolver; import javax.xml.catalog.CatalogResolver;
import javax.xml.catalog.CatalogUriResolver;
import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLInputFactory;
import javax.xml.transform.Source; import javax.xml.transform.Source;
import jdk.xml.internal.JdkXmlUtils; import jdk.xml.internal.JdkXmlUtils;
@ -420,7 +416,6 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
private boolean fUseCatalog = true; private boolean fUseCatalog = true;
CatalogFeatures fCatalogFeatures; CatalogFeatures fCatalogFeatures;
CatalogResolver fCatalogResolver; CatalogResolver fCatalogResolver;
CatalogUriResolver fCatalogUriResolver;
private String fCatalogFile; private String fCatalogFile;
private String fDefer; private String fDefer;
@ -1044,6 +1039,7 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
} }
fCatalogFile = fCatalogFeatures.get(Feature.FILES); fCatalogFile = fCatalogFeatures.get(Feature.FILES);
if (fUseCatalog && fCatalogFile != null) { if (fUseCatalog && fCatalogFile != null) {
try {
if (fCatalogResolver == null) { if (fCatalogResolver == null) {
fCatalogResolver = CatalogManager.catalogResolver(fCatalogFeatures); fCatalogResolver = CatalogManager.catalogResolver(fCatalogFeatures);
} }
@ -1051,6 +1047,11 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
if (is != null && !is.isEmpty()) { if (is != null && !is.isEmpty()) {
staxInputSource = new StaxXMLInputSource(new XMLInputSource(is, true), true); staxInputSource = new StaxXMLInputSource(new XMLInputSource(is, true), true);
} }
} catch (CatalogException e) {
fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,"CatalogException",
new Object[]{SecuritySupport.sanitizePath(fCatalogFile)},
XMLErrorReporter.SEVERITY_FATAL_ERROR, e );
}
} }
} }
@ -1140,7 +1141,7 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
if (fUseCatalog && fCatalogFile != null) { if (fUseCatalog && fCatalogFile != null) {
/* /*
since the method can be called from various processors, both since the method can be called from various processors, both
CatalogResolver and CatalogUriResolver are used to attempt to find EntityResolver and URIResolver are used to attempt to find
a match a match
*/ */
InputSource is = null; InputSource is = null;
@ -1153,13 +1154,20 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver {
is = fCatalogResolver.resolveEntity(pid, literalSystemId); is = fCatalogResolver.resolveEntity(pid, literalSystemId);
} }
} catch (CatalogException e) {} } catch (CatalogException e) {}
if (is != null && !is.isEmpty()) { if (is != null && !is.isEmpty()) {
xmlInputSource = new XMLInputSource(is, true); xmlInputSource = new XMLInputSource(is, true);
} else if (literalSystemId != null) { } else if (literalSystemId != null) {
if (fCatalogUriResolver == null) { if (fCatalogResolver == null) {
fCatalogUriResolver = CatalogManager.catalogUriResolver(fCatalogFeatures); fCatalogResolver = CatalogManager.catalogResolver(fCatalogFeatures);
}
Source source = null;
try {
source = fCatalogResolver.resolve(literalSystemId, baseSystemId);
} catch (CatalogException e) {
throw new XNIException(e);
} }
Source source = fCatalogUriResolver.resolve(literalSystemId, baseSystemId);
if (source != null && !source.isEmpty()) { if (source != null && !source.isEmpty()) {
xmlInputSource = new XMLInputSource(publicId, source.getSystemId(), baseSystemId, true); xmlInputSource = new XMLInputSource(publicId, source.getSystemId(), baseSystemId, true);
} }

View file

@ -303,3 +303,5 @@
MaxElementDepthLimit=JAXP00010006: The element \"{0}\" has a depth of \"{1}\" that exceeds the limit \"{2}\" set by \"{3}\". MaxElementDepthLimit=JAXP00010006: The element \"{0}\" has a depth of \"{1}\" that exceeds the limit \"{2}\" set by \"{3}\".
EntityReplacementLimit=JAXP00010007: The total number of nodes in entity references is \"{0}\" that is over the limit \"{1}\" set by \"{2}\". EntityReplacementLimit=JAXP00010007: The total number of nodes in entity references is \"{0}\" that is over the limit \"{1}\" set by \"{2}\".
# Catalog 09
CatalogException=JAXP00090001: The CatalogResolver is enabled with the catalog \"{0}\", but a CatalogException is returned.

View file

@ -1,13 +1,13 @@
/* /*
* reserved comment block * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT REMOVE OR ALTER!
*/ */
/* /*
* Copyright 2001, 2002,2004 The Apache Software Foundation. * Licensed to the Apache Software Foundation (ASF) under one or more
* * contributor license agreements. See the NOTICE file distributed with
* Licensed under the Apache License, Version 2.0 (the "License"); * this work for additional information regarding copyright ownership.
* you may not use this file except in compliance with the License. * The ASF licenses this file to You under the Apache License, Version 2.0
* You may obtain a copy of the License at * (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
@ -28,6 +28,7 @@ import com.sun.org.apache.xerces.internal.xni.XNIException;
import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier; import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
import com.sun.org.apache.xerces.internal.xni.parser.XMLEntityResolver; import com.sun.org.apache.xerces.internal.xni.parser.XMLEntityResolver;
import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource; import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
import javax.xml.catalog.CatalogException;
import org.xml.sax.EntityResolver; import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource; import org.xml.sax.InputSource;
@ -132,6 +133,10 @@ public class EntityResolverWrapper
} }
throw new XNIException(ex); throw new XNIException(ex);
} }
catch (CatalogException e) {
throw new XNIException(e);
}
} }
// unable to resolve entity // unable to resolve entity

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
*/ */
/* /*
* Licensed to the Apache Software Foundation (ASF) under one or more * Licensed to the Apache Software Foundation (ASF) under one or more
@ -75,7 +75,6 @@ import javax.xml.catalog.CatalogException;
import javax.xml.catalog.CatalogFeatures; import javax.xml.catalog.CatalogFeatures;
import javax.xml.catalog.CatalogManager; import javax.xml.catalog.CatalogManager;
import javax.xml.catalog.CatalogResolver; import javax.xml.catalog.CatalogResolver;
import javax.xml.catalog.CatalogUriResolver;
import javax.xml.transform.Source; import javax.xml.transform.Source;
import jdk.xml.internal.JdkXmlUtils; import jdk.xml.internal.JdkXmlUtils;
import org.xml.sax.InputSource; import org.xml.sax.InputSource;
@ -371,7 +370,6 @@ public class XIncludeHandler
private boolean fUseCatalog = true; private boolean fUseCatalog = true;
CatalogFeatures fCatalogFeatures; CatalogFeatures fCatalogFeatures;
CatalogResolver fCatalogResolver; CatalogResolver fCatalogResolver;
CatalogUriResolver fCatalogUriResolver;
private String fCatalogFile; private String fCatalogFile;
private String fDefer; private String fDefer;
@ -1638,10 +1636,10 @@ public class XIncludeHandler
*/ */
Source source = null; Source source = null;
try { try {
if (fCatalogUriResolver == null) { if (fCatalogResolver == null) {
fCatalogUriResolver = CatalogManager.catalogUriResolver(fCatalogFeatures); fCatalogResolver = CatalogManager.catalogResolver(fCatalogFeatures);
} }
source = fCatalogUriResolver.resolve(href, fCurrentBaseURI.getExpandedSystemId()); source = fCatalogResolver.resolve(href, fCurrentBaseURI.getExpandedSystemId());
} catch (CatalogException e) {} } catch (CatalogException e) {}
if (source != null && !source.isEmpty()) { if (source != null && !source.isEmpty()) {
@ -1669,7 +1667,7 @@ public class XIncludeHandler
includedSource.getBaseSystemId(), accept, acceptLanguage); includedSource.getBaseSystemId(), accept, acceptLanguage);
} }
} }
catch (IOException e) { catch (IOException | CatalogException e) {
reportResourceError( reportResourceError(
"XMLResourceError", "XMLResourceError",
new Object[] { href, e.getMessage()}); new Object[] { href, e.getMessage()});

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -33,6 +33,7 @@ import javax.xml.stream.XMLStreamReader;
import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier; import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
import com.sun.org.apache.xerces.internal.xni.XNIException; import com.sun.org.apache.xerces.internal.xni.XNIException;
import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource; import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
import javax.xml.catalog.CatalogException;
/** /**
* *
@ -58,11 +59,11 @@ public class StaxEntityResolverWrapper {
public StaxXMLInputSource resolveEntity(XMLResourceIdentifier resourceIdentifier) public StaxXMLInputSource resolveEntity(XMLResourceIdentifier resourceIdentifier)
throws XNIException, java.io.IOException { throws XNIException, java.io.IOException {
Object object = null ; Object object = null ;
try{ try {
object = fStaxResolver.resolveEntity(resourceIdentifier.getPublicId(), resourceIdentifier.getLiteralSystemId(), object = fStaxResolver.resolveEntity(resourceIdentifier.getPublicId(), resourceIdentifier.getLiteralSystemId(),
resourceIdentifier.getBaseSystemId(), null); resourceIdentifier.getBaseSystemId(), null);
return getStaxInputSource(object) ; return getStaxInputSource(object) ;
}catch(XMLStreamException streamException){ } catch(XMLStreamException | CatalogException streamException){
throw new XNIException(streamException) ; throw new XNIException(streamException) ;
} }
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -42,9 +42,9 @@ import java.util.stream.Stream;
* <p> * <p>
* A catalog can be used in two situations: * A catalog can be used in two situations:
* <ul> * <ul>
* <li>Locate the replacement text for an external entity; * <li>Locate the external resources with a public or system identifier;
* </li> * </li>
* <li>Locate an alternate URI reference for a resource. * <li>Locate an alternate URI reference with an URI.
* </li> * </li>
* </ul> * </ul>
* <p> * <p>

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -76,17 +76,6 @@ public final class CatalogManager {
return new CatalogResolverImpl(catalog); return new CatalogResolverImpl(catalog);
} }
/**
* Creates an instance of a {@code CatalogUriResolver} using the specified catalog.
*
* @param catalog the catalog instance
* @return an instance of a {@code CatalogResolver}
*/
public static CatalogUriResolver catalogUriResolver(Catalog catalog) {
if (catalog == null) CatalogMessages.reportNPEOnNull("catalog", null);
return new CatalogUriResolverImpl(catalog);
}
/** /**
* Creates an instance of a {@code CatalogResolver} using the specified feature * Creates an instance of a {@code CatalogResolver} using the specified feature
* settings and path to one or more catalog files. * settings and path to one or more catalog files.
@ -115,33 +104,4 @@ public final class CatalogManager {
Catalog catalog = catalog(features, paths); Catalog catalog = catalog(features, paths);
return new CatalogResolverImpl(catalog); return new CatalogResolverImpl(catalog);
} }
/**
* Creates an instance of a {@code CatalogUriResolver} using the specified
* feature settings and path to one or more catalog files.
* <p>
* If {@code paths} is empty, system property {@code javax.xml.catalog.files}
* will be read to locate the initial list of catalog files.
* <p>
* If more than one catalog files are specified through the paths argument or
* {@code javax.xml.catalog.files} property, the first entry is considered
* the main catalog, while others are treated as alternative catalogs after
* those referenced by the {@code nextCatalog} elements in the main catalog.
* <p>
* As specified in
* <a href="https://www.oasis-open.org/committees/download.php/14809/xml-catalogs.html#s.res.fail">
* XML Catalogs, OASIS Standard V1.1</a>, invalid path entries will be ignored.
* No error will be reported. In case all entries are invalid, the resolver
* will return as no mapping is found.
*
* @param features the catalog features
* @param paths the path(s) to one or more catalogs
*
* @return an instance of a {@code CatalogUriResolver}
* @throws CatalogException If an error occurs while parsing the catalog
*/
public static CatalogUriResolver catalogUriResolver(CatalogFeatures features, String... paths) {
Catalog catalog = catalog(features, paths);
return new CatalogUriResolverImpl(catalog);
}
} }

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -24,32 +24,90 @@
*/ */
package javax.xml.catalog; package javax.xml.catalog;
import java.io.InputStream;
import javax.xml.stream.XMLResolver;
import javax.xml.transform.Source;
import javax.xml.transform.URIResolver;
import org.w3c.dom.ls.LSInput;
import org.w3c.dom.ls.LSResourceResolver;
import org.xml.sax.EntityResolver; import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource; import org.xml.sax.InputSource;
/** /**
* A SAX EntityResolver that uses catalogs to resolve references. * A Catalog Resolver that implements SAX {@link org.xml.sax.EntityResolver},
* StAX {@link javax.xml.stream.XMLResolver},
* DOM LS {@link org.w3c.dom.ls.LSResourceResolver} used by Schema Validation, and
* Transform {@link javax.xml.transform.URIResolver}, and resolves
* external references using catalogs.
* <p>
* The <a href="https://www.oasis-open.org/committees/download.php/14809/xml-catalogs.html">
* Catalog Standard</a> distinguished {@code external identifiers} from {@code uri entries}
* as being used to solely identify DTDs, while {@code uri entries} for
* other resources such as stylesheets and schema. The Java APIs, such as
* {@link javax.xml.stream.XMLResolver} and {@link org.w3c.dom.ls.LSResourceResolver}
* however, make no such distinction.
* In consistent with the existing Java API, this CatalogResolver recognizes a
* system identifier as an URI and will search both {@code system} and {@code uri}
* entries in a catalog in order to find a matching entry.
* <p>
* The search is started in the current catalog. If a match is found,
* no further attempt will be made. Only if there is no match in the current
* catalog, will alternate catalogs including delegate and next catalogs be considered.
* <p>
* <h3>Search Order</h3>
* The resolver will first search the system-type of entries with the specified
* {@code systemId}. The system entries include {@code system},
* {@code rewriteSystem} and {@code systemSuffix} entries.
* <p>
* If no match is found, {@code public} entries may be searched in accordance with
* the {@code prefer} attribute.
* <p>
* <b>The {@code prefer} attribute</b>: if the {@code prefer} is public,
* and there is no match found through the system entries, {@code public} entries
* will be considered. If it is not specified, the {@code prefer} is public
* by default (Note that by the OASIS standard, system entries will always
* be considered before public entries. Prefer public means that public entries
* will be matched when both system and public identifiers are specified.
* In general therefore, prefer public is recommended.)
* <p>
* If no match is found with the {@code systemId} and {@code public} identifier,
* the resolver will continue searching {@code uri} entries
* with the specified {@code systemId} or {@code href}. The {@code uri} entries
* include {@code uri}, {@code rewriteURI}, and {@code uriSuffix} entries.
*
* <p>
* <h3>Error Handling</h3>
* The interfaces that the CatalogResolver extend specified checked exceptions, including:
* <ul>
* <li>
* {@link org.xml.sax.SAXException} and {@link java.io.IOException} by
* {@link org.xml.sax.EntityResolver#resolveEntity(java.lang.String, java.lang.String)}
* </li>
* <li>
* {@link javax.xml.stream.XMLStreamException} by
* {@link javax.xml.stream.XMLResolver#resolveEntity(java.lang.String, java.lang.String, java.lang.String, java.lang.String)}
* </li>
* <li>
* {@link javax.xml.transform.TransformerException} by
* {@link javax.xml.transform.URIResolver#resolve(java.lang.String, java.lang.String)}
* </li>
* </ul>
* <p>
* The CatalogResolver however, will throw {@link javax.xml.catalog.CatalogException}
* only when {@code javax.xml.catalog.resolve} is specified as {@code strict}.
* For applications that expect to handle the checked Exceptions, it may be
* necessary to use a custom resolver to wrap the CatalogResolver or implement it
* with a {@link javax.xml.catalog.Catalog} object.
* *
* @since 9 * @since 9
*/ */
public interface CatalogResolver extends EntityResolver { public interface CatalogResolver extends EntityResolver, XMLResolver,
URIResolver, LSResourceResolver {
/** /**
* The method searches through the catalog entries in the main and * Implements {@link org.xml.sax.EntityResolver}. The method searches through
* alternative catalogs to attempt to find a match with the specified publicId * the catalog entries in the main and alternative catalogs to attempt to find
* or systemId. * a match with the specified {@code publicId} or systemId.
* <p>
* For resolving external entities, system entries will be matched before
* the public entries.
* <p>
* <b>The {@code prefer} attribute</b>: if the {@code prefer} is public,
* and there is no match found through the system entries, public entries
* will be considered. If it is not specified, the {@code prefer} is public
* by default (Note that by the OASIS standard, system entries will always
* be considered first when the external system identifier is specified.
* Prefer public means that public entries will be matched when both system
* and public identifiers are specified. In general therefore, prefer
* public is recommended.)
* *
* @param publicId the public identifier of the external entity being * @param publicId the public identifier of the external entity being
* referenced, or null if none was supplied * referenced, or null if none was supplied
@ -59,15 +117,123 @@ public interface CatalogResolver extends EntityResolver {
* requires a system identifier on all external entities, so this value is * requires a system identifier on all external entities, so this value is
* always specified. * always specified.
* *
* @return a {@link org.xml.sax.InputSource} object if a mapping is found. If no mapping is * @return a {@link org.xml.sax.InputSource} object if a mapping is found.
* found, returns a {@link org.xml.sax.InputSource} object containing an empty * If no mapping is found, returns a {@link org.xml.sax.InputSource} object
* {@link java.io.Reader} if the {@code javax.xml.catalog.resolve} property * containing an empty {@link java.io.Reader} if the
* is set to {@code ignore}; returns null if the * {@code javax.xml.catalog.resolve} property is set to {@code ignore};
* returns null if the
* {@code javax.xml.catalog.resolve} property is set to {@code continue}. * {@code javax.xml.catalog.resolve} property is set to {@code continue}.
* *
* @throws CatalogException if no mapping is found and * @throws CatalogException if no mapping is found and
* {@code javax.xml.catalog.resolve} is specified as strict * {@code javax.xml.catalog.resolve} is specified as {@code strict}
*/ */
@Override @Override
public InputSource resolveEntity(String publicId, String systemId); public InputSource resolveEntity(String publicId, String systemId);
/**
* Implements URIResolver. The method searches through the catalog entries
* in the main and alternative catalogs to attempt to find a match
* with the specified {@code href} attribute. The {@code href} attribute will
* be used literally, with no attempt to be made absolute to the {@code base}.
* <p>
* If the value is an URN, the {@code href} attribute is recognized as a
* {@code publicId}, and used to search {@code public} entries.
* If the value is an URI, it is taken as a {@code systemId}, and used to
* search both {@code system} and {@code uri} entries.
*
*
* @param href the href attribute that specifies the URI of a style sheet,
* which may be relative or absolute
* @param base The base URI against which the href attribute will be made
* absolute if the absolute URI is required
*
* @return a {@link javax.xml.transform.Source} object if a mapping is found.
* If no mapping is found, returns an empty {@link javax.xml.transform.Source}
* object if the {@code javax.xml.catalog.resolve} property is set to
* {@code ignore};
* returns a {@link javax.xml.transform.Source} object with the original URI
* (href, or href resolved with base if base is not null) if the
* {@code javax.xml.catalog.resolve} property is set to {@code continue}.
*
* @throws CatalogException if no mapping is found and
* {@code javax.xml.catalog.resolve} is specified as {@code strict}
*/
@Override
public Source resolve(String href, String base);
/**
* Implements {@link javax.xml.stream.XMLResolver}. For the purpose of resolving
* {@code publicId} and {@code systemId}, this method is equivalent to
* {@link #resolveEntity(java.lang.String, java.lang.String) }.
* <p>
* The {@code systemId} will be used literally, with no attempt to be made
* absolute to the {@code baseUri}. The {@code baseUri} and {@code namespace}
* are not used in the search for a match in a catalog. However, a relative
* {@code systemId} in an xml source may have been made absolute by the parser
* with the {@code baseURI}, thus making it unable to find a {@code system} entry.
* In such a case, a {@code systemSuffix} entry is recommended over a
* {@code system} entry.
*
* @param publicId the public identifier of the external entity being
* referenced, or null if none was supplied
*
* @param systemId the system identifier of the external entity being
* referenced. A system identifier is required on all external entities. XML
* requires a system identifier on all external entities, so this value is
* always specified.
* @param baseUri the absolute base URI, not used by the CatalogResolver
* @param namespace the namespace of the entity to resolve, not used by the
* CatalogResolver.
*
* @return an {@link java.io.InputStream} object if a mapping is found; null
* if no mapping is found and the {@code javax.xml.catalog.resolve} property
* is set to {@code continue} or {@code ignore}. Note that for XMLResolver,
* it is not possible to ignore a reference, {@code ignore} is therefore
* treated the same as {@code continue}.
*
* @throws CatalogException if no mapping is found and
* {@code javax.xml.catalog.resolve} is specified as {@code strict}
*/
@Override
public InputStream resolveEntity(String publicId, String systemId,
String baseUri, String namespace);
/**
* Implements {@link org.w3c.dom.ls.LSResourceResolver}. For the purpose of
* resolving {@code publicId} and {@code systemId}, this method is equivalent
* to {@link #resolveEntity(java.lang.String, java.lang.String) }.
* <p>
* The {@code systemId} will be used literally, with no attempt to be made
* absolute to the {@code baseUri}. The {@code baseUri}, {@code namespaceUri}
* and {@code type} are not used in the search for a match in a catalog.
* However, a relative {@code systemId} in a source may have been made absolute
* by the parser with the {@code baseURI}, thus making it unable to find a
* {@code system} entry. In such a case, a {@code systemSuffix} entry is
* recommended over a {@code system} entry.
*
* @param type the type of the resource being resolved,
* not used by the CatalogResolver
* @param namespaceUri the namespace of the resource being resolved,
* not used by the CatalogResolver
* @param publicId the public identifier of the external entity being
* referenced, or {@code null} if no public identifier was
* supplied or if the resource is not an entity.
* @param systemId the system identifier, an URI reference of the
* external resource being referenced
* @param baseUri the absolute base URI, not used by the CatalogResolver
*
* @return a {@link org.w3c.dom.ls.LSInput} object if a mapping is found; null
* if no mapping is found and the {@code javax.xml.catalog.resolve} property
* is set to {@code continue} or {@code ignore}. Note that for
* {@link org.w3c.dom.ls.LSResourceResolver}, it is not possible to ignore a
* reference, {@code ignore} is therefore treated the same as {@code continue}.
*
* @throws CatalogException if no mapping is found and
* {@code javax.xml.catalog.resolve} is specified as {@code strict}
*/
@Override
public LSInput resolveResource(String type, String namespaceUri,
String publicId, String systemId, String baseUri);
} }

View file

@ -24,15 +24,27 @@
*/ */
package javax.xml.catalog; package javax.xml.catalog;
import com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader; import java.io.StringReader;
import java.util.Iterator; import java.net.URL;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.Source;
import javax.xml.transform.sax.SAXSource;
import org.w3c.dom.ls.LSInput;
import org.xml.sax.InputSource; import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
/** /**
* A SAX EntityResolver/JAXP URIResolver that uses catalogs. * Implements CatalogResolver.
* *
* <p> * <p>
* This class implements both a SAX EntityResolver and a JAXP URIResolver. * This class implements a SAX EntityResolver, StAX XMLResolver,
* Schema Validation LSResourceResolver and Transform URIResolver.
* *
* *
* @since 9 * @since 9
@ -49,9 +61,14 @@ final class CatalogResolverImpl implements CatalogResolver {
this.catalog = catalog; this.catalog = catalog;
} }
/*
Implements the EntityResolver interface
*/
@Override @Override
public InputSource resolveEntity(String publicId, String systemId) { public InputSource resolveEntity(String publicId, String systemId) {
//8150187: NPE expected if the system identifier is null for CatalogResolver
CatalogMessages.reportNPEOnNull("systemId", systemId); CatalogMessages.reportNPEOnNull("systemId", systemId);
//Normalize publicId and systemId //Normalize publicId and systemId
systemId = Normalizer.normalizeURI(Util.getNotNullOrEmpty(systemId)); systemId = Normalizer.normalizeURI(Util.getNotNullOrEmpty(systemId));
publicId = Normalizer.normalizePublicId(Normalizer.decodeURN(Util.getNotNullOrEmpty(publicId))); publicId = Normalizer.normalizePublicId(Normalizer.decodeURN(Util.getNotNullOrEmpty(publicId)));
@ -87,4 +104,242 @@ final class CatalogResolverImpl implements CatalogResolver {
return null; return null;
} }
/*
Implements the URIResolver interface
*/
CatalogResolverImpl entityResolver;
@Override
public Source resolve(String href, String base) {
CatalogMessages.reportNPEOnNull("href", href);
href = Util.getNotNullOrEmpty(href);
base = Util.getNotNullOrEmpty(base);
String result = null;
CatalogImpl c = (CatalogImpl)catalog;
String uri = Normalizer.normalizeURI(href);
//check whether uri is an urn
if (uri != null && uri.startsWith(Util.URN)) {
String publicId = Normalizer.decodeURN(uri);
if (publicId != null) {
result = Util.resolve(c, publicId, null);
}
}
//if no match with a public id, continue search for an URI
if (result == null) {
//remove fragment if any.
int hashPos = uri.indexOf("#");
if (hashPos >= 0) {
uri = uri.substring(0, hashPos);
}
//search the current catalog
result = Util.resolve(c, null, uri);
}
//Report error or return the URI as is when no match is found
if (result == null) {
GroupEntry.ResolveType resolveType = c.getResolve();
switch (resolveType) {
case IGNORE:
return new SAXSource(new InputSource(new StringReader("")));
case STRICT:
CatalogMessages.reportError(CatalogMessages.ERR_NO_URI_MATCH,
new Object[]{href, base});
}
try {
URL url = null;
if (base == null) {
url = new URL(uri);
result = url.toString();
} else {
URL baseURL = new URL(base);
url = (href.length() == 0 ? baseURL : new URL(baseURL, uri));
result = url.toString();
}
} catch (java.net.MalformedURLException mue) {
CatalogMessages.reportError(CatalogMessages.ERR_CREATING_URI,
new Object[]{href, base});
}
}
SAXSource source = new SAXSource();
source.setInputSource(new InputSource(result));
setEntityResolver(source);
return source;
}
/**
* Establish an entityResolver for newly resolved URIs.
* <p>
* This is called from the URIResolver to set an EntityResolver on the SAX
* parser to be used for new XML documents that are encountered as a result
* of the document() function, xsl:import, or xsl:include. This is done
* because the XSLT processor calls out to the SAXParserFactory itself to
* create a new SAXParser to parse the new document. The new parser does not
* automatically inherit the EntityResolver of the original (although
* arguably it should). Quote from JAXP specification on Class
* SAXTransformerFactory:
* <p>
* {@code If an application wants to set the ErrorHandler or EntityResolver
* for an XMLReader used during a transformation, it should use a URIResolver
* to return the SAXSource which provides (with getXMLReader) a reference to
* the XMLReader}
*
*/
private void setEntityResolver(SAXSource source) {
XMLReader reader = source.getXMLReader();
if (reader == null) {
SAXParserFactory spFactory = new SAXParserFactoryImpl();
spFactory.setNamespaceAware(true);
try {
reader = spFactory.newSAXParser().getXMLReader();
} catch (ParserConfigurationException | SAXException ex) {
CatalogMessages.reportRunTimeError(CatalogMessages.ERR_PARSER_CONF, ex);
}
}
if (entityResolver != null) {
entityResolver = new CatalogResolverImpl(catalog);
}
reader.setEntityResolver(entityResolver);
source.setXMLReader(reader);
}
@Override
public InputStream resolveEntity(String publicId, String systemId, String baseUri, String namespace) {
InputSource is = resolveEntity(publicId, systemId);
if (is != null && !is.isEmpty()) {
try {
return new URL(is.getSystemId()).openStream();
} catch (IOException ex) {
//considered as no mapping.
}
}
GroupEntry.ResolveType resolveType = ((CatalogImpl) catalog).getResolve();
switch (resolveType) {
case IGNORE:
return null;
case STRICT:
CatalogMessages.reportError(CatalogMessages.ERR_NO_MATCH,
new Object[]{publicId, systemId});
}
//no action, allow the parser to continue
return null;
}
@Override
public LSInput resolveResource(String type, String namespaceURI, String publicId, String systemId, String baseURI) {
InputSource is = resolveEntity(publicId, systemId);
if (is != null && !is.isEmpty()) {
return new LSInputImpl(is.getSystemId());
}
GroupEntry.ResolveType resolveType = ((CatalogImpl) catalog).getResolve();
switch (resolveType) {
case IGNORE:
return null;
case STRICT:
CatalogMessages.reportError(CatalogMessages.ERR_NO_MATCH,
new Object[]{publicId, systemId});
}
//no action, allow the parser to continue
return null;
}
/**
* Implements LSInput. All that we need is the systemId since the Catalog
* has already resolved it.
*/
class LSInputImpl implements LSInput {
private String systemId;
public LSInputImpl(String systemId) {
this.systemId = systemId;
}
@Override
public Reader getCharacterStream() {
return null;
}
@Override
public void setCharacterStream(Reader characterStream) {
}
@Override
public InputStream getByteStream() {
return null;
}
@Override
public void setByteStream(InputStream byteStream) {
}
@Override
public String getStringData() {
return null;
}
@Override
public void setStringData(String stringData) {
}
@Override
public String getSystemId() {
return systemId;
}
@Override
public void setSystemId(String systemId) {
this.systemId = systemId;
}
@Override
public String getPublicId() {
return null;
}
@Override
public void setPublicId(String publicId) {
}
@Override
public String getBaseURI() {
return null;
}
@Override
public void setBaseURI(String baseURI) {
}
@Override
public String getEncoding() {
return null;
}
@Override
public void setEncoding(String encoding) {
}
@Override
public boolean getCertifiedText() {
return false;
}
@Override
public void setCertifiedText(boolean certifiedText) {
}
}
} }

View file

@ -1,58 +0,0 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.xml.catalog;
import javax.xml.transform.Source;
import javax.xml.transform.URIResolver;
/**
* A JAXP URIResolver that uses catalogs to resolve references.
*
* @since 9
*/
public interface CatalogUriResolver extends URIResolver {
/**
* The method searches through the catalog entries in the main and
* alternative catalogs to attempt to find a match with the specified URI.
*
* @param href an href attribute, which may be relative or absolute
* @param base The base URI against which the href attribute will be made
* absolute if the absolute URI is required
*
* @return a {@link javax.xml.transform.Source} object if a mapping is found.
* If no mapping is found, returns an empty {@link javax.xml.transform.Source}
* object if the {@code javax.xml.catalog.resolve} property is set to
* {@code ignore};
* returns a {@link javax.xml.transform.Source} object with the original URI
* (href, or href resolved with base if base is not null) if the
* {@code javax.xml.catalog.resolve} property is set to {@code continue}.
*
* @throws CatalogException if no mapping is found and
* {@code javax.xml.catalog.resolve} is specified as strict
*/
@Override
public Source resolve(String href, String base);
}

View file

@ -1,191 +0,0 @@
/*
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.xml.catalog;
import com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl;
import java.io.StringReader;
import java.net.URL;
import java.util.Iterator;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.Source;
import javax.xml.transform.sax.SAXSource;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
/**
* A SAX EntityResolver/JAXP URIResolver that uses catalogs.
* <p>
* This class implements both a SAX EntityResolver and a JAXP URIResolver.
*
*
* @since 9
*/
final class CatalogUriResolverImpl implements CatalogUriResolver {
Catalog catalog;
CatalogResolverImpl entityResolver;
/**
* Construct an instance of the CatalogResolver from a Catalog.
*
* @param catalog A Catalog.
*/
public CatalogUriResolverImpl(Catalog catalog) {
this.catalog = catalog;
}
@Override
public Source resolve(String href, String base) {
href = Util.getNotNullOrEmpty(href);
base = Util.getNotNullOrEmpty(base);
if (href == null) return null;
String result = null;
CatalogImpl c = (CatalogImpl)catalog;
String uri = Normalizer.normalizeURI(href);
//check whether uri is an urn
if (uri != null && uri.startsWith(Util.URN)) {
String publicId = Normalizer.decodeURN(uri);
if (publicId != null) {
result = Util.resolve(c, publicId, null);
}
}
//if no match with a public id, continue search for an URI
if (result == null) {
//remove fragment if any.
int hashPos = uri.indexOf("#");
if (hashPos >= 0) {
uri = uri.substring(0, hashPos);
}
//search the current catalog
result = resolve(c, uri);
}
//Report error or return the URI as is when no match is found
if (result == null) {
GroupEntry.ResolveType resolveType = c.getResolve();
switch (resolveType) {
case IGNORE:
return new SAXSource(new InputSource(new StringReader("")));
case STRICT:
CatalogMessages.reportError(CatalogMessages.ERR_NO_URI_MATCH,
new Object[]{href, base});
}
try {
URL url = null;
if (base == null) {
url = new URL(uri);
result = url.toString();
} else {
URL baseURL = new URL(base);
url = (href.length() == 0 ? baseURL : new URL(baseURL, uri));
result = url.toString();
}
} catch (java.net.MalformedURLException mue) {
CatalogMessages.reportError(CatalogMessages.ERR_CREATING_URI,
new Object[]{href, base});
}
}
SAXSource source = new SAXSource();
source.setInputSource(new InputSource(result));
setEntityResolver(source);
return source;
}
/**
* Resolves the publicId or systemId to one specified in the catalog.
* @param catalog the catalog
* @param href an href attribute, which may be relative or absolute
* @return the resolved systemId if a match is found, null otherwise
*/
String resolve(CatalogImpl catalog, String href) {
String result = null;
//search the current catalog
catalog.reset();
if (href != null) {
result = catalog.matchURI(href);
}
//mark the catalog as having been searched before trying alternatives
catalog.markAsSearched();
//search alternative catalogs
if (result == null) {
Iterator<Catalog> iter = catalog.catalogs().iterator();
while (iter.hasNext()) {
result = resolve((CatalogImpl)iter.next(), href);
if (result != null) {
break;
}
}
}
return result;
}
/**
* Establish an entityResolver for newly resolved URIs.
* <p>
* This is called from the URIResolver to set an EntityResolver on the SAX
* parser to be used for new XML documents that are encountered as a result
* of the document() function, xsl:import, or xsl:include. This is done
* because the XSLT processor calls out to the SAXParserFactory itself to
* create a new SAXParser to parse the new document. The new parser does not
* automatically inherit the EntityResolver of the original (although
* arguably it should). Quote from JAXP specification on Class
* SAXTransformerFactory:
* <p>
* {@code If an application wants to set the ErrorHandler or EntityResolver
* for an XMLReader used during a transformation, it should use a URIResolver
* to return the SAXSource which provides (with getXMLReader) a reference to
* the XMLReader}
*
*/
private void setEntityResolver(SAXSource source) {
XMLReader reader = source.getXMLReader();
if (reader == null) {
SAXParserFactory spFactory = new SAXParserFactoryImpl();
spFactory.setNamespaceAware(true);
try {
reader = spFactory.newSAXParser().getXMLReader();
} catch (ParserConfigurationException | SAXException ex) {
CatalogMessages.reportRunTimeError(CatalogMessages.ERR_PARSER_CONF, ex);
}
}
if (entityResolver != null) {
entityResolver = new CatalogResolverImpl(catalog);
}
reader.setEntityResolver(entityResolver);
source.setXMLReader(reader);
}
}

View file

@ -55,6 +55,9 @@ class Util {
* prefer "public": attempts to resolve with a system entry; * prefer "public": attempts to resolve with a system entry;
* attempts to resolve with a public entry if no matching * attempts to resolve with a public entry if no matching
* system entry is found. * system entry is found.
*
* If no match is found, continue searching uri entries
*
* @param catalog the catalog * @param catalog the catalog
* @param publicId the publicId * @param publicId the publicId
* @param systemId the systemId * @param systemId the systemId
@ -77,6 +80,10 @@ class Util {
resolvedSystemId = catalog.matchPublic(publicId); resolvedSystemId = catalog.matchPublic(publicId);
} }
if (resolvedSystemId == null && systemId != null) {
resolvedSystemId = catalog.matchURI(systemId);
}
//mark the catalog as having been searched before trying alternatives //mark the catalog as having been searched before trying alternatives
catalog.markAsSearched(); catalog.markAsSearched();

View file

@ -64,4 +64,3 @@ public class CatalogReferCircularityTest {
{ "catalogReferCircle-left.xml" } }; { "catalogReferCircle-left.xml" } };
} }
} }

View file

@ -69,4 +69,3 @@ public class DefaultFeaturesTest {
{ Feature.RESOLVE, CatalogTestUtils.RESOLVE_STRICT } }; { Feature.RESOLVE, CatalogTestUtils.RESOLVE_STRICT } };
} }
} }

View file

@ -86,4 +86,3 @@ public class DeferFeatureTest {
return (int) method.invoke(catalog); return (int) method.invoke(catalog);
} }
} }

View file

@ -100,4 +100,3 @@ public class DelegatePublicTest {
return catalogResolver("delegatePublic.xml"); return catalogResolver("delegatePublic.xml");
} }
} }

View file

@ -100,4 +100,3 @@ public class DelegateSystemTest {
return catalogResolver("delegateSystem.xml"); return catalogResolver("delegateSystem.xml");
} }
} }

View file

@ -27,8 +27,8 @@ import static catalog.CatalogTestUtils.catalogUriResolver;
import static catalog.ResolutionChecker.checkUriResolution; import static catalog.ResolutionChecker.checkUriResolution;
import static catalog.ResolutionChecker.expectExceptionOnUri; import static catalog.ResolutionChecker.expectExceptionOnUri;
import javax.xml.catalog.CatalogResolver;
import javax.xml.catalog.CatalogException; import javax.xml.catalog.CatalogException;
import javax.xml.catalog.CatalogUriResolver;
import org.testng.annotations.DataProvider; import org.testng.annotations.DataProvider;
import org.testng.annotations.Listeners; import org.testng.annotations.Listeners;
@ -95,8 +95,7 @@ public class DelegateUriTest {
CatalogException.class } }; CatalogException.class } };
} }
private CatalogUriResolver createResolver() { private CatalogResolver createResolver() {
return catalogUriResolver("delegateUri.xml"); return catalogUriResolver("delegateUri.xml");
} }
} }

View file

@ -131,4 +131,3 @@ public class GroupTest {
return catalogResolver(CATALOG_GROUP); return catalogResolver(CATALOG_GROUP);
} }
} }

View file

@ -33,7 +33,6 @@ import static catalog.ResolutionChecker.checkUriResolution;
import javax.xml.catalog.CatalogException; import javax.xml.catalog.CatalogException;
import javax.xml.catalog.CatalogResolver; import javax.xml.catalog.CatalogResolver;
import javax.xml.catalog.CatalogUriResolver;
import org.testng.annotations.DataProvider; import org.testng.annotations.DataProvider;
import org.testng.annotations.Listeners; import org.testng.annotations.Listeners;
@ -56,6 +55,7 @@ public class LoadCatalogTest {
private static final String CATALOG_DUMMY = "dummy.xml"; private static final String CATALOG_DUMMY = "dummy.xml";
private static final String ID_ALICE = "http://remote/dtd/alice/docAlice.dtd"; private static final String ID_ALICE = "http://remote/dtd/alice/docAlice.dtd";
private static final String ID_ALICE_URI = "http://remote/dtd/uri/alice/docAlice.dtd";
private static final String ID_DUMMY = "http://remote/dtd/doc.dtd"; private static final String ID_DUMMY = "http://remote/dtd/doc.dtd";
@Test(dataProvider = "entityResolver") @Test(dataProvider = "entityResolver")
@ -79,8 +79,8 @@ public class LoadCatalogTest {
} }
@Test(dataProvider = "uriResolver") @Test(dataProvider = "uriResolver")
public void testMatchOnUriResolver(CatalogUriResolver resolver) { public void testMatchOnUriResolver(CatalogResolver resolver) {
checkUriResolution(resolver, ID_ALICE, checkUriResolution(resolver, ID_ALICE_URI,
"http://local/dtd/docAliceURI.dtd"); "http://local/dtd/docAliceURI.dtd");
} }
@ -121,4 +121,3 @@ public class LoadCatalogTest {
{ new String[] { CATALOG_LOADCATALOGFILES } } }; { new String[] { CATALOG_LOADCATALOGFILES } } };
} }
} }

View file

@ -30,7 +30,6 @@ import static catalog.ResolutionChecker.checkSysIdResolution;
import static catalog.ResolutionChecker.checkUriResolution; import static catalog.ResolutionChecker.checkUriResolution;
import javax.xml.catalog.CatalogResolver; import javax.xml.catalog.CatalogResolver;
import javax.xml.catalog.CatalogUriResolver;
import org.testng.annotations.DataProvider; import org.testng.annotations.DataProvider;
import org.testng.annotations.Listeners; import org.testng.annotations.Listeners;
@ -154,9 +153,8 @@ public class NextCatalogTest {
CATALOG_NEXTCATALOGRIGHT); CATALOG_NEXTCATALOGRIGHT);
} }
private CatalogUriResolver createUriResolver() { private CatalogResolver createUriResolver() {
return catalogUriResolver(CATALOG_NEXTCATALOGLEFT, return catalogUriResolver(CATALOG_NEXTCATALOGLEFT,
CATALOG_NEXTCATALOGRIGHT); CATALOG_NEXTCATALOGRIGHT);
} }
} }

View file

@ -30,7 +30,6 @@ import static catalog.ResolutionChecker.checkSysIdResolution;
import static catalog.ResolutionChecker.checkUriResolution; import static catalog.ResolutionChecker.checkUriResolution;
import javax.xml.catalog.CatalogResolver; import javax.xml.catalog.CatalogResolver;
import javax.xml.catalog.CatalogUriResolver;
import org.testng.annotations.DataProvider; import org.testng.annotations.DataProvider;
import org.testng.annotations.Listeners; import org.testng.annotations.Listeners;
@ -111,8 +110,7 @@ public class NormalizationTest {
return catalogResolver(CATALOG_NORMALIZATION); return catalogResolver(CATALOG_NORMALIZATION);
} }
private CatalogUriResolver createUriResolver() { private CatalogResolver createUriResolver() {
return catalogUriResolver(CATALOG_NORMALIZATION); return catalogUriResolver(CATALOG_NORMALIZATION);
} }
} }

View file

@ -81,4 +81,3 @@ public class PreferFeatureTest {
"preferFeature.xml"); "preferFeature.xml");
} }
} }

View file

@ -92,4 +92,3 @@ public class PreferTest {
return catalogResolver("prefer.xml"); return catalogResolver("prefer.xml");
} }
} }

View file

@ -70,4 +70,3 @@ public class PublicFamilyTest {
return catalogResolver("publicFamily.xml"); return catalogResolver("publicFamily.xml");
} }
} }

View file

@ -92,4 +92,3 @@ public class PublicTest {
return catalogResolver(CATALOG_PUBLIC); return catalogResolver(CATALOG_PUBLIC);
} }
} }

View file

@ -38,7 +38,6 @@ import javax.xml.catalog.CatalogException;
import javax.xml.catalog.CatalogFeatures; import javax.xml.catalog.CatalogFeatures;
import javax.xml.catalog.CatalogFeatures.Feature; import javax.xml.catalog.CatalogFeatures.Feature;
import javax.xml.catalog.CatalogResolver; import javax.xml.catalog.CatalogResolver;
import javax.xml.catalog.CatalogUriResolver;
import org.testng.annotations.Listeners; import org.testng.annotations.Listeners;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -93,7 +92,7 @@ public class ResolveFeatureTest {
*/ */
@Test @Test
public void testContinueResolutionOnUriResolver() { public void testContinueResolutionOnUriResolver() {
CatalogUriResolver resolver = createUriResolver(RESOLVE_CONTINUE); CatalogResolver resolver = createUriResolver(RESOLVE_CONTINUE);
resolver.resolve("http://remote/dtd/bob/docBobDummy.dtd", null); resolver.resolve("http://remote/dtd/bob/docBobDummy.dtd", null);
checkUriResolution(resolver, "http://remote/dtd/bob/docBob.dtd", checkUriResolution(resolver, "http://remote/dtd/bob/docBob.dtd",
"http://local/base/dtd/docBobURI.dtd"); "http://local/base/dtd/docBobURI.dtd");
@ -123,7 +122,7 @@ public class ResolveFeatureTest {
return catalogResolver(createFeature(resolve), CATALOG_SYSTEM); return catalogResolver(createFeature(resolve), CATALOG_SYSTEM);
} }
private CatalogUriResolver createUriResolver(String resolve) { private CatalogResolver createUriResolver(String resolve) {
return catalogUriResolver(createFeature(resolve), CATALOG_URI); return catalogUriResolver(createFeature(resolve), CATALOG_URI);
} }
@ -131,4 +130,3 @@ public class ResolveFeatureTest {
return builder().with(Feature.RESOLVE, resolve).build(); return builder().with(Feature.RESOLVE, resolve).build();
} }
} }

View file

@ -95,4 +95,3 @@ public class RewriteSystemTest {
return catalogResolver("rewriteSystem.xml"); return catalogResolver("rewriteSystem.xml");
} }
} }

View file

@ -24,11 +24,11 @@
package catalog; package catalog;
import static catalog.CatalogTestUtils.catalogUriResolver; import static catalog.CatalogTestUtils.catalogUriResolver;
import static catalog.ResolutionChecker.checkNoMatch; import static catalog.ResolutionChecker.checkNoUriMatch;
import static catalog.ResolutionChecker.checkUriResolution; import static catalog.ResolutionChecker.checkUriResolution;
import javax.xml.catalog.CatalogResolver;
import javax.xml.catalog.CatalogException; import javax.xml.catalog.CatalogException;
import javax.xml.catalog.CatalogUriResolver;
import org.testng.annotations.DataProvider; import org.testng.annotations.DataProvider;
import org.testng.annotations.Listeners; import org.testng.annotations.Listeners;
@ -88,11 +88,10 @@ public class RewriteUriTest {
*/ */
@Test(expectedExceptions = CatalogException.class) @Test(expectedExceptions = CatalogException.class)
public void testNoMatch() { public void testNoMatch() {
checkNoMatch(createResolver()); checkNoUriMatch(createResolver());
} }
private CatalogUriResolver createResolver() { private CatalogResolver createResolver() {
return catalogUriResolver("rewriteUri.xml"); return catalogUriResolver("rewriteUri.xml");
} }
} }

View file

@ -36,7 +36,6 @@ import static javax.xml.catalog.CatalogFeatures.Feature.FILES;
import javax.xml.catalog.CatalogFeatures; import javax.xml.catalog.CatalogFeatures;
import javax.xml.catalog.CatalogResolver; import javax.xml.catalog.CatalogResolver;
import javax.xml.catalog.CatalogUriResolver;
import org.testng.annotations.Listeners; import org.testng.annotations.Listeners;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -68,7 +67,7 @@ public class SpecifyCatalogTest {
} }
/* /*
* CatalogUriResolver specifies catalog via feature javax.xml.catalog.files. * CatalogResolver specifies catalog via feature javax.xml.catalog.files.
*/ */
@Test @Test
public void specifyCatalogOnUriResolver() { public void specifyCatalogOnUriResolver() {
@ -102,7 +101,7 @@ public class SpecifyCatalogTest {
checkSysIdResolution(resolver, ID_SYS, matchedUri); checkSysIdResolution(resolver, ID_SYS, matchedUri);
} }
private void checkResolutionOnUriResolver(CatalogUriResolver resolver, private void checkResolutionOnUriResolver(CatalogResolver resolver,
String matchedUri) { String matchedUri) {
checkUriResolution(resolver, ID_URI, matchedUri); checkUriResolution(resolver, ID_URI, matchedUri);
} }
@ -111,4 +110,3 @@ public class SpecifyCatalogTest {
return builder().with(FILES, getCatalogPath(catalogName)).build(); return builder().with(FILES, getCatalogPath(catalogName)).build();
} }
} }

View file

@ -84,4 +84,3 @@ public class SystemFamilyTest {
return catalogResolver("systemFamily.xml"); return catalogResolver("systemFamily.xml");
} }
} }

View file

@ -95,4 +95,3 @@ public class SystemSuffixTest {
return catalogResolver("systemSuffix.xml"); return catalogResolver("systemSuffix.xml");
} }
} }

View file

@ -92,4 +92,3 @@ public class SystemTest {
return catalogResolver(CATALOG_SYSTEM); return catalogResolver(CATALOG_SYSTEM);
} }
} }

View file

@ -24,11 +24,11 @@
package catalog; package catalog;
import static catalog.CatalogTestUtils.catalogUriResolver; import static catalog.CatalogTestUtils.catalogUriResolver;
import static catalog.ResolutionChecker.checkNoMatch; import static catalog.ResolutionChecker.checkNoUriMatch;
import static catalog.ResolutionChecker.checkUriResolution; import static catalog.ResolutionChecker.checkUriResolution;
import javax.xml.catalog.CatalogResolver;
import javax.xml.catalog.CatalogException; import javax.xml.catalog.CatalogException;
import javax.xml.catalog.CatalogUriResolver;
import org.testng.annotations.DataProvider; import org.testng.annotations.DataProvider;
import org.testng.annotations.Listeners; import org.testng.annotations.Listeners;
@ -58,7 +58,7 @@ public class UriFamilyTest {
return new Object[][] { return new Object[][] {
// The matched URI of the specified URI reference is defined in // The matched URI of the specified URI reference is defined in
// a uri entry. // a uri entry.
{ "http://remote/dtd/alice/docAlice.dtd", { "http://remote/dtd/uri/alice/docAlice.dtd",
"http://local/base/dtd/docAliceURI.dtd" }, "http://local/base/dtd/docAliceURI.dtd" },
// The matched URI of the specified URI reference is defined in // The matched URI of the specified URI reference is defined in
@ -77,11 +77,10 @@ public class UriFamilyTest {
*/ */
@Test(expectedExceptions = CatalogException.class) @Test(expectedExceptions = CatalogException.class)
public void testNoMatch() { public void testNoMatch() {
checkNoMatch(createResolver()); checkNoUriMatch(createResolver());
} }
private CatalogUriResolver createResolver() { private CatalogResolver createResolver() {
return catalogUriResolver("uriFamily.xml"); return catalogUriResolver("uriFamily.xml");
} }
} }

View file

@ -24,11 +24,11 @@
package catalog; package catalog;
import static catalog.CatalogTestUtils.catalogUriResolver; import static catalog.CatalogTestUtils.catalogUriResolver;
import static catalog.ResolutionChecker.checkNoMatch; import static catalog.ResolutionChecker.checkNoUriMatch;
import static catalog.ResolutionChecker.checkUriResolution; import static catalog.ResolutionChecker.checkUriResolution;
import javax.xml.catalog.CatalogResolver;
import javax.xml.catalog.CatalogException; import javax.xml.catalog.CatalogException;
import javax.xml.catalog.CatalogUriResolver;
import org.testng.annotations.DataProvider; import org.testng.annotations.DataProvider;
import org.testng.annotations.Listeners; import org.testng.annotations.Listeners;
@ -88,11 +88,10 @@ public class UriSuffixTest {
*/ */
@Test(expectedExceptions = CatalogException.class) @Test(expectedExceptions = CatalogException.class)
public void testNoMatch() { public void testNoMatch() {
checkNoMatch(createResolver()); checkNoUriMatch(createResolver());
} }
private CatalogUriResolver createResolver() { private CatalogResolver createResolver() {
return catalogUriResolver("uriSuffix.xml"); return catalogUriResolver("uriSuffix.xml");
} }
} }

View file

@ -26,12 +26,12 @@ package catalog;
import static catalog.CatalogTestUtils.CATALOG_URI; import static catalog.CatalogTestUtils.CATALOG_URI;
import static catalog.CatalogTestUtils.RESOLVE_CONTINUE; import static catalog.CatalogTestUtils.RESOLVE_CONTINUE;
import static catalog.CatalogTestUtils.catalogUriResolver; import static catalog.CatalogTestUtils.catalogUriResolver;
import static catalog.ResolutionChecker.checkNoMatch; import static catalog.ResolutionChecker.checkNoUriMatch;
import static catalog.ResolutionChecker.checkUriResolution; import static catalog.ResolutionChecker.checkUriResolution;
import javax.xml.catalog.CatalogResolver;
import javax.xml.catalog.CatalogException; import javax.xml.catalog.CatalogException;
import javax.xml.catalog.CatalogFeatures; import javax.xml.catalog.CatalogFeatures;
import javax.xml.catalog.CatalogUriResolver;
import org.testng.annotations.DataProvider; import org.testng.annotations.DataProvider;
import org.testng.annotations.Listeners; import org.testng.annotations.Listeners;
@ -58,7 +58,7 @@ public class UriTest {
return new Object[][] { return new Object[][] {
// The matched URI of the specified URI reference is defined in // The matched URI of the specified URI reference is defined in
// a uri entry. The match is an absolute path. // a uri entry. The match is an absolute path.
{ "http://remote/dtd/alice/docAlice.dtd", { "http://remote/dtd/uri/alice/docAlice.dtd",
"http://local/dtd/docAliceURI.dtd" }, "http://local/dtd/docAliceURI.dtd" },
// The matched URI of the specified URI reference is defined in // The matched URI of the specified URI reference is defined in
@ -76,7 +76,7 @@ public class UriTest {
} }
/* /*
* Specify base location via method CatalogUriResolver.resolve(href, base). * Specify base location via method CatalogResolver.resolve(href, base).
*/ */
@Test @Test
public void testSpecifyBaseByAPI() { public void testSpecifyBaseByAPI() {
@ -84,7 +84,7 @@ public class UriTest {
"http://remote/dtd/carl/docCarl.dtd", "http://remote/dtd/carl/docCarl.dtd",
"http://local/carlBase/dtd/docCarlURI.dtd"); "http://local/carlBase/dtd/docCarlURI.dtd");
CatalogUriResolver continueResolver = catalogUriResolver( CatalogResolver continueResolver = catalogUriResolver(
CatalogFeatures.builder().with(CatalogFeatures.Feature.RESOLVE, CatalogFeatures.builder().with(CatalogFeatures.Feature.RESOLVE,
RESOLVE_CONTINUE).build(), CATALOG_URI); RESOLVE_CONTINUE).build(), CATALOG_URI);
checkUriResolution(continueResolver, "docCarl.dtd", checkUriResolution(continueResolver, "docCarl.dtd",
@ -97,11 +97,10 @@ public class UriTest {
*/ */
@Test(expectedExceptions = CatalogException.class) @Test(expectedExceptions = CatalogException.class)
public void testNoMatch() { public void testNoMatch() {
checkNoMatch(createResolver()); checkNoUriMatch(createResolver());
} }
private CatalogUriResolver createResolver() { private CatalogResolver createResolver() {
return catalogUriResolver(CATALOG_URI); return catalogUriResolver(CATALOG_URI);
} }
} }

View file

@ -67,4 +67,3 @@ public class UrnUnwrappingTest {
return catalogResolver("urnUnwrapping.xml"); return catalogResolver("urnUnwrapping.xml");
} }
} }

View file

@ -98,8 +98,7 @@ public class ValidateCatalogTest {
"http://remote/dtd/alice/docAlice.dtd", "http://remote/dtd/alice/docAlice.dtd",
"http://local/dtd/docAliceSys.dtd"); "http://local/dtd/docAliceSys.dtd");
checkUriResolution(catalogUriResolver(catalogName, CATALOG_URI), checkUriResolution(catalogUriResolver(catalogName, CATALOG_URI),
"http://remote/dtd/alice/docAlice.dtd", "http://remote/dtd/uri/alice/docAlice.dtd",
"http://local/dtd/docAliceURI.dtd"); "http://local/dtd/docAliceURI.dtd");
} }
} }

View file

@ -2,7 +2,7 @@
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog"> <catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
<system systemId="http://remote/dtd/alice/docAlice.dtd" uri="http://local/dtd/docAliceSys.dtd" /> <system systemId="http://remote/dtd/alice/docAlice.dtd" uri="http://local/dtd/docAliceSys.dtd" />
<uri name="http://remote/dtd/alice/docAlice.dtd" uri="http://local/dtd/docAliceURI.dtd" /> <uri name="http://remote/dtd/uri/alice/docAlice.dtd" uri="http://local/dtd/docAliceURI.dtd" />
<delegateSystem systemIdStartString="http://remote/dtd/alice/" catalog="delegateSystem-alice.xml" /> <delegateSystem systemIdStartString="http://remote/dtd/alice/" catalog="delegateSystem-alice.xml" />
<delegatePublic publicIdStartString="-//REMOTE//DTD ALICE DOCALICE" catalog="delegatePublic-alice.xml" /> <delegatePublic publicIdStartString="-//REMOTE//DTD ALICE DOCALICE" catalog="delegatePublic-alice.xml" />

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog" xml:base="http://local/base/dtd/"> <catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog" xml:base="http://local/base/dtd/">
<uri name="http://remote/dtd/alice/docAlice.dtd" uri="http://local/dtd/docAliceURI.dtd" /> <uri name="http://remote/dtd/uri/alice/docAlice.dtd" uri="http://local/dtd/docAliceURI.dtd" />
<uri name="http://remote/dtd/bob/docBob.dtd" uri="docBobURI.dtd" /> <uri name="http://remote/dtd/bob/docBob.dtd" uri="docBobURI.dtd" />

View file

@ -4,7 +4,7 @@
<delegateURI uriStartString="http://remote/dtd/alice/" catalog="delegateURI-alice.xml" /> <delegateURI uriStartString="http://remote/dtd/alice/" catalog="delegateURI-alice.xml" />
<uriSuffix uriSuffix="docAlice.dtd" uri="docAliceUS.dtd" /> <uriSuffix uriSuffix="docAlice.dtd" uri="docAliceUS.dtd" />
<rewriteURI uriStartString="http://remote/dtd/alice/" rewritePrefix="http://local/base/ru/" /> <rewriteURI uriStartString="http://remote/dtd/alice/" rewritePrefix="http://local/base/ru/" />
<uri name="http://remote/dtd/alice/docAlice.dtd" uri="docAliceURI.dtd" /> <uri name="http://remote/dtd/uri/alice/docAlice.dtd" uri="docAliceURI.dtd" />
<delegateURI uriStartString="http://remote/dtd/bob/" catalog="delegateURI-bob.xml" /> <delegateURI uriStartString="http://remote/dtd/bob/" catalog="delegateURI-bob.xml" />
<uriSuffix uriSuffix="docBob.dtd" uri="docBobUS.dtd" /> <uriSuffix uriSuffix="docBob.dtd" uri="docBobUS.dtd" />

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -42,7 +42,6 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import javax.xml.catalog.CatalogResolver; import javax.xml.catalog.CatalogResolver;
import javax.xml.catalog.CatalogUriResolver;
/* /*
* This case tests if the properties FILES, DEFER, PREFER, RESOLVE in * This case tests if the properties FILES, DEFER, PREFER, RESOLVE in
@ -96,7 +95,7 @@ public class PropertiesTest {
} }
private static void testPropertiesOnUriResolver() { private static void testPropertiesOnUriResolver() {
CatalogUriResolver uriResolver = catalogUriResolver((String[]) null); CatalogResolver uriResolver = catalogUriResolver((String[]) null);
uriResolver.resolve("http://remote/uri/dtd/docDummy.dtd", null); uriResolver.resolve("http://remote/uri/dtd/docDummy.dtd", null);
"http://local/base/dtd/docURI.dtd".equals(uriResolver.resolve( "http://local/base/dtd/docURI.dtd".equals(uriResolver.resolve(
"http://remote/dtd/doc.dtd", null).getSystemId()); "http://remote/dtd/doc.dtd", null).getSystemId());

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -35,7 +35,6 @@ import java.util.stream.Stream;
import javax.xml.catalog.CatalogFeatures; import javax.xml.catalog.CatalogFeatures;
import javax.xml.catalog.CatalogManager; import javax.xml.catalog.CatalogManager;
import javax.xml.catalog.CatalogResolver; import javax.xml.catalog.CatalogResolver;
import javax.xml.catalog.CatalogUriResolver;
import jaxp.library.JAXPTestUtilities; import jaxp.library.JAXPTestUtilities;
@ -101,18 +100,18 @@ final class CatalogTestUtils {
/* /*
* Creates catalogUriResolver with a set of catalogs. * Creates catalogUriResolver with a set of catalogs.
*/ */
static CatalogUriResolver catalogUriResolver(String... catalogName) { static CatalogResolver catalogUriResolver(String... catalogName) {
return catalogUriResolver(CatalogFeatures.defaults(), catalogName); return catalogUriResolver(CatalogFeatures.defaults(), catalogName);
} }
/* /*
* Creates catalogUriResolver with a feature and a set of catalogs. * Creates catalogUriResolver with a feature and a set of catalogs.
*/ */
static CatalogUriResolver catalogUriResolver( static CatalogResolver catalogUriResolver(
CatalogFeatures features, String... catalogName) { CatalogFeatures features, String... catalogName) {
return (catalogName == null) ? return (catalogName == null) ?
CatalogManager.catalogUriResolver(features) : CatalogManager.catalogResolver(features) :
CatalogManager.catalogUriResolver(features, getCatalogPaths(catalogName)); CatalogManager.catalogResolver(features, getCatalogPaths(catalogName));
} }
// Gets the paths of the specified catalogs. // Gets the paths of the specified catalogs.

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -24,7 +24,6 @@
package catalog; package catalog;
import javax.xml.catalog.CatalogResolver; import javax.xml.catalog.CatalogResolver;
import javax.xml.catalog.CatalogUriResolver;
import org.testng.Assert; import org.testng.Assert;
@ -65,7 +64,7 @@ class ResolutionChecker {
* Checks the resolution result for specified URI references * Checks the resolution result for specified URI references
* with the specified base location. * with the specified base location.
*/ */
static void checkUriResolution(CatalogUriResolver resolver, static void checkUriResolution(CatalogResolver resolver,
String href, String base, String matchedUri) { String href, String base, String matchedUri) {
Assert.assertEquals(resolver.resolve(href, base).getSystemId(), Assert.assertEquals(resolver.resolve(href, base).getSystemId(),
matchedUri); matchedUri);
@ -74,7 +73,7 @@ class ResolutionChecker {
/* /*
* Checks the resolution result for specified URI references. * Checks the resolution result for specified URI references.
*/ */
static void checkUriResolution(CatalogUriResolver resolver, static void checkUriResolution(CatalogResolver resolver,
String href, String matchedUri) { String href, String matchedUri) {
checkUriResolution(resolver, href, null, matchedUri); checkUriResolution(resolver, href, null, matchedUri);
} }
@ -92,9 +91,9 @@ class ResolutionChecker {
/* /*
* With strict resolution, if no match is found, * With strict resolution, if no match is found,
* CatalogUriResolver should throw CatalogException. * CatalogResolver should throw CatalogException.
*/ */
static void checkNoMatch(CatalogUriResolver resolver) { static void checkNoUriMatch(CatalogResolver resolver) {
resolver.resolve("http://uri/noMatch/docNoMatch.dtd", getNotSpecified(null)); resolver.resolve("http://uri/noMatch/docNoMatch.dtd", getNotSpecified(null));
} }
@ -139,7 +138,7 @@ class ResolutionChecker {
* URI reference with a specified base location. * URI reference with a specified base location.
*/ */
static <T extends Throwable> void expectExceptionOnUri( static <T extends Throwable> void expectExceptionOnUri(
CatalogUriResolver resolver, String href, String base, CatalogResolver resolver, String href, String base,
Class<T> expectedExceptionClass) { Class<T> expectedExceptionClass) {
expectThrows(expectedExceptionClass, () -> { expectThrows(expectedExceptionClass, () -> {
resolver.resolve(href, base); resolver.resolve(href, base);
@ -151,7 +150,7 @@ class ResolutionChecker {
* URI reference without any specified base location. * URI reference without any specified base location.
*/ */
static <T extends Throwable> void expectExceptionOnUri( static <T extends Throwable> void expectExceptionOnUri(
CatalogUriResolver resolver, String href, CatalogResolver resolver, String href,
Class<T> expectedExceptionClass) { Class<T> expectedExceptionClass) {
expectExceptionOnUri(resolver, href, null, expectedExceptionClass); expectExceptionOnUri(resolver, href, null, expectedExceptionClass);
} }

View file

@ -327,4 +327,3 @@ public class CatalogSupport extends CatalogSupportBase {
}; };
} }
} }

View file

@ -11,32 +11,32 @@
<!-- public publicId="datatypes" uri="datatypes.dtd"/--> <!-- public publicId="datatypes" uri="datatypes.dtd"/-->
<!-- XInclude --> <!-- XInclude -->
<uri name="XI_simple.xml" uri="XI_simple4Catalog.xml"/> <system systemId="XI_simple.xml" uri="XI_simple4Catalog.xml"/>
<uri name="XI_utf8.xml" uri="XI_utf8.xml"/> <system systemId="XI_utf8.xml" uri="XI_utf8.xml"/>
<uri name="XI_utf8Catalog.xml" uri="XI_utf8Catalog.xml"/> <system systemId="XI_utf8Catalog.xml" uri="XI_utf8Catalog.xml"/>
<uri name="XI_test2.xml" uri="XI_test2.xml"/> <system systemId="XI_test2.xml" uri="XI_test2.xml"/>
<system systemId="XI_red.dtd" uri="XI_red.dtd"/> <system systemId="XI_red.dtd" uri="XI_red.dtd"/>
<!-- xsd import can be mapped using the namespace or systemId --> <!-- xsd import can be mapped using the namespace or systemId -->
<!--public publicId="http://www.w3.org/XML/1998/namespace" uri="xml.xsd"/--> <!--public publicId="http://www.w3.org/XML/1998/namespace" uri="xml.xsd"/-->
<!--uri name="http://www.w3.org/XML/1998/namespace" uri="xml.xsd"/--> <!--uri name="http://www.w3.org/XML/1998/namespace" uri="xml.xsd"/-->
<uri name="http://www.w3.org/2001/pathto/xml.xsd" uri="xml.xsd"/> <system systemId="http://www.w3.org/2001/pathto/xml.xsd" uri="xml.xsd"/>
<!-- schema include --> <!-- schema include -->
<uri name="pathto/XSDInclude_person.xsd" uri="XSDInclude_person.xsd"/> <system systemId="pathto/XSDInclude_person.xsd" uri="XSDInclude_person.xsd"/>
<uri name="pathto/XSDInclude_product.xsd" uri="XSDInclude_product.xsd"/> <system systemId="pathto/XSDInclude_product.xsd" uri="XSDInclude_product.xsd"/>
<!-- for relative path, use Suffix --> <!-- for relative path, use Suffix -->
<systemSuffix systemIdSuffix="pathto/val_test.xsd" uri="val_test.xsd"/> <systemSuffix systemIdSuffix="pathto/val_test.xsd" uri="val_test.xsd"/>
<!-- XSL import and include --> <!-- XSL import and include -->
<uri name="pathto/XSLImport_html.xsl" uri="XSLImport_html.xsl"/> <system systemId="pathto/XSLImport_html.xsl" uri="XSLImport_html.xsl"/>
<uri name="pathto/XSLInclude_header.xsl" uri="XSLInclude_header.xsl"/> <system systemId="pathto/XSLInclude_header.xsl" uri="XSLInclude_header.xsl"/>
<uri name="pathto/XSLInclude_footer.xsl" uri="XSLInclude_footer.xsl"/> <system systemId="pathto/XSLInclude_footer.xsl" uri="XSLInclude_footer.xsl"/>
<!-- and DTDs --> <!-- and DTDs -->
<system systemId="http://openjdk.java.net/xml/catalog/dtd/XSLDTD.dtd" uri="XSLDTD.dtd"/> <system systemId="http://openjdk.java.net/xml/catalog/dtd/XSLDTD.dtd" uri="XSLDTD.dtd"/>
<system systemId="http://openjdk.java.net/xml/catalog/dtd/include.dtd" uri="include.dtd"/> <system systemId="http://openjdk.java.net/xml/catalog/dtd/include.dtd" uri="include.dtd"/>
<!-- XSLT document function --> <!-- XSLT document function -->
<uri name="pathto/DocFunc2.xml" uri="DocFuncCatalog.xml"/> <system systemId="pathto/DocFunc2.xml" uri="DocFuncCatalog.xml"/>
</catalog> </catalog>

View file

@ -268,4 +268,3 @@ public class CatalogSupport1 extends CatalogSupportBase {
} }
} }

View file

@ -270,4 +270,3 @@ public class CatalogSupport2 extends CatalogSupportBase {
}; };
} }
} }

View file

@ -280,4 +280,3 @@ public class CatalogSupport3 extends CatalogSupportBase {
}; };
} }
} }

View file

@ -269,4 +269,3 @@ public class CatalogSupport4 extends CatalogSupportBase {
}; };
} }
} }

View file

@ -0,0 +1,250 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package catalog;
import java.io.File;
import java.io.StringReader;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
import javax.xml.transform.URIResolver;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stax.StAXSource;
import javax.xml.transform.stream.StreamSource;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;
import org.w3c.dom.ls.LSResourceResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
/*
* @test
* @bug 8158084 8163232
* @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
* @run testng/othervm -DrunSecMngr=true catalog.CatalogSupport5
* @run testng/othervm catalog.CatalogSupport5
* @summary extends CatalogSupport tests, verifies that when errors occur,
* relevant checked Exceptions are returned.
*/
/**
* The CatalogResolver will throw CatalogException when there is no match and
* the resolve property is strict. The Exception should be caught with the existing
* mechanisms so that the checked Exception corresponding to the process can be
* returned.
*
* @author huizhe.wang@oracle.com
*/
@Listeners({jaxp.library.FilePolicy.class, jaxp.library.NetAccessPolicy.class})
public class CatalogSupport5 extends CatalogSupportBase {
/*
* Initializing fields
*/
@BeforeClass
public void setUpClass() throws Exception {
setUp();
}
/*
Verifies the Catalog support on SAXParser.
*/
@Test(dataProvider = "data_SAXC", expectedExceptions = SAXException.class)
public void testSAXC(boolean setUseCatalog, boolean useCatalog, String catalog, String
xml, MyHandler handler, String expected) throws Exception {
testSAX(setUseCatalog, useCatalog, catalog, xml, handler, expected);
}
/*
Verifies the Catalog support on XMLReader.
*/
@Test(dataProvider = "data_SAXC", expectedExceptions = SAXException.class)
public void testXMLReaderC(boolean setUseCatalog, boolean useCatalog, String catalog,
String xml, MyHandler handler, String expected) throws Exception {
testXMLReader(setUseCatalog, useCatalog, catalog, xml, handler, expected);
}
/*
Verifies the Catalog support on XInclude.
*/
@Test(dataProvider = "data_XIC", expectedExceptions = SAXException.class)
public void testXIncludeC(boolean setUseCatalog, boolean useCatalog, String catalog,
String xml, MyHandler handler, String expected) throws Exception {
testXInclude(setUseCatalog, useCatalog, catalog, xml, handler, expected);
}
/*
Verifies the Catalog support on DOM parser.
*/
@Test(dataProvider = "data_DOMC", expectedExceptions = SAXException.class)
public void testDOMC(boolean setUseCatalog, boolean useCatalog, String catalog,
String xml, MyHandler handler, String expected) throws Exception {
testDOM(setUseCatalog, useCatalog, catalog, xml, handler, expected);
}
/*
Verifies the Catalog support on resolving DTD, xsd import and include in
Schema files.
*/
@Test(dataProvider = "data_SchemaC", expectedExceptions = SAXException.class)
public void testValidationC(boolean setUseCatalog, boolean useCatalog, String catalog,
String xsd, LSResourceResolver resolver)
throws Exception {
testValidation(setUseCatalog, useCatalog, catalog, xsd, resolver) ;
}
@Test(dataProvider = "data_ValidatorC", expectedExceptions = SAXException.class)
public void testValidatorC(boolean setUseCatalog1, boolean setUseCatalog2, boolean useCatalog,
Source source, LSResourceResolver resolver1, LSResourceResolver resolver2,
String catalog1, String catalog2)
throws Exception {
testValidator(setUseCatalog1, setUseCatalog2, useCatalog, source,
resolver1, resolver2, catalog1, catalog2);
}
/*
Verifies the Catalog support on resolving DTD, xsl import and include in
XSL files.
*/
@Test(dataProvider = "data_XSLC", expectedExceptions = TransformerException.class)
public void testXSLImportC(boolean setUseCatalog, boolean useCatalog, String catalog,
SAXSource xsl, StreamSource xml, URIResolver resolver, String expected) throws Exception {
testXSLImport(setUseCatalog, useCatalog, catalog, xsl, xml, resolver, expected);
}
/*
@bug 8158084 8162442
Verifies the Catalog support on resolving DTD, xsl import and include in
XSL files.
*/
@Test(dataProvider = "data_XSLC", expectedExceptions = TransformerException.class)
public void testXSLImportWTemplatesC(boolean setUseCatalog, boolean useCatalog, String catalog,
SAXSource xsl, StreamSource xml, URIResolver resolver, String expected) throws Exception {
testXSLImportWTemplates(setUseCatalog, useCatalog, catalog, xsl, xml, resolver, expected);
}
/*
DataProvider: for testing the SAX parser
Data: set use_catalog, use_catalog, catalog file, xml file, handler, expected result string
*/
@DataProvider(name = "data_SAXC")
public Object[][] getDataSAXC() {
return new Object[][]{
{false, true, xml_bogus_catalog, xml_system, new MyHandler(elementInSystem), expectedWCatalog}
};
}
/*
DataProvider: for testing XInclude
Data: set use_catalog, use_catalog, catalog file, xml file, handler, expected result string
*/
@DataProvider(name = "data_XIC")
public Object[][] getDataXIC() {
return new Object[][]{
{false, true, xml_bogus_catalog, xml_xInclude, new MyHandler(elementInXISimple), contentInUIutf8Catalog},
};
}
/*
DataProvider: for testing DOM parser
Data: set use_catalog, use_catalog, catalog file, xml file, handler, expected result string
*/
@DataProvider(name = "data_DOMC")
public Object[][] getDataDOMC() {
return new Object[][]{
{false, true, xml_bogus_catalog, xml_system, new MyHandler(elementInSystem), expectedWCatalog}
};
}
/*
DataProvider: for testing Schema validation
Data: set use_catalog, use_catalog, catalog file, xsd file, a LSResourceResolver
*/
@DataProvider(name = "data_SchemaC")
public Object[][] getDataSchemaC() {
return new Object[][]{
// for resolving DTD in xsd
{false, true, xml_bogus_catalog, xsd_xmlSchema, null},
// for resolving xsd import
{false, true, xml_bogus_catalog, xsd_xmlSchema_import, null},
// for resolving xsd include
{false, true, xml_bogus_catalog, xsd_include_company, null}
};
}
/*
DataProvider: for testing Schema Validator
Data: setUseCatalog1, setUseCatalog2, useCatalog, source, resolver1, resolver2,
catalog1, catalog2
*/
@DataProvider(name = "data_ValidatorC")
public Object[][] getDataValidator() {
DOMSource ds = getDOMSource(xml_val_test, xml_val_test_id, true, true, xml_catalog);
SAXSource ss = new SAXSource(new InputSource(xml_val_test));
ss.setSystemId(xml_val_test_id);
StAXSource stax = getStaxSource(xml_val_test, xml_val_test_id);
StAXSource stax1 = getStaxSource(xml_val_test, xml_val_test_id);
StreamSource source = new StreamSource(new File(xml_val_test));
return new Object[][]{
// use catalog
{false, false, true, ds, null, null, xml_bogus_catalog, null},
{false, false, true, ds, null, null, null, xml_bogus_catalog},
{false, false, true, ss, null, null, xml_bogus_catalog, null},
{false, false, true, ss, null, null, null, xml_bogus_catalog},
{false, false, true, stax, null, null, xml_bogus_catalog, null},
{false, false, true, stax1, null, null, null, xml_bogus_catalog},
{false, false, true, source, null, null, xml_bogus_catalog, null},
{false, false, true, source, null, null, null, xml_bogus_catalog},
};
}
/*
DataProvider: for testing XSL import and include
Data: set use_catalog, use_catalog, catalog file, xsl file, xml file, a URIResolver, expected
*/
@DataProvider(name = "data_XSLC")
public Object[][] getDataXSLC() {
SAXSource xslSourceDTD = new SAXSource(new InputSource(new StringReader(xsl_includeDTD)));
StreamSource xmlSourceDTD = new StreamSource(new StringReader(xml_xslDTD));
SAXSource xslDocSource = new SAXSource(new InputSource(new File(xsl_doc).toURI().toASCIIString()));
StreamSource xmlDocSource = new StreamSource(new File(xml_doc));
return new Object[][]{
// for resolving DTD, import and include in xsl
{false, true, xml_bogus_catalog, xslSourceDTD, xmlSourceDTD, null, ""},
// for resolving reference by the document function
{false, true, xml_bogus_catalog, xslDocSource, xmlDocSource, null, "Resolved by a catalog"},
};
}
}

View file

@ -35,9 +35,9 @@ import java.io.Reader;
import java.io.StringReader; import java.io.StringReader;
import java.io.StringWriter; import java.io.StringWriter;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import javax.xml.XMLConstants; import javax.xml.XMLConstants;
import javax.xml.catalog.CatalogFeatures; import javax.xml.catalog.CatalogFeatures;
import javax.xml.catalog.CatalogResolver;
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.ParserConfigurationException;
@ -61,7 +61,6 @@ import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema; import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory; import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator; import javax.xml.validation.Validator;
import org.testng.Assert; import org.testng.Assert;
import org.w3c.dom.Document; import org.w3c.dom.Document;
import org.w3c.dom.Node; import org.w3c.dom.Node;
@ -677,6 +676,29 @@ public class CatalogSupportBase {
} }
/**
* Extends MyHandler and overrides resolveEntity with a CatalogResolver
*/
class MyCatalogHandler extends MyHandler {
CatalogResolver cr;
public MyCatalogHandler(CatalogResolver cr, String elementName) {
super(elementName);
this.cr = cr;
}
@Override
public InputSource resolveEntity(String publicId, String systemId) {
return cr.resolveEntity(publicId, systemId);
}
@Override
public InputSource resolveEntity(String name, String publicId,
String baseURI, String systemId) {
return cr.resolveEntity(publicId, systemId);
}
}
/** /**
* Extends MyHandler and overrides resolveEntity * Extends MyHandler and overrides resolveEntity
*/ */
@ -935,4 +957,3 @@ public class CatalogSupportBase {
} }
} }
} }

View file

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
<!-- DTDs and external entities -->
<uri name="http://openjdk.java.net/xml/catalog/dtd/system.dtd" uri="system.dtd"/>
<!-- XMLSchema refers to XMLSchema.dtd -->
<public publicId="-//W3C//DTD XMLSCHEMA 200102//EN" uri="XMLSchema.dtd"/>
<!-- XMLSchema.dtd refers to datatypes.dtd -->
<uriSuffix uriSuffix="datatypes.dtd" uri="datatypes.dtd"/>
<!-- XMLSchema.dtd refers to datatypes.dtd, can use public entry as well -->
<!-- public publicId="datatypes" uri="datatypes.dtd"/-->
<!-- XInclude -->
<uri name="XI_simple.xml" uri="XI_simple4Catalog.xml"/>
<uri name="XI_utf8.xml" uri="XI_utf8.xml"/>
<uri name="XI_utf8Catalog.xml" uri="XI_utf8Catalog.xml"/>
<uri name="XI_test2.xml" uri="XI_test2.xml"/>
<uri name="XI_red.dtd" uri="XI_red.dtd"/>
<!-- xsd import can be mapped using the namespace or systemId -->
<!--public publicId="http://www.w3.org/XML/1998/namespace" uri="xml.xsd"/-->
<!--uri name="http://www.w3.org/XML/1998/namespace" uri="xml.xsd"/-->
<uri name="http://www.w3.org/2001/pathto/xml.xsd" uri="xml.xsd"/>
<!-- schema include -->
<uri name="pathto/XSDInclude_person.xsd" uri="XSDInclude_person.xsd"/>
<uri name="pathto/XSDInclude_product.xsd" uri="XSDInclude_product.xsd"/>
<!-- for relative path, use Suffix -->
<uriSuffix uriSuffix="pathto/val_test.xsd" uri="val_test.xsd"/>
<!-- XSL import and include -->
<uri name="pathto/XSLImport_html.xsl" uri="XSLImport_html.xsl"/>
<uri name="pathto/XSLInclude_header.xsl" uri="XSLInclude_header.xsl"/>
<uri name="pathto/XSLInclude_footer.xsl" uri="XSLInclude_footer.xsl"/>
<!-- and DTDs -->
<uri name="http://openjdk.java.net/xml/catalog/dtd/XSLDTD.dtd" uri="XSLDTD.dtd"/>
<uri name="http://openjdk.java.net/xml/catalog/dtd/include.dtd" uri="include.dtd"/>
<!-- XSLT document function -->
<uri name="pathto/DocFunc2.xml" uri="DocFuncCatalog.xml"/>
</catalog>

View file

@ -26,23 +26,37 @@ import static jaxp.library.JAXPTestUtilities.clearSystemProperty;
import static jaxp.library.JAXPTestUtilities.getSystemProperty; import static jaxp.library.JAXPTestUtilities.getSystemProperty;
import static jaxp.library.JAXPTestUtilities.setSystemProperty; import static jaxp.library.JAXPTestUtilities.setSystemProperty;
import java.io.File;
import java.io.FileInputStream;
import java.io.FilePermission; import java.io.FilePermission;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.PropertyPermission; import java.util.PropertyPermission;
import javax.xml.XMLConstants;
import javax.xml.catalog.Catalog; import javax.xml.catalog.Catalog;
import javax.xml.catalog.CatalogException; import javax.xml.catalog.CatalogException;
import javax.xml.catalog.CatalogFeatures; import javax.xml.catalog.CatalogFeatures;
import javax.xml.catalog.CatalogFeatures.Feature; import javax.xml.catalog.CatalogFeatures.Feature;
import javax.xml.catalog.CatalogManager; import javax.xml.catalog.CatalogManager;
import javax.xml.catalog.CatalogResolver; import javax.xml.catalog.CatalogResolver;
import javax.xml.catalog.CatalogUriResolver;
import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory; import javax.xml.parsers.SAXParserFactory;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.Source; import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import jaxp.library.JAXPTestUtilities; import jaxp.library.JAXPTestUtilities;
import org.testng.Assert; import org.testng.Assert;
@ -59,29 +73,235 @@ import org.xml.sax.ext.DefaultHandler2;
/* /*
* @test * @test
* @bug 8081248 8144966 8146606 8146237 8151154 8150969 8151162 8152527 8154220 * @bug 8081248 8144966 8146606 8146237 8151154 8150969 8151162 8152527 8154220 8163232
* @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
* @run testng/othervm -DrunSecMngr=true catalog.CatalogTest * @run testng/othervm -DrunSecMngr=true catalog.CatalogTest
* @run testng/othervm catalog.CatalogTest * @run testng/othervm catalog.CatalogTest
* @summary Tests basic Catalog functions. * @summary Tests basic Catalog functions.
*/ */
@Listeners({jaxp.library.FilePolicy.class}) @Listeners({jaxp.library.FilePolicy.class})
public class CatalogTest { public class CatalogTest extends CatalogSupportBase {
static final String KEY_FILES = "javax.xml.catalog.files"; static final String KEY_FILES = "javax.xml.catalog.files";
public String filepath;
/* /*
* Initializing fields * Initializing fields
*/ */
@BeforeClass @BeforeClass
public void setUpClass() throws Exception { public void setUpClass() throws Exception {
String file1 = getClass().getResource("first_cat.xml").getFile(); super.setUp();
if (getSystemProperty("os.name").contains("Windows")) {
filepath = file1.substring(1, file1.lastIndexOf("/") + 1);
} else {
filepath = file1.substring(0, file1.lastIndexOf("/") + 1);
} }
/*
* @bug 8163232
* Verifies that the CatalogResolver supports the following XML Resolvers:
javax.xml.stream.XMLResolver
javax.xml.transform.URIResolver
org.w3c.dom.ls.LSResourceResolver
org.xml.sax.EntityResolver
*
* Plus, system and uri entries can equally be used.
*/
/*
* Verifies the support for org.xml.sax.EntityResolver.
* Expected: the parser returns the expected string.
*/
@Test(dataProvider = "supportXMLResolver")
public void supportEntityResolver(String catalogFile, String xml, String expected) throws Exception {
String xmlSource = getClass().getResource(xml).getFile();
CatalogResolver cr = CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalogFile);
MyCatalogHandler handler = new MyCatalogHandler(cr, elementInSystem);
SAXParser parser = getSAXParser(false, true, null);
parser.parse(xmlSource, handler);
Assert.assertEquals(handler.getResult().trim(), expected);
}
/*
* Verifies the support for javax.xml.stream.XMLResolver.
* Expected: the parser returns the expected string.
*/
@Test(dataProvider = "supportXMLResolver")
public void supportXMLResolver(String catalogFile, String xml, String expected) throws Exception {
String xmlSource = getClass().getResource(xml).getFile();
CatalogResolver cr = CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalogFile);
XMLInputFactory xifactory = XMLInputFactory.newInstance();
xifactory.setProperty(XMLInputFactory.IS_COALESCING, true);
xifactory.setProperty(XMLInputFactory.RESOLVER, cr);
File file = new File(xmlSource);
String systemId = file.toURI().toString();
InputStream entityxml = new FileInputStream(file);
XMLStreamReader streamReader = xifactory.createXMLStreamReader(systemId, entityxml);
String result = null;
while (streamReader.hasNext()) {
int eventType = streamReader.next();
if (eventType == XMLStreamConstants.START_ELEMENT) {
eventType = streamReader.next();
if (eventType == XMLStreamConstants.CHARACTERS) {
result = streamReader.getText();
}
}
}
System.out.println(": expected [" + expected + "] <> actual [" + result.trim() + "]");
Assert.assertEquals(result.trim(), expected);
}
/*
* Verifies the support for org.w3c.dom.ls.LSResourceResolver by ShemaFactory.
* Success: parsing goes through with no error
* Fail: throws Exception if references are not resolved (by the CatalogResolver)
*/
@Test(dataProvider = "supportLSResourceResolver")
public void supportLSResourceResolver(String catalogFile, Source schemaSource) throws SAXException {
CatalogResolver cr = CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalogFile);
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
factory.setResourceResolver(cr);
Schema schema = factory.newSchema(schemaSource);
}
/*
* Verifies the support for org.w3c.dom.ls.LSResourceResolver by Validator.
* Success: parsing goes through with no error
* Fail: throws Exception if references are not resolved (by the CatalogResolver)
*/
@Test(dataProvider = "supportLSResourceResolver1")
public void supportLSResourceResolver1(String catalogFile, Source source) throws Exception {
CatalogResolver cr = CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalogFile);
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Validator validator = factory.newSchema().newValidator();
validator.setResourceResolver(cr);
validator.validate(source);
}
/*
* Verifies the support for javax.xml.transform.URIResolver.
* Success: parsing goes through with no error
* Fail: throws Exception if references are not resolved (by the CatalogResolver)
*/
@Test(dataProvider = "supportURIResolver")
public void supportURIResolver(String catalogFile, Source xsl, Source xml, String expected) throws Exception {
CatalogResolver cr = CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalogFile);
TransformerFactory factory = TransformerFactory.newInstance();
factory.setURIResolver(cr);
Transformer transformer = factory.newTransformer(xsl);
StringWriter out = new StringWriter();
transformer.transform(xml, new StreamResult(out));
if (expected != null) {
Assert.assertTrue(out.toString().contains(expected), "supportURIResolver");
}
}
/*
DataProvider: used to verify the support of XML Resolvers.
Data columns:
catalog filepath, xml source file, expected result
*/
@DataProvider(name = "supportXMLResolver")
public Object[][] supportXMLResolver() {
String catalogFile = getClass().getResource("catalog.xml").getFile();
String catalogFileUri = getClass().getResource("catalog_uri.xml").getFile();
return new Object[][]{
{catalogFile, "system.xml", "Test system entry"},
{catalogFile, "rewritesystem.xml", "Test rewritesystem entry"},
{catalogFile, "rewritesystem1.xml", "Test rewritesystem entry"},
{catalogFile, "systemsuffix.xml", "Test systemsuffix entry"},
{catalogFile, "delegatesystem.xml", "Test delegatesystem entry"},
{catalogFile, "public.xml", "Test public entry"},
{catalogFile, "delegatepublic.xml", "Test delegatepublic entry"},
// using uri entries
{catalogFileUri, "system.xml", "Test system entry"},
{catalogFileUri, "rewritesystem.xml", "Test rewritesystem entry"},
{catalogFileUri, "rewritesystem1.xml", "Test rewritesystem entry"},
{catalogFileUri, "systemsuffix.xml", "Test systemsuffix entry"},
{catalogFileUri, "delegateuri.xml", "Test delegateuri entry"},
{catalogFileUri, "public.xml", "Test public entry"},
};
}
/*
DataProvider: used to verify the support of LSResourceResolver by SchemaFactory.
Data columns:
catalog filepath, schema source file
*/
@DataProvider(name = "supportLSResourceResolver")
public Object[][] supportLSResourceResolver() {
String catalogFile = getClass().getResource("CatalogSupport.xml").getFile();
String catalogFileUri = getClass().getResource("CatalogSupport_uri.xml").getFile();
/*
* XMLSchema.xsd has a reference to XMLSchema.dtd which in turn refers to
* datatypes.dtd
*/
return new Object[][]{
{catalogFile, new StreamSource(new StringReader(xsd_xmlSchema))},
{catalogFile, new StreamSource(new StringReader(xsd_xmlSchema_import))},
{catalogFile, new StreamSource(new StringReader(xsd_include_company))},
{catalogFileUri, new StreamSource(new StringReader(xsd_xmlSchema))},
{catalogFileUri, new StreamSource(new StringReader(xsd_xmlSchema_import))},
{catalogFileUri, new StreamSource(new StringReader(xsd_include_company))},
};
}
/*
DataProvider: used to verify the support of LSResourceResolver by Validator.
Data columns:
catalog filepath, source file
*/
@DataProvider(name = "supportLSResourceResolver1")
public Object[][] supportLSResourceResolver1() {
String catalogFile = getClass().getResource("CatalogSupport.xml").getFile();
String catalogFileUri = getClass().getResource("CatalogSupport_uri.xml").getFile();
/*
* val_test.xml has a reference to system.dtd and val_test.xsd
*/
SAXSource ss = new SAXSource(new InputSource(xml_val_test));
ss.setSystemId(xml_val_test_id);
return new Object[][]{
{catalogFile, ss},
{catalogFileUri, ss},
};
}
/*
DataProvider: used to verify the support of LSResourceResolver by Validator.
Data columns:
catalog filepath, xsl source, xml source file
*/
@DataProvider(name = "supportURIResolver")
public Object[][] supportURIResolver() {
String catalogFile = getClass().getResource("CatalogSupport.xml").getFile();
String catalogFileUri = getClass().getResource("CatalogSupport_uri.xml").getFile();
SAXSource xslSource = new SAXSource(new InputSource(new File(xsl_doc).toURI().toASCIIString()));
/*
* val_test.xml has a reference to system.dtd and val_test.xsd
*/
SAXSource ss = new SAXSource(new InputSource(xml_val_test));
ss.setSystemId(xml_val_test_id);
return new Object[][]{
{catalogFile, new SAXSource(new InputSource(new File(xsl_doc).toURI().toASCIIString())),
new StreamSource(new File(xml_doc)), "Resolved by a catalog"},
{catalogFileUri, new SAXSource(new InputSource(new StringReader(xsl_include))),
new StreamSource(new StringReader(xml_xsl)), null},
};
} }
/* /*
@ -110,7 +330,7 @@ public class CatalogTest {
@Test(dataProvider = "resolveUri") @Test(dataProvider = "resolveUri")
public void testMatch1(String cFile, String href, String expectedFile, String expectedUri, String msg) { public void testMatch1(String cFile, String href, String expectedFile, String expectedUri, String msg) {
String catalogFile = getClass().getResource(cFile).getFile(); String catalogFile = getClass().getResource(cFile).getFile();
CatalogUriResolver cur = CatalogManager.catalogUriResolver(CatalogFeatures.defaults(), catalogFile); CatalogResolver cur = CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalogFile);
Source source = cur.resolve(href, null); Source source = cur.resolve(href, null);
Assert.assertNotNull(source, "Source returned is null"); Assert.assertNotNull(source, "Source returned is null");
Assert.assertEquals(expectedUri, source.getSystemId(), msg); Assert.assertEquals(expectedUri, source.getSystemId(), msg);
@ -275,7 +495,7 @@ public class CatalogTest {
try { try {
CatalogUriResolver resolver = CatalogManager.catalogUriResolver(CatalogFeatures.defaults(), catalog); CatalogResolver resolver = CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalog);
String actualSystemId = resolver.resolve("http://remote.com/import/import.xsl", null).getSystemId(); String actualSystemId = resolver.resolve("http://remote.com/import/import.xsl", null).getSystemId();
Assert.assertTrue(!actualSystemId.contains("//"), "result contains duplicate slashes"); Assert.assertTrue(!actualSystemId.contains("//"), "result contains duplicate slashes");
} catch (Exception e) { } catch (Exception e) {
@ -383,7 +603,7 @@ public class CatalogTest {
/* /*
DataProvider: used to verify CatalogUriResolver's resolve function. DataProvider: used to verify CatalogResolver's resolve function.
Data columns: Data columns:
catalog, uri or publicId, expectedFile, expectedUri, msg catalog, uri or publicId, expectedFile, expectedUri, msg
@ -571,4 +791,3 @@ public class CatalogTest {
} }
} }
} }

View file

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<catalog
xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
<!-- using uri entries -->
<uri name="http://openjdk.java.net/xml/catalog/dtd/system.dtd" uri="system.dtd"/>
<rewriteURI uriStartString="http://openjdk.java.net/"
rewritePrefix="files" />
<rewriteURI uriStartString="http://openjdk.java.net/xml/catalog/dtd/"
rewritePrefix="files" />
<uriSuffix uriSuffix="systemsuffix.dtd" uri="systemsuffix.dtd"/>
<delegateURI uriStartString="http://java.com/xml/catalog/dtd/" catalog="files/delegatecatalog_uri.xml"/>
<uri name="-//OPENJDK//XML CATALOG DTD//1.0" uri="public.dtd"/>
<delegateURI uriStartString="-//JAVASE//XML CATALOG DTD//DELEGATEPULIC" catalog="files/delegatecatalog_uri.xml"/>
</catalog>

View file

@ -0,0 +1,5 @@
<?xml version="1.0"?>
<!DOCTYPE catalogtest PUBLIC "-//JAVASE//XML CATALOG DTD//DELEGATEURI"
"http://java.com/xml/catalog/dtd/delegateuri.dtd">
<catalogtest>Test &delegateuri; entry</catalogtest>

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<catalog
xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
<uri name="http://java.com/xml/catalog/dtd/delegateuri.dtd" uri="delegateuri.dtd"/>
</catalog>

View file

@ -0,0 +1,2 @@
<!ENTITY delegateuri "delegateuri">

View file

@ -1,5 +1,5 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<!DOCTYPE catalogtest PUBLIC "-//OPENJDK//XML CATALOG DTD//1.0" <!DOCTYPE catalogtest PUBLIC "-//OPENJDK//XML CATALOG DTD SYSTEM//1.0"
"http://openjdk.java.net/xml/catalog/dtd/system.dtd"> "http://openjdk.java.net/xml/catalog/dtd/system.dtd">
<catalogtest>Test &system; entry</catalogtest> <catalogtest>Test &system; entry</catalogtest>