diff --git a/java/src/org/apache/xml/resolver/CatalogManager.java b/java/src/org/apache/xml/resolver/CatalogManager.java index 67063ce..66972d8 100644 --- a/java/src/org/apache/xml/resolver/CatalogManager.java +++ b/java/src/org/apache/xml/resolver/CatalogManager.java @@ -70,6 +70,9 @@ import java.net.MalformedURLException; import java.io.*; import java.util.*; +import org.apache.xml.resolver.helpers.Debug; +import org.apache.xml.resolver.Catalog; + /** *

CatalogManager provides an interface to the catalog properties.

* @@ -166,43 +169,102 @@ public class CatalogManager { 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(); + /** Flag to ignore missing property files and/or properties */ - private static boolean ignoreMissingProperties + private boolean ignoreMissingProperties = (System.getProperty(pIgnoreMissing) != null || System.getProperty(pFiles) != null); /** Holds the resources after they are loaded from the file. */ - private static ResourceBundle resources; + private ResourceBundle resources; /** The name of the CatalogManager properties file. */ - private static String propertyFile = "CatalogManager.properties"; + private String propertyFile = "CatalogManager.properties"; /** The location of the propertyFile */ - private static URL propertyFileURI = null; + private URL propertyFileURI = null; /** Default catalog files list. */ - private static String defaultCatalogFiles = "./xcatalog"; + private String defaultCatalogFiles = "./xcatalog"; + + /** Current catalog files list. */ + private String catalogFiles = null; + + /** Did the catalgoFiles come from the properties file? */ + private boolean fromPropertiesFile = false; /** Default verbosity level if there is no property setting for it. */ - private static int defaultVerbosity = 1; + private int defaultVerbosity = 1; + + /** Current verbosity level. */ + private Integer verbosity = null; /** Default preference setting. */ - private static boolean defaultPreferPublic = true; + private boolean defaultPreferPublic = true; + + /** Current preference setting. */ + private Boolean preferPublic = null; /** Default setting of the static catalog flag. */ - private static boolean defaultStaticCatalog = true; + 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 static boolean defaultOasisXMLCatalogPI = true; + private boolean defaultOasisXMLCatalogPI = true; + + /** Current setting of the oasisXMLCatalogPI flag. */ + private Boolean oasisXMLCatalogPI = null; /** Default setting of the relativeCatalogs flag. */ - private static boolean defaultRelativeCatalogs = true; + 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. + } /** - *

Load the properties from the propertyFile and build the - * resources from it.

+ * Load the properties from the propertyFile and build the + * resources from it. */ - private synchronized static void readProperties() { + private synchronized void readProperties() { try { propertyFileURI = CatalogManager.class.getResource("/"+propertyFile); InputStream in = @@ -210,6 +272,8 @@ public class CatalogManager { 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; } @@ -223,26 +287,71 @@ public class CatalogManager { 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 + } + } } /** - *

Tell the CatalogManager how to handle missing properties

+ * 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 static void ignoreMissingProperties(boolean ignore) { + public void setIgnoreMissingProperties(boolean ignore) { ignoreMissingProperties = ignore; } /** - *

Obtain the verbosity setting from the properties.

+ * 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. * * @returns The verbosity level from the propertyFile or the * defaultVerbosity. */ - public static int verbosity () { + private int queryVerbosity () { String verbStr = System.getProperty(pVerbosity); if (verbStr == null) { @@ -265,7 +374,56 @@ public class CatalogManager { } /** - *

Obtain the relativeCatalogs setting from the properties.

+ * 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. + * + * @returns 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 @@ -284,34 +442,43 @@ public class CatalogManager { * @returns The relativeCatalogs setting from the propertyFile or the * defaultRelativeCatalogs. */ - public static boolean relativeCatalogs () { - 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; + public boolean getRelativeCatalogs () { + if (relativeCatalogs == null) { + relativeCatalogs = new Boolean(queryRelativeCatalogs()); } + + return relativeCatalogs.booleanValue(); } /** - *

Obtain the list of catalog files from the properties.

+ * Set the relativeCatalogs setting. * - *

Note that the list of catalog files is always a semicolon - * delimited list, even on Unix systems where a colon delimited list - * might be considered more natural.

+ * @returns The relativeCatalogs setting from the propertyFile or the + * defaultRelativeCatalogs. * - * @returns A vector of the catalog file names or null if no catalogs - * are available in the properties. + * @see #getRelativeCatalogs() */ - public static Vector catalogFiles () { + 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. + * + * @returns A semicolon delimited list of catlog file URIs + */ + private String queryCatalogFiles () { String catalogList = System.getProperty(pFiles); - boolean fromPropertiesFile = false; + fromPropertiesFile = false; if (catalogList == null) { if (resources == null) readProperties(); @@ -330,7 +497,21 @@ public class CatalogManager { catalogList = defaultCatalogFiles; } - StringTokenizer files = new StringTokenizer(catalogList, ";"); + return catalogList; + } + + /** + * Return the current list of catalog files. + * + * @returns 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(); @@ -347,19 +528,40 @@ public class CatalogManager { catalogs.add(catalogFile); } + return catalogs; } /** - *

Obtain the preferPublic setting from the properties.

- * - *

In the properties, a value of 'public' is true, - * anything else is false.

- * - * @returns True if prefer is public or the - * defaultPreferSetting. - */ - public static boolean preferPublic () { + * Set the list of catalog files. + */ + public void setCatalogFiles(String fileList) { + catalogFiles = fileList; + fromPropertiesFile = false; + } + + /** + * Return the current list of catalog files. + * + * @returns 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.

+ * + * @returns True if prefer is public or the + * defaultPreferSetting. + */ + private boolean queryPreferPublic () { String prefer = System.getProperty(pPrefer); if (prefer == null) { @@ -380,29 +582,61 @@ public class CatalogManager { } /** - *

Obtain the static-catalog setting from the properties.

+ * Return the current prefer public setting. + * + * @returns True if public identifiers are preferred. + */ + public boolean getPreferPublic () { + if (preferPublic == null) { + preferPublic = new Boolean(queryPreferPublic()); + } + return preferPublic.booleanValue(); + } + + /** + * Set the prefer public setting. + * + * @returns True if public identifiers are preferred. + */ + public void setPreferPublic (boolean preferPublic) { + this.preferPublic = new Boolean(preferPublic); + } + + /** + * Return the current prefer public setting. + * + * @returns 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.

* * @returns The static-catalog setting from the propertyFile or the - * defaultStaticCatalog. + * defaultUseStaticCatalog. */ - public static boolean staticCatalog () { + private boolean queryUseStaticCatalog () { String staticCatalog = System.getProperty(pStatic); - if (staticCatalog == null) { + if (useStaticCatalog == null) { if (resources==null) readProperties(); - if (resources==null) return defaultStaticCatalog; + if (resources==null) return defaultUseStaticCatalog; try { staticCatalog = resources.getString("static-catalog"); } catch (MissingResourceException e) { - return defaultStaticCatalog; + return defaultUseStaticCatalog; } } if (staticCatalog == null) { - return defaultStaticCatalog; + return defaultUseStaticCatalog; } return (staticCatalog.equalsIgnoreCase("true") @@ -410,6 +644,106 @@ public class CatalogManager { || 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.

* @@ -419,7 +753,7 @@ public class CatalogManager { * @returns The oasisXMLCatalogPI setting from the propertyFile or the * defaultOasisXMLCatalogPI. */ - public static boolean allowOasisXMLCatalogPI () { + public boolean queryAllowOasisXMLCatalogPI () { String allow = System.getProperty(pAllowPI); if (allow == null) { @@ -441,11 +775,38 @@ public class CatalogManager { || 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 static String catalogClassName () { + public String queryCatalogClassName () { String className = System.getProperty(pClassname); if (className == null) { @@ -460,4 +821,31 @@ public class CatalogManager { 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(); + } }