Initial checkin of Sun Resolver 1.1 sources
git-svn-id: https://svn.apache.org/repos/asf/xml/commons/trunk@225950 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
1 parent
32b041f81d
commit
92f652862f
35 files changed
+9761
No files matched your search
@@ -0,0 +1,11 @@
|
||||
Manifest-Version: 1.0
|
||||
Created-By: 1.2.2 (Sun Microsystems Inc.)
|
||||
Main-Class: org.apache.xml.resolver.Catalog
|
||||
|
||||
Name: org/apache/xml/resolver
|
||||
Comment: xml-commons Resolver code
|
||||
Implementation-Title: org.apache.xml.resolver.Catalog
|
||||
Implementation-Version: 1.0
|
||||
Implementation-Vendor: Apache Software Foundation
|
||||
Implementation-URL: http://xml.apache.org/commons/
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,289 @@
|
||||
// CatalogEntry.java - Represents Catalog entries
|
||||
|
||||
/*
|
||||
* The Apache Software License, Version 1.1
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2001 The Apache Software Foundation. All rights
|
||||
* reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The end-user documentation included with the redistribution,
|
||||
* if any, must include the following acknowledgment:
|
||||
* "This product includes software developed by the
|
||||
* Apache Software Foundation (http://www.apache.org/)."
|
||||
* Alternately, this acknowledgment may appear in the software itself,
|
||||
* if and wherever such third-party acknowledgments normally appear.
|
||||
*
|
||||
* 4. The names "Xalan" and "Apache Software Foundation" must
|
||||
* not be used to endorse or promote products derived from this
|
||||
* software without prior written permission. For written
|
||||
* permission, please contact apache@apache.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "Apache",
|
||||
* nor may "Apache" appear in their name, without prior written
|
||||
* permission of the Apache Software Foundation.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation and was
|
||||
* originally based on software copyright (c) 2001, International
|
||||
* Business Machines Corporation., http://www.ibm.com. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*/
|
||||
|
||||
package org.apache.xml.resolver;
|
||||
|
||||
import java.util.Hashtable;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* <p>Represents a Catalog entry.</p>
|
||||
*
|
||||
* <p>Instances of this class represent individual entries
|
||||
* in a Catalog.</p>
|
||||
*
|
||||
* <p>Each catalog entry has a unique name and is associated with
|
||||
* an arbitrary number of arguments (all strings). For example, the
|
||||
* TR9401 catalog entry "PUBLIC" has two arguments, a public identifier
|
||||
* and a system identifier. Each entry has a unique numeric type,
|
||||
* assigned automatically when the entry type is created.</p>
|
||||
*
|
||||
* <p>The number and type of catalog entries is maintained
|
||||
* <em>statically</em>. Catalog classes, or their subclasses, can add
|
||||
* new entry types, but all Catalog objects share the same global pool
|
||||
* of types.</p>
|
||||
*
|
||||
* <p>Initially there are no valid entries.</p>
|
||||
*
|
||||
* @see Catalog
|
||||
*
|
||||
* @author Norman Walsh
|
||||
* <a href="mailto:Norman.Walsh@Sun.COM">Norman.Walsh@Sun.COM</a>
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
public class CatalogEntry {
|
||||
/** The nextEntry is the ordinal number of the next entry type. */
|
||||
protected static int nextEntry = 0;
|
||||
|
||||
/**
|
||||
* The entryTypes vector maps catalog entry names
|
||||
* (e.g., 'BASE' or 'SYSTEM') to their type (1, 2, etc.).
|
||||
* Names are case sensitive.
|
||||
*/
|
||||
protected static Hashtable entryTypes = new Hashtable();
|
||||
|
||||
/** The entryTypes vector maps catalog entry types to the
|
||||
number of arguments they're required to have. */
|
||||
protected static Vector entryArgs = new Vector();
|
||||
|
||||
/**
|
||||
* <p>Adds a new catalog entry type.</p>
|
||||
*
|
||||
* @param name The name of the catalog entry type. This must be
|
||||
* unique among all types and is case-sensitive. (Adding a duplicate
|
||||
* name effectively replaces the old type with the new type.)
|
||||
* @param numArgs The number of arguments that this entry type
|
||||
* is required to have. There is no provision for variable numbers
|
||||
* of arguments.
|
||||
* @return The type for the new entry.
|
||||
*/
|
||||
public static int addEntryType(String name, int numArgs) {
|
||||
entryTypes.put(name, new Integer(nextEntry));
|
||||
entryArgs.add(nextEntry, new Integer(numArgs));
|
||||
nextEntry++;
|
||||
|
||||
return nextEntry-1;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Lookup an entry type</p>
|
||||
*
|
||||
* @param name The name of the catalog entry type.
|
||||
* @return The type of the catalog entry with the specified name.
|
||||
* @throws InvalidCatalogEntryTypeException if no entry has the
|
||||
* specified name.
|
||||
*/
|
||||
public static int getEntryType(String name)
|
||||
throws CatalogException {
|
||||
if (!entryTypes.containsKey(name)) {
|
||||
throw new CatalogException(CatalogException.INVALID_ENTRY_TYPE);
|
||||
}
|
||||
|
||||
Integer iType = (Integer) entryTypes.get(name);
|
||||
|
||||
if (iType == null) {
|
||||
throw new CatalogException(CatalogException.INVALID_ENTRY_TYPE);
|
||||
}
|
||||
|
||||
return iType.intValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Find out how many arguments an entry is required to have.</p>
|
||||
*
|
||||
* @param name The name of the catalog entry type.
|
||||
* @return The number of arguments that entry type is required to have.
|
||||
* @throws InvalidCatalogEntryTypeException if no entry has the
|
||||
* specified name.
|
||||
*/
|
||||
public static int getEntryArgCount(String name)
|
||||
throws CatalogException {
|
||||
return getEntryArgCount(getEntryType(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Find out how many arguments an entry is required to have.</p>
|
||||
*
|
||||
* @param type A valid catalog entry type.
|
||||
* @return The number of arguments that entry type is required to have.
|
||||
* @throws InvalidCatalogEntryTypeException if the type is invalid.
|
||||
*/
|
||||
public static int getEntryArgCount(int type)
|
||||
throws CatalogException {
|
||||
try {
|
||||
Integer iArgs = (Integer) entryArgs.get(type);
|
||||
return iArgs.intValue();
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
throw new CatalogException(CatalogException.INVALID_ENTRY_TYPE);
|
||||
}
|
||||
}
|
||||
|
||||
/** The entry type of this entry */
|
||||
protected int entryType = 0;
|
||||
|
||||
/** The arguments associated with this entry */
|
||||
protected Vector args = null;
|
||||
|
||||
/**
|
||||
* <p>Null constructor; something for subclasses to call.</p>
|
||||
*/
|
||||
public CatalogEntry() {}
|
||||
|
||||
/**
|
||||
* <p>Construct a catalog entry of the specified type.</p>
|
||||
*
|
||||
* @param name The name of the entry type
|
||||
* @param args A String Vector of arguments
|
||||
* @throws InvalidCatalogEntryTypeException if no such entry type
|
||||
* exists.
|
||||
* @throws InvalidCatalogEntryException if the wrong number of arguments
|
||||
* is passed.
|
||||
*/
|
||||
public CatalogEntry(String name, Vector args)
|
||||
throws CatalogException {
|
||||
Integer iType = (Integer) entryTypes.get(name);
|
||||
|
||||
if (iType == null) {
|
||||
throw new CatalogException(CatalogException.INVALID_ENTRY_TYPE);
|
||||
}
|
||||
|
||||
int type = iType.intValue();
|
||||
|
||||
try {
|
||||
Integer iArgs = (Integer) entryArgs.get(type);
|
||||
if (iArgs.intValue() != args.size()) {
|
||||
throw new CatalogException(CatalogException.INVALID_ENTRY);
|
||||
}
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
throw new CatalogException(CatalogException.INVALID_ENTRY_TYPE);
|
||||
}
|
||||
|
||||
entryType = type;
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Construct a catalog entry of the specified type.</p>
|
||||
*
|
||||
* @param name The name of the entry type
|
||||
* @param args A String Vector of arguments
|
||||
* @throws InvalidCatalogEntryTypeException if no such entry type
|
||||
* exists.
|
||||
* @throws InvalidCatalogEntryException if the wrong number of arguments
|
||||
* is passed.
|
||||
*/
|
||||
public CatalogEntry(int type, Vector args)
|
||||
throws CatalogException {
|
||||
try {
|
||||
Integer iArgs = (Integer) entryArgs.get(type);
|
||||
if (iArgs.intValue() != args.size()) {
|
||||
throw new CatalogException(CatalogException.INVALID_ENTRY);
|
||||
}
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
throw new CatalogException(CatalogException.INVALID_ENTRY_TYPE);
|
||||
}
|
||||
|
||||
entryType = type;
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Get the entry type.</p>
|
||||
*
|
||||
* @return The entry type of the CatalogEntry
|
||||
*/
|
||||
public int getEntryType() {
|
||||
return entryType;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Get an entry argument.</p>
|
||||
*
|
||||
* @param argNum The argument number (arguments are numbered from 0).
|
||||
* @return The specified argument or null if an invalid argNum is
|
||||
* provided.
|
||||
*/
|
||||
public String getEntryArg(int argNum) {
|
||||
try {
|
||||
String arg = (String) args.get(argNum);
|
||||
return arg;
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Set an entry argument.</p>
|
||||
*
|
||||
* <p>Catalogs sometimes need to adjust the catlog entry parameters,
|
||||
* for example to make a relative URI absolute with respect to the
|
||||
* current base URI. But in general, this function should only be
|
||||
* called shortly after object creation to do some sort of cleanup.
|
||||
* Catalog entries should not mutate over time.</p>
|
||||
*
|
||||
* @param argNum The argument number (arguments are numbered from 0).
|
||||
* @throws ArrayIndexOutOfBoundsException if an invalid argument
|
||||
* number is provided.
|
||||
*/
|
||||
public void setEntryArg(int argNum, String newspec)
|
||||
throws ArrayIndexOutOfBoundsException {
|
||||
args.set(argNum, newspec);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
// CatalogException.java - Catalog exception
|
||||
|
||||
/*
|
||||
* The Apache Software License, Version 1.1
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2001 The Apache Software Foundation. All rights
|
||||
* reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The end-user documentation included with the redistribution,
|
||||
* if any, must include the following acknowledgment:
|
||||
* "This product includes software developed by the
|
||||
* Apache Software Foundation (http://www.apache.org/)."
|
||||
* Alternately, this acknowledgment may appear in the software itself,
|
||||
* if and wherever such third-party acknowledgments normally appear.
|
||||
*
|
||||
* 4. The names "Xalan" and "Apache Software Foundation" must
|
||||
* not be used to endorse or promote products derived from this
|
||||
* software without prior written permission. For written
|
||||
* permission, please contact apache@apache.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "Apache",
|
||||
* nor may "Apache" appear in their name, without prior written
|
||||
* permission of the Apache Software Foundation.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation and was
|
||||
* originally based on software copyright (c) 2001, International
|
||||
* Business Machines Corporation., http://www.ibm.com. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*/
|
||||
|
||||
package org.apache.xml.resolver;
|
||||
|
||||
/**
|
||||
* <p>Signal Catalog exception.</p>
|
||||
*
|
||||
* <p>This exception is thrown if an error occurs loading a
|
||||
* catalog file.</p>
|
||||
*
|
||||
* @see Catalog
|
||||
*
|
||||
* @author Norman Walsh
|
||||
* <a href="mailto:Norman.Walsh@Sun.COM">Norman.Walsh@Sun.COM</a>
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
public class CatalogException extends Exception {
|
||||
/** A wrapper around another exception */
|
||||
public static final int WRAPPER = 1;
|
||||
/** An invalid entry */
|
||||
public static final int INVALID_ENTRY = 2;
|
||||
/** An invalid entry type */
|
||||
public static final int INVALID_ENTRY_TYPE = 3;
|
||||
/** Could not instantiate an XML parser */
|
||||
public static final int NO_XML_PARSER = 4;
|
||||
/** Unknown XML format */
|
||||
public static final int UNKNOWN_FORMAT = 5;
|
||||
/** Unparseable XML catalog (not XML)*/
|
||||
public static final int UNPARSEABLE = 6;
|
||||
/** XML but parse failed */
|
||||
public static final int PARSE_FAILED = 7;
|
||||
|
||||
/**
|
||||
* The embedded exception if tunnelling, or null.
|
||||
*/
|
||||
private Exception exception = null;
|
||||
private int exceptionType = 0;
|
||||
|
||||
/**
|
||||
* Create a new CatalogException.
|
||||
*
|
||||
* @param type The exception type
|
||||
* @param message The error or warning message.
|
||||
*/
|
||||
public CatalogException (int type, String message) {
|
||||
super(message);
|
||||
this.exceptionType = type;
|
||||
this.exception = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new CatalogException.
|
||||
*
|
||||
* @param type The exception type
|
||||
*/
|
||||
public CatalogException (int type) {
|
||||
super("Catalog Exception " + type);
|
||||
this.exceptionType = type;
|
||||
this.exception = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new CatalogException wrapping an existing exception.
|
||||
*
|
||||
* <p>The existing exception will be embedded in the new
|
||||
* one, and its message will become the default message for
|
||||
* the CatalogException.</p>
|
||||
*
|
||||
* @param e The exception to be wrapped in a CatalogException.
|
||||
*/
|
||||
public CatalogException (Exception e) {
|
||||
super();
|
||||
this.exceptionType = WRAPPER;
|
||||
this.exception = e;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new CatalogException from an existing exception.
|
||||
*
|
||||
* <p>The existing exception will be embedded in the new
|
||||
* one, but the new exception will have its own message.</p>
|
||||
*
|
||||
* @param message The detail message.
|
||||
* @param e The exception to be wrapped in a CatalogException.
|
||||
*/
|
||||
public CatalogException (String message, Exception e) {
|
||||
super(message);
|
||||
this.exceptionType = WRAPPER;
|
||||
this.exception = e;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a detail message for this exception.
|
||||
*
|
||||
* <p>If there is an embedded exception, and if the CatalogException
|
||||
* has no detail message of its own, this method will return
|
||||
* the detail message from the embedded exception.</p>
|
||||
*
|
||||
* @return The error or warning message.
|
||||
*/
|
||||
public String getMessage ()
|
||||
{
|
||||
String message = super.getMessage();
|
||||
|
||||
if (message == null && exception != null) {
|
||||
return exception.getMessage();
|
||||
} else {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the embedded exception, if any.
|
||||
*
|
||||
* @return The embedded exception, or null if there is none.
|
||||
*/
|
||||
public Exception getException ()
|
||||
{
|
||||
return exception;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the exception type
|
||||
*
|
||||
* @return The exception type
|
||||
*/
|
||||
public int getExceptionType ()
|
||||
{
|
||||
return exceptionType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override toString to pick up any embedded exception.
|
||||
*
|
||||
* @return A string representation of this exception.
|
||||
*/
|
||||
public String toString ()
|
||||
{
|
||||
if (exception != null) {
|
||||
return exception.toString();
|
||||
} else {
|
||||
return super.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,463 @@
|
||||
// CatalogManager.java - Access CatalogManager.properties
|
||||
|
||||
/*
|
||||
* The Apache Software License, Version 1.1
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2001 The Apache Software Foundation. All rights
|
||||
* reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The end-user documentation included with the redistribution,
|
||||
* if any, must include the following acknowledgment:
|
||||
* "This product includes software developed by the
|
||||
* Apache Software Foundation (http://www.apache.org/)."
|
||||
* Alternately, this acknowledgment may appear in the software itself,
|
||||
* if and wherever such third-party acknowledgments normally appear.
|
||||
*
|
||||
* 4. The names "Xalan" and "Apache Software Foundation" must
|
||||
* not be used to endorse or promote products derived from this
|
||||
* software without prior written permission. For written
|
||||
* permission, please contact apache@apache.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "Apache",
|
||||
* nor may "Apache" appear in their name, without prior written
|
||||
* permission of the Apache Software Foundation.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation and was
|
||||
* originally based on software copyright (c) 2001, International
|
||||
* Business Machines Corporation., http://www.ibm.com. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*/
|
||||
|
||||
package org.apache.xml.resolver;
|
||||
|
||||
import java.lang.ClassNotFoundException;
|
||||
import java.lang.IllegalAccessException;
|
||||
import java.lang.InstantiationException;
|
||||
import java.lang.SecurityException;
|
||||
import java.lang.ClassCastException;
|
||||
import java.net.URL;
|
||||
import java.net.MalformedURLException;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* <p>CatalogManager provides an interface to the catalog properties.</p>
|
||||
*
|
||||
* <p>Properties can come from two places: from system properties or
|
||||
* from a <i>CatalogManager.properties</i> file. This class provides a transparent
|
||||
* interface to both, with system properties preferred over property file values.</p>
|
||||
*
|
||||
* <p>The following table summarizes the properties:</p>
|
||||
*
|
||||
* <table border="1">
|
||||
* <thead>
|
||||
* <tr>
|
||||
* <td>System Property</td>
|
||||
* <td>CatalogManager.properties<br/>Property</td>
|
||||
* <td>Description</td>
|
||||
* </tr>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <tr>
|
||||
* <td>xml.catalog.ignoreMissing</td>
|
||||
* <td> </td>
|
||||
* <td>If true, a missing <i>CatalogManager.properties</i> file or missing properties
|
||||
* within that file will not generate warning messages. See also the
|
||||
* <i>ignoreMissingProperties</i> method.</td>
|
||||
* </tr>
|
||||
*
|
||||
* <tr>
|
||||
* <td>xml.catalog.files</td>
|
||||
* <td>catalogs</td>
|
||||
* <td>The <emph>semicolon-delimited</emph> list of catalog files.</td>
|
||||
* </tr>
|
||||
*
|
||||
* <tr>
|
||||
* <td> </td>
|
||||
* <td>relative-catalogs</td>
|
||||
* <td>If false, relative catalog URIs are made absolute with respect to the base URI of
|
||||
* the <i>CatalogManager.properties</i> file. This setting only applies to catalog
|
||||
* URIs obtained from the <i>catalogs</i> property <emph>in the</emph>
|
||||
* <i>CatalogManager.properties</i> file</td>
|
||||
* </tr>
|
||||
*
|
||||
* <tr>
|
||||
* <td>xml.catalog.verbosity</td>
|
||||
* <td>verbosity</td>
|
||||
* <td>If non-zero, the Catalog classes will print informative and debugging messages.
|
||||
* The higher the number, the more messages.</td>
|
||||
* </tr>
|
||||
*
|
||||
* <tr>
|
||||
* <td>xml.catalog.prefer</td>
|
||||
* <td>prefer</td>
|
||||
* <td>Which identifier is preferred, "public" or "system"?</td>
|
||||
* </tr>
|
||||
*
|
||||
* <tr>
|
||||
* <td>xml.catalog.staticCatalog</td>
|
||||
* <td>static-catalog</td>
|
||||
* <td>Should a single catalog be constructed for all parsing, or should a different
|
||||
* catalog be created for each parser?</td>
|
||||
* </tr>
|
||||
*
|
||||
* <tr>
|
||||
* <td>xml.catalog.allowPI</td>
|
||||
* <td>allow-oasis-xml-catalog-pi</td>
|
||||
* <td>If the source document contains "oasis-xml-catalog" processing instructions,
|
||||
* should they be used?</td>
|
||||
* </tr>
|
||||
*
|
||||
* <tr>
|
||||
* <td>xml.catalog.className</td>
|
||||
* <td>catalog-class-name</td>
|
||||
* <td>If you're using the convenience classes
|
||||
* <tt>org.apache.xml.resolver.tools.*</tt>), this setting
|
||||
* allows you to specify an alternate class name to use for the underlying
|
||||
* catalog.</td>
|
||||
* </tr>
|
||||
* </tbody>
|
||||
* </table>
|
||||
*
|
||||
* @see Catalog
|
||||
*
|
||||
* @author Norman Walsh
|
||||
* <a href="mailto:Norman.Walsh@Sun.COM">Norman.Walsh@Sun.COM</a>
|
||||
*
|
||||
* @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";
|
||||
|
||||
/** Flag to ignore missing property files and/or properties */
|
||||
private static boolean ignoreMissingProperties
|
||||
= (System.getProperty(pIgnoreMissing) != null
|
||||
|| System.getProperty(pFiles) != null);
|
||||
|
||||
/** Holds the resources after they are loaded from the file. */
|
||||
private static ResourceBundle resources;
|
||||
|
||||
/** The name of the CatalogManager properties file. */
|
||||
private static String propertyFile = "CatalogManager.properties";
|
||||
|
||||
/** The location of the propertyFile */
|
||||
private static URL propertyFileURI = null;
|
||||
|
||||
/** Default catalog files list. */
|
||||
private static String defaultCatalogFiles = "./xcatalog";
|
||||
|
||||
/** Default verbosity level if there is no property setting for it. */
|
||||
private static int defaultVerbosity = 1;
|
||||
|
||||
/** Default preference setting. */
|
||||
private static boolean defaultPreferPublic = true;
|
||||
|
||||
/** Default setting of the static catalog flag. */
|
||||
private static boolean defaultStaticCatalog = true;
|
||||
|
||||
/** Default setting of the oasisXMLCatalogPI flag. */
|
||||
private static boolean defaultOasisXMLCatalogPI = true;
|
||||
|
||||
/** Default setting of the relativeCatalogs flag. */
|
||||
private static boolean defaultRelativeCatalogs = true;
|
||||
|
||||
/**
|
||||
* <p>Load the properties from the propertyFile and build the
|
||||
* resources from it.</p>
|
||||
*/
|
||||
private synchronized static 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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Tell the CatalogManager how to handle missing properties</p>
|
||||
*
|
||||
* <p>If ignore is true, missing or unreadable property files will
|
||||
* not be reported. Otherwise, a message will be sent to System.err.
|
||||
* </p>
|
||||
*/
|
||||
public static void ignoreMissingProperties(boolean ignore) {
|
||||
ignoreMissingProperties = ignore;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Obtain the verbosity setting from the properties.</p>
|
||||
*
|
||||
* @returns The verbosity level from the propertyFile or the
|
||||
* defaultVerbosity.
|
||||
*/
|
||||
public static int verbosity () {
|
||||
String verbStr = System.getProperty(pVerbosity);
|
||||
|
||||
if (verbStr == null) {
|
||||
if (resources==null) readProperties();
|
||||
if (resources==null) return defaultVerbosity;
|
||||
try {
|
||||
verbStr = resources.getString("verbosity");
|
||||
} catch (MissingResourceException e) {
|
||||
return defaultVerbosity;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
int verb = Integer.parseInt(verbStr.trim());
|
||||
return verb;
|
||||
} catch (Exception e) {
|
||||
System.err.println("Cannot parse verbosity: \"" + verbStr + "\"");
|
||||
return defaultVerbosity;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Obtain the relativeCatalogs setting from the properties.</p>
|
||||
*
|
||||
* <p>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.</p>
|
||||
*
|
||||
* <p>This property <emph>only applies</emph> 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?)</p>
|
||||
*
|
||||
* <p>In the properties, a value of 'yes', 'true', or '1' is considered
|
||||
* true, anything else is false.</p>
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Obtain the list of catalog files from the properties.</p>
|
||||
*
|
||||
* <p>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.</p>
|
||||
*
|
||||
* @returns A vector of the catalog file names or null if no catalogs
|
||||
* are available in the properties.
|
||||
*/
|
||||
public static Vector catalogFiles () {
|
||||
String catalogList = System.getProperty(pFiles);
|
||||
boolean 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;
|
||||
}
|
||||
|
||||
StringTokenizer files = new StringTokenizer(catalogList, ";");
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Obtain the preferPublic setting from the properties.</p>
|
||||
*
|
||||
* <p>In the properties, a value of 'public' is true,
|
||||
* anything else is false.</p>
|
||||
*
|
||||
* @returns True if prefer is public or the
|
||||
* defaultPreferSetting.
|
||||
*/
|
||||
public static boolean preferPublic () {
|
||||
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"));
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Obtain the static-catalog setting from the properties.</p>
|
||||
*
|
||||
* <p>In the properties, a value of 'yes', 'true', or '1' is considered
|
||||
* true, anything else is false.</p>
|
||||
*
|
||||
* @returns The static-catalog setting from the propertyFile or the
|
||||
* defaultStaticCatalog.
|
||||
*/
|
||||
public static boolean staticCatalog () {
|
||||
String staticCatalog = System.getProperty(pStatic);
|
||||
|
||||
if (staticCatalog == null) {
|
||||
if (resources==null) readProperties();
|
||||
if (resources==null) return defaultStaticCatalog;
|
||||
try {
|
||||
staticCatalog = resources.getString("static-catalog");
|
||||
} catch (MissingResourceException e) {
|
||||
return defaultStaticCatalog;
|
||||
}
|
||||
}
|
||||
|
||||
if (staticCatalog == null) {
|
||||
return defaultStaticCatalog;
|
||||
}
|
||||
|
||||
return (staticCatalog.equalsIgnoreCase("true")
|
||||
|| staticCatalog.equalsIgnoreCase("yes")
|
||||
|| staticCatalog.equalsIgnoreCase("1"));
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Obtain the oasisXMLCatalogPI setting from the properties.</p>
|
||||
*
|
||||
* <p>In the properties, a value of 'yes', 'true', or '1' is considered
|
||||
* true, anything else is false.</p>
|
||||
*
|
||||
* @returns The oasisXMLCatalogPI setting from the propertyFile or the
|
||||
* defaultOasisXMLCatalogPI.
|
||||
*/
|
||||
public static boolean allowOasisXMLCatalogPI () {
|
||||
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"));
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Obtain the Catalog class name setting from the properties.</p>
|
||||
*
|
||||
*/
|
||||
public static String catalogClassName () {
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* The Apache Software License, Version 1.1
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2001 The Apache Software Foundation. All rights
|
||||
* reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The end-user documentation included with the redistribution,
|
||||
* if any, must include the following acknowledgment:
|
||||
* "This product includes software developed by the
|
||||
* Apache Software Foundation (http://www.apache.org/)."
|
||||
* Alternately, this acknowledgment may appear in the software itself,
|
||||
* if and wherever such third-party acknowledgments normally appear.
|
||||
*
|
||||
* 4. The names "Xalan" and "Apache Software Foundation" must
|
||||
* not be used to endorse or promote products derived from this
|
||||
* software without prior written permission. For written
|
||||
* permission, please contact apache@apache.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "Apache",
|
||||
* nor may "Apache" appear in their name, without prior written
|
||||
* permission of the Apache Software Foundation.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation and was
|
||||
* originally based on software copyright (c) 2001, International
|
||||
* Business Machines Corporation., http://www.ibm.com. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,746 @@
|
||||
// Resolver.java - Represents an extension of OASIS Open Catalog files.
|
||||
|
||||
/*
|
||||
* The Apache Software License, Version 1.1
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2001 The Apache Software Foundation. All rights
|
||||
* reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The end-user documentation included with the redistribution,
|
||||
* if any, must include the following acknowledgment:
|
||||
* "This product includes software developed by the
|
||||
* Apache Software Foundation (http://www.apache.org/)."
|
||||
* Alternately, this acknowledgment may appear in the software itself,
|
||||
* if and wherever such third-party acknowledgments normally appear.
|
||||
*
|
||||
* 4. The names "Xalan" and "Apache Software Foundation" must
|
||||
* not be used to endorse or promote products derived from this
|
||||
* software without prior written permission. For written
|
||||
* permission, please contact apache@apache.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "Apache",
|
||||
* nor may "Apache" appear in their name, without prior written
|
||||
* permission of the Apache Software Foundation.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation and was
|
||||
* originally based on software copyright (c) 2001, International
|
||||
* Business Machines Corporation., http://www.ibm.com. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*/
|
||||
|
||||
package org.apache.xml.resolver;
|
||||
|
||||
import java.lang.Integer;
|
||||
import java.io.IOException;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.FileWriter;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Vector;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import org.apache.xml.resolver.readers.CatalogReader;
|
||||
import org.apache.xml.resolver.readers.SAXCatalogReader;
|
||||
import org.apache.xml.resolver.readers.OASISXMLCatalogReader;
|
||||
import org.apache.xml.resolver.readers.ExtendedXMLCatalogReader;
|
||||
import org.apache.xml.resolver.readers.TR9401CatalogReader;
|
||||
import org.apache.xml.resolver.readers.TextCatalogReader;
|
||||
import org.apache.xml.resolver.helpers.Debug;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.EntityResolver;
|
||||
import javax.xml.parsers.SAXParserFactory;
|
||||
|
||||
/**
|
||||
* <p>An extension to OASIS Open Catalog files, this class supports
|
||||
* suffix-based matching and an external RFC2483 resolver.</p>
|
||||
*
|
||||
* @see Catalog
|
||||
*
|
||||
* @author Norman Walsh
|
||||
* <a href="mailto:Norman.Walsh@Sun.COM">Norman.Walsh@Sun.COM</a>
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
public class Resolver extends Catalog {
|
||||
/**
|
||||
* <p>The URISUFFIX Catalog Entry type.</p>
|
||||
*
|
||||
* <p>URI suffix entries match URIs that end in a specified suffix.</p>
|
||||
*/
|
||||
public static final int URISUFFIX = CatalogEntry.addEntryType("URISUFFIX", 2);
|
||||
|
||||
/**
|
||||
* <p>The SYSTEMSUFFIX Catalog Entry type.</p>
|
||||
*
|
||||
* <p>System suffix entries match system identifiers that end in a
|
||||
* specified suffix.</p>
|
||||
*/
|
||||
public static final int SYSTEMSUFFIX = CatalogEntry.addEntryType("SYSTEMSUFFIX", 2);
|
||||
|
||||
/**
|
||||
* <p>The RESOLVER Catalog Entry type.</p>
|
||||
*
|
||||
* <p>A hook for providing support for web-based backup resolvers.</p>
|
||||
*/
|
||||
public static final int RESOLVER = CatalogEntry.addEntryType("RESOLVER", 1);
|
||||
|
||||
/**
|
||||
* <p>The SYSTEMREVERSE Catalog Entry type.</p>
|
||||
*
|
||||
* <p>This is a bit of a hack. There's no actual SYSTEMREVERSE entry,
|
||||
* but this entry type is used to indicate that a reverse lookup is
|
||||
* being performed. (This allows the Resolver to implement
|
||||
* RFC2483 I2N and I2NS.)
|
||||
*/
|
||||
public static final int SYSTEMREVERSE
|
||||
= CatalogEntry.addEntryType("SYSTEMREVERSE", 1);
|
||||
|
||||
/**
|
||||
* <p>Setup readers.</p>
|
||||
*/
|
||||
public void setupReaders() {
|
||||
SAXParserFactory spf = SAXParserFactory.newInstance();
|
||||
spf.setNamespaceAware(true);
|
||||
spf.setValidating(false);
|
||||
|
||||
SAXCatalogReader saxReader = new SAXCatalogReader(spf);
|
||||
|
||||
saxReader.setCatalogParser(null, "XMLCatalog",
|
||||
"org.apache.xml.resolver.readers.XCatalogReader");
|
||||
|
||||
saxReader.setCatalogParser(OASISXMLCatalogReader.namespaceName,
|
||||
"catalog",
|
||||
"org.apache.xml.resolver.readers.ExtendedXMLCatalogReader");
|
||||
|
||||
addReader("application/xml", saxReader);
|
||||
|
||||
TR9401CatalogReader textReader = new TR9401CatalogReader();
|
||||
addReader("text/plain", textReader);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Cleanup and process a Catalog entry.</p>
|
||||
*
|
||||
* <p>This method processes each Catalog entry, changing mapped
|
||||
* relative system identifiers into absolute ones (based on the current
|
||||
* base URI), and maintaining other information about the current
|
||||
* catalog.</p>
|
||||
*
|
||||
* @param entry The CatalogEntry to process.
|
||||
*/
|
||||
public void addEntry(CatalogEntry entry) {
|
||||
int type = entry.getEntryType();
|
||||
|
||||
if (type == URISUFFIX) {
|
||||
String suffix = normalizeURI(entry.getEntryArg(0));
|
||||
String fsi = makeAbsolute(normalizeURI(entry.getEntryArg(1)));
|
||||
|
||||
entry.setEntryArg(1, fsi);
|
||||
|
||||
Debug.message(4, "URISUFFIX", suffix, fsi);
|
||||
} else if (type == SYSTEMSUFFIX) {
|
||||
String suffix = normalizeURI(entry.getEntryArg(0));
|
||||
String fsi = makeAbsolute(normalizeURI(entry.getEntryArg(1)));
|
||||
|
||||
entry.setEntryArg(1, fsi);
|
||||
|
||||
Debug.message(4, "SYSTEMSUFFIX", suffix, fsi);
|
||||
}
|
||||
|
||||
super.addEntry(entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Return the applicable URI</p>
|
||||
*
|
||||
* <p>If a URI entry exists in the Catalog
|
||||
* for the URI specified, return the mapped value.</p>
|
||||
*
|
||||
* <p>In the Resolver (as opposed to the Catalog) class, if the
|
||||
* URI isn't found by the usual algorithm, URISUFFIX entries are
|
||||
* considered.</p>
|
||||
*
|
||||
* <p>URI comparison is case sensitive.</p>
|
||||
*
|
||||
* @param uri The URI to locate in the catalog.
|
||||
*
|
||||
* @return The resolved URI.
|
||||
*
|
||||
* @throws MalformedURLException The system identifier of a
|
||||
* subordinate catalog cannot be turned into a valid URL.
|
||||
* @throws IOException Error reading subordinate catalog file.
|
||||
*/
|
||||
public String resolveURI(String uri)
|
||||
throws MalformedURLException, IOException {
|
||||
|
||||
String resolved = super.resolveURI(uri);
|
||||
if (resolved != null) {
|
||||
return resolved;
|
||||
}
|
||||
|
||||
Enumeration enum = catalogEntries.elements();
|
||||
while (enum.hasMoreElements()) {
|
||||
CatalogEntry e = (CatalogEntry) enum.nextElement();
|
||||
if (e.getEntryType() == RESOLVER) {
|
||||
resolved = resolveExternalSystem(uri, e.getEntryArg(0));
|
||||
if (resolved != null) {
|
||||
return resolved;
|
||||
}
|
||||
} else if (e.getEntryType() == URISUFFIX) {
|
||||
String suffix = e.getEntryArg(0);
|
||||
String result = e.getEntryArg(1);
|
||||
|
||||
if (suffix.length() <= uri.length()
|
||||
&& uri.substring(uri.length()-suffix.length()).equals(suffix)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, look in the subordinate catalogs
|
||||
return resolveSubordinateCatalogs(Catalog.URI,
|
||||
null,
|
||||
null,
|
||||
uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Return the applicable SYSTEM system identifier, resorting
|
||||
* to external RESOLVERs if necessary.</p>
|
||||
*
|
||||
* <p>If a SYSTEM entry exists in the Catalog
|
||||
* for the system ID specified, return the mapped value.</p>
|
||||
*
|
||||
* <p>In the Resolver (as opposed to the Catalog) class, if the
|
||||
* URI isn't found by the usual algorithm, SYSTEMSUFFIX entries are
|
||||
* considered.</p>
|
||||
*
|
||||
* <p>On Windows-based operating systems, the comparison between
|
||||
* the system identifier provided and the SYSTEM entries in the
|
||||
* Catalog is case-insensitive.</p>
|
||||
*
|
||||
* @param systemId The system ID to locate in the catalog.
|
||||
*
|
||||
* @return The system identifier to use for systemId.
|
||||
*
|
||||
* @throws MalformedURLException The formal system identifier of a
|
||||
* subordinate catalog cannot be turned into a valid URL.
|
||||
* @throws IOException Error reading subordinate catalog file.
|
||||
*/
|
||||
public String resolveSystem(String systemId)
|
||||
throws MalformedURLException, IOException {
|
||||
|
||||
String resolved = super.resolveSystem(systemId);
|
||||
if (resolved != null) {
|
||||
return resolved;
|
||||
}
|
||||
|
||||
Enumeration enum = catalogEntries.elements();
|
||||
while (enum.hasMoreElements()) {
|
||||
CatalogEntry e = (CatalogEntry) enum.nextElement();
|
||||
if (e.getEntryType() == RESOLVER) {
|
||||
resolved = resolveExternalSystem(systemId, e.getEntryArg(0));
|
||||
if (resolved != null) {
|
||||
return resolved;
|
||||
}
|
||||
} else if (e.getEntryType() == SYSTEMSUFFIX) {
|
||||
String suffix = e.getEntryArg(0);
|
||||
String result = e.getEntryArg(1);
|
||||
|
||||
if (suffix.length() <= systemId.length()
|
||||
&& systemId.substring(systemId.length()-suffix.length()).equals(suffix)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return resolveSubordinateCatalogs(Catalog.SYSTEM,
|
||||
null,
|
||||
null,
|
||||
systemId);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Return the applicable PUBLIC or SYSTEM identifier, resorting
|
||||
* to external resolvers if necessary.</p>
|
||||
*
|
||||
* <p>This method searches the Catalog and returns the system
|
||||
* identifier specified for the given system or
|
||||
* public identifiers. If
|
||||
* no appropriate PUBLIC or SYSTEM entry is found in the Catalog,
|
||||
* null is returned.</p>
|
||||
*
|
||||
* <p>Note that a system or public identifier in the current catalog
|
||||
* (or subordinate catalogs) will be used in preference to an
|
||||
* external resolver. Further, if a systemId is present, the external
|
||||
* resolver(s) will be queried for that before the publicId.</p>
|
||||
*
|
||||
* @param publicId The public identifier to locate in the catalog.
|
||||
* Public identifiers are normalized before comparison.
|
||||
* @param systemId The nominal system identifier for the entity
|
||||
* in question (as provided in the source document).
|
||||
*
|
||||
* @throws MalformedURLException The formal system identifier of a
|
||||
* subordinate catalog cannot be turned into a valid URL.
|
||||
* @throws IOException Error reading subordinate catalog file.
|
||||
*
|
||||
* @return The system identifier to use.
|
||||
* Note that the nominal system identifier is not returned if a
|
||||
* match is not found in the catalog, instead null is returned
|
||||
* to indicate that no match was found.
|
||||
*/
|
||||
public String resolvePublic(String publicId, String systemId)
|
||||
throws MalformedURLException, IOException {
|
||||
|
||||
String resolved = super.resolvePublic(publicId, systemId);
|
||||
if (resolved != null) {
|
||||
return resolved;
|
||||
}
|
||||
|
||||
Enumeration enum = catalogEntries.elements();
|
||||
while (enum.hasMoreElements()) {
|
||||
CatalogEntry e = (CatalogEntry) enum.nextElement();
|
||||
if (e.getEntryType() == RESOLVER) {
|
||||
if (systemId != null) {
|
||||
resolved = resolveExternalSystem(systemId,
|
||||
e.getEntryArg(0));
|
||||
if (resolved != null) {
|
||||
return resolved;
|
||||
}
|
||||
}
|
||||
resolved = resolveExternalPublic(publicId, e.getEntryArg(0));
|
||||
if (resolved != null) {
|
||||
return resolved;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return resolveSubordinateCatalogs(Catalog.PUBLIC,
|
||||
null,
|
||||
publicId,
|
||||
systemId);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Query an external RFC2483 resolver for a system identifier.</p>
|
||||
*
|
||||
* @param systemId The system ID to locate.
|
||||
* @param resolver The name of the resolver to use.
|
||||
*
|
||||
* @return The system identifier to use for the systemId.
|
||||
*/
|
||||
protected String resolveExternalSystem(String systemId, String resolver)
|
||||
throws MalformedURLException, IOException {
|
||||
Resolver r = queryResolver(resolver, "i2l", systemId, null);
|
||||
if (r != null) {
|
||||
return r.resolveSystem(systemId);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Query an external RFC2483 resolver for a public identifier.</p>
|
||||
*
|
||||
* @param publicId The system ID to locate.
|
||||
* @param resolver The name of the resolver to use.
|
||||
*
|
||||
* @return The system identifier to use for the systemId.
|
||||
*/
|
||||
protected String resolveExternalPublic(String publicId, String resolver)
|
||||
throws MalformedURLException, IOException {
|
||||
Resolver r = queryResolver(resolver, "fpi2l", publicId, null);
|
||||
if (r != null) {
|
||||
return r.resolvePublic(publicId, null);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Query an external RFC2483 resolver.</p>
|
||||
*
|
||||
* @param resolver The URL of the RFC2483 resolver.
|
||||
* @param command The command to send the resolver.
|
||||
* @param arg1 The first argument to the resolver.
|
||||
* @param arg2 The second argument to the resolver, usually null.
|
||||
*
|
||||
* @return The Resolver constructed.
|
||||
*/
|
||||
protected Resolver queryResolver(String resolver,
|
||||
String command,
|
||||
String arg1,
|
||||
String arg2) {
|
||||
InputStream iStream = null;
|
||||
String RFC2483 = resolver + "?command=" + command
|
||||
+ "&format=tr9401&uri=" + arg1
|
||||
+ "&uri2=" + arg2;
|
||||
String line = null;
|
||||
|
||||
try {
|
||||
URL url = new URL(RFC2483);
|
||||
|
||||
URLConnection urlCon = url.openConnection();
|
||||
|
||||
urlCon.setUseCaches(false);
|
||||
|
||||
Resolver r = (Resolver) newCatalog();
|
||||
|
||||
String cType = urlCon.getContentType();
|
||||
|
||||
// I don't care about the character set or subtype
|
||||
if (cType.indexOf(";") > 0) {
|
||||
cType = cType.substring(0, cType.indexOf(";"));
|
||||
}
|
||||
|
||||
r.parseCatalog(cType, urlCon.getInputStream());
|
||||
|
||||
return r;
|
||||
} catch (CatalogException cex) {
|
||||
if (cex.getExceptionType() == CatalogException.UNPARSEABLE) {
|
||||
Debug.message(1, "Unparseable catalog: " + RFC2483);
|
||||
} else if (cex.getExceptionType()
|
||||
== CatalogException.UNKNOWN_FORMAT) {
|
||||
Debug.message(1, "Unknown catalog format: " + RFC2483);
|
||||
}
|
||||
return null;
|
||||
} catch (MalformedURLException mue) {
|
||||
Debug.message(1, "Malformed resolver URL: " + RFC2483);
|
||||
return null;
|
||||
} catch (IOException ie) {
|
||||
Debug.message(1, "I/O Exception opening resolver: " + RFC2483);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Append two vectors, returning the result.</p>
|
||||
*
|
||||
* @param vec The first vector
|
||||
* @param appvec The vector to be appended
|
||||
* @return The vector vec, with appvec's elements appended to it
|
||||
*/
|
||||
private Vector appendVector(Vector vec, Vector appvec) {
|
||||
if (appvec != null) {
|
||||
for (int count = 0; count < appvec.size(); count++) {
|
||||
vec.addElement(appvec.elementAt(count));
|
||||
}
|
||||
}
|
||||
return vec;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Find the URNs for a given system identifier in all catalogs.</p>
|
||||
*
|
||||
* @param systemId The system ID to locate.
|
||||
*
|
||||
* @return A vector of URNs that map to the systemId.
|
||||
*/
|
||||
public Vector resolveAllSystemReverse(String systemId)
|
||||
throws MalformedURLException, IOException {
|
||||
Vector resolved = new Vector();
|
||||
|
||||
// If there's a SYSTEM entry in this catalog, use it
|
||||
if (systemId != null) {
|
||||
Vector localResolved = resolveLocalSystemReverse(systemId);
|
||||
resolved = appendVector(resolved, localResolved);
|
||||
}
|
||||
|
||||
// Otherwise, look in the subordinate catalogs
|
||||
Vector subResolved = resolveAllSubordinateCatalogs(SYSTEMREVERSE,
|
||||
null,
|
||||
null,
|
||||
systemId);
|
||||
|
||||
return appendVector(resolved, subResolved);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Find the URN for a given system identifier.</p>
|
||||
*
|
||||
* @param systemId The system ID to locate.
|
||||
*
|
||||
* @return A (single) URN that maps to the systemId.
|
||||
*/
|
||||
public String resolveSystemReverse(String systemId)
|
||||
throws MalformedURLException, IOException {
|
||||
Vector resolved = resolveAllSystemReverse(systemId);
|
||||
if (resolved != null && resolved.size() > 0) {
|
||||
return (String) resolved.elementAt(0);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Return the applicable SYSTEM system identifiers</p>
|
||||
*
|
||||
* <p>If one or more SYSTEM entries exists in the Catalog
|
||||
* for the system ID specified, return the mapped values.</p>
|
||||
*
|
||||
* <p>The caller is responsible for doing any necessary
|
||||
* normalization of the system identifier before calling
|
||||
* this method. For example, a relative system identifier in
|
||||
* a document might be converted to an absolute system identifier
|
||||
* before attempting to resolve it.</p>
|
||||
*
|
||||
* <p>Note that this function will force all subordinate catalogs
|
||||
* to be loaded.</p>
|
||||
*
|
||||
* <p>On Windows-based operating systems, the comparison between
|
||||
* the system identifier provided and the SYSTEM entries in the
|
||||
* Catalog is case-insensitive.</p>
|
||||
*
|
||||
* @param systemId The system ID to locate in the catalog.
|
||||
*
|
||||
* @return The system identifier to use for the notation.
|
||||
*
|
||||
* @throws MalformedURLException The formal system identifier of a
|
||||
* subordinate catalog cannot be turned into a valid URL.
|
||||
* @throws IOException Error reading subordinate catalog file.
|
||||
*/
|
||||
public Vector resolveAllSystem(String systemId)
|
||||
throws MalformedURLException, IOException {
|
||||
Vector resolutions = new Vector();
|
||||
|
||||
// If there are SYSTEM entries in this catalog, start with them
|
||||
if (systemId != null) {
|
||||
Vector localResolutions = resolveAllLocalSystem(systemId);
|
||||
resolutions = appendVector(resolutions, localResolutions);
|
||||
}
|
||||
|
||||
// Then look in the subordinate catalogs
|
||||
Vector subResolutions = resolveAllSubordinateCatalogs(SYSTEM,
|
||||
null,
|
||||
null,
|
||||
systemId);
|
||||
resolutions = appendVector(resolutions, subResolutions);
|
||||
|
||||
if (resolutions.size() > 0) {
|
||||
return resolutions;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Return all applicable SYSTEM system identifiers in this
|
||||
* catalog.</p>
|
||||
*
|
||||
* <p>If one or more SYSTEM entries exists in the catalog file
|
||||
* for the system ID specified, return the mapped values.</p>
|
||||
*
|
||||
* @param systemId The system ID to locate in the catalog
|
||||
*
|
||||
* @return A vector of the mapped system identifiers or null
|
||||
*/
|
||||
private Vector resolveAllLocalSystem(String systemId) {
|
||||
Vector map = new Vector();
|
||||
String osname = System.getProperty("os.name");
|
||||
boolean windows = (osname.indexOf("Windows") >= 0);
|
||||
Enumeration enum = catalogEntries.elements();
|
||||
while (enum.hasMoreElements()) {
|
||||
CatalogEntry e = (CatalogEntry) enum.nextElement();
|
||||
if (e.getEntryType() == SYSTEM
|
||||
&& (e.getEntryArg(0).equals(systemId)
|
||||
|| (windows
|
||||
&& e.getEntryArg(0).equalsIgnoreCase(systemId)))) {
|
||||
map.addElement(e.getEntryArg(1));
|
||||
}
|
||||
}
|
||||
if (map.size() == 0) {
|
||||
return null;
|
||||
} else {
|
||||
return map;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Find the URNs for a given system identifier in the current catalog.</p>
|
||||
*
|
||||
* @param systemId The system ID to locate.
|
||||
*
|
||||
* @return A vector of URNs that map to the systemId.
|
||||
*/
|
||||
private Vector resolveLocalSystemReverse(String systemId) {
|
||||
Vector map = new Vector();
|
||||
String osname = System.getProperty("os.name");
|
||||
boolean windows = (osname.indexOf("Windows") >= 0);
|
||||
Enumeration enum = catalogEntries.elements();
|
||||
while (enum.hasMoreElements()) {
|
||||
CatalogEntry e = (CatalogEntry) enum.nextElement();
|
||||
if (e.getEntryType() == SYSTEM
|
||||
&& (e.getEntryArg(1).equals(systemId)
|
||||
|| (windows
|
||||
&& e.getEntryArg(1).equalsIgnoreCase(systemId)))) {
|
||||
map.addElement(e.getEntryArg(0));
|
||||
}
|
||||
}
|
||||
if (map.size() == 0) {
|
||||
return null;
|
||||
} else {
|
||||
return map;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Search the subordinate catalogs, in order, looking for all
|
||||
* match.</p>
|
||||
*
|
||||
* <p>This method searches the Catalog and returns all of the system
|
||||
* identifiers specified for the given entity type with the given
|
||||
* name, public, and system identifiers. In some contexts, these
|
||||
* may be null.</p>
|
||||
*
|
||||
* @param entityType The CatalogEntry type for which this query is
|
||||
* being conducted. This is necessary in order to do the approprate
|
||||
* query on a subordinate catalog.
|
||||
* @param entityName The name of the entity being searched for, if
|
||||
* appropriate.
|
||||
* @param publicId The public identifier of the entity in question
|
||||
* (as provided in the source document).
|
||||
* @param systemId The nominal system identifier for the entity
|
||||
* in question (as provided in the source document).
|
||||
*
|
||||
* @throws MalformedURLException The formal system identifier of a
|
||||
* delegated catalog cannot be turned into a valid URL.
|
||||
* @throws IOException Error reading delegated catalog file.
|
||||
*
|
||||
* @return The system identifier to use.
|
||||
* Note that the nominal system identifier is not returned if a
|
||||
* match is not found in the catalog, instead null is returned
|
||||
* to indicate that no match was found.
|
||||
*/
|
||||
private synchronized Vector resolveAllSubordinateCatalogs(int entityType,
|
||||
String entityName,
|
||||
String publicId,
|
||||
String systemId)
|
||||
throws MalformedURLException, IOException {
|
||||
|
||||
Vector resolutions = new Vector();
|
||||
|
||||
for (int catPos = 0; catPos < catalogs.size(); catPos++) {
|
||||
Resolver c = null;
|
||||
|
||||
try {
|
||||
c = (Resolver) catalogs.elementAt(catPos);
|
||||
} catch (ClassCastException e) {
|
||||
String catfile = (String) catalogs.elementAt(catPos);
|
||||
c = (Resolver) newCatalog();
|
||||
|
||||
try {
|
||||
c.parseCatalog(catfile);
|
||||
} catch (MalformedURLException mue) {
|
||||
Debug.message(1, "Malformed Catalog URL", catfile);
|
||||
} catch (FileNotFoundException fnfe) {
|
||||
Debug.message(1, "Failed to load catalog, file not found",
|
||||
catfile);
|
||||
} catch (IOException ioe) {
|
||||
Debug.message(1, "Failed to load catalog, I/O error", catfile);
|
||||
}
|
||||
|
||||
catalogs.setElementAt(c, catPos);
|
||||
}
|
||||
|
||||
String resolved = null;
|
||||
|
||||
// Ok, now what are we supposed to call here?
|
||||
if (entityType == DOCTYPE) {
|
||||
resolved = c.resolveDoctype(entityName,
|
||||
publicId,
|
||||
systemId);
|
||||
if (resolved != null) {
|
||||
// Only find one DOCTYPE resolution
|
||||
resolutions.addElement(resolved);
|
||||
return resolutions;
|
||||
}
|
||||
} else if (entityType == DOCUMENT) {
|
||||
resolved = c.resolveDocument();
|
||||
if (resolved != null) {
|
||||
// Only find one DOCUMENT resolution
|
||||
resolutions.addElement(resolved);
|
||||
return resolutions;
|
||||
}
|
||||
} else if (entityType == ENTITY) {
|
||||
resolved = c.resolveEntity(entityName,
|
||||
publicId,
|
||||
systemId);
|
||||
if (resolved != null) {
|
||||
// Only find one ENTITY resolution
|
||||
resolutions.addElement(resolved);
|
||||
return resolutions;
|
||||
}
|
||||
} else if (entityType == NOTATION) {
|
||||
resolved = c.resolveNotation(entityName,
|
||||
publicId,
|
||||
systemId);
|
||||
if (resolved != null) {
|
||||
// Only find one NOTATION resolution
|
||||
resolutions.addElement(resolved);
|
||||
return resolutions;
|
||||
}
|
||||
} else if (entityType == PUBLIC) {
|
||||
resolved = c.resolvePublic(publicId, systemId);
|
||||
if (resolved != null) {
|
||||
// Only find one PUBLIC resolution
|
||||
resolutions.addElement(resolved);
|
||||
return resolutions;
|
||||
}
|
||||
} else if (entityType == SYSTEM) {
|
||||
Vector localResolutions = c.resolveAllSystem(systemId);
|
||||
resolutions = appendVector(resolutions, localResolutions);
|
||||
break;
|
||||
} else if (entityType == SYSTEMREVERSE) {
|
||||
Vector localResolutions = c.resolveAllSystemReverse(systemId);
|
||||
resolutions = appendVector(resolutions, localResolutions);
|
||||
}
|
||||
}
|
||||
|
||||
if (resolutions != null) {
|
||||
return resolutions;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,200 @@
|
||||
// XParseError.java - An error handler for xparse
|
||||
|
||||
/*
|
||||
* The Apache Software License, Version 1.1
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2001 The Apache Software Foundation. All rights
|
||||
* reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The end-user documentation included with the redistribution,
|
||||
* if any, must include the following acknowledgment:
|
||||
* "This product includes software developed by the
|
||||
* Apache Software Foundation (http://www.apache.org/)."
|
||||
* Alternately, this acknowledgment may appear in the software itself,
|
||||
* if and wherever such third-party acknowledgments normally appear.
|
||||
*
|
||||
* 4. The names "Xalan" and "Apache Software Foundation" must
|
||||
* not be used to endorse or promote products derived from this
|
||||
* software without prior written permission. For written
|
||||
* permission, please contact apache@apache.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "Apache",
|
||||
* nor may "Apache" appear in their name, without prior written
|
||||
* permission of the Apache Software Foundation.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation and was
|
||||
* originally based on software copyright (c) 2001, International
|
||||
* Business Machines Corporation., http://www.ibm.com. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*/
|
||||
|
||||
package org.apache.xml.resolver.apps;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.net.MalformedURLException;
|
||||
|
||||
import org.xml.sax.*;
|
||||
import org.xml.sax.helpers.*;
|
||||
|
||||
/**
|
||||
* <p>An ErrorHandler for xparse.</p>
|
||||
*
|
||||
* <p>This class is just the error handler for xparse.</p>
|
||||
*
|
||||
* @see xparse
|
||||
*
|
||||
* @author Norman Walsh
|
||||
* <a href="mailto:Norman.Walsh@Sun.COM">Norman.Walsh@Sun.COM</a>
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
public class XParseError implements ErrorHandler {
|
||||
/** Show errors? */
|
||||
private boolean showErrors = true;
|
||||
|
||||
/** Show warnings? */
|
||||
private boolean showWarnings = false;
|
||||
|
||||
/** How many messages should be presented? */
|
||||
private int maxMessages = 10;
|
||||
|
||||
/** The number of fatal errors seen so far. */
|
||||
private int fatalCount = 0;
|
||||
|
||||
/** The number of errors seen so far. */
|
||||
private int errorCount = 0;
|
||||
|
||||
/** The number of warnings seen so far. */
|
||||
private int warningCount = 0;
|
||||
|
||||
/** The base URI of the running application. */
|
||||
private String baseURI = "";
|
||||
|
||||
/** Constructor */
|
||||
public XParseError(boolean errors, boolean warnings) {
|
||||
showErrors = errors;
|
||||
showWarnings = warnings;
|
||||
|
||||
String dir = System.getProperty("user.dir");
|
||||
String file = "";
|
||||
|
||||
if (dir.endsWith("/")) {
|
||||
file = "file:" + dir + "file";
|
||||
} else {
|
||||
file = "file:" + dir + "/" + file;
|
||||
}
|
||||
|
||||
try {
|
||||
URL url = new URL(file);
|
||||
baseURI = url.toString();
|
||||
} catch (MalformedURLException mue) {
|
||||
// nop;
|
||||
}
|
||||
}
|
||||
|
||||
/** Return the error count */
|
||||
public int getErrorCount() {
|
||||
return errorCount;
|
||||
}
|
||||
|
||||
/** Return the fatal error count */
|
||||
public int getFatalCount() {
|
||||
return fatalCount;
|
||||
}
|
||||
|
||||
/** Return the warning count */
|
||||
public int getWarningCount() {
|
||||
return warningCount;
|
||||
}
|
||||
|
||||
/** Return the number of messages to display */
|
||||
public int getMaxMessages() {
|
||||
return maxMessages;
|
||||
}
|
||||
|
||||
/** Set the number of messages to display */
|
||||
public void setMaxMessages(int max) {
|
||||
maxMessages = max;
|
||||
}
|
||||
|
||||
/** SAX2 API */
|
||||
public void error(SAXParseException exception) {
|
||||
if (showErrors) {
|
||||
if (errorCount+warningCount < maxMessages) {
|
||||
message("Error", exception);
|
||||
}
|
||||
errorCount++;
|
||||
}
|
||||
}
|
||||
|
||||
/** SAX2 API */
|
||||
public void fatalError(SAXParseException exception) {
|
||||
if (showErrors) {
|
||||
if (errorCount+warningCount < maxMessages) {
|
||||
message("Fatal error", exception);
|
||||
}
|
||||
errorCount++;
|
||||
fatalCount++;
|
||||
}
|
||||
}
|
||||
|
||||
/** SAX2 API */
|
||||
public void warning(SAXParseException exception) {
|
||||
if (showWarnings) {
|
||||
if ((errorCount+warningCount < maxMessages)) {
|
||||
message("Warning", exception);
|
||||
}
|
||||
warningCount++;
|
||||
}
|
||||
}
|
||||
|
||||
/** Display a message to the user */
|
||||
private void message(String type, SAXParseException exception) {
|
||||
String filename = exception.getSystemId();
|
||||
if (filename.startsWith(baseURI)) {
|
||||
filename = filename.substring(baseURI.length());
|
||||
}
|
||||
|
||||
System.out.print(type
|
||||
+ ":"
|
||||
+ filename
|
||||
+ ":"
|
||||
+ exception.getLineNumber());
|
||||
|
||||
if (exception.getColumnNumber() > 0) {
|
||||
System.out.print(":" + exception.getColumnNumber());
|
||||
}
|
||||
|
||||
System.out.println(":" + exception.getMessage());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Apache XML Commons Resolver Applications package</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>Apache XML Commons Resolver Applications package</p>
|
||||
|
||||
<p>This package provides a few simple command-line tools for exploring
|
||||
the facilities of the resolver.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,338 @@
|
||||
// resolver.java - A simple command-line test tool for the resolver
|
||||
|
||||
/*
|
||||
* The Apache Software License, Version 1.1
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2001 The Apache Software Foundation. All rights
|
||||
* reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The end-user documentation included with the redistribution,
|
||||
* if any, must include the following acknowledgment:
|
||||
* "This product includes software developed by the
|
||||
* Apache Software Foundation (http://www.apache.org/)."
|
||||
* Alternately, this acknowledgment may appear in the software itself,
|
||||
* if and wherever such third-party acknowledgments normally appear.
|
||||
*
|
||||
* 4. The names "Xalan" and "Apache Software Foundation" must
|
||||
* not be used to endorse or promote products derived from this
|
||||
* software without prior written permission. For written
|
||||
* permission, please contact apache@apache.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "Apache",
|
||||
* nor may "Apache" appear in their name, without prior written
|
||||
* permission of the Apache Software Foundation.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation and was
|
||||
* originally based on software copyright (c) 2001, International
|
||||
* Business Machines Corporation., http://www.ibm.com. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*/
|
||||
|
||||
package org.apache.xml.resolver.apps;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.Vector;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
import org.xml.sax.*;
|
||||
import org.xml.sax.helpers.*;
|
||||
|
||||
import javax.xml.parsers.*;
|
||||
import javax.xml.transform.*;
|
||||
import javax.xml.transform.sax.SAXSource;
|
||||
|
||||
import org.apache.xml.resolver.Catalog;
|
||||
import org.apache.xml.resolver.tools.CatalogResolver;
|
||||
import org.apache.xml.resolver.helpers.Debug;
|
||||
import org.apache.xml.resolver.tools.CatalogResolver;
|
||||
|
||||
/**
|
||||
* <p>A simple command-line resolver.</p>
|
||||
*
|
||||
* <p>This class implements a simple command-line resolver. It takes
|
||||
* some parameters and passes them through the resolver, printing the
|
||||
* result.
|
||||
* </p>
|
||||
*
|
||||
* <p>Usage: resolver [options] keyword</p>
|
||||
*
|
||||
* <p>Where options are:</p>
|
||||
*
|
||||
* <dl>
|
||||
* <dt><code>-c</code> <em>catalogfile</em></dt>
|
||||
* <dd>Load a particular catalog file.</dd>
|
||||
* <dt><code>-n</code> <em>name</em></dt>
|
||||
* <dd>Sets the name.</dd>
|
||||
* <dt><code>-p</code> <em>publicId</em></dt>
|
||||
* <dd>Sets the public identifier.</dd>
|
||||
* <dt><code>-s</code> <em>systemId</em></dt>
|
||||
* <dd>Sets the system identifier.</dd>
|
||||
* <dt><code>-a</code></dt>
|
||||
* <dd>Absolute system URI.</dd>
|
||||
* <dt><code>-u</code> <em>uri</em></dt>
|
||||
* <dd>Sets the URI.</dd>
|
||||
* <dt><code>-d</code> <em>integer</em></dt>
|
||||
* <dd>Set the debug level.</dd>
|
||||
* </dl>
|
||||
*
|
||||
* <p>And keyword is one of: doctype, document, entity, notation, public,
|
||||
* system, or uri.</p>
|
||||
*
|
||||
* <p>The process ends with error-level 1, if there errors.</p>
|
||||
*
|
||||
* @see org.apache.xml.resolver.tools.ResolvingParser
|
||||
*
|
||||
* @author Norman Walsh
|
||||
* <a href="mailto:Norman.Walsh@Sun.COM">Norman.Walsh@Sun.COM</a>
|
||||
*
|
||||
* @version 1.0 */
|
||||
public class resolver {
|
||||
/** The main entry point */
|
||||
public static void main (String[] args)
|
||||
throws FileNotFoundException, IOException {
|
||||
|
||||
int debug = 0;
|
||||
Vector catalogFiles = new Vector();
|
||||
int resType = 0;
|
||||
String resTypeStr = null;
|
||||
String name = null;
|
||||
String publicId = null;
|
||||
String systemId = null;
|
||||
String uri = null;
|
||||
boolean absoluteSystem = false;
|
||||
|
||||
for (int i=0; i<args.length; i++) {
|
||||
if (args[i].equals("-c")) {
|
||||
++i;
|
||||
catalogFiles.add(args[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (args[i].equals("-p")) {
|
||||
++i;
|
||||
publicId = args[i];
|
||||
continue;
|
||||
}
|
||||
|
||||
if (args[i].equals("-s")) {
|
||||
++i;
|
||||
systemId = args[i];
|
||||
continue;
|
||||
}
|
||||
|
||||
if (args[i].equals("-n")) {
|
||||
++i;
|
||||
name = args[i];
|
||||
continue;
|
||||
}
|
||||
|
||||
if (args[i].equals("-u")) {
|
||||
++i;
|
||||
uri = args[i];
|
||||
continue;
|
||||
}
|
||||
|
||||
if (args[i].equals("-a")) {
|
||||
absoluteSystem = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (args[i].equals("-d")) {
|
||||
++i;
|
||||
String debugstr = args[i];
|
||||
try {
|
||||
debug = Integer.parseInt(debugstr);
|
||||
if (debug >= 0) {
|
||||
Debug.setDebug(debug);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// nop
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
resTypeStr = args[i];
|
||||
}
|
||||
|
||||
if (resTypeStr == null) {
|
||||
usage();
|
||||
}
|
||||
|
||||
if (resTypeStr.equalsIgnoreCase("doctype")) {
|
||||
resType = Catalog.DOCTYPE;
|
||||
if (publicId == null && systemId == null) {
|
||||
System.out.println("DOCTYPE requires public or system identifier.");
|
||||
usage();
|
||||
}
|
||||
} else if (resTypeStr.equalsIgnoreCase("document")) {
|
||||
resType = Catalog.DOCUMENT;
|
||||
} else if (resTypeStr.equalsIgnoreCase("entity")) {
|
||||
resType = Catalog.ENTITY;
|
||||
if (publicId == null && systemId == null && name == null) {
|
||||
System.out.println("ENTITY requires name or public or system identifier.");
|
||||
usage();
|
||||
}
|
||||
} else if (resTypeStr.equalsIgnoreCase("notation")) {
|
||||
resType = Catalog.NOTATION;
|
||||
if (publicId == null && systemId == null && name == null) {
|
||||
System.out.println("NOTATION requires name or public or system identifier.");
|
||||
usage();
|
||||
}
|
||||
} else if (resTypeStr.equalsIgnoreCase("public")) {
|
||||
resType = Catalog.PUBLIC;
|
||||
if (publicId == null) {
|
||||
System.out.println("PUBLIC requires public identifier.");
|
||||
usage();
|
||||
}
|
||||
} else if (resTypeStr.equalsIgnoreCase("system")) {
|
||||
resType = Catalog.SYSTEM;
|
||||
if (systemId == null) {
|
||||
System.out.println("SYSTEM requires system identifier.");
|
||||
usage();
|
||||
}
|
||||
} else if (resTypeStr.equalsIgnoreCase("uri")) {
|
||||
resType = Catalog.URI;
|
||||
if (uri == null) {
|
||||
System.out.println("URI requires a uri.");
|
||||
usage();
|
||||
}
|
||||
} else {
|
||||
System.out.println(resTypeStr + " is not a recognized keyword.");
|
||||
usage();
|
||||
}
|
||||
|
||||
if (absoluteSystem) {
|
||||
URL base = null;
|
||||
URL sysid = null;
|
||||
|
||||
// Calculate the appropriate BASE URI
|
||||
try {
|
||||
// tack on a basename because URLs point to files not dirs
|
||||
String userdir = System.getProperty("user.dir");
|
||||
userdir.replace('\\', '/');
|
||||
base = new URL("file:///" + userdir + "/basename");
|
||||
} catch (MalformedURLException e) {
|
||||
String userdir = System.getProperty("user.dir");
|
||||
userdir.replace('\\', '/');
|
||||
Debug.message(1, "Malformed URL on cwd", userdir);
|
||||
base = null;
|
||||
}
|
||||
|
||||
try {
|
||||
sysid = new URL(base, systemId);
|
||||
systemId = sysid.toString();
|
||||
} catch (MalformedURLException e) {
|
||||
try {
|
||||
sysid = new URL("file:///" + systemId);
|
||||
} catch (MalformedURLException e2) {
|
||||
Debug.message(1, "Malformed URL on system id", systemId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CatalogResolver catalogResolver = new CatalogResolver();
|
||||
Catalog resolver = catalogResolver.getCatalog();
|
||||
|
||||
for (int count = 0; count < catalogFiles.size(); count++) {
|
||||
String file = (String) catalogFiles.elementAt(count);
|
||||
resolver.parseCatalog(file);
|
||||
}
|
||||
String result = null;
|
||||
|
||||
if (resType == Catalog.DOCTYPE) {
|
||||
System.out.println("Resolve DOCTYPE (name, publicid, systemid):");
|
||||
if (name != null) { System.out.println(" name: " + name); }
|
||||
if (publicId != null) { System.out.println(" public id: " + publicId); }
|
||||
if (systemId != null) { System.out.println(" system id: " + systemId); }
|
||||
if (uri != null) { System.out.println(" uri: " + uri); }
|
||||
result = resolver.resolveDoctype(name, publicId, systemId);
|
||||
} else if (resType == Catalog.DOCUMENT) {
|
||||
System.out.println("Resolve DOCUMENT ():");
|
||||
result = resolver.resolveDocument();
|
||||
} else if (resType == Catalog.ENTITY) {
|
||||
System.out.println("Resolve ENTITY (name, publicid, systemid):");
|
||||
if (name != null) { System.out.println(" name: " + name); }
|
||||
if (publicId != null) { System.out.println(" public id: " + publicId); }
|
||||
if (systemId != null) { System.out.println(" system id: " + systemId); }
|
||||
result = resolver.resolveEntity(name, publicId, systemId);
|
||||
} else if (resType == Catalog.NOTATION) {
|
||||
System.out.println("Resolve NOTATION (name, publicid, systemid):");
|
||||
if (name != null) { System.out.println(" name: " + name); }
|
||||
if (publicId != null) { System.out.println(" public id: " + publicId); }
|
||||
if (systemId != null) { System.out.println(" system id: " + systemId); }
|
||||
result = resolver.resolveNotation(name, publicId, systemId);
|
||||
} else if (resType == Catalog.PUBLIC) {
|
||||
System.out.println("Resolve PUBLIC (publicid, systemid):");
|
||||
if (publicId != null) { System.out.println(" public id: " + publicId); }
|
||||
if (systemId != null) { System.out.println(" system id: " + systemId); }
|
||||
result = resolver.resolvePublic(publicId, systemId);
|
||||
} else if (resType == Catalog.SYSTEM) {
|
||||
System.out.println("Resolve SYSTEM (systemid):");
|
||||
if (systemId != null) { System.out.println(" system id: " + systemId); }
|
||||
result = resolver.resolveSystem(systemId);
|
||||
} else if (resType == Catalog.URI) {
|
||||
System.out.println("Resolve URI (uri):");
|
||||
if (uri != null) { System.out.println(" uri: " + uri); }
|
||||
result = resolver.resolveURI(uri);
|
||||
} else {
|
||||
System.out.println("resType is wrong!? This can't happen!");
|
||||
usage();
|
||||
}
|
||||
|
||||
System.out.println("Result: " + result);
|
||||
}
|
||||
|
||||
public static void usage() {
|
||||
System.out.println("Usage: resolver [options] keyword");
|
||||
System.out.println("");
|
||||
System.out.println("Where:");
|
||||
System.out.println("");
|
||||
System.out.println("-c catalogfile Loads a particular catalog file.");
|
||||
System.out.println("-n name Sets the name.");
|
||||
System.out.println("-p publicId Sets the public identifier.");
|
||||
System.out.println("-s systemId Sets the system identifier.");
|
||||
System.out.println("-a Makes the system URI absolute before resolution");
|
||||
System.out.println("-u uri Sets the URI.");
|
||||
System.out.println("-d integer Set the debug level.");
|
||||
System.out.println("keyword Identifies the type of resolution to perform:");
|
||||
System.out.println(" doctype, document, entity, notation, public, system,");
|
||||
System.out.println(" or uri.");
|
||||
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,300 @@
|
||||
// xparse.java - A simple command-line XML parser
|
||||
|
||||
/*
|
||||
* The Apache Software License, Version 1.1
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2001 The Apache Software Foundation. All rights
|
||||
* reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The end-user documentation included with the redistribution,
|
||||
* if any, must include the following acknowledgment:
|
||||
* "This product includes software developed by the
|
||||
* Apache Software Foundation (http://www.apache.org/)."
|
||||
* Alternately, this acknowledgment may appear in the software itself,
|
||||
* if and wherever such third-party acknowledgments normally appear.
|
||||
*
|
||||
* 4. The names "Xalan" and "Apache Software Foundation" must
|
||||
* not be used to endorse or promote products derived from this
|
||||
* software without prior written permission. For written
|
||||
* permission, please contact apache@apache.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "Apache",
|
||||
* nor may "Apache" appear in their name, without prior written
|
||||
* permission of the Apache Software Foundation.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation and was
|
||||
* originally based on software copyright (c) 2001, International
|
||||
* Business Machines Corporation., http://www.ibm.com. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*/
|
||||
|
||||
package org.apache.xml.resolver.apps;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.Vector;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
import org.xml.sax.*;
|
||||
import org.xml.sax.helpers.*;
|
||||
|
||||
import javax.xml.parsers.*;
|
||||
|
||||
import org.apache.xml.resolver.tools.ResolvingParser;
|
||||
import org.apache.xml.resolver.Catalog;
|
||||
import org.apache.xml.resolver.helpers.Debug;
|
||||
|
||||
/**
|
||||
* <p>A simple command-line XML parsing application.</p>
|
||||
*
|
||||
* <p>This class implements a simple command-line XML Parser. It's
|
||||
* just a little wrapper around the JAXP Parser with support for
|
||||
* catalogs.
|
||||
* </p>
|
||||
*
|
||||
* <p>Usage: xparse [options] document.xml</p>
|
||||
*
|
||||
* <p>Where:</p>
|
||||
*
|
||||
* <dl>
|
||||
* <dt><code>-c</code> <em>catalogfile</em></dt>
|
||||
* <dd>Load a particular catalog file.</dd>
|
||||
* <dt><code>-w</code></dt>
|
||||
* <dd>Perform a well-formed parse, not a validating parse.</dd>
|
||||
* <dt><code>-v</code> (the default)</dt>
|
||||
* <dd>Perform a validating parse.</dd>
|
||||
* <dt><code>-n</code></dt>
|
||||
* <dd>Perform a namespace-ignorant parse.</dd>
|
||||
* <dt><code>-N</code> (the default)</dt>
|
||||
* <dd>Perform a namespace-aware parse.</dd>
|
||||
* <dt><code>-d</code> <em>integer</em></dt>
|
||||
* <dd>Set the debug level. Warnings are shown if the debug level
|
||||
* is > 2.</dd>
|
||||
* <dt><code>-E</code> <em>integer</em></dt>
|
||||
* <dd>Set the maximum number of errors to display.</dd>
|
||||
* </dl>
|
||||
*
|
||||
* <p>The process ends with error-level 1, if there errors.</p>
|
||||
*
|
||||
* @deprecated This interface has been replaced by the
|
||||
* {@link org.apache.xml.resolver.tools.ResolvingXMLReader} for SAX2.
|
||||
*
|
||||
* @see org.apache.xml.resolver.tools.ResolvingParser
|
||||
*
|
||||
* @author Norman Walsh
|
||||
* <a href="mailto:Norman.Walsh@Sun.COM">Norman.Walsh@Sun.COM</a>
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
public class xparse
|
||||
{
|
||||
/** The main entry point */
|
||||
public static void main (String[] args)
|
||||
throws FileNotFoundException, IOException {
|
||||
|
||||
String xmlfile = null;
|
||||
int debug = 0;
|
||||
int maxErrs = 10;
|
||||
boolean nsAware = true;
|
||||
boolean validating = true;
|
||||
boolean showWarnings = (debug > 2);
|
||||
boolean showErrors = true;
|
||||
Vector catalogFiles = new Vector();
|
||||
|
||||
for (int i=0; i<args.length; i++) {
|
||||
if (args[i].equals("-c")) {
|
||||
++i;
|
||||
catalogFiles.add(args[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (args[i].equals("-w")) {
|
||||
validating = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (args[i].equals("-v")) {
|
||||
validating = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (args[i].equals("-n")) {
|
||||
nsAware = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (args[i].equals("-N")) {
|
||||
nsAware = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (args[i].equals("-d")) {
|
||||
++i;
|
||||
String debugstr = args[i];
|
||||
try {
|
||||
debug = Integer.parseInt(debugstr);
|
||||
if (debug >= 0) {
|
||||
Debug.setDebug(debug);
|
||||
showWarnings = (debug > 2);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// nop
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (args[i].equals("-E")) {
|
||||
++i;
|
||||
String errstr = args[i];
|
||||
try {
|
||||
int errs = Integer.parseInt(errstr);
|
||||
if (errs >= 0) {
|
||||
maxErrs = errs;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// nop
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
xmlfile = args[i];
|
||||
}
|
||||
|
||||
if (xmlfile == null) {
|
||||
System.out.println("Usage: org.apache.xml.resolver.apps.xparse [opts] xmlfile");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
ResolvingParser.validating = validating;
|
||||
ResolvingParser.namespaceAware = nsAware;
|
||||
ResolvingParser reader = new ResolvingParser();
|
||||
Catalog catalog = reader.getCatalog();
|
||||
|
||||
for (int count = 0; count < catalogFiles.size(); count++) {
|
||||
String file = (String) catalogFiles.elementAt(count);
|
||||
catalog.parseCatalog(file);
|
||||
}
|
||||
|
||||
XParseError xpe = new XParseError(showErrors, showWarnings);
|
||||
xpe.setMaxMessages(maxErrs);
|
||||
reader.setErrorHandler(xpe);
|
||||
|
||||
String parseType = validating ? "validating" : "well-formed";
|
||||
String nsType = nsAware ? "namespace-aware" : "namespace-ignorant";
|
||||
if (maxErrs > 0) {
|
||||
System.out.println("Attempting "
|
||||
+ parseType
|
||||
+ ", "
|
||||
+ nsType
|
||||
+ " parse");
|
||||
}
|
||||
|
||||
Date startTime = new Date();
|
||||
|
||||
try {
|
||||
reader.parse(xmlfile);
|
||||
} catch (SAXException sx) {
|
||||
System.out.println("SAX Exception: " + sx);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Date endTime = new Date();
|
||||
|
||||
long millisec = endTime.getTime() - startTime.getTime();
|
||||
long secs = 0;
|
||||
long mins = 0;
|
||||
long hours = 0;
|
||||
|
||||
if (millisec > 1000) {
|
||||
secs = millisec / 1000;
|
||||
millisec = millisec % 1000;
|
||||
}
|
||||
|
||||
if (secs > 60) {
|
||||
mins = secs / 60;
|
||||
secs = secs % 60;
|
||||
}
|
||||
|
||||
if (mins > 60) {
|
||||
hours = mins / 60;
|
||||
mins = mins % 60;
|
||||
}
|
||||
|
||||
if (maxErrs > 0) {
|
||||
System.out.print("Parse ");
|
||||
if (xpe.getFatalCount() > 0) {
|
||||
System.out.print("failed ");
|
||||
} else {
|
||||
System.out.print("succeeded ");
|
||||
System.out.print("(");
|
||||
if (hours > 0) {
|
||||
System.out.print(hours + ":");
|
||||
}
|
||||
if (hours > 0 || mins > 0) {
|
||||
System.out.print(mins + ":");
|
||||
}
|
||||
System.out.print(secs + "." + millisec);
|
||||
System.out.print(") ");
|
||||
}
|
||||
System.out.print("with ");
|
||||
|
||||
int errCount = xpe.getErrorCount();
|
||||
int warnCount = xpe.getWarningCount();
|
||||
|
||||
if (errCount > 0) {
|
||||
System.out.print(errCount + " error");
|
||||
System.out.print(errCount > 1 ? "s" : "");
|
||||
System.out.print(" and ");
|
||||
} else {
|
||||
System.out.print("no errors and ");
|
||||
}
|
||||
|
||||
if (warnCount > 0) {
|
||||
System.out.print(warnCount + " warning");
|
||||
System.out.print(warnCount > 1 ? "s" : "");
|
||||
System.out.print(".");
|
||||
} else {
|
||||
System.out.print("no warnings.");
|
||||
}
|
||||
|
||||
System.out.println("");
|
||||
}
|
||||
|
||||
if (xpe.getErrorCount() > 0) {
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,303 @@
|
||||
// xread.java - A simple command-line XML parser
|
||||
|
||||
/*
|
||||
* The Apache Software License, Version 1.1
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2001 The Apache Software Foundation. All rights
|
||||
* reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The end-user documentation included with the redistribution,
|
||||
* if any, must include the following acknowledgment:
|
||||
* "This product includes software developed by the
|
||||
* Apache Software Foundation (http://www.apache.org/)."
|
||||
* Alternately, this acknowledgment may appear in the software itself,
|
||||
* if and wherever such third-party acknowledgments normally appear.
|
||||
*
|
||||
* 4. The names "Xalan" and "Apache Software Foundation" must
|
||||
* not be used to endorse or promote products derived from this
|
||||
* software without prior written permission. For written
|
||||
* permission, please contact apache@apache.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "Apache",
|
||||
* nor may "Apache" appear in their name, without prior written
|
||||
* permission of the Apache Software Foundation.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation and was
|
||||
* originally based on software copyright (c) 2001, International
|
||||
* Business Machines Corporation., http://www.ibm.com. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*/
|
||||
|
||||
package org.apache.xml.resolver.apps;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.Vector;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
import org.xml.sax.*;
|
||||
import org.xml.sax.helpers.*;
|
||||
|
||||
import javax.xml.parsers.*;
|
||||
|
||||
import org.apache.xml.resolver.tools.ResolvingXMLReader;
|
||||
import org.apache.xml.resolver.Catalog;
|
||||
import org.apache.xml.resolver.helpers.Debug;
|
||||
|
||||
/**
|
||||
* <p>A simple command-line XML parsing application.</p>
|
||||
*
|
||||
* <p>This class implements a simple command-line XML Parser. It's
|
||||
* just a little wrapper around the JAXP XMLReader with support for
|
||||
* catalogs.
|
||||
* </p>
|
||||
*
|
||||
* <p>Usage: xread [options] document.xml</p>
|
||||
*
|
||||
* <p>Where:</p>
|
||||
*
|
||||
* <dl>
|
||||
* <dt><code>-c</code> <em>catalogfile</em></dt>
|
||||
* <dd>Load a particular catalog file.</dd>
|
||||
* <dt><code>-w</code></dt>
|
||||
* <dd>Perform a well-formed parse, not a validating parse.</dd>
|
||||
* <dt><code>-v</code> (the default)</dt>
|
||||
* <dd>Perform a validating parse.</dd>
|
||||
* <dt><code>-n</code></dt>
|
||||
* <dd>Perform a namespace-ignorant parse.</dd>
|
||||
* <dt><code>-N</code> (the default)</dt>
|
||||
* <dd>Perform a namespace-aware parse.</dd>
|
||||
* <dt><code>-d</code> <em>integer</em></dt>
|
||||
* <dd>Set the debug level. Warnings are shown if the debug level
|
||||
* is > 2.</dd>
|
||||
* <dt><code>-E</code> <em>integer</em></dt>
|
||||
* <dd>Set the maximum number of errors to display.</dd>
|
||||
* </dl>
|
||||
*
|
||||
* <p>The process ends with error-level 1, if there errors.</p>
|
||||
*
|
||||
* @see org.apache.xml.resolver.tools.ResolvingXMLReader
|
||||
*
|
||||
* @author Norman Walsh
|
||||
* <a href="mailto:Norman.Walsh@Sun.COM">Norman.Walsh@Sun.COM</a>
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
public class xread
|
||||
{
|
||||
/** The main entry point */
|
||||
public static void main (String[] args)
|
||||
throws FileNotFoundException, IOException {
|
||||
|
||||
String xmlfile = null;
|
||||
int debug = 0;
|
||||
int maxErrs = 10;
|
||||
boolean nsAware = true;
|
||||
boolean validating = true;
|
||||
boolean showWarnings = (debug > 2);
|
||||
boolean showErrors = true;
|
||||
Vector catalogFiles = new Vector();
|
||||
|
||||
for (int i=0; i<args.length; i++) {
|
||||
if (args[i].equals("-c")) {
|
||||
++i;
|
||||
catalogFiles.add(args[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (args[i].equals("-w")) {
|
||||
validating = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (args[i].equals("-v")) {
|
||||
validating = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (args[i].equals("-n")) {
|
||||
nsAware = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (args[i].equals("-N")) {
|
||||
nsAware = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (args[i].equals("-d")) {
|
||||
++i;
|
||||
String debugstr = args[i];
|
||||
try {
|
||||
debug = Integer.parseInt(debugstr);
|
||||
if (debug >= 0) {
|
||||
Debug.setDebug(debug);
|
||||
showWarnings = (debug > 2);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// nop
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (args[i].equals("-E")) {
|
||||
++i;
|
||||
String errstr = args[i];
|
||||
try {
|
||||
int errs = Integer.parseInt(errstr);
|
||||
if (errs >= 0) {
|
||||
maxErrs = errs;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// nop
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
xmlfile = args[i];
|
||||
}
|
||||
|
||||
if (xmlfile == null) {
|
||||
System.out.println("Usage: org.apache.xml.resolver.apps.xread [opts] xmlfile");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
ResolvingXMLReader reader = new ResolvingXMLReader();
|
||||
|
||||
try {
|
||||
reader.setFeature("http://xml.org/sax/features/namespaces", nsAware);
|
||||
reader.setFeature("http://xml.org/sax/features/validation", validating);
|
||||
} catch (SAXException e) {
|
||||
// nop;
|
||||
}
|
||||
|
||||
Catalog catalog = reader.getCatalog();
|
||||
|
||||
for (int count = 0; count < catalogFiles.size(); count++) {
|
||||
String file = (String) catalogFiles.elementAt(count);
|
||||
catalog.parseCatalog(file);
|
||||
}
|
||||
|
||||
XParseError xpe = new XParseError(showErrors, showWarnings);
|
||||
xpe.setMaxMessages(maxErrs);
|
||||
reader.setErrorHandler(xpe);
|
||||
|
||||
String parseType = validating ? "validating" : "well-formed";
|
||||
String nsType = nsAware ? "namespace-aware" : "namespace-ignorant";
|
||||
if (maxErrs > 0) {
|
||||
System.out.println("Attempting "
|
||||
+ parseType
|
||||
+ ", "
|
||||
+ nsType
|
||||
+ " parse");
|
||||
}
|
||||
|
||||
Date startTime = new Date();
|
||||
|
||||
try {
|
||||
reader.parse(xmlfile);
|
||||
} catch (SAXException sx) {
|
||||
System.out.println("SAX Exception: " + sx);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Date endTime = new Date();
|
||||
|
||||
long millisec = endTime.getTime() - startTime.getTime();
|
||||
long secs = 0;
|
||||
long mins = 0;
|
||||
long hours = 0;
|
||||
|
||||
if (millisec > 1000) {
|
||||
secs = millisec / 1000;
|
||||
millisec = millisec % 1000;
|
||||
}
|
||||
|
||||
if (secs > 60) {
|
||||
mins = secs / 60;
|
||||
secs = secs % 60;
|
||||
}
|
||||
|
||||
if (mins > 60) {
|
||||
hours = mins / 60;
|
||||
mins = mins % 60;
|
||||
}
|
||||
|
||||
if (maxErrs > 0) {
|
||||
System.out.print("Parse ");
|
||||
if (xpe.getFatalCount() > 0) {
|
||||
System.out.print("failed ");
|
||||
} else {
|
||||
System.out.print("succeeded ");
|
||||
System.out.print("(");
|
||||
if (hours > 0) {
|
||||
System.out.print(hours + ":");
|
||||
}
|
||||
if (hours > 0 || mins > 0) {
|
||||
System.out.print(mins + ":");
|
||||
}
|
||||
System.out.print(secs + "." + millisec);
|
||||
System.out.print(") ");
|
||||
}
|
||||
System.out.print("with ");
|
||||
|
||||
int errCount = xpe.getErrorCount();
|
||||
int warnCount = xpe.getWarningCount();
|
||||
|
||||
if (errCount > 0) {
|
||||
System.out.print(errCount + " error");
|
||||
System.out.print(errCount > 1 ? "s" : "");
|
||||
System.out.print(" and ");
|
||||
} else {
|
||||
System.out.print("no errors and ");
|
||||
}
|
||||
|
||||
if (warnCount > 0) {
|
||||
System.out.print(warnCount + " warning");
|
||||
System.out.print(warnCount > 1 ? "s" : "");
|
||||
System.out.print(".");
|
||||
} else {
|
||||
System.out.print("no warnings.");
|
||||
}
|
||||
|
||||
System.out.println("");
|
||||
}
|
||||
|
||||
if (xpe.getErrorCount() > 0) {
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
// Debug.java - Print debug messages
|
||||
|
||||
/*
|
||||
* The Apache Software License, Version 1.1
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2001 The Apache Software Foundation. All rights
|
||||
* reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The end-user documentation included with the redistribution,
|
||||
* if any, must include the following acknowledgment:
|
||||
* "This product includes software developed by the
|
||||
* Apache Software Foundation (http://www.apache.org/)."
|
||||
* Alternately, this acknowledgment may appear in the software itself,
|
||||
* if and wherever such third-party acknowledgments normally appear.
|
||||
*
|
||||
* 4. The names "Xalan" and "Apache Software Foundation" must
|
||||
* not be used to endorse or promote products derived from this
|
||||
* software without prior written permission. For written
|
||||
* permission, please contact apache@apache.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "Apache",
|
||||
* nor may "Apache" appear in their name, without prior written
|
||||
* permission of the Apache Software Foundation.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation and was
|
||||
* originally based on software copyright (c) 2001, International
|
||||
* Business Machines Corporation., http://www.ibm.com. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*/
|
||||
|
||||
package org.apache.xml.resolver.helpers;
|
||||
|
||||
import org.apache.xml.resolver.CatalogManager;
|
||||
|
||||
/**
|
||||
* <p>Static debugging/messaging class for Catalogs.</p>
|
||||
*
|
||||
* <p>This class defines a set of static methods that can be called
|
||||
* to produce debugging messages. Messages have an associated "debug
|
||||
* level" and messages below the current setting are not displayed.</p>
|
||||
*
|
||||
* @author Norman Walsh
|
||||
* <a href="mailto:Norman.Walsh@Sun.COM">Norman.Walsh@Sun.COM</a>
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
public class Debug {
|
||||
/** The internal debug level. */
|
||||
protected static int debug = CatalogManager.verbosity();
|
||||
|
||||
/** Set the debug level for future messages. */
|
||||
public static void setDebug(int newDebug) {
|
||||
debug = newDebug;
|
||||
}
|
||||
|
||||
/** Get the current debug level. */
|
||||
public static int getDebug() {
|
||||
return debug;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Print debug message (if the debug level is high enough).</p>
|
||||
*
|
||||
* <p>Prints "the message"</p>
|
||||
*
|
||||
* @param level The debug level of this message. This message
|
||||
* will only be
|
||||
* displayed if the current debug level is at least equal to this
|
||||
* value.
|
||||
* @param message The text of the message.
|
||||
*/
|
||||
public static void message(int level, String message) {
|
||||
if (debug >= level) {
|
||||
System.out.println(message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Print debug message (if the debug level is high enough).</p>
|
||||
*
|
||||
* <p>Prints "the message: spec"</p>
|
||||
*
|
||||
* @param level The debug level of this message. This message
|
||||
* will only be
|
||||
* displayed if the current debug level is at least equal to this
|
||||
* value.
|
||||
* @param message The text of the message.
|
||||
* @param spec An argument to the message.
|
||||
*/
|
||||
public static void message(int level, String message, String spec) {
|
||||
if (debug >= level) {
|
||||
System.out.println(message + ": " + spec);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Print debug message (if the debug level is high enough).</p>
|
||||
*
|
||||
* <p>Prints "the message: spec1" and "spec2" indented on the next line.</p>
|
||||
*
|
||||
* @param level The debug level of this message. This message
|
||||
* will only be
|
||||
* displayed if the current debug level is at least equal to this
|
||||
* value.
|
||||
* @param message The text of the message.
|
||||
* @param spec1 An argument to the message.
|
||||
* @param spec2 Another argument to the message.
|
||||
*/
|
||||
public static void message(int level, String message,
|
||||
String spec1, String spec2) {
|
||||
if (debug >= level) {
|
||||
System.out.println(message + ": " + spec1);
|
||||
System.out.println("\t" + spec2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
// Namespaces.java - Analyze namespace nodes in a DOM tree
|
||||
|
||||
/*
|
||||
* The Apache Software License, Version 1.1
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2001 The Apache Software Foundation. All rights
|
||||
* reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The end-user documentation included with the redistribution,
|
||||
* if any, must include the following acknowledgment:
|
||||
* "This product includes software developed by the
|
||||
* Apache Software Foundation (http://www.apache.org/)."
|
||||
* Alternately, this acknowledgment may appear in the software itself,
|
||||
* if and wherever such third-party acknowledgments normally appear.
|
||||
*
|
||||
* 4. The names "Xalan" and "Apache Software Foundation" must
|
||||
* not be used to endorse or promote products derived from this
|
||||
* software without prior written permission. For written
|
||||
* permission, please contact apache@apache.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "Apache",
|
||||
* nor may "Apache" appear in their name, without prior written
|
||||
* permission of the Apache Software Foundation.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation and was
|
||||
* originally based on software copyright (c) 2001, International
|
||||
* Business Machines Corporation., http://www.ibm.com. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*/
|
||||
|
||||
package org.apache.xml.resolver.helpers;
|
||||
|
||||
import org.w3c.dom.*;
|
||||
|
||||
/**
|
||||
* <p>Static Namespace query methods.</p>
|
||||
*
|
||||
* <p>This class defines a set of static methods that can be called
|
||||
* to analyze the namespace properties of DOM nodes.</p>
|
||||
*
|
||||
* @author Norman Walsh
|
||||
* <a href="mailto:Norman.Walsh@Sun.COM">Norman.Walsh@Sun.COM</a>
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
public class Namespaces {
|
||||
/**
|
||||
* <p>Returns the "prefix" part of a QName or the empty string (not
|
||||
* null) if the name has no prefix.</p>
|
||||
*
|
||||
* @param element The QName of an element.
|
||||
* @return The prefix part of the element name.
|
||||
*/
|
||||
public static String getPrefix(Element element) {
|
||||
String name = element.getTagName();
|
||||
String prefix = "";
|
||||
|
||||
if (name.indexOf(':') > 0) {
|
||||
prefix = name.substring(0, name.indexOf(':'));
|
||||
}
|
||||
|
||||
return prefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the "localname" part of a QName, which is the whole
|
||||
* name if it has no prefix.</p>
|
||||
*
|
||||
* @param element The QName of an element.
|
||||
* @return The local part of a QName.
|
||||
*/
|
||||
public static String getLocalName(Element element) {
|
||||
String name = element.getTagName();
|
||||
|
||||
if (name.indexOf(':') > 0) {
|
||||
name = name.substring(name.indexOf(':')+1);
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the namespace URI for the specified prefix at the
|
||||
* specified context node.</p>
|
||||
*
|
||||
* @param node The context node.
|
||||
* @param prefix The prefix.
|
||||
* @return The namespace URI associated with the prefix, or
|
||||
* null if no namespace declaration exists for the prefix.
|
||||
*/
|
||||
public static String getNamespaceURI(Node node, String prefix) {
|
||||
if (node == null || node.getNodeType() != Node.ELEMENT_NODE) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (prefix.equals("")) {
|
||||
if (((Element) node).hasAttribute("xmlns")) {
|
||||
return ((Element) node).getAttribute("xmlns");
|
||||
}
|
||||
} else {
|
||||
String nsattr = "xmlns:" + prefix;
|
||||
if (((Element) node).hasAttribute(nsattr)) {
|
||||
return ((Element) node).getAttribute(nsattr);
|
||||
}
|
||||
}
|
||||
|
||||
return getNamespaceURI(node.getParentNode(), prefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the namespace URI for the namespace to which the
|
||||
* element belongs.</p>
|
||||
*
|
||||
* @param element The element.
|
||||
* @return The namespace URI associated with the namespace of the
|
||||
* element, or null if no namespace declaration exists for it.
|
||||
*/
|
||||
public static String getNamespaceURI(Element element) {
|
||||
String prefix = getPrefix(element);
|
||||
return getNamespaceURI(element, prefix);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,198 @@
|
||||
// PublicId.java - Information about public identifiers
|
||||
|
||||
/*
|
||||
* The Apache Software License, Version 1.1
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2001 The Apache Software Foundation. All rights
|
||||
* reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The end-user documentation included with the redistribution,
|
||||
* if any, must include the following acknowledgment:
|
||||
* "This product includes software developed by the
|
||||
* Apache Software Foundation (http://www.apache.org/)."
|
||||
* Alternately, this acknowledgment may appear in the software itself,
|
||||
* if and wherever such third-party acknowledgments normally appear.
|
||||
*
|
||||
* 4. The names "Xalan" and "Apache Software Foundation" must
|
||||
* not be used to endorse or promote products derived from this
|
||||
* software without prior written permission. For written
|
||||
* permission, please contact apache@apache.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "Apache",
|
||||
* nor may "Apache" appear in their name, without prior written
|
||||
* permission of the Apache Software Foundation.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation and was
|
||||
* originally based on software copyright (c) 2001, International
|
||||
* Business Machines Corporation., http://www.ibm.com. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*/
|
||||
|
||||
package org.apache.xml.resolver.helpers;
|
||||
|
||||
/**
|
||||
* <p>Static methods for dealing with public identifiers.</p>
|
||||
*
|
||||
* <p>This class defines a set of static methods that can be called
|
||||
* to handle public identifiers.</p>
|
||||
*
|
||||
* @author Norman Walsh
|
||||
* <a href="mailto:Norman.Walsh@Sun.COM">Norman.Walsh@Sun.COM</a>
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
public abstract class PublicId {
|
||||
protected PublicId() { }
|
||||
|
||||
/**
|
||||
* <p>Normalize a public identifier.</p>
|
||||
*
|
||||
* <p>Public identifiers must be normalized according to the following
|
||||
* rules before comparisons between them can be made:</p>
|
||||
*
|
||||
* <ul>
|
||||
* <li>Whitespace characters are normalized to spaces (e.g., line feeds,
|
||||
* tabs, etc. become spaces).</li>
|
||||
* <li>Leading and trailing whitespace is removed.</li>
|
||||
* <li>Multiple internal whitespaces are normalized to a single
|
||||
* space.</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>This method is declared static so that other classes
|
||||
* can use it directly.</p>
|
||||
*
|
||||
* @param publicId The unnormalized public identifier.
|
||||
*
|
||||
* @return The normalized identifier.
|
||||
*/
|
||||
public static String normalize(String publicId) {
|
||||
String normal = publicId.replace('\t', ' ');
|
||||
normal = normal.replace('\r', ' ');
|
||||
normal = normal.replace('\n', ' ');
|
||||
normal = normal.trim();
|
||||
|
||||
int pos;
|
||||
|
||||
while ((pos = normal.indexOf(" ")) >= 0) {
|
||||
normal = normal.substring(0, pos) + normal.substring(pos+1);
|
||||
}
|
||||
|
||||
return normal;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Encode a public identifier as a "publicid" URN.</p>
|
||||
*
|
||||
* <p>This method is declared static so that other classes
|
||||
* can use it directly.</p>
|
||||
*
|
||||
* @param publicId The unnormalized public identifier.
|
||||
*
|
||||
* @return The normalized identifier.
|
||||
*/
|
||||
public static String encodeURN(String publicId) {
|
||||
String urn = PublicId.normalize(publicId);
|
||||
|
||||
urn = PublicId.stringReplace(urn, "%", "%25");
|
||||
urn = PublicId.stringReplace(urn, ";", "%3B");
|
||||
urn = PublicId.stringReplace(urn, "'", "%27");
|
||||
urn = PublicId.stringReplace(urn, "?", "%3F");
|
||||
urn = PublicId.stringReplace(urn, "#", "%23");
|
||||
urn = PublicId.stringReplace(urn, "+", "%2B");
|
||||
urn = PublicId.stringReplace(urn, " ", "+");
|
||||
urn = PublicId.stringReplace(urn, "::", ";");
|
||||
urn = PublicId.stringReplace(urn, ":", "%3A");
|
||||
urn = PublicId.stringReplace(urn, "//", ":");
|
||||
urn = PublicId.stringReplace(urn, "/", "%2F");
|
||||
|
||||
return "urn:publicid:" + urn;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Decode a "publicid" URN into a public identifier.</p>
|
||||
*
|
||||
* <p>This method is declared static so that other classes
|
||||
* can use it directly.</p>
|
||||
*
|
||||
* @param publicId The unnormalized public identifier.
|
||||
*
|
||||
* @return The normalized identifier.
|
||||
*/
|
||||
public static String decodeURN(String urn) {
|
||||
String publicId = "";
|
||||
|
||||
if (urn.startsWith("urn:publicid:")) {
|
||||
publicId = urn.substring(13);
|
||||
} else {
|
||||
return urn;
|
||||
}
|
||||
|
||||
publicId = PublicId.stringReplace(publicId, "%2F", "/");
|
||||
publicId = PublicId.stringReplace(publicId, ":", "//");
|
||||
publicId = PublicId.stringReplace(publicId, "%3A", ":");
|
||||
publicId = PublicId.stringReplace(publicId, ";", "::");
|
||||
publicId = PublicId.stringReplace(publicId, "+", " ");
|
||||
publicId = PublicId.stringReplace(publicId, "%2B", "+");
|
||||
publicId = PublicId.stringReplace(publicId, "%23", "#");
|
||||
publicId = PublicId.stringReplace(publicId, "%3F", "?");
|
||||
publicId = PublicId.stringReplace(publicId, "%27", "'");
|
||||
publicId = PublicId.stringReplace(publicId, "%3B", ";");
|
||||
publicId = PublicId.stringReplace(publicId, "%25", "%");
|
||||
|
||||
return publicId;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Replace one string with another.</p>
|
||||
*
|
||||
*/
|
||||
private static String stringReplace(String str,
|
||||
String oldStr,
|
||||
String newStr) {
|
||||
|
||||
String result = "";
|
||||
int pos = str.indexOf(oldStr);
|
||||
|
||||
// System.out.println(str + ": " + oldStr + " => " + newStr);
|
||||
|
||||
while (pos >= 0) {
|
||||
// System.out.println(str + " (" + pos + ")");
|
||||
result += str.substring(0, pos);
|
||||
result += newStr;
|
||||
str = str.substring(pos+1);
|
||||
|
||||
pos = str.indexOf(oldStr);
|
||||
}
|
||||
|
||||
return result + str;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Apache XML Commons Resolver Helpers package</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>Apache XML Commons Resolver Helpers package</p>
|
||||
|
||||
<p>This package provides a collection of static helper functions used
|
||||
across a number of different classes.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,41 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Apache XML Common Resolver</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>The Apache XML Commons Resolver classes implement Catalog-based entity and
|
||||
URI resolution.</p>
|
||||
|
||||
<h1>Overview</h1>
|
||||
|
||||
<p>The resolver class implements the full semantics of OASIS
|
||||
<a href="http://www.oasis-open.org/html/a401.htm">Technical
|
||||
Resolution 9401:1997 (Amendment 2 to TR 9401)</a> catalogs and
|
||||
the 06 Aug 2001 Committee Specification of OASIS
|
||||
<a href="http://www.oasis-open.org/committees/entity/spec-2001-08-01.html">XML
|
||||
Catalogs</a>.</p>
|
||||
|
||||
<p>It also
|
||||
includes a framework of classes designed to read catalog files in
|
||||
a number of formats:
|
||||
</p>
|
||||
|
||||
<ol>
|
||||
<li>The plain-text flavor described by TR9401.
|
||||
<li>The <a href="http://home.ccil.org/~cowan/XML/XCatalog.html">XCatalog</a>
|
||||
XML format defined by John Cowan
|
||||
<li>The XML Catalog format defined by the OASIS
|
||||
<a href="http://www.oasis-open.org/committees/entity/">Entity Resolution
|
||||
Technical Committee</a>.
|
||||
</ol>
|
||||
|
||||
<h2>Quick Start</h2>
|
||||
|
||||
<p>The <a href="org/apache/xml/resolver/tools/package-summary.html">tools
|
||||
classes</a> provide "out-of-the-box" SAX1 Parser, SAX2 XMLReader,
|
||||
and JAXP URIResolvers. If you're just interested in hooking a
|
||||
parser or URI resolver into your application, this is the place to start.
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,34 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Apache XML Commons Resolver package</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>Apache XML Commons Resolver package</p>
|
||||
|
||||
<p>The classes in this package implement the full semantics of
|
||||
<a href="http://www.oasis-open.org/html/a401.htm">OASIS Technical
|
||||
Resolution 9401:1997 (Amendment 2 to TR 9401)</a> catalogs. Also included
|
||||
are a framework of classes designed to read catalog files in
|
||||
a number of formats.
|
||||
</p>
|
||||
|
||||
<p>The principal classes in this package are:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="Catalog.html">Catalog</a>, implements the
|
||||
semantics of OASIS Catalogs.
|
||||
<li><a href="Resolver.html">Resolver</a>, demonstrates how the semantics
|
||||
of OASIS Catalogs can be extended with these classes.
|
||||
<li><a href="CatalogManager.html">CatalogManager</a>, interfaces with the
|
||||
Catalog properties file (that controls the default values of certain
|
||||
properties).
|
||||
<li><a href="TR9401CatalogReader.html">TR9401CatalogReader</a>, reads
|
||||
plain text TR9401 catalog files
|
||||
<li><a href="OASISXMLCatalogReader.html">OASISXMLCatalogReader</a>, reads
|
||||
OASIS XML Catalogs (as defined in the 2001-08-01 committee draft)
|
||||
<li><a href="XCatalogReader.html">XCatalogReader</a>, reads John Cowan's
|
||||
XCatalog files
|
||||
</ul>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,118 @@
|
||||
// CatalogReader.java - An interface for reading catalog files
|
||||
|
||||
/*
|
||||
* The Apache Software License, Version 1.1
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2001 The Apache Software Foundation. All rights
|
||||
* reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The end-user documentation included with the redistribution,
|
||||
* if any, must include the following acknowledgment:
|
||||
* "This product includes software developed by the
|
||||
* Apache Software Foundation (http://www.apache.org/)."
|
||||
* Alternately, this acknowledgment may appear in the software itself,
|
||||
* if and wherever such third-party acknowledgments normally appear.
|
||||
*
|
||||
* 4. The names "Xalan" and "Apache Software Foundation" must
|
||||
* not be used to endorse or promote products derived from this
|
||||
* software without prior written permission. For written
|
||||
* permission, please contact apache@apache.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "Apache",
|
||||
* nor may "Apache" appear in their name, without prior written
|
||||
* permission of the Apache Software Foundation.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation and was
|
||||
* originally based on software copyright (c) 2001, International
|
||||
* Business Machines Corporation., http://www.ibm.com. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*/
|
||||
|
||||
package org.apache.xml.resolver.readers;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import org.apache.xml.resolver.CatalogException;
|
||||
|
||||
import java.io.InputStream;
|
||||
import org.apache.xml.resolver.Catalog;
|
||||
|
||||
/**
|
||||
* <p>The CatalogReader interface.</p>
|
||||
*
|
||||
* <p>The Catalog class requires that classes implement this interface
|
||||
* in order to be used to read catalogs. Examples of CatalogReaders
|
||||
* include the TextCatalogReader, the SAXCatalogReader, and the
|
||||
* DOMCatalogReader.</p>
|
||||
*
|
||||
* @see Catalog
|
||||
*
|
||||
* @author Norman Walsh
|
||||
* <a href="mailto:Norman.Walsh@Sun.COM">Norman.Walsh@Sun.COM</a>
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
public interface CatalogReader {
|
||||
/**
|
||||
* <p>Read a catalog from a file</p>
|
||||
*
|
||||
* <p>This class reads a catalog from a URL.</p>
|
||||
*
|
||||
* @param catalog The catalog for which this reader is called.
|
||||
* @param fileUrl The URL of a document to be read.
|
||||
* @throws MalformedURLException if the specified URL cannot be
|
||||
* turned into a URL object.
|
||||
* @throws IOException if the URL cannot be read.
|
||||
* @throws UnknownCatalogFormatException if the catalog format is
|
||||
* not recognized.
|
||||
* @throws UnparseableCatalogException if the catalog cannot be parsed.
|
||||
* (For example, if it is supposed to be XML and isn't well-formed.)
|
||||
*/
|
||||
public void readCatalog(Catalog catalog, String fileUrl)
|
||||
throws MalformedURLException, IOException, CatalogException;
|
||||
|
||||
/**
|
||||
* <p>Read a catalog from an input stream</p>
|
||||
*
|
||||
* <p>This class reads a catalog from an input stream.</p>
|
||||
*
|
||||
* @param catalog The catalog for which this reader is called.
|
||||
* @param is The input stream that is to be read.
|
||||
* @throws IOException if the URL cannot be read.
|
||||
* @throws UnknownCatalogFormatException if the catalog format is
|
||||
* not recognized.
|
||||
* @throws UnparseableCatalogException if the catalog cannot be parsed.
|
||||
* (For example, if it is supposed to be XML and isn't well-formed.)
|
||||
*/
|
||||
public void readCatalog(Catalog catalog, InputStream is)
|
||||
throws IOException, CatalogException;
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
// DOMCatalogParser.java - An interface for reading catalog files
|
||||
|
||||
/*
|
||||
* The Apache Software License, Version 1.1
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2001 The Apache Software Foundation. All rights
|
||||
* reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The end-user documentation included with the redistribution,
|
||||
* if any, must include the following acknowledgment:
|
||||
* "This product includes software developed by the
|
||||
* Apache Software Foundation (http://www.apache.org/)."
|
||||
* Alternately, this acknowledgment may appear in the software itself,
|
||||
* if and wherever such third-party acknowledgments normally appear.
|
||||
*
|
||||
* 4. The names "Xalan" and "Apache Software Foundation" must
|
||||
* not be used to endorse or promote products derived from this
|
||||
* software without prior written permission. For written
|
||||
* permission, please contact apache@apache.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "Apache",
|
||||
* nor may "Apache" appear in their name, without prior written
|
||||
* permission of the Apache Software Foundation.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation and was
|
||||
* originally based on software copyright (c) 2001, International
|
||||
* Business Machines Corporation., http://www.ibm.com. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*/
|
||||
|
||||
package org.apache.xml.resolver.readers;
|
||||
|
||||
import org.apache.xml.resolver.Catalog;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
/**
|
||||
* <p>The DOMCatalogParser interface.</p>
|
||||
*
|
||||
* <p>This interface must be implemented in order for a class to
|
||||
* participate as a parser for the DOMCatalogReader.
|
||||
*
|
||||
* @see Catalog
|
||||
* @see DOMCatalogReader
|
||||
*
|
||||
* @author Norman Walsh
|
||||
* <a href="mailto:Norman.Walsh@Sun.COM">Norman.Walsh@Sun.COM</a>
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
public interface DOMCatalogParser {
|
||||
/**
|
||||
* <p>Parse a DOM node as a catalog entry</p>
|
||||
*
|
||||
* <p>This method is expected to analyze the specified node and
|
||||
* construct appropriate catalog entry(ies) from it.</p>
|
||||
*
|
||||
* @param catalog The catalog for which this node is being considered.
|
||||
* @param node The DOM Node from the catalog.
|
||||
*/
|
||||
public void parseCatalogEntry(Catalog catalog, Node node);
|
||||
}
|
||||
@@ -0,0 +1,288 @@
|
||||
// DOMCatalogReader.java - Read XML Catalog files
|
||||
|
||||
/*
|
||||
* The Apache Software License, Version 1.1
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2001 The Apache Software Foundation. All rights
|
||||
* reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The end-user documentation included with the redistribution,
|
||||
* if any, must include the following acknowledgment:
|
||||
* "This product includes software developed by the
|
||||
* Apache Software Foundation (http://www.apache.org/)."
|
||||
* Alternately, this acknowledgment may appear in the software itself,
|
||||
* if and wherever such third-party acknowledgments normally appear.
|
||||
*
|
||||
* 4. The names "Xalan" and "Apache Software Foundation" must
|
||||
* not be used to endorse or promote products derived from this
|
||||
* software without prior written permission. For written
|
||||
* permission, please contact apache@apache.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "Apache",
|
||||
* nor may "Apache" appear in their name, without prior written
|
||||
* permission of the Apache Software Foundation.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation and was
|
||||
* originally based on software copyright (c) 2001, International
|
||||
* Business Machines Corporation., http://www.ibm.com. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*/
|
||||
|
||||
package org.apache.xml.resolver.readers;
|
||||
|
||||
import java.lang.Integer;
|
||||
import java.util.Vector;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Enumeration;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
import org.apache.xml.resolver.Catalog;
|
||||
import org.apache.xml.resolver.CatalogEntry;
|
||||
import org.apache.xml.resolver.CatalogException;
|
||||
import org.apache.xml.resolver.readers.CatalogReader;
|
||||
import org.apache.xml.resolver.helpers.Debug;
|
||||
import org.apache.xml.resolver.helpers.PublicId;
|
||||
import org.apache.xml.resolver.helpers.Namespaces;
|
||||
|
||||
import org.xml.sax.SAXException;
|
||||
import org.w3c.dom.*;
|
||||
|
||||
/**
|
||||
* <p>A DOM-based CatalogReader</p>
|
||||
*
|
||||
* <p>This class is used to read XML Catalogs using the DOM. This reader
|
||||
* has an advantage over the SAX-based reader that it can analyze the
|
||||
* DOM tree rather than simply a series of SAX events. It has the disadvantage
|
||||
* that it requires all of the code necessary to build and walk a DOM
|
||||
* tree.</p>
|
||||
*
|
||||
* <p>Since the choice of CatalogReaders (in the InputStream case) can only
|
||||
* be made on the basis of MIME type, the following problem occurs: only
|
||||
* one CatalogReader can exist for all XML mime types. In order to get
|
||||
* around this problem, the DOMCatalogReader relies on a set of external
|
||||
* CatalogParsers to actually build the catalog.</p>
|
||||
*
|
||||
* <p>The selection of CatalogParsers is made on the basis of the QName
|
||||
* of the root element of the document.</p>
|
||||
*
|
||||
* <p>This class requires the <a href="http://java.sun.com/aboutJava/communityprocess/final/jsr005/index.html">Java API for XML Parsing</a>.</p>
|
||||
*
|
||||
* @see Catalog
|
||||
* @see CatalogReader
|
||||
* @see SAXCatalogReader
|
||||
* @see TextCatalogReader
|
||||
* @see DOMCatalogParser
|
||||
*
|
||||
* @author Norman Walsh
|
||||
* <a href="mailto:Norman.Walsh@Sun.COM">Norman.Walsh@Sun.COM</a>
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
public class DOMCatalogReader implements CatalogReader {
|
||||
/**
|
||||
* <p>Mapping table from QNames to CatalogParser classes.</p>
|
||||
*
|
||||
* <p>Each key in this hash table has the form "elementname"
|
||||
* or "{namespaceuri}elementname". The former is used if the
|
||||
* namespace URI is null.</p>
|
||||
*/
|
||||
protected Hashtable namespaceMap = new Hashtable();
|
||||
|
||||
/**
|
||||
* <p>Add a new parser to the reader.</p>
|
||||
*
|
||||
* <p>This method associates the specified parserClass with the
|
||||
* namespaceURI/rootElement names specified.</p>
|
||||
*
|
||||
* @param namespaceURI The namespace URI. <em>Not</em> the prefix.
|
||||
* @param rootElement The name of the root element.
|
||||
* @param parserClass The name of the parserClass to instantiate
|
||||
* for this kind of catalog.
|
||||
*/
|
||||
public void setCatalogParser(String namespaceURI,
|
||||
String rootElement,
|
||||
String parserClass) {
|
||||
if (namespaceURI == null) {
|
||||
namespaceMap.put(rootElement, parserClass);
|
||||
} else {
|
||||
namespaceMap.put("{"+namespaceURI+"}"+rootElement, parserClass);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Get the name of the parser class for a given catalog type.</p>
|
||||
*
|
||||
* <p>This method returns the parserClass associated with the
|
||||
* namespaceURI/rootElement names specified.</p>
|
||||
*
|
||||
* @param namespaceURI The namespace URI. <em>Not</em> the prefix.
|
||||
* @param rootElement The name of the root element.
|
||||
* @return The parser class.
|
||||
*/
|
||||
public String getCatalogParser(String namespaceURI,
|
||||
String rootElement) {
|
||||
if (namespaceURI == null) {
|
||||
return (String) namespaceMap.get(rootElement);
|
||||
} else {
|
||||
return (String) namespaceMap.get("{"+namespaceURI+"}"+rootElement);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Null constructor; something for subclasses to call.</p>
|
||||
*/
|
||||
public DOMCatalogReader() { }
|
||||
|
||||
/**
|
||||
* <p>Read a catalog from an input stream</p>
|
||||
*
|
||||
* <p>This class reads a catalog from an input stream:</p>
|
||||
*
|
||||
* <ul>
|
||||
* <li>Based on the QName of the root element, it determines which
|
||||
* parser to instantiate for this catalog.</li>
|
||||
* <li>It constructs a DOM Document from the catalog and</li>
|
||||
* <li>For each child of the root node, it calls the parser's
|
||||
* parseCatalogEntry method. This method is expected to make
|
||||
* appropriate calls back into the catalog to add entries for the
|
||||
* entries in the catalog. It is free to do this in whatever manner
|
||||
* is appropriate (perhaps using just the node passed in, perhaps
|
||||
* wandering arbitrarily throughout the tree).</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param catalog The catalog for which this reader is called.
|
||||
* @param is The input stream that is to be read.
|
||||
* @throws IOException if the URL cannot be read.
|
||||
* @throws UnknownCatalogFormatException if the catalog format is
|
||||
* not recognized.
|
||||
* @throws UnparseableCatalogException if the catalog cannot be parsed.
|
||||
* (For example, if it is supposed to be XML and isn't well-formed or
|
||||
* if the parser class cannot be instantiated.)
|
||||
*/
|
||||
public void readCatalog(Catalog catalog, InputStream is)
|
||||
throws IOException, CatalogException {
|
||||
|
||||
DocumentBuilderFactory factory = null;
|
||||
DocumentBuilder builder = null;
|
||||
|
||||
factory = DocumentBuilderFactory.newInstance();
|
||||
factory.setNamespaceAware(false);
|
||||
factory.setValidating(false);
|
||||
try {
|
||||
builder = factory.newDocumentBuilder();
|
||||
} catch (ParserConfigurationException pce) {
|
||||
throw new CatalogException(CatalogException.UNPARSEABLE);
|
||||
}
|
||||
|
||||
Document doc = null;
|
||||
|
||||
try {
|
||||
doc = builder.parse(is);
|
||||
} catch (SAXException se) {
|
||||
throw new CatalogException(CatalogException.UNKNOWN_FORMAT);
|
||||
}
|
||||
|
||||
Element root = doc.getDocumentElement();
|
||||
|
||||
String namespaceURI = Namespaces.getNamespaceURI(root);
|
||||
String localName = Namespaces.getLocalName(root);
|
||||
|
||||
String domParserClass = getCatalogParser(namespaceURI,
|
||||
localName);
|
||||
|
||||
if (domParserClass == null) {
|
||||
if (namespaceURI == null) {
|
||||
Debug.message(1, "No Catalog parser for " + localName);
|
||||
} else {
|
||||
Debug.message(1, "No Catalog parser for "
|
||||
+ "{" + namespaceURI + "}"
|
||||
+ localName);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
DOMCatalogParser domParser = null;
|
||||
|
||||
try {
|
||||
domParser = (DOMCatalogParser) Class.forName(domParserClass).newInstance();
|
||||
} catch (ClassNotFoundException cnfe) {
|
||||
Debug.message(1, "Cannot load XML Catalog Parser class", domParserClass);
|
||||
throw new CatalogException(CatalogException.UNPARSEABLE);
|
||||
} catch (InstantiationException ie) {
|
||||
Debug.message(1, "Cannot instantiate XML Catalog Parser class", domParserClass);
|
||||
throw new CatalogException(CatalogException.UNPARSEABLE);
|
||||
} catch (IllegalAccessException iae) {
|
||||
Debug.message(1, "Cannot access XML Catalog Parser class", domParserClass);
|
||||
throw new CatalogException(CatalogException.UNPARSEABLE);
|
||||
} catch (ClassCastException cce ) {
|
||||
Debug.message(1, "Cannot cast XML Catalog Parser class", domParserClass);
|
||||
throw new CatalogException(CatalogException.UNPARSEABLE);
|
||||
}
|
||||
|
||||
Node node = root.getFirstChild();
|
||||
while (node != null) {
|
||||
domParser.parseCatalogEntry(catalog, node);
|
||||
node = node.getNextSibling();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Read the catalog behind the specified URL.</p>
|
||||
*
|
||||
* @see #readCatalog(Catalog, InputStream)
|
||||
*
|
||||
* @param catalog The catalog for which we are reading.
|
||||
* @param fileUrl The URL of the document that should be read.
|
||||
*
|
||||
* @throws MalformedURLException if the specified URL cannot be
|
||||
* turned into a URL object.
|
||||
* @throws IOException if the URL cannot be read.
|
||||
* @throws UnknownCatalogFormatException if the catalog format is
|
||||
* not recognized.
|
||||
* @throws UnparseableCatalogException if the catalog cannot be parsed.
|
||||
* (For example, if it is supposed to be XML and isn't well-formed.)
|
||||
*/
|
||||
public void readCatalog(Catalog catalog, String fileUrl)
|
||||
throws MalformedURLException, IOException, CatalogException {
|
||||
URL url = new URL(fileUrl);
|
||||
URLConnection urlCon = url.openConnection();
|
||||
readCatalog(catalog, urlCon.getInputStream());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,235 @@
|
||||
// ExtendedXMLCatalogReader.java - Read XML Catalog files
|
||||
|
||||
/*
|
||||
* The Apache Software License, Version 1.1
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2001 The Apache Software Foundation. All rights
|
||||
* reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The end-user documentation included with the redistribution,
|
||||
* if any, must include the following acknowledgment:
|
||||
* "This product includes software developed by the
|
||||
* Apache Software Foundation (http://www.apache.org/)."
|
||||
* Alternately, this acknowledgment may appear in the software itself,
|
||||
* if and wherever such third-party acknowledgments normally appear.
|
||||
*
|
||||
* 4. The names "Xalan" and "Apache Software Foundation" must
|
||||
* not be used to endorse or promote products derived from this
|
||||
* software without prior written permission. For written
|
||||
* permission, please contact apache@apache.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "Apache",
|
||||
* nor may "Apache" appear in their name, without prior written
|
||||
* permission of the Apache Software Foundation.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation and was
|
||||
* originally based on software copyright (c) 2001, International
|
||||
* Business Machines Corporation., http://www.ibm.com. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*/
|
||||
|
||||
package org.apache.xml.resolver.readers;
|
||||
|
||||
import java.lang.Integer;
|
||||
import java.util.Stack;
|
||||
import java.util.Vector;
|
||||
import java.util.Enumeration;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import org.apache.xml.resolver.Catalog;
|
||||
import org.apache.xml.resolver.Resolver;
|
||||
import org.apache.xml.resolver.CatalogEntry;
|
||||
import org.apache.xml.resolver.CatalogException;
|
||||
import org.apache.xml.resolver.readers.CatalogReader;
|
||||
import org.apache.xml.resolver.helpers.PublicId;
|
||||
import org.apache.xml.resolver.helpers.Debug;
|
||||
|
||||
import org.xml.sax.*;
|
||||
import org.w3c.dom.*;
|
||||
|
||||
/**
|
||||
* <p>Parse Extended OASIS Entity Resolution Technical Committee
|
||||
* XML Catalog files.</p>
|
||||
*
|
||||
* @see Catalog
|
||||
*
|
||||
* @author Norman Walsh
|
||||
* <a href="mailto:Norman.Walsh@Sun.COM">Norman.Walsh@Sun.COM</a>
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
public class ExtendedXMLCatalogReader extends OASISXMLCatalogReader {
|
||||
/** The namespace name of extended catalog elements */
|
||||
public static final String extendedNamespaceName = "http://nwalsh.com/xcatalog/1.0";
|
||||
|
||||
/**
|
||||
* <p>The SAX <code>startElement</code> method recognizes elements
|
||||
* from the plain catalog format and instantiates CatalogEntry
|
||||
* objects for them.</p>
|
||||
*
|
||||
* @param namespaceURI The namespace name of the element.
|
||||
* @param localName The local name of the element.
|
||||
* @param qName The QName of the element.
|
||||
* @param atts The list of attributes on the element.
|
||||
*
|
||||
* @see CatalogEntry
|
||||
*/
|
||||
public void startElement (String namespaceURI,
|
||||
String localName,
|
||||
String qName,
|
||||
Attributes atts)
|
||||
throws SAXException {
|
||||
|
||||
// Check before calling the super because super will report our
|
||||
// namespace as an extension namespace, but that doesn't count
|
||||
// for this element.
|
||||
boolean inExtension = inExtensionNamespace();
|
||||
|
||||
super.startElement(namespaceURI, localName, qName, atts);
|
||||
|
||||
int entryType = -1;
|
||||
Vector entryArgs = new Vector();
|
||||
|
||||
if (namespaceURI != null && extendedNamespaceName.equals(namespaceURI)
|
||||
&& !inExtension) {
|
||||
// This is an Extended XML Catalog entry
|
||||
|
||||
if (atts.getValue("xml:base") != null) {
|
||||
String baseURI = atts.getValue("xml:base");
|
||||
entryType = Catalog.BASE;
|
||||
entryArgs.add(baseURI);
|
||||
baseURIStack.push(baseURI);
|
||||
|
||||
Debug.message(4, "xml:base", baseURI);
|
||||
|
||||
try {
|
||||
CatalogEntry ce = new CatalogEntry(entryType, entryArgs);
|
||||
catalog.addEntry(ce);
|
||||
} catch (CatalogException cex) {
|
||||
if (cex.getExceptionType() == CatalogException.INVALID_ENTRY_TYPE) {
|
||||
Debug.message(1, "Invalid catalog entry type", localName);
|
||||
} else if (cex.getExceptionType() == CatalogException.INVALID_ENTRY) {
|
||||
Debug.message(1, "Invalid catalog entry (base)", localName);
|
||||
}
|
||||
}
|
||||
|
||||
entryType = -1;
|
||||
entryArgs = new Vector();
|
||||
} else {
|
||||
baseURIStack.push(baseURIStack.peek());
|
||||
}
|
||||
|
||||
if (localName.equals("uriSuffix")) {
|
||||
if (checkAttributes(atts, "suffix", "uri")) {
|
||||
entryType = Resolver.URISUFFIX;
|
||||
entryArgs.add(atts.getValue("suffix"));
|
||||
entryArgs.add(atts.getValue("uri"));
|
||||
|
||||
Debug.message(4, "uriSuffix",
|
||||
atts.getValue("suffix"),
|
||||
atts.getValue("uri"));
|
||||
}
|
||||
} else if (localName.equals("systemSuffix")) {
|
||||
if (checkAttributes(atts, "suffix", "uri")) {
|
||||
entryType = Resolver.SYSTEMSUFFIX;
|
||||
entryArgs.add(atts.getValue("suffix"));
|
||||
entryArgs.add(atts.getValue("uri"));
|
||||
|
||||
Debug.message(4, "systemSuffix",
|
||||
atts.getValue("suffix"),
|
||||
atts.getValue("uri"));
|
||||
}
|
||||
} else {
|
||||
// This is equivalent to an invalid catalog entry type
|
||||
Debug.message(1, "Invalid catalog entry type", localName);
|
||||
}
|
||||
|
||||
if (entryType >= 0) {
|
||||
try {
|
||||
CatalogEntry ce = new CatalogEntry(entryType, entryArgs);
|
||||
catalog.addEntry(ce);
|
||||
} catch (CatalogException cex) {
|
||||
if (cex.getExceptionType() == CatalogException.INVALID_ENTRY_TYPE) {
|
||||
Debug.message(1, "Invalid catalog entry type", localName);
|
||||
} else if (cex.getExceptionType() == CatalogException.INVALID_ENTRY) {
|
||||
Debug.message(1, "Invalid catalog entry", localName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** <p>The SAX <code>endElement</code> method does nothing.</p> */
|
||||
public void endElement (String namespaceURI,
|
||||
String localName,
|
||||
String qName)
|
||||
throws SAXException {
|
||||
|
||||
super.endElement(namespaceURI, localName, qName);
|
||||
|
||||
// Check after popping the stack so we don't erroneously think we
|
||||
// are our own extension namespace...
|
||||
boolean inExtension = inExtensionNamespace();
|
||||
|
||||
int entryType = -1;
|
||||
Vector entryArgs = new Vector();
|
||||
|
||||
if (namespaceURI != null
|
||||
&& (extendedNamespaceName.equals(namespaceURI))
|
||||
&& !inExtension) {
|
||||
|
||||
String popURI = (String) baseURIStack.pop();
|
||||
String baseURI = (String) baseURIStack.peek();
|
||||
|
||||
if (!baseURI.equals(popURI)) {
|
||||
entryType = catalog.BASE;
|
||||
entryArgs.add(baseURI);
|
||||
|
||||
Debug.message(4, "(reset) xml:base", baseURI);
|
||||
|
||||
try {
|
||||
CatalogEntry ce = new CatalogEntry(entryType, entryArgs);
|
||||
catalog.addEntry(ce);
|
||||
} catch (CatalogException cex) {
|
||||
if (cex.getExceptionType() == CatalogException.INVALID_ENTRY_TYPE) {
|
||||
Debug.message(1, "Invalid catalog entry type", localName);
|
||||
} else if (cex.getExceptionType() == CatalogException.INVALID_ENTRY) {
|
||||
Debug.message(1, "Invalid catalog entry (rbase)", localName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,565 @@
|
||||
// OASISXMLCatalogReader.java - Read XML Catalog files
|
||||
|
||||
/*
|
||||
* The Apache Software License, Version 1.1
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2001 The Apache Software Foundation. All rights
|
||||
* reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The end-user documentation included with the redistribution,
|
||||
* if any, must include the following acknowledgment:
|
||||
* "This product includes software developed by the
|
||||
* Apache Software Foundation (http://www.apache.org/)."
|
||||
* Alternately, this acknowledgment may appear in the software itself,
|
||||
* if and wherever such third-party acknowledgments normally appear.
|
||||
*
|
||||
* 4. The names "Xalan" and "Apache Software Foundation" must
|
||||
* not be used to endorse or promote products derived from this
|
||||
* software without prior written permission. For written
|
||||
* permission, please contact apache@apache.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "Apache",
|
||||
* nor may "Apache" appear in their name, without prior written
|
||||
* permission of the Apache Software Foundation.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation and was
|
||||
* originally based on software copyright (c) 2001, International
|
||||
* Business Machines Corporation., http://www.ibm.com. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*/
|
||||
|
||||
package org.apache.xml.resolver.readers;
|
||||
|
||||
import java.lang.Integer;
|
||||
import java.util.Stack;
|
||||
import java.util.Vector;
|
||||
import java.util.Enumeration;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import org.apache.xml.resolver.Catalog;
|
||||
import org.apache.xml.resolver.CatalogEntry;
|
||||
import org.apache.xml.resolver.CatalogException;
|
||||
import org.apache.xml.resolver.readers.CatalogReader;
|
||||
import org.apache.xml.resolver.helpers.PublicId;
|
||||
import org.apache.xml.resolver.helpers.Debug;
|
||||
|
||||
import org.xml.sax.*;
|
||||
import org.w3c.dom.*;
|
||||
|
||||
/**
|
||||
* <p>Parse OASIS Entity Resolution Technical Committee
|
||||
* XML Catalog files.</p>
|
||||
*
|
||||
* @see Catalog
|
||||
*
|
||||
* @author Norman Walsh
|
||||
* <a href="mailto:Norman.Walsh@Sun.COM">Norman.Walsh@Sun.COM</a>
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
public class OASISXMLCatalogReader extends SAXCatalogReader implements SAXCatalogParser {
|
||||
/** The catalog object needs to be stored by the object so that
|
||||
* SAX callbacks can use it.
|
||||
*/
|
||||
protected Catalog catalog = null;
|
||||
|
||||
/** The namespace name of OASIS ERTC catalogs */
|
||||
public static final String namespaceName = "urn:oasis:names:tc:entity:xmlns:xml:catalog";
|
||||
|
||||
/** The namespace name of OASIS ERTC TR9401 catalog extension */
|
||||
public static final String tr9401NamespaceName = "urn:oasis:names:tc:entity:xmlns:tr9401:catalog";
|
||||
|
||||
protected Stack baseURIStack = new Stack();
|
||||
protected Stack overrideStack = new Stack();
|
||||
protected Stack namespaceStack = new Stack();
|
||||
|
||||
/** Set the current catalog. */
|
||||
public void setCatalog (Catalog catalog) {
|
||||
this.catalog = catalog;
|
||||
}
|
||||
|
||||
/** Get the current catalog. */
|
||||
public Catalog getCatalog () {
|
||||
return catalog;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Are we in an extension namespace?</p>
|
||||
*
|
||||
* @returns true if the current stack of open namespaces includes
|
||||
* an extension namespace.
|
||||
*/
|
||||
protected boolean inExtensionNamespace() {
|
||||
boolean inExtension = false;
|
||||
|
||||
Enumeration elements = namespaceStack.elements();
|
||||
while (!inExtension && elements.hasMoreElements()) {
|
||||
String ns = (String) elements.nextElement();
|
||||
if (ns == null) {
|
||||
inExtension = true;
|
||||
} else {
|
||||
inExtension = (!ns.equals(tr9401NamespaceName)
|
||||
&& !ns.equals(namespaceName));
|
||||
}
|
||||
}
|
||||
|
||||
return inExtension;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Implement the SAX ContentHandler interface
|
||||
|
||||
/** <p>The SAX <code>setDocumentLocator</code> method does nothing.</p> */
|
||||
public void setDocumentLocator (Locator locator) {
|
||||
return;
|
||||
}
|
||||
|
||||
/** <p>The SAX <code>startDocument</code> method does nothing.</p> */
|
||||
public void startDocument ()
|
||||
throws SAXException {
|
||||
baseURIStack.push(catalog.getCurrentBase());
|
||||
overrideStack.push(catalog.getDefaultOverride());
|
||||
return;
|
||||
}
|
||||
|
||||
/** <p>The SAX <code>endDocument</code> method does nothing.</p> */
|
||||
public void endDocument ()
|
||||
throws SAXException {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>The SAX <code>startElement</code> method recognizes elements
|
||||
* from the plain catalog format and instantiates CatalogEntry
|
||||
* objects for them.</p>
|
||||
*
|
||||
* @param namespaceURI The namespace name of the element.
|
||||
* @param localName The local name of the element.
|
||||
* @param qName The QName of the element.
|
||||
* @param atts The list of attributes on the element.
|
||||
*
|
||||
* @see CatalogEntry
|
||||
*/
|
||||
public void startElement (String namespaceURI,
|
||||
String localName,
|
||||
String qName,
|
||||
Attributes atts)
|
||||
throws SAXException {
|
||||
|
||||
int entryType = -1;
|
||||
Vector entryArgs = new Vector();
|
||||
|
||||
namespaceStack.push(namespaceURI);
|
||||
|
||||
boolean inExtension = inExtensionNamespace();
|
||||
|
||||
if (namespaceURI != null && namespaceName.equals(namespaceURI)
|
||||
&& !inExtension) {
|
||||
// This is an XML Catalog entry
|
||||
|
||||
if (atts.getValue("xml:base") != null) {
|
||||
String baseURI = atts.getValue("xml:base");
|
||||
entryType = Catalog.BASE;
|
||||
entryArgs.add(baseURI);
|
||||
baseURIStack.push(baseURI);
|
||||
|
||||
Debug.message(4, "xml:base", baseURI);
|
||||
|
||||
try {
|
||||
CatalogEntry ce = new CatalogEntry(entryType, entryArgs);
|
||||
catalog.addEntry(ce);
|
||||
} catch (CatalogException cex) {
|
||||
if (cex.getExceptionType() == CatalogException.INVALID_ENTRY_TYPE) {
|
||||
Debug.message(1, "Invalid catalog entry type", localName);
|
||||
} else if (cex.getExceptionType() == CatalogException.INVALID_ENTRY) {
|
||||
Debug.message(1, "Invalid catalog entry (base)", localName);
|
||||
}
|
||||
}
|
||||
|
||||
entryType = -1;
|
||||
entryArgs = new Vector();
|
||||
|
||||
} else {
|
||||
baseURIStack.push(baseURIStack.peek());
|
||||
}
|
||||
|
||||
if ((localName.equals("catalog") || localName.equals("group"))
|
||||
&& atts.getValue("prefer") != null) {
|
||||
String override = atts.getValue("prefer");
|
||||
|
||||
if (override.equals("public")) {
|
||||
override = "yes";
|
||||
} else if (override.equals("system")) {
|
||||
override = "no";
|
||||
} else {
|
||||
Debug.message(1,
|
||||
"Invalid prefer: must be 'system' or 'public'",
|
||||
localName);
|
||||
override = catalog.getDefaultOverride();
|
||||
}
|
||||
|
||||
entryType = Catalog.OVERRIDE;
|
||||
entryArgs.add(override);
|
||||
overrideStack.push(override);
|
||||
|
||||
Debug.message(4, "override", override);
|
||||
|
||||
try {
|
||||
CatalogEntry ce = new CatalogEntry(entryType, entryArgs);
|
||||
catalog.addEntry(ce);
|
||||
} catch (CatalogException cex) {
|
||||
if (cex.getExceptionType() == CatalogException.INVALID_ENTRY_TYPE) {
|
||||
Debug.message(1, "Invalid catalog entry type", localName);
|
||||
} else if (cex.getExceptionType() == CatalogException.INVALID_ENTRY) {
|
||||
Debug.message(1, "Invalid catalog entry (override)", localName);
|
||||
}
|
||||
}
|
||||
|
||||
entryType = -1;
|
||||
entryArgs = new Vector();
|
||||
|
||||
} else {
|
||||
overrideStack.push(overrideStack.peek());
|
||||
}
|
||||
|
||||
if (localName.equals("delegatePublic")) {
|
||||
if (checkAttributes(atts, "publicIdStartString", "catalog")) {
|
||||
entryType = Catalog.DELEGATE_PUBLIC;
|
||||
entryArgs.add(atts.getValue("publicIdStartString"));
|
||||
entryArgs.add(atts.getValue("catalog"));
|
||||
|
||||
Debug.message(4, "delegatePublic",
|
||||
PublicId.normalize(atts.getValue("publicIdStartString")),
|
||||
atts.getValue("catalog"));
|
||||
}
|
||||
} else if (localName.equals("delegateSystem")) {
|
||||
if (checkAttributes(atts, "systemIdStartString", "catalog")) {
|
||||
entryType = Catalog.DELEGATE_SYSTEM;
|
||||
entryArgs.add(atts.getValue("systemIdStartString"));
|
||||
entryArgs.add(atts.getValue("catalog"));
|
||||
|
||||
Debug.message(4, "delegateSystem",
|
||||
atts.getValue("systemIdStartString"),
|
||||
atts.getValue("catalog"));
|
||||
}
|
||||
} else if (localName.equals("delegateURI")) {
|
||||
if (checkAttributes(atts, "uriStartString", "catalog")) {
|
||||
entryType = Catalog.DELEGATE_URI;
|
||||
entryArgs.add(atts.getValue("uriStartString"));
|
||||
entryArgs.add(atts.getValue("catalog"));
|
||||
|
||||
Debug.message(4, "delegateURI",
|
||||
atts.getValue("uriStartString"),
|
||||
atts.getValue("catalog"));
|
||||
}
|
||||
} else if (localName.equals("rewriteSystem")) {
|
||||
if (checkAttributes(atts, "systemIdStartString", "rewritePrefix")) {
|
||||
entryType = Catalog.REWRITE_SYSTEM;
|
||||
entryArgs.add(atts.getValue("systemIdStartString"));
|
||||
entryArgs.add(atts.getValue("rewritePrefix"));
|
||||
|
||||
Debug.message(4, "rewriteSystem",
|
||||
atts.getValue("systemIdStartString"),
|
||||
atts.getValue("rewritePrefix"));
|
||||
}
|
||||
} else if (localName.equals("rewriteURI")) {
|
||||
if (checkAttributes(atts, "uriStartString", "rewritePrefix")) {
|
||||
entryType = Catalog.REWRITE_URI;
|
||||
entryArgs.add(atts.getValue("uriStartString"));
|
||||
entryArgs.add(atts.getValue("rewritePrefix"));
|
||||
|
||||
Debug.message(4, "rewriteURI",
|
||||
atts.getValue("uriStartString"),
|
||||
atts.getValue("rewritePrefix"));
|
||||
}
|
||||
} else if (localName.equals("nextCatalog")) {
|
||||
if (checkAttributes(atts, "catalog")) {
|
||||
entryType = Catalog.CATALOG;
|
||||
entryArgs.add(atts.getValue("catalog"));
|
||||
|
||||
Debug.message(4, "nextCatalog", atts.getValue("catalog"));
|
||||
}
|
||||
} else if (localName.equals("public")) {
|
||||
if (checkAttributes(atts, "publicId", "uri")) {
|
||||
entryType = Catalog.PUBLIC;
|
||||
entryArgs.add(atts.getValue("publicId"));
|
||||
entryArgs.add(atts.getValue("uri"));
|
||||
|
||||
Debug.message(4, "public",
|
||||
PublicId.normalize(atts.getValue("publicId")),
|
||||
atts.getValue("uri"));
|
||||
}
|
||||
} else if (localName.equals("system")) {
|
||||
if (checkAttributes(atts, "systemId", "uri")) {
|
||||
entryType = Catalog.SYSTEM;
|
||||
entryArgs.add(atts.getValue("systemId"));
|
||||
entryArgs.add(atts.getValue("uri"));
|
||||
|
||||
Debug.message(4, "system",
|
||||
atts.getValue("systemId"),
|
||||
atts.getValue("uri"));
|
||||
}
|
||||
} else if (localName.equals("uri")) {
|
||||
if (checkAttributes(atts, "name", "uri")) {
|
||||
entryType = Catalog.URI;
|
||||
entryArgs.add(atts.getValue("name"));
|
||||
entryArgs.add(atts.getValue("uri"));
|
||||
|
||||
Debug.message(4, "uri",
|
||||
atts.getValue("name"),
|
||||
atts.getValue("uri"));
|
||||
}
|
||||
} else if (localName.equals("catalog")) {
|
||||
// nop, start of catalog
|
||||
} else if (localName.equals("group")) {
|
||||
// nop, a group
|
||||
} else {
|
||||
// This is equivalent to an invalid catalog entry type
|
||||
Debug.message(1, "Invalid catalog entry type", localName);
|
||||
}
|
||||
|
||||
if (entryType >= 0) {
|
||||
try {
|
||||
CatalogEntry ce = new CatalogEntry(entryType, entryArgs);
|
||||
catalog.addEntry(ce);
|
||||
} catch (CatalogException cex) {
|
||||
if (cex.getExceptionType() == CatalogException.INVALID_ENTRY_TYPE) {
|
||||
Debug.message(1, "Invalid catalog entry type", localName);
|
||||
} else if (cex.getExceptionType() == CatalogException.INVALID_ENTRY) {
|
||||
Debug.message(1, "Invalid catalog entry", localName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (namespaceURI != null && tr9401NamespaceName.equals(namespaceURI)
|
||||
&& !inExtension) {
|
||||
// This is a TR9401 Catalog entry
|
||||
|
||||
if (atts.getValue("xml:base") != null) {
|
||||
String baseURI = atts.getValue("xml:base");
|
||||
entryType = Catalog.BASE;
|
||||
entryArgs.add(baseURI);
|
||||
baseURIStack.push(baseURI);
|
||||
|
||||
Debug.message(4, "xml:base", baseURI);
|
||||
|
||||
try {
|
||||
CatalogEntry ce = new CatalogEntry(entryType, entryArgs);
|
||||
catalog.addEntry(ce);
|
||||
} catch (CatalogException cex) {
|
||||
if (cex.getExceptionType() == CatalogException.INVALID_ENTRY_TYPE) {
|
||||
Debug.message(1, "Invalid catalog entry type", localName);
|
||||
} else if (cex.getExceptionType() == CatalogException.INVALID_ENTRY) {
|
||||
Debug.message(1, "Invalid catalog entry (base)", localName);
|
||||
}
|
||||
}
|
||||
|
||||
entryType = -1;
|
||||
entryArgs = new Vector();
|
||||
|
||||
} else {
|
||||
baseURIStack.push(baseURIStack.peek());
|
||||
}
|
||||
|
||||
if (localName.equals("doctype")) {
|
||||
entryType = catalog.DOCTYPE;
|
||||
entryArgs.add(atts.getValue("name"));
|
||||
entryArgs.add(atts.getValue("uri"));
|
||||
} else if (localName.equals("document")) {
|
||||
entryType = catalog.DOCUMENT;
|
||||
entryArgs.add(atts.getValue("uri"));
|
||||
} else if (localName.equals("dtddecl")) {
|
||||
entryType = catalog.DTDDECL;
|
||||
entryArgs.add(atts.getValue("publicId"));
|
||||
entryArgs.add(atts.getValue("uri"));
|
||||
} else if (localName.equals("entity")) {
|
||||
entryType = Catalog.ENTITY;
|
||||
entryArgs.add(atts.getValue("name"));
|
||||
entryArgs.add(atts.getValue("uri"));
|
||||
} else if (localName.equals("linktype")) {
|
||||
entryType = Catalog.LINKTYPE;
|
||||
entryArgs.add(atts.getValue("name"));
|
||||
entryArgs.add(atts.getValue("uri"));
|
||||
} else if (localName.equals("notation")) {
|
||||
entryType = Catalog.NOTATION;
|
||||
entryArgs.add(atts.getValue("name"));
|
||||
entryArgs.add(atts.getValue("uri"));
|
||||
} else if (localName.equals("sgmldecl")) {
|
||||
entryType = Catalog.SGMLDECL;
|
||||
entryArgs.add(atts.getValue("uri"));
|
||||
} else {
|
||||
// This is equivalent to an invalid catalog entry type
|
||||
Debug.message(1, "Invalid catalog entry type", localName);
|
||||
}
|
||||
|
||||
if (entryType >= 0) {
|
||||
try {
|
||||
CatalogEntry ce = new CatalogEntry(entryType, entryArgs);
|
||||
catalog.addEntry(ce);
|
||||
} catch (CatalogException cex) {
|
||||
if (cex.getExceptionType() == CatalogException.INVALID_ENTRY_TYPE) {
|
||||
Debug.message(1, "Invalid catalog entry type", localName);
|
||||
} else if (cex.getExceptionType() == CatalogException.INVALID_ENTRY) {
|
||||
Debug.message(1, "Invalid catalog entry", localName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean checkAttributes (Attributes atts, String attName) {
|
||||
if (atts.getValue(attName) == null) {
|
||||
Debug.message(1, "Error: required attribute " + attName + " missing.");
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean checkAttributes (Attributes atts,
|
||||
String attName1,
|
||||
String attName2) {
|
||||
return checkAttributes(atts, attName1)
|
||||
&& checkAttributes(atts, attName2);
|
||||
}
|
||||
|
||||
/** <p>The SAX <code>endElement</code> method does nothing.</p> */
|
||||
public void endElement (String namespaceURI,
|
||||
String localName,
|
||||
String qName)
|
||||
throws SAXException {
|
||||
|
||||
int entryType = -1;
|
||||
Vector entryArgs = new Vector();
|
||||
|
||||
boolean inExtension = inExtensionNamespace();
|
||||
|
||||
if (namespaceURI != null
|
||||
&& !inExtension
|
||||
&& (namespaceName.equals(namespaceURI)
|
||||
|| tr9401NamespaceName.equals(namespaceURI))) {
|
||||
|
||||
String popURI = (String) baseURIStack.pop();
|
||||
String baseURI = (String) baseURIStack.peek();
|
||||
|
||||
if (!baseURI.equals(popURI)) {
|
||||
entryType = catalog.BASE;
|
||||
entryArgs.add(baseURI);
|
||||
|
||||
Debug.message(4, "(reset) xml:base", baseURI);
|
||||
|
||||
try {
|
||||
CatalogEntry ce = new CatalogEntry(entryType, entryArgs);
|
||||
catalog.addEntry(ce);
|
||||
} catch (CatalogException cex) {
|
||||
if (cex.getExceptionType() == CatalogException.INVALID_ENTRY_TYPE) {
|
||||
Debug.message(1, "Invalid catalog entry type", localName);
|
||||
} else if (cex.getExceptionType() == CatalogException.INVALID_ENTRY) {
|
||||
Debug.message(1, "Invalid catalog entry (rbase)", localName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (namespaceURI != null && namespaceName.equals(namespaceURI)
|
||||
&& !inExtension) {
|
||||
if (localName.equals("catalog") || localName.equals("group")) {
|
||||
String popOverride = (String) overrideStack.pop();
|
||||
String override = (String) overrideStack.peek();
|
||||
|
||||
if (!override.equals(popOverride)) {
|
||||
entryType = catalog.OVERRIDE;
|
||||
entryArgs.add(override);
|
||||
overrideStack.push(override);
|
||||
|
||||
Debug.message(4, "(reset) override", override);
|
||||
|
||||
try {
|
||||
CatalogEntry ce = new CatalogEntry(entryType, entryArgs);
|
||||
catalog.addEntry(ce);
|
||||
} catch (CatalogException cex) {
|
||||
if (cex.getExceptionType() == CatalogException.INVALID_ENTRY_TYPE) {
|
||||
Debug.message(1, "Invalid catalog entry type", localName);
|
||||
} else if (cex.getExceptionType() == CatalogException.INVALID_ENTRY) {
|
||||
Debug.message(1, "Invalid catalog entry (roverride)", localName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespaceStack.pop();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/** <p>The SAX <code>characters</code> method does nothing.</p> */
|
||||
public void characters (char ch[], int start, int length)
|
||||
throws SAXException {
|
||||
return;
|
||||
}
|
||||
|
||||
/** <p>The SAX <code>ignorableWhitespace</code> method does nothing.</p> */
|
||||
public void ignorableWhitespace (char ch[], int start, int length)
|
||||
throws SAXException {
|
||||
return;
|
||||
}
|
||||
|
||||
/** <p>The SAX <code>processingInstruction</code> method does nothing.</p> */
|
||||
public void processingInstruction (String target, String data)
|
||||
throws SAXException {
|
||||
return;
|
||||
}
|
||||
|
||||
/** <p>The SAX <code>skippedEntity</code> method does nothing.</p> */
|
||||
public void skippedEntity (String name)
|
||||
throws SAXException {
|
||||
return;
|
||||
}
|
||||
|
||||
/** <p>The SAX <code>startPrefixMapping</code> method does nothing.</p> */
|
||||
public void startPrefixMapping(String prefix, String uri)
|
||||
throws SAXException {
|
||||
return;
|
||||
}
|
||||
|
||||
/** <p>The SAX <code>endPrefixMapping</code> method does nothing.</p> */
|
||||
public void endPrefixMapping(String prefix)
|
||||
throws SAXException {
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
// SAXCatalogParser.java - An interface for reading catalog files
|
||||
|
||||
/*
|
||||
* The Apache Software License, Version 1.1
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2001 The Apache Software Foundation. All rights
|
||||
* reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The end-user documentation included with the redistribution,
|
||||
* if any, must include the following acknowledgment:
|
||||
* "This product includes software developed by the
|
||||
* Apache Software Foundation (http://www.apache.org/)."
|
||||
* Alternately, this acknowledgment may appear in the software itself,
|
||||
* if and wherever such third-party acknowledgments normally appear.
|
||||
*
|
||||
* 4. The names "Xalan" and "Apache Software Foundation" must
|
||||
* not be used to endorse or promote products derived from this
|
||||
* software without prior written permission. For written
|
||||
* permission, please contact apache@apache.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "Apache",
|
||||
* nor may "Apache" appear in their name, without prior written
|
||||
* permission of the Apache Software Foundation.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation and was
|
||||
* originally based on software copyright (c) 2001, International
|
||||
* Business Machines Corporation., http://www.ibm.com. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*/
|
||||
|
||||
package org.apache.xml.resolver.readers;
|
||||
|
||||
import org.apache.xml.resolver.Catalog;
|
||||
import org.xml.sax.*;
|
||||
|
||||
/**
|
||||
* <p>The SAXCatalogParser interface.</p>
|
||||
*
|
||||
* <p>This interface must be implemented in order for a class to
|
||||
* participate as a parser for the SAXCatalogReader.
|
||||
*
|
||||
* @see Catalog
|
||||
* @see SAXCatalogReader
|
||||
*
|
||||
* @author Norman Walsh
|
||||
* <a href="mailto:Norman.Walsh@Sun.COM">Norman.Walsh@Sun.COM</a>
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
public interface SAXCatalogParser extends ContentHandler, DocumentHandler {
|
||||
/** Set the Catalog for which parsing is being performed. */
|
||||
public void setCatalog(Catalog catalog);
|
||||
}
|
||||
@@ -0,0 +1,515 @@
|
||||
// SAXCatalogReader.java - Read XML Catalog files
|
||||
|
||||
/*
|
||||
* The Apache Software License, Version 1.1
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2001 The Apache Software Foundation. All rights
|
||||
* reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The end-user documentation included with the redistribution,
|
||||
* if any, must include the following acknowledgment:
|
||||
* "This product includes software developed by the
|
||||
* Apache Software Foundation (http://www.apache.org/)."
|
||||
* Alternately, this acknowledgment may appear in the software itself,
|
||||
* if and wherever such third-party acknowledgments normally appear.
|
||||
*
|
||||
* 4. The names "Xalan" and "Apache Software Foundation" must
|
||||
* not be used to endorse or promote products derived from this
|
||||
* software without prior written permission. For written
|
||||
* permission, please contact apache@apache.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "Apache",
|
||||
* nor may "Apache" appear in their name, without prior written
|
||||
* permission of the Apache Software Foundation.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation and was
|
||||
* originally based on software copyright (c) 2001, International
|
||||
* Business Machines Corporation., http://www.ibm.com. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*/
|
||||
|
||||
package org.apache.xml.resolver.readers;
|
||||
|
||||
import java.lang.Integer;
|
||||
import java.util.Vector;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Enumeration;
|
||||
import java.io.IOException;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.UnknownHostException;
|
||||
import org.apache.xml.resolver.Catalog;
|
||||
import org.apache.xml.resolver.CatalogEntry;
|
||||
import org.apache.xml.resolver.CatalogException;
|
||||
import org.apache.xml.resolver.readers.CatalogReader;
|
||||
import org.apache.xml.resolver.helpers.Debug;
|
||||
import org.apache.xml.resolver.helpers.PublicId;
|
||||
import org.apache.xml.resolver.helpers.Namespaces;
|
||||
|
||||
import org.xml.sax.*;
|
||||
|
||||
import javax.xml.parsers.*;
|
||||
|
||||
/**
|
||||
* <p>A SAX-based CatalogReader</p>
|
||||
*
|
||||
* <p>This class is used to read XML Catalogs using the SAX. This reader
|
||||
* has an advantage over the DOM-based reader in that it functions on
|
||||
* the stream of SAX events. It has the disadvantage
|
||||
* that it cannot look around in the tree.</p>
|
||||
*
|
||||
* <p>Since the choice of CatalogReaders (in the InputStream case) can only
|
||||
* be made on the basis of MIME type, the following problem occurs: only
|
||||
* one CatalogReader can exist for all XML mime types. In order to get
|
||||
* around this problem, the SAXCatalogReader relies on a set of external
|
||||
* CatalogParsers to actually build the catalog.</p>
|
||||
*
|
||||
* <p>The selection of CatalogParsers is made on the basis of the QName
|
||||
* of the root element of the document.</p>
|
||||
*
|
||||
* @see Catalog
|
||||
* @see CatalogReader
|
||||
* @see SAXCatalogReader
|
||||
* @see TextCatalogReader
|
||||
* @see DOMCatalogParser
|
||||
*
|
||||
* @author Norman Walsh
|
||||
* <a href="mailto:Norman.Walsh@Sun.COM">Norman.Walsh@Sun.COM</a>
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
public class SAXCatalogReader implements CatalogReader, ContentHandler, DocumentHandler {
|
||||
/** The SAX Parser Factory */
|
||||
protected SAXParserFactory parserFactory = null;
|
||||
|
||||
/** The SAX Parser Class */
|
||||
protected String parserClass = null;
|
||||
|
||||
/**
|
||||
* <p>Mapping table from QNames to CatalogParser classes.</p>
|
||||
*
|
||||
* <p>Each key in this hash table has the form "elementname"
|
||||
* or "{namespaceuri}elementname". The former is used if the
|
||||
* namespace URI is null.</p>
|
||||
*/
|
||||
protected Hashtable namespaceMap = new Hashtable();
|
||||
|
||||
/** The parser in use for the current catalog. */
|
||||
private SAXCatalogParser saxParser = null;
|
||||
|
||||
/** Set if something goes horribly wrong. It allows the class to
|
||||
* ignore the rest of the events that are received.
|
||||
*/
|
||||
private boolean abandonHope = false;
|
||||
|
||||
/** The Catalog that we're working for. */
|
||||
private Catalog catalog;
|
||||
|
||||
/** Set the XML SAX Parser Factory.
|
||||
*/
|
||||
public void setParserFactory(SAXParserFactory parserFactory) {
|
||||
this.parserFactory = parserFactory;
|
||||
}
|
||||
|
||||
/** Set the XML SAX Parser Class
|
||||
*/
|
||||
public void setParserClass(String parserClass) {
|
||||
this.parserClass = parserClass;
|
||||
}
|
||||
|
||||
/** Get the parser factory currently in use. */
|
||||
public SAXParserFactory getParserFactory() {
|
||||
return parserFactory;
|
||||
}
|
||||
|
||||
/** Get the parser class currently in use. */
|
||||
public String getParserClass() {
|
||||
return parserClass;
|
||||
}
|
||||
|
||||
/** Set the SAXCatalogParser class for the given namespace/root
|
||||
* element type.
|
||||
*/
|
||||
public void setCatalogParser(String namespaceURI,
|
||||
String rootElement,
|
||||
String parserClass) {
|
||||
if (namespaceURI == null) {
|
||||
namespaceMap.put(rootElement, parserClass);
|
||||
} else {
|
||||
namespaceMap.put("{"+namespaceURI+"}"+rootElement, parserClass);
|
||||
}
|
||||
}
|
||||
|
||||
/** Get the SAXCatalogParser class for the given namespace/root
|
||||
* element type.
|
||||
*/
|
||||
public String getCatalogParser(String namespaceURI,
|
||||
String rootElement) {
|
||||
if (namespaceURI == null) {
|
||||
return (String) namespaceMap.get(rootElement);
|
||||
} else {
|
||||
return (String) namespaceMap.get("{"+namespaceURI+"}"+rootElement);
|
||||
}
|
||||
}
|
||||
|
||||
/** The constructor */
|
||||
public SAXCatalogReader() {
|
||||
parserFactory = null;
|
||||
parserClass = null;
|
||||
}
|
||||
|
||||
/** The constructor */
|
||||
public SAXCatalogReader(SAXParserFactory parserFactory) {
|
||||
this.parserFactory = parserFactory;
|
||||
}
|
||||
|
||||
/** The constructor */
|
||||
public SAXCatalogReader(String parserClass) {
|
||||
this.parserClass = parserClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Parse an XML Catalog file.</p>
|
||||
*
|
||||
* @param catalog The catalog to which this catalog file belongs
|
||||
* @param fileUrl The URL or filename of the catalog file to process
|
||||
*
|
||||
* @throws MalformedURLException Improper fileUrl
|
||||
* @throws IOException Error reading catalog file
|
||||
*/
|
||||
public void readCatalog(Catalog catalog, String fileUrl)
|
||||
throws MalformedURLException, IOException,
|
||||
CatalogException {
|
||||
|
||||
URL url = null;
|
||||
|
||||
try {
|
||||
url = new URL(fileUrl);
|
||||
} catch (MalformedURLException e) {
|
||||
url = new URL("file:///" + fileUrl);
|
||||
}
|
||||
|
||||
try {
|
||||
URLConnection urlCon = url.openConnection();
|
||||
readCatalog(catalog, urlCon.getInputStream());
|
||||
} catch (FileNotFoundException e) {
|
||||
Debug.message(1, "Failed to load catalog, file not found",
|
||||
url.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Parse an XML Catalog stream.</p>
|
||||
*
|
||||
* @param catalog The catalog to which this catalog file belongs
|
||||
* @param is The input stream from which the catalog will be read
|
||||
*
|
||||
* @throws MalformedURLException Improper fileUrl
|
||||
* @throws IOException Error reading catalog file
|
||||
* @throws CatalogException A Catalog exception
|
||||
*/
|
||||
public void readCatalog(Catalog catalog, InputStream is)
|
||||
throws IOException, CatalogException {
|
||||
|
||||
// Create an instance of the parser
|
||||
if (parserFactory == null && parserClass == null) {
|
||||
Debug.message(1, "Cannot read SAX catalog without a parser");
|
||||
throw new CatalogException(CatalogException.UNPARSEABLE);
|
||||
}
|
||||
|
||||
this.catalog = catalog;
|
||||
|
||||
try {
|
||||
if (parserFactory != null) {
|
||||
SAXParser parser = parserFactory.newSAXParser();
|
||||
SAXParserHandler spHandler = new SAXParserHandler();
|
||||
spHandler.setContentHandler(this);
|
||||
parser.parse(new InputSource(is), spHandler);
|
||||
} else {
|
||||
Parser parser = (Parser) Class.forName(parserClass).newInstance();
|
||||
parser.setDocumentHandler(this);
|
||||
parser.parse(new InputSource(is));
|
||||
}
|
||||
} catch (ClassNotFoundException cnfe) {
|
||||
throw new CatalogException(CatalogException.UNPARSEABLE);
|
||||
} catch (IllegalAccessException iae) {
|
||||
throw new CatalogException(CatalogException.UNPARSEABLE);
|
||||
} catch (InstantiationException ie) {
|
||||
throw new CatalogException(CatalogException.UNPARSEABLE);
|
||||
} catch (ParserConfigurationException pce) {
|
||||
throw new CatalogException(CatalogException.UNKNOWN_FORMAT);
|
||||
} catch (SAXException se) {
|
||||
Exception e = se.getException();
|
||||
// FIXME: there must be a better way
|
||||
UnknownHostException uhe = new UnknownHostException();
|
||||
FileNotFoundException fnfe = new FileNotFoundException();
|
||||
if (e != null) {
|
||||
if (e.getClass() == uhe.getClass()) {
|
||||
throw new CatalogException(CatalogException.PARSE_FAILED,
|
||||
e.toString());
|
||||
} else if (e.getClass() == fnfe.getClass()) {
|
||||
throw new CatalogException(CatalogException.PARSE_FAILED,
|
||||
e.toString());
|
||||
}
|
||||
}
|
||||
throw new CatalogException(se);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Implement the SAX ContentHandler interface
|
||||
|
||||
/** <p>The SAX <code>setDocumentLocator</code> method. Does nothing.</p> */
|
||||
public void setDocumentLocator (Locator locator) {
|
||||
if (saxParser != null) {
|
||||
saxParser.setDocumentLocator(locator);
|
||||
}
|
||||
}
|
||||
|
||||
/** <p>The SAX <code>startDocument</code> method. Does nothing.</p> */
|
||||
public void startDocument () throws SAXException {
|
||||
saxParser = null;
|
||||
abandonHope = false;
|
||||
return;
|
||||
}
|
||||
|
||||
/** <p>The SAX <code>endDocument</code> method. Does nothing.</p> */
|
||||
public void endDocument ()throws SAXException {
|
||||
if (saxParser != null) {
|
||||
saxParser.endDocument();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>The SAX <code>startElement</code> method.</p>
|
||||
*
|
||||
* <p>The catalog parser is selected based on the namespace of the
|
||||
* first element encountered in the catalog.</p>
|
||||
*/
|
||||
public void startElement (String name,
|
||||
AttributeList atts)
|
||||
throws SAXException {
|
||||
|
||||
if (abandonHope) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (saxParser == null) {
|
||||
String prefix = "";
|
||||
if (name.indexOf(':') > 0) {
|
||||
prefix = name.substring(0, name.indexOf(':'));
|
||||
}
|
||||
|
||||
String localName = name;
|
||||
if (localName.indexOf(':') > 0) {
|
||||
localName = localName.substring(localName.indexOf(':')+1);
|
||||
}
|
||||
|
||||
String namespaceURI = null;
|
||||
if (prefix.equals("")) {
|
||||
namespaceURI = atts.getValue("xmlns");
|
||||
} else {
|
||||
namespaceURI = atts.getValue("xmlns:" + prefix);
|
||||
}
|
||||
|
||||
String saxParserClass = getCatalogParser(namespaceURI,
|
||||
localName);
|
||||
|
||||
if (saxParserClass == null) {
|
||||
abandonHope = true;
|
||||
if (namespaceURI == null) {
|
||||
Debug.message(2, "No Catalog parser for " + name);
|
||||
} else {
|
||||
Debug.message(2, "No Catalog parser for "
|
||||
+ "{" + namespaceURI + "}"
|
||||
+ name);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
saxParser = (SAXCatalogParser)
|
||||
Class.forName(saxParserClass).newInstance();
|
||||
|
||||
saxParser.setCatalog(catalog);
|
||||
saxParser.startDocument();
|
||||
saxParser.startElement(name, atts);
|
||||
} catch (ClassNotFoundException cnfe) {
|
||||
saxParser = null;
|
||||
abandonHope = true;
|
||||
Debug.message(2, cnfe.toString());
|
||||
} catch (InstantiationException ie) {
|
||||
saxParser = null;
|
||||
abandonHope = true;
|
||||
Debug.message(2, ie.toString());
|
||||
} catch (IllegalAccessException iae) {
|
||||
saxParser = null;
|
||||
abandonHope = true;
|
||||
Debug.message(2, iae.toString());
|
||||
} catch (ClassCastException cce ) {
|
||||
saxParser = null;
|
||||
abandonHope = true;
|
||||
Debug.message(2, cce.toString());
|
||||
}
|
||||
} else {
|
||||
saxParser.startElement(name, atts);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>The SAX2 <code>startElement</code> method.</p>
|
||||
*
|
||||
* <p>The catalog parser is selected based on the namespace of the
|
||||
* first element encountered in the catalog.</p>
|
||||
*/
|
||||
public void startElement (String namespaceURI,
|
||||
String localName,
|
||||
String qName,
|
||||
Attributes atts)
|
||||
throws SAXException {
|
||||
|
||||
if (abandonHope) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (saxParser == null) {
|
||||
String saxParserClass = getCatalogParser(namespaceURI,
|
||||
localName);
|
||||
|
||||
if (saxParserClass == null) {
|
||||
abandonHope = true;
|
||||
if (namespaceURI == null) {
|
||||
Debug.message(2, "No Catalog parser for " + localName);
|
||||
} else {
|
||||
Debug.message(2, "No Catalog parser for "
|
||||
+ "{" + namespaceURI + "}"
|
||||
+ localName);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
saxParser = (SAXCatalogParser)
|
||||
Class.forName(saxParserClass).newInstance();
|
||||
|
||||
saxParser.setCatalog(catalog);
|
||||
saxParser.startDocument();
|
||||
saxParser.startElement(namespaceURI, localName, qName, atts);
|
||||
} catch (ClassNotFoundException cnfe) {
|
||||
saxParser = null;
|
||||
abandonHope = true;
|
||||
Debug.message(2, cnfe.toString());
|
||||
} catch (InstantiationException ie) {
|
||||
saxParser = null;
|
||||
abandonHope = true;
|
||||
Debug.message(2, ie.toString());
|
||||
} catch (IllegalAccessException iae) {
|
||||
saxParser = null;
|
||||
abandonHope = true;
|
||||
Debug.message(2, iae.toString());
|
||||
} catch (ClassCastException cce ) {
|
||||
saxParser = null;
|
||||
abandonHope = true;
|
||||
Debug.message(2, cce.toString());
|
||||
}
|
||||
} else {
|
||||
saxParser.startElement(namespaceURI, localName, qName, atts);
|
||||
}
|
||||
}
|
||||
|
||||
/** <p>The SAX <code>endElement</code> method. Does nothing.</p> */
|
||||
public void endElement (String name) throws SAXException {
|
||||
if (saxParser != null) {
|
||||
saxParser.endElement(name);
|
||||
}
|
||||
}
|
||||
|
||||
/** <p>The SAX2 <code>endElement</code> method. Does nothing.</p> */
|
||||
public void endElement (String namespaceURI,
|
||||
String localName,
|
||||
String qName) throws SAXException {
|
||||
if (saxParser != null) {
|
||||
saxParser.endElement(namespaceURI, localName, qName);
|
||||
}
|
||||
}
|
||||
|
||||
/** <p>The SAX <code>characters</code> method. Does nothing.</p> */
|
||||
public void characters (char ch[], int start, int length)
|
||||
throws SAXException {
|
||||
if (saxParser != null) {
|
||||
saxParser.characters(ch, start, length);
|
||||
}
|
||||
}
|
||||
|
||||
/** <p>The SAX <code>ignorableWhitespace</code> method. Does nothing.</p> */
|
||||
public void ignorableWhitespace (char ch[], int start, int length)
|
||||
throws SAXException {
|
||||
if (saxParser != null) {
|
||||
saxParser.ignorableWhitespace(ch, start, length);
|
||||
}
|
||||
}
|
||||
|
||||
/** <p>The SAX <code>processingInstruction</code> method. Does nothing.</p> */
|
||||
public void processingInstruction (String target, String data)
|
||||
throws SAXException {
|
||||
if (saxParser != null) {
|
||||
saxParser.processingInstruction(target, data);
|
||||
}
|
||||
}
|
||||
|
||||
/** <p>The SAX <code>startPrefixMapping</code> method. Does nothing.</p> */
|
||||
public void startPrefixMapping (String prefix, String uri)
|
||||
throws SAXException {
|
||||
if (saxParser != null) {
|
||||
saxParser.startPrefixMapping (prefix, uri);
|
||||
}
|
||||
}
|
||||
|
||||
/** <p>The SAX <code>endPrefixMapping</code> method. Does nothing.</p> */
|
||||
public void endPrefixMapping (String prefix)
|
||||
throws SAXException {
|
||||
if (saxParser != null) {
|
||||
saxParser.endPrefixMapping (prefix);
|
||||
}
|
||||
}
|
||||
|
||||
/** <p>The SAX <code>skippedentity</code> method. Does nothing.</p> */
|
||||
public void skippedEntity (String name)
|
||||
throws SAXException {
|
||||
if (saxParser != null) {
|
||||
saxParser.skippedEntity(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
// SAXParserHandler.java - An entity-resolving DefaultHandler
|
||||
|
||||
/*
|
||||
* The Apache Software License, Version 1.1
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2001 The Apache Software Foundation. All rights
|
||||
* reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The end-user documentation included with the redistribution,
|
||||
* if any, must include the following acknowledgment:
|
||||
* "This product includes software developed by the
|
||||
* Apache Software Foundation (http://www.apache.org/)."
|
||||
* Alternately, this acknowledgment may appear in the software itself,
|
||||
* if and wherever such third-party acknowledgments normally appear.
|
||||
*
|
||||
* 4. The names "Xalan" and "Apache Software Foundation" must
|
||||
* not be used to endorse or promote products derived from this
|
||||
* software without prior written permission. For written
|
||||
* permission, please contact apache@apache.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "Apache",
|
||||
* nor may "Apache" appear in their name, without prior written
|
||||
* permission of the Apache Software Foundation.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation and was
|
||||
* originally based on software copyright (c) 2001, International
|
||||
* Business Machines Corporation., http://www.ibm.com. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*/
|
||||
|
||||
package org.apache.xml.resolver.readers;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.xml.sax.*;
|
||||
import org.xml.sax.helpers.*;
|
||||
|
||||
/**
|
||||
* <p>An entity-resolving DefaultHandler</p>
|
||||
*
|
||||
* <p>This class provides a SAXParser DefaultHandler that performs
|
||||
* entity resolution.
|
||||
* </p>
|
||||
*
|
||||
* @author Norman Walsh
|
||||
* <a href="mailto:Norman.Walsh@Sun.COM">Norman.Walsh@Sun.COM</a>
|
||||
* @version 1.0
|
||||
*/
|
||||
public class SAXParserHandler extends DefaultHandler {
|
||||
private EntityResolver er = null;
|
||||
private ContentHandler ch = null;
|
||||
|
||||
public SAXParserHandler() {
|
||||
super();
|
||||
}
|
||||
|
||||
public void setEntityResolver(EntityResolver er) {
|
||||
this.er = er;
|
||||
}
|
||||
|
||||
public void setContentHandler(ContentHandler ch) {
|
||||
this.ch = ch;
|
||||
}
|
||||
|
||||
// Entity Resolver
|
||||
public InputSource resolveEntity(String publicId, String systemId)
|
||||
throws SAXException {
|
||||
|
||||
if (er != null) {
|
||||
try {
|
||||
return er.resolveEntity(publicId, systemId);
|
||||
} catch (IOException e) {
|
||||
System.out.println("resolveEntity threw IOException!");
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Content Handler
|
||||
public void characters(char[] ch, int start, int length)
|
||||
throws SAXException {
|
||||
if (this.ch != null) {
|
||||
this.ch.characters(ch, start, length);
|
||||
}
|
||||
}
|
||||
|
||||
public void endDocument()
|
||||
throws SAXException {
|
||||
if (ch != null) {
|
||||
ch.endDocument();
|
||||
}
|
||||
}
|
||||
|
||||
public void endElement(String namespaceURI, String localName, String qName)
|
||||
throws SAXException {
|
||||
if (ch != null) {
|
||||
ch.endElement(namespaceURI, localName, qName);
|
||||
}
|
||||
}
|
||||
|
||||
public void endPrefixMapping(String prefix)
|
||||
throws SAXException {
|
||||
if (ch != null) {
|
||||
ch.endPrefixMapping(prefix);
|
||||
}
|
||||
}
|
||||
|
||||
public void ignorableWhitespace(char[] ch, int start, int length)
|
||||
throws SAXException {
|
||||
if (this.ch != null) {
|
||||
this.ch.ignorableWhitespace(ch, start, length);
|
||||
}
|
||||
}
|
||||
|
||||
public void processingInstruction(String target, String data)
|
||||
throws SAXException {
|
||||
if (ch != null) {
|
||||
ch.processingInstruction(target, data);
|
||||
}
|
||||
}
|
||||
|
||||
public void setDocumentLocator(Locator locator) {
|
||||
if (ch != null) {
|
||||
ch.setDocumentLocator(locator);
|
||||
}
|
||||
}
|
||||
|
||||
public void skippedEntity(String name)
|
||||
throws SAXException {
|
||||
if (ch != null) {
|
||||
ch.skippedEntity(name);
|
||||
}
|
||||
}
|
||||
|
||||
public void startDocument()
|
||||
throws SAXException {
|
||||
if (ch != null) {
|
||||
ch.startDocument();
|
||||
}
|
||||
}
|
||||
|
||||
public void startElement(String namespaceURI, String localName,
|
||||
String qName, Attributes atts)
|
||||
throws SAXException {
|
||||
if (ch != null) {
|
||||
ch.startElement(namespaceURI, localName, qName, atts);
|
||||
}
|
||||
}
|
||||
|
||||
public void startPrefixMapping(String prefix, String uri)
|
||||
throws SAXException {
|
||||
if (ch != null) {
|
||||
ch.startPrefixMapping(prefix, uri);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
// TR9401CatalogReader.java - Read OASIS Catalog files
|
||||
|
||||
/*
|
||||
* The Apache Software License, Version 1.1
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2001 The Apache Software Foundation. All rights
|
||||
* reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The end-user documentation included with the redistribution,
|
||||
* if any, must include the following acknowledgment:
|
||||
* "This product includes software developed by the
|
||||
* Apache Software Foundation (http://www.apache.org/)."
|
||||
* Alternately, this acknowledgment may appear in the software itself,
|
||||
* if and wherever such third-party acknowledgments normally appear.
|
||||
*
|
||||
* 4. The names "Xalan" and "Apache Software Foundation" must
|
||||
* not be used to endorse or promote products derived from this
|
||||
* software without prior written permission. For written
|
||||
* permission, please contact apache@apache.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "Apache",
|
||||
* nor may "Apache" appear in their name, without prior written
|
||||
* permission of the Apache Software Foundation.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation and was
|
||||
* originally based on software copyright (c) 2001, International
|
||||
* Business Machines Corporation., http://www.ibm.com. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*/
|
||||
|
||||
package org.apache.xml.resolver.readers;
|
||||
|
||||
import java.lang.Integer;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.Vector;
|
||||
import java.util.Stack;
|
||||
import org.apache.xml.resolver.Catalog;
|
||||
import org.apache.xml.resolver.CatalogEntry;
|
||||
import org.apache.xml.resolver.CatalogException;
|
||||
import org.apache.xml.resolver.readers.CatalogReader;
|
||||
import org.apache.xml.resolver.helpers.Debug;
|
||||
import org.apache.xml.resolver.helpers.PublicId;
|
||||
|
||||
/**
|
||||
* <p>Parses OASIS Open Catalog files.</p>
|
||||
*
|
||||
* <p>This class reads OASIS Open Catalog files, returning a stream
|
||||
* of tokens.</p>
|
||||
*
|
||||
* <p>This code interrogates the following non-standard system properties:</p>
|
||||
*
|
||||
* <dl>
|
||||
* <dt><b>xml.catalog.debug</b></dt>
|
||||
* <dd><p>Sets the debug level. A value of 0 is assumed if the
|
||||
* property is not set or is not a number.</p></dd>
|
||||
* </dl>
|
||||
*
|
||||
* @see Catalog
|
||||
*
|
||||
* @author Norman Walsh
|
||||
* <a href="mailto:Norman.Walsh@Sun.COM">Norman.Walsh@Sun.COM</a>
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
public class TR9401CatalogReader extends TextCatalogReader {
|
||||
|
||||
/**
|
||||
* <p>Start parsing an OASIS TR9401 Open Catalog file. The file is
|
||||
* actually read and parsed
|
||||
* as needed by <code>nextEntry</code>.</p>
|
||||
*
|
||||
* <p>In a TR9401 Catalog the 'DELEGATE' entry delegates public
|
||||
* identifiers. There is no delegate entry for system identifiers
|
||||
* or URIs.</p>
|
||||
*
|
||||
* @param fileUrl The URL or filename of the catalog file to process
|
||||
*
|
||||
* @throws MalformedURLException Improper fileUrl
|
||||
* @throws IOException Error reading catalog file
|
||||
*/
|
||||
public void readCatalog(Catalog catalog, InputStream is)
|
||||
throws MalformedURLException, IOException {
|
||||
|
||||
catfile = is;
|
||||
|
||||
if (catfile == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Vector unknownEntry = null;
|
||||
|
||||
while (true) {
|
||||
String token = nextToken();
|
||||
|
||||
if (token == null) {
|
||||
if (unknownEntry != null) {
|
||||
catalog.unknownEntry(unknownEntry);
|
||||
unknownEntry = null;
|
||||
}
|
||||
catfile.close();
|
||||
catfile = null;
|
||||
return;
|
||||
}
|
||||
|
||||
String entryToken = null;
|
||||
if (caseSensitive) {
|
||||
entryToken = token;
|
||||
} else {
|
||||
entryToken = token.toUpperCase();
|
||||
}
|
||||
|
||||
if (entryToken.equals("DELEGATE")) {
|
||||
entryToken = "DELEGATE_PUBLIC";
|
||||
}
|
||||
|
||||
try {
|
||||
int type = CatalogEntry.getEntryType(entryToken);
|
||||
int numArgs = CatalogEntry.getEntryArgCount(type);
|
||||
Vector args = new Vector();
|
||||
|
||||
if (unknownEntry != null) {
|
||||
catalog.unknownEntry(unknownEntry);
|
||||
unknownEntry = null;
|
||||
}
|
||||
|
||||
for (int count = 0; count < numArgs; count++) {
|
||||
args.addElement(nextToken());
|
||||
}
|
||||
|
||||
catalog.addEntry(new CatalogEntry(entryToken, args));
|
||||
} catch (CatalogException cex) {
|
||||
if (cex.getExceptionType() == CatalogException.INVALID_ENTRY_TYPE) {
|
||||
if (unknownEntry == null) {
|
||||
unknownEntry = new Vector();
|
||||
}
|
||||
unknownEntry.addElement(token);
|
||||
} else if (cex.getExceptionType() == CatalogException.INVALID_ENTRY) {
|
||||
Debug.message(1, "Invalid catalog entry", token);
|
||||
unknownEntry = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,328 @@
|
||||
// TextCatalogReader.java - Read text/plain Catalog files
|
||||
|
||||
/*
|
||||
* The Apache Software License, Version 1.1
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2001 The Apache Software Foundation. All rights
|
||||
* reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The end-user documentation included with the redistribution,
|
||||
* if any, must include the following acknowledgment:
|
||||
* "This product includes software developed by the
|
||||
* Apache Software Foundation (http://www.apache.org/)."
|
||||
* Alternately, this acknowledgment may appear in the software itself,
|
||||
* if and wherever such third-party acknowledgments normally appear.
|
||||
*
|
||||
* 4. The names "Xalan" and "Apache Software Foundation" must
|
||||
* not be used to endorse or promote products derived from this
|
||||
* software without prior written permission. For written
|
||||
* permission, please contact apache@apache.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "Apache",
|
||||
* nor may "Apache" appear in their name, without prior written
|
||||
* permission of the Apache Software Foundation.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation and was
|
||||
* originally based on software copyright (c) 2001, International
|
||||
* Business Machines Corporation., http://www.ibm.com. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*/
|
||||
|
||||
package org.apache.xml.resolver.readers;
|
||||
|
||||
import java.lang.Integer;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.Vector;
|
||||
import java.util.Stack;
|
||||
import org.apache.xml.resolver.Catalog;
|
||||
import org.apache.xml.resolver.CatalogEntry;
|
||||
import org.apache.xml.resolver.CatalogException;
|
||||
import org.apache.xml.resolver.readers.CatalogReader;
|
||||
import org.apache.xml.resolver.helpers.Debug;
|
||||
import org.apache.xml.resolver.helpers.PublicId;
|
||||
|
||||
/**
|
||||
* <p>Parses plain text Catalog files.</p>
|
||||
*
|
||||
* <p>This class reads plain text Open Catalog files.</p>
|
||||
*
|
||||
* @see Catalog
|
||||
*
|
||||
* @author Norman Walsh
|
||||
* <a href="mailto:Norman.Walsh@Sun.COM">Norman.Walsh@Sun.COM</a>
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
public class TextCatalogReader implements CatalogReader {
|
||||
/** The input stream used to read the catalog */
|
||||
protected InputStream catfile = null;
|
||||
|
||||
/**
|
||||
* Character lookahead stack. Reading a catalog sometimes requires
|
||||
* up to two characters of lookahead.
|
||||
*/
|
||||
protected int[] stack = new int[3];
|
||||
|
||||
/**
|
||||
* Token stack. Recognizing an unexpected catalog entry requires
|
||||
* the ability to "push back" a token.
|
||||
*/
|
||||
protected Stack tokenStack = new Stack();
|
||||
|
||||
/** The current position on the lookahead stack */
|
||||
protected int top = -1;
|
||||
|
||||
/** Are keywords in the catalog case sensitive? */
|
||||
protected boolean caseSensitive = false;
|
||||
|
||||
/**
|
||||
* <p>Construct a CatalogReader object.</p>
|
||||
*/
|
||||
public TextCatalogReader() { }
|
||||
|
||||
public void setCaseSensitive(boolean isCaseSensitive) {
|
||||
caseSensitive = isCaseSensitive;
|
||||
}
|
||||
|
||||
public boolean getCaseSensitive() {
|
||||
return caseSensitive;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Start parsing a text catalog file. The file is
|
||||
* actually read and parsed
|
||||
* as needed by <code>nextEntry</code>.</p>
|
||||
*
|
||||
* @param fileUrl The URL or filename of the catalog file to process
|
||||
*
|
||||
* @throws MalformedURLException Improper fileUrl
|
||||
* @throws IOException Error reading catalog file
|
||||
*/
|
||||
public void readCatalog(Catalog catalog, String fileUrl)
|
||||
throws MalformedURLException, IOException {
|
||||
URL catURL = null;
|
||||
|
||||
try {
|
||||
catURL = new URL(fileUrl);
|
||||
} catch (MalformedURLException e) {
|
||||
catURL = new URL("file:///" + fileUrl);
|
||||
}
|
||||
|
||||
URLConnection urlCon = catURL.openConnection();
|
||||
try {
|
||||
readCatalog(catalog, urlCon.getInputStream());
|
||||
} catch (FileNotFoundException e) {
|
||||
Debug.message(1, "Failed to load catalog, file not found",
|
||||
catURL.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public void readCatalog(Catalog catalog, InputStream is)
|
||||
throws MalformedURLException, IOException {
|
||||
|
||||
catfile = is;
|
||||
|
||||
if (catfile == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Vector unknownEntry = null;
|
||||
|
||||
while (true) {
|
||||
String token = nextToken();
|
||||
|
||||
if (token == null) {
|
||||
if (unknownEntry != null) {
|
||||
catalog.unknownEntry(unknownEntry);
|
||||
unknownEntry = null;
|
||||
}
|
||||
catfile.close();
|
||||
catfile = null;
|
||||
return;
|
||||
}
|
||||
|
||||
String entryToken = null;
|
||||
if (caseSensitive) {
|
||||
entryToken = token;
|
||||
} else {
|
||||
entryToken = token.toUpperCase();
|
||||
}
|
||||
|
||||
try {
|
||||
int type = CatalogEntry.getEntryType(entryToken);
|
||||
int numArgs = CatalogEntry.getEntryArgCount(type);
|
||||
Vector args = new Vector();
|
||||
|
||||
if (unknownEntry != null) {
|
||||
catalog.unknownEntry(unknownEntry);
|
||||
unknownEntry = null;
|
||||
}
|
||||
|
||||
for (int count = 0; count < numArgs; count++) {
|
||||
args.addElement(nextToken());
|
||||
}
|
||||
|
||||
catalog.addEntry(new CatalogEntry(entryToken, args));
|
||||
} catch (CatalogException cex) {
|
||||
if (cex.getExceptionType() == CatalogException.INVALID_ENTRY_TYPE) {
|
||||
if (unknownEntry == null) {
|
||||
unknownEntry = new Vector();
|
||||
}
|
||||
unknownEntry.addElement(token);
|
||||
} else if (cex.getExceptionType() == CatalogException.INVALID_ENTRY) {
|
||||
Debug.message(1, "Invalid catalog entry", token);
|
||||
unknownEntry = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>The destructor.</p>
|
||||
*
|
||||
* <p>Makes sure the catalog file is closed.</p>
|
||||
*/
|
||||
protected void finalize() {
|
||||
if (catfile != null) {
|
||||
try {
|
||||
catfile.close();
|
||||
} catch (IOException e) {
|
||||
// whatever...
|
||||
}
|
||||
}
|
||||
catfile = null;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* <p>Return the next token in the catalog file.</p>
|
||||
*
|
||||
* @return The Catalog file token from the input stream.
|
||||
* @throws IOException If an error occurs reading from the stream.
|
||||
*/
|
||||
protected String nextToken() throws IOException {
|
||||
String token = "";
|
||||
int ch, nextch;
|
||||
|
||||
if (!tokenStack.empty()) {
|
||||
return (String) tokenStack.pop();
|
||||
}
|
||||
|
||||
// Skip over leading whitespace and comments
|
||||
while (true) {
|
||||
// skip leading whitespace
|
||||
ch = catfile.read();
|
||||
while (ch <= ' ') { // all ctrls are whitespace
|
||||
ch = catfile.read();
|
||||
if (ch < 0) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// now 'ch' is the current char from the file
|
||||
nextch = catfile.read();
|
||||
if (nextch < 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (ch == '-' && nextch == '-') {
|
||||
// we've found a comment, skip it...
|
||||
ch = ' ';
|
||||
nextch = nextChar();
|
||||
while (ch != '-' || nextch != '-') {
|
||||
ch = nextch;
|
||||
nextch = nextChar();
|
||||
}
|
||||
|
||||
// Ok, we've found the end of the comment,
|
||||
// loop back to the top and start again...
|
||||
} else {
|
||||
stack[++top] = nextch;
|
||||
stack[++top] = ch;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ch = nextChar();
|
||||
if (ch == '"' || ch == '\'') {
|
||||
int quote = ch;
|
||||
while ((ch = nextChar()) != quote) {
|
||||
char[] chararr = new char[1];
|
||||
chararr[0] = (char) ch;
|
||||
String s = new String(chararr);
|
||||
token = token.concat(s);
|
||||
}
|
||||
return token;
|
||||
} else {
|
||||
// return the next whitespace or comment delimited
|
||||
// string
|
||||
while (ch > ' ') {
|
||||
nextch = nextChar();
|
||||
if (ch == '-' && nextch == '-') {
|
||||
stack[++top] = ch;
|
||||
stack[++top] = nextch;
|
||||
return token;
|
||||
} else {
|
||||
char[] chararr = new char[1];
|
||||
chararr[0] = (char) ch;
|
||||
String s = new String(chararr);
|
||||
token = token.concat(s);
|
||||
ch = nextch;
|
||||
}
|
||||
}
|
||||
return token;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Return the next logical character from the input stream.</p>
|
||||
*
|
||||
* @return The next (logical) character from the input stream. The
|
||||
* character may be buffered from a previous lookahead.
|
||||
*
|
||||
* @throws IOException If an error occurs reading from the stream.
|
||||
*/
|
||||
protected int nextChar() throws IOException {
|
||||
if (top < 0) {
|
||||
return catfile.read();
|
||||
} else {
|
||||
return stack[top--];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,234 @@
|
||||
// XCatalogReader.java - Read XML Catalog files
|
||||
|
||||
/*
|
||||
* The Apache Software License, Version 1.1
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2001 The Apache Software Foundation. All rights
|
||||
* reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The end-user documentation included with the redistribution,
|
||||
* if any, must include the following acknowledgment:
|
||||
* "This product includes software developed by the
|
||||
* Apache Software Foundation (http://www.apache.org/)."
|
||||
* Alternately, this acknowledgment may appear in the software itself,
|
||||
* if and wherever such third-party acknowledgments normally appear.
|
||||
*
|
||||
* 4. The names "Xalan" and "Apache Software Foundation" must
|
||||
* not be used to endorse or promote products derived from this
|
||||
* software without prior written permission. For written
|
||||
* permission, please contact apache@apache.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "Apache",
|
||||
* nor may "Apache" appear in their name, without prior written
|
||||
* permission of the Apache Software Foundation.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation and was
|
||||
* originally based on software copyright (c) 2001, International
|
||||
* Business Machines Corporation., http://www.ibm.com. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*/
|
||||
|
||||
package org.apache.xml.resolver.readers;
|
||||
|
||||
import java.lang.Integer;
|
||||
import java.util.Vector;
|
||||
import java.util.Enumeration;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import org.apache.xml.resolver.Catalog;
|
||||
import org.apache.xml.resolver.CatalogEntry;
|
||||
import org.apache.xml.resolver.CatalogException;
|
||||
import org.apache.xml.resolver.readers.CatalogReader;
|
||||
import org.apache.xml.resolver.helpers.PublicId;
|
||||
import org.apache.xml.resolver.helpers.Debug;
|
||||
|
||||
import org.xml.sax.*;
|
||||
|
||||
import javax.xml.parsers.*;
|
||||
|
||||
/**
|
||||
* <p>Parse "xcatalog" XML Catalog files, this is the XML Catalog format
|
||||
* developed by John Cowan and supported by Apache.</p>
|
||||
*
|
||||
* @see Catalog
|
||||
*
|
||||
* @author Norman Walsh
|
||||
* <a href="mailto:Norman.Walsh@Sun.COM">Norman.Walsh@Sun.COM</a>
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
public class XCatalogReader extends SAXCatalogReader implements SAXCatalogParser {
|
||||
/** The catalog object needs to be stored by the object so that
|
||||
* SAX callbacks can use it.
|
||||
*/
|
||||
protected Catalog catalog = null;
|
||||
|
||||
/** Set the current catalog. */
|
||||
public void setCatalog (Catalog catalog) {
|
||||
this.catalog = catalog;
|
||||
}
|
||||
|
||||
/** Get the current catalog. */
|
||||
public Catalog getCatalog () {
|
||||
return catalog;
|
||||
}
|
||||
|
||||
/** The constructor */
|
||||
public XCatalogReader(SAXParserFactory parserFactory) {
|
||||
super(parserFactory);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Implement the SAX DocumentHandler interface
|
||||
|
||||
/** <p>The SAX <code>setDocumentLocator</code> method does nothing.</p> */
|
||||
public void setDocumentLocator (Locator locator) {
|
||||
return;
|
||||
}
|
||||
|
||||
/** <p>The SAX <code>startDocument</code> method does nothing.</p> */
|
||||
public void startDocument ()
|
||||
throws SAXException {
|
||||
return;
|
||||
}
|
||||
|
||||
/** <p>The SAX <code>endDocument</code> method does nothing.</p> */
|
||||
public void endDocument ()
|
||||
throws SAXException {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>The SAX <code>startElement</code> method recognizes elements
|
||||
* from the plain catalog format and instantiates CatalogEntry
|
||||
* objects for them.</p>
|
||||
*
|
||||
* @param namespaceURI The namespace name of the element.
|
||||
* @param localName The local name of the element.
|
||||
* @param qName The QName of the element.
|
||||
* @param atts The list of attributes on the element.
|
||||
*
|
||||
* @see CatalogEntry
|
||||
*/
|
||||
public void startElement (String namespaceURI,
|
||||
String localName,
|
||||
String qName,
|
||||
Attributes atts)
|
||||
throws SAXException {
|
||||
|
||||
int entryType = -1;
|
||||
Vector entryArgs = new Vector();
|
||||
|
||||
if (localName.equals("Base")) {
|
||||
entryType = catalog.BASE;
|
||||
entryArgs.add(atts.getValue("HRef"));
|
||||
|
||||
Debug.message(4, "Base", atts.getValue("HRef"));
|
||||
} else if (localName.equals("Delegate")) {
|
||||
entryType = catalog.DELEGATE_PUBLIC;
|
||||
entryArgs.add(atts.getValue("PublicId"));
|
||||
entryArgs.add(atts.getValue("HRef"));
|
||||
|
||||
Debug.message(4, "Delegate",
|
||||
PublicId.normalize(atts.getValue("PublicId")),
|
||||
atts.getValue("HRef"));
|
||||
} else if (localName.equals("Extend")) {
|
||||
entryType = catalog.CATALOG;
|
||||
entryArgs.add(atts.getValue("HRef"));
|
||||
|
||||
Debug.message(4, "Extend", atts.getValue("HRef"));
|
||||
} else if (localName.equals("Map")) {
|
||||
entryType = catalog.PUBLIC;
|
||||
entryArgs.add(atts.getValue("PublicId"));
|
||||
entryArgs.add(atts.getValue("HRef"));
|
||||
|
||||
Debug.message(4, "Map",
|
||||
PublicId.normalize(atts.getValue("PublicId")),
|
||||
atts.getValue("HRef"));
|
||||
} else if (localName.equals("Remap")) {
|
||||
entryType = catalog.SYSTEM;
|
||||
entryArgs.add(atts.getValue("SystemId"));
|
||||
entryArgs.add(atts.getValue("HRef"));
|
||||
|
||||
Debug.message(4, "Remap",
|
||||
atts.getValue("SystemId"),
|
||||
atts.getValue("HRef"));
|
||||
} else if (localName.equals("XMLCatalog")) {
|
||||
// nop, start of catalog
|
||||
} else {
|
||||
// This is equivalent to an invalid catalog entry type
|
||||
Debug.message(1, "Invalid catalog entry type", localName);
|
||||
}
|
||||
|
||||
if (entryType >= 0) {
|
||||
try {
|
||||
CatalogEntry ce = new CatalogEntry(entryType, entryArgs);
|
||||
catalog.addEntry(ce);
|
||||
} catch (CatalogException cex) {
|
||||
if (cex.getExceptionType() == CatalogException.INVALID_ENTRY_TYPE) {
|
||||
Debug.message(1, "Invalid catalog entry type", localName);
|
||||
} else if (cex.getExceptionType() == CatalogException.INVALID_ENTRY) {
|
||||
Debug.message(1, "Invalid catalog entry", localName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** <p>The SAX <code>endElement</code> method does nothing.</p> */
|
||||
public void endElement (String namespaceURI,
|
||||
String localName,
|
||||
String qName)
|
||||
throws SAXException {
|
||||
return;
|
||||
}
|
||||
|
||||
/** <p>The SAX <code>characters</code> method does nothing.</p> */
|
||||
public void characters (char ch[], int start, int length)
|
||||
throws SAXException {
|
||||
return;
|
||||
}
|
||||
|
||||
/** <p>The SAX <code>ignorableWhitespace</code> method does nothing.</p> */
|
||||
public void ignorableWhitespace (char ch[], int start, int length)
|
||||
throws SAXException {
|
||||
return;
|
||||
}
|
||||
|
||||
/** <p>The SAX <code>processingInstruction</code> method does nothing.</p> */
|
||||
public void processingInstruction (String target, String data)
|
||||
throws SAXException {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Apache XML Commons Resolver Readers package</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>Apache XML Commons Resolver Readers package</p>
|
||||
|
||||
<p>This package provides the set of classes that read catalog files
|
||||
and extract catalog entries from them.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,371 @@
|
||||
// CatalogResolver.java - A SAX EntityResolver/JAXP URI Resolver
|
||||
|
||||
/*
|
||||
* The Apache Software License, Version 1.1
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2001 The Apache Software Foundation. All rights
|
||||
* reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The end-user documentation included with the redistribution,
|
||||
* if any, must include the following acknowledgment:
|
||||
* "This product includes software developed by the
|
||||
* Apache Software Foundation (http://www.apache.org/)."
|
||||
* Alternately, this acknowledgment may appear in the software itself,
|
||||
* if and wherever such third-party acknowledgments normally appear.
|
||||
*
|
||||
* 4. The names "Xalan" and "Apache Software Foundation" must
|
||||
* not be used to endorse or promote products derived from this
|
||||
* software without prior written permission. For written
|
||||
* permission, please contact apache@apache.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "Apache",
|
||||
* nor may "Apache" appear in their name, without prior written
|
||||
* permission of the Apache Software Foundation.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation and was
|
||||
* originally based on software copyright (c) 2001, International
|
||||
* Business Machines Corporation., http://www.ibm.com. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*/
|
||||
|
||||
package org.apache.xml.resolver.tools;
|
||||
|
||||
import java.lang.ClassNotFoundException;
|
||||
import java.lang.ClassCastException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.net.MalformedURLException;
|
||||
|
||||
import org.xml.sax.*;
|
||||
import org.xml.sax.helpers.*;
|
||||
|
||||
import javax.xml.parsers.*;
|
||||
import javax.xml.transform.*;
|
||||
import javax.xml.transform.sax.SAXSource;
|
||||
|
||||
import org.apache.xml.resolver.Catalog;
|
||||
import org.apache.xml.resolver.CatalogManager;
|
||||
import org.apache.xml.resolver.helpers.Debug;
|
||||
|
||||
/**
|
||||
* <p>A SAX EntityResolver/JAXP URIResolver that uses catalogs.</p>
|
||||
*
|
||||
* <p>This class implements both a SAX EntityResolver and a JAXP URIResolver.
|
||||
* </p>
|
||||
*
|
||||
* <p>This resolver understands OASIS TR9401 catalogs, XCatalogs, and the
|
||||
* current working draft of the OASIS Entity Resolution Technical
|
||||
* Committee specification.</p>
|
||||
*
|
||||
* @see Catalog
|
||||
* @see org.xml.sax.EntityResolver
|
||||
* @see javax.xml.transform.URIResolver
|
||||
*
|
||||
* @author Norman Walsh
|
||||
* <a href="mailto:Norman.Walsh@Sun.COM">Norman.Walsh@Sun.COM</a>
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
public class CatalogResolver implements EntityResolver, URIResolver {
|
||||
/** Make the parser Namespace aware? */
|
||||
public boolean namespaceAware = true;
|
||||
|
||||
/** Make the parser validating? */
|
||||
public boolean validating = false;
|
||||
|
||||
/** The underlying catalog */
|
||||
private static Catalog staticCatalog = null;
|
||||
private Catalog catalog = null;
|
||||
|
||||
/** Constructor */
|
||||
public CatalogResolver() {
|
||||
initializeCatalogs(false);
|
||||
}
|
||||
|
||||
/** Constructor */
|
||||
public CatalogResolver(boolean privateCatalog) {
|
||||
initializeCatalogs(privateCatalog);
|
||||
}
|
||||
|
||||
/** Initialize catalog */
|
||||
private void initializeCatalogs(boolean privateCatalog) {
|
||||
catalog = staticCatalog;
|
||||
|
||||
if (privateCatalog || catalog == null) {
|
||||
try {
|
||||
String catalogClassName = CatalogManager.catalogClassName();
|
||||
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.setupReaders();
|
||||
|
||||
if (!privateCatalog) {
|
||||
catalog.loadSystemCatalogs();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (!privateCatalog && catalog != null && CatalogManager.staticCatalog()) {
|
||||
staticCatalog = catalog;
|
||||
}
|
||||
}
|
||||
|
||||
/** Return the underlying catalog */
|
||||
public Catalog getCatalog() {
|
||||
return catalog;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Implements the guts of the <code>resolveEntity</code> method
|
||||
* for the SAX interface.</p>
|
||||
*
|
||||
* <p>Presented with an optional public identifier and a system
|
||||
* identifier, this function attempts to locate a mapping in the
|
||||
* catalogs.</p>
|
||||
*
|
||||
* <p>If such a mapping is found, it is returned. If no mapping is
|
||||
* found, null is returned.</p>
|
||||
*
|
||||
* @param publicId The public identifier for the entity in question.
|
||||
* This may be null.
|
||||
*
|
||||
* @param systemId The system identifier for the entity in question.
|
||||
* XML requires a system identifier on all external entities, so this
|
||||
* value is always specified.
|
||||
*
|
||||
* @return The resolved identifier (a URI reference).
|
||||
*/
|
||||
public String getResolvedEntity (String publicId, String systemId) {
|
||||
String resolved = null;
|
||||
|
||||
if (catalog == null) {
|
||||
Debug.message(1, "Catalog resolution attempted with null catalog; ignored");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (systemId != null) {
|
||||
try {
|
||||
resolved = catalog.resolveSystem(systemId);
|
||||
} catch (MalformedURLException me) {
|
||||
Debug.message(1, "Malformed URL exception trying to resolve",
|
||||
publicId);
|
||||
resolved = null;
|
||||
} catch (IOException ie) {
|
||||
Debug.message(1, "I/O exception trying to resolve", publicId);
|
||||
resolved = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (resolved == null) {
|
||||
if (publicId != null) {
|
||||
try {
|
||||
resolved = catalog.resolvePublic(publicId, systemId);
|
||||
} catch (MalformedURLException me) {
|
||||
Debug.message(1, "Malformed URL exception trying to resolve",
|
||||
publicId);
|
||||
} catch (IOException ie) {
|
||||
Debug.message(1, "I/O exception trying to resolve", publicId);
|
||||
}
|
||||
}
|
||||
|
||||
if (resolved != null) {
|
||||
Debug.message(2, "Resolved public", publicId, resolved);
|
||||
}
|
||||
} else {
|
||||
Debug.message(2, "Resolved system", systemId, resolved);
|
||||
}
|
||||
|
||||
return resolved;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Implements the <code>resolveEntity</code> method
|
||||
* for the SAX interface.</p>
|
||||
*
|
||||
* <p>Presented with an optional public identifier and a system
|
||||
* identifier, this function attempts to locate a mapping in the
|
||||
* catalogs.</p>
|
||||
*
|
||||
* <p>If such a mapping is found, the resolver attempts to open
|
||||
* the mapped value as an InputSource and return it. Exceptions are
|
||||
* ignored and null is returned if the mapped value cannot be opened
|
||||
* as an input source.</p>
|
||||
*
|
||||
* <p>If no mapping is found (or an error occurs attempting to open
|
||||
* the mapped value as an input source), null is returned and the system
|
||||
* will use the specified system identifier as if no entityResolver
|
||||
* was specified.</p>
|
||||
*
|
||||
* @param publicId The public identifier for the entity in question.
|
||||
* This may be null.
|
||||
*
|
||||
* @param systemId The system identifier for the entity in question.
|
||||
* XML requires a system identifier on all external entities, so this
|
||||
* value is always specified.
|
||||
*
|
||||
* @return An InputSource for the mapped identifier, or null.
|
||||
*/
|
||||
public InputSource resolveEntity (String publicId, String systemId) {
|
||||
String resolved = getResolvedEntity(publicId, systemId);
|
||||
|
||||
if (resolved != null) {
|
||||
try {
|
||||
InputSource iSource = new InputSource(resolved);
|
||||
iSource.setPublicId(publicId);
|
||||
|
||||
// Ideally this method would not attempt to open the
|
||||
// InputStream, but there is a bug (in Xerces, at least)
|
||||
// that causes the parser to mistakenly open the wrong
|
||||
// system identifier if the returned InputSource does
|
||||
// not have a byteStream.
|
||||
//
|
||||
// It could be argued that we still shouldn't do this here,
|
||||
// but since the purpose of calling the entityResolver is
|
||||
// almost certainly to open the input stream, it seems to
|
||||
// do little harm.
|
||||
//
|
||||
URL url = new URL(resolved);
|
||||
InputStream iStream = url.openStream();
|
||||
iSource.setByteStream(iStream);
|
||||
|
||||
return iSource;
|
||||
} catch (Exception e) {
|
||||
Debug.message(1, "Failed to create InputSource", resolved);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/** JAXP URIResolver API */
|
||||
public Source resolve(String href, String base)
|
||||
throws TransformerException {
|
||||
|
||||
String uri = href;
|
||||
String fragment = null;
|
||||
int hashPos = href.indexOf("#");
|
||||
if (hashPos >= 0) {
|
||||
uri = href.substring(0, hashPos);
|
||||
fragment = href.substring(hashPos+1);
|
||||
}
|
||||
|
||||
String result = null;
|
||||
|
||||
try {
|
||||
result = catalog.resolveURI(href);
|
||||
} catch (Exception e) {
|
||||
// nop;
|
||||
}
|
||||
|
||||
if (result == null) {
|
||||
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) {
|
||||
// try to make an absolute URI from the current base
|
||||
String absBase = makeAbsolute(base);
|
||||
if (!absBase.equals(base)) {
|
||||
// don't bother if the absBase isn't different!
|
||||
return resolve(href, absBase);
|
||||
} else {
|
||||
throw new TransformerException("Malformed URL "
|
||||
+ href + "(base " + base + ")",
|
||||
mue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if (!href.equals(result)) {
|
||||
Debug.message(2, "Resolved URI", href, result);
|
||||
// }
|
||||
|
||||
SAXSource source = new SAXSource();
|
||||
source.setInputSource(new InputSource(result));
|
||||
return source;
|
||||
}
|
||||
|
||||
/** Attempt to construct an absolute URI */
|
||||
private String makeAbsolute(String uri) {
|
||||
if (uri == null) {
|
||||
uri = "";
|
||||
}
|
||||
|
||||
try {
|
||||
URL url = new URL(uri);
|
||||
return url.toString();
|
||||
} catch (MalformedURLException mue) {
|
||||
String dir = System.getProperty("user.dir");
|
||||
String file = "";
|
||||
|
||||
if (dir.endsWith("/")) {
|
||||
file = "file://" + dir + uri;
|
||||
} else {
|
||||
file = "file://" + dir + "/" + uri;
|
||||
}
|
||||
|
||||
try {
|
||||
URL fileURL = new URL(file);
|
||||
return fileURL.toString();
|
||||
} catch (MalformedURLException mue2) {
|
||||
// bail
|
||||
return uri;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,459 @@
|
||||
// ResolvingParser.java - An interface for reading catalog files
|
||||
|
||||
/*
|
||||
* The Apache Software License, Version 1.1
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2001 The Apache Software Foundation. All rights
|
||||
* reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The end-user documentation included with the redistribution,
|
||||
* if any, must include the following acknowledgment:
|
||||
* "This product includes software developed by the
|
||||
* Apache Software Foundation (http://www.apache.org/)."
|
||||
* Alternately, this acknowledgment may appear in the software itself,
|
||||
* if and wherever such third-party acknowledgments normally appear.
|
||||
*
|
||||
* 4. The names "Xalan" and "Apache Software Foundation" must
|
||||
* not be used to endorse or promote products derived from this
|
||||
* software without prior written permission. For written
|
||||
* permission, please contact apache@apache.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "Apache",
|
||||
* nor may "Apache" appear in their name, without prior written
|
||||
* permission of the Apache Software Foundation.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation and was
|
||||
* originally based on software copyright (c) 2001, International
|
||||
* Business Machines Corporation., http://www.ibm.com. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*/
|
||||
|
||||
package org.apache.xml.resolver.tools;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.xml.sax.*;
|
||||
|
||||
import javax.xml.parsers.*;
|
||||
|
||||
import org.apache.xml.resolver.Catalog;
|
||||
import org.apache.xml.resolver.CatalogManager;
|
||||
import org.apache.xml.resolver.helpers.Debug;
|
||||
|
||||
/**
|
||||
* <p>A SAX Parser that performs catalog-based entity resolution.</p>
|
||||
*
|
||||
* <p>This class implements a SAX Parser that performs entity resolution
|
||||
* using the CatalogResolver. The actual, underlying parser is obtained
|
||||
* from a SAXParserFactory.</p>
|
||||
* </p>
|
||||
*
|
||||
* @deprecated This interface has been replaced by the
|
||||
* {@link org.apache.xml.resolver.tools.ResolvingXMLReader} for SAX2.
|
||||
* @see CatalogResolver
|
||||
* @see org.xml.sax.Parser
|
||||
*
|
||||
* @author Norman Walsh
|
||||
* <a href="mailto:Norman.Walsh@Sun.COM">Norman.Walsh@Sun.COM</a>
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
public class ResolvingParser
|
||||
implements Parser, DTDHandler, DocumentHandler, EntityResolver {
|
||||
/** Make the parser Namespace aware? */
|
||||
public static boolean namespaceAware = true;
|
||||
|
||||
/** Make the parser validating? */
|
||||
public static boolean validating = false;
|
||||
|
||||
/** Suppress explanatory message?
|
||||
*
|
||||
* @see #parse(InputSource)
|
||||
*/
|
||||
public static boolean suppressExplanation = false;
|
||||
|
||||
/** The underlying parser */
|
||||
private SAXParser saxParser = null;
|
||||
|
||||
/** The underlying reader */
|
||||
private Parser parser = null;
|
||||
|
||||
/** The underlying DocumentHandler */
|
||||
private DocumentHandler documentHandler = null;
|
||||
|
||||
/** The underlying DTDHandler */
|
||||
private DTDHandler dtdHandler = null;
|
||||
|
||||
/** The underlying catalog resolver */
|
||||
private CatalogResolver catalogResolver = new CatalogResolver();
|
||||
|
||||
/** A separate resolver for oasis-xml-pi catalogs */
|
||||
private CatalogResolver piCatalogResolver = null;
|
||||
|
||||
/** Are we in the prolog? Is an oasis-xml-catalog PI valid now? */
|
||||
private boolean allowXMLCatalogPI = false;
|
||||
|
||||
/** Has an oasis-xml-catalog PI been seen? */
|
||||
private boolean oasisXMLCatalogPI = false;
|
||||
|
||||
/** The base URI of the input document, if known. */
|
||||
private URL baseURL = null;
|
||||
|
||||
/** Constructor */
|
||||
public ResolvingParser() {
|
||||
SAXParserFactory spf = SAXParserFactory.newInstance();
|
||||
spf.setNamespaceAware(namespaceAware);
|
||||
spf.setValidating(validating);
|
||||
|
||||
try {
|
||||
saxParser = spf.newSAXParser();
|
||||
parser = saxParser.getParser();
|
||||
documentHandler = null;
|
||||
dtdHandler = null;
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/** Return the Catalog being used */
|
||||
public Catalog getCatalog() {
|
||||
return catalogResolver.getCatalog();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>SAX Parser API</p>
|
||||
*
|
||||
* <p>Note that the JAXP 1.1ea2 parser crashes with an InternalError if
|
||||
* it encounters a system identifier that appears to be a relative URI
|
||||
* that begins with a slash. For example, the declaration:</p>
|
||||
*
|
||||
* <pre>
|
||||
* <!DOCTYPE book SYSTEM "/path/to/dtd/on/my/system/docbookx.dtd">
|
||||
* </pre>
|
||||
*
|
||||
* <p>would cause such an error. As a convenience, this method catches
|
||||
* that error and prints an explanation. (Unfortunately, it's not possible
|
||||
* to identify the particular system identifier that causes the problem.)
|
||||
* </p>
|
||||
*
|
||||
* <p>The underlying error is forwarded after printing the explanatory
|
||||
* message. The message is only every printed once and if
|
||||
* <code>suppressExplanation</code> is set to <code>false</code> before
|
||||
* parsing, it will never be printed.</p>
|
||||
*/
|
||||
public void parse(InputSource input)
|
||||
throws IOException,
|
||||
SAXException {
|
||||
setupParse(input.getSystemId());
|
||||
try {
|
||||
parser.parse(input);
|
||||
} catch (InternalError ie) {
|
||||
explain(input.getSystemId());
|
||||
throw ie;
|
||||
}
|
||||
}
|
||||
|
||||
/** SAX Parser API
|
||||
*
|
||||
* @see #parse(InputSource)
|
||||
*/
|
||||
public void parse(String systemId)
|
||||
throws IOException,
|
||||
SAXException {
|
||||
setupParse(systemId);
|
||||
try {
|
||||
parser.parse(systemId);
|
||||
} catch (InternalError ie) {
|
||||
explain(systemId);
|
||||
throw ie;
|
||||
}
|
||||
}
|
||||
|
||||
/** SAX Parser API */
|
||||
public void setDocumentHandler(DocumentHandler handler) {
|
||||
documentHandler = handler;
|
||||
}
|
||||
|
||||
/** SAX Parser API */
|
||||
public void setDTDHandler(DTDHandler handler) {
|
||||
dtdHandler = handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>SAX Parser API</p>
|
||||
*
|
||||
* <p>The purpose of this class is to implement an entity resolver.
|
||||
* Attempting to set a different one is pointless (and ignored).</p>
|
||||
*/
|
||||
public void setEntityResolver(EntityResolver resolver) {
|
||||
// nop
|
||||
}
|
||||
|
||||
/** SAX Parser API */
|
||||
public void setErrorHandler(ErrorHandler handler) {
|
||||
parser.setErrorHandler(handler);
|
||||
}
|
||||
|
||||
/** SAX Parser API */
|
||||
public void setLocale(Locale locale) throws SAXException {
|
||||
parser.setLocale(locale);
|
||||
}
|
||||
|
||||
/** SAX DocumentHandler API */
|
||||
public void characters(char[] ch, int start, int length)
|
||||
throws SAXException {
|
||||
if (documentHandler != null) {
|
||||
documentHandler.characters(ch,start,length);
|
||||
}
|
||||
}
|
||||
|
||||
/** SAX DocumentHandler API */
|
||||
public void endDocument() throws SAXException {
|
||||
if (documentHandler != null) {
|
||||
documentHandler.endDocument();
|
||||
}
|
||||
}
|
||||
|
||||
/** SAX DocumentHandler API */
|
||||
public void endElement(String name) throws SAXException {
|
||||
if (documentHandler != null) {
|
||||
documentHandler.endElement(name);
|
||||
}
|
||||
}
|
||||
|
||||
/** SAX DocumentHandler API */
|
||||
public void ignorableWhitespace(char[] ch, int start, int length)
|
||||
throws SAXException {
|
||||
if (documentHandler != null) {
|
||||
documentHandler.ignorableWhitespace(ch,start,length);
|
||||
}
|
||||
}
|
||||
|
||||
/** SAX DocumentHandler API */
|
||||
public void processingInstruction(String target, String pidata)
|
||||
throws SAXException {
|
||||
|
||||
if (target.equals("oasis-xml-catalog")) {
|
||||
URL catalog = null;
|
||||
String data = pidata;
|
||||
|
||||
int pos = data.indexOf("catalog=");
|
||||
if (pos >= 0) {
|
||||
data = data.substring(pos+8);
|
||||
if (data.length() > 1) {
|
||||
String quote = data.substring(0,1);
|
||||
data = data.substring(1);
|
||||
pos = data.indexOf(quote);
|
||||
if (pos >= 0) {
|
||||
data = data.substring(0, pos);
|
||||
try {
|
||||
if (baseURL != null) {
|
||||
catalog = new URL(baseURL, data);
|
||||
} else {
|
||||
catalog = new URL(data);
|
||||
}
|
||||
} catch (MalformedURLException mue) {
|
||||
// nevermind
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (allowXMLCatalogPI) {
|
||||
if (CatalogManager.allowOasisXMLCatalogPI()) {
|
||||
Debug.message(4,"oasis-xml-catalog PI", pidata);
|
||||
|
||||
if (catalog != null) {
|
||||
try {
|
||||
Debug.message(4,"oasis-xml-catalog", catalog.toString());
|
||||
oasisXMLCatalogPI = true;
|
||||
|
||||
if (piCatalogResolver == null) {
|
||||
piCatalogResolver = new CatalogResolver(true);
|
||||
}
|
||||
|
||||
piCatalogResolver.getCatalog().parseCatalog(catalog.toString());
|
||||
} catch (Exception e) {
|
||||
Debug.message(3, "Exception parsing oasis-xml-catalog: "
|
||||
+ catalog.toString());
|
||||
}
|
||||
} else {
|
||||
Debug.message(3, "PI oasis-xml-catalog unparseable: " + pidata);
|
||||
}
|
||||
} else {
|
||||
Debug.message(4,"PI oasis-xml-catalog ignored: " + pidata);
|
||||
}
|
||||
} else {
|
||||
Debug.message(3, "PI oasis-xml-catalog occurred in an invalid place: "
|
||||
+ pidata);
|
||||
}
|
||||
} else {
|
||||
if (documentHandler != null) {
|
||||
documentHandler.processingInstruction(target, pidata);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** SAX DocumentHandler API */
|
||||
public void setDocumentLocator(Locator locator) {
|
||||
if (documentHandler != null) {
|
||||
documentHandler.setDocumentLocator(locator);
|
||||
}
|
||||
}
|
||||
|
||||
/** SAX DocumentHandler API */
|
||||
public void startDocument() throws SAXException {
|
||||
if (documentHandler != null) {
|
||||
documentHandler.startDocument();
|
||||
}
|
||||
}
|
||||
|
||||
/** SAX DocumentHandler API */
|
||||
public void startElement(String name, AttributeList atts)
|
||||
throws SAXException {
|
||||
allowXMLCatalogPI = false;
|
||||
if (documentHandler != null) {
|
||||
documentHandler.startElement(name,atts);
|
||||
}
|
||||
}
|
||||
|
||||
/** SAX DTDHandler API */
|
||||
public void notationDecl (String name, String publicId, String systemId)
|
||||
throws SAXException {
|
||||
allowXMLCatalogPI = false;
|
||||
if (dtdHandler != null) {
|
||||
dtdHandler.notationDecl(name,publicId,systemId);
|
||||
}
|
||||
}
|
||||
|
||||
/** SAX DTDHandler API */
|
||||
public void unparsedEntityDecl (String name,
|
||||
String publicId,
|
||||
String systemId,
|
||||
String notationName)
|
||||
throws SAXException {
|
||||
allowXMLCatalogPI = false;
|
||||
if (dtdHandler != null) {
|
||||
dtdHandler.unparsedEntityDecl (name, publicId, systemId, notationName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Implements the <code>resolveEntity</code> method
|
||||
* for the SAX interface, using an underlying CatalogResolver
|
||||
* to do the real work.</p>
|
||||
*/
|
||||
public InputSource resolveEntity (String publicId, String systemId) {
|
||||
allowXMLCatalogPI = false;
|
||||
String resolved = catalogResolver.getResolvedEntity(publicId, systemId);
|
||||
|
||||
if (resolved == null && piCatalogResolver != null) {
|
||||
resolved = piCatalogResolver.getResolvedEntity(publicId, systemId);
|
||||
}
|
||||
|
||||
if (resolved != null) {
|
||||
try {
|
||||
InputSource iSource = new InputSource(resolved);
|
||||
iSource.setPublicId(publicId);
|
||||
|
||||
// Ideally this method would not attempt to open the
|
||||
// InputStream, but there is a bug (in Xerces, at least)
|
||||
// that causes the parser to mistakenly open the wrong
|
||||
// system identifier if the returned InputSource does
|
||||
// not have a byteStream.
|
||||
//
|
||||
// It could be argued that we still shouldn't do this here,
|
||||
// but since the purpose of calling the entityResolver is
|
||||
// almost certainly to open the input stream, it seems to
|
||||
// do little harm.
|
||||
//
|
||||
URL url = new URL(resolved);
|
||||
InputStream iStream = url.openStream();
|
||||
iSource.setByteStream(iStream);
|
||||
|
||||
return iSource;
|
||||
} catch (Exception e) {
|
||||
Debug.message(1, "Failed to create InputSource", resolved);
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/** Setup for parsing */
|
||||
private void setupParse(String systemId) {
|
||||
allowXMLCatalogPI = true;
|
||||
parser.setEntityResolver(this);
|
||||
parser.setDocumentHandler(this);
|
||||
parser.setDTDHandler(this);
|
||||
|
||||
String userdir = System.getProperty("user.dir");
|
||||
URL cwd = null;
|
||||
|
||||
userdir.replace('\\', '/');
|
||||
try {
|
||||
cwd = new URL("file:///" + userdir + "/basename");
|
||||
} catch (MalformedURLException mue) {
|
||||
cwd = null;
|
||||
}
|
||||
|
||||
try {
|
||||
baseURL = new URL(systemId);
|
||||
} catch (MalformedURLException mue) {
|
||||
if (cwd != null) {
|
||||
try {
|
||||
baseURL = new URL(cwd, systemId);
|
||||
} catch (MalformedURLException mue2) {
|
||||
// give up
|
||||
baseURL = null;
|
||||
}
|
||||
} else {
|
||||
// give up
|
||||
baseURL = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Provide one possible explanation for an InternalError */
|
||||
private void explain(String systemId) {
|
||||
if (!suppressExplanation) {
|
||||
System.out.println("Parser probably encountered bad URI in " + systemId);
|
||||
System.out.println("For example, replace '/some/uri' with 'file:/some/uri'.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,370 @@
|
||||
// ResolvingXMLFilter.java - An XMLFilter that performs catalog resolution
|
||||
|
||||
/*
|
||||
* The Apache Software License, Version 1.1
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2001 The Apache Software Foundation. All rights
|
||||
* reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The end-user documentation included with the redistribution,
|
||||
* if any, must include the following acknowledgment:
|
||||
* "This product includes software developed by the
|
||||
* Apache Software Foundation (http://www.apache.org/)."
|
||||
* Alternately, this acknowledgment may appear in the software itself,
|
||||
* if and wherever such third-party acknowledgments normally appear.
|
||||
*
|
||||
* 4. The names "Xalan" and "Apache Software Foundation" must
|
||||
* not be used to endorse or promote products derived from this
|
||||
* software without prior written permission. For written
|
||||
* permission, please contact apache@apache.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "Apache",
|
||||
* nor may "Apache" appear in their name, without prior written
|
||||
* permission of the Apache Software Foundation.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation and was
|
||||
* originally based on software copyright (c) 2001, International
|
||||
* Business Machines Corporation., http://www.ibm.com. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*/
|
||||
|
||||
package org.apache.xml.resolver.tools;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
import org.xml.sax.*;
|
||||
import org.xml.sax.helpers.XMLFilterImpl;
|
||||
|
||||
import javax.xml.parsers.*;
|
||||
|
||||
import org.apache.xml.resolver.Catalog;
|
||||
import org.apache.xml.resolver.CatalogManager;
|
||||
import org.apache.xml.resolver.helpers.Debug;
|
||||
|
||||
/**
|
||||
* <p>A SAX XMLFilter that performs catalog-based entity resolution.</p>
|
||||
*
|
||||
* <p>This class implements a SAX XMLFilter that performs entity resolution
|
||||
* using the CatalogResolver. The actual, underlying parser is obtained
|
||||
* from a SAXParserFactory.</p>
|
||||
* </p>
|
||||
*
|
||||
* @see CatalogResolver
|
||||
* @see org.xml.sax.XMLFilter
|
||||
*
|
||||
* @author Norman Walsh
|
||||
* <a href="mailto:Norman.Walsh@Sun.COM">Norman.Walsh@Sun.COM</a>
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
public class ResolvingXMLFilter extends XMLFilterImpl {
|
||||
/** Suppress explanatory message?
|
||||
*
|
||||
* @see #parse(InputSource)
|
||||
*/
|
||||
public static boolean suppressExplanation = false;
|
||||
|
||||
/** The underlying catalog resolver */
|
||||
private CatalogResolver catalogResolver = new CatalogResolver();
|
||||
|
||||
/** A separate resolver for oasis-xml-pi catalogs */
|
||||
private CatalogResolver piCatalogResolver = null;
|
||||
|
||||
/** Are we in the prolog? Is an oasis-xml-catalog PI valid now? */
|
||||
private boolean allowXMLCatalogPI = false;
|
||||
|
||||
/** Has an oasis-xml-catalog PI been seen? */
|
||||
private boolean oasisXMLCatalogPI = false;
|
||||
|
||||
/** The base URI of the input document, if known. */
|
||||
private URL baseURL = null;
|
||||
|
||||
/** Construct an empty XML Filter with no parent */
|
||||
public ResolvingXMLFilter() {
|
||||
super();
|
||||
}
|
||||
|
||||
/** Construct an XML filter with the specified parent */
|
||||
public ResolvingXMLFilter(XMLReader parent) {
|
||||
super(parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Provide accessto the underlying Catalog</p>
|
||||
*/
|
||||
public Catalog getCatalog() {
|
||||
return catalogResolver.getCatalog();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>SAX XMLReader API</p>
|
||||
*
|
||||
* <p>Note that the JAXP 1.1ea2 parser crashes with an InternalError if
|
||||
* it encounters a system identifier that appears to be a relative URI
|
||||
* that begins with a slash. For example, the declaration:</p>
|
||||
*
|
||||
* <pre>
|
||||
* <!DOCTYPE book SYSTEM "/path/to/dtd/on/my/system/docbookx.dtd">
|
||||
* </pre>
|
||||
*
|
||||
* <p>would cause such an error. As a convenience, this method catches
|
||||
* that error and prints an explanation. (Unfortunately, it's not possible
|
||||
* to identify the particular system identifier that causes the problem.)
|
||||
* </p>
|
||||
*
|
||||
* <p>The underlying error is forwarded after printing the explanatory
|
||||
* message. The message is only every printed once and if
|
||||
* <code>suppressExplanation</code> is set to <code>false</code> before
|
||||
* parsing, it will never be printed.</p>
|
||||
*/
|
||||
public void parse(InputSource input)
|
||||
throws IOException, SAXException {
|
||||
allowXMLCatalogPI = true;
|
||||
|
||||
setupBaseURI(input.getSystemId());
|
||||
|
||||
try {
|
||||
super.parse(input);
|
||||
} catch (InternalError ie) {
|
||||
explain(input.getSystemId());
|
||||
throw ie;
|
||||
}
|
||||
}
|
||||
|
||||
/** SAX XMLReader API
|
||||
*
|
||||
* @see #parse(InputSource)
|
||||
*/
|
||||
public void parse(String systemId)
|
||||
throws IOException, SAXException {
|
||||
allowXMLCatalogPI = true;
|
||||
|
||||
setupBaseURI(systemId);
|
||||
|
||||
try {
|
||||
super.parse(systemId);
|
||||
} catch (InternalError ie) {
|
||||
explain(systemId);
|
||||
throw ie;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Implements the <code>resolveEntity</code> method
|
||||
* for the SAX interface, using an underlying CatalogResolver
|
||||
* to do the real work.</p>
|
||||
*/
|
||||
public InputSource resolveEntity (String publicId, String systemId) {
|
||||
allowXMLCatalogPI = false;
|
||||
String resolved = catalogResolver.getResolvedEntity(publicId, systemId);
|
||||
|
||||
if (resolved == null && piCatalogResolver != null) {
|
||||
resolved = piCatalogResolver.getResolvedEntity(publicId, systemId);
|
||||
}
|
||||
|
||||
if (resolved != null) {
|
||||
try {
|
||||
InputSource iSource = new InputSource(resolved);
|
||||
iSource.setPublicId(publicId);
|
||||
|
||||
// Ideally this method would not attempt to open the
|
||||
// InputStream, but there is a bug (in Xerces, at least)
|
||||
// that causes the parser to mistakenly open the wrong
|
||||
// system identifier if the returned InputSource does
|
||||
// not have a byteStream.
|
||||
//
|
||||
// It could be argued that we still shouldn't do this here,
|
||||
// but since the purpose of calling the entityResolver is
|
||||
// almost certainly to open the input stream, it seems to
|
||||
// do little harm.
|
||||
//
|
||||
URL url = new URL(resolved);
|
||||
InputStream iStream = url.openStream();
|
||||
iSource.setByteStream(iStream);
|
||||
|
||||
return iSource;
|
||||
} catch (Exception e) {
|
||||
Debug.message(1, "Failed to create InputSource", resolved);
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/** SAX DTDHandler API
|
||||
*
|
||||
* <p>Captured here only to detect the end of the prolog so that
|
||||
* we can ignore subsequent oasis-xml-catalog PIs. Otherwise
|
||||
* the events are just passed through.</p>
|
||||
*/
|
||||
public void notationDecl (String name, String publicId, String systemId)
|
||||
throws SAXException {
|
||||
allowXMLCatalogPI = false;
|
||||
super.notationDecl(name,publicId,systemId);
|
||||
}
|
||||
|
||||
/** SAX DTDHandler API
|
||||
*
|
||||
* <p>Captured here only to detect the end of the prolog so that
|
||||
* we can ignore subsequent oasis-xml-catalog PIs. Otherwise
|
||||
* the events are just passed through.</p>
|
||||
*/
|
||||
public void unparsedEntityDecl (String name,
|
||||
String publicId,
|
||||
String systemId,
|
||||
String notationName)
|
||||
throws SAXException {
|
||||
allowXMLCatalogPI = false;
|
||||
super.unparsedEntityDecl (name, publicId, systemId, notationName);
|
||||
}
|
||||
|
||||
/** SAX ContentHandler API
|
||||
*
|
||||
* <p>Captured here only to detect the end of the prolog so that
|
||||
* we can ignore subsequent oasis-xml-catalog PIs. Otherwise
|
||||
* the events are just passed through.</p>
|
||||
*/
|
||||
public void startElement (String uri, String localName, String qName,
|
||||
Attributes atts)
|
||||
throws SAXException {
|
||||
allowXMLCatalogPI = false;
|
||||
super.startElement(uri,localName,qName,atts);
|
||||
}
|
||||
|
||||
/** SAX ContentHandler API
|
||||
*
|
||||
* <p>Detect and use the oasis-xml-catalog PI if it occurs.</p>
|
||||
*/
|
||||
public void processingInstruction(String target, String pidata)
|
||||
throws SAXException {
|
||||
if (target.equals("oasis-xml-catalog")) {
|
||||
URL catalog = null;
|
||||
String data = pidata;
|
||||
|
||||
int pos = data.indexOf("catalog=");
|
||||
if (pos >= 0) {
|
||||
data = data.substring(pos+8);
|
||||
if (data.length() > 1) {
|
||||
String quote = data.substring(0,1);
|
||||
data = data.substring(1);
|
||||
pos = data.indexOf(quote);
|
||||
if (pos >= 0) {
|
||||
data = data.substring(0, pos);
|
||||
try {
|
||||
if (baseURL != null) {
|
||||
catalog = new URL(baseURL, data);
|
||||
} else {
|
||||
catalog = new URL(data);
|
||||
}
|
||||
} catch (MalformedURLException mue) {
|
||||
// nevermind
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (allowXMLCatalogPI) {
|
||||
if (CatalogManager.allowOasisXMLCatalogPI()) {
|
||||
Debug.message(4,"oasis-xml-catalog PI", pidata);
|
||||
|
||||
if (catalog != null) {
|
||||
try {
|
||||
Debug.message(4,"oasis-xml-catalog", catalog.toString());
|
||||
oasisXMLCatalogPI = true;
|
||||
|
||||
if (piCatalogResolver == null) {
|
||||
piCatalogResolver = new CatalogResolver(true);
|
||||
}
|
||||
|
||||
piCatalogResolver.getCatalog().parseCatalog(catalog.toString());
|
||||
} catch (Exception e) {
|
||||
Debug.message(3, "Exception parsing oasis-xml-catalog: "
|
||||
+ catalog.toString());
|
||||
}
|
||||
} else {
|
||||
Debug.message(3, "PI oasis-xml-catalog unparseable: " + pidata);
|
||||
}
|
||||
} else {
|
||||
Debug.message(4,"PI oasis-xml-catalog ignored: " + pidata);
|
||||
}
|
||||
} else {
|
||||
Debug.message(3, "PI oasis-xml-catalog occurred in an invalid place: "
|
||||
+ pidata);
|
||||
}
|
||||
} else {
|
||||
super.processingInstruction(target, pidata);
|
||||
}
|
||||
}
|
||||
|
||||
/** Save the base URI of the document being parsed. */
|
||||
private void setupBaseURI(String systemId) {
|
||||
String userdir = System.getProperty("user.dir");
|
||||
URL cwd = null;
|
||||
|
||||
userdir.replace('\\', '/');
|
||||
try {
|
||||
cwd = new URL("file:///" + userdir + "/basename");
|
||||
} catch (MalformedURLException mue) {
|
||||
cwd = null;
|
||||
}
|
||||
|
||||
try {
|
||||
baseURL = new URL(systemId);
|
||||
} catch (MalformedURLException mue) {
|
||||
if (cwd != null) {
|
||||
try {
|
||||
baseURL = new URL(cwd, systemId);
|
||||
} catch (MalformedURLException mue2) {
|
||||
// give up
|
||||
baseURL = null;
|
||||
}
|
||||
} else {
|
||||
// give up
|
||||
baseURL = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Provide one possible explanation for an InternalError */
|
||||
private void explain(String systemId) {
|
||||
if (!suppressExplanation) {
|
||||
System.out.println("XMLReader probably encountered bad URI in " + systemId);
|
||||
System.out.println("For example, replace '/some/uri' with 'file:/some/uri'.");
|
||||
}
|
||||
suppressExplanation = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
// ResolvingXMLReader.java - An XMLReader that performs catalog resolution
|
||||
|
||||
/*
|
||||
* The Apache Software License, Version 1.1
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2001 The Apache Software Foundation. All rights
|
||||
* reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The end-user documentation included with the redistribution,
|
||||
* if any, must include the following acknowledgment:
|
||||
* "This product includes software developed by the
|
||||
* Apache Software Foundation (http://www.apache.org/)."
|
||||
* Alternately, this acknowledgment may appear in the software itself,
|
||||
* if and wherever such third-party acknowledgments normally appear.
|
||||
*
|
||||
* 4. The names "Xalan" and "Apache Software Foundation" must
|
||||
* not be used to endorse or promote products derived from this
|
||||
* software without prior written permission. For written
|
||||
* permission, please contact apache@apache.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "Apache",
|
||||
* nor may "Apache" appear in their name, without prior written
|
||||
* permission of the Apache Software Foundation.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation and was
|
||||
* originally based on software copyright (c) 2001, International
|
||||
* Business Machines Corporation., http://www.ibm.com. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*/
|
||||
|
||||
package org.apache.xml.resolver.tools;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
|
||||
import org.xml.sax.*;
|
||||
import org.xml.sax.helpers.XMLFilterImpl;
|
||||
|
||||
import javax.xml.parsers.*;
|
||||
|
||||
import org.apache.xml.resolver.*;
|
||||
|
||||
/**
|
||||
* <p>A SAX XMLReader that performs catalog-based entity resolution.</p>
|
||||
*
|
||||
* <p>This class implements a SAX XMLReader that performs entity resolution
|
||||
* using the CatalogResolver. The actual, underlying parser is obtained
|
||||
* from a SAXParserFactory.</p>
|
||||
* </p>
|
||||
*
|
||||
* @see CatalogResolver
|
||||
* @see org.xml.sax.XMLReader
|
||||
*
|
||||
* @author Norman Walsh
|
||||
* <a href="mailto:Norman.Walsh@Sun.COM">Norman.Walsh@Sun.COM</a>
|
||||
*
|
||||
* @version 1.0
|
||||
*/
|
||||
public class ResolvingXMLReader extends ResolvingXMLFilter {
|
||||
/**
|
||||
* <p>Construct a new reader from the JAXP factory</p>
|
||||
*
|
||||
* <p>In order to do its job, a ResolvingXMLReader must in fact be
|
||||
* a filter. So the only difference between this code and the filter
|
||||
* code is that a zero-argument constructor builds a new reader.</p>
|
||||
*/
|
||||
public ResolvingXMLReader() {
|
||||
super();
|
||||
SAXParserFactory spf = SAXParserFactory.newInstance();
|
||||
try {
|
||||
SAXParser parser = spf.newSAXParser();
|
||||
setParent(parser.getXMLReader());
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Apache XML Commons Resolver Tools package</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>Apache XML Commons Resolver Tools package</p>
|
||||
|
||||
<p>This package implements several tool classes for catalog-based
|
||||
entity resolution:</p>
|
||||
|
||||
<dl>
|
||||
<dt><code>org.apache.xml.resolver.tools.CatalogResolver</code></dt>
|
||||
<dd>This class provides a SAX EntityResolver and a JAXP URIResolver.
|
||||
</dd>
|
||||
|
||||
<dt><code>org.apache.xml.resolver.tools.ResolvingXMLReader</code></dt>
|
||||
<dd>This class provides a SAX2 XMLReader with catalog support.
|
||||
The parser uses a CatalogResolver to provide entity resolution.
|
||||
</dd>
|
||||
|
||||
<dt><code>org.apache.xml.resolver.tools.ResolvingParser</code></dt>
|
||||
<dd>This class provides a SAX1 Parser with catalog support.
|
||||
The parser uses a CatalogResolver to provide entity resolution.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<p>Typically, these classes can be used in other applications. For example,
|
||||
running the <a href="http://saxon.sourceforge.net/">Saxon</a>
|
||||
XSLT processor with the arguments:</p>
|
||||
|
||||
<pre>
|
||||
-x org.apache.xml.resolver.tools.ResolvingXMLReader
|
||||
-y org.apache.xml.resolver.tools.ResolvingXMLReader
|
||||
-r org.apache.xml.resolver.tools.CatalogResolver
|
||||
</pre>
|
||||
|
||||
<p>will provide catalog-based entity resolution for all of the entities
|
||||
and stylesheets that you use. (The CatalogResolver can only be used
|
||||
with Saxon 6.1 or later.)</p>
|
||||
|
||||
<h2>Requirements</h2>
|
||||
|
||||
<p>In order to use these classes, you must have the JAXP 1.1 jar files
|
||||
in your <tt>CLASSPATH</tt>.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Reference in new issue
Block a user