org.apache.xml.resolver.CatalogManager Maven / Gradle / Ivy
// CatalogManager.java - Access CatalogManager.properties
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (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
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.xml.resolver;
import java.io.InputStream;
import java.net.URL;
import java.net.MalformedURLException;
import java.util.MissingResourceException;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
import java.util.StringTokenizer;
import java.util.Vector;
import org.apache.xml.resolver.helpers.Debug;
import org.apache.xml.resolver.helpers.BootstrapResolver;
import org.apache.xml.resolver.Catalog;
/**
* CatalogManager provides an interface to the catalog properties.
*
* Properties can come from two places: from system properties or
* from a CatalogManager.properties file. This class provides a transparent
* interface to both, with system properties preferred over property file values.
*
* The following table summarizes the properties:
*
*
*
*
* System Property
* CatalogManager.properties
Property
* Description
*
*
*
*
* xml.catalog.ignoreMissing
*
* If true, a missing CatalogManager.properties file or missing properties
* within that file will not generate warning messages. See also the
* ignoreMissingProperties method.
*
*
*
* xml.catalog.files
* catalogs
* The semicolon-delimited list of catalog files.
*
*
*
*
* relative-catalogs
* If false, relative catalog URIs are made absolute with respect to the base URI of
* the CatalogManager.properties file. This setting only applies to catalog
* URIs obtained from the catalogs property in the
* CatalogManager.properties file
*
*
*
* xml.catalog.verbosity
* verbosity
* If non-zero, the Catalog classes will print informative and debugging messages.
* The higher the number, the more messages.
*
*
*
* xml.catalog.prefer
* prefer
* Which identifier is preferred, "public" or "system"?
*
*
*
* xml.catalog.staticCatalog
* static-catalog
* Should a single catalog be constructed for all parsing, or should a different
* catalog be created for each parser?
*
*
*
* xml.catalog.allowPI
* allow-oasis-xml-catalog-pi
* If the source document contains "oasis-xml-catalog" processing instructions,
* should they be used?
*
*
*
* xml.catalog.className
* catalog-class-name
* If you're using the convenience classes
* org.apache.xml.resolver.tools.*), this setting
* allows you to specify an alternate class name to use for the underlying
* catalog.
*
*
*
*
* @see Catalog
*
* @author Norman Walsh
* [email protected]
*
* @version 1.0
*/
public class CatalogManager {
private static String pFiles = "xml.catalog.files";
private static String pVerbosity = "xml.catalog.verbosity";
private static String pPrefer = "xml.catalog.prefer";
private static String pStatic = "xml.catalog.staticCatalog";
private static String pAllowPI = "xml.catalog.allowPI";
private static String pClassname = "xml.catalog.className";
private static String pIgnoreMissing = "xml.catalog.ignoreMissing";
/** A static CatalogManager instance for sharing */
private static CatalogManager staticManager = new CatalogManager();
/** The bootstrap resolver to use when loading XML Catalogs. */
private BootstrapResolver bResolver = new BootstrapResolver();
/** Flag to ignore missing property files and/or properties */
private boolean ignoreMissingProperties
= (System.getProperty(pIgnoreMissing) != null
|| System.getProperty(pFiles) != null);
/** Holds the resources after they are loaded from the file. */
private ResourceBundle resources;
/** The name of the CatalogManager properties file. */
private String propertyFile = "CatalogManager.properties";
/** The location of the propertyFile */
private URL propertyFileURI = null;
/** Default catalog files list. */
private String defaultCatalogFiles = "./xcatalog";
/** Current catalog files list. */
private String catalogFiles = null;
/** Did the catalogFiles come from the properties file? */
private boolean fromPropertiesFile = false;
/** Default verbosity level if there is no property setting for it. */
private int defaultVerbosity = 1;
/** Current verbosity level. */
private Integer verbosity = null;
/** Default preference setting. */
private boolean defaultPreferPublic = true;
/** Current preference setting. */
private Boolean preferPublic = null;
/** Default setting of the static catalog flag. */
private boolean defaultUseStaticCatalog = true;
/** Current setting of the static catalog flag. */
private Boolean useStaticCatalog = null;
/** The static catalog used by this manager. */
private static Catalog staticCatalog = null;
/** Default setting of the oasisXMLCatalogPI flag. */
private boolean defaultOasisXMLCatalogPI = true;
/** Current setting of the oasisXMLCatalogPI flag. */
private Boolean oasisXMLCatalogPI = null;
/** Default setting of the relativeCatalogs flag. */
private boolean defaultRelativeCatalogs = true;
/** Current setting of the relativeCatalogs flag. */
private Boolean relativeCatalogs = null;
/** Current catalog class name. */
private String catalogClassName = null;
/** The manager's debug object. Used for printing debugging messages.
*
* This field is public so that objects that have access to this
* CatalogManager can use this debug object.
*/
public Debug debug = null;
/** Constructor. */
public CatalogManager() {
debug = new Debug();
// Note that we don't setDebug() here; we do that lazily. Either the
// user will set it explicitly, or we'll do it automagically if they
// read from the propertyFile for some other reason. That way, there's
// no attempt to read from the file before the caller has had a chance
// to avoid it.
}
/** Constructor that specifies an explicit property file. */
public CatalogManager(String propertyFile) {
this.propertyFile = propertyFile;
debug = new Debug();
// Note that we don't setDebug() here; we do that lazily. Either the
// user will set it explicitly, or we'll do it automagically if they
// read from the propertyFile for some other reason. That way, there's
// no attempt to read from the file before the caller has had a chance
// to avoid it.
}
/** Set the bootstrap resolver.*/
public void setBootstrapResolver(BootstrapResolver resolver) {
bResolver = resolver;
}
/** Get the bootstrap resolver.*/
public BootstrapResolver getBootstrapResolver() {
return bResolver;
}
/**
* Load the properties from the propertyFile and build the
* resources from it.
*/
private synchronized void readProperties() {
try {
propertyFileURI = CatalogManager.class.getResource("/"+propertyFile);
InputStream in =
CatalogManager.class.getResourceAsStream("/"+propertyFile);
if (in==null) {
if (!ignoreMissingProperties) {
System.err.println("Cannot find "+propertyFile);
// there's no reason to give this warning more than once
ignoreMissingProperties = true;
}
return;
}
resources = new PropertyResourceBundle(in);
} catch (MissingResourceException mre) {
if (!ignoreMissingProperties) {
System.err.println("Cannot read "+propertyFile);
}
} catch (java.io.IOException e) {
if (!ignoreMissingProperties) {
System.err.println("Failure trying to read "+propertyFile);
}
}
// This is a bit of a hack. After we've successfully read the properties,
// use them to set the default debug level, if the user hasn't already set
// the default debug level.
if (verbosity == null) {
try {
String verbStr = resources.getString("verbosity");
int verb = Integer.parseInt(verbStr.trim());
debug.setDebug(verb);
verbosity = new Integer(verb);
} catch (Exception e) {
// nop
}
}
}
/**
* Allow access to the static CatalogManager
*/
public static CatalogManager getStaticManager() {
return staticManager;
}
/**
* How are missing properties handled?
*
* If true, missing or unreadable property files will
* not be reported. Otherwise, a message will be sent to System.err.
*
*/
public boolean getIgnoreMissingProperties() {
return ignoreMissingProperties;
}
/**
* How should missing properties be handled?
*
* If ignore is true, missing or unreadable property files will
* not be reported. Otherwise, a message will be sent to System.err.
*
*/
public void setIgnoreMissingProperties(boolean ignore) {
ignoreMissingProperties = ignore;
}
/**
* How are missing properties handled?
*
* If ignore is true, missing or unreadable property files will
* not be reported. Otherwise, a message will be sent to System.err.
*
*
* @deprecated No longer static; use get/set methods.
*/
public void ignoreMissingProperties(boolean ignore) {
setIgnoreMissingProperties(ignore);
}
/**
* Obtain the verbosity setting from the properties.
*
* @return The verbosity level from the propertyFile or the
* defaultVerbosity.
*/
private int queryVerbosity () {
String defaultVerbStr = Integer.toString(defaultVerbosity);
String verbStr = System.getProperty(pVerbosity);
if (verbStr == null) {
if (resources==null) readProperties();
if (resources != null) {
try {
verbStr = resources.getString("verbosity");
} catch (MissingResourceException e) {
verbStr = defaultVerbStr;
}
} else {
verbStr = defaultVerbStr;
}
}
int verb = defaultVerbosity;
try {
verb = Integer.parseInt(verbStr.trim());
} catch (Exception e) {
System.err.println("Cannot parse verbosity: \"" + verbStr + "\"");
}
// This is a bit of a hack. After we've successfully got the verbosity,
// we have to use it to set the default debug level,
// if the user hasn't already set the default debug level.
if (verbosity == null) {
debug.setDebug(verb);
verbosity = new Integer(verb);
}
return verb;
}
/**
* What is the current verbosity?
*/
public int getVerbosity() {
if (verbosity == null) {
verbosity = new Integer(queryVerbosity());
}
return verbosity.intValue();
}
/**
* Set the current verbosity.
*/
public void setVerbosity (int verbosity) {
this.verbosity = new Integer(verbosity);
debug.setDebug(verbosity);
}
/**
* What is the current verbosity?
*
* @deprecated No longer static; use get/set methods.
*/
public int verbosity () {
return getVerbosity();
}
/**
* Obtain the relativeCatalogs setting from the properties.
*
* @return The relativeCatalogs setting from the propertyFile or the
* defaultRelativeCatalogs.
*/
private boolean queryRelativeCatalogs () {
if (resources==null) readProperties();
if (resources==null) return defaultRelativeCatalogs;
try {
String allow = resources.getString("relative-catalogs");
return (allow.equalsIgnoreCase("true")
|| allow.equalsIgnoreCase("yes")
|| allow.equalsIgnoreCase("1"));
} catch (MissingResourceException e) {
return defaultRelativeCatalogs;
}
}
/**
* Get the relativeCatalogs setting.
*
* This property is used when the catalogFiles property is
* interrogated. If true, then relative catalog entry file names
* are returned. If false, relative catalog entry file names are
* made absolute with respect to the properties file before returning
* them.
*
* This property only applies when the catalog files
* come from a properties file. If they come from a system property or
* the default list, they are never considered relative. (What would
* they be relative to?)
*
* In the properties, a value of 'yes', 'true', or '1' is considered
* true, anything else is false.
*
* @return The relativeCatalogs setting from the propertyFile or the
* defaultRelativeCatalogs.
*/
public boolean getRelativeCatalogs () {
if (relativeCatalogs == null) {
relativeCatalogs = new Boolean(queryRelativeCatalogs());
}
return relativeCatalogs.booleanValue();
}
/**
* Set the relativeCatalogs setting.
*
* @see #getRelativeCatalogs()
*/
public void setRelativeCatalogs (boolean relative) {
relativeCatalogs = new Boolean(relative);
}
/**
* Get the relativeCatalogs setting.
*
* @deprecated No longer static; use get/set methods.
*/
public boolean relativeCatalogs () {
return getRelativeCatalogs();
}
/**
* Obtain the list of catalog files from the properties.
*
* @return A semicolon delimited list of catlog file URIs
*/
private String queryCatalogFiles () {
String catalogList = System.getProperty(pFiles);
fromPropertiesFile = false;
if (catalogList == null) {
if (resources == null) readProperties();
if (resources != null) {
try {
catalogList = resources.getString("catalogs");
fromPropertiesFile = true;
} catch (MissingResourceException e) {
System.err.println(propertyFile + ": catalogs not found.");
catalogList = null;
}
}
}
if (catalogList == null) {
catalogList = defaultCatalogFiles;
}
return catalogList;
}
/**
* Return the current list of catalog files.
*
* @return A vector of the catalog file names or null if no catalogs
* are available in the properties.
*/
public Vector getCatalogFiles() {
if (catalogFiles == null) {
catalogFiles = queryCatalogFiles();
}
StringTokenizer files = new StringTokenizer(catalogFiles, ";");
Vector catalogs = new Vector();
while (files.hasMoreTokens()) {
String catalogFile = files.nextToken();
URL absURI = null;
if (fromPropertiesFile && !relativeCatalogs()) {
try {
absURI = new URL(propertyFileURI, catalogFile);
catalogFile = absURI.toString();
} catch (MalformedURLException mue) {
absURI = null;
}
}
catalogs.add(catalogFile);
}
return catalogs;
}
/**
* Set the list of catalog files.
*/
public void setCatalogFiles(String fileList) {
catalogFiles = fileList;
fromPropertiesFile = false;
}
/**
* Return the current list of catalog files.
*
* @return A vector of the catalog file names or null if no catalogs
* are available in the properties.
*
* @deprecated No longer static; use get/set methods.
*/
public Vector catalogFiles() {
return getCatalogFiles();
}
/**
* Obtain the preferPublic setting from the properties.
*
* In the properties, a value of 'public' is true,
* anything else is false.
*
* @return True if prefer is public or the
* defaultPreferSetting.
*/
private boolean queryPreferPublic () {
String prefer = System.getProperty(pPrefer);
if (prefer == null) {
if (resources==null) readProperties();
if (resources==null) return defaultPreferPublic;
try {
prefer = resources.getString("prefer");
} catch (MissingResourceException e) {
return defaultPreferPublic;
}
}
if (prefer == null) {
return defaultPreferPublic;
}
return (prefer.equalsIgnoreCase("public"));
}
/**
* Return the current prefer public setting.
*
* @return True if public identifiers are preferred.
*/
public boolean getPreferPublic () {
if (preferPublic == null) {
preferPublic = new Boolean(queryPreferPublic());
}
return preferPublic.booleanValue();
}
/**
* Set the prefer public setting.
*/
public void setPreferPublic (boolean preferPublic) {
this.preferPublic = new Boolean(preferPublic);
}
/**
* Return the current prefer public setting.
*
* @return True if public identifiers are preferred.
*
* @deprecated No longer static; use get/set methods.
*/
public boolean preferPublic () {
return getPreferPublic();
}
/**
* Obtain the static-catalog setting from the properties.
*
* In the properties, a value of 'yes', 'true', or '1' is considered
* true, anything else is false.
*
* @return The static-catalog setting from the propertyFile or the
* defaultUseStaticCatalog.
*/
private boolean queryUseStaticCatalog () {
String staticCatalog = System.getProperty(pStatic);
if (staticCatalog == null) {
if (resources==null) readProperties();
if (resources==null) return defaultUseStaticCatalog;
try {
staticCatalog = resources.getString("static-catalog");
} catch (MissingResourceException e) {
return defaultUseStaticCatalog;
}
}
if (staticCatalog == null) {
return defaultUseStaticCatalog;
}
return (staticCatalog.equalsIgnoreCase("true")
|| staticCatalog.equalsIgnoreCase("yes")
|| staticCatalog.equalsIgnoreCase("1"));
}
/**
* Get the current use static catalog setting.
*/
public boolean getUseStaticCatalog() {
if (useStaticCatalog == null) {
useStaticCatalog = new Boolean(queryUseStaticCatalog());
}
return useStaticCatalog.booleanValue();
}
/**
* Set the use static catalog setting.
*/
public void setUseStaticCatalog(boolean useStatic) {
useStaticCatalog = new Boolean(useStatic);
}
/**
* Get the current use static catalog setting.
*
* @deprecated No longer static; use get/set methods.
*/
public boolean staticCatalog() {
return getUseStaticCatalog();
}
/**
* Get a new catalog instance.
*
* This method always returns a new instance of the underlying catalog class.
*/
public Catalog getPrivateCatalog() {
Catalog catalog = staticCatalog;
if (useStaticCatalog == null) {
useStaticCatalog = new Boolean(getUseStaticCatalog());
}
if (catalog == null || !useStaticCatalog.booleanValue()) {
try {
String catalogClassName = getCatalogClassName();
if (catalogClassName == null) {
catalog = new Catalog();
} else {
try {
catalog = (Catalog) Class.forName(catalogClassName).newInstance();
} catch (ClassNotFoundException cnfe) {
debug.message(1,"Catalog class named '"
+ catalogClassName
+ "' could not be found. Using default.");
catalog = new Catalog();
} catch (ClassCastException cnfe) {
debug.message(1,"Class named '"
+ catalogClassName
+ "' is not a Catalog. Using default.");
catalog = new Catalog();
}
}
catalog.setCatalogManager(this);
catalog.setupReaders();
catalog.loadSystemCatalogs();
} catch (Exception ex) {
ex.printStackTrace();
}
if (useStaticCatalog.booleanValue()) {
staticCatalog = catalog;
}
}
return catalog;
}
/**
* Get a catalog instance.
*
* If this manager uses static catalogs, the same static catalog will
* always be returned. Otherwise a new catalog will be returned.
*/
public Catalog getCatalog() {
Catalog catalog = staticCatalog;
if (useStaticCatalog == null) {
useStaticCatalog = new Boolean(getUseStaticCatalog());
}
if (catalog == null || !useStaticCatalog.booleanValue()) {
catalog = getPrivateCatalog();
if (useStaticCatalog.booleanValue()) {
staticCatalog = catalog;
}
}
return catalog;
}
/**
* Obtain the oasisXMLCatalogPI setting from the properties.
*
* In the properties, a value of 'yes', 'true', or '1' is considered
* true, anything else is false.
*
* @return The oasisXMLCatalogPI setting from the propertyFile or the
* defaultOasisXMLCatalogPI.
*/
public boolean queryAllowOasisXMLCatalogPI () {
String allow = System.getProperty(pAllowPI);
if (allow == null) {
if (resources==null) readProperties();
if (resources==null) return defaultOasisXMLCatalogPI;
try {
allow = resources.getString("allow-oasis-xml-catalog-pi");
} catch (MissingResourceException e) {
return defaultOasisXMLCatalogPI;
}
}
if (allow == null) {
return defaultOasisXMLCatalogPI;
}
return (allow.equalsIgnoreCase("true")
|| allow.equalsIgnoreCase("yes")
|| allow.equalsIgnoreCase("1"));
}
/**
* Get the current XML Catalog PI setting.
*/
public boolean getAllowOasisXMLCatalogPI () {
if (oasisXMLCatalogPI == null) {
oasisXMLCatalogPI = new Boolean(queryAllowOasisXMLCatalogPI());
}
return oasisXMLCatalogPI.booleanValue();
}
/**
* Set the XML Catalog PI setting
*/
public void setAllowOasisXMLCatalogPI(boolean allowPI) {
oasisXMLCatalogPI = new Boolean(allowPI);
}
/**
* Get the current XML Catalog PI setting.
*
* @deprecated No longer static; use get/set methods.
*/
public boolean allowOasisXMLCatalogPI() {
return getAllowOasisXMLCatalogPI();
}
/**
* Obtain the Catalog class name setting from the properties.
*
*/
public String queryCatalogClassName () {
String className = System.getProperty(pClassname);
if (className == null) {
if (resources==null) readProperties();
if (resources==null) return null;
try {
return resources.getString("catalog-class-name");
} catch (MissingResourceException e) {
return null;
}
}
return className;
}
/**
* Get the current Catalog class name.
*/
public String getCatalogClassName() {
if (catalogClassName == null) {
catalogClassName = queryCatalogClassName();
}
return catalogClassName;
}
/**
* Set the Catalog class name.
*/
public void setCatalogClassName(String className) {
catalogClassName = className;
}
/**
* Get the current Catalog class name.
*
* @deprecated No longer static; use get/set methods.
*/
public String catalogClassName() {
return getCatalogClassName();
}
}