Merging in SecuritySupport code from the tck-jaxp-1_2_0 branch.

git-svn-id: https://svn.apache.org/repos/asf/xml/commons/trunk@226249 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
mrglavas 2005-06-21 19:03:16 +00:00
parent 410062edf4
commit 80124b43a8
3 changed files with 298 additions and 75 deletions

View File

@ -0,0 +1,95 @@
/*
* Copyright 2002-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.xml.sax.helpers;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
/**
* 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,90 @@
/*
* Copyright 2002-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.xml.sax.helpers;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
/**
* 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

@ -102,60 +102,98 @@ final public class XMLReaderFactory
* @see #createXMLReader(java.lang.String)
*/
public static XMLReader createXMLReader ()
throws SAXException
throws SAXException
{
String className = null;
ClassLoader loader = NewInstance.getClassLoader ();
String className = null;
SecuritySupport ss = SecuritySupport.getInstance();
ClassLoader loader = NewInstance.getClassLoader ();
// 1. try the JVM-instance-wide system property
try { className = System.getProperty (property); }
catch (RuntimeException e) { /* normally fails for applets */ }
// 1. try the JVM-instance-wide system property
try { className = System.getProperty (property); }
catch (RuntimeException e) { /* normally fails for applets */ }
// 2. if that fails, try META-INF/services/
if (className == null) {
try {
String service = "META-INF/services/" + property;
InputStream in;
BufferedReader reader;
// 2. if that fails, try META-INF/services/
if (className == null) {
String service = "META-INF/services/" + property;
if (loader == null)
in = ClassLoader.getSystemResourceAsStream (service);
else
in = loader.getResourceAsStream (service);
InputStream is = null;
if (in != null) {
reader = new BufferedReader (
new InputStreamReader (in, "UTF8"));
className = reader.readLine ();
in.close ();
}
} catch (Exception e) {
}
}
// First try the Context ClassLoader
ClassLoader cl = ss.getContextClassLoader();
if (cl != null) {
is = ss.getResourceAsStream(cl, service);
// 3. Distro-specific fallback
if (className == null) {
// BEGIN DISTRIBUTION-SPECIFIC
// If no provider found then try the current ClassLoader
if (is == null) {
cl = XMLReaderFactory.class.getClassLoader();
is = ss.getResourceAsStream(cl, service);
}
} else {
// No Context ClassLoader or JDK 1.1 so try the current
// ClassLoader
cl = XMLReaderFactory.class.getClassLoader();
is = ss.getResourceAsStream(cl, service);
}
// EXAMPLE:
// className = "com.example.sax.XmlReader";
// or a $JAVA_HOME/jre/lib/*properties setting...
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
}
}
}
// 3. Distro-specific fallback
if (className == null) {
// BEGIN DISTRIBUTION-SPECIFIC
// EXAMPLE:
// className = "com.example.sax.XmlReader";
// or a $JAVA_HOME/jre/lib/*properties setting...
className = "org.apache.xerces.parsers.SAXParser";
// END DISTRIBUTION-SPECIFIC
}
// END DISTRIBUTION-SPECIFIC
}
// do we know the XMLReader implementation class yet?
if (className != null)
return loadClass (loader, className);
// do we know the XMLReader implementation class yet?
if (className != null)
return loadClass (loader, className);
// 4. panic -- adapt any SAX1 parser
try {
return new ParserAdapter (ParserFactory.makeParser ());
} catch (Exception e) {
throw new SAXException ("Can't create default XMLReader; "
+ "is system property org.xml.sax.driver set?");
}
// 4. panic -- adapt any SAX1 parser
try {
return new ParserAdapter (ParserFactory.makeParser ());
} catch (Exception e) {
throw new SAXException ("Can't create default XMLReader; "
+ "is system property org.xml.sax.driver set?");
}
}
@ -175,29 +213,29 @@ final public class XMLReaderFactory
* @see #createXMLReader()
*/
public static XMLReader createXMLReader (String className)
throws SAXException
throws SAXException
{
return loadClass (NewInstance.getClassLoader (), className);
return loadClass (NewInstance.getClassLoader (), className);
}
private static XMLReader loadClass (ClassLoader loader, String className)
throws SAXException
{
try {
return (XMLReader) NewInstance.newInstance (loader, className);
} catch (ClassNotFoundException e1) {
throw new SAXException("SAX2 driver class " + className +
" not found", e1);
} catch (IllegalAccessException e2) {
throw new SAXException("SAX2 driver class " + className +
" found but cannot be loaded", e2);
} catch (InstantiationException e3) {
throw new SAXException("SAX2 driver class " + className +
" loaded but cannot be instantiated (no empty public constructor?)",
e3);
} catch (ClassCastException e4) {
throw new SAXException("SAX2 driver class " + className +
" does not implement XMLReader", e4);
}
try {
return (XMLReader) NewInstance.newInstance (loader, className);
} catch (ClassNotFoundException e1) {
throw new SAXException("SAX2 driver class " + className +
" not found", e1);
} catch (IllegalAccessException e2) {
throw new SAXException("SAX2 driver class " + className +
" found but cannot be loaded", e2);
} catch (InstantiationException e3) {
throw new SAXException("SAX2 driver class " + className +
" loaded but cannot be instantiated (no empty public constructor?)",
e3);
} catch (ClassCastException e4) {
throw new SAXException("SAX2 driver class " + className +
" does not implement XMLReader", e4);
}
}
}