Changes needed to permit the xml-apis.jar generated

from this branch to pass the JAXP 1.2 TCK.  I've attempted to keep
these as limited as possible, in a few cases simply
modifying the original commons source directly rather than simply
importing Xerces code.  However, for many changes--such as that
involving correct handling of security-critical operations
like property checking--I've simply imported the relevant Xerces code.

I have always indicated in the comments at the top of substituted
files that they are substitutions (except in the case of the JAXP code
in which virtually all files were touched); where I've modified commons
code directly, I've placed comments immediately above
the modifications.


git-svn-id: https://svn.apache.org/repos/asf/xml/commons/trunk@226021 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
neilg 2002-12-12 16:26:53 +00:00
parent df6b11c28f
commit c9ce59d37b
20 changed files with 1374 additions and 544 deletions

View File

@ -100,6 +100,7 @@ public abstract class DocumentBuilder {
protected DocumentBuilder () { protected DocumentBuilder () {
} }
private static final boolean DEBUG = false ;
/** /**
* Parse the content of the given <code>InputStream</code> as an XML * Parse the content of the given <code>InputStream</code> as an XML
* document and return a new DOM {@link org.w3c.dom.Document} object. * document and return a new DOM {@link org.w3c.dom.Document} object.
@ -189,11 +190,12 @@ public abstract class DocumentBuilder {
throw new IllegalArgumentException("File cannot be null"); throw new IllegalArgumentException("File cannot be null");
} }
String uri = "file:" + f.getAbsolutePath(); String escapedURI = FilePathToURI.filepath2URI(f.getAbsolutePath()) ;
if (File.separatorChar == '\\') {
uri = uri.replace('\\', '/'); if(DEBUG)
} System.out.println("Escaped URI = " + escapedURI) ;
InputSource in = new InputSource(uri);
InputSource in = new InputSource(escapedURI);
return parse(in); return parse(in);
} }

View File

@ -140,7 +140,7 @@ public abstract class DocumentBuilderFactory {
/* The default property name according to the JAXP spec */ /* The default property name according to the JAXP spec */
"javax.xml.parsers.DocumentBuilderFactory", "javax.xml.parsers.DocumentBuilderFactory",
/* The fallback implementation class name */ /* The fallback implementation class name */
null); "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl");
} catch (FactoryFinder.ConfigurationError e) { } catch (FactoryFinder.ConfigurationError e) {
throw new FactoryConfigurationError(e.getException(), throw new FactoryConfigurationError(e.getException(),
e.getMessage()); e.getMessage());

View File

@ -55,17 +55,15 @@
package javax.xml.parsers; package javax.xml.parsers;
import java.io.InputStream;
import java.io.IOException;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.IOException;
import java.util.Properties;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.util.Properties;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
/** /**
* This class is duplicated for each JAXP subpackage so keep it in sync. * This class is duplicated for each JAXP subpackage so keep it in sync.
@ -73,65 +71,170 @@ import java.lang.reflect.InvocationTargetException;
* API. * API.
* *
* This code is designed to implement the JAXP 1.1 spec pluggability * This code is designed to implement the JAXP 1.1 spec pluggability
* feature and is designed to both compile and run on JDK version 1.1 and * feature. The code runs both as part of an unbundled jar file and also
* later. The code also runs both as part of an unbundled jar file and * when bundled as part of the JDK. Ideally the code should both compile
* when bundled as part of the JDK. * and run on JDK version 1.1 and later. However, due to the complexities
* of invoking Java 2 security methods via reflection, this code will only
* compile on Java 2 although it will run under JDK 1.1 VMs. As of 1may02
* this file is on a "java2-branch".
*
* @author Edwin Goei
*/ */
class FactoryFinder { class FactoryFinder {
/** Set to true for debugging */ /** Controls debugging output to stderr */
private static final boolean debug = false; private static boolean debug;
private static void debugPrintln(String msg) { // Define system property "jaxp.debug" to get output
static {
try {
String val =
SecuritySupport.getInstance().getSystemProperty("jaxp.debug");
// Allow simply setting the prop to turn on debug
debug = val != null && (! "false".equals(val));
} catch (SecurityException se) {
debug = false;
}
}
/**
* Main entry point. Finds and creates a new instance of a concrete
* factory implementation in the specified order as stated in the JAXP
* spec. This code attempts to find a factory implementation in
* serveral locations. If one fails, the next one is tried. To be
* more robust, this occurs even if a SecurityException is thrown, but
* perhaps it may be better to propogate the SecurityException instead,
* so SecurityException-s are not masked.
*
* @return A new instance of the concrete factory class, never null
*
* @param factoryId
* Name of the factory to find, same as a property name
*
* @param fallbackClassName
* Implementation class name, if nothing else is found. Use
* null to mean not to use a fallback.
*
* @throws FactoryFinder.ConfigurationError
* If a factory instance cannot be returned
*
* Package private so this code can be shared.
*/
static Object find(String factoryId, String fallbackClassName)
throws ConfigurationError
{
SecuritySupport ss = SecuritySupport.getInstance();
// Figure out which ClassLoader to use for loading the provider
// class. If there is a Context ClassLoader then use it.
ClassLoader cl = ss.getContextClassLoader();
if (cl == null) {
// Assert: we are on JDK 1.1 or we have no Context ClassLoader
// so use the current ClassLoader
cl = FactoryFinder.class.getClassLoader();
}
dPrint("find factoryId=" + factoryId);
// Use the system property first
try {
String systemProp = ss.getSystemProperty(factoryId);
if (systemProp != null) {
dPrint("found system property, value=" + systemProp);
return newInstance(systemProp, cl, true);
}
} catch (SecurityException se) {
// Ignore and continue w/ next location
}
// Try to read from $java.home/lib/jaxp.properties
try {
String javah = ss.getSystemProperty("java.home");
String configFile = javah + File.separator +
"lib" + File.separator + "jaxp.properties";
FileInputStream fis = ss.getFileInputStream(new File(configFile));
Properties props = new Properties();
props.load(fis);
String factoryClassName = props.getProperty(factoryId);
if (factoryClassName != null) {
dPrint("found in jaxp.properties, value=" + factoryClassName);
return newInstance(factoryClassName, cl, true);
}
} catch (Exception x) {
// assert(x instanceof FileNotFoundException
// || x instanceof SecurityException)
// In both cases, ignore and continue w/ next location
}
// Try Jar Service Provider Mechanism
Object provider = findJarServiceProvider(factoryId);
if (provider != null) {
return provider;
}
if (fallbackClassName == null) {
throw new ConfigurationError(
"Provider for " + factoryId + " cannot be found", null);
}
dPrint("using fallback, value=" + fallbackClassName);
return newInstance(fallbackClassName, cl, true);
}
private static void dPrint(String msg) {
if (debug) { if (debug) {
System.err.println("JAXP: " + msg); System.err.println("JAXP: " + msg);
} }
} }
/** /**
* Figure out which ClassLoader to use. For JDK 1.2 and later use * Create an instance of a class using the specified ClassLoader and
* the context ClassLoader. * optionally fall back to the current ClassLoader if not found.
*
* @param className Name of the concrete class corresponding to the
* service provider
*
* @param cl ClassLoader to use to load the class, null means to use
* the bootstrap ClassLoader
*
* @param doFallback true if the current ClassLoader should be tried as
* a fallback if the class is not found using cl
*/ */
private static ClassLoader findClassLoader() private static Object newInstance(String className, ClassLoader cl,
boolean doFallback)
throws ConfigurationError throws ConfigurationError
{ {
Method m = null; // assert(className != null);
try { try {
m = Thread.class.getMethod("getContextClassLoader", null); Class providerClass;
} catch (NoSuchMethodException e) { if (cl == null) {
// Assume that we are running JDK 1.1, use the current ClassLoader // XXX Use the bootstrap ClassLoader. There is no way to
debugPrintln("assuming JDK 1.1"); // load a class using the bootstrap ClassLoader that works
return FactoryFinder.class.getClassLoader(); // in both JDK 1.1 and Java 2. However, this should still
} // work b/c the following should be true:
//
try { // (cl == null) iff current ClassLoader == null
return (ClassLoader) m.invoke(Thread.currentThread(), null); //
} catch (IllegalAccessException e) { // Thus Class.forName(String) will use the current
// assert(false) // ClassLoader which will be the bootstrap ClassLoader.
throw new ConfigurationError("Unexpected IllegalAccessException", providerClass = Class.forName(className);
e);
} catch (InvocationTargetException e) {
// assert(e.getTargetException() instanceof SecurityException)
throw new ConfigurationError("Unexpected InvocationTargetException",
e);
}
}
/**
* Create an instance of a class using the specified ClassLoader
*/
private static Object newInstance(String className,
ClassLoader classLoader)
throws ConfigurationError
{
try {
Class spiClass;
if (classLoader == null) {
spiClass = Class.forName(className);
} else { } else {
spiClass = classLoader.loadClass(className); try {
providerClass = cl.loadClass(className);
} catch (ClassNotFoundException x) {
if (doFallback) {
// Fall back to current classloader
cl = FactoryFinder.class.getClassLoader();
providerClass = cl.loadClass(className);
} else {
throw x;
} }
return spiClass.newInstance(); }
}
Object instance = providerClass.newInstance();
dPrint("created new instance of " + providerClass +
" using ClassLoader: " + cl);
return instance;
} catch (ClassNotFoundException x) { } catch (ClassNotFoundException x) {
throw new ConfigurationError( throw new ConfigurationError(
"Provider " + className + " not found", x); "Provider " + className + " not found", x);
@ -142,67 +245,42 @@ class FactoryFinder {
} }
} }
/** /*
* Finds the implementation Class object in the specified order. Main * Try to find provider using Jar Service Provider Mechanism
* entry point.
* @return Class object of factory, never null
* *
* @param factoryId Name of the factory to find, same as * @return instance of provider class if found or null
* a property name
* @param fallbackClassName Implementation class name, if nothing else
* is found. Use null to mean no fallback.
*
* @exception FactoryFinder.ConfigurationError
*
* Package private so this code can be shared.
*/ */
static Object find(String factoryId, String fallbackClassName) private static Object findJarServiceProvider(String factoryId)
throws ConfigurationError throws ConfigurationError
{ {
debugPrintln("debug is on"); SecuritySupport ss = SecuritySupport.getInstance();
ClassLoader classLoader = findClassLoader();
// Use the system property first
try {
String systemProp =
System.getProperty( factoryId );
if( systemProp!=null) {
debugPrintln("found system property " + systemProp);
return newInstance(systemProp, classLoader);
}
} catch (SecurityException se) {
}
// try to read from $java.home/lib/xml.properties
try {
String javah=System.getProperty( "java.home" );
String configFile = javah + File.separator +
"lib" + File.separator + "jaxp.properties";
File f=new File( configFile );
if( f.exists()) {
Properties props=new Properties();
props.load( new FileInputStream(f));
String factoryClassName = props.getProperty(factoryId);
debugPrintln("found java.home property " + factoryClassName);
return newInstance(factoryClassName, classLoader);
}
} catch(Exception ex ) {
if( debug ) ex.printStackTrace();
}
String serviceId = "META-INF/services/" + factoryId; String serviceId = "META-INF/services/" + factoryId;
// try to find services in CLASSPATH
try {
InputStream is = null; InputStream is = null;
if (classLoader == null) {
is=ClassLoader.getSystemResourceAsStream( serviceId ); // First try the Context ClassLoader
ClassLoader cl = ss.getContextClassLoader();
if (cl != null) {
is = ss.getResourceAsStream(cl, serviceId);
// If no provider found then try the current ClassLoader
if (is == null) {
cl = FactoryFinder.class.getClassLoader();
is = ss.getResourceAsStream(cl, serviceId);
}
} else { } else {
is=classLoader.getResourceAsStream( serviceId ); // No Context ClassLoader or JDK 1.1 so try the current
// ClassLoader
cl = FactoryFinder.class.getClassLoader();
is = ss.getResourceAsStream(cl, serviceId);
} }
if( is!=null ) { if (is == null) {
debugPrintln("found " + serviceId); // No provider found
return null;
}
dPrint("found jar resource=" + serviceId +
" using ClassLoader: " + cl);
// Read the service provider name in UTF-8 as specified in // Read the service provider name in UTF-8 as specified in
// the jar spec. Unfortunately this fails in Microsoft // the jar spec. Unfortunately this fails in Microsoft
@ -227,26 +305,31 @@ class FactoryFinder {
rd = new BufferedReader(new InputStreamReader(is)); rd = new BufferedReader(new InputStreamReader(is));
} }
String factoryClassName = rd.readLine(); String factoryClassName = null;
try {
// XXX Does not handle all possible input as specified by the
// Jar Service Provider specification
factoryClassName = rd.readLine();
rd.close(); rd.close();
} catch (IOException x) {
// No provider found
return null;
}
if (factoryClassName != null && if (factoryClassName != null &&
! "".equals(factoryClassName)) { ! "".equals(factoryClassName)) {
debugPrintln("loaded from services: " + factoryClassName); dPrint("found in resource, value="
return newInstance(factoryClassName, classLoader); + factoryClassName);
}
} // Note: here we do not want to fall back to the current
} catch( Exception ex ) { // ClassLoader because we want to avoid the case where the
if( debug ) ex.printStackTrace(); // resource file was found using one ClassLoader and the
// provider class was instantiated using a different one.
return newInstance(factoryClassName, cl, false);
} }
if (fallbackClassName == null) { // No provider found
throw new ConfigurationError( return null;
"Provider for " + factoryId + " cannot be found", null);
}
debugPrintln("loaded from fallback value: " + fallbackClassName);
return newInstance(fallbackClassName, classLoader);
} }
static class ConfigurationError extends Error { static class ConfigurationError extends Error {

View File

@ -0,0 +1,169 @@
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2002 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 "Xerces" 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) 1999, International
* Business Machines, Inc., http://www.apache.org. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package javax.xml.parsers;
class FilePathToURI {
// which ASCII characters need to be escaped
private static boolean gNeedEscaping[] = new boolean[128];
// the first hex character if a character needs to be escaped
private static char gAfterEscaping1[] = new char[128];
// the second hex character if a character needs to be escaped
private static char gAfterEscaping2[] = new char[128];
private static char[] gHexChs = {'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
// initialize the above 3 arrays
static {
for (int i = 0; i <= 0x1f; i++) {
gNeedEscaping[i] = true;
gAfterEscaping1[i] = gHexChs[i >> 4];
gAfterEscaping2[i] = gHexChs[i & 0xf];
}
gNeedEscaping[0x7f] = true;
gAfterEscaping1[0x7f] = '7';
gAfterEscaping2[0x7f] = 'F';
char[] escChs = {' ', '<', '>', '#', '%', '"', '{', '}',
'|', '\\', '^', '~', '[', ']', '`'};
int len = escChs.length;
char ch;
for (int i = 0; i < len; i++) {
ch = escChs[i];
gNeedEscaping[ch] = true;
gAfterEscaping1[ch] = gHexChs[ch >> 4];
gAfterEscaping2[ch] = gHexChs[ch & 0xf];
}
}
// To escape a file path to a URI, by using %HH to represent
// special ASCII characters: 0x00~0x1F, 0x7F, ' ', '<', '>', '#', '%'
// and '"' and non-ASCII characters (whose value >= 128).
public static String filepath2URI(String path){
// return null if path is null.
if (path == null)
return null;
char separator = java.io.File.separatorChar;
path = path.replace(separator, '/');
int len = path.length(), ch;
StringBuffer buffer = new StringBuffer(len*3);
buffer.append("file://");
// change C:/blah to /C:/blah
if (len >= 2 && path.charAt(1) == ':') {
ch = Character.toUpperCase(path.charAt(0));
if (ch >= 'A' && ch <= 'Z') {
buffer.append('/');
}
}
// for each character in the path
int i = 0;
for (; i < len; i++) {
ch = path.charAt(i);
// if it's not an ASCII character, break here, and use UTF-8 encoding
if (ch >= 128)
break;
if (gNeedEscaping[ch]) {
buffer.append('%');
buffer.append(gAfterEscaping1[ch]);
buffer.append(gAfterEscaping2[ch]);
// record the fact that it's escaped
}
else {
buffer.append((char)ch);
}
}
// we saw some non-ascii character
if (i < len) {
// get UTF-8 bytes for the remaining sub-string
byte[] bytes = null;
byte b;
try {
bytes = path.substring(i).getBytes("UTF-8");
} catch (java.io.UnsupportedEncodingException e) {
// should never happen
return path;
}
len = bytes.length;
// for each byte
for (i = 0; i < len; i++) {
b = bytes[i];
// for non-ascii character: make it positive, then escape
if (b < 0) {
ch = b + 256;
buffer.append('%');
buffer.append(gHexChs[ch >> 4]);
buffer.append(gHexChs[ch & 0xf]);
}
else if (gNeedEscaping[b]) {
buffer.append('%');
buffer.append(gAfterEscaping1[b]);
buffer.append(gAfterEscaping2[b]);
}
else {
buffer.append((char)b);
}
}
}
return buffer.toString();
}
}//FilePathToURI

View File

@ -107,6 +107,7 @@ import org.xml.sax.SAXNotSupportedException;
public abstract class SAXParser { public abstract class SAXParser {
private static final boolean DEBUG = false ;
protected SAXParser () { protected SAXParser () {
} }
@ -293,14 +294,16 @@ public abstract class SAXParser {
throw new IllegalArgumentException("File cannot be null"); throw new IllegalArgumentException("File cannot be null");
} }
String uri = "file:" + f.getAbsolutePath(); String escapedURI = FilePathToURI.filepath2URI(f.getAbsolutePath()) ;
if (File.separatorChar == '\\') {
uri = uri.replace('\\', '/'); if(DEBUG)
} System.out.println("Escaped URI = " + escapedURI) ;
InputSource input = new InputSource(uri);
InputSource input = new InputSource(escapedURI);
this.parse(input, hb); this.parse(input, hb);
} }
/** /**
* Parse the content of the file specified as XML using the * Parse the content of the file specified as XML using the
* specified {@link org.xml.sax.helpers.DefaultHandler}. * specified {@link org.xml.sax.helpers.DefaultHandler}.
@ -321,11 +324,12 @@ public abstract class SAXParser {
throw new IllegalArgumentException("File cannot be null"); throw new IllegalArgumentException("File cannot be null");
} }
String uri = "file:" + f.getAbsolutePath(); String escapedURI = FilePathToURI.filepath2URI(f.getAbsolutePath()) ;
if (File.separatorChar == '\\') {
uri = uri.replace('\\', '/'); if(DEBUG)
} System.out.println("Escaped URI = " + escapedURI) ;
InputSource input = new InputSource(uri);
InputSource input = new InputSource(escapedURI);
this.parse(input, dh); this.parse(input, dh);
} }
@ -353,6 +357,7 @@ public abstract class SAXParser {
} }
Parser parser = this.getParser(); Parser parser = this.getParser();
if (hb != null) { if (hb != null) {
parser.setDocumentHandler(hb); parser.setDocumentHandler(hb);
parser.setEntityResolver(hb); parser.setEntityResolver(hb);

View File

@ -136,7 +136,7 @@ public abstract class SAXParserFactory {
/* The default property name according to the JAXP spec */ /* The default property name according to the JAXP spec */
"javax.xml.parsers.SAXParserFactory", "javax.xml.parsers.SAXParserFactory",
/* The fallback implementation class name */ /* The fallback implementation class name */
null); "org.apache.xerces.jaxp.SAXParserFactoryImpl");
} catch (FactoryFinder.ConfigurationError e) { } catch (FactoryFinder.ConfigurationError e) {
throw new FactoryConfigurationError(e.getException(), throw new FactoryConfigurationError(e.getException(),
e.getMessage()); e.getMessage());

View File

@ -0,0 +1,140 @@
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2002 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 name "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) 1999-2002, Sun Microsystems,
* Inc., http://www.sun.com. For more information on the Apache Software
* Foundation, please see <http://www.apache.org/>.
*/
package javax.xml.parsers;
import java.lang.reflect.*;
import java.net.*;
import java.io.*;
/**
* This class is duplicated for each JAXP subpackage so keep it in sync.
* It is package private and therefore is not exposed as part of the JAXP
* API.
*
* Base class with security related methods that work on JDK 1.1.
*/
class SecuritySupport {
/*
* Make this of type Object so that the verifier won't try to
* prove its type, thus possibly trying to load the SecuritySupport12
* class.
*/
private static final Object securitySupport;
static {
SecuritySupport ss = null;
try {
Class c = Class.forName("java.security.AccessController");
// if that worked, we're on 1.2.
/*
// don't reference the class explicitly so it doesn't
// get dragged in accidentally.
c = Class.forName("javax.mail.SecuritySupport12");
Constructor cons = c.getConstructor(new Class[] { });
ss = (SecuritySupport)cons.newInstance(new Object[] { });
*/
/*
* Unfortunately, we can't load the class using reflection
* because the class is package private. And the class has
* to be package private so the APIs aren't exposed to other
* code that could use them to circumvent security. Thus,
* we accept the risk that the direct reference might fail
* on some JDK 1.1 JVMs, even though we would never execute
* this code in such a case. Sigh...
*/
ss = new SecuritySupport12();
} catch (Exception ex) {
// ignore it
} finally {
if (ss == null)
ss = new SecuritySupport();
securitySupport = ss;
}
}
/**
* Return an appropriate instance of this class, depending on whether
* we're on a JDK 1.1 or J2SE 1.2 (or later) system.
*/
public static SecuritySupport getInstance() {
return (SecuritySupport)securitySupport;
}
public ClassLoader getContextClassLoader() {
return null;
}
public String getSystemProperty(String propName) {
return System.getProperty(propName);
}
public FileInputStream getFileInputStream(File file)
throws FileNotFoundException
{
return new FileInputStream(file);
}
public InputStream getResourceAsStream(ClassLoader cl, String name) {
InputStream ris;
if (cl == null) {
ris = ClassLoader.getSystemResourceAsStream(name);
} else {
ris = cl.getResourceAsStream(name);
}
return ris;
}
}

View File

@ -0,0 +1,125 @@
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2002 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 name "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) 1999-2002, Sun Microsystems,
* Inc., http://www.sun.com. For more information on the Apache Software
* Foundation, please see <http://www.apache.org/>.
*/
package javax.xml.parsers;
import java.security.*;
import java.net.*;
import java.io.*;
import java.util.*;
/**
* This class is duplicated for each JAXP subpackage so keep it in sync.
* It is package private and therefore is not exposed as part of the JAXP
* API.
*
* Security related methods that only work on J2SE 1.2 and newer.
*/
class SecuritySupport12 extends SecuritySupport {
public ClassLoader getContextClassLoader() {
return (ClassLoader)
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
ClassLoader cl = null;
try {
cl = Thread.currentThread().getContextClassLoader();
} catch (SecurityException ex) { }
return cl;
}
});
}
public String getSystemProperty(final String propName) {
return (String)
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
return System.getProperty(propName);
}
});
}
public FileInputStream getFileInputStream(final File file)
throws FileNotFoundException
{
try {
return (FileInputStream)
AccessController.doPrivileged(new PrivilegedExceptionAction() {
public Object run() throws FileNotFoundException {
return new FileInputStream(file);
}
});
} catch (PrivilegedActionException e) {
throw (FileNotFoundException)e.getException();
}
}
public InputStream getResourceAsStream(final ClassLoader cl,
final String name)
{
return (InputStream)
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
InputStream ris;
if (cl == null) {
ris = ClassLoader.getSystemResourceAsStream(name);
} else {
ris = cl.getResourceAsStream(name);
}
return ris;
}
});
}
}

View File

@ -40,11 +40,14 @@ public class SAXException extends Exception {
/** /**
* Create a new SAXException. * Create a new SAXException.
*/ */
/****
* commented out by neilg for JAXP 1.2 compatibiliby.
public SAXException () public SAXException ()
{ {
super(); super();
this.exception = null; this.exception = null;
} }
****/
/** /**

View File

@ -34,10 +34,13 @@ public class SAXNotRecognizedException extends SAXException
/** /**
* Default constructor. * Default constructor.
*/ */
/****
* commented out by neilg for JAXP 1.2 compatibiliby.
public SAXNotRecognizedException () public SAXNotRecognizedException ()
{ {
super(); super();
} }
*****/
/** /**

View File

@ -34,10 +34,13 @@ public class SAXNotSupportedException extends SAXException
/** /**
* Construct a new exception with no message. * Construct a new exception with no message.
*/ */
/****
* commented out by neilg for JAXP 1.2 compatibiliby.
public SAXNotSupportedException () public SAXNotSupportedException ()
{ {
super(); super();
} }
*****/
/** /**

View File

@ -1,6 +1,5 @@
// NamespaceSupport.java - generic Namespace support for SAX. // NamespaceSupport.java - generic Namespace support for SAX.
// http://www.saxproject.org // Written by David Megginson, sax@megginson.com
// Written by David Megginson
// This class is in the Public Domain. NO WARRANTY! // This class is in the Public Domain. NO WARRANTY!
// $Id$ // $Id$
@ -14,14 +13,11 @@ import java.util.Vector;
/** /**
* Encapsulate Namespace logic for use by applications using SAX, * Encapsulate Namespace logic for use by SAX drivers.
* or internally by SAX drivers.
* *
* <blockquote> * <blockquote>
* <em>This module, both source code and documentation, is in the * <em>This module, both source code and documentation, is in the
* Public Domain, and comes with <strong>NO WARRANTY</strong>.</em> * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
* See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
* for further information.
* </blockquote> * </blockquote>
* *
* <p>This class encapsulates the logic of Namespace processing: * <p>This class encapsulates the logic of Namespace processing:
@ -43,16 +39,16 @@ import java.util.Vector;
* support.declarePrefix("", "http://www.w3.org/1999/xhtml"); * support.declarePrefix("", "http://www.w3.org/1999/xhtml");
* support.declarePrefix("dc", "http://www.purl.org/dc#"); * support.declarePrefix("dc", "http://www.purl.org/dc#");
* *
* parts = support.processName("p", parts, false); * String parts[] = support.processName("p", parts, false);
* System.out.println("Namespace URI: " + parts[0]); * System.out.println("Namespace URI: " + parts[0]);
* System.out.println("Local name: " + parts[1]); * System.out.println("Local name: " + parts[1]);
* System.out.println("Raw name: " + parts[2]); * System.out.println("Raw name: " + parts[2]);
*
* parts = support.processName("dc:title", parts, false); * String parts[] = support.processName("dc:title", parts, false);
* System.out.println("Namespace URI: " + parts[0]); * System.out.println("Namespace URI: " + parts[0]);
* System.out.println("Local name: " + parts[1]); * System.out.println("Local name: " + parts[1]);
* System.out.println("Raw name: " + parts[2]); * System.out.println("Raw name: " + parts[2]);
*
* support.popContext(); * support.popContext();
* </pre> * </pre>
* *
@ -61,14 +57,15 @@ import java.util.Vector;
* prefix/URI mapping is repeated for each context (for example), this * prefix/URI mapping is repeated for each context (for example), this
* class will be somewhat less efficient.</p> * class will be somewhat less efficient.</p>
* *
* <p>Although SAX drivers (parsers) may choose to use this class to * This class is <strong>not</strong> the 2.0.1 version; this was taken from Xerces
* implement namespace handling, they are not required to do so. * to ensure JAXP 1.2 compatibility. It is unlikely the code changes
* Applications must track namespace information themselves if they * between this class and the 2.0.1 version are significant, but
* want to use namespace information. * it is best to be safe.
* *
* @since SAX 2.0 * @since SAX 2.0
* @author David Megginson * @author David Megginson,
* @version 2.0.1 (sax2r2) * <a href="mailto:sax@megginson.com">sax@megginson.com</a>
* @version 2.0
*/ */
public class NamespaceSupport public class NamespaceSupport
{ {
@ -80,9 +77,7 @@ public class NamespaceSupport
/** /**
* The XML Namespace URI as a constant. * The XML Namespace as a constant.
* The value is <code>http://www.w3.org/XML/1998/namespace</code>
* as defined in the XML Namespaces specification.
* *
* <p>This is the Namespace URI that is automatically mapped * <p>This is the Namespace URI that is automatically mapped
* to the "xml" prefix.</p> * to the "xml" prefix.</p>
@ -135,45 +130,21 @@ public class NamespaceSupport
/** /**
* Start a new Namespace context. * Start a new Namespace context.
* The new context will automatically inherit *
* <p>Normally, you should push a new context at the beginning
* of each XML element: the new context will automatically inherit
* the declarations of its parent context, but it will also keep * the declarations of its parent context, but it will also keep
* track of which declarations were made within this context. * track of which declarations were made within this context.</p>
*
* <p>Event callback code should start a new context once per element.
* This means being ready to call this in either of two places.
* For elements that don't include namespace declarations, the
* <em>ContentHandler.startElement()</em> callback is the right place.
* For elements with such a declaration, it'd done in the first
* <em>ContentHandler.startPrefixMapping()</em> callback.
* A boolean flag can be used to
* track whether a context has been started yet. When either of
* those methods is called, it checks the flag to see if a new context
* needs to be started. If so, it starts the context and sets the
* flag. After <em>ContentHandler.startElement()</em>
* does that, it always clears the flag.
*
* <p>Normally, SAX drivers would push a new context at the beginning
* of each XML element. Then they perform a first pass over the
* attributes to process all namespace declarations, making
* <em>ContentHandler.startPrefixMapping()</em> callbacks.
* Then a second pass is made, to determine the namespace-qualified
* names for all attributes and for the element name.
* Finally all the information for the
* <em>ContentHandler.startElement()</em> callback is available,
* so it can then be made.
* *
* <p>The Namespace support object always starts with a base context * <p>The Namespace support object always starts with a base context
* already in force: in this context, only the "xml" prefix is * already in force: in this context, only the "xml" prefix is
* declared.</p> * declared.</p>
* *
* @see org.xml.sax.ContentHandler
* @see #popContext * @see #popContext
*/ */
public void pushContext () public void pushContext ()
{ {
int max = contexts.length; int max = contexts.length;
contexts [contextPos].declsOK = false;
contextPos++; contextPos++;
// Extend the array if necessary // Extend the array if necessary
@ -212,7 +183,6 @@ public class NamespaceSupport
*/ */
public void popContext () public void popContext ()
{ {
contexts[contextPos].clear();
contextPos--; contextPos--;
if (contextPos < 0) { if (contextPos < 0) {
throw new EmptyStackException(); throw new EmptyStackException();
@ -228,42 +198,29 @@ public class NamespaceSupport
/** /**
* Declare a Namespace prefix. All prefixes must be declared * Declare a Namespace prefix.
* before they are referenced. For example, a SAX driver (parser)
* would scan an element's attributes
* in two passes: first for namespace declarations,
* then a second pass using {@link #processName processName()} to
* interpret prefixes against (potentially redefined) prefixes.
* *
* <p>This method declares a prefix in the current Namespace * <p>This method declares a prefix in the current Namespace
* context; the prefix will remain in force until this context * context; the prefix will remain in force until this context
* is popped, unless it is shadowed in a descendant context.</p> * is popped, unless it is shadowed in a descendant context.</p>
* *
* <p>To declare the default element Namespace, use the empty string as * <p>To declare a default Namespace, use the empty string. The
* the prefix.</p> * prefix must not be "xml" or "xmlns".</p>
* *
* <p>Note that you must <em>not</em> declare a prefix after * <p>Note that you must <em>not</em> declare a prefix after
* you've pushed and popped another Namespace context, or * you've pushed and popped another Namespace.</p>
* treated the declarations phase as complete by processing
* a prefixed name.</p>
* *
* <p>Note that there is an asymmetry in this library: {@link * <p>Note that there is an asymmetry in this library: while {@link
* #getPrefix getPrefix} will not return the "" prefix, * #getPrefix getPrefix} will not return the default "" prefix,
* even if you have declared a default element namespace. * even if you have declared one; to check for a default prefix,
* To check for a default namespace,
* you have to look it up explicitly using {@link #getURI getURI}. * you have to look it up explicitly using {@link #getURI getURI}.
* This asymmetry exists to make it easier to look up prefixes * This asymmetry exists to make it easier to look up prefixes
* for attribute names, where the default prefix is not allowed.</p> * for attribute names, where the default prefix is not allowed.</p>
* *
* @param prefix The prefix to declare, or the empty string to * @param prefix The prefix to declare, or null for the empty
* indicate the default element namespace. This may never have * string.
* the value "xml" or "xmlns".
* @param uri The Namespace URI to associate with the prefix. * @param uri The Namespace URI to associate with the prefix.
* @return true if the prefix was legal, false otherwise * @return true if the prefix was legal, false otherwise
* @exception IllegalStateException when a prefix is declared
* after looking up a name in the context, or after pushing
* another context on top of it.
*
* @see #processName * @see #processName
* @see #getURI * @see #getURI
* @see #getPrefix * @see #getPrefix
@ -280,8 +237,7 @@ public class NamespaceSupport
/** /**
* Process a raw XML 1.0 name, after all declarations in the current * Process a raw XML 1.0 name.
* context have been handled by {@link #declarePrefix declarePrefix()}.
* *
* <p>This method processes a raw XML 1.0 name in the current * <p>This method processes a raw XML 1.0 name in the current
* context by removing the prefix and looking it up among the * context by removing the prefix and looking it up among the
@ -304,7 +260,7 @@ public class NamespaceSupport
* *
* <p>Note that attribute names are processed differently than * <p>Note that attribute names are processed differently than
* element names: an unprefixed element name will received the * element names: an unprefixed element name will received the
* default Namespace (if any), while an unprefixed attribute name * default Namespace (if any), while an unprefixed element name
* will not.</p> * will not.</p>
* *
* @param qName The raw XML 1.0 name to be processed. * @param qName The raw XML 1.0 name to be processed.
@ -468,14 +424,9 @@ public class NamespaceSupport
/** /**
* Internal class for a single Namespace context. * Internal class for a single Namespace context.
* *
* <p>This module caches and reuses Namespace contexts, * <p>This module caches and reuses Namespace contexts, so the number allocated
* so the number allocated
* will be equal to the element depth of the document, not to the total * will be equal to the element depth of the document, not to the total
* number of elements (i.e. 5-10 rather than tens of thousands). * number of elements (i.e. 5-10 rather than tens of thousands).</p>
* Also, data structures used to represent contexts are shared when
* possible (child contexts without declarations) to further reduce
* the amount of memory that's consumed.
* </p>
*/ */
final class Context { final class Context {
@ -490,8 +441,6 @@ public class NamespaceSupport
/** /**
* (Re)set the parent of this Namespace context. * (Re)set the parent of this Namespace context.
* The context must either have been freshly constructed,
* or must have been cleared.
* *
* @param context The parent Namespace context object. * @param context The parent Namespace context object.
*/ */
@ -504,24 +453,7 @@ public class NamespaceSupport
elementNameTable = parent.elementNameTable; elementNameTable = parent.elementNameTable;
attributeNameTable = parent.attributeNameTable; attributeNameTable = parent.attributeNameTable;
defaultNS = parent.defaultNS; defaultNS = parent.defaultNS;
declSeen = false; tablesDirty = false;
declsOK = true;
}
/**
* Makes associated state become collectible,
* invalidating this context.
* {@link #setParent} must be called before
* this context may be used again.
*/
void clear ()
{
parent = null;
prefixTable = null;
uriTable = null;
elementNameTable = null;
attributeNameTable = null;
defaultNS = null;
} }
@ -535,10 +467,7 @@ public class NamespaceSupport
void declarePrefix (String prefix, String uri) void declarePrefix (String prefix, String uri)
{ {
// Lazy processing... // Lazy processing...
if (!declsOK) if (!tablesDirty) {
throw new IllegalStateException (
"can't declare any more prefixes in this context");
if (!declSeen) {
copyTables(); copyTables();
} }
if (declarations == null) { if (declarations == null) {
@ -577,14 +506,11 @@ public class NamespaceSupport
String name[]; String name[];
Hashtable table; Hashtable table;
// detect errors in call sequence
declsOK = false;
// Select the appropriate table. // Select the appropriate table.
if (isAttribute) { if (isAttribute) {
table = attributeNameTable;
} else {
table = elementNameTable; table = elementNameTable;
} else {
table = attributeNameTable;
} }
// Start by looking in the cache, and // Start by looking in the cache, and
@ -596,11 +522,8 @@ public class NamespaceSupport
} }
// We haven't seen this name in this // We haven't seen this name in this
// context before. Maybe in the parent // context before.
// context, but we can't assume prefix
// bindings are the same.
name = new String[3]; name = new String[3];
name[2] = qName.intern();
int index = qName.indexOf(':'); int index = qName.indexOf(':');
@ -611,7 +534,8 @@ public class NamespaceSupport
} else { } else {
name[0] = defaultNS; name[0] = defaultNS;
} }
name[1] = name[2]; name[1] = qName.intern();
name[2] = name[1];
} }
// Prefix // Prefix
@ -629,11 +553,12 @@ public class NamespaceSupport
} }
name[0] = uri; name[0] = uri;
name[1] = local.intern(); name[1] = local.intern();
name[2] = qName.intern();
} }
// Save in the cache for future use. // Save in the cache for future use.
// (Could be shared with parent context...)
table.put(name[2], name); table.put(name[2], name);
tablesDirty = true;
return name; return name;
} }
@ -739,7 +664,7 @@ public class NamespaceSupport
} }
elementNameTable = new Hashtable(); elementNameTable = new Hashtable();
attributeNameTable = new Hashtable(); attributeNameTable = new Hashtable();
declSeen = true; tablesDirty = true;
} }
@ -753,7 +678,6 @@ public class NamespaceSupport
Hashtable elementNameTable; Hashtable elementNameTable;
Hashtable attributeNameTable; Hashtable attributeNameTable;
String defaultNS = null; String defaultNS = null;
boolean declsOK = true;
@ -762,7 +686,7 @@ public class NamespaceSupport
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
private Vector declarations = null; private Vector declarations = null;
private boolean declSeen = false; private boolean tablesDirty = false;
private Context parent = null; private Context parent = null;
} }
} }

View File

@ -3,7 +3,6 @@
// Written by Edwin Goei, edwingo@apache.org // Written by Edwin Goei, edwingo@apache.org
// and by David Brownell, dbrownell@users.sourceforge.net // and by David Brownell, dbrownell@users.sourceforge.net
// NO WARRANTY! This class is in the Public Domain. // NO WARRANTY! This class is in the Public Domain.
// $Id$ // $Id$
package org.xml.sax.helpers; package org.xml.sax.helpers;
@ -24,32 +23,64 @@ import java.lang.reflect.InvocationTargetException;
* <p>This class contains a static method for creating an instance of a * <p>This class contains a static method for creating an instance of a
* class from an explicit class name. It tries to use the thread's context * class from an explicit class name. It tries to use the thread's context
* ClassLoader if possible and falls back to using * ClassLoader if possible and falls back to using
* Class.forName(String).</p> * Class.forName(String). It also takes into account JDK 1.2+'s
* AccessController mechanism for performing its actions. </p>
* *
* <p>This code is designed to compile and run on JDK version 1.1 and later * <p>This code is designed to run on JDK version 1.1 and later and compile
* including versions of Java 2.</p> * on versions of Java 2 and later.</p>
* *
* @author Edwin Goei, David Brownell * <p>This is <strong>not</strong> the NewInstance accompanying SAX 2.0.1; it
* @version 2.0.1 (sax2r2) * represents some fixes to that code.
*
* @author Edwin Goei, David Brownell, Neil Graham
* @version $Id$
*/ */
class NewInstance { class NewInstance {
// constants
// governs whether, if we fail in finding a class even
// when given a classloader, we'll make a last-ditch attempt
// to use the current classloader.
private static final boolean DO_FALLBACK = true;
/** /**
* Creates a new instance of the specified class name * Creates a new instance of the specified class name
* *
* Package private so this code is not exposed at the API level. * Package private so this code is not exposed at the API level.
*/ */
static Object newInstance (ClassLoader classLoader, String className) static Object newInstance (ClassLoader cl, String className)
throws ClassNotFoundException, IllegalAccessException, throws ClassNotFoundException, IllegalAccessException,
InstantiationException InstantiationException
{ {
Class driverClass;
if (classLoader == null) { Class providerClass;
driverClass = Class.forName(className); if (cl == null) {
// XXX Use the bootstrap ClassLoader. There is no way to
// load a class using the bootstrap ClassLoader that works
// in both JDK 1.1 and Java 2. However, this should still
// work b/c the following should be true:
//
// (cl == null) iff current ClassLoader == null
//
// Thus Class.forName(String) will use the current
// ClassLoader which will be the bootstrap ClassLoader.
providerClass = Class.forName(className);
} else { } else {
driverClass = classLoader.loadClass(className); try {
providerClass = cl.loadClass(className);
} catch (ClassNotFoundException x) {
if (DO_FALLBACK) {
// Fall back to current classloader
cl = NewInstance.class.getClassLoader();
providerClass = cl.loadClass(className);
} else {
throw x;
} }
return driverClass.newInstance(); }
}
Object instance = providerClass.newInstance();
return instance;
} }
/** /**
@ -58,23 +89,18 @@ class NewInstance {
*/ */
static ClassLoader getClassLoader () static ClassLoader getClassLoader ()
{ {
Method m = null;
try { SecuritySupport ss = SecuritySupport.getInstance();
m = Thread.class.getMethod("getContextClassLoader", null);
} catch (NoSuchMethodException e) { // Figure out which ClassLoader to use for loading the provider
// Assume that we are running JDK 1.1, use the current ClassLoader // class. If there is a Context ClassLoader then use it.
return NewInstance.class.getClassLoader(); ClassLoader cl = ss.getContextClassLoader();
} if (cl == null) {
// Assert: we are on JDK 1.1 or we have no Context ClassLoader
// so use the current ClassLoader
cl = NewInstance.class.getClassLoader();
}
return cl;
try {
return (ClassLoader) m.invoke(Thread.currentThread(), null);
} catch (IllegalAccessException e) {
// assert(false)
throw new UnknownError(e.getMessage());
} catch (InvocationTargetException e) {
// assert(e.getTargetException() instanceof SecurityException)
throw new UnknownError(e.getMessage());
}
} }
} }

View File

@ -1,6 +1,5 @@
// ParserAdapter.java - adapt a SAX1 Parser to a SAX2 XMLReader. // ParserAdapter.java - adapt a SAX1 Parser to a SAX2 XMLReader.
// http://www.saxproject.org // Written by David Megginson, sax@megginson.com
// Written by David Megginson
// NO WARRANTY! This class is in the public domain. // NO WARRANTY! This class is in the public domain.
// $Id$ // $Id$
@ -9,7 +8,6 @@ package org.xml.sax.helpers;
import java.io.IOException; import java.io.IOException;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.Vector;
import org.xml.sax.Parser; // deprecated import org.xml.sax.Parser; // deprecated
import org.xml.sax.InputSource; import org.xml.sax.InputSource;
@ -35,8 +33,6 @@ import org.xml.sax.SAXNotSupportedException;
* <blockquote> * <blockquote>
* <em>This module, both source code and documentation, is in the * <em>This module, both source code and documentation, is in the
* Public Domain, and comes with <strong>NO WARRANTY</strong>.</em> * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
* See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
* for further information.
* </blockquote> * </blockquote>
* *
* <p>This class wraps a SAX1 {@link org.xml.sax.Parser Parser} * <p>This class wraps a SAX1 {@link org.xml.sax.Parser Parser}
@ -48,9 +44,15 @@ import org.xml.sax.SAXNotSupportedException;
* <p>This adapter does not test for duplicate Namespace-qualified * <p>This adapter does not test for duplicate Namespace-qualified
* attribute names.</p> * attribute names.</p>
* *
* <p> Note that this is <strong>not</strong> the class shipped with
* SAX 2.0.1; this class takes into account the presence of AccessControllers
* in J2EE 1.4. It also throws NullPointerExceptions when setters are
* called with null parameters; the 2.0.1 version does not exhibit this behaviour.</p>
*
* @since SAX 2.0 * @since SAX 2.0
* @author David Megginson * @author David Megginson,
* @version 2.0.1 (sax2r2) * <a href="mailto:sax@megginson.com">sax@megginson.com</a>
* @version 2.0
* @see org.xml.sax.helpers.XMLReaderAdapter * @see org.xml.sax.helpers.XMLReaderAdapter
* @see org.xml.sax.XMLReader * @see org.xml.sax.XMLReader
* @see org.xml.sax.Parser * @see org.xml.sax.Parser
@ -70,7 +72,7 @@ public class ParserAdapter implements XMLReader, DocumentHandler
* <p>Use the "org.xml.sax.parser" property to locate the * <p>Use the "org.xml.sax.parser" property to locate the
* embedded SAX1 driver.</p> * embedded SAX1 driver.</p>
* *
* @exception SAXException If the embedded driver * @exception org.xml.sax.SAXException If the embedded driver
* cannot be instantiated or if the * cannot be instantiated or if the
* org.xml.sax.parser property is not specified. * org.xml.sax.parser property is not specified.
*/ */
@ -79,7 +81,8 @@ public class ParserAdapter implements XMLReader, DocumentHandler
{ {
super(); super();
String driver = System.getProperty("org.xml.sax.parser"); SecuritySupport ss = SecuritySupport.getInstance();
String driver = ss.getSystemProperty("org.xml.sax.parser");
try { try {
setup(ParserFactory.makeParser()); setup(ParserFactory.makeParser());
@ -159,37 +162,46 @@ public class ParserAdapter implements XMLReader, DocumentHandler
private final static String FEATURES = "http://xml.org/sax/features/"; private final static String FEATURES = "http://xml.org/sax/features/";
private final static String NAMESPACES = FEATURES + "namespaces"; private final static String NAMESPACES = FEATURES + "namespaces";
private final static String NAMESPACE_PREFIXES = FEATURES + "namespace-prefixes"; private final static String NAMESPACE_PREFIXES = FEATURES + "namespace-prefixes";
private final static String VALIDATION = FEATURES + "validation";
private final static String EXTERNAL_GENERAL =
FEATURES + "external-general-entities";
private final static String EXTERNAL_PARAMETER =
FEATURES + "external-parameter-entities";
/** /**
* Set a feature flag for the parser. * Set a feature for the parser.
* *
* <p>The only features recognized are namespaces and * <p>The only features supported are namespaces and
* namespace-prefixes.</p> * namespace-prefixes.</p>
* *
* @param name The feature name, as a complete URI. * @param name The feature name, as a complete URI.
* @param value The requested feature value. * @param state The requested feature state.
* @exception SAXNotRecognizedException If the feature * @exception org.xml.sax.SAXNotRecognizedException If the feature
* can't be assigned or retrieved. * name is not known.
* @exception SAXNotSupportedException If the feature * @exception org.xml.sax.SAXNotSupportedException If the feature
* can't be assigned that value. * state is not supported.
* @see org.xml.sax.XMLReader#setFeature * @see org.xml.sax.XMLReader#setFeature
*/ */
public void setFeature (String name, boolean value) public void setFeature (String name, boolean state)
throws SAXNotRecognizedException, SAXNotSupportedException throws SAXNotRecognizedException, SAXNotSupportedException
{ {
if (name.equals(NAMESPACES)) { if (name.equals(NAMESPACES)) {
checkNotParsing("feature", name); checkNotParsing("feature", name);
namespaces = value; namespaces = state;
if (!namespaces && !prefixes) { if (!namespaces && !prefixes) {
prefixes = true; prefixes = true;
} }
} else if (name.equals(NAMESPACE_PREFIXES)) { } else if (name.equals(NAMESPACE_PREFIXES)) {
checkNotParsing("feature", name); checkNotParsing("feature", name);
prefixes = value; prefixes = state;
if (!prefixes && !namespaces) { if (!prefixes && !namespaces) {
namespaces = true; namespaces = true;
} }
} else if (name.equals(VALIDATION) ||
name.equals(EXTERNAL_GENERAL) ||
name.equals(EXTERNAL_PARAMETER)) {
throw new SAXNotSupportedException("Feature: " + name);
} else { } else {
throw new SAXNotRecognizedException("Feature: " + name); throw new SAXNotRecognizedException("Feature: " + name);
} }
@ -197,17 +209,17 @@ public class ParserAdapter implements XMLReader, DocumentHandler
/** /**
* Check a parser feature flag. * Check a parser feature.
* *
* <p>The only features recognized are namespaces and * <p>The only features supported are namespaces and
* namespace-prefixes.</p> * namespace-prefixes.</p>
* *
* @param name The feature name, as a complete URI. * @param name The feature name, as a complete URI.
* @return The current feature value. * @return The current feature state.
* @exception SAXNotRecognizedException If the feature * @exception org.xml.sax.SAXNotRecognizedException If the feature
* value can't be assigned or retrieved. * name is not known.
* @exception SAXNotSupportedException If the * @exception org.xml.sax.SAXNotSupportedException If querying the
* feature is not currently readable. * feature state is not supported.
* @see org.xml.sax.XMLReader#setFeature * @see org.xml.sax.XMLReader#setFeature
*/ */
public boolean getFeature (String name) public boolean getFeature (String name)
@ -217,6 +229,10 @@ public class ParserAdapter implements XMLReader, DocumentHandler
return namespaces; return namespaces;
} else if (name.equals(NAMESPACE_PREFIXES)) { } else if (name.equals(NAMESPACE_PREFIXES)) {
return prefixes; return prefixes;
} else if (name.equals(VALIDATION) ||
name.equals(EXTERNAL_GENERAL) ||
name.equals(EXTERNAL_PARAMETER)) {
throw new SAXNotSupportedException("Feature: " + name);
} else { } else {
throw new SAXNotRecognizedException("Feature: " + name); throw new SAXNotRecognizedException("Feature: " + name);
} }
@ -226,14 +242,14 @@ public class ParserAdapter implements XMLReader, DocumentHandler
/** /**
* Set a parser property. * Set a parser property.
* *
* <p>No properties are currently recognized.</p> * <p>No special properties are currently supported.</p>
* *
* @param name The property name. * @param name The property name.
* @param value The property value. * @param value The property value.
* @exception SAXNotRecognizedException If the property * @exception org.xml.sax.SAXNotRecognizedException If the feature
* value can't be assigned or retrieved. * name is not known.
* @exception SAXNotSupportedException If the property * @exception org.xml.sax.SAXNotSupportedException If the feature
* can't be assigned that value. * state is not supported.
* @see org.xml.sax.XMLReader#setProperty * @see org.xml.sax.XMLReader#setProperty
*/ */
public void setProperty (String name, Object value) public void setProperty (String name, Object value)
@ -246,14 +262,14 @@ public class ParserAdapter implements XMLReader, DocumentHandler
/** /**
* Get a parser property. * Get a parser property.
* *
* <p>No properties are currently recognized.</p> * <p>No special properties are currently supported.</p>
* *
* @param name The property name. * @param name The property name.
* @return The property value. * @return The property value.
* @exception SAXNotRecognizedException If the property * @exception org.xml.sax.SAXNotRecognizedException If the feature
* value can't be assigned or retrieved. * name is not known.
* @exception SAXNotSupportedException If the property * @exception org.xml.sax.SAXNotSupportedException If the feature
* value is not currently readable. * state is not supported.
* @see org.xml.sax.XMLReader#getProperty * @see org.xml.sax.XMLReader#getProperty
*/ */
public Object getProperty (String name) public Object getProperty (String name)
@ -267,10 +283,15 @@ public class ParserAdapter implements XMLReader, DocumentHandler
* Set the entity resolver. * Set the entity resolver.
* *
* @param resolver The new entity resolver. * @param resolver The new entity resolver.
* @exception java.lang.NullPointerException If the entity resolver
* parameter is null.
* @see org.xml.sax.XMLReader#setEntityResolver * @see org.xml.sax.XMLReader#setEntityResolver
*/ */
public void setEntityResolver (EntityResolver resolver) public void setEntityResolver (EntityResolver resolver)
{ {
if (resolver == null) {
throw new NullPointerException("Null entity resolver");
}
entityResolver = resolver; entityResolver = resolver;
} }
@ -291,10 +312,15 @@ public class ParserAdapter implements XMLReader, DocumentHandler
* Set the DTD handler. * Set the DTD handler.
* *
* @param resolver The new DTD handler. * @param resolver The new DTD handler.
* @exception java.lang.NullPointerException If the DTD handler
* parameter is null.
* @see org.xml.sax.XMLReader#setEntityResolver * @see org.xml.sax.XMLReader#setEntityResolver
*/ */
public void setDTDHandler (DTDHandler handler) public void setDTDHandler (DTDHandler handler)
{ {
if (handler == null) {
throw new NullPointerException("Null DTD handler");
}
dtdHandler = handler; dtdHandler = handler;
} }
@ -315,10 +341,15 @@ public class ParserAdapter implements XMLReader, DocumentHandler
* Set the content handler. * Set the content handler.
* *
* @param resolver The new content handler. * @param resolver The new content handler.
* @exception java.lang.NullPointerException If the content handler
* parameter is null.
* @see org.xml.sax.XMLReader#setEntityResolver * @see org.xml.sax.XMLReader#setEntityResolver
*/ */
public void setContentHandler (ContentHandler handler) public void setContentHandler (ContentHandler handler)
{ {
if (handler == null) {
throw new NullPointerException("Null content handler");
}
contentHandler = handler; contentHandler = handler;
} }
@ -339,10 +370,15 @@ public class ParserAdapter implements XMLReader, DocumentHandler
* Set the error handler. * Set the error handler.
* *
* @param resolver The new error handler. * @param resolver The new error handler.
* @exception java.lang.NullPointerException If the error handler
* parameter is null.
* @see org.xml.sax.XMLReader#setEntityResolver * @see org.xml.sax.XMLReader#setEntityResolver
*/ */
public void setErrorHandler (ErrorHandler handler) public void setErrorHandler (ErrorHandler handler)
{ {
if (handler == null) {
throw new NullPointerException("Null error handler");
}
errorHandler = handler; errorHandler = handler;
} }
@ -365,7 +401,7 @@ public class ParserAdapter implements XMLReader, DocumentHandler
* @param systemId The absolute URL of the document. * @param systemId The absolute URL of the document.
* @exception java.io.IOException If there is a problem reading * @exception java.io.IOException If there is a problem reading
* the raw content of the document. * the raw content of the document.
* @exception SAXException If there is a problem * @exception org.xml.sax.SAXException If there is a problem
* processing the document. * processing the document.
* @see #parse(org.xml.sax.InputSource) * @see #parse(org.xml.sax.InputSource)
* @see org.xml.sax.Parser#parse(java.lang.String) * @see org.xml.sax.Parser#parse(java.lang.String)
@ -383,7 +419,7 @@ public class ParserAdapter implements XMLReader, DocumentHandler
* @param input An input source for the document. * @param input An input source for the document.
* @exception java.io.IOException If there is a problem reading * @exception java.io.IOException If there is a problem reading
* the raw content of the document. * the raw content of the document.
* @exception SAXException If there is a problem * @exception org.xml.sax.SAXException If there is a problem
* processing the document. * processing the document.
* @see #parse(java.lang.String) * @see #parse(java.lang.String)
* @see org.xml.sax.Parser#parse(org.xml.sax.InputSource) * @see org.xml.sax.Parser#parse(org.xml.sax.InputSource)
@ -412,7 +448,6 @@ public class ParserAdapter implements XMLReader, DocumentHandler
/** /**
* Adapter implementation method; do not call.
* Adapt a SAX1 document locator event. * Adapt a SAX1 document locator event.
* *
* @param locator A document locator. * @param locator A document locator.
@ -428,10 +463,9 @@ public class ParserAdapter implements XMLReader, DocumentHandler
/** /**
* Adapter implementation method; do not call.
* Adapt a SAX1 start document event. * Adapt a SAX1 start document event.
* *
* @exception SAXException The client may raise a * @exception org.xml.sax.SAXException The client may raise a
* processing exception. * processing exception.
* @see org.xml.sax.DocumentHandler#startDocument * @see org.xml.sax.DocumentHandler#startDocument
*/ */
@ -445,10 +479,9 @@ public class ParserAdapter implements XMLReader, DocumentHandler
/** /**
* Adapter implementation method; do not call.
* Adapt a SAX1 end document event. * Adapt a SAX1 end document event.
* *
* @exception SAXException The client may raise a * @exception org.xml.sax.SAXException The client may raise a
* processing exception. * processing exception.
* @see org.xml.sax.DocumentHandler#endDocument * @see org.xml.sax.DocumentHandler#endDocument
*/ */
@ -462,25 +495,16 @@ public class ParserAdapter implements XMLReader, DocumentHandler
/** /**
* Adapter implementation method; do not call.
* Adapt a SAX1 startElement event. * Adapt a SAX1 startElement event.
* *
* <p>If necessary, perform Namespace processing.</p> * <p>If necessary, perform Namespace processing.</p>
* *
* @param qName The qualified (prefixed) name. * @param qName The qualified (prefixed) name.
* @param qAtts The XML 1.0 attribute list (with qnames). * @param qAtts The XML 1.0 attribute list (with qnames).
* @exception SAXException The client may raise a
* processing exception.
*/ */
public void startElement (String qName, AttributeList qAtts) public void startElement (String qName, AttributeList qAtts)
throws SAXException throws SAXException
{ {
// These are exceptions from the
// first pass; they should be
// ignored if there's a second pass,
// but reported otherwise.
Vector exceptions = null;
// If we're not doing Namespace // If we're not doing Namespace
// processing, dispatch this quickly. // processing, dispatch this quickly.
if (!namespaces) { if (!namespaces) {
@ -495,103 +519,80 @@ public class ParserAdapter implements XMLReader, DocumentHandler
// OK, we're doing Namespace processing. // OK, we're doing Namespace processing.
nsSupport.pushContext(); nsSupport.pushContext();
int length = qAtts.getLength(); boolean seenDecl = false;
// First pass: handle NS decls
for (int i = 0; i < length; i++) {
String attQName = qAtts.getName(i);
if (!attQName.startsWith("xmlns"))
continue;
// Could be a declaration...
String prefix;
int n = attQName.indexOf(':');
// xmlns=...
if (n == -1 && attQName.length () == 5) {
prefix = "";
} else if (n != 5) {
// XML namespaces spec doesn't discuss "xmlnsf:oo"
// (and similarly named) attributes ... at most, warn
continue;
} else // xmlns:foo=...
prefix = attQName.substring(n+1);
String value = qAtts.getValue(i);
if (!nsSupport.declarePrefix(prefix, value)) {
reportError("Illegal Namespace prefix: " + prefix);
continue;
}
if (contentHandler != null)
contentHandler.startPrefixMapping(prefix, value);
}
// Second pass: copy all relevant
// attributes into the SAX2 AttributeList
// using updated prefix bindings
atts.clear(); atts.clear();
// Take a first pass and copy all
// attributes into the SAX2 attribute
// list, noting any Namespace
// declarations.
int length = qAtts.getLength();
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
String attQName = qAtts.getName(i); String attQName = qAtts.getName(i);
String type = qAtts.getType(i); String type = qAtts.getType(i);
String value = qAtts.getValue(i); String value = qAtts.getValue(i);
// Declaration? // Found a declaration...
if (attQName.startsWith("xmlns")) { if (attQName.startsWith("xmlns")) {
String prefix; String prefix;
int n = attQName.indexOf(':'); int n = attQName.indexOf(':');
if (n == -1) {
if (n == -1 && attQName.length () == 5) {
prefix = ""; prefix = "";
} else if (n != 5) {
// XML namespaces spec doesn't discuss "xmlnsf:oo"
// (and similarly named) attributes ... ignore
prefix = null;
} else { } else {
prefix = attQName.substring(n+1); prefix = attQName.substring(n+1);
} }
// Yes, decl: report or prune if (!nsSupport.declarePrefix(prefix, value)) {
if (prefix != null) { reportError("Illegal Namespace prefix: " + prefix);
if (prefixes) }
if (contentHandler != null) {
contentHandler.startPrefixMapping(prefix, value);
}
// We may still have to add this to
// the list.
if (prefixes) {
atts.addAttribute("", "", attQName.intern(), atts.addAttribute("", "", attQName.intern(),
type, value); type, value);
continue;
}
} }
seenDecl = true;
// Not a declaration -- report // This isn't a declaration.
try { } else {
String attName[] = processName(attQName, true, true); String attName[] = processName(attQName, true);
atts.addAttribute(attName[0], attName[1], attName[2], atts.addAttribute(attName[0], attName[1], attName[2],
type, value); type, value);
} catch (SAXException e) {
if (exceptions == null)
exceptions = new Vector();
exceptions.addElement(e);
atts.addAttribute("", attQName, attQName, type, value);
} }
} }
// now handle the deferred exception reports // If there was a Namespace declaration,
if (exceptions != null && errorHandler != null) { // we have to make a second pass just
for (int i = 0; i < exceptions.size(); i++) // to be safe -- this will happen very
errorHandler.error((SAXParseException) // rarely, possibly only once for each
(exceptions.elementAt(i))); // document.
if (seenDecl) {
length = atts.getLength();
for (int i = 0; i < length; i++) {
String attQName = atts.getQName(i);
if (!attQName.startsWith("xmlns")) {
String attName[] = processName(attQName, true);
atts.setURI(i, attName[0]);
atts.setLocalName(i, attName[1]);
}
}
} }
// OK, finally report the event. // OK, finally report the event.
if (contentHandler != null) { if (contentHandler != null) {
String name[] = processName(qName, false, false); String name[] = processName(qName, false);
contentHandler.startElement(name[0], name[1], name[2], atts); contentHandler.startElement(name[0], name[1], name[2], atts);
} }
} }
/** /**
* Adapter implementation method; do not call.
* Adapt a SAX1 end element event. * Adapt a SAX1 end element event.
* *
* @param qName The qualified (prefixed) name. * @param qName The qualified (prefixed) name.
* @exception SAXException The client may raise a * @exception org.xml.sax.SAXException The client may raise a
* processing exception. * processing exception.
* @see org.xml.sax.DocumentHandler#endElement * @see org.xml.sax.DocumentHandler#endElement
*/ */
@ -608,7 +609,7 @@ public class ParserAdapter implements XMLReader, DocumentHandler
} }
// Split the name. // Split the name.
String names[] = processName(qName, false, false); String names[] = processName(qName, false);
if (contentHandler != null) { if (contentHandler != null) {
contentHandler.endElement(names[0], names[1], names[2]); contentHandler.endElement(names[0], names[1], names[2]);
Enumeration prefixes = nsSupport.getDeclaredPrefixes(); Enumeration prefixes = nsSupport.getDeclaredPrefixes();
@ -622,13 +623,12 @@ public class ParserAdapter implements XMLReader, DocumentHandler
/** /**
* Adapter implementation method; do not call.
* Adapt a SAX1 characters event. * Adapt a SAX1 characters event.
* *
* @param ch An array of characters. * @param ch An array of characters.
* @param start The starting position in the array. * @param start The starting position in the array.
* @param length The number of characters to use. * @param length The number of characters to use.
* @exception SAXException The client may raise a * @exception org.xml.sax.SAXException The client may raise a
* processing exception. * processing exception.
* @see org.xml.sax.DocumentHandler#characters * @see org.xml.sax.DocumentHandler#characters
*/ */
@ -642,13 +642,12 @@ public class ParserAdapter implements XMLReader, DocumentHandler
/** /**
* Adapter implementation method; do not call.
* Adapt a SAX1 ignorable whitespace event. * Adapt a SAX1 ignorable whitespace event.
* *
* @param ch An array of characters. * @param ch An array of characters.
* @param start The starting position in the array. * @param start The starting position in the array.
* @param length The number of characters to use. * @param length The number of characters to use.
* @exception SAXException The client may raise a * @exception org.xml.sax.SAXException The client may raise a
* processing exception. * processing exception.
* @see org.xml.sax.DocumentHandler#ignorableWhitespace * @see org.xml.sax.DocumentHandler#ignorableWhitespace
*/ */
@ -662,12 +661,11 @@ public class ParserAdapter implements XMLReader, DocumentHandler
/** /**
* Adapter implementation method; do not call.
* Adapt a SAX1 processing instruction event. * Adapt a SAX1 processing instruction event.
* *
* @param target The processing instruction target. * @param target The processing instruction target.
* @param data The remainder of the processing instruction * @param data The remainder of the processing instruction
* @exception SAXException The client may raise a * @exception org.xml.sax.SAXException The client may raise a
* processing exception. * processing exception.
* @see org.xml.sax.DocumentHandler#processingInstruction * @see org.xml.sax.DocumentHandler#processingInstruction
*/ */
@ -717,22 +715,18 @@ public class ParserAdapter implements XMLReader, DocumentHandler
* @param qName The qualified (prefixed) name. * @param qName The qualified (prefixed) name.
* @param isAttribute true if this is an attribute name. * @param isAttribute true if this is an attribute name.
* @return The name split into three parts. * @return The name split into three parts.
* @exception SAXException The client may throw * @exception org.xml.sax.SAXException The client may throw
* an exception if there is an error callback. * an exception if there is an error callback.
*/ */
private String [] processName (String qName, boolean isAttribute, private String [] processName (String qName, boolean isAttribute)
boolean useException)
throws SAXException throws SAXException
{ {
String parts[] = nsSupport.processName(qName, nameParts, String parts[] = nsSupport.processName(qName, nameParts,
isAttribute); isAttribute);
if (parts == null) { if (parts == null) {
if (useException)
throw makeException("Undeclared prefix: " + qName);
reportError("Undeclared prefix: " + qName);
parts = new String[3]; parts = new String[3];
parts[0] = parts[1] = "";
parts[2] = qName.intern(); parts[2] = qName.intern();
reportError("Undeclared prefix: " + qName);
} }
return parts; return parts;
} }
@ -742,29 +736,23 @@ public class ParserAdapter implements XMLReader, DocumentHandler
* Report a non-fatal error. * Report a non-fatal error.
* *
* @param message The error message. * @param message The error message.
* @exception SAXException The client may throw * @exception org.xml.sax.SAXException The client may throw
* an exception. * an exception.
*/ */
void reportError (String message) void reportError (String message)
throws SAXException throws SAXException
{ {
if (errorHandler != null) if (errorHandler == null) {
errorHandler.error(makeException(message)); return;
} }
SAXParseException e;
/**
* Construct an exception for the current context.
*
* @param message The error message.
*/
private SAXParseException makeException (String message)
{
if (locator != null) { if (locator != null) {
return new SAXParseException(message, locator); e = new SAXParseException(message, locator);
} else { } else {
return new SAXParseException(message, null, null, -1, -1); e = new SAXParseException(message, null, null, -1, -1);
} }
errorHandler.error(e);
} }
@ -776,7 +764,7 @@ public class ParserAdapter implements XMLReader, DocumentHandler
* *
* @param type The type of thing (feature or property). * @param type The type of thing (feature or property).
* @param name The feature or property name. * @param name The feature or property name.
* @exception SAXNotSupportedException If a * @exception org.xml.sax.SAXNotSupportedException If a
* document is currently being parsed. * document is currently being parsed.
*/ */
private void checkNotParsing (String type, String name) private void checkNotParsing (String type, String name)

View File

@ -39,12 +39,15 @@ import org.xml.sax.Parser;
* <p>Note that the application still requires an XML parser that * <p>Note that the application still requires an XML parser that
* implements SAX1.</p> * implements SAX1.</p>
* *
* <p>Note that this is <strong>not</strong> the ParserFactory shipped with SAX 2.0.1;
* this class takes into account the needs of J2EE 1.4 AccessControllers.</p>
*
* @deprecated This class works with the deprecated * @deprecated This class works with the deprecated
* {@link org.xml.sax.Parser Parser} * {@link org.xml.sax.Parser Parser}
* interface. * interface.
* @since SAX 1.0 * @since SAX 1.0
* @author David Megginson * @author David Megginson
* @version 2.0.1 (sax2r2) * @version 2.0r2pre3
*/ */
public class ParserFactory { public class ParserFactory {
@ -85,7 +88,8 @@ public class ParserFactory {
NullPointerException, NullPointerException,
ClassCastException ClassCastException
{ {
String className = System.getProperty("org.xml.sax.parser"); SecuritySupport ss = SecuritySupport.getInstance();
String className = ss.getSystemProperty("org.xml.sax.parser");
if (className == null) { if (className == null) {
throw new NullPointerException("No value for sax.parser property"); throw new NullPointerException("No value for sax.parser property");
} else { } else {

View File

@ -0,0 +1,133 @@
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2002 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 name "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) 1999-2002, Sun Microsystems,
* Inc., http://www.sun.com. For more information on the Apache Software
* Foundation, please see <http://www.apache.org/>.
*/
package org.xml.sax.helpers;
import java.lang.reflect.*;
import java.net.*;
import java.io.*;
/**
* This class is duplicated for each JAXP subpackage so keep it in sync.
* It is package private and therefore is not exposed as part of the JAXP
* API.
*
* Base class with security related methods that work on JDK 1.1.
*/
class SecuritySupport {
/*
* Make this of type Object so that the verifier won't try to
* prove its type, thus possibly trying to load the SecuritySupport12
* class.
*/
private static final Object securitySupport;
static {
SecuritySupport ss = null;
try {
Class c = Class.forName("java.security.AccessController");
// if that worked, we're on 1.2.
/*
* Unfortunately, we can't load the class using reflection
* because the class is package private. And the class has
* to be package private so the APIs aren't exposed to other
* code that could use them to circumvent security. Thus,
* we accept the risk that the direct reference might fail
* on some JDK 1.1 JVMs, even though we would never execute
* this code in such a case. Sigh...
*/
ss = new SecuritySupport12();
} catch (Exception ex) {
// ignore it
} finally {
if (ss == null)
ss = new SecuritySupport();
securitySupport = ss;
}
}
/**
* Return an appropriate instance of this class, depending on whether
* we're on a JDK 1.1 or J2SE 1.2 (or later) system.
*/
public static SecuritySupport getInstance() {
return (SecuritySupport)securitySupport;
}
public ClassLoader getContextClassLoader() {
return null;
}
public String getSystemProperty(String propName) {
return System.getProperty(propName);
}
public FileInputStream getFileInputStream(File file)
throws FileNotFoundException
{
return new FileInputStream(file);
}
public InputStream getResourceAsStream(ClassLoader cl, String name) {
InputStream ris;
if (cl == null) {
ris = ClassLoader.getSystemResourceAsStream(name);
} else {
ris = cl.getResourceAsStream(name);
}
return ris;
}
}

View File

@ -0,0 +1,125 @@
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2002 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 name "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) 1999-2002, Sun Microsystems,
* Inc., http://www.sun.com. For more information on the Apache Software
* Foundation, please see <http://www.apache.org/>.
*/
package org.xml.sax.helpers;
import java.security.*;
import java.net.*;
import java.io.*;
import java.util.*;
/**
* This class is duplicated for each JAXP subpackage so keep it in sync.
* It is package private and therefore is not exposed as part of the JAXP
* API.
*
* Security related methods that only work on J2SE 1.2 and newer.
*/
class SecuritySupport12 extends SecuritySupport {
public ClassLoader getContextClassLoader() {
return (ClassLoader)
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
ClassLoader cl = null;
try {
cl = Thread.currentThread().getContextClassLoader();
} catch (SecurityException ex) { }
return cl;
}
});
}
public String getSystemProperty(final String propName) {
return (String)
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
return System.getProperty(propName);
}
});
}
public FileInputStream getFileInputStream(final File file)
throws FileNotFoundException
{
try {
return (FileInputStream)
AccessController.doPrivileged(new PrivilegedExceptionAction() {
public Object run() throws FileNotFoundException {
return new FileInputStream(file);
}
});
} catch (PrivilegedActionException e) {
throw (FileNotFoundException)e.getException();
}
}
public InputStream getResourceAsStream(final ClassLoader cl,
final String name)
{
return (InputStream)
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
InputStream ris;
if (cl == null) {
ris = ClassLoader.getSystemResourceAsStream(name);
} else {
ris = cl.getResourceAsStream(name);
}
return ris;
}
});
}
}

View File

@ -1,6 +1,5 @@
// XMLFilterImpl.java - base SAX2 filter implementation. // XMLFilterImpl.java - base SAX2 filter implementation.
// http://www.saxproject.org // Written by David Megginson, sax@megginson.com
// Written by David Megginson
// NO WARRANTY! This class is in the Public Domain. // NO WARRANTY! This class is in the Public Domain.
// $Id$ // $Id$
@ -30,8 +29,6 @@ import org.xml.sax.SAXNotRecognizedException;
* <blockquote> * <blockquote>
* <em>This module, both source code and documentation, is in the * <em>This module, both source code and documentation, is in the
* Public Domain, and comes with <strong>NO WARRANTY</strong>.</em> * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
* See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
* for further information.
* </blockquote> * </blockquote>
* *
* <p>This class is designed to sit between an {@link org.xml.sax.XMLReader * <p>This class is designed to sit between an {@link org.xml.sax.XMLReader
@ -41,9 +38,14 @@ import org.xml.sax.SAXNotRecognizedException;
* specific methods to modify the event stream or the configuration * specific methods to modify the event stream or the configuration
* requests as they pass through.</p> * requests as they pass through.</p>
* *
* <p>Note that this is <strong>not</strong> the version shipped with SAX 2.0.1; this class
* throws NullPointerExceptions when setter methods are called with null parameters;
* the 2.0.1 version does not exhibit this behaviour. </p>
*
* @since SAX 2.0 * @since SAX 2.0
* @author David Megginson * @author David Megginson,
* @version 2.0.1 (sax2r2) * <a href="mailto:sax@megginson.com">sax@megginson.com</a>
* @version 2.0
* @see org.xml.sax.XMLFilter * @see org.xml.sax.XMLFilter
* @see org.xml.sax.XMLReader * @see org.xml.sax.XMLReader
* @see org.xml.sax.EntityResolver * @see org.xml.sax.EntityResolver
@ -66,12 +68,10 @@ public class XMLFilterImpl
* *
* <p>This filter will have no parent: you must assign a parent * <p>This filter will have no parent: you must assign a parent
* before you start a parse or do any configuration with * before you start a parse or do any configuration with
* setFeature or setProperty, unless you use this as a pure event * setFeature or setProperty.</p>
* consumer rather than as an {@link XMLReader}.</p>
* *
* @see org.xml.sax.XMLReader#setFeature * @see org.xml.sax.XMLReader#setFeature
* @see org.xml.sax.XMLReader#setProperty * @see org.xml.sax.XMLReader#setProperty
* @see #setParent
*/ */
public XMLFilterImpl () public XMLFilterImpl ()
{ {
@ -109,10 +109,14 @@ public class XMLFilterImpl
* or to set or get a feature or property will fail.</p> * or to set or get a feature or property will fail.</p>
* *
* @param parent The parent XML reader. * @param parent The parent XML reader.
* @exception java.lang.NullPointerException If the parent is null.
* @see #getParent * @see #getParent
*/ */
public void setParent (XMLReader parent) public void setParent (XMLReader parent)
{ {
if (parent == null) {
throw new NullPointerException("Null parent");
}
this.parent = parent; this.parent = parent;
} }
@ -136,23 +140,24 @@ public class XMLFilterImpl
/** /**
* Set the value of a feature. * Set the state of a feature.
* *
* <p>This will always fail if the parent is null.</p> * <p>This will always fail if the parent is null.</p>
* *
* @param name The feature name. * @param name The feature name.
* @param value The requested feature value. * @param state The requested feature state.
* @exception org.xml.sax.SAXNotRecognizedException If the feature * @exception org.xml.sax.SAXNotRecognizedException When the
* value can't be assigned or retrieved from the parent. * XMLReader does not recognize the feature name.
* @exception org.xml.sax.SAXNotSupportedException When the * @exception org.xml.sax.SAXNotSupportedException When the
* parent recognizes the feature name but * XMLReader recognizes the feature name but
* cannot set the requested value. * cannot set the requested value.
* @see org.xml.sax.XMLReader#setFeature
*/ */
public void setFeature (String name, boolean value) public void setFeature (String name, boolean state)
throws SAXNotRecognizedException, SAXNotSupportedException throws SAXNotRecognizedException, SAXNotSupportedException
{ {
if (parent != null) { if (parent != null) {
parent.setFeature(name, value); parent.setFeature(name, state);
} else { } else {
throw new SAXNotRecognizedException("Feature: " + name); throw new SAXNotRecognizedException("Feature: " + name);
} }
@ -160,17 +165,18 @@ public class XMLFilterImpl
/** /**
* Look up the value of a feature. * Look up the state of a feature.
* *
* <p>This will always fail if the parent is null.</p> * <p>This will always fail if the parent is null.</p>
* *
* @param name The feature name. * @param name The feature name.
* @return The current value of the feature. * @return The current state of the feature.
* @exception org.xml.sax.SAXNotRecognizedException If the feature * @exception org.xml.sax.SAXNotRecognizedException When the
* value can't be assigned or retrieved from the parent. * XMLReader does not recognize the feature name.
* @exception org.xml.sax.SAXNotSupportedException When the * @exception org.xml.sax.SAXNotSupportedException When the
* parent recognizes the feature name but * XMLReader recognizes the feature name but
* cannot determine its value at this time. * cannot determine its state at this time.
* @see org.xml.sax.XMLReader#getFeature
*/ */
public boolean getFeature (String name) public boolean getFeature (String name)
throws SAXNotRecognizedException, SAXNotSupportedException throws SAXNotRecognizedException, SAXNotSupportedException
@ -189,12 +195,13 @@ public class XMLFilterImpl
* <p>This will always fail if the parent is null.</p> * <p>This will always fail if the parent is null.</p>
* *
* @param name The property name. * @param name The property name.
* @param value The requested property value. * @param state The requested property value.
* @exception org.xml.sax.SAXNotRecognizedException If the property * @exception org.xml.sax.SAXNotRecognizedException When the
* value can't be assigned or retrieved from the parent. * XMLReader does not recognize the property name.
* @exception org.xml.sax.SAXNotSupportedException When the * @exception org.xml.sax.SAXNotSupportedException When the
* parent recognizes the property name but * XMLReader recognizes the property name but
* cannot set the requested value. * cannot set the requested value.
* @see org.xml.sax.XMLReader#setProperty
*/ */
public void setProperty (String name, Object value) public void setProperty (String name, Object value)
throws SAXNotRecognizedException, SAXNotSupportedException throws SAXNotRecognizedException, SAXNotSupportedException
@ -212,11 +219,12 @@ public class XMLFilterImpl
* *
* @param name The property name. * @param name The property name.
* @return The current value of the property. * @return The current value of the property.
* @exception org.xml.sax.SAXNotRecognizedException If the property * @exception org.xml.sax.SAXNotRecognizedException When the
* value can't be assigned or retrieved from the parent. * XMLReader does not recognize the feature name.
* @exception org.xml.sax.SAXNotSupportedException When the * @exception org.xml.sax.SAXNotSupportedException When the
* parent recognizes the property name but * XMLReader recognizes the property name but
* cannot determine its value at this time. * cannot determine its value at this time.
* @see org.xml.sax.XMLReader#setFeature
*/ */
public Object getProperty (String name) public Object getProperty (String name)
throws SAXNotRecognizedException, SAXNotSupportedException throws SAXNotRecognizedException, SAXNotSupportedException
@ -233,17 +241,25 @@ public class XMLFilterImpl
* Set the entity resolver. * Set the entity resolver.
* *
* @param resolver The new entity resolver. * @param resolver The new entity resolver.
* @exception java.lang.NullPointerException If the resolver
* is null.
* @see org.xml.sax.XMLReader#setEntityResolver
*/ */
public void setEntityResolver (EntityResolver resolver) public void setEntityResolver (EntityResolver resolver)
{ {
if (resolver == null) {
throw new NullPointerException("Null entity resolver");
} else {
entityResolver = resolver; entityResolver = resolver;
} }
}
/** /**
* Get the current entity resolver. * Get the current entity resolver.
* *
* @return The current entity resolver, or null if none was set. * @return The current entity resolver, or null if none was set.
* @see org.xml.sax.XMLReader#getEntityResolver
*/ */
public EntityResolver getEntityResolver () public EntityResolver getEntityResolver ()
{ {
@ -255,17 +271,25 @@ public class XMLFilterImpl
* Set the DTD event handler. * Set the DTD event handler.
* *
* @param resolver The new DTD handler. * @param resolver The new DTD handler.
* @exception java.lang.NullPointerException If the handler
* is null.
* @see org.xml.sax.XMLReader#setDTDHandler
*/ */
public void setDTDHandler (DTDHandler handler) public void setDTDHandler (DTDHandler handler)
{ {
if (handler == null) {
throw new NullPointerException("Null DTD handler");
} else {
dtdHandler = handler; dtdHandler = handler;
} }
}
/** /**
* Get the current DTD event handler. * Get the current DTD event handler.
* *
* @return The current DTD handler, or null if none was set. * @return The current DTD handler, or null if none was set.
* @see org.xml.sax.XMLReader#getDTDHandler
*/ */
public DTDHandler getDTDHandler () public DTDHandler getDTDHandler ()
{ {
@ -277,17 +301,25 @@ public class XMLFilterImpl
* Set the content event handler. * Set the content event handler.
* *
* @param resolver The new content handler. * @param resolver The new content handler.
* @exception java.lang.NullPointerException If the handler
* is null.
* @see org.xml.sax.XMLReader#setContentHandler
*/ */
public void setContentHandler (ContentHandler handler) public void setContentHandler (ContentHandler handler)
{ {
if (handler == null) {
throw new NullPointerException("Null content handler");
} else {
contentHandler = handler; contentHandler = handler;
} }
}
/** /**
* Get the content event handler. * Get the content event handler.
* *
* @return The current content handler, or null if none was set. * @return The current content handler, or null if none was set.
* @see org.xml.sax.XMLReader#getContentHandler
*/ */
public ContentHandler getContentHandler () public ContentHandler getContentHandler ()
{ {
@ -299,17 +331,25 @@ public class XMLFilterImpl
* Set the error event handler. * Set the error event handler.
* *
* @param handle The new error handler. * @param handle The new error handler.
* @exception java.lang.NullPointerException If the handler
* is null.
* @see org.xml.sax.XMLReader#setErrorHandler
*/ */
public void setErrorHandler (ErrorHandler handler) public void setErrorHandler (ErrorHandler handler)
{ {
if (handler == null) {
throw new NullPointerException("Null error handler");
} else {
errorHandler = handler; errorHandler = handler;
} }
}
/** /**
* Get the current error event handler. * Get the current error event handler.
* *
* @return The current error handler, or null if none was set. * @return The current error handler, or null if none was set.
* @see org.xml.sax.XMLReader#getErrorHandler
*/ */
public ErrorHandler getErrorHandler () public ErrorHandler getErrorHandler ()
{ {
@ -326,6 +366,7 @@ public class XMLFilterImpl
* @exception java.io.IOException An IO exception from the parser, * @exception java.io.IOException An IO exception from the parser,
* possibly from a byte stream or character stream * possibly from a byte stream or character stream
* supplied by the application. * supplied by the application.
* @see org.xml.sax.XMLReader#parse(org.xml.sax.InputSource)
*/ */
public void parse (InputSource input) public void parse (InputSource input)
throws SAXException, IOException throws SAXException, IOException
@ -344,6 +385,7 @@ public class XMLFilterImpl
* @exception java.io.IOException An IO exception from the parser, * @exception java.io.IOException An IO exception from the parser,
* possibly from a byte stream or character stream * possibly from a byte stream or character stream
* supplied by the application. * supplied by the application.
* @see org.xml.sax.XMLReader#parse(java.lang.String)
*/ */
public void parse (String systemId) public void parse (String systemId)
throws SAXException, IOException throws SAXException, IOException
@ -369,6 +411,7 @@ public class XMLFilterImpl
* @exception java.io.IOException The client may throw an * @exception java.io.IOException The client may throw an
* I/O-related exception while obtaining the * I/O-related exception while obtaining the
* new InputSource. * new InputSource.
* @see org.xml.sax.EntityResolver#resolveEntity
*/ */
public InputSource resolveEntity (String publicId, String systemId) public InputSource resolveEntity (String publicId, String systemId)
throws SAXException, IOException throws SAXException, IOException
@ -395,6 +438,7 @@ public class XMLFilterImpl
* @param systemId The notation's system identifier, or null. * @param systemId The notation's system identifier, or null.
* @exception org.xml.sax.SAXException The client may throw * @exception org.xml.sax.SAXException The client may throw
* an exception during processing. * an exception during processing.
* @see org.xml.sax.DTDHandler#notationDecl
*/ */
public void notationDecl (String name, String publicId, String systemId) public void notationDecl (String name, String publicId, String systemId)
throws SAXException throws SAXException
@ -414,6 +458,7 @@ public class XMLFilterImpl
* @param notationName The name of the associated notation. * @param notationName The name of the associated notation.
* @exception org.xml.sax.SAXException The client may throw * @exception org.xml.sax.SAXException The client may throw
* an exception during processing. * an exception during processing.
* @see org.xml.sax.DTDHandler#unparsedEntityDecl
*/ */
public void unparsedEntityDecl (String name, String publicId, public void unparsedEntityDecl (String name, String publicId,
String systemId, String notationName) String systemId, String notationName)
@ -436,6 +481,7 @@ public class XMLFilterImpl
* Filter a new document locator event. * Filter a new document locator event.
* *
* @param locator The document locator. * @param locator The document locator.
* @see org.xml.sax.ContentHandler#setDocumentLocator
*/ */
public void setDocumentLocator (Locator locator) public void setDocumentLocator (Locator locator)
{ {
@ -451,6 +497,7 @@ public class XMLFilterImpl
* *
* @exception org.xml.sax.SAXException The client may throw * @exception org.xml.sax.SAXException The client may throw
* an exception during processing. * an exception during processing.
* @see org.xml.sax.ContentHandler#startDocument
*/ */
public void startDocument () public void startDocument ()
throws SAXException throws SAXException
@ -466,6 +513,7 @@ public class XMLFilterImpl
* *
* @exception org.xml.sax.SAXException The client may throw * @exception org.xml.sax.SAXException The client may throw
* an exception during processing. * an exception during processing.
* @see org.xml.sax.ContentHandler#endDocument
*/ */
public void endDocument () public void endDocument ()
throws SAXException throws SAXException
@ -483,6 +531,7 @@ public class XMLFilterImpl
* @param uri The Namespace URI. * @param uri The Namespace URI.
* @exception org.xml.sax.SAXException The client may throw * @exception org.xml.sax.SAXException The client may throw
* an exception during processing. * an exception during processing.
* @see org.xml.sax.ContentHandler#startPrefixMapping
*/ */
public void startPrefixMapping (String prefix, String uri) public void startPrefixMapping (String prefix, String uri)
throws SAXException throws SAXException
@ -499,6 +548,7 @@ public class XMLFilterImpl
* @param prefix The Namespace prefix. * @param prefix The Namespace prefix.
* @exception org.xml.sax.SAXException The client may throw * @exception org.xml.sax.SAXException The client may throw
* an exception during processing. * an exception during processing.
* @see org.xml.sax.ContentHandler#endPrefixMapping
*/ */
public void endPrefixMapping (String prefix) public void endPrefixMapping (String prefix)
throws SAXException throws SAXException
@ -519,6 +569,7 @@ public class XMLFilterImpl
* @param atts The element's attributes. * @param atts The element's attributes.
* @exception org.xml.sax.SAXException The client may throw * @exception org.xml.sax.SAXException The client may throw
* an exception during processing. * an exception during processing.
* @see org.xml.sax.ContentHandler#startElement
*/ */
public void startElement (String uri, String localName, String qName, public void startElement (String uri, String localName, String qName,
Attributes atts) Attributes atts)
@ -539,6 +590,7 @@ public class XMLFilterImpl
* string. * string.
* @exception org.xml.sax.SAXException The client may throw * @exception org.xml.sax.SAXException The client may throw
* an exception during processing. * an exception during processing.
* @see org.xml.sax.ContentHandler#endElement
*/ */
public void endElement (String uri, String localName, String qName) public void endElement (String uri, String localName, String qName)
throws SAXException throws SAXException
@ -557,6 +609,7 @@ public class XMLFilterImpl
* @param length The number of characters to use from the array. * @param length The number of characters to use from the array.
* @exception org.xml.sax.SAXException The client may throw * @exception org.xml.sax.SAXException The client may throw
* an exception during processing. * an exception during processing.
* @see org.xml.sax.ContentHandler#characters
*/ */
public void characters (char ch[], int start, int length) public void characters (char ch[], int start, int length)
throws SAXException throws SAXException
@ -575,6 +628,7 @@ public class XMLFilterImpl
* @param length The number of characters to use from the array. * @param length The number of characters to use from the array.
* @exception org.xml.sax.SAXException The client may throw * @exception org.xml.sax.SAXException The client may throw
* an exception during processing. * an exception during processing.
* @see org.xml.sax.ContentHandler#ignorableWhitespace
*/ */
public void ignorableWhitespace (char ch[], int start, int length) public void ignorableWhitespace (char ch[], int start, int length)
throws SAXException throws SAXException
@ -592,6 +646,7 @@ public class XMLFilterImpl
* @param data The text following the target. * @param data The text following the target.
* @exception org.xml.sax.SAXException The client may throw * @exception org.xml.sax.SAXException The client may throw
* an exception during processing. * an exception during processing.
* @see org.xml.sax.ContentHandler#processingInstruction
*/ */
public void processingInstruction (String target, String data) public void processingInstruction (String target, String data)
throws SAXException throws SAXException
@ -608,6 +663,7 @@ public class XMLFilterImpl
* @param name The name of the skipped entity. * @param name The name of the skipped entity.
* @exception org.xml.sax.SAXException The client may throw * @exception org.xml.sax.SAXException The client may throw
* an exception during processing. * an exception during processing.
* @see org.xml.sax.ContentHandler#skippedEntity
*/ */
public void skippedEntity (String name) public void skippedEntity (String name)
throws SAXException throws SAXException
@ -627,9 +683,10 @@ public class XMLFilterImpl
/** /**
* Filter a warning event. * Filter a warning event.
* *
* @param e The warning as an exception. * @param e The nwarning as an exception.
* @exception org.xml.sax.SAXException The client may throw * @exception org.xml.sax.SAXException The client may throw
* an exception during processing. * an exception during processing.
* @see org.xml.sax.ErrorHandler#warning
*/ */
public void warning (SAXParseException e) public void warning (SAXParseException e)
throws SAXException throws SAXException
@ -646,6 +703,7 @@ public class XMLFilterImpl
* @param e The error as an exception. * @param e The error as an exception.
* @exception org.xml.sax.SAXException The client may throw * @exception org.xml.sax.SAXException The client may throw
* an exception during processing. * an exception during processing.
* @see org.xml.sax.ErrorHandler#error
*/ */
public void error (SAXParseException e) public void error (SAXParseException e)
throws SAXException throws SAXException
@ -662,6 +720,7 @@ public class XMLFilterImpl
* @param e The error as an exception. * @param e The error as an exception.
* @exception org.xml.sax.SAXException The client may throw * @exception org.xml.sax.SAXException The client may throw
* an exception during processing. * an exception during processing.
* @see org.xml.sax.ErrorHandler#fatalError
*/ */
public void fatalError (SAXParseException e) public void fatalError (SAXParseException e)
throws SAXException throws SAXException

View File

@ -1,6 +1,5 @@
// XMLReaderAdapter.java - adapt an SAX2 XMLReader to a SAX1 Parser // XMLReaderAdapter.java - adapt an SAX2 XMLReader to a SAX1 Parser
// http://www.saxproject.org // Written by David Megginson, sax@megginson.com
// Written by David Megginson
// NO WARRANTY! This class is in the public domain. // NO WARRANTY! This class is in the public domain.
// $Id$ // $Id$
@ -32,8 +31,6 @@ import org.xml.sax.SAXNotSupportedException;
* <blockquote> * <blockquote>
* <em>This module, both source code and documentation, is in the * <em>This module, both source code and documentation, is in the
* Public Domain, and comes with <strong>NO WARRANTY</strong>.</em> * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
* See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
* for further information.
* </blockquote> * </blockquote>
* *
* <p>This class wraps a SAX2 {@link org.xml.sax.XMLReader XMLReader} * <p>This class wraps a SAX2 {@link org.xml.sax.XMLReader XMLReader}
@ -44,9 +41,14 @@ import org.xml.sax.SAXNotSupportedException;
* supports a false value for the http://xml.org/sax/features/namespaces * supports a false value for the http://xml.org/sax/features/namespaces
* property, that will also be used to improve efficiency.</p> * property, that will also be used to improve efficiency.</p>
* *
* <p>Note that this is <strong>not</strong> the version shipped with SAX 2.0.1; this class
* throws NullPointerExceptions when setter methods are called with null parameters;
* the 2.0.1 version does not exhibit this behaviour. </p>
*
* @since SAX 2.0 * @since SAX 2.0
* @author David Megginson * @author David Megginson,
* @version 2.0.1 (sax2r2) * <a href="mailto:sax@megginson.com">sax@megginson.com</a>
* @version 2.0
* @see org.xml.sax.Parser * @see org.xml.sax.Parser
* @see org.xml.sax.XMLReader * @see org.xml.sax.XMLReader
*/ */
@ -122,7 +124,6 @@ public class XMLReaderAdapter implements Parser, ContentHandler
* *
* @param The locale for error reporting. * @param The locale for error reporting.
* @see org.xml.sax.Parser#setLocale * @see org.xml.sax.Parser#setLocale
* @exception org.xml.sax.SAXException Thrown unless overridden.
*/ */
public void setLocale (Locale locale) public void setLocale (Locale locale)
throws SAXException throws SAXException
@ -258,7 +259,6 @@ public class XMLReaderAdapter implements Parser, ContentHandler
*/ */
public void setDocumentLocator (Locator locator) public void setDocumentLocator (Locator locator)
{ {
if (documentHandler != null)
documentHandler.setDocumentLocator(locator); documentHandler.setDocumentLocator(locator);
} }
@ -273,7 +273,6 @@ public class XMLReaderAdapter implements Parser, ContentHandler
public void startDocument () public void startDocument ()
throws SAXException throws SAXException
{ {
if (documentHandler != null)
documentHandler.startDocument(); documentHandler.startDocument();
} }
@ -288,7 +287,6 @@ public class XMLReaderAdapter implements Parser, ContentHandler
public void endDocument () public void endDocument ()
throws SAXException throws SAXException
{ {
if (documentHandler != null)
documentHandler.endDocument(); documentHandler.endDocument();
} }
@ -331,11 +329,9 @@ public class XMLReaderAdapter implements Parser, ContentHandler
String qName, Attributes atts) String qName, Attributes atts)
throws SAXException throws SAXException
{ {
if (documentHandler != null) {
qAtts.setAttributes(atts); qAtts.setAttributes(atts);
documentHandler.startElement(qName, qAtts); documentHandler.startElement(qName, qAtts);
} }
}
/** /**
@ -352,7 +348,6 @@ public class XMLReaderAdapter implements Parser, ContentHandler
String qName) String qName)
throws SAXException throws SAXException
{ {
if (documentHandler != null)
documentHandler.endElement(qName); documentHandler.endElement(qName);
} }
@ -370,7 +365,6 @@ public class XMLReaderAdapter implements Parser, ContentHandler
public void characters (char ch[], int start, int length) public void characters (char ch[], int start, int length)
throws SAXException throws SAXException
{ {
if (documentHandler != null)
documentHandler.characters(ch, start, length); documentHandler.characters(ch, start, length);
} }
@ -388,7 +382,6 @@ public class XMLReaderAdapter implements Parser, ContentHandler
public void ignorableWhitespace (char ch[], int start, int length) public void ignorableWhitespace (char ch[], int start, int length)
throws SAXException throws SAXException
{ {
if (documentHandler != null)
documentHandler.ignorableWhitespace(ch, start, length); documentHandler.ignorableWhitespace(ch, start, length);
} }
@ -405,7 +398,6 @@ public class XMLReaderAdapter implements Parser, ContentHandler
public void processingInstruction (String target, String data) public void processingInstruction (String target, String data)
throws SAXException throws SAXException
{ {
if (documentHandler != null)
documentHandler.processingInstruction(target, data); documentHandler.processingInstruction(target, data);
} }
@ -415,7 +407,6 @@ public class XMLReaderAdapter implements Parser, ContentHandler
* *
* @param name The name of the skipped entity. * @param name The name of the skipped entity.
* @see org.xml.sax.ContentHandler#skippedEntity * @see org.xml.sax.ContentHandler#skippedEntity
* @exception org.xml.sax.SAXException Throwable by subclasses.
*/ */
public void skippedEntity (String name) public void skippedEntity (String name)
throws SAXException throws SAXException

View File

@ -3,7 +3,6 @@
// Written by David Megginson // Written by David Megginson
// and by David Brownell // and by David Brownell
// NO WARRANTY! This class is in the Public Domain. // NO WARRANTY! This class is in the Public Domain.
// $Id$ // $Id$
package org.xml.sax.helpers; package org.xml.sax.helpers;
@ -43,9 +42,12 @@ import org.xml.sax.SAXException;
* nothing bound its class name to <code>org.xml.sax.driver</code> so * nothing bound its class name to <code>org.xml.sax.driver</code> so
* those configuration mechanisms would see it.</p> * those configuration mechanisms would see it.</p>
* *
* <p>Note that this is <strong>not</strong> the XMLReaderFactory shipped with SAX 2.0.1;
* this class takes into account the needs of J2EE 1.4 AccessControllers.</p>
*
* @since SAX 2.0 * @since SAX 2.0
* @author David Megginson, David Brownell * @author David Megginson, David Brownell
* @version 2.0.1 (sax2r2) * @version 2.0r2pre3
*/ */
final public class XMLReaderFactory final public class XMLReaderFactory
{ {
@ -106,43 +108,88 @@ final public class XMLReaderFactory
throws SAXException throws SAXException
{ {
String className = null; String className = null;
SecuritySupport ss = SecuritySupport.getInstance();
ClassLoader loader = NewInstance.getClassLoader (); ClassLoader loader = NewInstance.getClassLoader ();
// 1. try the JVM-instance-wide system property // 1. try the JVM-instance-wide system property
try { className = System.getProperty (property); } try {
catch (Exception e) { /* normally fails for applets */ } className = ss.getSystemProperty(property);
} catch (Exception e) { /* normally fails for applets */ }
// 2. if that fails, try META-INF/services/ // 2. if that fails, try META-INF/services/
if (className == null) { if (className == null) {
try {
String service = "META-INF/services/" + property; String service = "META-INF/services/" + property;
InputStream in;
BufferedReader reader;
if (loader == null) InputStream is = null;
in = ClassLoader.getSystemResourceAsStream (service);
else
in = loader.getResourceAsStream (service);
if (in != null) { // First try the Context ClassLoader
reader = new BufferedReader ( ClassLoader cl = ss.getContextClassLoader();
new InputStreamReader (in, "UTF8")); if (cl != null) {
className = reader.readLine (); is = ss.getResourceAsStream(cl, service);
in.close ();
// If no provider found then try the current ClassLoader
if (is == null) {
cl = XMLReaderFactory.class.getClassLoader();
is = ss.getResourceAsStream(cl, service);
} }
} catch (Exception e) { } else {
// No Context ClassLoader or JDK 1.1 so try the current
// ClassLoader
cl = XMLReaderFactory.class.getClassLoader();
is = ss.getResourceAsStream(cl, service);
}
if (is != null) {
// Read the service provider name in UTF-8 as specified in
// the jar spec. Unfortunately this fails in Microsoft
// VJ++, which does not implement the UTF-8
// encoding. Theoretically, we should simply let it fail in
// that case, since the JVM is obviously broken if it
// doesn't support such a basic standard. But since there
// are still some users attempting to use VJ++ for
// development, we have dropped in a fallback which makes a
// second attempt using the platform's default encoding. In
// VJ++ this is apparently ASCII, which is a subset of
// UTF-8... and since the strings we'll be reading here are
// also primarily limited to the 7-bit ASCII range (at
// least, in English versions), this should work well
// enough to keep us on the air until we're ready to
// officially decommit from VJ++. [Edited comment from
// jkesselm]
BufferedReader rd;
try {
rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
} catch (java.io.UnsupportedEncodingException e) {
rd = new BufferedReader(new InputStreamReader(is));
}
try {
// XXX Does not handle all possible input as specified by the
// Jar Service Provider specification
className = rd.readLine();
rd.close();
} catch (Exception x) {
// No provider found
} }
} }
}
// REVISIT: there is a comment in the original FactoryFinder codde to the effect:
//
// ClassLoader because we want to avoid the case where the
// resource file was found using one ClassLoader and the
// provider class was instantiated using a different one.
//
// But it's not clear how the class loader "cl" (now out of scope!)
// that loaded the inputStream would matter here...
// 3. Distro-specific fallback // 3. Distro-specific fallback
if (className == null) { if (className == null) {
// BEGIN DISTRIBUTION-SPECIFIC // modified by neilg in accordance with the "strong encouragement"
// provided to distributions which include parsers.
// EXAMPLE: className = "org.apache.xerces.parsers.SAXParser";
// className = "com.example.sax.XmlReader";
// or a $JAVA_HOME/jre/lib/*properties setting...
// END DISTRIBUTION-SPECIFIC
} }
// do we know the XMLReader implementation class yet? // do we know the XMLReader implementation class yet?