# HG changeset patch # User joehw # Date 1334686679 25200 # Node ID ceae213d9812bce5b0b01c475f7ba76883395fad # Parent 7b89fed7212b9e4a9506cdd8c628f48ab447da0b 7160380: Sync JDK8 with JAXP 1.4.5 Summary: bring JDK8 up to date to what we have in 7u4 Reviewed-by: lancea, mullan diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/XalanConstants.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/com/sun/org/apache/xalan/internal/XalanConstants.java Tue Apr 17 11:17:59 2012 -0700 @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.org.apache.xalan.internal; + +import com.sun.org.apache.xerces.internal.impl.*; +import java.util.Enumeration; +import java.util.NoSuchElementException; + +/** + * Commonly used constants. + * + * @author Huizhe Wang, Oracle + * + * @version $Id: Constants.java,v 1.14 2011-06-07 04:39:40 joehw Exp $ + */ +public final class XalanConstants { + + // + // Constants + // + // Oracle Feature: + /** + *

Use Service Mechanism

+ * + * + */ + public static final String ORACLE_FEATURE_SERVICE_MECHANISM = "http://www.oracle.com/feature/use-service-mechanism"; + +} // class Constants diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/lib/ExsltDatetime.java --- a/src/com/sun/org/apache/xalan/internal/lib/ExsltDatetime.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/lib/ExsltDatetime.java Tue Apr 17 11:17:59 2012 -0700 @@ -97,7 +97,7 @@ // In a few cases, the time zone may be +/-hh:30. int min = offset%(60*60*1000); char posneg = hrs < 0? '-': '+'; - buff.append(posneg + formatDigits(hrs) + ':' + formatDigits(min)); + buff.append(posneg).append(formatDigits(hrs)).append(':').append(formatDigits(min)); } return buff.toString(); } diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/lib/ExsltMath.java --- a/src/com/sun/org/apache/xalan/internal/lib/ExsltMath.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/lib/ExsltMath.java Tue Apr 17 11:17:59 2012 -0700 @@ -381,7 +381,7 @@ if (bits <= value.length()) value = value.substring(0, bits); - return new Double(value).doubleValue(); + return Double.parseDouble(value); } else return Double.NaN; diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/lib/Extensions.java --- a/src/com/sun/org/apache/xalan/internal/lib/Extensions.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/lib/Extensions.java Tue Apr 17 11:17:59 2012 -0700 @@ -35,6 +35,7 @@ import com.sun.org.apache.xpath.internal.objects.XBoolean; import com.sun.org.apache.xpath.internal.objects.XNumber; import com.sun.org.apache.xpath.internal.objects.XObject; +import com.sun.org.apache.xalan.internal.utils.ObjectFactory; import org.w3c.dom.Document; import org.w3c.dom.DocumentFragment; @@ -363,8 +364,7 @@ try { // Use reflection to try to find xml-commons utility 'Which' - Class clazz = ObjectFactory.findProviderClass( - WHICH_CLASSNAME, ObjectFactory.findClassLoader(), true); + Class clazz = ObjectFactory.findProviderClass(WHICH_CLASSNAME, true); if (null == clazz) return null; diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/lib/ObjectFactory.java --- a/src/com/sun/org/apache/xalan/internal/lib/ObjectFactory.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,661 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2001-2004 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. - */ -/* - * $Id: ObjectFactory.java,v 1.2.4.1 2005/09/15 02:39:54 jeffsuttor Exp $ - */ - -package com.sun.org.apache.xalan.internal.lib; - -import java.io.InputStream; -import java.io.IOException; -import java.io.File; -import java.io.FileInputStream; - -import java.util.Properties; -import java.io.BufferedReader; -import java.io.InputStreamReader; - -/** - * 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. - *

- * This code is designed to implement the JAXP 1.1 spec pluggability - * feature and is designed to run on JDK version 1.1 and - * later, and to compile on JDK 1.2 and onward. - * The code also runs both as part of an unbundled jar file and - * when bundled as part of the JDK. - *

- * This class was moved from the javax.xml.parsers.ObjectFactory - * class and modified to be used as a general utility for creating objects - * dynamically. - * - * @version $Id: ObjectFactory.java,v 1.9 2008/04/02 00:40:59 joehw Exp $ - */ -class ObjectFactory { - - // - // Constants - // - - // name of default properties file to look for in JDK's jre/lib directory - private static final String DEFAULT_PROPERTIES_FILENAME = - "xalan.properties"; - - private static final String SERVICES_PATH = "META-INF/services/"; - - /** Set to true for debugging */ - private static final boolean DEBUG = false; - - /** cache the contents of the xalan.properties file. - * Until an attempt has been made to read this file, this will - * be null; if the file does not exist or we encounter some other error - * during the read, this will be empty. - */ - private static Properties fXalanProperties = null; - - /*** - * Cache the time stamp of the xalan.properties file so - * that we know if it's been modified and can invalidate - * the cache when necessary. - */ - private static long fLastModified = -1; - - // - // Public static methods - // - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *

    - *
  1. query the system property using System.getProperty - *
  2. read META-INF/services/factoryId file - *
  3. use fallback classname - *
- * - * @return instance of factory, 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 no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Object createObject(String factoryId, String fallbackClassName) - throws ConfigurationError { - return createObject(factoryId, null, fallbackClassName); - } // createObject(String,String):Object - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return instance of factory, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Object createObject(String factoryId, - String propertiesFilename, - String fallbackClassName) - throws ConfigurationError - { - Class factoryClass = lookUpFactoryClass(factoryId, - propertiesFilename, - fallbackClassName); - - if (factoryClass == null) { - throw new ConfigurationError( - "Provider for " + factoryId + " cannot be found", null); - } - - try{ - Object instance = factoryClass.newInstance(); - if (DEBUG) debugPrintln("created new instance of factory " + factoryId); - return instance; - } catch (Exception x) { - throw new ConfigurationError( - "Provider for factory " + factoryId - + " could not be instantiated: " + x, x); - } - } // createObject(String,String,String):Object - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return Class object of factory, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Class lookUpFactoryClass(String factoryId) - throws ConfigurationError - { - return lookUpFactoryClass(factoryId, null, null); - } // lookUpFactoryClass(String):Class - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return Class object that provides factory service, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Class lookUpFactoryClass(String factoryId, - String propertiesFilename, - String fallbackClassName) - throws ConfigurationError - { - String factoryClassName = lookUpFactoryClassName(factoryId, - propertiesFilename, - fallbackClassName); - ClassLoader cl = findClassLoader(); - - if (factoryClassName == null) { - factoryClassName = fallbackClassName; - } - - // assert(className != null); - try{ - Class providerClass = findProviderClass(factoryClassName, - cl, - true); - if (DEBUG) debugPrintln("created new instance of " + providerClass + - " using ClassLoader: " + cl); - return providerClass; - } catch (ClassNotFoundException x) { - throw new ConfigurationError( - "Provider " + factoryClassName + " not found", x); - } catch (Exception x) { - throw new ConfigurationError( - "Provider "+factoryClassName+" could not be instantiated: "+x, - x); - } - } // lookUpFactoryClass(String,String,String):Class - - /** - * Finds the name of the required implementation class in the specified - * order. The specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return name of class that provides factory service, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static String lookUpFactoryClassName(String factoryId, - String propertiesFilename, - String fallbackClassName) - { - SecuritySupport ss = SecuritySupport.getInstance(); - - // Use the system property first - try { - String systemProp = ss.getSystemProperty(factoryId); - if (systemProp != null) { - if (DEBUG) debugPrintln("found system property, value=" + systemProp); - return systemProp; - } - } catch (SecurityException se) { - // Ignore and continue w/ next location - } - - // Try to read from propertiesFilename, or - // $java.home/lib/xalan.properties - String factoryClassName = null; - // no properties file name specified; use - // $JAVA_HOME/lib/xalan.properties: - if (propertiesFilename == null) { - File propertiesFile = null; - boolean propertiesFileExists = false; - try { - String javah = ss.getSystemProperty("java.home"); - propertiesFilename = javah + File.separator + - "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME; - propertiesFile = new File(propertiesFilename); - propertiesFileExists = ss.getFileExists(propertiesFile); - } catch (SecurityException e) { - // try again... - fLastModified = -1; - fXalanProperties = null; - } - - synchronized (ObjectFactory.class) { - boolean loadProperties = false; - FileInputStream fis = null; - try { - // file existed last time - if(fLastModified >= 0) { - if(propertiesFileExists && - (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) { - loadProperties = true; - } else { - // file has stopped existing... - if(!propertiesFileExists) { - fLastModified = -1; - fXalanProperties = null; - } // else, file wasn't modified! - } - } else { - // file has started to exist: - if(propertiesFileExists) { - loadProperties = true; - fLastModified = ss.getLastModified(propertiesFile); - } // else, nothing's changed - } - if(loadProperties) { - // must never have attempted to read xalan.properties - // before (or it's outdeated) - fXalanProperties = new Properties(); - fis = ss.getFileInputStream(propertiesFile); - fXalanProperties.load(fis); - } - } catch (Exception x) { - fXalanProperties = null; - fLastModified = -1; - // assert(x instanceof FileNotFoundException - // || x instanceof SecurityException) - // In both cases, ignore and continue w/ next location - } - finally { - // try to close the input stream if one was opened. - if (fis != null) { - try { - fis.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - } - } - if(fXalanProperties != null) { - factoryClassName = fXalanProperties.getProperty(factoryId); - } - } else { - FileInputStream fis = null; - try { - fis = ss.getFileInputStream(new File(propertiesFilename)); - Properties props = new Properties(); - props.load(fis); - factoryClassName = props.getProperty(factoryId); - } catch (Exception x) { - // assert(x instanceof FileNotFoundException - // || x instanceof SecurityException) - // In both cases, ignore and continue w/ next location - } - finally { - // try to close the input stream if one was opened. - if (fis != null) { - try { - fis.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - } - } - if (factoryClassName != null) { - if (DEBUG) debugPrintln("found in " + propertiesFilename + ", value=" - + factoryClassName); - return factoryClassName; - } - - // Try Jar Service Provider Mechanism - return findJarServiceProviderName(factoryId); - } // lookUpFactoryClass(String,String):String - - // - // Private static methods - // - - /** Prints a message to standard error if debugging is enabled. */ - private static void debugPrintln(String msg) { - System.err.println("JAXP: " + msg); - } // debugPrintln(String) - - /** - * Figure out which ClassLoader to use. For JDK 1.2 and later use - * the context ClassLoader. - */ - static ClassLoader findClassLoader() - 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 context = ss.getContextClassLoader(); - ClassLoader system = ss.getSystemClassLoader(); - - ClassLoader chain = system; - while (true) { - if (context == chain) { - // Assert: we are on JDK 1.1 or we have no Context ClassLoader - // or any Context ClassLoader in chain of system classloader - // (including extension ClassLoader) so extend to widest - // ClassLoader (always look in system ClassLoader if Xalan - // is in boot/extension/system classpath and in current - // ClassLoader otherwise); normal classloaders delegate - // back to system ClassLoader first so this widening doesn't - // change the fact that context ClassLoader will be consulted - ClassLoader current = ObjectFactory.class.getClassLoader(); - - chain = system; - while (true) { - if (current == chain) { - // Assert: Current ClassLoader in chain of - // boot/extension/system ClassLoaders - return system; - } - if (chain == null) { - break; - } - chain = ss.getParentClassLoader(chain); - } - - // Assert: Current ClassLoader not in chain of - // boot/extension/system ClassLoaders - return current; - } - - if (chain == null) { - // boot ClassLoader reached - break; - } - - // Check for any extension ClassLoaders in chain up to - // boot ClassLoader - chain = ss.getParentClassLoader(chain); - }; - - // Assert: Context ClassLoader not in chain of - // boot/extension/system ClassLoaders - return context; - } // findClassLoader():ClassLoader - - /** - * Create an instance of a class using the specified ClassLoader - */ - static Object newInstance(String className, ClassLoader cl, - boolean doFallback) - throws ConfigurationError - { - // assert(className != null); - try{ - Class providerClass = findProviderClass(className, cl, doFallback); - Object instance = providerClass.newInstance(); - if (DEBUG) debugPrintln("created new instance of " + providerClass + - " using ClassLoader: " + cl); - return instance; - } catch (ClassNotFoundException x) { - throw new ConfigurationError( - "Provider " + className + " not found", x); - } catch (Exception x) { - throw new ConfigurationError( - "Provider " + className + " could not be instantiated: " + x, - x); - } - } - - /** - * Find a Class using the specified ClassLoader - */ - static Class findProviderClass(String className, ClassLoader cl, - boolean doFallback) - throws ClassNotFoundException, ConfigurationError - { - //throw security exception if the calling thread is not allowed to access the - //class. Restrict the access to the package classes as specified in java.security policy. - SecurityManager security = System.getSecurityManager(); - try{ - if (security != null){ - final int lastDot = className.lastIndexOf("."); - String packageName = className; - if (lastDot != -1) packageName = className.substring(0, lastDot); - security.checkPackageAccess(packageName); - } - }catch(SecurityException e){ - throw e; - } - - Class providerClass; - 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 { - try { - providerClass = cl.loadClass(className); - } catch (ClassNotFoundException x) { - if (doFallback) { - // Fall back to current classloader - ClassLoader current = ObjectFactory.class.getClassLoader(); - if (current == null) { - providerClass = Class.forName(className); - } else if (cl != current) { - cl = current; - providerClass = cl.loadClass(className); - } else { - throw x; - } - } else { - throw x; - } - } - } - - return providerClass; - } - - /** - * Find the name of service provider using Jar Service Provider Mechanism - * - * @return instance of provider class if found or null - */ - private static String findJarServiceProviderName(String factoryId) - { - SecuritySupport ss = SecuritySupport.getInstance(); - String serviceId = SERVICES_PATH + factoryId; - InputStream is = null; - - // First try the Context ClassLoader - ClassLoader cl = findClassLoader(); - - is = ss.getResourceAsStream(cl, serviceId); - - // If no provider found then try the current ClassLoader - if (is == null) { - ClassLoader current = ObjectFactory.class.getClassLoader(); - if (cl != current) { - cl = current; - is = ss.getResourceAsStream(cl, serviceId); - } - } - - if (is == null) { - // No provider found - return null; - } - - if (DEBUG) debugPrintln("found jar resource=" + serviceId + - " using ClassLoader: " + cl); - - // 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)); - } - - String factoryClassName = null; - try { - // XXX Does not handle all possible input as specified by the - // Jar Service Provider specification - factoryClassName = rd.readLine(); - } catch (IOException x) { - // No provider found - return null; - } - finally { - try { - // try to close the reader. - rd.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - - if (factoryClassName != null && - ! "".equals(factoryClassName)) { - if (DEBUG) debugPrintln("found in resource, value=" - + factoryClassName); - - // Note: here we do not want to fall back to the current - // 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. - return factoryClassName; - } - - // No provider found - return null; - } - - // - // Classes - // - - /** - * A configuration error. - */ - static class ConfigurationError - extends Error { - static final long serialVersionUID = -7640369932165775029L; - // - // Data - // - - /** Exception. */ - private Exception exception; - - // - // Constructors - // - - /** - * Construct a new instance with the specified detail string and - * exception. - */ - ConfigurationError(String msg, Exception x) { - super(msg); - this.exception = x; - } // (String,Exception) - - // - // Public methods - // - - /** Returns the exception associated to this error. */ - Exception getException() { - return exception; - } // getException():Exception - - } // class ConfigurationError - -} // class ObjectFactory diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/lib/SecuritySupport.java --- a/src/com/sun/org/apache/xalan/internal/lib/SecuritySupport.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,127 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2002-2004 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. - */ -/* - * $Id: SecuritySupport.java,v 1.1.2.1 2005/08/01 02:08:48 jeffsuttor Exp $ - */ - -package com.sun.org.apache.xalan.internal.lib; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.InputStream; - -import java.util.Properties; - -/** - * This class is duplicated for each Xalan-Java subpackage so keep it in sync. - * It is package private and therefore is not exposed as part of the Xalan-Java - * 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. - */ - static SecuritySupport getInstance() { - return (SecuritySupport)securitySupport; - } - - ClassLoader getContextClassLoader() { - return null; - } - - ClassLoader getSystemClassLoader() { - return null; - } - - ClassLoader getParentClassLoader(ClassLoader cl) { - return null; - } - - String getSystemProperty(String propName) { - return System.getProperty(propName); - } - - FileInputStream getFileInputStream(File file) - throws FileNotFoundException - { - return new FileInputStream(file); - } - - InputStream getResourceAsStream(ClassLoader cl, String name) { - InputStream ris; - if (cl == null) { - ris = ClassLoader.getSystemResourceAsStream(name); - } else { - ris = cl.getResourceAsStream(name); - } - return ris; - } - - boolean getFileExists(File f) { - return f.exists(); - } - - long getLastModified(File f) { - return f.lastModified(); - } -} diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/lib/SecuritySupport12.java --- a/src/com/sun/org/apache/xalan/internal/lib/SecuritySupport12.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,148 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2002-2004 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. - */ -/* - * $Id: SecuritySupport12.java,v 1.1.2.1 2005/08/01 02:08:47 jeffsuttor Exp $ - */ - -package com.sun.org.apache.xalan.internal.lib; - -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; - -import java.util.Properties; - -/** - * This class is duplicated for each Xalan-Java subpackage so keep it in sync. - * It is package private and therefore is not exposed as part of the Xalan-Java - * API. - * - * Security related methods that only work on J2SE 1.2 and newer. - */ -class SecuritySupport12 extends SecuritySupport { - - ClassLoader getContextClassLoader() { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader cl = null; - try { - cl = Thread.currentThread().getContextClassLoader(); - } catch (SecurityException ex) { } - return cl; - } - }); - } - - ClassLoader getSystemClassLoader() { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader cl = null; - try { - cl = ClassLoader.getSystemClassLoader(); - } catch (SecurityException ex) {} - return cl; - } - }); - } - - ClassLoader getParentClassLoader(final ClassLoader cl) { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader parent = null; - try { - parent = cl.getParent(); - } catch (SecurityException ex) {} - - // eliminate loops in case of the boot - // ClassLoader returning itself as a parent - return (parent == cl) ? null : parent; - } - }); - } - - String getSystemProperty(final String propName) { - return (String) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return System.getProperty(propName); - } - }); - } - - 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(); - } - } - - 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; - } - }); - } - - boolean getFileExists(final File f) { - return ((Boolean) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return new Boolean(f.exists()); - } - })).booleanValue(); - } - - long getLastModified(final File f) { - return ((Long) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return new Long(f.lastModified()); - } - })).longValue(); - } - -} diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/utils/ConfigurationError.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/com/sun/org/apache/xalan/internal/utils/ConfigurationError.java Tue Apr 17 11:17:59 2012 -0700 @@ -0,0 +1,61 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Copyright 2001-2004 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. + */ +/* + * $Id: ObjectFactory.java,v 1.2.4.1 2005/09/15 02:39:54 jeffsuttor Exp $ + */ + +package com.sun.org.apache.xalan.internal.utils; + +/** + * A configuration error. This was an internal class in ObjectFactory previously + */ +public final class ConfigurationError + extends Error { + + // + // Data + // + + /** Exception. */ + private Exception exception; + + // + // Constructors + // + + /** + * Construct a new instance with the specified detail string and + * exception. + */ + ConfigurationError(String msg, Exception x) { + super(msg); + this.exception = x; + } // (String,Exception) + + // + // methods + // + + /** Returns the exception associated to this error. */ + public Exception getException() { + return exception; + } // getException():Exception + +} // class ConfigurationError diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/utils/FactoryImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/com/sun/org/apache/xalan/internal/utils/FactoryImpl.java Tue Apr 17 11:17:59 2012 -0700 @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.org.apache.xalan.internal.utils; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.SAXParserFactory; + +/** + * + * @author huizhe wang + */ +public class FactoryImpl { + + static final String DBF = "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl"; + static final String SF = "com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl"; + + static public DocumentBuilderFactory getDOMFactory(boolean useServicesMechanism) { + DocumentBuilderFactory dbf = + useServicesMechanism ? + DocumentBuilderFactory.newInstance() : + DocumentBuilderFactory.newInstance( DBF, + FactoryImpl.class.getClassLoader()); + + return dbf; + } + static public SAXParserFactory getSAXFactory(boolean useServicesMechanism) { + SAXParserFactory factory = + useServicesMechanism ? + SAXParserFactory.newInstance() : + SAXParserFactory.newInstance(SF, + FactoryImpl.class.getClassLoader()); + return factory; + } +} diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/utils/ObjectFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/com/sun/org/apache/xalan/internal/utils/ObjectFactory.java Tue Apr 17 11:17:59 2012 -0700 @@ -0,0 +1,652 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Copyright 2001-2004 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. + */ +/* + * $Id: ObjectFactory.java,v 1.2.4.1 2005/09/15 02:39:54 jeffsuttor Exp $ + */ + +package com.sun.org.apache.xalan.internal.utils; + +import java.io.InputStream; +import java.io.IOException; +import java.io.File; +import java.io.FileInputStream; + +import java.util.Properties; +import java.io.BufferedReader; +import java.io.InputStreamReader; + +/** + * 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. + *

+ * This code is designed to implement the JAXP 1.1 spec pluggability + * feature and is designed to run on JDK version 1.1 and + * later, and to compile on JDK 1.2 and onward. + * The code also runs both as part of an unbundled jar file and + * when bundled as part of the JDK. + *

+ * This class was moved from the javax.xml.parsers.ObjectFactory + * class and modified to be used as a general utility for creating objects + * dynamically. + * + * @version $Id: ObjectFactory.java,v 1.11 2010-11-01 04:34:25 joehw Exp $ + */ +public class ObjectFactory { + + // + // Constants + // + + // name of default properties file to look for in JDK's jre/lib directory + private static final String DEFAULT_PROPERTIES_FILENAME = + "xalan.properties"; + + private static final String SERVICES_PATH = "META-INF/services/"; + + /** Set to true for debugging */ + private static final boolean DEBUG = false; + + /** cache the contents of the xalan.properties file. + * Until an attempt has been made to read this file, this will + * be null; if the file does not exist or we encounter some other error + * during the read, this will be empty. + */ + private static Properties fXalanProperties = null; + + /*** + * Cache the time stamp of the xalan.properties file so + * that we know if it's been modified and can invalidate + * the cache when necessary. + */ + private static long fLastModified = -1; + + // + // Public static methods + // + + /** + * Finds the implementation Class object in the specified order. The + * specified order is the following: + *

    + *
  1. query the system property using System.getProperty + *
  2. read META-INF/services/factoryId file + *
  3. use fallback classname + *
+ * + * @return instance of factory, 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 no fallback. + * + * @exception ObjectFactory.ConfigurationError + */ + public static Object createObject(String factoryId, String fallbackClassName) + throws ConfigurationError { + return createObject(factoryId, null, fallbackClassName); + } // createObject(String,String):Object + + /** + * Finds the implementation Class object in the specified order. The + * specified order is the following: + *
    + *
  1. query the system property using System.getProperty + *
  2. read $java.home/lib/propertiesFilename file + *
  3. read META-INF/services/factoryId file + *
  4. use fallback classname + *
+ * + * @return instance of factory, never null + * + * @param factoryId Name of the factory to find, same as + * a property name + * @param propertiesFilename The filename in the $java.home/lib directory + * of the properties file. If none specified, + * ${java.home}/lib/xalan.properties will be used. + * @param fallbackClassName Implementation class name, if nothing else + * is found. Use null to mean no fallback. + * + * @exception ObjectFactory.ConfigurationError + */ + static Object createObject(String factoryId, + String propertiesFilename, + String fallbackClassName) + throws ConfigurationError + { + Class factoryClass = lookUpFactoryClass(factoryId, + propertiesFilename, + fallbackClassName); + + if (factoryClass == null) { + throw new ConfigurationError( + "Provider for " + factoryId + " cannot be found", null); + } + + try{ + Object instance = factoryClass.newInstance(); + if (DEBUG) debugPrintln("created new instance of factory " + factoryId); + return instance; + } catch (Exception x) { + throw new ConfigurationError( + "Provider for factory " + factoryId + + " could not be instantiated: " + x, x); + } + } // createObject(String,String,String):Object + + /** + * Finds the implementation Class object in the specified order. The + * specified order is the following: + *
    + *
  1. query the system property using System.getProperty + *
  2. read $java.home/lib/propertiesFilename file + *
  3. read META-INF/services/factoryId file + *
  4. use fallback classname + *
+ * + * @return Class object of factory, never null + * + * @param factoryId Name of the factory to find, same as + * a property name + * @param propertiesFilename The filename in the $java.home/lib directory + * of the properties file. If none specified, + * ${java.home}/lib/xalan.properties will be used. + * @param fallbackClassName Implementation class name, if nothing else + * is found. Use null to mean no fallback. + * + * @exception ObjectFactory.ConfigurationError + */ + public static Class lookUpFactoryClass(String factoryId) + throws ConfigurationError + { + return lookUpFactoryClass(factoryId, null, null); + } // lookUpFactoryClass(String):Class + + /** + * Finds the implementation Class object in the specified order. The + * specified order is the following: + *
    + *
  1. query the system property using System.getProperty + *
  2. read $java.home/lib/propertiesFilename file + *
  3. read META-INF/services/factoryId file + *
  4. use fallback classname + *
+ * + * @return Class object that provides factory service, never null + * + * @param factoryId Name of the factory to find, same as + * a property name + * @param propertiesFilename The filename in the $java.home/lib directory + * of the properties file. If none specified, + * ${java.home}/lib/xalan.properties will be used. + * @param fallbackClassName Implementation class name, if nothing else + * is found. Use null to mean no fallback. + * + * @exception ObjectFactory.ConfigurationError + */ + public static Class lookUpFactoryClass(String factoryId, + String propertiesFilename, + String fallbackClassName) + throws ConfigurationError + { + String factoryClassName = lookUpFactoryClassName(factoryId, + propertiesFilename, + fallbackClassName); + ClassLoader cl = findClassLoader(); + + if (factoryClassName == null) { + factoryClassName = fallbackClassName; + } + + // assert(className != null); + try{ + Class providerClass = findProviderClass(factoryClassName, + cl, + true); + if (DEBUG) debugPrintln("created new instance of " + providerClass + + " using ClassLoader: " + cl); + return providerClass; + } catch (ClassNotFoundException x) { + throw new ConfigurationError( + "Provider " + factoryClassName + " not found", x); + } catch (Exception x) { + throw new ConfigurationError( + "Provider "+factoryClassName+" could not be instantiated: "+x, + x); + } + } // lookUpFactoryClass(String,String,String):Class + + /** + * Finds the name of the required implementation class in the specified + * order. The specified order is the following: + *
    + *
  1. query the system property using System.getProperty + *
  2. read $java.home/lib/propertiesFilename file + *
  3. read META-INF/services/factoryId file + *
  4. use fallback classname + *
+ * + * @return name of class that provides factory service, never null + * + * @param factoryId Name of the factory to find, same as + * a property name + * @param propertiesFilename The filename in the $java.home/lib directory + * of the properties file. If none specified, + * ${java.home}/lib/xalan.properties will be used. + * @param fallbackClassName Implementation class name, if nothing else + * is found. Use null to mean no fallback. + * + * @exception ObjectFactory.ConfigurationError + */ + static String lookUpFactoryClassName(String factoryId, + String propertiesFilename, + String fallbackClassName) + { + // Use the system property first + try { + String systemProp = SecuritySupport.getSystemProperty(factoryId); + if (systemProp != null) { + if (DEBUG) debugPrintln("found system property, value=" + systemProp); + return systemProp; + } + } catch (SecurityException se) { + // Ignore and continue w/ next location + } + + // Try to read from propertiesFilename, or + // $java.home/lib/xalan.properties + String factoryClassName = null; + // no properties file name specified; use + // $JAVA_HOME/lib/xalan.properties: + if (propertiesFilename == null) { + File propertiesFile = null; + boolean propertiesFileExists = false; + try { + String javah = SecuritySupport.getSystemProperty("java.home"); + propertiesFilename = javah + File.separator + + "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME; + propertiesFile = new File(propertiesFilename); + propertiesFileExists = SecuritySupport.getFileExists(propertiesFile); + } catch (SecurityException e) { + // try again... + fLastModified = -1; + fXalanProperties = null; + } + + synchronized (ObjectFactory.class) { + boolean loadProperties = false; + FileInputStream fis = null; + try { + // file existed last time + if(fLastModified >= 0) { + if(propertiesFileExists && + (fLastModified < (fLastModified = SecuritySupport.getLastModified(propertiesFile)))) { + loadProperties = true; + } else { + // file has stopped existing... + if(!propertiesFileExists) { + fLastModified = -1; + fXalanProperties = null; + } // else, file wasn't modified! + } + } else { + // file has started to exist: + if(propertiesFileExists) { + loadProperties = true; + fLastModified = SecuritySupport.getLastModified(propertiesFile); + } // else, nothing's changed + } + if(loadProperties) { + // must never have attempted to read xalan.properties + // before (or it's outdeated) + fXalanProperties = new Properties(); + fis = SecuritySupport.getFileInputStream(propertiesFile); + fXalanProperties.load(fis); + } + } catch (Exception x) { + fXalanProperties = null; + fLastModified = -1; + // assert(x instanceof FileNotFoundException + // || x instanceof SecurityException) + // In both cases, ignore and continue w/ next location + } + finally { + // try to close the input stream if one was opened. + if (fis != null) { + try { + fis.close(); + } + // Ignore the exception. + catch (IOException exc) {} + } + } + } + if(fXalanProperties != null) { + factoryClassName = fXalanProperties.getProperty(factoryId); + } + } else { + FileInputStream fis = null; + try { + fis = SecuritySupport.getFileInputStream(new File(propertiesFilename)); + Properties props = new Properties(); + props.load(fis); + factoryClassName = props.getProperty(factoryId); + } catch (Exception x) { + // assert(x instanceof FileNotFoundException + // || x instanceof SecurityException) + // In both cases, ignore and continue w/ next location + } + finally { + // try to close the input stream if one was opened. + if (fis != null) { + try { + fis.close(); + } + // Ignore the exception. + catch (IOException exc) {} + } + } + } + if (factoryClassName != null) { + if (DEBUG) debugPrintln("found in " + propertiesFilename + ", value=" + + factoryClassName); + return factoryClassName; + } + + // Try Jar Service Provider Mechanism + return findJarServiceProviderName(factoryId); + } // lookUpFactoryClass(String,String):String + + // + // Private static methods + // + + /** Prints a message to standard error if debugging is enabled. */ + private static void debugPrintln(String msg) { + if (DEBUG) { + System.err.println("JAXP: " + msg); + } + } // debugPrintln(String) + + /** + * Figure out which ClassLoader to use. For JDK 1.2 and later use + * the context ClassLoader. + */ + public static ClassLoader findClassLoader() + throws ConfigurationError + { + if (System.getSecurityManager()!=null) { + //this will ensure bootclassloader is used + return null; + } + + // Figure out which ClassLoader to use for loading the provider + // class. If there is a Context ClassLoader then use it. + ClassLoader context = SecuritySupport.getContextClassLoader(); + ClassLoader system = SecuritySupport.getSystemClassLoader(); + + ClassLoader chain = system; + while (true) { + if (context == chain) { + // Assert: we are on JDK 1.1 or we have no Context ClassLoader + // or any Context ClassLoader in chain of system classloader + // (including extension ClassLoader) so extend to widest + // ClassLoader (always look in system ClassLoader if Xalan + // is in boot/extension/system classpath and in current + // ClassLoader otherwise); normal classloaders delegate + // back to system ClassLoader first so this widening doesn't + // change the fact that context ClassLoader will be consulted + ClassLoader current = ObjectFactory.class.getClassLoader(); + + chain = system; + while (true) { + if (current == chain) { + // Assert: Current ClassLoader in chain of + // boot/extension/system ClassLoaders + return system; + } + if (chain == null) { + break; + } + chain = SecuritySupport.getParentClassLoader(chain); + } + + // Assert: Current ClassLoader not in chain of + // boot/extension/system ClassLoaders + return current; + } + + if (chain == null) { + // boot ClassLoader reached + break; + } + + // Check for any extension ClassLoaders in chain up to + // boot ClassLoader + chain = SecuritySupport.getParentClassLoader(chain); + } + + // Assert: Context ClassLoader not in chain of + // boot/extension/system ClassLoaders + return context; + } // findClassLoader():ClassLoader + + /** + * Create an instance of a class using the same classloader for the ObjectFactory by default + * or bootclassloader when Security Manager is in place + */ + public static Object newInstance(String className, boolean doFallback) + throws ConfigurationError + { + if (System.getSecurityManager()!=null) { + return newInstance(className, null, doFallback); + } else { + return newInstance(className, + findClassLoader (), doFallback); + } + } + + /** + * Create an instance of a class using the specified ClassLoader + */ + static Object newInstance(String className, ClassLoader cl, + boolean doFallback) + throws ConfigurationError + { + // assert(className != null); + try{ + Class providerClass = findProviderClass(className, cl, doFallback); + Object instance = providerClass.newInstance(); + if (DEBUG) debugPrintln("created new instance of " + providerClass + + " using ClassLoader: " + cl); + return instance; + } catch (ClassNotFoundException x) { + throw new ConfigurationError( + "Provider " + className + " not found", x); + } catch (Exception x) { + throw new ConfigurationError( + "Provider " + className + " could not be instantiated: " + x, + x); + } + } + + /** + * Find a Class using the same classloader for the ObjectFactory by default + * or bootclassloader when Security Manager is in place + */ + public static Class findProviderClass(String className, boolean doFallback) + throws ClassNotFoundException, ConfigurationError + { + if (System.getSecurityManager()!=null) { + return Class.forName(className); + } else { + return findProviderClass (className, + findClassLoader (), doFallback); + } + } + + /** + * Find a Class using the specified ClassLoader + */ + static Class findProviderClass(String className, ClassLoader cl, + boolean doFallback) + throws ClassNotFoundException, ConfigurationError + { + //throw security exception if the calling thread is not allowed to access the + //class. Restrict the access to the package classes as specified in java.security policy. + SecurityManager security = System.getSecurityManager(); + try{ + if (security != null){ + final int lastDot = className.lastIndexOf("."); + String packageName = className; + if (lastDot != -1) packageName = className.substring(0, lastDot); + security.checkPackageAccess(packageName); + } + }catch(SecurityException e){ + throw e; + } + + Class providerClass; + 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 { + try { + providerClass = cl.loadClass(className); + } catch (ClassNotFoundException x) { + if (doFallback) { + // Fall back to current classloader + ClassLoader current = ObjectFactory.class.getClassLoader(); + if (current == null) { + providerClass = Class.forName(className); + } else if (cl != current) { + cl = current; + providerClass = cl.loadClass(className); + } else { + throw x; + } + } else { + throw x; + } + } + } + + return providerClass; + } + + /** + * Find the name of service provider using Jar Service Provider Mechanism + * + * @return instance of provider class if found or null + */ + private static String findJarServiceProviderName(String factoryId) + { + String serviceId = SERVICES_PATH + factoryId; + InputStream is = null; + + // First try the Context ClassLoader + ClassLoader cl = findClassLoader(); + + is = SecuritySupport.getResourceAsStream(cl, serviceId); + + // If no provider found then try the current ClassLoader + if (is == null) { + ClassLoader current = ObjectFactory.class.getClassLoader(); + if (cl != current) { + cl = current; + is = SecuritySupport.getResourceAsStream(cl, serviceId); + } + } + + if (is == null) { + // No provider found + return null; + } + + if (DEBUG) debugPrintln("found jar resource=" + serviceId + + " using ClassLoader: " + cl); + + // 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)); + } + + String factoryClassName = null; + try { + // XXX Does not handle all possible input as specified by the + // Jar Service Provider specification + factoryClassName = rd.readLine(); + } catch (IOException x) { + // No provider found + return null; + } + finally { + try { + // try to close the reader. + rd.close(); + } + // Ignore the exception. + catch (IOException exc) {} + } + + if (factoryClassName != null && + ! "".equals(factoryClassName)) { + if (DEBUG) debugPrintln("found in resource, value=" + + factoryClassName); + + // Note: here we do not want to fall back to the current + // 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. + return factoryClassName; + } + + // No provider found + return null; + } + +} // class ObjectFactory diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/utils/SecuritySupport.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/com/sun/org/apache/xalan/internal/utils/SecuritySupport.java Tue Apr 17 11:17:59 2012 -0700 @@ -0,0 +1,166 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Copyright 2002-2004 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. + */ +/* + * $Id: SecuritySupport.java,v 1.1.2.1 2005/08/01 02:08:48 jeffsuttor Exp $ + */ + +package com.sun.org.apache.xalan.internal.utils; + +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 subpackage so keep it in sync. + * It is package private and therefore is not exposed as part of any API. + * + * @xerces.internal + */ +public final class SecuritySupport { + + private static final SecuritySupport securitySupport = new SecuritySupport(); + + /** + * Return an instance of this class. + */ + public static SecuritySupport getInstance() { + return securitySupport; + } + + static ClassLoader getContextClassLoader() { + return (ClassLoader) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + ClassLoader cl = null; + try { + cl = Thread.currentThread().getContextClassLoader(); + } catch (SecurityException ex) { } + return cl; + } + }); + } + + static ClassLoader getSystemClassLoader() { + return (ClassLoader) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + ClassLoader cl = null; + try { + cl = ClassLoader.getSystemClassLoader(); + } catch (SecurityException ex) {} + return cl; + } + }); + } + + static ClassLoader getParentClassLoader(final ClassLoader cl) { + return (ClassLoader) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + ClassLoader parent = null; + try { + parent = cl.getParent(); + } catch (SecurityException ex) {} + + // eliminate loops in case of the boot + // ClassLoader returning itself as a parent + return (parent == cl) ? null : parent; + } + }); + } + + public static String getSystemProperty(final String propName) { + return (String) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + return System.getProperty(propName); + } + }); + } + + static 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(); + } + } + /** + * Return resource using the same classloader for the ObjectFactory by default + * or bootclassloader when Security Manager is in place + */ + public static InputStream getResourceAsStream(final String name) { + if (System.getSecurityManager()!=null) { + return getResourceAsStream(null, name); + } else { + return getResourceAsStream(ObjectFactory.findClassLoader(), name); + } + } + + public static InputStream getResourceAsStream(final ClassLoader cl, + final String name) + { + return (InputStream) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + InputStream ris; + if (cl == null) { + ris = Object.class.getResourceAsStream("/"+name); + } else { + ris = cl.getResourceAsStream(name); + } + return ris; + } + }); + } + + static boolean getFileExists(final File f) { + return ((Boolean) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + return f.exists() ? Boolean.TRUE : Boolean.FALSE; + } + })).booleanValue(); + } + + static long getLastModified(final File f) { + return ((Long) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + return new Long(f.lastModified()); + } + })).longValue(); + } + + private SecuritySupport () {} +} diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xslt/EnvironmentCheck.java --- a/src/com/sun/org/apache/xalan/internal/xslt/EnvironmentCheck.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xslt/EnvironmentCheck.java Tue Apr 17 11:17:59 2012 -0700 @@ -22,6 +22,8 @@ */ package com.sun.org.apache.xalan.internal.xslt; +import com.sun.org.apache.xalan.internal.utils.ObjectFactory; + import java.io.File; import java.io.FileWriter; import java.io.PrintWriter; @@ -794,8 +796,7 @@ { final String JAXP1_CLASS = "javax.xml.stream.XMLStreamConstants"; - clazz = ObjectFactory.findProviderClass( - JAXP1_CLASS, ObjectFactory.findClassLoader(), true); + clazz = ObjectFactory.findProviderClass(JAXP1_CLASS, true); // If we succeeded, we have JAXP 1.4 available h.put(VERSION + "JAXP", "1.4"); @@ -825,8 +826,7 @@ final String XALAN1_VERSION_CLASS = "com.sun.org.apache.xalan.internal.xslt.XSLProcessorVersion"; - Class clazz = ObjectFactory.findProviderClass( - XALAN1_VERSION_CLASS, ObjectFactory.findClassLoader(), true); + Class clazz = ObjectFactory.findProviderClass(XALAN1_VERSION_CLASS, true); // Found Xalan-J 1.x, grab it's version fields StringBuffer buf = new StringBuffer(); @@ -858,8 +858,7 @@ final String XALAN2_VERSION_CLASS = "com.sun.org.apache.xalan.internal.processor.XSLProcessorVersion"; - Class clazz = ObjectFactory.findProviderClass( - XALAN2_VERSION_CLASS, ObjectFactory.findClassLoader(), true); + Class clazz = ObjectFactory.findProviderClass(XALAN2_VERSION_CLASS, true); // Found Xalan-J 2.x, grab it's version fields StringBuffer buf = new StringBuffer(); @@ -880,8 +879,7 @@ final String XALAN2_2_VERSION_METHOD = "getVersion"; final Class noArgs[] = new Class[0]; - Class clazz = ObjectFactory.findProviderClass( - XALAN2_2_VERSION_CLASS, ObjectFactory.findClassLoader(), true); + Class clazz = ObjectFactory.findProviderClass(XALAN2_2_VERSION_CLASS, true); Method method = clazz.getMethod(XALAN2_2_VERSION_METHOD, noArgs); Object returnValue = method.invoke(null, new Object[0]); @@ -913,8 +911,7 @@ { final String XERCES1_VERSION_CLASS = "com.sun.org.apache.xerces.internal.framework.Version"; - Class clazz = ObjectFactory.findProviderClass( - XERCES1_VERSION_CLASS, ObjectFactory.findClassLoader(), true); + Class clazz = ObjectFactory.findProviderClass(XERCES1_VERSION_CLASS, true); // Found Xerces-J 1.x, grab it's version fields Field f = clazz.getField("fVersion"); @@ -932,8 +929,7 @@ { final String XERCES2_VERSION_CLASS = "com.sun.org.apache.xerces.internal.impl.Version"; - Class clazz = ObjectFactory.findProviderClass( - XERCES2_VERSION_CLASS, ObjectFactory.findClassLoader(), true); + Class clazz = ObjectFactory.findProviderClass(XERCES2_VERSION_CLASS, true); // Found Xerces-J 2.x, grab it's version fields Field f = clazz.getField("fVersion"); @@ -950,8 +946,7 @@ { final String CRIMSON_CLASS = "org.apache.crimson.parser.Parser2"; - Class clazz = ObjectFactory.findProviderClass( - CRIMSON_CLASS, ObjectFactory.findClassLoader(), true); + Class clazz = ObjectFactory.findProviderClass(CRIMSON_CLASS, true); //@todo determine specific crimson version h.put(VERSION + "crimson", CLASS_PRESENT); @@ -979,8 +974,7 @@ final String ANT_VERSION_METHOD = "getAntVersion"; // noArgs final Class noArgs[] = new Class[0]; - Class clazz = ObjectFactory.findProviderClass( - ANT_VERSION_CLASS, ObjectFactory.findClassLoader(), true); + Class clazz = ObjectFactory.findProviderClass(ANT_VERSION_CLASS, true); Method method = clazz.getMethod(ANT_VERSION_METHOD, noArgs); Object returnValue = method.invoke(null, new Object[0]); @@ -1009,8 +1003,7 @@ try { - Class clazz = ObjectFactory.findProviderClass( - DOM_CLASS, ObjectFactory.findClassLoader(), true); + Class clazz = ObjectFactory.findProviderClass(DOM_CLASS, true); Method method = clazz.getMethod(DOM_LEVEL3_METHOD, null); @@ -1052,8 +1045,7 @@ try { - Class clazz = ObjectFactory.findProviderClass( - DOM_LEVEL2_CLASS, ObjectFactory.findClassLoader(), true); + Class clazz = ObjectFactory.findProviderClass(DOM_LEVEL2_CLASS, true); Method method = clazz.getMethod(DOM_LEVEL2_METHOD, twoStringArgs); @@ -1065,8 +1057,7 @@ { // Check for the working draft version, which is // commonly found, but won't work anymore - clazz = ObjectFactory.findProviderClass( - DOM_LEVEL2WD_CLASS, ObjectFactory.findClassLoader(), true); + clazz = ObjectFactory.findProviderClass(DOM_LEVEL2WD_CLASS, true); method = clazz.getMethod(DOM_LEVEL2WD_METHOD, twoStringArgs); @@ -1078,8 +1069,7 @@ try { // Check for the final draft version as well - clazz = ObjectFactory.findProviderClass( - DOM_LEVEL2FD_CLASS, ObjectFactory.findClassLoader(), true); + clazz = ObjectFactory.findProviderClass(DOM_LEVEL2FD_CLASS, true); method = clazz.getMethod(DOM_LEVEL2FD_METHOD, twoStringArgs); @@ -1133,8 +1123,7 @@ { // This method was only added in the final SAX 2.0 release; // see changes.html "Changes from SAX 2.0beta2 to SAX 2.0prerelease" - Class clazz = ObjectFactory.findProviderClass( - SAX_VERSION2BETA_CLASSNF, ObjectFactory.findClassLoader(), true); + Class clazz = ObjectFactory.findProviderClass(SAX_VERSION2BETA_CLASSNF, true); Method method = clazz.getMethod(SAX_VERSION2BETA_METHODNF, attributesArg); @@ -1151,8 +1140,7 @@ try { - Class clazz = ObjectFactory.findProviderClass( - SAX_VERSION2_CLASS, ObjectFactory.findClassLoader(), true); + Class clazz = ObjectFactory.findProviderClass(SAX_VERSION2_CLASS, true); Method method = clazz.getMethod(SAX_VERSION2_METHOD, oneStringArg); @@ -1170,8 +1158,7 @@ try { - Class clazz = ObjectFactory.findProviderClass( - SAX_VERSION1_CLASS, ObjectFactory.findClassLoader(), true); + Class clazz = ObjectFactory.findProviderClass(SAX_VERSION1_CLASS, true); Method method = clazz.getMethod(SAX_VERSION1_METHOD, oneStringArg); diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xslt/ObjectFactory.java --- a/src/com/sun/org/apache/xalan/internal/xslt/ObjectFactory.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,663 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2001-2004 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. - */ -/* - * $Id: ObjectFactory.java,v 1.2.4.1 2005/09/12 12:18:06 pvedula Exp $ - */ - -package com.sun.org.apache.xalan.internal.xslt; - -import java.io.InputStream; -import java.io.IOException; -import java.io.File; -import java.io.FileInputStream; - -import java.util.Properties; -import java.io.BufferedReader; -import java.io.InputStreamReader; - -/** - * 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. - *

- * This code is designed to implement the JAXP 1.1 spec pluggability - * feature and is designed to run on JDK version 1.1 and - * later, and to compile on JDK 1.2 and onward. - * The code also runs both as part of an unbundled jar file and - * when bundled as part of the JDK. - *

- * This class was moved from the javax.xml.parsers.ObjectFactory - * class and modified to be used as a general utility for creating objects - * dynamically. - * - * @version $Id: ObjectFactory.java,v 1.9 2008/04/02 00:41:00 joehw Exp $ - */ -class ObjectFactory { - - // - // Constants - // - - // name of default properties file to look for in JDK's jre/lib directory - private static final String DEFAULT_PROPERTIES_FILENAME = - "xalan.properties"; - - private static final String SERVICES_PATH = "META-INF/services/"; - - /** Set to true for debugging */ - private static final boolean DEBUG = false; - - /** cache the contents of the xalan.properties file. - * Until an attempt has been made to read this file, this will - * be null; if the file does not exist or we encounter some other error - * during the read, this will be empty. - */ - private static Properties fXalanProperties = null; - - /*** - * Cache the time stamp of the xalan.properties file so - * that we know if it's been modified and can invalidate - * the cache when necessary. - */ - private static long fLastModified = -1; - - // - // Public static methods - // - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *

    - *
  1. query the system property using System.getProperty - *
  2. read META-INF/services/factoryId file - *
  3. use fallback classname - *
- * - * @return instance of factory, 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 no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Object createObject(String factoryId, String fallbackClassName) - throws ConfigurationError { - return createObject(factoryId, null, fallbackClassName); - } // createObject(String,String):Object - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return instance of factory, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Object createObject(String factoryId, - String propertiesFilename, - String fallbackClassName) - throws ConfigurationError - { - Class factoryClass = lookUpFactoryClass(factoryId, - propertiesFilename, - fallbackClassName); - - if (factoryClass == null) { - throw new ConfigurationError( - "Provider for " + factoryId + " cannot be found", null); - } - - try{ - Object instance = factoryClass.newInstance(); - if (DEBUG) debugPrintln("created new instance of factory " + factoryId); - return instance; - } catch (Exception x) { - throw new ConfigurationError( - "Provider for factory " + factoryId - + " could not be instantiated: " + x, x); - } - } // createObject(String,String,String):Object - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return Class object of factory, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Class lookUpFactoryClass(String factoryId) - throws ConfigurationError - { - return lookUpFactoryClass(factoryId, null, null); - } // lookUpFactoryClass(String):Class - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return Class object that provides factory service, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Class lookUpFactoryClass(String factoryId, - String propertiesFilename, - String fallbackClassName) - throws ConfigurationError - { - String factoryClassName = lookUpFactoryClassName(factoryId, - propertiesFilename, - fallbackClassName); - ClassLoader cl = findClassLoader(); - - if (factoryClassName == null) { - factoryClassName = fallbackClassName; - } - - // assert(className != null); - try{ - Class providerClass = findProviderClass(factoryClassName, - cl, - true); - if (DEBUG) debugPrintln("created new instance of " + providerClass + - " using ClassLoader: " + cl); - return providerClass; - } catch (ClassNotFoundException x) { - throw new ConfigurationError( - "Provider " + factoryClassName + " not found", x); - } catch (Exception x) { - throw new ConfigurationError( - "Provider "+factoryClassName+" could not be instantiated: "+x, - x); - } - } // lookUpFactoryClass(String,String,String):Class - - /** - * Finds the name of the required implementation class in the specified - * order. The specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return name of class that provides factory service, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static String lookUpFactoryClassName(String factoryId, - String propertiesFilename, - String fallbackClassName) - { - SecuritySupport ss = SecuritySupport.getInstance(); - - // Use the system property first - try { - String systemProp = ss.getSystemProperty(factoryId); - if (systemProp != null) { - if (DEBUG) debugPrintln("found system property, value=" + systemProp); - return systemProp; - } - } catch (SecurityException se) { - // Ignore and continue w/ next location - } - - // Try to read from propertiesFilename, or - // $java.home/lib/xalan.properties - String factoryClassName = null; - // no properties file name specified; use - // $JAVA_HOME/lib/xalan.properties: - if (propertiesFilename == null) { - File propertiesFile = null; - boolean propertiesFileExists = false; - try { - String javah = ss.getSystemProperty("java.home"); - propertiesFilename = javah + File.separator + - "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME; - propertiesFile = new File(propertiesFilename); - propertiesFileExists = ss.getFileExists(propertiesFile); - } catch (SecurityException e) { - // try again... - fLastModified = -1; - fXalanProperties = null; - } - - synchronized (ObjectFactory.class) { - boolean loadProperties = false; - FileInputStream fis = null; - try { - // file existed last time - if(fLastModified >= 0) { - if(propertiesFileExists && - (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) { - loadProperties = true; - } else { - // file has stopped existing... - if(!propertiesFileExists) { - fLastModified = -1; - fXalanProperties = null; - } // else, file wasn't modified! - } - } else { - // file has started to exist: - if(propertiesFileExists) { - loadProperties = true; - fLastModified = ss.getLastModified(propertiesFile); - } // else, nothing's changed - } - if(loadProperties) { - // must never have attempted to read xalan.properties - // before (or it's outdeated) - fXalanProperties = new Properties(); - fis = ss.getFileInputStream(propertiesFile); - fXalanProperties.load(fis); - } - } catch (Exception x) { - fXalanProperties = null; - fLastModified = -1; - // assert(x instanceof FileNotFoundException - // || x instanceof SecurityException) - // In both cases, ignore and continue w/ next location - } - finally { - // try to close the input stream if one was opened. - if (fis != null) { - try { - fis.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - } - } - if(fXalanProperties != null) { - factoryClassName = fXalanProperties.getProperty(factoryId); - } - } else { - FileInputStream fis = null; - try { - fis = ss.getFileInputStream(new File(propertiesFilename)); - Properties props = new Properties(); - props.load(fis); - factoryClassName = props.getProperty(factoryId); - } catch (Exception x) { - // assert(x instanceof FileNotFoundException - // || x instanceof SecurityException) - // In both cases, ignore and continue w/ next location - } - finally { - // try to close the input stream if one was opened. - if (fis != null) { - try { - fis.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - } - } - if (factoryClassName != null) { - if (DEBUG) debugPrintln("found in " + propertiesFilename + ", value=" - + factoryClassName); - return factoryClassName; - } - - // Try Jar Service Provider Mechanism - return findJarServiceProviderName(factoryId); - } // lookUpFactoryClass(String,String):String - - // - // Private static methods - // - - /** Prints a message to standard error if debugging is enabled. */ - private static void debugPrintln(String msg) { - if (DEBUG) { - System.err.println("JAXP: " + msg); - } - } // debugPrintln(String) - - /** - * Figure out which ClassLoader to use. For JDK 1.2 and later use - * the context ClassLoader. - */ - static ClassLoader findClassLoader() - 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 context = ss.getContextClassLoader(); - ClassLoader system = ss.getSystemClassLoader(); - - ClassLoader chain = system; - while (true) { - if (context == chain) { - // Assert: we are on JDK 1.1 or we have no Context ClassLoader - // or any Context ClassLoader in chain of system classloader - // (including extension ClassLoader) so extend to widest - // ClassLoader (always look in system ClassLoader if Xalan - // is in boot/extension/system classpath and in current - // ClassLoader otherwise); normal classloaders delegate - // back to system ClassLoader first so this widening doesn't - // change the fact that context ClassLoader will be consulted - ClassLoader current = ObjectFactory.class.getClassLoader(); - - chain = system; - while (true) { - if (current == chain) { - // Assert: Current ClassLoader in chain of - // boot/extension/system ClassLoaders - return system; - } - if (chain == null) { - break; - } - chain = ss.getParentClassLoader(chain); - } - - // Assert: Current ClassLoader not in chain of - // boot/extension/system ClassLoaders - return current; - } - - if (chain == null) { - // boot ClassLoader reached - break; - } - - // Check for any extension ClassLoaders in chain up to - // boot ClassLoader - chain = ss.getParentClassLoader(chain); - }; - - // Assert: Context ClassLoader not in chain of - // boot/extension/system ClassLoaders - return context; - } // findClassLoader():ClassLoader - - /** - * Create an instance of a class using the specified ClassLoader - */ - static Object newInstance(String className, ClassLoader cl, - boolean doFallback) - throws ConfigurationError - { - // assert(className != null); - try{ - Class providerClass = findProviderClass(className, cl, doFallback); - Object instance = providerClass.newInstance(); - if (DEBUG) debugPrintln("created new instance of " + providerClass + - " using ClassLoader: " + cl); - return instance; - } catch (ClassNotFoundException x) { - throw new ConfigurationError( - "Provider " + className + " not found", x); - } catch (Exception x) { - throw new ConfigurationError( - "Provider " + className + " could not be instantiated: " + x, - x); - } - } - - /** - * Find a Class using the specified ClassLoader - */ - static Class findProviderClass(String className, ClassLoader cl, - boolean doFallback) - throws ClassNotFoundException, ConfigurationError - { - //throw security exception if the calling thread is not allowed to access the - //class. Restrict the access to the package classes as specified in java.security policy. - SecurityManager security = System.getSecurityManager(); - try{ - if (security != null){ - final int lastDot = className.lastIndexOf("."); - String packageName = className; - if (lastDot != -1) packageName = className.substring(0, lastDot); - security.checkPackageAccess(packageName); - } - }catch(SecurityException e){ - throw e; - } - - Class providerClass; - 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 { - try { - providerClass = cl.loadClass(className); - } catch (ClassNotFoundException x) { - if (doFallback) { - // Fall back to current classloader - ClassLoader current = ObjectFactory.class.getClassLoader(); - if (current == null) { - providerClass = Class.forName(className); - } else if (cl != current) { - cl = current; - providerClass = cl.loadClass(className); - } else { - throw x; - } - } else { - throw x; - } - } - } - - return providerClass; - } - - /** - * Find the name of service provider using Jar Service Provider Mechanism - * - * @return instance of provider class if found or null - */ - private static String findJarServiceProviderName(String factoryId) - { - SecuritySupport ss = SecuritySupport.getInstance(); - String serviceId = SERVICES_PATH + factoryId; - InputStream is = null; - - // First try the Context ClassLoader - ClassLoader cl = findClassLoader(); - - is = ss.getResourceAsStream(cl, serviceId); - - // If no provider found then try the current ClassLoader - if (is == null) { - ClassLoader current = ObjectFactory.class.getClassLoader(); - if (cl != current) { - cl = current; - is = ss.getResourceAsStream(cl, serviceId); - } - } - - if (is == null) { - // No provider found - return null; - } - - if (DEBUG) debugPrintln("found jar resource=" + serviceId + - " using ClassLoader: " + cl); - - // 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)); - } - - String factoryClassName = null; - try { - // XXX Does not handle all possible input as specified by the - // Jar Service Provider specification - factoryClassName = rd.readLine(); - } catch (IOException x) { - // No provider found - return null; - } - finally { - try { - // try to close the reader. - rd.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - - if (factoryClassName != null && - ! "".equals(factoryClassName)) { - if (DEBUG) debugPrintln("found in resource, value=" - + factoryClassName); - - // Note: here we do not want to fall back to the current - // 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. - return factoryClassName; - } - - // No provider found - return null; - } - - // - // Classes - // - - /** - * A configuration error. - */ - static class ConfigurationError - extends Error { - static final long serialVersionUID = 2276082712114762609L; - // - // Data - // - - /** Exception. */ - private Exception exception; - - // - // Constructors - // - - /** - * Construct a new instance with the specified detail string and - * exception. - */ - ConfigurationError(String msg, Exception x) { - super(msg); - this.exception = x; - } // (String,Exception) - - // - // Public methods - // - - /** Returns the exception associated to this error. */ - Exception getException() { - return exception; - } // getException():Exception - - } // class ConfigurationError - -} // class ObjectFactory diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xslt/Process.java --- a/src/com/sun/org/apache/xalan/internal/xslt/Process.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xslt/Process.java Tue Apr 17 11:17:59 2012 -0700 @@ -55,6 +55,8 @@ import com.sun.org.apache.xalan.internal.Version; import com.sun.org.apache.xalan.internal.res.XSLMessages; import com.sun.org.apache.xalan.internal.res.XSLTErrorResources; +import com.sun.org.apache.xalan.internal.utils.ObjectFactory; +import com.sun.org.apache.xalan.internal.utils.ConfigurationError; //J2SE does not support Xalan interpretive /* @@ -457,12 +459,11 @@ { try { - uriResolver = (URIResolver) ObjectFactory.newInstance( - argv[++i], ObjectFactory.findClassLoader(), true); + uriResolver = (URIResolver) ObjectFactory.newInstance(argv[++i], true); tfactory.setURIResolver(uriResolver); } - catch (ObjectFactory.ConfigurationError cnfe) + catch (ConfigurationError cnfe) { msg = XSLMessages.createMessage( XSLTErrorResources.ER_CLASS_NOT_FOUND_FOR_OPTION, @@ -486,10 +487,9 @@ { try { - entityResolver = (EntityResolver) ObjectFactory.newInstance( - argv[++i], ObjectFactory.findClassLoader(), true); + entityResolver = (EntityResolver) ObjectFactory.newInstance(argv[++i], true); } - catch (ObjectFactory.ConfigurationError cnfe) + catch (ConfigurationError cnfe) { msg = XSLMessages.createMessage( XSLTErrorResources.ER_CLASS_NOT_FOUND_FOR_OPTION, @@ -514,10 +514,9 @@ { try { - contentHandler = (ContentHandler) ObjectFactory.newInstance( - argv[++i], ObjectFactory.findClassLoader(), true); + contentHandler = (ContentHandler) ObjectFactory.newInstance(argv[++i], true); } - catch (ObjectFactory.ConfigurationError cnfe) + catch (ConfigurationError cnfe) { msg = XSLMessages.createMessage( XSLTErrorResources.ER_CLASS_NOT_FOUND_FOR_OPTION, diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xslt/SecuritySupport.java --- a/src/com/sun/org/apache/xalan/internal/xslt/SecuritySupport.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,127 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2002-2004 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. - */ -/* - * $Id: SecuritySupport.java,v 1.2.4.1 2005/09/09 07:17:15 pvedula Exp $ - */ - -package com.sun.org.apache.xalan.internal.xslt; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.InputStream; - -import java.util.Properties; - -/** - * This class is duplicated for each Xalan-Java subpackage so keep it in sync. - * It is package private and therefore is not exposed as part of the Xalan-Java - * 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. - */ - static SecuritySupport getInstance() { - return (SecuritySupport)securitySupport; - } - - ClassLoader getContextClassLoader() { - return null; - } - - ClassLoader getSystemClassLoader() { - return null; - } - - ClassLoader getParentClassLoader(ClassLoader cl) { - return null; - } - - String getSystemProperty(String propName) { - return System.getProperty(propName); - } - - FileInputStream getFileInputStream(File file) - throws FileNotFoundException - { - return new FileInputStream(file); - } - - InputStream getResourceAsStream(ClassLoader cl, String name) { - InputStream ris; - if (cl == null) { - ris = ClassLoader.getSystemResourceAsStream(name); - } else { - ris = cl.getResourceAsStream(name); - } - return ris; - } - - boolean getFileExists(File f) { - return f.exists(); - } - - long getLastModified(File f) { - return f.lastModified(); - } -} diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xslt/SecuritySupport12.java --- a/src/com/sun/org/apache/xalan/internal/xslt/SecuritySupport12.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,148 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2002-2004 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. - */ -/* - * $Id: SecuritySupport12.java,v 1.2.4.1 2005/09/09 07:17:45 pvedula Exp $ - */ - -package com.sun.org.apache.xalan.internal.xslt; - -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; - -import java.util.Properties; - -/** - * This class is duplicated for each Xalan-Java subpackage so keep it in sync. - * It is package private and therefore is not exposed as part of the Xalan-Java - * API. - * - * Security related methods that only work on J2SE 1.2 and newer. - */ -class SecuritySupport12 extends SecuritySupport { - - ClassLoader getContextClassLoader() { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader cl = null; - try { - cl = Thread.currentThread().getContextClassLoader(); - } catch (SecurityException ex) { } - return cl; - } - }); - } - - ClassLoader getSystemClassLoader() { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader cl = null; - try { - cl = ClassLoader.getSystemClassLoader(); - } catch (SecurityException ex) {} - return cl; - } - }); - } - - ClassLoader getParentClassLoader(final ClassLoader cl) { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader parent = null; - try { - parent = cl.getParent(); - } catch (SecurityException ex) {} - - // eliminate loops in case of the boot - // ClassLoader returning itself as a parent - return (parent == cl) ? null : parent; - } - }); - } - - String getSystemProperty(final String propName) { - return (String) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return System.getProperty(propName); - } - }); - } - - 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(); - } - } - - 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; - } - }); - } - - boolean getFileExists(final File f) { - return ((Boolean) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return new Boolean(f.exists()); - } - })).booleanValue(); - } - - long getLastModified(final File f) { - return ((Long) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return new Long(f.lastModified()); - } - })).longValue(); - } - -} diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/Translet.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/Translet.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/Translet.java Tue Apr 17 11:17:59 2012 -0700 @@ -51,4 +51,7 @@ public String[] getUrisArray(); public int[] getTypesArray(); public String[] getNamespaceArray(); + public boolean useServicesMechnism(); + public void setServicesMechnism(boolean flag); + } diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/cmdline/Compile.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/cmdline/Compile.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/cmdline/Compile.java Tue Apr 17 11:17:59 2012 -0700 @@ -55,11 +55,10 @@ public static void printUsage() { - StringBuffer vers = new StringBuffer("XSLTC version " + - VERSION_MAJOR + "." + VERSION_MINOR + - ((VERSION_DELTA > 0) ? ("."+VERSION_DELTA) : (""))); - System.err.println(vers + "\n" + - new ErrorMsg(ErrorMsg.COMPILE_USAGE_STR)); + System.err.println("XSLTC version " + + VERSION_MAJOR + "." + VERSION_MINOR + + ((VERSION_DELTA > 0) ? ("." + VERSION_DELTA) : ("")) + "\n" + + new ErrorMsg(ErrorMsg.COMPILE_USAGE_STR)); if (_allowExit) System.exit(-1); } @@ -78,7 +77,7 @@ final GetOpt getopt = new GetOpt(args, "o:d:j:p:uxhsinv"); if (args.length < 1) printUsage(); - final XSLTC xsltc = new XSLTC(); + final XSLTC xsltc = new XSLTC(true); xsltc.init(); int c; diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/cmdline/ObjectFactory.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/cmdline/ObjectFactory.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,663 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2001-2004 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. - */ -/* - * $Id: ObjectFactory.java,v 1.2.4.1 2005/09/12 09:12:02 pvedula Exp $ - */ - -package com.sun.org.apache.xalan.internal.xsltc.cmdline; - -import java.io.InputStream; -import java.io.IOException; -import java.io.File; -import java.io.FileInputStream; - -import java.util.Properties; -import java.io.BufferedReader; -import java.io.InputStreamReader; - -/** - * 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. - *

- * This code is designed to implement the JAXP 1.1 spec pluggability - * feature and is designed to run on JDK version 1.1 and - * later, and to compile on JDK 1.2 and onward. - * The code also runs both as part of an unbundled jar file and - * when bundled as part of the JDK. - *

- * This class was moved from the javax.xml.parsers.ObjectFactory - * class and modified to be used as a general utility for creating objects - * dynamically. - * - * @version $Id: ObjectFactory.java,v 1.9 2008/04/02 00:41:02 joehw Exp $ - */ -class ObjectFactory { - - // - // Constants - // - - // name of default properties file to look for in JDK's jre/lib directory - private static final String DEFAULT_PROPERTIES_FILENAME = - "xalan.properties"; - - private static final String SERVICES_PATH = "META-INF/services/"; - - /** Set to true for debugging */ - private static final boolean DEBUG = false; - - /** cache the contents of the xalan.properties file. - * Until an attempt has been made to read this file, this will - * be null; if the file does not exist or we encounter some other error - * during the read, this will be empty. - */ - private static Properties fXalanProperties = null; - - /*** - * Cache the time stamp of the xalan.properties file so - * that we know if it's been modified and can invalidate - * the cache when necessary. - */ - private static long fLastModified = -1; - - // - // Public static methods - // - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *

    - *
  1. query the system property using System.getProperty - *
  2. read META-INF/services/factoryId file - *
  3. use fallback classname - *
- * - * @return instance of factory, 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 no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Object createObject(String factoryId, String fallbackClassName) - throws ConfigurationError { - return createObject(factoryId, null, fallbackClassName); - } // createObject(String,String):Object - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return instance of factory, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Object createObject(String factoryId, - String propertiesFilename, - String fallbackClassName) - throws ConfigurationError - { - Class factoryClass = lookUpFactoryClass(factoryId, - propertiesFilename, - fallbackClassName); - - if (factoryClass == null) { - throw new ConfigurationError( - "Provider for " + factoryId + " cannot be found", null); - } - - try{ - Object instance = factoryClass.newInstance(); - if (DEBUG) debugPrintln("created new instance of factory " + factoryId); - return instance; - } catch (Exception x) { - throw new ConfigurationError( - "Provider for factory " + factoryId - + " could not be instantiated: " + x, x); - } - } // createObject(String,String,String):Object - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return Class object of factory, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Class lookUpFactoryClass(String factoryId) - throws ConfigurationError - { - return lookUpFactoryClass(factoryId, null, null); - } // lookUpFactoryClass(String):Class - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return Class object that provides factory service, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Class lookUpFactoryClass(String factoryId, - String propertiesFilename, - String fallbackClassName) - throws ConfigurationError - { - String factoryClassName = lookUpFactoryClassName(factoryId, - propertiesFilename, - fallbackClassName); - ClassLoader cl = findClassLoader(); - - if (factoryClassName == null) { - factoryClassName = fallbackClassName; - } - - // assert(className != null); - try{ - Class providerClass = findProviderClass(factoryClassName, - cl, - true); - if (DEBUG) debugPrintln("created new instance of " + providerClass + - " using ClassLoader: " + cl); - return providerClass; - } catch (ClassNotFoundException x) { - throw new ConfigurationError( - "Provider " + factoryClassName + " not found", x); - } catch (Exception x) { - throw new ConfigurationError( - "Provider "+factoryClassName+" could not be instantiated: "+x, - x); - } - } // lookUpFactoryClass(String,String,String):Class - - /** - * Finds the name of the required implementation class in the specified - * order. The specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return name of class that provides factory service, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static String lookUpFactoryClassName(String factoryId, - String propertiesFilename, - String fallbackClassName) - { - SecuritySupport ss = SecuritySupport.getInstance(); - - // Use the system property first - try { - String systemProp = ss.getSystemProperty(factoryId); - if (systemProp != null) { - if (DEBUG) debugPrintln("found system property, value=" + systemProp); - return systemProp; - } - } catch (SecurityException se) { - // Ignore and continue w/ next location - } - - // Try to read from propertiesFilename, or - // $java.home/lib/xalan.properties - String factoryClassName = null; - // no properties file name specified; use - // $JAVA_HOME/lib/xalan.properties: - if (propertiesFilename == null) { - File propertiesFile = null; - boolean propertiesFileExists = false; - try { - String javah = ss.getSystemProperty("java.home"); - propertiesFilename = javah + File.separator + - "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME; - propertiesFile = new File(propertiesFilename); - propertiesFileExists = ss.getFileExists(propertiesFile); - } catch (SecurityException e) { - // try again... - fLastModified = -1; - fXalanProperties = null; - } - - synchronized (ObjectFactory.class) { - boolean loadProperties = false; - FileInputStream fis = null; - try { - // file existed last time - if(fLastModified >= 0) { - if(propertiesFileExists && - (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) { - loadProperties = true; - } else { - // file has stopped existing... - if(!propertiesFileExists) { - fLastModified = -1; - fXalanProperties = null; - } // else, file wasn't modified! - } - } else { - // file has started to exist: - if(propertiesFileExists) { - loadProperties = true; - fLastModified = ss.getLastModified(propertiesFile); - } // else, nothing's changed - } - if(loadProperties) { - // must never have attempted to read xalan.properties - // before (or it's outdeated) - fXalanProperties = new Properties(); - fis = ss.getFileInputStream(propertiesFile); - fXalanProperties.load(fis); - } - } catch (Exception x) { - fXalanProperties = null; - fLastModified = -1; - // assert(x instanceof FileNotFoundException - // || x instanceof SecurityException) - // In both cases, ignore and continue w/ next location - } - finally { - // try to close the input stream if one was opened. - if (fis != null) { - try { - fis.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - } - } - if(fXalanProperties != null) { - factoryClassName = fXalanProperties.getProperty(factoryId); - } - } else { - FileInputStream fis = null; - try { - fis = ss.getFileInputStream(new File(propertiesFilename)); - Properties props = new Properties(); - props.load(fis); - factoryClassName = props.getProperty(factoryId); - } catch (Exception x) { - // assert(x instanceof FileNotFoundException - // || x instanceof SecurityException) - // In both cases, ignore and continue w/ next location - } - finally { - // try to close the input stream if one was opened. - if (fis != null) { - try { - fis.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - } - } - if (factoryClassName != null) { - if (DEBUG) debugPrintln("found in " + propertiesFilename + ", value=" - + factoryClassName); - return factoryClassName; - } - - // Try Jar Service Provider Mechanism - return findJarServiceProviderName(factoryId); - } // lookUpFactoryClass(String,String):String - - // - // Private static methods - // - - /** Prints a message to standard error if debugging is enabled. */ - private static void debugPrintln(String msg) { - if (DEBUG) { - System.err.println("JAXP: " + msg); - } - } // debugPrintln(String) - - /** - * Figure out which ClassLoader to use. For JDK 1.2 and later use - * the context ClassLoader. - */ - static ClassLoader findClassLoader() - 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 context = ss.getContextClassLoader(); - ClassLoader system = ss.getSystemClassLoader(); - - ClassLoader chain = system; - while (true) { - if (context == chain) { - // Assert: we are on JDK 1.1 or we have no Context ClassLoader - // or any Context ClassLoader in chain of system classloader - // (including extension ClassLoader) so extend to widest - // ClassLoader (always look in system ClassLoader if Xalan - // is in boot/extension/system classpath and in current - // ClassLoader otherwise); normal classloaders delegate - // back to system ClassLoader first so this widening doesn't - // change the fact that context ClassLoader will be consulted - ClassLoader current = ObjectFactory.class.getClassLoader(); - - chain = system; - while (true) { - if (current == chain) { - // Assert: Current ClassLoader in chain of - // boot/extension/system ClassLoaders - return system; - } - if (chain == null) { - break; - } - chain = ss.getParentClassLoader(chain); - } - - // Assert: Current ClassLoader not in chain of - // boot/extension/system ClassLoaders - return current; - } - - if (chain == null) { - // boot ClassLoader reached - break; - } - - // Check for any extension ClassLoaders in chain up to - // boot ClassLoader - chain = ss.getParentClassLoader(chain); - }; - - // Assert: Context ClassLoader not in chain of - // boot/extension/system ClassLoaders - return context; - } // findClassLoader():ClassLoader - - /** - * Create an instance of a class using the specified ClassLoader - */ - static Object newInstance(String className, ClassLoader cl, - boolean doFallback) - throws ConfigurationError - { - // assert(className != null); - try{ - Class providerClass = findProviderClass(className, cl, doFallback); - Object instance = providerClass.newInstance(); - if (DEBUG) debugPrintln("created new instance of " + providerClass + - " using ClassLoader: " + cl); - return instance; - } catch (ClassNotFoundException x) { - throw new ConfigurationError( - "Provider " + className + " not found", x); - } catch (Exception x) { - throw new ConfigurationError( - "Provider " + className + " could not be instantiated: " + x, - x); - } - } - - /** - * Find a Class using the specified ClassLoader - */ - static Class findProviderClass(String className, ClassLoader cl, - boolean doFallback) - throws ClassNotFoundException, ConfigurationError - { - //throw security exception if the calling thread is not allowed to access the - //class. Restrict the access to the package classes as specified in java.security policy. - SecurityManager security = System.getSecurityManager(); - try{ - if (security != null){ - final int lastDot = className.lastIndexOf("."); - String packageName = className; - if (lastDot != -1) packageName = className.substring(0, lastDot); - security.checkPackageAccess(packageName); - } - }catch(SecurityException e){ - throw e; - } - - Class providerClass; - 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 { - try { - providerClass = cl.loadClass(className); - } catch (ClassNotFoundException x) { - if (doFallback) { - // Fall back to current classloader - ClassLoader current = ObjectFactory.class.getClassLoader(); - if (current == null) { - providerClass = Class.forName(className); - } else if (cl != current) { - cl = current; - providerClass = cl.loadClass(className); - } else { - throw x; - } - } else { - throw x; - } - } - } - - return providerClass; - } - - /** - * Find the name of service provider using Jar Service Provider Mechanism - * - * @return instance of provider class if found or null - */ - private static String findJarServiceProviderName(String factoryId) - { - SecuritySupport ss = SecuritySupport.getInstance(); - String serviceId = SERVICES_PATH + factoryId; - InputStream is = null; - - // First try the Context ClassLoader - ClassLoader cl = findClassLoader(); - - is = ss.getResourceAsStream(cl, serviceId); - - // If no provider found then try the current ClassLoader - if (is == null) { - ClassLoader current = ObjectFactory.class.getClassLoader(); - if (cl != current) { - cl = current; - is = ss.getResourceAsStream(cl, serviceId); - } - } - - if (is == null) { - // No provider found - return null; - } - - if (DEBUG) debugPrintln("found jar resource=" + serviceId + - " using ClassLoader: " + cl); - - // 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)); - } - - String factoryClassName = null; - try { - // XXX Does not handle all possible input as specified by the - // Jar Service Provider specification - factoryClassName = rd.readLine(); - } catch (IOException x) { - // No provider found - return null; - } - finally { - try { - // try to close the reader. - rd.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - - if (factoryClassName != null && - ! "".equals(factoryClassName)) { - if (DEBUG) debugPrintln("found in resource, value=" - + factoryClassName); - - // Note: here we do not want to fall back to the current - // 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. - return factoryClassName; - } - - // No provider found - return null; - } - - // - // Classes - // - - /** - * A configuration error. - */ - static class ConfigurationError - extends Error { - static final long serialVersionUID = -6072257854297546607L; - // - // Data - // - - /** Exception. */ - private Exception exception; - - // - // Constructors - // - - /** - * Construct a new instance with the specified detail string and - * exception. - */ - ConfigurationError(String msg, Exception x) { - super(msg); - this.exception = x; - } // (String,Exception) - - // - // Public methods - // - - /** Returns the exception associated to this error. */ - Exception getException() { - return exception; - } // getException():Exception - - } // class ConfigurationError - -} // class ObjectFactory diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/cmdline/SecuritySupport.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/cmdline/SecuritySupport.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,127 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2002-2004 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. - */ -/* - * $Id: SecuritySupport.java,v 1.2.4.1 2005/08/31 11:30:44 pvedula Exp $ - */ - -package com.sun.org.apache.xalan.internal.xsltc.cmdline; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.InputStream; - -import java.util.Properties; - -/** - * This class is duplicated for each Xalan-Java subpackage so keep it in sync. - * It is package private and therefore is not exposed as part of the Xalan-Java - * 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. - */ - static SecuritySupport getInstance() { - return (SecuritySupport)securitySupport; - } - - ClassLoader getContextClassLoader() { - return null; - } - - ClassLoader getSystemClassLoader() { - return null; - } - - ClassLoader getParentClassLoader(ClassLoader cl) { - return null; - } - - String getSystemProperty(String propName) { - return System.getProperty(propName); - } - - FileInputStream getFileInputStream(File file) - throws FileNotFoundException - { - return new FileInputStream(file); - } - - InputStream getResourceAsStream(ClassLoader cl, String name) { - InputStream ris; - if (cl == null) { - ris = ClassLoader.getSystemResourceAsStream(name); - } else { - ris = cl.getResourceAsStream(name); - } - return ris; - } - - boolean getFileExists(File f) { - return f.exists(); - } - - long getLastModified(File f) { - return f.lastModified(); - } -} diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/cmdline/SecuritySupport12.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/cmdline/SecuritySupport12.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,148 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2002-2004 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. - */ -/* - * $Id: SecuritySupport12.java,v 1.2.4.1 2005/08/31 11:33:55 pvedula Exp $ - */ - -package com.sun.org.apache.xalan.internal.xsltc.cmdline; - -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; - -import java.util.Properties; - -/** - * This class is duplicated for each Xalan-Java subpackage so keep it in sync. - * It is package private and therefore is not exposed as part of the Xalan-Java - * API. - * - * Security related methods that only work on J2SE 1.2 and newer. - */ -class SecuritySupport12 extends SecuritySupport { - - ClassLoader getContextClassLoader() { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader cl = null; - try { - cl = Thread.currentThread().getContextClassLoader(); - } catch (SecurityException ex) { } - return cl; - } - }); - } - - ClassLoader getSystemClassLoader() { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader cl = null; - try { - cl = ClassLoader.getSystemClassLoader(); - } catch (SecurityException ex) {} - return cl; - } - }); - } - - ClassLoader getParentClassLoader(final ClassLoader cl) { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader parent = null; - try { - parent = cl.getParent(); - } catch (SecurityException ex) {} - - // eliminate loops in case of the boot - // ClassLoader returning itself as a parent - return (parent == cl) ? null : parent; - } - }); - } - - String getSystemProperty(final String propName) { - return (String) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return System.getProperty(propName); - } - }); - } - - 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(); - } - } - - 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; - } - }); - } - - boolean getFileExists(final File f) { - return ((Boolean) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return new Boolean(f.exists()); - } - })).booleanValue(); - } - - long getLastModified(final File f) { - return ((Long) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return new Long(f.lastModified()); - } - })).longValue(); - } - -} diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/cmdline/Transform.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/cmdline/Transform.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/cmdline/Transform.java Tue Apr 17 11:17:59 2012 -0700 @@ -49,6 +49,7 @@ import com.sun.org.apache.xalan.internal.xsltc.StripFilter; import com.sun.org.apache.xml.internal.dtm.DTMWSFilter; import com.sun.org.apache.xalan.internal.xsltc.dom.DOMWSFilter; +import com.sun.org.apache.xalan.internal.utils.ObjectFactory; /** * @author Jacek Ambroziak @@ -97,8 +98,7 @@ private void doTransform() { try { - final Class clazz = ObjectFactory.findProviderClass( - _className, ObjectFactory.findClassLoader(), true); + final Class clazz = ObjectFactory.findProviderClass(_className, true); final AbstractTranslet translet = (AbstractTranslet)clazz.newInstance(); translet.postInitialization(); diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/AbsoluteLocationPath.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/AbsoluteLocationPath.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/AbsoluteLocationPath.java Tue Apr 17 11:17:59 2012 -0700 @@ -106,13 +106,15 @@ LocalVariableGen relPathIterator = methodGen.addLocalVariable("abs_location_path_tmp", Util.getJCRefType(NODE_ITERATOR_SIG), - il.getEnd(), null); - il.append(new ASTORE(relPathIterator.getIndex())); + null, null); + relPathIterator.setStart( + il.append(new ASTORE(relPathIterator.getIndex()))); // Create new AbsoluteIterator il.append(new NEW(cpg.addClass(ABSOLUTE_ITERATOR))); il.append(DUP); - il.append(new ALOAD(relPathIterator.getIndex())); + relPathIterator.setEnd( + il.append(new ALOAD(relPathIterator.getIndex()))); // Initialize AbsoluteIterator with iterator from the stack il.append(new INVOKESPECIAL(initAI)); diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/AbsolutePathPattern.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/AbsolutePathPattern.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/AbsolutePathPattern.java Tue Apr 17 11:17:59 2012 -0700 @@ -87,9 +87,9 @@ // absolute path pattern temporary methodGen.addLocalVariable2("apptmp", Util.getJCRefType(NODE_SIG), - il.getEnd()); + null); il.append(DUP); - il.append(new ISTORE(local.getIndex())); + local.setStart(il.append(new ISTORE(local.getIndex()))); _left.translate(classGen, methodGen); il.append(methodGen.loadDOM()); local.setEnd(il.append(new ILOAD(local.getIndex()))); diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/AttributeSet.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/AttributeSet.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/AttributeSet.java Tue Apr 17 11:17:59 2012 -0700 @@ -192,11 +192,7 @@ final InstructionList il = methodGen.getInstructionList(); il.append(RETURN); - methodGen.stripAttributes(true); - methodGen.setMaxLocals(); - methodGen.setMaxStack(); - methodGen.removeNOPs(); - classGen.addMethod(methodGen.getMethod()); + classGen.addMethod(methodGen); } public String toString() { diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/Copy.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Copy.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Copy.java Tue Apr 17 11:17:59 2012 -0700 @@ -84,11 +84,11 @@ final LocalVariableGen name = methodGen.addLocalVariable2("name", Util.getJCRefType(STRING_SIG), - il.getEnd()); + null); final LocalVariableGen length = methodGen.addLocalVariable2("length", Util.getJCRefType("I"), - il.getEnd()); + null); // Get the name of the node to copy and save for later il.append(methodGen.loadDOM()); @@ -102,7 +102,7 @@ + ")" + STRING_SIG); il.append(new INVOKEINTERFACE(cpy, 3)); il.append(DUP); - il.append(new ASTORE(name.getIndex())); + name.setStart(il.append(new ASTORE(name.getIndex()))); final BranchHandle ifBlock1 = il.append(new IFNULL(null)); // Get the length of the node name and save for later @@ -110,7 +110,7 @@ final int lengthMethod = cpg.addMethodref(STRING_CLASS,"length","()I"); il.append(new INVOKEVIRTUAL(lengthMethod)); il.append(DUP); - il.append(new ISTORE(length.getIndex())); + length.setStart(il.append(new ISTORE(length.getIndex()))); // Ignore attribute sets if current node is ROOT. DOM.shallowCopy() // returns "" for ROOT, so skip attribute sets if length == 0 @@ -144,10 +144,10 @@ // Call the output handler's endElement() if we copied an element // (The DOM.shallowCopy() method calls startElement().) - il.append(new ILOAD(length.getIndex())); + length.setEnd(il.append(new ILOAD(length.getIndex()))); final BranchHandle ifBlock3 = il.append(new IFEQ(null)); il.append(methodGen.loadHandler()); - il.append(new ALOAD(name.getIndex())); + name.setEnd(il.append(new ALOAD(name.getIndex()))); il.append(methodGen.endElement()); final InstructionHandle end = il.append(NOP); diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/FilterExpr.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/FilterExpr.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/FilterExpr.java Tue Apr 17 11:17:59 2012 -0700 @@ -28,11 +28,12 @@ import com.sun.org.apache.bcel.internal.generic.ALOAD; import com.sun.org.apache.bcel.internal.generic.ASTORE; import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen; -import com.sun.org.apache.bcel.internal.generic.NEW; +import com.sun.org.apache.bcel.internal.generic.ILOAD; import com.sun.org.apache.bcel.internal.generic.INVOKEINTERFACE; import com.sun.org.apache.bcel.internal.generic.INVOKESPECIAL; import com.sun.org.apache.bcel.internal.generic.INVOKESTATIC; import com.sun.org.apache.bcel.internal.generic.InstructionList; +import com.sun.org.apache.bcel.internal.generic.ISTORE; import com.sun.org.apache.bcel.internal.generic.LocalVariableGen; import com.sun.org.apache.bcel.internal.generic.NEW; import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator; @@ -99,6 +100,7 @@ */ public Type typeCheck(SymbolTable stable) throws TypeCheckError { Type ptype = _primary.typeCheck(stable); + boolean canOptimize = _primary instanceof KeyCall; if (ptype instanceof NodeSetType == false) { if (ptype instanceof ReferenceType) { @@ -109,11 +111,14 @@ } } - // Type check predicates and turn all optimizations off + // Type check predicates and turn all optimizations off if appropriate int n = _predicates.size(); for (int i = 0; i < n; i++) { Predicate pred = (Predicate) _predicates.elementAt(i); - pred.dontOptimize(); + + if (!canOptimize) { + pred.dontOptimize(); + } pred.typeCheck(stable); } return _type = Type.NodeSet; @@ -155,52 +160,95 @@ translateFilterExpr(classGen, methodGen, predicateIndex); } else { - // Translate predicates from right to left - final int initCNLI = cpg.addMethodref(CURRENT_NODE_LIST_ITERATOR, - "", - "("+NODE_ITERATOR_SIG+"Z"+ - CURRENT_NODE_LIST_FILTER_SIG + - NODE_SIG+TRANSLET_SIG+")V"); - - // Backwards branches are prohibited if an uninitialized object is - // on the stack by section 4.9.4 of the JVM Specification, 2nd Ed. - // We don't know whether this code might contain backwards branches, - // so we mustn't create the new object until after we've created - // the suspect arguments to its constructor. Instead we calculate - // the values of the arguments to the constructor first, store them - // in temporary variables, create the object and reload the - // arguments from the temporaries to avoid the problem. - // Get the next predicate to be translated Predicate predicate = (Predicate) _predicates.get(predicateIndex--); // Translate the rest of the predicates from right to left translatePredicates(classGen, methodGen, predicateIndex); - LocalVariableGen nodeIteratorTemp = - methodGen.addLocalVariable("filter_expr_tmp1", - Util.getJCRefType(NODE_ITERATOR_SIG), - il.getEnd(), null); - il.append(new ASTORE(nodeIteratorTemp.getIndex())); + if (predicate.isNthPositionFilter()) { + int nthIteratorIdx = cpg.addMethodref(NTH_ITERATOR_CLASS, + "", + "("+NODE_ITERATOR_SIG+"I)V"); + + // Backwards branches are prohibited if an uninitialized object + // is on the stack by section 4.9.4 of the JVM Specification, + // 2nd Ed. We don't know whether this code might contain + // backwards branches, so we mustn't create the new object unti + + // after we've created the suspect arguments to its constructor + + // Instead we calculate the values of the arguments to the + // constructor first, store them in temporary variables, create + // the object and reload the arguments from the temporaries to + // avoid the problem. + LocalVariableGen iteratorTemp + = methodGen.addLocalVariable("filter_expr_tmp1", + Util.getJCRefType(NODE_ITERATOR_SIG), + null, null); + iteratorTemp.setStart( + il.append(new ASTORE(iteratorTemp.getIndex()))); + + predicate.translate(classGen, methodGen); + LocalVariableGen predicateValueTemp + = methodGen.addLocalVariable("filter_expr_tmp2", + Util.getJCRefType("I"), + null, null); + predicateValueTemp.setStart( + il.append(new ISTORE(predicateValueTemp.getIndex()))); - predicate.translate(classGen, methodGen); - LocalVariableGen filterTemp = - methodGen.addLocalVariable("filter_expr_tmp2", - Util.getJCRefType(CURRENT_NODE_LIST_FILTER_SIG), - il.getEnd(), null); - il.append(new ASTORE(filterTemp.getIndex())); + il.append(new NEW(cpg.addClass(NTH_ITERATOR_CLASS))); + il.append(DUP); + iteratorTemp.setEnd( + il.append(new ALOAD(iteratorTemp.getIndex()))); + predicateValueTemp.setEnd( + il.append(new ILOAD(predicateValueTemp.getIndex()))); + il.append(new INVOKESPECIAL(nthIteratorIdx)); + } else { + // Translate predicates from right to left + final int initCNLI = cpg.addMethodref(CURRENT_NODE_LIST_ITERATOR, + "", + "("+NODE_ITERATOR_SIG+"Z"+ + CURRENT_NODE_LIST_FILTER_SIG + + NODE_SIG+TRANSLET_SIG+")V"); + + // Backwards branches are prohibited if an uninitialized object is + // on the stack by section 4.9.4 of the JVM Specification, 2nd Ed. + // We don't know whether this code might contain backwards branches, + // so we mustn't create the new object until after we've created + // the suspect arguments to its constructor. Instead we calculate + // the values of the arguments to the constructor first, store them + // in temporary variables, create the object and reload the + // arguments from the temporaries to avoid the problem. + - // Create a CurrentNodeListIterator - il.append(new NEW(cpg.addClass(CURRENT_NODE_LIST_ITERATOR))); - il.append(DUP); + LocalVariableGen nodeIteratorTemp = + methodGen.addLocalVariable("filter_expr_tmp1", + Util.getJCRefType(NODE_ITERATOR_SIG), + null, null); + nodeIteratorTemp.setStart( + il.append(new ASTORE(nodeIteratorTemp.getIndex()))); + + predicate.translate(classGen, methodGen); + LocalVariableGen filterTemp = + methodGen.addLocalVariable("filter_expr_tmp2", + Util.getJCRefType(CURRENT_NODE_LIST_FILTER_SIG), + null, null); + filterTemp.setStart(il.append(new ASTORE(filterTemp.getIndex()))); - // Initialize CurrentNodeListIterator - il.append(new ALOAD(nodeIteratorTemp.getIndex())); - il.append(ICONST_1); - il.append(new ALOAD(filterTemp.getIndex())); - il.append(methodGen.loadCurrentNode()); - il.append(classGen.loadTranslet()); - il.append(new INVOKESPECIAL(initCNLI)); + // Create a CurrentNodeListIterator + il.append(new NEW(cpg.addClass(CURRENT_NODE_LIST_ITERATOR))); + il.append(DUP); + + // Initialize CurrentNodeListIterator + nodeIteratorTemp.setEnd( + il.append(new ALOAD(nodeIteratorTemp.getIndex()))); + il.append(ICONST_1); + filterTemp.setEnd(il.append(new ALOAD(filterTemp.getIndex()))); + il.append(methodGen.loadCurrentNode()); + il.append(classGen.loadTranslet()); + il.append(new INVOKESPECIAL(initCNLI)); + } } } } diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/FilterParentPath.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/FilterParentPath.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/FilterParentPath.java Tue Apr 17 11:17:59 2012 -0700 @@ -128,20 +128,20 @@ LocalVariableGen filterTemp = methodGen.addLocalVariable("filter_parent_path_tmp1", Util.getJCRefType(NODE_ITERATOR_SIG), - il.getEnd(), null); - il.append(new ASTORE(filterTemp.getIndex())); + null, null); + filterTemp.setStart(il.append(new ASTORE(filterTemp.getIndex()))); _path.translate(classGen, methodGen); LocalVariableGen pathTemp = methodGen.addLocalVariable("filter_parent_path_tmp2", Util.getJCRefType(NODE_ITERATOR_SIG), - il.getEnd(), null); - il.append(new ASTORE(pathTemp.getIndex())); + null, null); + pathTemp.setStart(il.append(new ASTORE(pathTemp.getIndex()))); il.append(new NEW(cpg.addClass(STEP_ITERATOR_CLASS))); il.append(DUP); - il.append(new ALOAD(filterTemp.getIndex())); - il.append(new ALOAD(pathTemp.getIndex())); + filterTemp.setEnd(il.append(new ALOAD(filterTemp.getIndex()))); + pathTemp.setEnd(il.append(new ALOAD(pathTemp.getIndex()))); // Initialize StepIterator with iterators from the stack il.append(new INVOKESPECIAL(initSI)); @@ -154,8 +154,16 @@ il.append(new INVOKEVIRTUAL(incl)); } - if (!(getParent() instanceof RelativeLocationPath) && - !(getParent() instanceof FilterParentPath)) { + SyntaxTreeNode parent = getParent(); + + boolean parentAlreadyOrdered = + (parent instanceof RelativeLocationPath) + || (parent instanceof FilterParentPath) + || (parent instanceof KeyCall) + || (parent instanceof CurrentCall) + || (parent instanceof DocumentCall); + + if (!parentAlreadyOrdered) { final int order = cpg.addInterfaceMethodref(DOM_INTF, ORDER_ITERATOR, ORDER_ITERATOR_SIG); diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/FilteredAbsoluteLocationPath.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/FilteredAbsoluteLocationPath.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/FilteredAbsoluteLocationPath.java Tue Apr 17 11:17:59 2012 -0700 @@ -104,14 +104,14 @@ LocalVariableGen pathTemp = methodGen.addLocalVariable("filtered_absolute_location_path_tmp", Util.getJCRefType(NODE_ITERATOR_SIG), - il.getEnd(), null); + null, null); _path.translate(classGen, methodGen); - il.append(new ASTORE(pathTemp.getIndex())); + pathTemp.setStart(il.append(new ASTORE(pathTemp.getIndex()))); // Create new Dup Filter Iterator il.append(new NEW(cpg.addClass(DUP_FILTERED_ITERATOR))); il.append(DUP); - il.append(new ALOAD(pathTemp.getIndex())); + pathTemp.setEnd(il.append(new ALOAD(pathTemp.getIndex()))); // Initialize Dup Filter Iterator with iterator from the stack il.append(new INVOKESPECIAL(initDFI)); diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionAvailableCall.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionAvailableCall.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionAvailableCall.java Tue Apr 17 11:17:59 2012 -0700 @@ -35,6 +35,7 @@ import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type; import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError; import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util; +import com.sun.org.apache.xalan.internal.utils.ObjectFactory; /** * @author G. Todd Miller @@ -132,8 +133,7 @@ methodName = replaceDash(methodName); try { - final Class clazz = ObjectFactory.findProviderClass( - className, ObjectFactory.findClassLoader(), true); + final Class clazz = ObjectFactory.findProviderClass(className, true); if (clazz == null) { return false; diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionCall.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionCall.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionCall.java Tue Apr 17 11:17:59 2012 -0700 @@ -53,6 +53,7 @@ import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ReferenceType; import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type; import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError; +import com.sun.org.apache.xalan.internal.utils.ObjectFactory; /** * @author Jacek Ambroziak @@ -355,8 +356,7 @@ else { if (_className != null && _className.length() > 0) { try { - _clazz = ObjectFactory.findProviderClass( - _className, ObjectFactory.findClassLoader(), true); + _clazz = ObjectFactory.findProviderClass(_className, true); _namespace_format = NAMESPACE_FORMAT_CLASS; } catch (ClassNotFoundException e) { @@ -775,8 +775,10 @@ paramTemp[i] = methodGen.addLocalVariable("function_call_tmp"+i, expType.toJCType(), - il.getEnd(), null); - il.append(expType.STORE(paramTemp[i].getIndex())); + null, null); + paramTemp[i].setStart( + il.append(expType.STORE(paramTemp[i].getIndex()))); + } il.append(new NEW(cpg.addClass(_className))); @@ -784,7 +786,8 @@ for (int i = 0; i < n; i++) { final Expression arg = argument(i); - il.append(arg.getType().LOAD(paramTemp[i].getIndex())); + paramTemp[i].setEnd( + il.append(arg.getType().LOAD(paramTemp[i].getIndex()))); } final StringBuffer buffer = new StringBuffer(); @@ -882,8 +885,7 @@ final int nArgs = _arguments.size(); try { if (_clazz == null) { - _clazz = ObjectFactory.findProviderClass( - _className, ObjectFactory.findClassLoader(), true); + _clazz = ObjectFactory.findProviderClass(_className, true); if (_clazz == null) { final ErrorMsg msg = @@ -929,8 +931,7 @@ final int nArgs = _arguments.size(); try { if (_clazz == null) { - _clazz = ObjectFactory.findProviderClass( - _className, ObjectFactory.findClassLoader(), true); + _clazz = ObjectFactory.findProviderClass(_className, true); if (_clazz == null) { final ErrorMsg msg = new ErrorMsg(ErrorMsg.CLASS_NOT_FOUND_ERR, _className); diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/Key.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Key.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Key.java Tue Apr 17 11:17:59 2012 -0700 @@ -166,10 +166,10 @@ final LocalVariableGen parentNode = methodGen.addLocalVariable("parentNode", Util.getJCRefType("I"), - il.getEnd(), null); + null, null); // Get the 'parameter' from the stack and store it in a local var. - il.append(new ISTORE(parentNode.getIndex())); + parentNode.setStart(il.append(new ISTORE(parentNode.getIndex()))); // Save current node and current iterator on the stack il.append(methodGen.loadCurrentNode()); @@ -186,9 +186,9 @@ // Prepare to call buildKeyIndex(String name, int node, String value); il.append(classGen.loadTranslet()); il.append(new PUSH(cpg, _name.toString())); - il.append(new ILOAD(parentNode.getIndex())); + parentNode.setEnd(il.append(new ILOAD(parentNode.getIndex()))); - // Now get the node value and feck it on the parameter stack + // Now get the node value and push it on the parameter stack il.append(methodGen.loadDOM()); il.append(methodGen.loadCurrentNode()); il.append(new INVOKEINTERFACE(getNodeValue, 2)); diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/Message.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Message.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Message.java Tue Apr 17 11:17:59 2012 -0700 @@ -24,6 +24,7 @@ package com.sun.org.apache.xalan.internal.xsltc.compiler; import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen; +import com.sun.org.apache.bcel.internal.generic.INVOKEINTERFACE; import com.sun.org.apache.bcel.internal.generic.INVOKESPECIAL; import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL; import com.sun.org.apache.bcel.internal.generic.InstructionList; @@ -97,36 +98,41 @@ // Invoke output.setWriter(STRING_WRITER) il.append(methodGen.loadHandler()); il.append(SWAP); - il.append(new INVOKEVIRTUAL( - cpg.addMethodref(OUTPUT_BASE, "setWriter", - "("+WRITER_SIG+")V"))); + il.append(new INVOKEINTERFACE( + cpg.addInterfaceMethodref(TRANSLET_OUTPUT_INTERFACE, + "setWriter", + "("+WRITER_SIG+")V"), 2)); // Invoke output.setEncoding("UTF-8") il.append(methodGen.loadHandler()); il.append(new PUSH(cpg, "UTF-8")); // other encodings? - il.append(new INVOKEVIRTUAL( - cpg.addMethodref(OUTPUT_BASE, "setEncoding", - "("+STRING_SIG+")V"))); + il.append(new INVOKEINTERFACE( + cpg.addInterfaceMethodref(TRANSLET_OUTPUT_INTERFACE, + "setEncoding", + "("+STRING_SIG+")V"), 2)); // Invoke output.setOmitXMLDeclaration(true) il.append(methodGen.loadHandler()); il.append(ICONST_1); - il.append(new INVOKEVIRTUAL( - cpg.addMethodref(OUTPUT_BASE, "setOmitXMLDeclaration", - "(Z)V"))); + il.append(new INVOKEINTERFACE( + cpg.addInterfaceMethodref(TRANSLET_OUTPUT_INTERFACE, + "setOmitXMLDeclaration", + "(Z)V"), 2)); il.append(methodGen.loadHandler()); - il.append(new INVOKEVIRTUAL( - cpg.addMethodref(OUTPUT_BASE, "startDocument", - "()V"))); + il.append(new INVOKEINTERFACE( + cpg.addInterfaceMethodref(TRANSLET_OUTPUT_INTERFACE, + "startDocument", + "()V"), 1)); // Inline translation of contents translateContents(classGen, methodGen); il.append(methodGen.loadHandler()); - il.append(new INVOKEVIRTUAL( - cpg.addMethodref(OUTPUT_BASE, "endDocument", - "()V"))); + il.append(new INVOKEINTERFACE( + cpg.addInterfaceMethodref(TRANSLET_OUTPUT_INTERFACE, + "endDocument", + "()V"), 1)); // Call toString() on StringWriter il.append(new INVOKEVIRTUAL( diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/Mode.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Mode.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Mode.java Tue Apr 17 11:17:59 2012 -0700 @@ -553,11 +553,7 @@ il.append(template.compile(classGen, methodGen)); il.append(RETURN); - methodGen.stripAttributes(true); - methodGen.setMaxLocals(); - methodGen.setMaxStack(); - methodGen.removeNOPs(); - classGen.addMethod(methodGen.getMethod()); + classGen.addMethod(methodGen); } private void compileTemplates(ClassGenerator classGen, @@ -765,12 +761,16 @@ getClassName(), mainIL, classGen.getConstantPool()); methodGen.addException("com.sun.org.apache.xalan.internal.xsltc.TransletException"); + // Insert an extra NOP just to keep "current" from appearing as if it + // has a value before the start of the loop. + mainIL.append(NOP); + // Create a local variable to hold the current node final LocalVariableGen current; current = methodGen.addLocalVariable2("current", com.sun.org.apache.bcel.internal.generic.Type.INT, - mainIL.getEnd()); + null); _currentIndex = current.getIndex(); // Create the "body" instruction list that will eventually hold the @@ -793,6 +793,11 @@ ifeq.setTarget(ilLoop.append(RETURN)); // applyTemplates() ends here! final InstructionHandle ihLoop = ilLoop.getStart(); + current.setStart(mainIL.append(new GOTO_W(ihLoop))); + + // Live range of "current" ends at end of loop + current.setEnd(loop); + // Compile default handling of elements (traverse children) InstructionList ilRecurse = compileDefaultRecursion(classGen, methodGen, ihLoop); @@ -1029,18 +1034,12 @@ body.append(ilText); // putting together constituent instruction lists - mainIL.append(new GOTO_W(ihLoop)); mainIL.append(body); // fall through to ilLoop mainIL.append(ilLoop); peepHoleOptimization(methodGen); - methodGen.stripAttributes(true); - - methodGen.setMaxLocals(); - methodGen.setMaxStack(); - methodGen.removeNOPs(); - classGen.addMethod(methodGen.getMethod()); + classGen.addMethod(methodGen); // Compile method(s) for for this mode if (_importLevels != null) { @@ -1131,11 +1130,11 @@ final LocalVariableGen current; current = methodGen.addLocalVariable2("current", com.sun.org.apache.bcel.internal.generic.Type.INT, - mainIL.getEnd()); + null); _currentIndex = current.getIndex(); - mainIL.append(new ILOAD(methodGen.getLocalIndex(NODE_PNAME))); - mainIL.append(new ISTORE(_currentIndex)); + mainIL.append(new ILOAD(methodGen.getLocalIndex(NODE_PNAME))); + current.setStart(mainIL.append(new ISTORE(_currentIndex))); // Create the "body" instruction list that will eventually hold the // code for the entire method (other ILs will be appended). @@ -1145,7 +1144,7 @@ // Create an instruction list that contains the default next-node // iteration final InstructionList ilLoop = new InstructionList(); - ilLoop.append(RETURN); + ilLoop.append(RETURN); final InstructionHandle ihLoop = ilLoop.getStart(); // Compile default handling of elements (traverse children) @@ -1385,16 +1384,15 @@ // putting together constituent instruction lists mainIL.append(body); + + // Mark the end of the live range for the "current" variable + current.setEnd(body.getEnd()); + // fall through to ilLoop mainIL.append(ilLoop); peepHoleOptimization(methodGen); - methodGen.stripAttributes(true); - - methodGen.setMaxLocals(); - methodGen.setMaxStack(); - methodGen.removeNOPs(); - classGen.addMethod(methodGen.getMethod()); + classGen.addMethod(methodGen); // Restore original (complete) set of templates for this transformation _templates = oldTemplates; diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/Number.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Number.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Number.java Tue Apr 17 11:17:59 2012 -0700 @@ -323,10 +323,7 @@ il.append(new INVOKESPECIAL(index)); il.append(RETURN); - cons.stripAttributes(true); - cons.setMaxLocals(); - cons.setMaxStack(); - classGen.addMethod(cons.getMethod()); + classGen.addMethod(cons); } /** @@ -349,7 +346,7 @@ ITERATOR_FIELD_SIG); il.append(ALOAD_0); // 'this' pointer on stack il.append(new GETFIELD(field)); - il.append(new ASTORE(local.getIndex())); + local.setStart(il.append(new ASTORE(local.getIndex()))); matchGen.setIteratorIndex(local.getIndex()); // Get NodeCounter._translet and store locally @@ -361,7 +358,7 @@ il.append(ALOAD_0); // 'this' pointer on stack il.append(new GETFIELD(field)); il.append(new CHECKCAST(cpg.addClass(TRANSLET_CLASS))); - il.append(new ASTORE(local.getIndex())); + local.setStart(il.append(new ASTORE(local.getIndex()))); nodeCounterGen.setTransletIndex(local.getIndex()); // Get NodeCounter._document and store locally @@ -372,7 +369,7 @@ il.append(ALOAD_0); // 'this' pointer on stack il.append(new GETFIELD(field)); // Make sure we have the correct DOM type on the stack!!! - il.append(new ASTORE(local.getIndex())); + local.setStart(il.append(new ASTORE(local.getIndex()))); matchGen.setDomIndex(local.getIndex()); } @@ -436,11 +433,7 @@ _from.synthesize(nodeCounterGen, matchGen); il.append(IRETURN); - matchGen.stripAttributes(true); - matchGen.setMaxLocals(); - matchGen.setMaxStack(); - matchGen.removeNOPs(); - nodeCounterGen.addMethod(matchGen.getMethod()); + nodeCounterGen.addMethod(matchGen); } /* @@ -467,11 +460,7 @@ il.append(IRETURN); - matchGen.stripAttributes(true); - matchGen.setMaxLocals(); - matchGen.setMaxStack(); - matchGen.removeNOPs(); - nodeCounterGen.addMethod(matchGen.getMethod()); + nodeCounterGen.addMethod(matchGen); } getXSLTC().dumpClass(nodeCounterGen.getJavaClass()); diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/ObjectFactory.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/ObjectFactory.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,663 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2001-2004 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. - */ -/* - * $Id: ObjectFactory.java,v 1.2.4.1 2005/09/12 10:51:22 pvedula Exp $ - */ - -package com.sun.org.apache.xalan.internal.xsltc.compiler; - -import java.io.InputStream; -import java.io.IOException; -import java.io.File; -import java.io.FileInputStream; - -import java.util.Properties; -import java.io.BufferedReader; -import java.io.InputStreamReader; - -/** - * 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. - *

- * This code is designed to implement the JAXP 1.1 spec pluggability - * feature and is designed to run on JDK version 1.1 and - * later, and to compile on JDK 1.2 and onward. - * The code also runs both as part of an unbundled jar file and - * when bundled as part of the JDK. - *

- * This class was moved from the javax.xml.parsers.ObjectFactory - * class and modified to be used as a general utility for creating objects - * dynamically. - * - * @version $Id: ObjectFactory.java,v 1.9 2008/04/02 00:41:01 joehw Exp $ - */ -class ObjectFactory { - - // - // Constants - // - - // name of default properties file to look for in JDK's jre/lib directory - private static final String DEFAULT_PROPERTIES_FILENAME = - "xalan.properties"; - - private static final String SERVICES_PATH = "META-INF/services/"; - - /** Set to true for debugging */ - private static final boolean DEBUG = false; - - /** cache the contents of the xalan.properties file. - * Until an attempt has been made to read this file, this will - * be null; if the file does not exist or we encounter some other error - * during the read, this will be empty. - */ - private static Properties fXalanProperties = null; - - /*** - * Cache the time stamp of the xalan.properties file so - * that we know if it's been modified and can invalidate - * the cache when necessary. - */ - private static long fLastModified = -1; - - // - // Public static methods - // - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *

    - *
  1. query the system property using System.getProperty - *
  2. read META-INF/services/factoryId file - *
  3. use fallback classname - *
- * - * @return instance of factory, 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 no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Object createObject(String factoryId, String fallbackClassName) - throws ConfigurationError { - return createObject(factoryId, null, fallbackClassName); - } // createObject(String,String):Object - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return instance of factory, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Object createObject(String factoryId, - String propertiesFilename, - String fallbackClassName) - throws ConfigurationError - { - Class factoryClass = lookUpFactoryClass(factoryId, - propertiesFilename, - fallbackClassName); - - if (factoryClass == null) { - throw new ConfigurationError( - "Provider for " + factoryId + " cannot be found", null); - } - - try{ - Object instance = factoryClass.newInstance(); - if (DEBUG) debugPrintln("created new instance of factory " + factoryId); - return instance; - } catch (Exception x) { - throw new ConfigurationError( - "Provider for factory " + factoryId - + " could not be instantiated: " + x, x); - } - } // createObject(String,String,String):Object - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return Class object of factory, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Class lookUpFactoryClass(String factoryId) - throws ConfigurationError - { - return lookUpFactoryClass(factoryId, null, null); - } // lookUpFactoryClass(String):Class - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return Class object that provides factory service, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Class lookUpFactoryClass(String factoryId, - String propertiesFilename, - String fallbackClassName) - throws ConfigurationError - { - String factoryClassName = lookUpFactoryClassName(factoryId, - propertiesFilename, - fallbackClassName); - ClassLoader cl = findClassLoader(); - - if (factoryClassName == null) { - factoryClassName = fallbackClassName; - } - - // assert(className != null); - try{ - Class providerClass = findProviderClass(factoryClassName, - cl, - true); - if (DEBUG) debugPrintln("created new instance of " + providerClass + - " using ClassLoader: " + cl); - return providerClass; - } catch (ClassNotFoundException x) { - throw new ConfigurationError( - "Provider " + factoryClassName + " not found", x); - } catch (Exception x) { - throw new ConfigurationError( - "Provider "+factoryClassName+" could not be instantiated: "+x, - x); - } - } // lookUpFactoryClass(String,String,String):Class - - /** - * Finds the name of the required implementation class in the specified - * order. The specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return name of class that provides factory service, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static String lookUpFactoryClassName(String factoryId, - String propertiesFilename, - String fallbackClassName) - { - SecuritySupport ss = SecuritySupport.getInstance(); - - // Use the system property first - try { - String systemProp = ss.getSystemProperty(factoryId); - if (systemProp != null) { - if (DEBUG) debugPrintln("found system property, value=" + systemProp); - return systemProp; - } - } catch (SecurityException se) { - // Ignore and continue w/ next location - } - - // Try to read from propertiesFilename, or - // $java.home/lib/xalan.properties - String factoryClassName = null; - // no properties file name specified; use - // $JAVA_HOME/lib/xalan.properties: - if (propertiesFilename == null) { - File propertiesFile = null; - boolean propertiesFileExists = false; - try { - String javah = ss.getSystemProperty("java.home"); - propertiesFilename = javah + File.separator + - "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME; - propertiesFile = new File(propertiesFilename); - propertiesFileExists = ss.getFileExists(propertiesFile); - } catch (SecurityException e) { - // try again... - fLastModified = -1; - fXalanProperties = null; - } - - synchronized (ObjectFactory.class) { - boolean loadProperties = false; - FileInputStream fis = null; - try { - // file existed last time - if(fLastModified >= 0) { - if(propertiesFileExists && - (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) { - loadProperties = true; - } else { - // file has stopped existing... - if(!propertiesFileExists) { - fLastModified = -1; - fXalanProperties = null; - } // else, file wasn't modified! - } - } else { - // file has started to exist: - if(propertiesFileExists) { - loadProperties = true; - fLastModified = ss.getLastModified(propertiesFile); - } // else, nothing's changed - } - if(loadProperties) { - // must never have attempted to read xalan.properties - // before (or it's outdeated) - fXalanProperties = new Properties(); - fis = ss.getFileInputStream(propertiesFile); - fXalanProperties.load(fis); - } - } catch (Exception x) { - fXalanProperties = null; - fLastModified = -1; - // assert(x instanceof FileNotFoundException - // || x instanceof SecurityException) - // In both cases, ignore and continue w/ next location - } - finally { - // try to close the input stream if one was opened. - if (fis != null) { - try { - fis.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - } - } - if(fXalanProperties != null) { - factoryClassName = fXalanProperties.getProperty(factoryId); - } - } else { - FileInputStream fis = null; - try { - fis = ss.getFileInputStream(new File(propertiesFilename)); - Properties props = new Properties(); - props.load(fis); - factoryClassName = props.getProperty(factoryId); - } catch (Exception x) { - // assert(x instanceof FileNotFoundException - // || x instanceof SecurityException) - // In both cases, ignore and continue w/ next location - } - finally { - // try to close the input stream if one was opened. - if (fis != null) { - try { - fis.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - } - } - if (factoryClassName != null) { - if (DEBUG) debugPrintln("found in " + propertiesFilename + ", value=" - + factoryClassName); - return factoryClassName; - } - - // Try Jar Service Provider Mechanism - return findJarServiceProviderName(factoryId); - } // lookUpFactoryClass(String,String):String - - // - // Private static methods - // - - /** Prints a message to standard error if debugging is enabled. */ - private static void debugPrintln(String msg) { - if (DEBUG) { - System.err.println("JAXP: " + msg); - } - } // debugPrintln(String) - - /** - * Figure out which ClassLoader to use. For JDK 1.2 and later use - * the context ClassLoader. - */ - static ClassLoader findClassLoader() - 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 context = ss.getContextClassLoader(); - ClassLoader system = ss.getSystemClassLoader(); - - ClassLoader chain = system; - while (true) { - if (context == chain) { - // Assert: we are on JDK 1.1 or we have no Context ClassLoader - // or any Context ClassLoader in chain of system classloader - // (including extension ClassLoader) so extend to widest - // ClassLoader (always look in system ClassLoader if Xalan - // is in boot/extension/system classpath and in current - // ClassLoader otherwise); normal classloaders delegate - // back to system ClassLoader first so this widening doesn't - // change the fact that context ClassLoader will be consulted - ClassLoader current = ObjectFactory.class.getClassLoader(); - - chain = system; - while (true) { - if (current == chain) { - // Assert: Current ClassLoader in chain of - // boot/extension/system ClassLoaders - return system; - } - if (chain == null) { - break; - } - chain = ss.getParentClassLoader(chain); - } - - // Assert: Current ClassLoader not in chain of - // boot/extension/system ClassLoaders - return current; - } - - if (chain == null) { - // boot ClassLoader reached - break; - } - - // Check for any extension ClassLoaders in chain up to - // boot ClassLoader - chain = ss.getParentClassLoader(chain); - }; - - // Assert: Context ClassLoader not in chain of - // boot/extension/system ClassLoaders - return context; - } // findClassLoader():ClassLoader - - /** - * Create an instance of a class using the specified ClassLoader - */ - static Object newInstance(String className, ClassLoader cl, - boolean doFallback) - throws ConfigurationError - { - // assert(className != null); - try{ - Class providerClass = findProviderClass(className, cl, doFallback); - Object instance = providerClass.newInstance(); - if (DEBUG) debugPrintln("created new instance of " + providerClass + - " using ClassLoader: " + cl); - return instance; - } catch (ClassNotFoundException x) { - throw new ConfigurationError( - "Provider " + className + " not found", x); - } catch (Exception x) { - throw new ConfigurationError( - "Provider " + className + " could not be instantiated: " + x, - x); - } - } - - /** - * Find a Class using the specified ClassLoader - */ - static Class findProviderClass(String className, ClassLoader cl, - boolean doFallback) - throws ClassNotFoundException, ConfigurationError - { - //throw security exception if the calling thread is not allowed to access the - //class. Restrict the access to the package classes as specified in java.security policy. - SecurityManager security = System.getSecurityManager(); - try{ - if (security != null){ - final int lastDot = className.lastIndexOf("."); - String packageName = className; - if (lastDot != -1) packageName = className.substring(0, lastDot); - security.checkPackageAccess(packageName); - } - }catch(SecurityException e){ - throw e; - } - - Class providerClass; - 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 { - try { - providerClass = cl.loadClass(className); - } catch (ClassNotFoundException x) { - if (doFallback) { - // Fall back to current classloader - ClassLoader current = ObjectFactory.class.getClassLoader(); - if (current == null) { - providerClass = Class.forName(className); - } else if (cl != current) { - cl = current; - providerClass = cl.loadClass(className); - } else { - throw x; - } - } else { - throw x; - } - } - } - - return providerClass; - } - - /** - * Find the name of service provider using Jar Service Provider Mechanism - * - * @return instance of provider class if found or null - */ - private static String findJarServiceProviderName(String factoryId) - { - SecuritySupport ss = SecuritySupport.getInstance(); - String serviceId = SERVICES_PATH + factoryId; - InputStream is = null; - - // First try the Context ClassLoader - ClassLoader cl = findClassLoader(); - - is = ss.getResourceAsStream(cl, serviceId); - - // If no provider found then try the current ClassLoader - if (is == null) { - ClassLoader current = ObjectFactory.class.getClassLoader(); - if (cl != current) { - cl = current; - is = ss.getResourceAsStream(cl, serviceId); - } - } - - if (is == null) { - // No provider found - return null; - } - - if (DEBUG) debugPrintln("found jar resource=" + serviceId + - " using ClassLoader: " + cl); - - // 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)); - } - - String factoryClassName = null; - try { - // XXX Does not handle all possible input as specified by the - // Jar Service Provider specification - factoryClassName = rd.readLine(); - } catch (IOException x) { - // No provider found - return null; - } - finally { - try { - // try to close the reader. - rd.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - - if (factoryClassName != null && - ! "".equals(factoryClassName)) { - if (DEBUG) debugPrintln("found in resource, value=" - + factoryClassName); - - // Note: here we do not want to fall back to the current - // 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. - return factoryClassName; - } - - // No provider found - return null; - } - - // - // Classes - // - - /** - * A configuration error. - */ - static class ConfigurationError - extends Error { - static final long serialVersionUID = 3326843611085065902L; - // - // Data - // - - /** Exception. */ - private Exception exception; - - // - // Constructors - // - - /** - * Construct a new instance with the specified detail string and - * exception. - */ - ConfigurationError(String msg, Exception x) { - super(msg); - this.exception = x; - } // (String,Exception) - - // - // Public methods - // - - /** Returns the exception associated to this error. */ - Exception getException() { - return exception; - } // getException():Exception - - } // class ConfigurationError - -} // class ObjectFactory diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/ParameterRef.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/ParameterRef.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/ParameterRef.java Tue Apr 17 11:17:59 2012 -0700 @@ -84,12 +84,10 @@ } else { il.append(_variable.loadInstruction()); - _variable.removeReference(this); } } else { il.append(_variable.loadInstruction()); - _variable.removeReference(this); } } else { diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/ParentLocationPath.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/ParentLocationPath.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/ParentLocationPath.java Tue Apr 17 11:17:59 2012 -0700 @@ -190,15 +190,15 @@ LocalVariableGen pathTemp = methodGen.addLocalVariable("parent_location_path_tmp1", Util.getJCRefType(NODE_ITERATOR_SIG), - il.getEnd(), null); - il.append(new ASTORE(pathTemp.getIndex())); + null, null); + pathTemp.setStart(il.append(new ASTORE(pathTemp.getIndex()))); _step.translate(classGen, methodGen); LocalVariableGen stepTemp = methodGen.addLocalVariable("parent_location_path_tmp2", Util.getJCRefType(NODE_ITERATOR_SIG), - il.getEnd(), null); - il.append(new ASTORE(stepTemp.getIndex())); + null, null); + stepTemp.setStart(il.append(new ASTORE(stepTemp.getIndex()))); // Create new StepIterator final int initSI = cpg.addMethodref(STEP_ITERATOR_CLASS, @@ -210,8 +210,8 @@ il.append(new NEW(cpg.addClass(STEP_ITERATOR_CLASS))); il.append(DUP); - il.append(new ALOAD(pathTemp.getIndex())); - il.append(new ALOAD(stepTemp.getIndex())); + pathTemp.setEnd(il.append(new ALOAD(pathTemp.getIndex()))); + stepTemp.setEnd(il.append(new ALOAD(stepTemp.getIndex()))); // Initialize StepIterator with iterators from the stack il.append(new INVOKESPECIAL(initSI)); diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/ParentPattern.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/ParentPattern.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/ParentPattern.java Tue Apr 17 11:17:59 2012 -0700 @@ -27,6 +27,7 @@ import com.sun.org.apache.bcel.internal.generic.ILOAD; import com.sun.org.apache.bcel.internal.generic.INVOKEINTERFACE; import com.sun.org.apache.bcel.internal.generic.ISTORE; +import com.sun.org.apache.bcel.internal.generic.InstructionHandle; import com.sun.org.apache.bcel.internal.generic.InstructionList; import com.sun.org.apache.bcel.internal.generic.LocalVariableGen; import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator; @@ -77,7 +78,7 @@ final LocalVariableGen local = methodGen.addLocalVariable2("ppt", Util.getJCRefType(NODE_SIG), - il.getEnd()); + null); final com.sun.org.apache.bcel.internal.generic.Instruction loadLocal = new ILOAD(local.getIndex()); @@ -90,7 +91,7 @@ } else if (_right instanceof StepPattern) { il.append(DUP); - il.append(storeLocal); + local.setStart(il.append(storeLocal)); _right.translate(classGen, methodGen); @@ -119,7 +120,11 @@ } else { il.append(DUP); - il.append(storeLocal); + InstructionHandle storeInst = il.append(storeLocal); + + if (local.getStart() == null) { + local.setStart(storeInst); + } _left.translate(classGen, methodGen); diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/Parser.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Parser.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Parser.java Tue Apr 17 11:17:59 2012 -0700 @@ -44,6 +44,8 @@ import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodType; import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type; import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError; +import com.sun.org.apache.xalan.internal.utils.FactoryImpl; +import com.sun.org.apache.xalan.internal.utils.ObjectFactory; import org.xml.sax.Attributes; import org.xml.sax.helpers.AttributesImpl; import org.xml.sax.ContentHandler; @@ -93,8 +95,11 @@ private int _currentImportPrecedence; - public Parser(XSLTC xsltc) { + private boolean _useServicesMechanism = true; + + public Parser(XSLTC xsltc, boolean useServicesMechanism) { _xsltc = xsltc; + _useServicesMechanism = useServicesMechanism; } public void init() { @@ -306,17 +311,22 @@ } else { Dictionary space = (Dictionary)_namespaces.get(namespace); + String lexicalQName = + (prefix == null || prefix.length() == 0) + ? localname + : (prefix + ':' + localname); + if (space == null) { final QName name = new QName(namespace, prefix, localname); _namespaces.put(namespace, space = new Hashtable()); - space.put(localname, name); + space.put(lexicalQName, name); return name; } else { - QName name = (QName)space.get(localname); + QName name = (QName)space.get(lexicalQName); if (name == null) { name = new QName(namespace, prefix, localname); - space.put(localname, name); + space.put(lexicalQName, name); } return name; } @@ -449,7 +459,7 @@ public SyntaxTreeNode parse(InputSource input) { try { // Create a SAX parser and get the XMLReader object it uses - final SAXParserFactory factory = SAXParserFactory.newInstance(); + final SAXParserFactory factory = FactoryImpl.getSAXFactory(_useServicesMechanism); if (_xsltc.isSecureProcessing()) { try { @@ -918,8 +928,7 @@ if (className != null) { try { - final Class clazz = ObjectFactory.findProviderClass( - className, ObjectFactory.findClassLoader(), true); + final Class clazz = ObjectFactory.findProviderClass(className, true); node = (SyntaxTreeNode)clazz.newInstance(); node.setQName(qname); node.setParser(this); @@ -1273,7 +1282,7 @@ // handled at this point in order to correctly generate // Fallback elements from s. getSymbolTable().setCurrentNode(element); - ((Stylesheet)element).excludeExtensionPrefixes(this); + ((Stylesheet)element).declareExtensionPrefixes(this); } _prefixMapping = null; diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/Predicate.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Predicate.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Predicate.java Tue Apr 17 11:17:59 2012 -0700 @@ -412,7 +412,7 @@ il.append(new CHECKCAST(cpg.addClass(className))); il.append(new GETFIELD(cpg.addFieldref(className, DOM_FIELD, DOM_INTF_SIG))); - il.append(new ASTORE(local.getIndex())); + local.setStart(il.append(new ASTORE(local.getIndex()))); // Store the dom index in the test generator testGen.setDomIndex(local.getIndex()); @@ -420,12 +420,8 @@ _exp.translate(filterGen, testGen); il.append(IRETURN); - testGen.stripAttributes(true); - testGen.setMaxLocals(); - testGen.setMaxStack(); - testGen.removeNOPs(); filterGen.addEmptyConstructor(ACC_PUBLIC); - filterGen.addMethod(testGen.getMethod()); + filterGen.addMethod(testGen); getXSLTC().dumpClass(filterGen.getJavaClass()); } diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/ProcessingInstruction.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/ProcessingInstruction.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/ProcessingInstruction.java Tue Apr 17 11:17:59 2012 -0700 @@ -83,13 +83,14 @@ if (!_isLiteral) { // if the ncname is an AVT, then the ncname has to be checked at runtime if it is a valid ncname - LocalVariableGen nameValue = methodGen.addLocalVariable2("nameValue", + LocalVariableGen nameValue = + methodGen.addLocalVariable2("nameValue", Util.getJCRefType(STRING_SIG), - il.getEnd()); + null); // store the name into a variable first so _name.translate only needs to be called once _name.translate(classGen, methodGen); - il.append(new ASTORE(nameValue.getIndex())); + nameValue.setStart(il.append(new ASTORE(nameValue.getIndex()))); il.append(new ALOAD(nameValue.getIndex())); // call checkNCName if the name is an AVT @@ -104,7 +105,7 @@ il.append(DUP); // first arg to "attributes" call // load name value again - il.append(new ALOAD(nameValue.getIndex())); + nameValue.setEnd(il.append(new ALOAD(nameValue.getIndex()))); } else { // Save the current handler base on the stack il.append(methodGen.loadHandler()); diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/SecuritySupport.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/SecuritySupport.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,127 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2002-2004 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. - */ -/* - * $Id: SecuritySupport.java,v 1.2.4.1 2005/09/05 08:57:13 pvedula Exp $ - */ - -package com.sun.org.apache.xalan.internal.xsltc.compiler; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.InputStream; - -import java.util.Properties; - -/** - * This class is duplicated for each Xalan-Java subpackage so keep it in sync. - * It is package private and therefore is not exposed as part of the Xalan-Java - * 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. - */ - static SecuritySupport getInstance() { - return (SecuritySupport)securitySupport; - } - - ClassLoader getContextClassLoader() { - return null; - } - - ClassLoader getSystemClassLoader() { - return null; - } - - ClassLoader getParentClassLoader(ClassLoader cl) { - return null; - } - - String getSystemProperty(String propName) { - return System.getProperty(propName); - } - - FileInputStream getFileInputStream(File file) - throws FileNotFoundException - { - return new FileInputStream(file); - } - - InputStream getResourceAsStream(ClassLoader cl, String name) { - InputStream ris; - if (cl == null) { - ris = ClassLoader.getSystemResourceAsStream(name); - } else { - ris = cl.getResourceAsStream(name); - } - return ris; - } - - boolean getFileExists(File f) { - return f.exists(); - } - - long getLastModified(File f) { - return f.lastModified(); - } -} diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/SecuritySupport12.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/SecuritySupport12.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,148 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2002-2004 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. - */ -/* - * $Id: SecuritySupport12.java,v 1.2.4.1 2005/09/05 08:58:02 pvedula Exp $ - */ - -package com.sun.org.apache.xalan.internal.xsltc.compiler; - -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; - -import java.util.Properties; - -/** - * This class is duplicated for each Xalan-Java subpackage so keep it in sync. - * It is package private and therefore is not exposed as part of the Xalan-Java - * API. - * - * Security related methods that only work on J2SE 1.2 and newer. - */ -class SecuritySupport12 extends SecuritySupport { - - ClassLoader getContextClassLoader() { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader cl = null; - try { - cl = Thread.currentThread().getContextClassLoader(); - } catch (SecurityException ex) { } - return cl; - } - }); - } - - ClassLoader getSystemClassLoader() { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader cl = null; - try { - cl = ClassLoader.getSystemClassLoader(); - } catch (SecurityException ex) {} - return cl; - } - }); - } - - ClassLoader getParentClassLoader(final ClassLoader cl) { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader parent = null; - try { - parent = cl.getParent(); - } catch (SecurityException ex) {} - - // eliminate loops in case of the boot - // ClassLoader returning itself as a parent - return (parent == cl) ? null : parent; - } - }); - } - - String getSystemProperty(final String propName) { - return (String) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return System.getProperty(propName); - } - }); - } - - 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(); - } - } - - 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; - } - }); - } - - boolean getFileExists(final File f) { - return ((Boolean) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return new Boolean(f.exists()); - } - })).booleanValue(); - } - - long getLastModified(final File f) { - return ((Long) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return new Long(f.lastModified()); - } - })).longValue(); - } - -} diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/Sort.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Sort.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Sort.java Tue Apr 17 11:17:59 2012 -0700 @@ -270,12 +270,12 @@ LocalVariableGen nodesTemp = methodGen.addLocalVariable("sort_tmp1", Util.getJCRefType(NODE_ITERATOR_SIG), - il.getEnd(), null); + null, null); LocalVariableGen sortRecordFactoryTemp = methodGen.addLocalVariable("sort_tmp2", Util.getJCRefType(NODE_SORT_FACTORY_SIG), - il.getEnd(), null); + null, null); // Get the current node iterator if (nodeSet == null) { // apply-templates default @@ -291,17 +291,19 @@ nodeSet.translate(classGen, methodGen); } - il.append(new ASTORE(nodesTemp.getIndex())); + nodesTemp.setStart(il.append(new ASTORE(nodesTemp.getIndex()))); // Compile the code for the NodeSortRecord producing class and pass // that as the last argument to the SortingIterator constructor. compileSortRecordFactory(sortObjects, classGen, methodGen); - il.append(new ASTORE(sortRecordFactoryTemp.getIndex())); + sortRecordFactoryTemp.setStart( + il.append(new ASTORE(sortRecordFactoryTemp.getIndex()))); il.append(new NEW(cpg.addClass(SORT_ITERATOR))); il.append(DUP); - il.append(new ALOAD(nodesTemp.getIndex())); - il.append(new ALOAD(sortRecordFactoryTemp.getIndex())); + nodesTemp.setEnd(il.append(new ALOAD(nodesTemp.getIndex()))); + sortRecordFactoryTemp.setEnd( + il.append(new ALOAD(sortRecordFactoryTemp.getIndex()))); il.append(new INVOKESPECIAL(init)); } @@ -346,7 +348,7 @@ LocalVariableGen sortOrderTemp = methodGen.addLocalVariable("sort_order_tmp", Util.getJCRefType("[" + STRING_SIG), - il.getEnd(), null); + null, null); il.append(new PUSH(cpg, nsorts)); il.append(new ANEWARRAY(cpg.addClass(STRING))); for (int level = 0; level < nsorts; level++) { @@ -356,12 +358,12 @@ sort.translateSortOrder(classGen, methodGen); il.append(AASTORE); } - il.append(new ASTORE(sortOrderTemp.getIndex())); + sortOrderTemp.setStart(il.append(new ASTORE(sortOrderTemp.getIndex()))); LocalVariableGen sortTypeTemp = methodGen.addLocalVariable("sort_type_tmp", Util.getJCRefType("[" + STRING_SIG), - il.getEnd(), null); + null, null); il.append(new PUSH(cpg, nsorts)); il.append(new ANEWARRAY(cpg.addClass(STRING))); for (int level = 0; level < nsorts; level++) { @@ -371,12 +373,12 @@ sort.translateSortType(classGen, methodGen); il.append(AASTORE); } - il.append(new ASTORE(sortTypeTemp.getIndex())); + sortTypeTemp.setStart(il.append(new ASTORE(sortTypeTemp.getIndex()))); LocalVariableGen sortLangTemp = methodGen.addLocalVariable("sort_lang_tmp", Util.getJCRefType("[" + STRING_SIG), - il.getEnd(), null); + null, null); il.append(new PUSH(cpg, nsorts)); il.append(new ANEWARRAY(cpg.addClass(STRING))); for (int level = 0; level < nsorts; level++) { @@ -386,12 +388,12 @@ sort.translateLang(classGen, methodGen); il.append(AASTORE); } - il.append(new ASTORE(sortLangTemp.getIndex())); + sortLangTemp.setStart(il.append(new ASTORE(sortLangTemp.getIndex()))); LocalVariableGen sortCaseOrderTemp = methodGen.addLocalVariable("sort_case_order_tmp", Util.getJCRefType("[" + STRING_SIG), - il.getEnd(), null); + null, null); il.append(new PUSH(cpg, nsorts)); il.append(new ANEWARRAY(cpg.addClass(STRING))); for (int level = 0; level < nsorts; level++) { @@ -401,7 +403,8 @@ sort.translateCaseOrder(classGen, methodGen); il.append(AASTORE); } - il.append(new ASTORE(sortCaseOrderTemp.getIndex())); + sortCaseOrderTemp.setStart( + il.append(new ASTORE(sortCaseOrderTemp.getIndex()))); il.append(new NEW(cpg.addClass(sortRecordFactoryClass))); il.append(DUP); @@ -409,10 +412,11 @@ il.append(new PUSH(cpg, sortRecordClass)); il.append(classGen.loadTranslet()); - il.append(new ALOAD(sortOrderTemp.getIndex())); - il.append(new ALOAD(sortTypeTemp.getIndex())); - il.append(new ALOAD(sortLangTemp.getIndex())); - il.append(new ALOAD(sortCaseOrderTemp.getIndex())); + sortOrderTemp.setEnd(il.append(new ALOAD(sortOrderTemp.getIndex()))); + sortTypeTemp.setEnd(il.append(new ALOAD(sortTypeTemp.getIndex()))); + sortLangTemp.setEnd(il.append(new ALOAD(sortLangTemp.getIndex()))); + sortCaseOrderTemp.setEnd( + il.append(new ALOAD(sortCaseOrderTemp.getIndex()))); il.append(new INVOKESPECIAL( cpg.addMethodref(sortRecordFactoryClass, "", @@ -584,10 +588,10 @@ constructor.setMaxLocals(); constructor.setMaxStack(); - sortRecordFactory.addMethod(constructor.getMethod()); + sortRecordFactory.addMethod(constructor); makeNodeSortRecord.setMaxLocals(); makeNodeSortRecord.setMaxStack(); - sortRecordFactory.addMethod(makeNodeSortRecord.getMethod()); + sortRecordFactory.addMethod(makeNodeSortRecord); xsltc.dumpClass(sortRecordFactory.getJavaClass()); return className; @@ -640,9 +644,9 @@ } } - Method init = compileInit(sortObjects, sortRecord, + MethodGenerator init = compileInit(sortObjects, sortRecord, cpg, className); - Method extract = compileExtract(sortObjects, sortRecord, + MethodGenerator extract = compileExtract(sortObjects, sortRecord, cpg, className); sortRecord.addMethod(init); sortRecord.addMethod(extract); @@ -656,7 +660,7 @@ * collator in the super calls only when the stylesheet specifies a new * language in xsl:sort. */ - private static Method compileInit(Vector sortObjects, + private static MethodGenerator compileInit(Vector sortObjects, NodeSortRecordGenerator sortRecord, ConstantPoolGen cpg, String className) @@ -677,18 +681,14 @@ il.append(RETURN); - init.stripAttributes(true); - init.setMaxLocals(); - init.setMaxStack(); - - return init.getMethod(); + return init; } /** * Compiles a method that overloads NodeSortRecord.extractValueFromDOM() */ - private static Method compileExtract(Vector sortObjects, + private static MethodGenerator compileExtract(Vector sortObjects, NodeSortRecordGenerator sortRecord, ConstantPoolGen cpg, String className) { @@ -745,11 +745,6 @@ il.append(ARETURN); } - extractMethod.stripAttributes(true); - extractMethod.setMaxLocals(); - extractMethod.setMaxStack(); - extractMethod.removeNOPs(); - - return extractMethod.getMethod(); + return extractMethod; } } diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/Step.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Step.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Step.java Tue Apr 17 11:17:59 2012 -0700 @@ -447,20 +447,24 @@ LocalVariableGen iteratorTemp = methodGen.addLocalVariable("step_tmp1", Util.getJCRefType(NODE_ITERATOR_SIG), - il.getEnd(), null); - il.append(new ASTORE(iteratorTemp.getIndex())); + null, null); + iteratorTemp.setStart( + il.append(new ASTORE(iteratorTemp.getIndex()))); predicate.translate(classGen, methodGen); LocalVariableGen predicateValueTemp = methodGen.addLocalVariable("step_tmp2", Util.getJCRefType("I"), - il.getEnd(), null); - il.append(new ISTORE(predicateValueTemp.getIndex())); + null, null); + predicateValueTemp.setStart( + il.append(new ISTORE(predicateValueTemp.getIndex()))); il.append(new NEW(cpg.addClass(NTH_ITERATOR_CLASS))); il.append(DUP); - il.append(new ALOAD(iteratorTemp.getIndex())); - il.append(new ILOAD(predicateValueTemp.getIndex())); + iteratorTemp.setEnd( + il.append(new ALOAD(iteratorTemp.getIndex()))); + predicateValueTemp.setEnd( + il.append(new ILOAD(predicateValueTemp.getIndex()))); il.append(new INVOKESPECIAL(idx)); } else { @@ -486,22 +490,24 @@ LocalVariableGen iteratorTemp = methodGen.addLocalVariable("step_tmp1", Util.getJCRefType(NODE_ITERATOR_SIG), - il.getEnd(), null); - il.append(new ASTORE(iteratorTemp.getIndex())); + null, null); + iteratorTemp.setStart( + il.append(new ASTORE(iteratorTemp.getIndex()))); predicate.translateFilter(classGen, methodGen); LocalVariableGen filterTemp = methodGen.addLocalVariable("step_tmp2", Util.getJCRefType(CURRENT_NODE_LIST_FILTER_SIG), - il.getEnd(), null); - il.append(new ASTORE(filterTemp.getIndex())); - + null, null); + filterTemp.setStart( + il.append(new ASTORE(filterTemp.getIndex()))); // create new CurrentNodeListIterator il.append(new NEW(cpg.addClass(CURRENT_NODE_LIST_ITERATOR))); il.append(DUP); - il.append(new ALOAD(iteratorTemp.getIndex())); - il.append(new ALOAD(filterTemp.getIndex())); + iteratorTemp.setEnd( + il.append(new ALOAD(iteratorTemp.getIndex()))); + filterTemp.setEnd(il.append(new ALOAD(filterTemp.getIndex()))); il.append(methodGen.loadCurrentNode()); il.append(classGen.loadTranslet()); diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/StepPattern.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/StepPattern.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/StepPattern.java Tue Apr 17 11:17:59 2012 -0700 @@ -328,8 +328,8 @@ LocalVariableGen match; match = methodGen.addLocalVariable("step_pattern_tmp1", Util.getJCRefType(NODE_SIG), - il.getEnd(), null); - il.append(new ISTORE(match.getIndex())); + null, null); + match.setStart(il.append(new ISTORE(match.getIndex()))); // If pattern not reduced then check kernel if (!_isEpsilon) { @@ -358,13 +358,15 @@ LocalVariableGen stepIteratorTemp = methodGen.addLocalVariable("step_pattern_tmp2", Util.getJCRefType(NODE_ITERATOR_SIG), - il.getEnd(), null); - il.append(new ASTORE(stepIteratorTemp.getIndex())); + null, null); + stepIteratorTemp.setStart( + il.append(new ASTORE(stepIteratorTemp.getIndex()))); il.append(new NEW(cpg.addClass(MATCHING_ITERATOR))); il.append(DUP); il.append(new ILOAD(match.getIndex())); - il.append(new ALOAD(stepIteratorTemp.getIndex())); + stepIteratorTemp.setEnd( + il.append(new ALOAD(stepIteratorTemp.getIndex()))); il.append(new INVOKESPECIAL(index)); // Get the parent of the matching node @@ -378,7 +380,7 @@ // Overwrite current iterator and current node il.append(methodGen.storeIterator()); - il.append(new ILOAD(match.getIndex())); + match.setEnd(il.append(new ILOAD(match.getIndex()))); il.append(methodGen.storeCurrentNode()); // Translate the expression of the predicate @@ -415,13 +417,13 @@ // Store node on the stack into a local variable node = methodGen.addLocalVariable("step_pattern_tmp1", Util.getJCRefType(NODE_SIG), - il.getEnd(), null); - il.append(new ISTORE(node.getIndex())); + null, null); + node.setStart(il.append(new ISTORE(node.getIndex()))); // Create a new local to store the iterator iter = methodGen.addLocalVariable("step_pattern_tmp2", Util.getJCRefType(NODE_ITERATOR_SIG), - il.getEnd(), null); + null, null); // Add a new private field if this is the main class if (!classGen.isExternal()) { @@ -438,20 +440,24 @@ il.append(classGen.loadTranslet()); il.append(new GETFIELD(iteratorIndex)); il.append(DUP); - il.append(new ASTORE(iter.getIndex())); + iter.setStart(il.append(new ASTORE(iter.getIndex()))); ifBlock = il.append(new IFNONNULL(null)); il.append(classGen.loadTranslet()); } // Compile the step created at type checking time _step.translate(classGen, methodGen); - il.append(new ASTORE(iter.getIndex())); + InstructionHandle iterStore = il.append(new ASTORE(iter.getIndex())); // If in the main class update the field too if (!classGen.isExternal()) { il.append(new ALOAD(iter.getIndex())); il.append(new PUTFIELD(iteratorIndex)); ifBlock.setTarget(il.append(NOP)); + } else { + // If class is not external, start of range for iter variable was + // set above + iter.setStart(iterStore); } // Get the parent of the node on the stack @@ -478,10 +484,11 @@ InstructionHandle begin, next; node2 = methodGen.addLocalVariable("step_pattern_tmp3", Util.getJCRefType(NODE_SIG), - il.getEnd(), null); + null, null); skipNext = il.append(new GOTO(null)); next = il.append(new ALOAD(iter.getIndex())); + node2.setStart(next); begin = il.append(methodGen.nextNode()); il.append(DUP); il.append(new ISTORE(node2.getIndex())); @@ -489,10 +496,10 @@ il.append(new ILOAD(node2.getIndex())); il.append(new ILOAD(node.getIndex())); - il.append(new IF_ICMPLT(next)); + iter.setEnd(il.append(new IF_ICMPLT(next))); - il.append(new ILOAD(node2.getIndex())); - il.append(new ILOAD(node.getIndex())); + node2.setEnd(il.append(new ILOAD(node2.getIndex()))); + node.setEnd(il.append(new ILOAD(node.getIndex()))); _falseList.add(il.append(new IF_ICMPNE(null))); skipNext.setTarget(begin); diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/Stylesheet.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Stylesheet.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Stylesheet.java Tue Apr 17 11:17:59 2012 -0700 @@ -23,9 +23,6 @@ package com.sun.org.apache.xalan.internal.xsltc.compiler; -import java.net.URL; -import java.net.MalformedURLException; - import java.util.Vector; import java.util.Enumeration; import java.util.Hashtable; @@ -203,8 +200,9 @@ /** * Set to true to enable template inlining optimization. + * @see XSLTC#_templateInlining */ - private boolean _templateInlining = true; + private boolean _templateInlining = false; /** * A reference to the last xsl:output object found in the styleshet. @@ -467,11 +465,11 @@ for (int i = 0; i < n; i++) { final Template template = (Template)templates.elementAt(i); if (template.hasParams()) { - _hasLocalParams = new Boolean(true); + _hasLocalParams = Boolean.TRUE; return true; } } - _hasLocalParams = new Boolean(false); + _hasLocalParams = Boolean.FALSE; return false; } else { @@ -509,15 +507,9 @@ return (_extensions.get(uri) != null); } - public void excludeExtensionPrefixes(Parser parser) { + public void declareExtensionPrefixes(Parser parser) { final SymbolTable stable = parser.getSymbolTable(); - final String excludePrefixes = getAttribute("exclude-result-prefixes"); final String extensionPrefixes = getAttribute("extension-element-prefixes"); - - // Exclude XSLT uri - stable.excludeURI(Constants.XSLT_URI); - stable.excludeNamespaces(excludePrefixes); - stable.excludeNamespaces(extensionPrefixes); extensionURI(extensionPrefixes, stable); } @@ -571,6 +563,16 @@ * Parse all direct children of the element. */ public final void parseOwnChildren(Parser parser) { + final SymbolTable stable = parser.getSymbolTable(); + final String excludePrefixes = getAttribute("exclude-result-prefixes"); + final String extensionPrefixes = getAttribute("extension-element-prefixes"); + + // Exclude XSLT uri + stable.pushExcludedNamespacesContext(); + stable.excludeURI(Constants.XSLT_URI); + stable.excludeNamespaces(excludePrefixes); + stable.excludeNamespaces(extensionPrefixes); + final Vector contents = getContents(); final int count = contents.size(); @@ -602,6 +604,8 @@ template.setName(parser.getQName(name)); } } + + stable.popExcludedNamespacesContext(); } public void processModes() { @@ -801,81 +805,99 @@ } } + staticConst.markChunkStart(); il.append(new PUSH(cpg, size)); il.append(new ANEWARRAY(cpg.addClass(STRING))); + int namesArrayRef = cpg.addFieldref(_className, + STATIC_NAMES_ARRAY_FIELD, + NAMES_INDEX_SIG); + il.append(new PUTSTATIC(namesArrayRef)); + staticConst.markChunkEnd(); for (int i = 0; i < size; i++) { final String name = namesArray[i]; - il.append(DUP); + staticConst.markChunkStart(); + il.append(new GETSTATIC(namesArrayRef)); il.append(new PUSH(cpg, i)); il.append(new PUSH(cpg, name)); il.append(AASTORE); + staticConst.markChunkEnd(); } - il.append(new PUTSTATIC(cpg.addFieldref(_className, - STATIC_NAMES_ARRAY_FIELD, - NAMES_INDEX_SIG))); + staticConst.markChunkStart(); il.append(new PUSH(cpg, size)); il.append(new ANEWARRAY(cpg.addClass(STRING))); + int urisArrayRef = cpg.addFieldref(_className, + STATIC_URIS_ARRAY_FIELD, + URIS_INDEX_SIG); + il.append(new PUTSTATIC(urisArrayRef)); + staticConst.markChunkEnd(); for (int i = 0; i < size; i++) { final String uri = urisArray[i]; - il.append(DUP); + staticConst.markChunkStart(); + il.append(new GETSTATIC(urisArrayRef)); il.append(new PUSH(cpg, i)); il.append(new PUSH(cpg, uri)); il.append(AASTORE); + staticConst.markChunkEnd(); } - il.append(new PUTSTATIC(cpg.addFieldref(_className, - STATIC_URIS_ARRAY_FIELD, - URIS_INDEX_SIG))); + staticConst.markChunkStart(); il.append(new PUSH(cpg, size)); il.append(new NEWARRAY(BasicType.INT)); + int typesArrayRef = cpg.addFieldref(_className, + STATIC_TYPES_ARRAY_FIELD, + TYPES_INDEX_SIG); + il.append(new PUTSTATIC(typesArrayRef)); + staticConst.markChunkEnd(); for (int i = 0; i < size; i++) { final int nodeType = typesArray[i]; - il.append(DUP); + staticConst.markChunkStart(); + il.append(new GETSTATIC(typesArrayRef)); il.append(new PUSH(cpg, i)); il.append(new PUSH(cpg, nodeType)); il.append(IASTORE); } - il.append(new PUTSTATIC(cpg.addFieldref(_className, - STATIC_TYPES_ARRAY_FIELD, - TYPES_INDEX_SIG))); // Put the namespace names array into the translet final Vector namespaces = getXSLTC().getNamespaceIndex(); + staticConst.markChunkStart(); il.append(new PUSH(cpg, namespaces.size())); il.append(new ANEWARRAY(cpg.addClass(STRING))); + int namespaceArrayRef = cpg.addFieldref(_className, + STATIC_NAMESPACE_ARRAY_FIELD, + NAMESPACE_INDEX_SIG); + il.append(new PUTSTATIC(namespaceArrayRef)); + staticConst.markChunkEnd(); for (int i = 0; i < namespaces.size(); i++) { final String ns = (String)namespaces.elementAt(i); - il.append(DUP); + staticConst.markChunkStart(); + il.append(new GETSTATIC(namespaceArrayRef)); il.append(new PUSH(cpg, i)); il.append(new PUSH(cpg, ns)); il.append(AASTORE); + staticConst.markChunkEnd(); } - il.append(new PUTSTATIC(cpg.addFieldref(_className, - STATIC_NAMESPACE_ARRAY_FIELD, - NAMESPACE_INDEX_SIG))); // Grab all the literal text in the stylesheet and put it in a char[] final int charDataCount = getXSLTC().getCharacterDataCount(); final int toCharArray = cpg.addMethodref(STRING, "toCharArray", "()[C"); for (int i = 0; i < charDataCount; i++) { + staticConst.markChunkStart(); il.append(new PUSH(cpg, getXSLTC().getCharacterData(i))); il.append(new INVOKEVIRTUAL(toCharArray)); il.append(new PUTSTATIC(cpg.addFieldref(_className, STATIC_CHAR_DATA_FIELD+i, STATIC_CHAR_DATA_FIELD_SIG))); + staticConst.markChunkEnd(); } il.append(RETURN); - staticConst.stripAttributes(true); - staticConst.setMaxLocals(); - staticConst.setMaxStack(); - classGen.addMethod(staticConst.getMethod()); + classGen.addMethod(staticConst); } @@ -898,6 +920,7 @@ il.append(new INVOKESPECIAL(cpg.addMethodref(TRANSLET_CLASS, "", "()V"))); + constructor.markChunkStart(); il.append(classGen.loadTranslet()); il.append(new GETSTATIC(cpg.addFieldref(_className, STATIC_NAMES_ARRAY_FIELD, @@ -913,7 +936,9 @@ il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, URIS_INDEX, URIS_INDEX_SIG))); + constructor.markChunkEnd(); + constructor.markChunkStart(); il.append(classGen.loadTranslet()); il.append(new GETSTATIC(cpg.addFieldref(_className, STATIC_TYPES_ARRAY_FIELD, @@ -921,7 +946,9 @@ il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, TYPES_INDEX, TYPES_INDEX_SIG))); + constructor.markChunkEnd(); + constructor.markChunkStart(); il.append(classGen.loadTranslet()); il.append(new GETSTATIC(cpg.addFieldref(_className, STATIC_NAMESPACE_ARRAY_FIELD, @@ -929,38 +956,45 @@ il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, NAMESPACE_INDEX, NAMESPACE_INDEX_SIG))); + constructor.markChunkEnd(); + constructor.markChunkStart(); il.append(classGen.loadTranslet()); il.append(new PUSH(cpg, AbstractTranslet.CURRENT_TRANSLET_VERSION)); il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, TRANSLET_VERSION_INDEX, TRANSLET_VERSION_INDEX_SIG))); + constructor.markChunkEnd(); if (_hasIdCall) { + constructor.markChunkStart(); il.append(classGen.loadTranslet()); il.append(new PUSH(cpg, Boolean.TRUE)); il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, HASIDCALL_INDEX, HASIDCALL_INDEX_SIG))); + constructor.markChunkEnd(); } // Compile in code to set the output configuration from if (output != null) { // Set all the output settings files in the translet + constructor.markChunkStart(); output.translate(classGen, constructor); + constructor.markChunkEnd(); } // Compile default decimal formatting symbols. // This is an implicit, nameless xsl:decimal-format top-level element. - if (_numberFormattingUsed) + if (_numberFormattingUsed) { + constructor.markChunkStart(); DecimalFormatting.translateDefaultDFS(classGen, constructor); + constructor.markChunkEnd(); + } il.append(RETURN); - constructor.stripAttributes(true); - constructor.setMaxLocals(); - constructor.setMaxStack(); - classGen.addMethod(constructor.getMethod()); + classGen.addMethod(constructor); } /** @@ -1000,25 +1034,23 @@ toplevel.addException("com.sun.org.apache.xalan.internal.xsltc.TransletException"); + // Define and initialize 'current' variable with the root node + final LocalVariableGen current = + toplevel.addLocalVariable("current", + com.sun.org.apache.bcel.internal.generic.Type.INT, + null, null); + final int setFilter = cpg.addInterfaceMethodref(DOM_INTF, "setFilter", "(Lcom/sun/org/apache/xalan/internal/xsltc/StripFilter;)V"); - // Define and initialize 'current' variable with the root node - final LocalVariableGen current = - toplevel.addLocalVariable("current", - com.sun.org.apache.bcel.internal.generic.Type.INT, - il.getEnd(), null); - - // Get root node from main DOM by calling dom.getIterator().next() final int gitr = cpg.addInterfaceMethodref(DOM_INTF, - "getIterator", "()"+NODE_ITERATOR_SIG); - final int next = cpg.addInterfaceMethodref(NODE_ITERATOR, - "next", "()I"); + "getIterator", + "()"+NODE_ITERATOR_SIG); il.append(toplevel.loadDOM()); il.append(new INVOKEINTERFACE(gitr, 1)); - il.append(new INVOKEINTERFACE(next, 1)); - il.append(new ISTORE(current.getIndex())); + il.append(toplevel.nextNode()); + current.setStart(il.append(new ISTORE(current.getIndex()))); // Create a new list containing variables/params + keys Vector varDepElements = new Vector(_globals); @@ -1073,12 +1105,7 @@ il.append(RETURN); // Compute max locals + stack and add method to class - toplevel.stripAttributes(true); - toplevel.setMaxLocals(); - toplevel.setMaxStack(); - toplevel.removeNOPs(); - - classGen.addMethod(toplevel.getMethod()); + classGen.addMethod(toplevel); return("("+DOM_INTF_SIG+NODE_ITERATOR_SIG+TRANSLET_OUTPUT_SIG+")V"); } @@ -1233,7 +1260,7 @@ final LocalVariableGen current = transf.addLocalVariable("current", com.sun.org.apache.bcel.internal.generic.Type.INT, - il.getEnd(), null); + null, null); final String applyTemplatesSig = classGen.getApplyTemplatesSig(); final int applyTemplates = cpg.addMethodref(getClassName(), "applyTemplates", @@ -1270,6 +1297,15 @@ //store to _dom variable il.append(new PUTFIELD(domField)); + // continue with globals initialization + final int gitr = cpg.addInterfaceMethodref(DOM_INTF, + "getIterator", + "()"+NODE_ITERATOR_SIG); + il.append(transf.loadDOM()); + il.append(new INVOKEINTERFACE(gitr, 1)); + il.append(transf.nextNode()); + current.setStart(il.append(new ISTORE(current.getIndex()))); + // Transfer the output settings to the output post-processor il.append(classGen.loadTranslet()); il.append(transf.loadHandler()); @@ -1326,12 +1362,8 @@ il.append(RETURN); // Compute max locals + stack and add method to class - transf.stripAttributes(true); - transf.setMaxLocals(); - transf.setMaxStack(); - transf.removeNOPs(); + classGen.addMethod(transf); - classGen.addMethod(transf.getMethod()); } /** diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/SymbolTable.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/SymbolTable.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/SymbolTable.java Tue Apr 17 11:17:59 2012 -0700 @@ -24,6 +24,7 @@ package com.sun.org.apache.xalan.internal.xsltc.compiler; import java.util.Hashtable; +import java.util.Stack; import java.util.StringTokenizer; import java.util.Vector; @@ -46,6 +47,7 @@ private Hashtable _attributeSets = null; private Hashtable _aliases = null; private Hashtable _excludedURI = null; + private Stack _excludedURIStack = null; private Hashtable _decimalFormats = null; private Hashtable _keys = null; @@ -158,7 +160,7 @@ private int _nsCounter = 0; public String generateNamespacePrefix() { - return(new String("ns"+(_nsCounter++))); + return("ns"+(_nsCounter++)); } /** @@ -261,5 +263,33 @@ } } } + /** + * Exclusion of namespaces by a stylesheet does not extend to any stylesheet + * imported or included by the stylesheet. Upon entering the context of a + * new stylesheet, a call to this method is needed to clear the current set + * of excluded namespaces temporarily. Every call to this method requires + * a corresponding call to {@link #popExcludedNamespacesContext()}. + */ + public void pushExcludedNamespacesContext() { + if (_excludedURIStack == null) { + _excludedURIStack = new Stack(); + } + _excludedURIStack.push(_excludedURI); + _excludedURI = null; + } + + /** + * Exclusion of namespaces by a stylesheet does not extend to any stylesheet + * imported or included by the stylesheet. Upon exiting the context of a + * stylesheet, a call to this method is needed to restore the set of + * excluded namespaces that was in effect prior to entering the context of + * the current stylesheet. + */ + public void popExcludedNamespacesContext() { + _excludedURI = (Hashtable) _excludedURIStack.pop(); + if (_excludedURIStack.isEmpty()) { + _excludedURIStack = null; + } + } } diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/SyntaxTreeNode.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/SyntaxTreeNode.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/SyntaxTreeNode.java Tue Apr 17 11:17:59 2012 -0700 @@ -512,9 +512,12 @@ MethodGenerator methodGen) { // Call translate() on all child nodes final int n = elementCount(); + for (int i = 0; i < n; i++) { + methodGen.markChunkStart(); final SyntaxTreeNode item = (SyntaxTreeNode)_contents.elementAt(i); item.translate(classGen, methodGen); + methodGen.markChunkEnd(); } // After translation, unmap any registers for any variables/parameters diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/TestSeq.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/TestSeq.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/TestSeq.java Tue Apr 17 11:17:59 2012 -0700 @@ -108,10 +108,10 @@ (LocationPathPattern) _patterns.elementAt(i); if (i == 0) { - result.append("Testseq for kernel " + _kernelType) + result.append("Testseq for kernel ").append(_kernelType) .append('\n'); } - result.append(" pattern " + i + ": ") + result.append(" pattern ").append(i).append(": ") .append(pattern.toString()) .append('\n'); } diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/Variable.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Variable.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Variable.java Tue Apr 17 11:17:59 2012 -0700 @@ -28,6 +28,7 @@ import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen; import com.sun.org.apache.bcel.internal.generic.DCONST; import com.sun.org.apache.bcel.internal.generic.ICONST; +import com.sun.org.apache.bcel.internal.generic.InstructionHandle; import com.sun.org.apache.bcel.internal.generic.InstructionList; import com.sun.org.apache.bcel.internal.generic.PUTFIELD; import com.sun.org.apache.xalan.internal.xsltc.compiler.util.BooleanType; @@ -128,7 +129,7 @@ if (_local == null) { _local = methodGen.addLocalVariable2(getEscapedName(), _type.toJCType(), - il.getEnd()); + null); } // Push the default value on the JVM's stack if ((_type instanceof IntType) || @@ -139,7 +140,10 @@ il.append(new DCONST(0)); // 0.0 for floating point numbers else il.append(new ACONST_NULL()); // and 'null' for anything else - il.append(_type.STORE(_local.getIndex())); + + // Mark the store as the start of the live range of the variable + _local.setStart(il.append(_type.STORE(_local.getIndex()))); + } } @@ -163,10 +167,20 @@ translateValue(classGen, methodGen); // Add a new local variable and store value - if (_local == null) { + boolean createLocal = _local == null; + if (createLocal) { mapRegister(methodGen); } + InstructionHandle storeInst = il.append(_type.STORE(_local.getIndex())); + + // If the local is just being created, mark the store as the start + // of its live range. Note that it might have been created by + // initializeVariables already, which would have set the start of + // the live range already. + if (createLocal) { + _local.setStart(storeInst); + } } else { String signature = _type.toSignature(); diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/VariableBase.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/VariableBase.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/VariableBase.java Tue Apr 17 11:17:59 2012 -0700 @@ -84,14 +84,6 @@ } /** - * Remove a reference to this variable. Called by VariableRef when this - * variable goes out of scope. - */ - public void removeReference(VariableRefBase vref) { - _refs.remove(vref); - } - - /** * When a variable is overriden by another, e.g. via xsl:import, * its references need to be copied or otherwise it may be * compiled away as dead code. This method can be used for that @@ -121,7 +113,7 @@ * Called when we leave the AST scope of the variable's declaration */ public void unmapRegister(MethodGenerator methodGen) { - if (_refs.isEmpty() && (_local != null)) { + if (_local != null) { _local.setEnd(methodGen.getInstructionList().getEnd()); methodGen.removeLocalVariable(_local); _refs = null; diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/VariableRef.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/VariableRef.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/VariableRef.java Tue Apr 17 11:17:59 2012 -0700 @@ -70,12 +70,10 @@ } else { il.append(_variable.loadInstruction()); - _variable.removeReference(this); } } else { il.append(_variable.loadInstruction()); - _variable.removeReference(this); } } else { diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/Whitespace.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Whitespace.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Whitespace.java Tue Apr 17 11:17:59 2012 -0700 @@ -157,8 +157,7 @@ if (col != -1) { namespace = lookupNamespace(token.substring(0,col)); if (namespace != null) { - elements.append(namespace+":"+ - token.substring(col+1,token.length())); + elements.append(namespace).append(':').append(token.substring(col + 1)); } else { elements.append(token); } @@ -426,12 +425,7 @@ compileStripSpace(strip, sCount, il); } - stripSpace.stripAttributes(true); - stripSpace.setMaxLocals(); - stripSpace.setMaxStack(); - stripSpace.removeNOPs(); - - classGen.addMethod(stripSpace.getMethod()); + classGen.addMethod(stripSpace); } /** @@ -463,12 +457,7 @@ il.append(ICONST_0); il.append(IRETURN); - stripSpace.stripAttributes(true); - stripSpace.setMaxLocals(); - stripSpace.setMaxStack(); - stripSpace.removeNOPs(); - - classGen.addMethod(stripSpace.getMethod()); + classGen.addMethod(stripSpace); } diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/XSLTC.java Tue Apr 17 11:17:59 2012 -0700 @@ -131,11 +131,13 @@ */ private boolean _isSecureProcessing = false; + private boolean _useServicesMechanism = true; + /** * XSLTC compiler constructor */ - public XSLTC() { - _parser = new Parser(this); + public XSLTC(boolean useServicesMechanism) { + _parser = new Parser(this, useServicesMechanism); } /** @@ -151,6 +153,19 @@ public boolean isSecureProcessing() { return _isSecureProcessing; } + /** + * Return the state of the services mechanism feature. + */ + public boolean useServicesMechnism() { + return _useServicesMechanism; + } + + /** + * Set the state of the services mechanism feature. + */ + public void setServicesMechnism(boolean flag) { + _useServicesMechanism = flag; + } /** * Only for user by the internal TrAX implementation. @@ -230,6 +245,12 @@ public void setTemplateInlining(boolean templateInlining) { _templateInlining = templateInlining; } + /** + * Return the state of the template inlining feature. + */ + public boolean getTemplateInlining() { + return _templateInlining; + } /** * Set the parameters to use to locate the correct diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/XslAttribute.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/XslAttribute.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/XslAttribute.java Tue Apr 17 11:17:59 2012 -0700 @@ -209,13 +209,14 @@ if (!_isLiteral) { // if the qname is an AVT, then the qname has to be checked at runtime if it is a valid qname - LocalVariableGen nameValue = methodGen.addLocalVariable2("nameValue", + LocalVariableGen nameValue = + methodGen.addLocalVariable2("nameValue", Util.getJCRefType(STRING_SIG), - il.getEnd()); + null); // store the name into a variable first so _name.translate only needs to be called once _name.translate(classGen, methodGen); - il.append(new ASTORE(nameValue.getIndex())); + nameValue.setStart(il.append(new ASTORE(nameValue.getIndex()))); il.append(new ALOAD(nameValue.getIndex())); // call checkQName if the name is an AVT @@ -230,7 +231,7 @@ il.append(DUP); // first arg to "attributes" call // load name value again - il.append(new ALOAD(nameValue.getIndex())); + nameValue.setEnd(il.append(new ALOAD(nameValue.getIndex()))); } else { // Save the current handler base on the stack il.append(methodGen.loadHandler()); diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/XslElement.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/XslElement.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/XslElement.java Tue Apr 17 11:17:59 2012 -0700 @@ -224,13 +224,14 @@ if (!_ignore) { // if the qname is an AVT, then the qname has to be checked at runtime if it is a valid qname - LocalVariableGen nameValue = methodGen.addLocalVariable2("nameValue", - Util.getJCRefType(STRING_SIG), - il.getEnd()); + LocalVariableGen nameValue = + methodGen.addLocalVariable2("nameValue", + Util.getJCRefType(STRING_SIG), + null); // store the name into a variable first so _name.translate only needs to be called once _name.translate(classGen, methodGen); - il.append(new ASTORE(nameValue.getIndex())); + nameValue.setStart(il.append(new ASTORE(nameValue.getIndex()))); il.append(new ALOAD(nameValue.getIndex())); // call checkQName if the name is an AVT @@ -244,7 +245,7 @@ il.append(methodGen.loadHandler()); // load name value again - il.append(new ALOAD(nameValue.getIndex())); + nameValue.setEnd(il.append(new ALOAD(nameValue.getIndex()))); if (_namespace != null) { _namespace.translate(classGen, methodGen); diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ClassGenerator.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ClassGenerator.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ClassGenerator.java Tue Apr 17 11:17:59 2012 -0700 @@ -23,6 +23,7 @@ package com.sun.org.apache.xalan.internal.xsltc.compiler.util; +import com.sun.org.apache.bcel.internal.classfile.Method; import com.sun.org.apache.bcel.internal.generic.ALOAD; import com.sun.org.apache.bcel.internal.generic.ClassGen; import com.sun.org.apache.bcel.internal.generic.Instruction; @@ -134,4 +135,10 @@ public boolean isExternal() { return false; } + public void addMethod(MethodGenerator methodGen) { + Method[] methodsToAdd = methodGen.getGeneratedMethods(this); + for (int i = 0; i < methodsToAdd.length; i++) { + addMethod(methodsToAdd[i]); } + } +} diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java Tue Apr 17 11:17:59 2012 -0700 @@ -941,7 +941,64 @@ "Cannot set the feature ''{0}'' on this TransformerFactory."}, {ErrorMsg.JAXP_SECUREPROCESSING_FEATURE, - "FEATURE_SECURE_PROCESSING: Cannot set the feature to false when security manager is present."} + "FEATURE_SECURE_PROCESSING: Cannot set the feature to false when security manager is present."}, + + /* + * Note to translators: This message describes an internal error in the + * processor. The term "byte code" is a Java technical term for the + * executable code in a Java method, and "try-catch-finally block" + * refers to the Java keywords with those names. "Outlined" is a + * technical term internal to XSLTC and should not be translated. + */ + {ErrorMsg.OUTLINE_ERR_TRY_CATCH, + "Internal XSLTC error: the generated byte code contains a " + + "try-catch-finally block and cannot be outlined."}, + + /* + * Note to translators: This message describes an internal error in the + * processor. The terms "OutlineableChunkStart" and + * "OutlineableChunkEnd" are the names of classes internal to XSLTC and + * should not be translated. The message indicates that for every + * "start" there must be a corresponding "end", and vice versa, and + * that if one of a pair of "start" and "end" appears between another + * pair of corresponding "start" and "end", then the other half of the + * pair must also be between that same enclosing pair. + */ + {ErrorMsg.OUTLINE_ERR_UNBALANCED_MARKERS, + "Internal XSLTC error: OutlineableChunkStart and " + + "OutlineableChunkEnd markers must be balanced and properly nested."}, + + /* + * Note to translators: This message describes an internal error in the + * processor. The term "byte code" is a Java technical term for the + * executable code in a Java method. The "method" that is being + * referred to is a Java method in a translet that XSLTC is generating + * in processing a stylesheet. The "instruction" that is being + * referred to is one of the instrutions in the Java byte code in that + * method. "Outlined" is a technical term internal to XSLTC and + * should not be translated. + */ + {ErrorMsg.OUTLINE_ERR_DELETED_TARGET, + "Internal XSLTC error: an instruction that was part of a block of " + + "byte code that was outlined is still referred to in the original " + + "method." + }, + + + /* + * Note to translators: This message describes an internal error in the + * processor. The "method" that is being referred to is a Java method + * in a translet that XSLTC is generating. + * + */ + {ErrorMsg.OUTLINE_ERR_METHOD_TOO_BIG, + "Internal XSLTC error: a method in the translet exceeds the Java " + + "Virtual Machine limitation on the length of a method of 64 " + + "kilobytes. This is usually caused by templates in a stylesheet " + + "that are very large. Try restructuring your stylesheet to use " + + "smaller templates." + } + }; /** Get the lookup table for error messages. diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMsg.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMsg.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMsg.java Tue Apr 17 11:17:59 2012 -0700 @@ -157,6 +157,14 @@ public static final String INVALID_NCNAME_ERR = "INVALID_NCNAME_ERR"; public static final String INVALID_METHOD_IN_OUTPUT = "INVALID_METHOD_IN_OUTPUT"; + public static final String OUTLINE_ERR_TRY_CATCH = "OUTLINE_ERR_TRY_CATCH"; + public static final String OUTLINE_ERR_UNBALANCED_MARKERS = + "OUTLINE_ERR_UNBALANCED_MARKERS"; + public static final String OUTLINE_ERR_DELETED_TARGET = + "OUTLINE_ERR_DELETED_TARGET"; + public static final String OUTLINE_ERR_METHOD_TOO_BIG = + "OUTLINE_ERR_METHOD_TOO_BIG"; + // All error messages are localized and are stored in resource bundles. // This array and the following 4 strings are read from that bundle. private static ResourceBundle _bundle; @@ -261,7 +269,7 @@ */ public String toString() { String suffix = (_params == null) ? - (null != _code ? new String(getErrorMessage()) : _message) + (null != _code ? getErrorMessage() : _message) : MessageFormat.format(getErrorMessage(), _params); return formatLine() + suffix; } diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/InternalError.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/InternalError.java Tue Apr 17 11:17:59 2012 -0700 @@ -0,0 +1,37 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Copyright 2001-2004 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. + */ + +/* + * $Id: InternalError.java,v 1.0 2011-08-18 04:34:19 joehw Exp $ + */ +package com.sun.org.apache.xalan.internal.xsltc.compiler.util; +/** + * Marks a class of errors in which XSLTC has reached some incorrect internal + * state from which it cannot recover. + */ +public class InternalError extends Error { + /** + * Construct an InternalError with the specified error message. + * @param msg the error message + */ + public InternalError(String msg) { + super(msg); + } +} diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/MarkerInstruction.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/MarkerInstruction.java Tue Apr 17 11:17:59 2012 -0700 @@ -0,0 +1,98 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Copyright 2001-2004 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. + */ + +/* + * $Id: MethodGenerator.java,v 1.10 2010-11-01 04:34:19 joehw Exp $ + */ +package com.sun.org.apache.xalan.internal.xsltc.compiler.util; +import java.io.DataOutputStream; +import java.io.IOException; + +import com.sun.org.apache.bcel.internal.Constants; +import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen; +import com.sun.org.apache.bcel.internal.generic.Instruction; +import com.sun.org.apache.bcel.internal.generic.Visitor; + +/** + * A special abstract dummy subclass of + * {@link org.apache.bcel.generic.Instruction} used to mark locations of + * interest in an {@link com.sun.org.apache.bcel.internal.generic.InstructionList}. It and + * its subclasses are only used as placeholders, and do not contribute to the + * actual byte code instruction stream. + */ +abstract class MarkerInstruction extends Instruction { + /** + * Zero-argument constructor. Sets the opcode to an invalid value and + * sets the length to zero, as it will not be written as part of the + * generated byte code. + */ + public MarkerInstruction() { + super(Constants.UNDEFINED, (short) 0); + } + + /** + * {@link com.sun.org.apache.bcel.internal.generic.Visitor}s will know nothing about this + * kind of {@link org.apche.bcel.generic.Instruction}, so this method does + * nothing. + */ + public void accept(Visitor v) { + } + + /** + * The number of JVM stack entries consumed by the instruction. + * This instruction is just a place holder, so it does not consume any + * stack entries. + * @param cpg The {@link com.sun.org.apache.bcel.internal.generic.ConstantPoolGen} for the + * current {@link com.sun.org.apache.bcel.internal.generic.ClassGen} + * @return 0 always + */ + final public int consumeStack(ConstantPoolGen cpg) { + return 0; + } + /** + * The number of JVM stack entries produced by the instruction. + * This instruction is just a place holder, so it does not produce any + * stack entries. + * @param cpg The {@link com.sun.org.apache.bcel.internal.generic.ConstantPoolGen} for the + * current {@link com.sun.org.apache.bcel.internal.generic.ClassGen} + * @return 0 always + */ + final public int produceStack(ConstantPoolGen cpg) { + return 0; + } + + /** + * Produce a copy of the instruction. By default a + * {@link MarkerInstruction} has no parameters, so the base implementation + * of {@link #copy()} returns the instruction itself. + * @return The instruction itself. + */ + public Instruction copy() { + return this; + } + /** + * Dump instruction as byte code to stream out. A {@link MarkerInstruction} + * has no effect on the generated byte code so it is never emitted to the + * output stream. + * @param out Output stream + */ + final public void dump(DataOutputStream out) throws IOException { + } +} diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/MethodGenerator.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/MethodGenerator.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/MethodGenerator.java Tue Apr 17 11:17:59 2012 -0700 @@ -23,22 +23,57 @@ package com.sun.org.apache.xalan.internal.xsltc.compiler.util; -import java.util.Hashtable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; + import java.util.Hashtable; +import java.util.Iterator; +import java.util.Map; +import java.util.Stack; + +import com.sun.org.apache.bcel.internal.Constants; +import com.sun.org.apache.bcel.internal.classfile.Field; +import com.sun.org.apache.bcel.internal.classfile.Method; import com.sun.org.apache.bcel.internal.generic.ALOAD; import com.sun.org.apache.bcel.internal.generic.ASTORE; +import com.sun.org.apache.bcel.internal.generic.BranchHandle; +import com.sun.org.apache.bcel.internal.generic.BranchInstruction; import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen; +import com.sun.org.apache.bcel.internal.generic.DLOAD; +import com.sun.org.apache.bcel.internal.generic.DSTORE; +import com.sun.org.apache.bcel.internal.generic.FLOAD; +import com.sun.org.apache.bcel.internal.generic.FSTORE; +import com.sun.org.apache.bcel.internal.generic.GETFIELD; +import com.sun.org.apache.bcel.internal.generic.GOTO; import com.sun.org.apache.bcel.internal.generic.ICONST; +import com.sun.org.apache.bcel.internal.generic.IfInstruction; import com.sun.org.apache.bcel.internal.generic.ILOAD; +import com.sun.org.apache.bcel.internal.generic.IndexedInstruction; import com.sun.org.apache.bcel.internal.generic.INVOKEINTERFACE; +import com.sun.org.apache.bcel.internal.generic.INVOKESPECIAL; +import com.sun.org.apache.bcel.internal.generic.INVOKESTATIC; +import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL; import com.sun.org.apache.bcel.internal.generic.ISTORE; import com.sun.org.apache.bcel.internal.generic.Instruction; +import com.sun.org.apache.bcel.internal.generic.InstructionConstants; import com.sun.org.apache.bcel.internal.generic.InstructionHandle; import com.sun.org.apache.bcel.internal.generic.InstructionList; +import com.sun.org.apache.bcel.internal.generic.InstructionTargeter; import com.sun.org.apache.bcel.internal.generic.LocalVariableGen; +import com.sun.org.apache.bcel.internal.generic.LocalVariableInstruction; +import com.sun.org.apache.bcel.internal.generic.LLOAD; +import com.sun.org.apache.bcel.internal.generic.LSTORE; import com.sun.org.apache.bcel.internal.generic.MethodGen; +import com.sun.org.apache.bcel.internal.generic.NEW; +import com.sun.org.apache.bcel.internal.generic.PUTFIELD; +import com.sun.org.apache.bcel.internal.generic.RET; +import com.sun.org.apache.bcel.internal.generic.Select; +import com.sun.org.apache.bcel.internal.generic.TargetLostException; import com.sun.org.apache.bcel.internal.generic.Type; + import com.sun.org.apache.xalan.internal.xsltc.compiler.Pattern; +import com.sun.org.apache.xalan.internal.xsltc.compiler.XSLTC; /** * @author Jacek Ambroziak @@ -59,6 +94,13 @@ private static final int ITERATOR_INDEX = 2; private static final int HANDLER_INDEX = 3; + private static final int MAX_METHOD_SIZE = 65535; + private static final int MAX_BRANCH_TARGET_OFFSET = 32767; + private static final int MIN_BRANCH_TARGET_OFFSET = -32768; + + private static final int TARGET_METHOD_SIZE = 60000; + private static final int MINIMUM_OUTLINEABLE_CHUNK_SIZE = 1000; + private Instruction _iloadCurrent; private Instruction _istoreCurrent; private final Instruction _astoreHandler; @@ -82,6 +124,7 @@ private SlotAllocator _slotAllocator; private boolean _allocatorInit = false; + private LocalVariableRegistry _localVariableRegistry; /** * A mapping between patterns and instruction lists used by * test sequences to avoid compiling the same pattern multiple @@ -168,7 +211,7 @@ _nextNode = new INVOKEINTERFACE(index, 1); _slotAllocator = new SlotAllocator(); - _slotAllocator.initialize(getLocalVariables()); + _slotAllocator.initialize(getLocalVariableRegistry().getLocals(false)); _allocatorInit = true; } @@ -182,20 +225,364 @@ InstructionHandle start, InstructionHandle end) { - return (_allocatorInit) ? addLocalVariable2(name, type, start) - : super.addLocalVariable(name, type, start, end); + LocalVariableGen lvg; + + if (_allocatorInit) { + lvg = addLocalVariable2(name, type, start); + } else { + lvg = super.addLocalVariable(name, type, start, end); + getLocalVariableRegistry().registerLocalVariable(lvg); + } + return lvg; } public LocalVariableGen addLocalVariable2(String name, Type type, InstructionHandle start) { - return super.addLocalVariable(name, type, - _slotAllocator.allocateSlot(type), - start, null); + LocalVariableGen lvg = super.addLocalVariable(name, type, + _slotAllocator.allocateSlot(type), + start, null); + getLocalVariableRegistry().registerLocalVariable(lvg); + return lvg; + } + private LocalVariableRegistry getLocalVariableRegistry() { + if (_localVariableRegistry == null) { + _localVariableRegistry = new LocalVariableRegistry(); + } + + return _localVariableRegistry; + } + + /** + * Keeps track of all local variables used in the method. + *

The + * {@link MethodGen#addLocalVariable(String,Type,InstructionHandle,InstructionHandle)} + * and + * {@link MethodGen#addLocalVariable(String,Type,int,InstructionHandle,InstructionHandle)} + * methods of {@link MethodGen} will only keep track of + * {@link LocalVariableGen} object until it'ss removed by a call to + * {@link MethodGen#removeLocalVariable(LocalVariableGen)}.

+ *

In order to support efficient copying of local variables to outlined + * methods by + * {@link #outline(InstructionHandle,InstructionHandle,String,ClassGenerator)}, + * this class keeps track of all local variables defined by the method.

+ */ + protected class LocalVariableRegistry { + /** + *

A java.lang.ArrayList of all + * {@link LocalVariableGen}s created for this method, indexed by the + * slot number of the local variable. The JVM stack frame of local + * variables is divided into "slots". A single slot can be used to + * store more than one variable in a method, without regard to type, so + * long as the byte code keeps the ranges of the two disjoint.

+ *

If only one registration of use of a particular slot occurs, the + * corresponding entry of _variables contains the + * LocalVariableGen; if more than one occurs, the + * corresponding entry contains all such LocalVariableGens + * registered for the same slot; and if none occurs, the entry will be + * null. + */ + protected ArrayList _variables = new ArrayList(); + + /** + * Maps a name to a {@link LocalVariableGen} + */ + protected HashMap _nameToLVGMap = new HashMap(); + + /** + * Registers a {@link org.apache.bcel.generic.LocalVariableGen} + * for this method. + *

Preconditions: + *

    + *
  • The range of instructions for lvg does not + * overlap with the range of instructions for any + * LocalVariableGen with the same slot index previously + * registered for this method. (Unchecked.)
  • + *

+ * @param lvg The variable to be registered + */ + protected void registerLocalVariable(LocalVariableGen lvg) { + int slot = lvg.getIndex(); + + int registrySize = _variables.size(); + + // If the LocalVariableGen uses a slot index beyond any previously + // encountered, expand the _variables, padding with intervening null + // entries as required. + if (slot >= registrySize) { + for (int i = registrySize; i < slot; i++) { + _variables.add(null); + } + _variables.add(lvg); + } else { + // If the LocalVariableGen reuses a slot, make sure the entry + // in _variables contains an ArrayList and add the newly + // registered LocalVariableGen to the list. If the entry in + // _variables just contains null padding, store the + // LocalVariableGen directly. + Object localsInSlot = _variables.get(slot); + if (localsInSlot != null) { + if (localsInSlot instanceof LocalVariableGen) { + ArrayList listOfLocalsInSlot = new ArrayList(); + listOfLocalsInSlot.add(localsInSlot); + listOfLocalsInSlot.add(lvg); + _variables.set(slot, listOfLocalsInSlot); + } else { + ((ArrayList) localsInSlot).add(lvg); + } + } else { + _variables.set(slot, lvg); + } + } + + registerByName(lvg); + } + + /** + *

Find which {@link LocalVariableGen}, if any, is registered for a + * particular JVM local stack frame slot at a particular position in the + * byte code for the method.

+ *

Preconditions: + *

    + *
  • The {@link InstructionList#setPositions()} has been called for + * the {@link InstructionList} associated with this + * {@link MethodGenerator}.
  • + *

+ * @param slot the JVM local stack frame slot number + * @param offset the position in the byte code + * @return the LocalVariableGen for the local variable + * stored in the relevant slot at the relevant offset; null + * if there is none. + */ + protected LocalVariableGen lookupRegisteredLocalVariable(int slot, + int offset) { + Object localsInSlot = (_variables != null) ? _variables.get(slot) + : null; + + // If this slot index was never used, _variables.get will return + // null; if it was used once, it will return the LocalVariableGen; + // more than once it will return an ArrayList of all the + // LocalVariableGens for variables stored in that slot. For each + // LocalVariableGen, check whether its range includes the + // specified offset, and return the first such encountered. + if (localsInSlot != null) { + if (localsInSlot instanceof LocalVariableGen) { + LocalVariableGen lvg = (LocalVariableGen)localsInSlot; + if (offsetInLocalVariableGenRange(lvg, offset)) { + return lvg; + } + } else { + ArrayList listOfLocalsInSlot = (ArrayList) localsInSlot; + int size = listOfLocalsInSlot.size(); + + for (int i = 0; i < size; i++) { + LocalVariableGen lvg = + (LocalVariableGen)listOfLocalsInSlot.get(i); + if (offsetInLocalVariableGenRange(lvg, offset)) { + return lvg; + } + } + } + } + + // No local variable stored in the specified slot at the specified + return null; + } + + /** + *

Set up a mapping of the name of the specified + * {@link LocalVariableGen} object to the LocalVariableGen + * itself.

+ *

This is a bit of a hack. XSLTC is relying on the fact that the + * name that is being looked up won't be duplicated, which isn't + * guaranteed. It replaces code which used to call + * {@link MethodGen#getLocalVariables()} and looped through the + * LocalVariableGen objects it contained to find the one + * with the specified name. However, getLocalVariables() + * has the side effect of setting the start and end for any + * LocalVariableGen which did not already have them + * set, which causes problems for outlining..

+ *

See also {@link #lookUpByName(String)} and + * {@link #removeByNameTracking(LocalVariableGen)}

LocalVariableGen + */ + protected void registerByName(LocalVariableGen lvg) { + Object duplicateNameEntry = _nameToLVGMap.get(lvg.getName()); + + if (duplicateNameEntry == null) { + _nameToLVGMap.put(lvg.getName(), lvg); + } else { + ArrayList sameNameList; + + if (duplicateNameEntry instanceof ArrayList) { + sameNameList = (ArrayList) duplicateNameEntry; + sameNameList.add(lvg); + } else { + sameNameList = new ArrayList(); + sameNameList.add(duplicateNameEntry); + sameNameList.add(lvg); + } + + _nameToLVGMap.put(lvg.getName(), sameNameList); + } + } + + /** + * Remove the mapping from the name of the specified + * {@link LocalVariableGen} to itself. + * See also {@link #registerByName(LocalVariableGen)} and + * {@link #lookUpByName(String)} + * @param lvg a LocalVariableGen + */ + protected void removeByNameTracking(LocalVariableGen lvg) { + Object duplicateNameEntry = _nameToLVGMap.get(lvg.getName()); + + if (duplicateNameEntry instanceof ArrayList) { + ArrayList sameNameList = (ArrayList) duplicateNameEntry; + for (int i = 0; i < sameNameList.size(); i++) { + if (sameNameList.get(i) == lvg) { + sameNameList.remove(i); + break; + } + } + } else { + _nameToLVGMap.remove(lvg); + } + } + + /** + *

Given the name of a variable, finds a {@link LocalVariableGen} + * corresponding to it.

+ *

See also {@link #registerByName(LocalVariableGen)} and + * {@link #removeByNameTracking(LocalVariableGen)}

+ * @param name + * @return + */ + protected LocalVariableGen lookUpByName(String name) { + LocalVariableGen lvg = null; + Object duplicateNameEntry = _nameToLVGMap.get(name); + + if (duplicateNameEntry instanceof ArrayList) { + ArrayList sameNameList = (ArrayList) duplicateNameEntry; + + for (int i = 0; i < sameNameList.size(); i++) { + lvg = (LocalVariableGen)sameNameList.get(i); + if (lvg.getName() == name) { + break; + } + } + } else { + lvg = (LocalVariableGen) duplicateNameEntry; + } + + return lvg; + } + + /** + *

Gets all {@link LocalVariableGen} objects for this method.

+ *

When the includeRemoved argument has the value + * false, this method replaces uses of + * {@link MethodGen#getLocalVariables()} which has + * a side-effect of setting the start and end range for any + * LocalVariableGen if either was null. That + * side-effect causes problems for outlining of code in XSLTC. + * @param includeRemoved Specifies whether all local variables ever + * declared should be returned (true) or only those not + * removed (false) + * @return an array of LocalVariableGen containing all the + * local variables + */ + protected LocalVariableGen[] getLocals(boolean includeRemoved) { + LocalVariableGen[] locals = null; + ArrayList allVarsEverDeclared = new ArrayList(); + + if (includeRemoved) { + int slotCount = allVarsEverDeclared.size(); + + for (int i = 0; i < slotCount; i++) { + Object slotEntries = _variables.get(i); + if (slotEntries != null) { + if (slotEntries instanceof ArrayList) { + ArrayList slotList = (ArrayList) slotEntries; + + for (int j = 0; j < slotList.size(); j++) { + allVarsEverDeclared.add(slotList.get(i)); + } + } else { + allVarsEverDeclared.add(slotEntries); + } + } + } + } else { + Iterator nameVarsPairsIter = _nameToLVGMap.entrySet().iterator(); + + while (nameVarsPairsIter.hasNext()) { + Map.Entry nameVarsPair = + (Map.Entry) nameVarsPairsIter.next(); + Object vars = nameVarsPair.getValue(); + if (vars != null) { + if (vars instanceof ArrayList) { + ArrayList varsList = (ArrayList) vars; + for (int i = 0; i < varsList.size(); i++) { + allVarsEverDeclared.add(varsList.get(i)); + } + } else { + allVarsEverDeclared.add(vars); + } + } + } + } + + locals = new LocalVariableGen[allVarsEverDeclared.size()]; + allVarsEverDeclared.toArray(locals); + + return locals; + } + } + + /** + * Determines whether a particular variable is in use at a particular offset + * in the byte code for this method. + *

Preconditions: + *

    + *
  • The {@link InstructionList#setPositions()} has been called for the + * {@link InstructionList} associated with this {@link MethodGenerator}. + *

+ * @param lvg the {@link LocalVariableGen} for the variable + * @param offset the position in the byte code + * @return true if and only if the specified variable is in + * use at the particular byte code offset. + */ + boolean offsetInLocalVariableGenRange(LocalVariableGen lvg, int offset) { + InstructionHandle lvgStart = lvg.getStart(); + InstructionHandle lvgEnd = lvg.getEnd(); + + // If no start handle is recorded for the LocalVariableGen, it is + // assumed to be in use from the beginning of the method. + if (lvgStart == null) { + lvgStart = getInstructionList().getStart(); + } + + // If no end handle is recorded for the LocalVariableGen, it is assumed + // to be in use to the end of the method. + if (lvgEnd == null) { + lvgEnd = getInstructionList().getEnd(); + } + + // Does the range of the instruction include the specified offset? + // Note that the InstructionHandle.getPosition method returns the + // offset of the beginning of an instruction. A LocalVariableGen's + // range includes the end instruction itself, so that instruction's + // length must be taken into consideration in computing whether the + // varible is in range at a particular offset. + return ((lvgStart.getPosition() <= offset) + && (lvgEnd.getPosition() + + lvgEnd.getInstruction().getLength() >= offset)); } public void removeLocalVariable(LocalVariableGen lvg) { _slotAllocator.releaseSlot(lvg); + getLocalVariableRegistry().removeByNameTracking(lvg); super.removeLocalVariable(lvg); } @@ -294,11 +681,7 @@ } public LocalVariableGen getLocalVariable(String name) { - final LocalVariableGen[] vars = getLocalVariables(); - for (int i = 0; i < vars.length; i++) - if (vars[i].getName().equals(name)) - return vars[i]; - return null; + return getLocalVariableRegistry().lookUpByName(name); } public void setMaxLocals() { @@ -320,21 +703,1447 @@ super.setMaxLocals(maxLocals); } + /** + * Add a pre-compiled pattern to this mode. + */ + public void addInstructionList(Pattern pattern, InstructionList ilist) { + _preCompiled.put(pattern, ilist); + } + + /** + * Get the instruction list for a pre-compiled pattern. Used by + * test sequences to avoid compiling patterns more than once. + */ + public InstructionList getInstructionList(Pattern pattern) { + return (InstructionList) _preCompiled.get(pattern); + } + + /** + * Used to keep track of an outlineable chunk of instructions in the + * current method. See {@link OutlineableChunkStart} and + * {@link OutlineableChunkEnd} for more information. + */ + private class Chunk implements Comparable { /** - * Add a pre-compiled pattern to this mode. + * {@link InstructionHandle} of the first instruction in the outlineable + * chunk. + */ + private InstructionHandle m_start; + + /** + * {@link org.apache.bcel.generic.InstructionHandle} of the first + * instruction in the outlineable chunk. + */ + private InstructionHandle m_end; + + /** + * Number of bytes in the instructions contained in this outlineable + * chunk. */ - public void addInstructionList(Pattern pattern, - InstructionList ilist) - { - _preCompiled.put(pattern, ilist); + private int m_size; + + /** + *

Constructor for an outlineable {@link MethodGenerator.Chunk}.

+ *

Preconditions: + *

    + *
  • The {@link InstructionList#setPositions()} has been called for + * the {@link InstructionList} associated with this + * {@link MethodGenerator}.
  • + *

+ * @param start The {@link InstructionHandle} of the first + * instruction in the outlineable chunk. + * @param end The {@link InstructionHandle} of the last + * instruction in the outlineable chunk. + */ + Chunk(InstructionHandle start, InstructionHandle end) { + m_start = start; + m_end = end; + m_size = end.getPosition() - start.getPosition(); + } + + /** + * Determines whether this outlineable {@link MethodGenerator.Chunk} is + * followed immediately by the argument + * MethodGenerator.Chunk, with no other intervening + * instructions, including {@link OutlineableChunkStart} or + * {@link OutlineableChunkEnd} instructions. + * @param neighbour an outlineable {@link MethodGenerator.Chunk} + * @return true if and only if the argument chunk + * immediately follows this chunk + */ + boolean isAdjacentTo(Chunk neighbour) { + return getChunkEnd().getNext() == neighbour.getChunkStart(); + } + + /** + * Getter method for the start of this {@linke MethodGenerator.Chunk} + * @return the {@link org.apache.bcel.generic.InstructionHandle} of the + * start of this chunk + */ + InstructionHandle getChunkStart() { + return m_start; + } + + /** + * Getter method for the end of this {@link MethodGenerator.Chunk} + * @return the {@link InstructionHandle} of the start of this chunk + */ + InstructionHandle getChunkEnd() { + return m_end; + } + + /** + * The size of this {@link MethodGenerator.Chunk} + * @return the number of bytes in the byte code represented by this + * chunk. + */ + int getChunkSize() { + return m_size; } /** - * Get the instruction list for a pre-compiled pattern. Used by - * test sequences to avoid compiling patterns more than once. + * Implements the java.util.Comparable.compareTo(Object) + * method. + * @return + *
    + *
  • A positive int if the length of this + * chunk in bytes is greater than that of comparand
  • + *
  • A negative int if the length of this + * chunk in bytes is less than that of comparand
  • + *
  • Zero, otherwise.
  • + *
*/ - public InstructionList getInstructionList(Pattern pattern) { - return (InstructionList) _preCompiled.get(pattern); + public int compareTo(Object comparand) { + return getChunkSize() - ((Chunk)comparand).getChunkSize(); + } + } + + /** + * Find the outlineable chunks in this method that would be the best choices + * to outline, based on size and position in the method. + * @param classGen The {@link ClassGen} with which the generated methods + * will be associated + * @param totalMethodSize the size of the bytecode in the original method + * @return a java.util.ArrayList containing the + * {@link MethodGenerator.Chunk}s that may be outlined from this method + */ + private ArrayList getCandidateChunks(ClassGenerator classGen, + int totalMethodSize) { + Iterator instructions = getInstructionList().iterator(); + ArrayList candidateChunks = new ArrayList(); + ArrayList currLevelChunks = new ArrayList(); + Stack subChunkStack = new Stack(); + boolean openChunkAtCurrLevel = false; + boolean firstInstruction = true; + + InstructionHandle currentHandle; + + if (m_openChunks != 0) { + String msg = + (new ErrorMsg(ErrorMsg.OUTLINE_ERR_UNBALANCED_MARKERS)) + .toString(); + throw new InternalError(msg); + } + + // Scan instructions in the method, keeping track of the nesting level + // of outlineable chunks. + // + // currLevelChunks + // keeps track of the child chunks of a chunk. For each chunk, + // there will be a pair of entries: the InstructionHandles for the + // start and for the end of the chunk + // subChunkStack + // a stack containing the partially accumulated currLevelChunks for + // each chunk that's still open at the current position in the + // InstructionList. + // candidateChunks + // the list of chunks which have been accepted as candidates chunks + // for outlining + do { + // Get the next instruction. The loop will perform one extra + // iteration after it reaches the end of the InstructionList, with + // currentHandle set to null. + currentHandle = instructions.hasNext() + ? (InstructionHandle) instructions.next() + : null; + Instruction inst = + (currentHandle != null) ? currentHandle.getInstruction() + : null; + + // At the first iteration, create a chunk representing all the + // code in the method. This is done just to simplify the logic - + // this chunk can never be outlined because it will be too big. + if (firstInstruction) { + openChunkAtCurrLevel = true; + currLevelChunks.add(currentHandle); + firstInstruction = false; + } + + // Found a new chunk + if (inst instanceof OutlineableChunkStart) { + // If last MarkerInstruction encountered was an + // OutlineableChunkStart, this represents the first chunk + // nested within that previous chunk - push the list of chunks + // from the outer level onto the stack + if (openChunkAtCurrLevel) { + subChunkStack.push(currLevelChunks); + currLevelChunks = new ArrayList(); + } + + openChunkAtCurrLevel = true; + currLevelChunks.add(currentHandle); + // Close off an open chunk + } else if (currentHandle == null + || inst instanceof OutlineableChunkEnd) { + ArrayList nestedSubChunks = null; + + // If the last MarkerInstruction encountered was an + // OutlineableChunkEnd, it means that the current instruction + // marks the end of a chunk that contained child chunks. + // Those children might need to be examined below in case they + // are better candidates for outlining than the current chunk. + if (!openChunkAtCurrLevel) { + nestedSubChunks = currLevelChunks; + currLevelChunks = (ArrayList)subChunkStack.pop(); + } + + // Get the handle for the start of this chunk (the last entry + // in currLevelChunks) + InstructionHandle chunkStart = + (InstructionHandle) currLevelChunks.get( + currLevelChunks.size()-1); + + int chunkEndPosition = + (currentHandle != null) ? currentHandle.getPosition() + : totalMethodSize; + int chunkSize = chunkEndPosition - chunkStart.getPosition(); + + // Two ranges of chunk size to consider: + // + // 1. [0,TARGET_METHOD_SIZE] + // Keep this chunk in consideration as a candidate, + // and ignore its subchunks, if any - there's nothing to be + // gained by outlining both the current chunk and its + // children! + // + // 2. (TARGET_METHOD_SIZE,+infinity) + // Ignore this chunk - it's too big. Add its subchunks + // as candidates, after merging adjacent chunks to produce + // chunks that are as large as possible + if (chunkSize <= TARGET_METHOD_SIZE) { + currLevelChunks.add(currentHandle); + } else { + if (!openChunkAtCurrLevel) { + int childChunkCount = nestedSubChunks.size() / 2; + if (childChunkCount > 0) { + Chunk[] childChunks = new Chunk[childChunkCount]; + + // Gather all the child chunks of the current chunk + for (int i = 0; i < childChunkCount; i++) { + InstructionHandle start = + (InstructionHandle) nestedSubChunks + .get(i*2); + InstructionHandle end = + (InstructionHandle) nestedSubChunks + .get(i*2+1); + + childChunks[i] = new Chunk(start, end); + } + + // Merge adjacent siblings + ArrayList mergedChildChunks = + mergeAdjacentChunks(childChunks); + + // Add chunks that mean minimum size requirements + // to the list of candidate chunks for outlining + for (int i = 0; i < mergedChildChunks.size(); i++) { + Chunk mergedChunk = + (Chunk)mergedChildChunks.get(i); + int mergedSize = mergedChunk.getChunkSize(); + + if (mergedSize >= MINIMUM_OUTLINEABLE_CHUNK_SIZE + && mergedSize <= TARGET_METHOD_SIZE) { + candidateChunks.add(mergedChunk); + } + } + } + } + + // Drop the chunk which was too big + currLevelChunks.remove(currLevelChunks.size() - 1); + } + + // currLevelChunks contains pairs of InstructionHandles. If + // its size is an odd number, the loop has encountered the + // start of a chunk at this level, but not its end. + openChunkAtCurrLevel = ((currLevelChunks.size() & 0x1) == 1); + } + + } while (currentHandle != null); + + return candidateChunks; + } + + /** + * Merge adjacent sibling chunks to produce larger candidate chunks for + * outlining + * @param chunks array of sibling {@link MethodGenerator.Chunk}s that are + * under consideration for outlining. Chunks must be in + * the order encountered in the {@link InstructionList} + * @return a java.util.ArrayList of + * MethodGenerator.Chunks maximally merged + */ + private ArrayList mergeAdjacentChunks(Chunk[] chunks) { + int[] adjacencyRunStart = new int[chunks.length]; + int[] adjacencyRunLength = new int[chunks.length]; + boolean[] chunkWasMerged = new boolean[chunks.length]; + + int maximumRunOfChunks = 0; + int startOfCurrentRun; + int numAdjacentRuns = 0; + + ArrayList mergedChunks = new ArrayList(); + + startOfCurrentRun = 0; + + // Loop through chunks, and record in adjacencyRunStart where each + // run of adjacent chunks begins and how many are in that run. For + // example, given chunks A B C D E F, if A is adjacent to B, but not + // to C, and C, D, E and F are all adjacent, + // adjacencyRunStart[0] == 0; adjacencyRunLength[0] == 2 + // adjacencyRunStart[1] == 2; adjacencyRunLength[1] == 4 + for (int i = 1; i < chunks.length; i++) { + if (!chunks[i-1].isAdjacentTo(chunks[i])) { + int lengthOfRun = i - startOfCurrentRun; + + // Track the longest run of chunks found + if (maximumRunOfChunks < lengthOfRun) { + maximumRunOfChunks = lengthOfRun; + } + + if (lengthOfRun > 1 ) { + adjacencyRunLength[numAdjacentRuns] = lengthOfRun; + adjacencyRunStart[numAdjacentRuns] = startOfCurrentRun; + numAdjacentRuns++; + } + + startOfCurrentRun = i; + } + } + + if (chunks.length - startOfCurrentRun > 1) { + int lengthOfRun = chunks.length - startOfCurrentRun; + + // Track the longest run of chunks found + if (maximumRunOfChunks < lengthOfRun) { + maximumRunOfChunks = lengthOfRun; + } + + adjacencyRunLength[numAdjacentRuns] = + chunks.length - startOfCurrentRun; + adjacencyRunStart[numAdjacentRuns] = startOfCurrentRun; + numAdjacentRuns++; + } + + // Try merging adjacent chunks to come up with better sized chunks for + // outlining. This algorithm is not optimal, but it should be + // reasonably fast. Consider an example like this, where four chunks + // of the sizes specified in brackets are adjacent. The best way of + // combining these chunks would be to merge the first pair and merge + // the last three to form two chunks, but the algorithm will merge the + // three in the middle instead, leaving three chunks in all. + // [25000] [25000] [20000] [1000] [20000] + + // Start by trying to merge the maximum number of adjacent chunks, and + // work down from there. + for (int numToMerge = maximumRunOfChunks; numToMerge>1; numToMerge--) { + // Look at each run of adjacent chunks + for (int run = 0; run < numAdjacentRuns; run++) { + int runStart = adjacencyRunStart[run]; + int runEnd = runStart + adjacencyRunLength[run] - 1; + + boolean foundChunksToMerge = false; + + // Within the current run of adjacent chunks, look at all + // "subruns" of length numToMerge, until we run out or find + // a subrun that can be merged. + for (int mergeStart = runStart; + mergeStart+numToMerge-1 <= runEnd && !foundChunksToMerge; + mergeStart++) { + int mergeEnd = mergeStart + numToMerge - 1; + int mergeSize = 0; + + // Find out how big the subrun is + for (int j = mergeStart; j <= mergeEnd; j++) { + mergeSize = mergeSize + chunks[j].getChunkSize(); + } + + // If the current subrun is small enough to outline, + // merge it, and split the remaining chunks in the run + if (mergeSize <= TARGET_METHOD_SIZE) { + foundChunksToMerge = true; + + for (int j = mergeStart; j <= mergeEnd; j++) { + chunkWasMerged[j] = true; + } + + mergedChunks.add( + new Chunk(chunks[mergeStart].getChunkStart(), + chunks[mergeEnd].getChunkEnd())); + + // Adjust the length of the current run of adjacent + // chunks to end at the newly merged chunk... + adjacencyRunLength[run] = + adjacencyRunStart[run] - mergeStart; + + int trailingRunLength = runEnd - mergeEnd; + + // and any chunks that follow the newly merged chunk + // in the current run of adjacent chunks form another + // new run of adjacent chunks + if (trailingRunLength >= 2) { + adjacencyRunStart[numAdjacentRuns] = mergeEnd + 1; + adjacencyRunLength[numAdjacentRuns] = + trailingRunLength; + numAdjacentRuns++; + } + } + } + } + } + + // Make a final pass for any chunk that wasn't merged with a sibling + // and include it in the list of chunks after merging. + for (int i = 0; i < chunks.length; i++) { + if (!chunkWasMerged[i]) { + mergedChunks.add(chunks[i]); + } + } + + return mergedChunks; + } + + /** + * Breaks up the IL for this {@link MethodGenerator} into separate + * outlined methods so that no method exceeds the 64KB limit on the length + * of the byte code associated with a method. + * @param classGen The {@link ClassGen} with which the generated methods + * will be associated + * @param originalMethodSize The number of bytes of bytecode represented by + * the {@link InstructionList} of this method + * @return an array of the outlined Methods and the original + * method itself + */ + public Method[] outlineChunks(ClassGenerator classGen, + int originalMethodSize) { + ArrayList methodsOutlined = new ArrayList(); + int currentMethodSize = originalMethodSize; + + int outlinedCount = 0; + boolean moreMethodsOutlined; + String originalMethodName = getName(); + + // Special handling for initialization methods. No other methods can + // include the less than and greater than characters in their names, + // so we munge the names here. + if (originalMethodName.equals("")) { + originalMethodName = "$lt$init$gt$"; + } else if (originalMethodName.equals("")) { + originalMethodName = "$lt$clinit$gt$"; + } + + // Loop until the original method comes in under the JVM limit or + // the loop was unable to outline any more methods + do { + // Get all the best candidates for outlining, and sort them in + // ascending order of size + ArrayList candidateChunks = getCandidateChunks(classGen, + currentMethodSize); + Collections.sort(candidateChunks); + + moreMethodsOutlined = false; + + // Loop over the candidates for outlining, from the largest to the + // smallest and outline them one at a time, until the loop has + // outlined all or the original method comes in under the JVM + // limit on the size of a method. + for (int i = candidateChunks.size()-1; + i >= 0 && currentMethodSize > TARGET_METHOD_SIZE; + i--) { + Chunk chunkToOutline = (Chunk)candidateChunks.get(i); + + methodsOutlined.add(outline(chunkToOutline.getChunkStart(), + chunkToOutline.getChunkEnd(), + originalMethodName + "$outline$" + + outlinedCount, + classGen)); + outlinedCount++; + moreMethodsOutlined = true; + + InstructionList il = getInstructionList(); + InstructionHandle lastInst = il.getEnd(); + il.setPositions(); + + // Check the size of the method now + currentMethodSize = + lastInst.getPosition() + + lastInst.getInstruction().getLength(); + } + } while (moreMethodsOutlined && currentMethodSize > TARGET_METHOD_SIZE); + + // Outlining failed to reduce the size of the current method + // sufficiently. Throw an internal error. + if (currentMethodSize > MAX_METHOD_SIZE) { + String msg = (new ErrorMsg(ErrorMsg.OUTLINE_ERR_METHOD_TOO_BIG)) + .toString(); + throw new InternalError(msg); + } + + Method[] methodsArr = new Method[methodsOutlined.size() + 1]; + methodsOutlined.toArray(methodsArr); + + methodsArr[methodsOutlined.size()] = getThisMethod(); + + return methodsArr; + } + + /** + * Given an outlineable chunk of code in the current {@link MethodGenerator} + * move ("outline") the chunk to a new method, and replace the chunk in the + * old method with a reference to that new method. No + * {@link OutlineableChunkStart} or {@link OutlineableChunkEnd} instructions + * are copied. + * @param first The {@link InstructionHandle} of the first instruction in + * the chunk to outline + * @param last The InstructionHandle of the last instruction in + * the chunk to outline + * @param outlinedMethodName The name of the new method + * @param classGen The {@link ClassGenerator} of which the original + * and new methods will be members + * @return The new {@link Method} containing the outlined code. + */ + private Method outline(InstructionHandle first, InstructionHandle last, + String outlinedMethodName, ClassGenerator classGen) { + // We're not equipped to deal with exception handlers yet. Bail out! + if (getExceptionHandlers().length != 0) { + String msg = (new ErrorMsg(ErrorMsg.OUTLINE_ERR_TRY_CATCH)) + .toString(); + throw new InternalError(msg); + } + + int outlineChunkStartOffset = first.getPosition(); + int outlineChunkEndOffset = last.getPosition() + + last.getInstruction().getLength(); + + ConstantPoolGen cpg = getConstantPool(); + + // Create new outlined method with signature: + // + // private final outlinedMethodName(CopyLocals copyLocals); + // + // CopyLocals is an object that is used to copy-in/copy-out local + // variables that are used by the outlined method. Only locals whose + // value is potentially set or referenced outside the range of the + // chunk that is being outlined will be represented in CopyLocals. The + // type of the variable for copying local variables is actually + // generated to be unique - it is not named CopyLocals. + // + // The outlined method never needs to be referenced outside of this + // class, and will never be overridden, so we mark it private final. + final InstructionList newIL = new InstructionList(); + + final XSLTC xsltc = classGen.getParser().getXSLTC(); + final String argTypeName = xsltc.getHelperClassName(); + final Type[] argTypes = + new Type[] {(new ObjectType(argTypeName)).toJCType()}; + final String argName = "copyLocals"; + final String[] argNames = new String[] {argName}; + + int methodAttributes = ACC_PRIVATE | ACC_FINAL; + final boolean isStaticMethod = (getAccessFlags() & ACC_STATIC) != 0; + + if (isStaticMethod) { + methodAttributes = methodAttributes | ACC_STATIC; + } + + final MethodGenerator outlinedMethodGen = + new MethodGenerator(methodAttributes, + com.sun.org.apache.bcel.internal.generic.Type.VOID, + argTypes, argNames, outlinedMethodName, + getClassName(), newIL, cpg); + + // Create class for copying local variables to the outlined method. + // The fields the class will need to contain will be determined as the + // code in the outlineable chunk is examined. + ClassGenerator copyAreaCG + = new ClassGenerator(argTypeName, OBJECT_CLASS, argTypeName+".java", + ACC_FINAL | ACC_PUBLIC | ACC_SUPER, null, + classGen.getStylesheet()) { + public boolean isExternal() { + return true; + } + }; + ConstantPoolGen copyAreaCPG = copyAreaCG.getConstantPool(); + copyAreaCG.addEmptyConstructor(ACC_PUBLIC); + + // Number of fields in the copy class + int copyAreaFieldCount = 0; + + // The handle for the instruction after the last one to be outlined. + // Note that this should never end up being null. An outlineable chunk + // won't contain a RETURN instruction or other branch out of the chunk, + // and the JVM specification prohibits code in a method from just + // "falling off the end" so this should always point to a valid handle. + InstructionHandle limit = last.getNext(); + + // InstructionLists for copying values into and out of an instance of + // CopyLocals: + // oldMethCoypInIL - from locals in old method into an instance + // of the CopyLocals class (oldMethCopyInIL) + // oldMethCopyOutIL - from CopyLocals back into locals in the old + // method + // newMethCopyInIL - from CopyLocals into locals in the new + // method + // newMethCopyOutIL - from locals in new method into the instance + // of the CopyLocals class + InstructionList oldMethCopyInIL = new InstructionList(); + InstructionList oldMethCopyOutIL = new InstructionList(); + InstructionList newMethCopyInIL = new InstructionList(); + InstructionList newMethCopyOutIL = new InstructionList(); + + // Allocate instance of class in which we'll copy in or copy out locals + // and make two copies: last copy is used to invoke constructor; + // other two are used for references to fields in the CopyLocals object + InstructionHandle outlinedMethodCallSetup = + oldMethCopyInIL.append(new NEW(cpg.addClass(argTypeName))); + oldMethCopyInIL.append(InstructionConstants.DUP); + oldMethCopyInIL.append(InstructionConstants.DUP); + oldMethCopyInIL.append( + new INVOKESPECIAL(cpg.addMethodref(argTypeName, "", "()V"))); + + // Generate code to invoke the new outlined method, and place the code + // on oldMethCopyOutIL + InstructionHandle outlinedMethodRef; + + if (isStaticMethod) { + outlinedMethodRef = + oldMethCopyOutIL.append( + new INVOKESTATIC(cpg.addMethodref( + classGen.getClassName(), + outlinedMethodName, + outlinedMethodGen.getSignature()))); + } else { + oldMethCopyOutIL.append(InstructionConstants.THIS); + oldMethCopyOutIL.append(InstructionConstants.SWAP); + outlinedMethodRef = + oldMethCopyOutIL.append( + new INVOKEVIRTUAL(cpg.addMethodref( + classGen.getClassName(), + outlinedMethodName, + outlinedMethodGen.getSignature()))); } + // Used to keep track of the first in a sequence of + // OutlineableChunkStart instructions + boolean chunkStartTargetMappingsPending = false; + InstructionHandle pendingTargetMappingHandle = null; + + // Used to keep track of the last instruction that was copied + InstructionHandle lastCopyHandle = null; + + // Keeps track of the mapping from instruction handles in the old + // method to instruction handles in the outlined method. Only need + // to track instructions that are targeted by something else in the + // generated BCEL + HashMap targetMap = new HashMap(); + + // Keeps track of the mapping from local variables in the old method + // to local variables in the outlined method. + HashMap localVarMap = new HashMap(); + + HashMap revisedLocalVarStart = new HashMap(); + HashMap revisedLocalVarEnd = new HashMap(); + + // Pass 1: Make copies of all instructions, append them to the new list + // and associate old instruction references with the new ones, i.e., + // a 1:1 mapping. The special marker instructions are not copied. + // Also, identify local variables whose values need to be copied into or + // out of the new outlined method, and builds up targetMap and + // localVarMap as described above. The code identifies those local + // variables first so that they can have fixed slots in the stack + // frame for the outlined method assigned them ahead of all those + // variables that don't need to exist for the entirety of the outlined + // method invocation. + for (InstructionHandle ih = first; ih != limit; ih = ih.getNext()) { + Instruction inst = ih.getInstruction(); + + // MarkerInstructions are not copied, so if something else targets + // one, the targetMap will point to the nearest copied sibling + // InstructionHandle: for an OutlineableChunkEnd, the nearest + // preceding sibling; for an OutlineableChunkStart, the nearest + // following sibling. + if (inst instanceof MarkerInstruction) { + if (ih.hasTargeters()) { + if (inst instanceof OutlineableChunkEnd) { + targetMap.put(ih, lastCopyHandle); + } else { + if (!chunkStartTargetMappingsPending) { + chunkStartTargetMappingsPending = true; + pendingTargetMappingHandle = ih; + } + } + } + } else { + // Copy the instruction and append it to the outlined method's + // InstructionList. + Instruction c = inst.copy(); // Use clone for shallow copy + + if (c instanceof BranchInstruction) { + lastCopyHandle = newIL.append((BranchInstruction)c); + } else { + lastCopyHandle = newIL.append(c); + } + + if (c instanceof LocalVariableInstruction + || c instanceof RET) { + // For any instruction that touches a local variable, + // check whether the local variable's value needs to be + // copied into or out of the outlined method. If so, + // generate the code to perform the necessary copying, and + // use localVarMap to map the variable in the original + // method to the variable in the new method. + IndexedInstruction lvi = (IndexedInstruction)c; + int oldLocalVarIndex = lvi.getIndex(); + LocalVariableGen oldLVG = + getLocalVariableRegistry() + .lookupRegisteredLocalVariable(oldLocalVarIndex, + ih.getPosition()); + LocalVariableGen newLVG = + (LocalVariableGen)localVarMap.get(oldLVG); + + // Has the code already mapped this local variable to a + // local in the new method? + if (localVarMap.get(oldLVG) == null) { + // Determine whether the local variable needs to be + // copied into or out of the outlined by checking + // whether the range of instructions in which the + // variable is accessible is outside the range of + // instructions in the outlineable chunk. + // Special case a chunk start offset of zero: a local + // variable live at that position must be a method + // parameter, so the code doesn't need to check whether + // the variable is live before that point; being live + // at offset zero is sufficient to know that the value + // must be copied in to the outlined method. + boolean copyInLocalValue = + offsetInLocalVariableGenRange(oldLVG, + (outlineChunkStartOffset != 0) + ? outlineChunkStartOffset-1 + : 0); + boolean copyOutLocalValue = + offsetInLocalVariableGenRange(oldLVG, + outlineChunkEndOffset+1); + + // For any variable that needs to be copied into or out + // of the outlined method, create a field in the + // CopyLocals class, and generate the necessary code for + // copying the value. + if (copyInLocalValue || copyOutLocalValue) { + String varName = oldLVG.getName(); + Type varType = oldLVG.getType(); + newLVG = outlinedMethodGen.addLocalVariable(varName, + varType, + null, + null); + int newLocalVarIndex = newLVG.getIndex(); + String varSignature = varType.getSignature(); + + // Record the mapping from the old local to the new + localVarMap.put(oldLVG, newLVG); + + copyAreaFieldCount++; + String copyAreaFieldName = + "field" + copyAreaFieldCount; + copyAreaCG.addField( + new Field(ACC_PUBLIC, + copyAreaCPG.addUtf8(copyAreaFieldName), + copyAreaCPG.addUtf8(varSignature), + null, copyAreaCPG.getConstantPool())); + + int fieldRef = cpg.addFieldref(argTypeName, + copyAreaFieldName, + varSignature); + + if (copyInLocalValue) { + // Generate code for the old method to store the + // value of the local into the correct field in + // CopyLocals prior to invocation of the + // outlined method. + oldMethCopyInIL.append( + InstructionConstants.DUP); + InstructionHandle copyInLoad = + oldMethCopyInIL.append( + loadLocal(oldLocalVarIndex, varType)); + oldMethCopyInIL.append(new PUTFIELD(fieldRef)); + + // If the end of the live range of the old + // variable was in the middle of the outlined + // chunk. Make the load of its value the new + // end of its range. + if (!copyOutLocalValue) { + revisedLocalVarEnd.put(oldLVG, copyInLoad); + } + + // Generate code for start of the outlined + // method to copy the value from a field in + // CopyLocals to the new local in the outlined + // method + newMethCopyInIL.append( + InstructionConstants.ALOAD_1); + newMethCopyInIL.append(new GETFIELD(fieldRef)); + newMethCopyInIL.append( + storeLocal(newLocalVarIndex, varType)); + } + + if (copyOutLocalValue) { + // Generate code for the end of the outlined + // method to copy the value from the new local + // variable into a field in CopyLocals + // method + newMethCopyOutIL.append( + InstructionConstants.ALOAD_1); + newMethCopyOutIL.append( + loadLocal(newLocalVarIndex, varType)); + newMethCopyOutIL.append(new PUTFIELD(fieldRef)); + + // Generate code to copy the value from a field + // in CopyLocals into a local in the original + // method following invocation of the outlined + // method. + oldMethCopyOutIL.append( + InstructionConstants.DUP); + oldMethCopyOutIL.append(new GETFIELD(fieldRef)); + InstructionHandle copyOutStore = + oldMethCopyOutIL.append( + storeLocal(oldLocalVarIndex, varType)); + + // If the start of the live range of the old + // variable was in the middle of the outlined + // chunk. Make this store into it the new start + // of its range. + if (!copyInLocalValue) { + revisedLocalVarStart.put(oldLVG, + copyOutStore); + } + } + } + } + } + + if (ih.hasTargeters()) { + targetMap.put(ih, lastCopyHandle); + } + + // If this is the first instruction copied following a sequence + // of OutlineableChunkStart instructions, indicate that the + // sequence of old instruction all map to this newly created + // instruction + if (chunkStartTargetMappingsPending) { + do { + targetMap.put(pendingTargetMappingHandle, + lastCopyHandle); + pendingTargetMappingHandle = + pendingTargetMappingHandle.getNext(); + } while(pendingTargetMappingHandle != ih); + + chunkStartTargetMappingsPending = false; + } + } + } + + // Pass 2: Walk old and new instruction lists, updating branch targets + // and local variable references in the new list + InstructionHandle ih = first; + InstructionHandle ch = newIL.getStart(); + + while (ch != null) { + // i == old instruction; c == copied instruction + Instruction i = ih.getInstruction(); + Instruction c = ch.getInstruction(); + + if (i instanceof BranchInstruction) { + BranchInstruction bc = (BranchInstruction)c; + BranchInstruction bi = (BranchInstruction)i; + InstructionHandle itarget = bi.getTarget(); // old target + + // New target must be in targetMap + InstructionHandle newTarget = + (InstructionHandle)targetMap.get(itarget); + + bc.setTarget(newTarget); + + // Handle LOOKUPSWITCH or TABLESWITCH which may have many + // target instructions + if (bi instanceof Select) { + InstructionHandle[] itargets = ((Select)bi).getTargets(); + InstructionHandle[] ctargets = ((Select)bc).getTargets(); + + // Update all targets + for (int j=0; j < itargets.length; j++) { + ctargets[j] = + (InstructionHandle)targetMap.get(itargets[j]); + } + } + } else if (i instanceof LocalVariableInstruction + || i instanceof RET) { + // For any instruction that touches a local variable, + // map the location of the variable in the original + // method to its location in the new method. + IndexedInstruction lvi = (IndexedInstruction)c; + int oldLocalVarIndex = lvi.getIndex(); + LocalVariableGen oldLVG = + getLocalVariableRegistry() + .lookupRegisteredLocalVariable(oldLocalVarIndex, + ih.getPosition()); + LocalVariableGen newLVG = + (LocalVariableGen)localVarMap.get(oldLVG); + int newLocalVarIndex; + + if (newLVG == null) { + // Create new variable based on old variable - use same + // name and type, but we will let the variable be active + // for the entire outlined method. + // LocalVariableGen oldLocal = oldLocals[oldLocalVarIndex]; + String varName = oldLVG.getName(); + Type varType = oldLVG.getType(); + newLVG = outlinedMethodGen.addLocalVariable(varName, + varType, + null, + null); + newLocalVarIndex = newLVG.getIndex(); + localVarMap.put(oldLVG, newLVG); + + // The old variable's live range was wholly contained in + // the outlined chunk. There should no longer be stores + // of values into it or loads of its value, so we can just + // mark its live range as the reference to the outlined + // method. + revisedLocalVarStart.put(oldLVG, outlinedMethodRef); + revisedLocalVarEnd.put(oldLVG, outlinedMethodRef); + } else { + newLocalVarIndex = newLVG.getIndex(); + } + lvi.setIndex(newLocalVarIndex); + } + + // If the old instruction marks the end of the range of a local + // variable, make sure that any slots on the stack reserved for + // local variables are made available for reuse by calling + // MethodGenerator.removeLocalVariable + if (ih.hasTargeters()) { + InstructionTargeter[] targeters = ih.getTargeters(); + + for (int idx = 0; idx < targeters.length; idx++) { + InstructionTargeter targeter = targeters[idx]; + + if (targeter instanceof LocalVariableGen + && ((LocalVariableGen)targeter).getEnd()==ih) { + Object newLVG = localVarMap.get(targeter); + if (newLVG != null) { + outlinedMethodGen.removeLocalVariable( + (LocalVariableGen)newLVG); + } + } + } + } + + // If the current instruction in the original list was a marker, + // it wasn't copied, so don't advance through the list of copied + // instructions yet. + if (!(i instanceof MarkerInstruction)) { + ch = ch.getNext(); + } + ih = ih.getNext(); + + } + + // POP the reference to the CopyLocals object from the stack + oldMethCopyOutIL.append(InstructionConstants.POP); + + // Now that the generation of the outlined code is complete, update + // the old local variables with new start and end ranges, as required. + Iterator revisedLocalVarStartPairIter = revisedLocalVarStart.entrySet() + .iterator(); + while (revisedLocalVarStartPairIter.hasNext()) { + Map.Entry lvgRangeStartPair = + (Map.Entry)revisedLocalVarStartPairIter.next(); + LocalVariableGen lvg = (LocalVariableGen)lvgRangeStartPair.getKey(); + InstructionHandle startInst = + (InstructionHandle)lvgRangeStartPair.getValue(); + + lvg.setStart(startInst); + + } + + Iterator revisedLocalVarEndPairIter = revisedLocalVarEnd.entrySet() + .iterator(); + while (revisedLocalVarEndPairIter.hasNext()) { + Map.Entry lvgRangeEndPair = + (Map.Entry)revisedLocalVarEndPairIter.next(); + LocalVariableGen lvg = (LocalVariableGen)lvgRangeEndPair.getKey(); + InstructionHandle endInst = + (InstructionHandle)lvgRangeEndPair.getValue(); + + lvg.setEnd(endInst); + } + + xsltc.dumpClass(copyAreaCG.getJavaClass()); + + // Assemble the instruction lists so that the old method invokes the + // new outlined method + InstructionList oldMethodIL = getInstructionList(); + + oldMethodIL.insert(first, oldMethCopyInIL); + oldMethodIL.insert(first, oldMethCopyOutIL); + + // Insert the copying code into the outlined method + newIL.insert(newMethCopyInIL); + newIL.append(newMethCopyOutIL); + newIL.append(InstructionConstants.RETURN); + + // Discard instructions in outlineable chunk from old method + try { + oldMethodIL.delete(first, last); + } catch (TargetLostException e) { + InstructionHandle[] targets = e.getTargets(); + // If there were still references to old instructions lingering, + // clean those up. The only instructions targetting the deleted + // instructions should have been part of the chunk that was just + // deleted, except that instructions might branch to the start of + // the outlined chunk; similarly, all the live ranges of local + // variables should have been adjusted, except for unreferenced + // variables. + for (int i = 0; i < targets.length; i++) { + InstructionHandle lostTarget = targets[i]; + InstructionTargeter[] targeters = lostTarget.getTargeters(); + for (int j = 0; j < targeters.length; j++) { + if (targeters[j] instanceof LocalVariableGen) { + LocalVariableGen lvgTargeter = + (LocalVariableGen) targeters[j]; + // In the case of any lingering variable references, + // just make the live range point to the outlined + // function reference. Such variables should be unused + // anyway. + if (lvgTargeter.getStart() == lostTarget) { + lvgTargeter.setStart(outlinedMethodRef); + } + if (lvgTargeter.getEnd() == lostTarget) { + lvgTargeter.setEnd(outlinedMethodRef); + } + } else { + targeters[j].updateTarget(lostTarget, + outlinedMethodCallSetup); + } + } + } + } + + // Make a copy for the new method of all exceptions that might be thrown + String[] exceptions = getExceptions(); + for (int i = 0; i < exceptions.length; i++) { + outlinedMethodGen.addException(exceptions[i]); + } + + return outlinedMethodGen.getThisMethod(); + } + + /** + * Helper method to generate an instance of a subclass of + * {@link LoadInstruction} based on the specified {@link Type} that will + * load the specified local variable + * @param index the JVM stack frame index of the variable that is to be + * loaded + * @param type the {@link Type} of the variable + * @return the generated {@link LoadInstruction} + */ + private static Instruction loadLocal(int index, Type type) { + if (type == Type.BOOLEAN) { + return new ILOAD(index); + } else if (type == Type.INT) { + return new ILOAD(index); + } else if (type == Type.SHORT) { + return new ILOAD(index); + } else if (type == Type.LONG) { + return new LLOAD(index); + } else if (type == Type.BYTE) { + return new ILOAD(index); + } else if (type == Type.CHAR) { + return new ILOAD(index); + } else if (type == Type.FLOAT) { + return new FLOAD(index); + } else if (type == Type.DOUBLE) { + return new DLOAD(index); + } else { + return new ALOAD(index); + } + } + + /** + * Helper method to generate an instance of a subclass of + * {@link StoreInstruction} based on the specified {@link Type} that will + * store a value in the specified local variable + * @param index the JVM stack frame index of the variable that is to be + * stored + * @param type the {@link Type} of the variable + * @return the generated {@link StoredInstruction} + */ + private static Instruction storeLocal(int index, Type type) { + if (type == Type.BOOLEAN) { + return new ISTORE(index); + } else if (type == Type.INT) { + return new ISTORE(index); + } else if (type == Type.SHORT) { + return new ISTORE(index); + } else if (type == Type.LONG) { + return new LSTORE(index); + } else if (type == Type.BYTE) { + return new ISTORE(index); + } else if (type == Type.CHAR) { + return new ISTORE(index); + } else if (type == Type.FLOAT) { + return new FSTORE(index); + } else if (type == Type.DOUBLE) { + return new DSTORE(index); + } else { + return new ASTORE(index); + } + } + + /** + * Track the number of outlineable chunks seen. + */ + private int m_totalChunks = 0; + + /** + * Track the number of outlineable chunks started but not yet ended. Used + * to detect imbalances in byte code generation. + */ + private int m_openChunks = 0; + + /** + * Mark the end of the method's + * {@link InstructionList} as the start of an outlineable chunk of code. + * The outlineable chunk begins after the {@link InstructionHandle} that is + * at the end of the method's {@link InstructionList}, or at the start of + * the method if the InstructionList is empty. + * See {@link OutlineableChunkStart} for more information. + */ + public void markChunkStart() { + // m_chunkTree.markChunkStart(); + getInstructionList() + .append(OutlineableChunkStart.OUTLINEABLECHUNKSTART); + m_totalChunks++; + m_openChunks++; + } + + /** + * Mark the end of an outlineable chunk of code. See + * {@link OutlineableChunkStart} for more information. + */ + public void markChunkEnd() { + // m_chunkTree.markChunkEnd(); + getInstructionList() + .append(OutlineableChunkEnd.OUTLINEABLECHUNKEND); + m_openChunks--; + if (m_openChunks < 0) { + String msg = (new ErrorMsg(ErrorMsg.OUTLINE_ERR_UNBALANCED_MARKERS)) + .toString(); + throw new InternalError(msg); + } + } + + /** + *

Get all {@link Method}s generated by this {@link MethodGenerator}. + * The {@link MethodGen#getMethod()} only returns a single + * Method object. This method takes into account the Java + * Virtual Machine Specification limit of 64KB on the size of a method, and + * may return more than one Method.

+ *

If the code associated with the MethodGenerator would + * exceed the 64KB limit, this method will attempt to split the code in + * the {@link InstructionList} associated with this + * MethodGenerator into several methods.

+ * @param classGen the {@link ClassGenerator} of which these methods are + * members + * @return an array of all the Methods generated + */ + Method[] getGeneratedMethods(ClassGenerator classGen) { + Method[] generatedMethods; + InstructionList il = getInstructionList(); + InstructionHandle last = il.getEnd(); + + il.setPositions(); + + int instructionListSize = + last.getPosition() + last.getInstruction().getLength(); + + // Need to look for any branch target offsets that exceed the range + // [-32768,32767] + if (instructionListSize > MAX_BRANCH_TARGET_OFFSET) { + boolean ilChanged = widenConditionalBranchTargetOffsets(); + + // If any branch instructions needed widening, recompute the size + // of the byte code for the method + if (ilChanged) { + il.setPositions(); + last = il.getEnd(); + instructionListSize = + last.getPosition() + last.getInstruction().getLength(); + } + } + + if (instructionListSize > MAX_METHOD_SIZE) { + generatedMethods = outlineChunks(classGen, instructionListSize); + } else { + generatedMethods = new Method[] {getThisMethod()}; + } + return generatedMethods; + } + + protected Method getThisMethod() { + stripAttributes(true); + setMaxLocals(); + setMaxStack(); + removeNOPs(); + + return getMethod(); + } + /** + *

Rewrites branches to avoid the JVM limits of relative branch + * offsets. There is no need to invoke this method if the bytecode for the + * {@link MethodGenerator} does not exceed 32KB.

+ *

The Java Virtual Machine Specification permits the code portion of a + * method to be up to 64KB in length. However, some control transfer + * instructions specify relative offsets as a signed 16-bit quantity, + * limiting the range to a subset of the instructions that might be in a + * method.

+ *

The TABLESWITCH and LOOKUPSWITCH + * instructions always use 32-bit signed relative offsets, so they are + * immune to this problem.

+ *

The GOTO and JSR + * instructions come in two forms, one of which uses 16-bit relative + * offsets, and the other of which uses 32-bit relative offsets. The BCEL + * library decides whether to use the wide form of GOTO or + * JSRinstructions based on the relative offset of the target + * of the instruction without any intervention by the user of the + * library.

+ *

This leaves the various conditional branch instructions, + * IFEQ, IFNULL, IF_ICMPEQ, + * et al., all of which use 16-bit signed relative offsets, with no + * 32-bit wide form available.

+ *

This method scans the {@link InstructionList} associated with this + * {@link MethodGenerator} and finds all conditional branch instructions + * that might exceed the 16-bit limitation for relative branch offsets. + * The logic of each such instruction is inverted, and made to target the + * instruction which follows it. An unconditional branch to the original + * target of the instruction is then inserted between the conditional + * branch and the instruction which previously followed it. The + * unconditional branch is permitted to have a 16-bit or a 32-bit relative + * offset, as described above. For example, + * + * 1234: NOP + * ... + * 55278: IFEQ -54044 + * 55280: NOP + * + * is rewritten as + * + * 1234: NOP + * ... + * 55278: IFNE 7 + * 55280: GOTO_W -54046 + * 55285: NOP + *

+ *

Preconditions: + *

  • The {@link InstructionList#setPositions()} has been called for + * the InstructionList associated with this + * MethodGenerator. + *

+ *

Postconditions: + *

  • Any further changes to the InstructionList for this + * MethodGenerator will invalidate the changes made by this + * method.
+ *

+ * @return true if the InstructionList was + * modified; false otherwise + * @see The Java Virtual Machine Specification, Second Edition + */ + boolean widenConditionalBranchTargetOffsets() { + boolean ilChanged = false; + int maxOffsetChange = 0; + InstructionList il = getInstructionList(); + + // Loop through all the instructions, finding those that would be + // affected by inserting new instructions in the InstructionList, and + // calculating the maximum amount by which the relative offset between + // two instructions could possibly change. + // In part this loop duplicates code in + // org.apache.bcel.generic.InstructionList.setPosition(), which does + // this to determine whether to use 16-bit or 32-bit offsets for GOTO + // and JSR instructions. Ideally, that method would do the same for + // conditional branch instructions, but it doesn't, so we duplicate the + // processing here. + for (InstructionHandle ih = il.getStart(); + ih != null; + ih = ih.getNext()) { + Instruction inst = ih.getInstruction(); + + switch (inst.getOpcode()) { + // Instructions that may have 16-bit or 32-bit branch targets. + // The size of the branch offset might increase by two bytes. + case Constants.GOTO: + case Constants.JSR: + maxOffsetChange = maxOffsetChange + 2; + break; + // Instructions that contain padding for alignment purposes + // Up to three bytes of padding might be needed. For greater + // accuracy, we should be able to discount any padding already + // added to these instructions by InstructionList.setPosition(), + // their APIs do not expose that information. + case Constants.TABLESWITCH: + case Constants.LOOKUPSWITCH: + maxOffsetChange = maxOffsetChange + 3; + break; + // Instructions that might be rewritten by this method as a + // conditional branch followed by an unconditional branch. + // The unconditional branch would require five bytes. + case Constants.IF_ACMPEQ: + case Constants.IF_ACMPNE: + case Constants.IF_ICMPEQ: + case Constants.IF_ICMPGE: + case Constants.IF_ICMPGT: + case Constants.IF_ICMPLE: + case Constants.IF_ICMPLT: + case Constants.IF_ICMPNE: + case Constants.IFEQ: + case Constants.IFGE: + case Constants.IFGT: + case Constants.IFLE: + case Constants.IFLT: + case Constants.IFNE: + case Constants.IFNONNULL: + case Constants.IFNULL: + maxOffsetChange = maxOffsetChange + 5; + break; + } + } + + // Now that the maximum number of bytes by which the method might grow + // has been determined, look for conditional branches to see which + // might possibly exceed the 16-bit relative offset. + for (InstructionHandle ih = il.getStart(); + ih != null; + ih = ih.getNext()) { + Instruction inst = ih.getInstruction(); + + if (inst instanceof IfInstruction) { + IfInstruction oldIfInst = (IfInstruction)inst; + BranchHandle oldIfHandle = (BranchHandle)ih; + InstructionHandle target = oldIfInst.getTarget(); + int relativeTargetOffset = target.getPosition() + - oldIfHandle.getPosition(); + + // Consider the worst case scenario in which the conditional + // branch and its target are separated by all the instructions + // in the method that might increase in size. If that results + // in a relative offset that cannot be represented as a 32-bit + // signed quantity, rewrite the instruction as described above. + if ((relativeTargetOffset - maxOffsetChange + < MIN_BRANCH_TARGET_OFFSET) + || (relativeTargetOffset + maxOffsetChange + > MAX_BRANCH_TARGET_OFFSET)) { + // Invert the logic of the IF instruction, and append + // that to the InstructionList following the original IF + // instruction + InstructionHandle nextHandle = oldIfHandle.getNext(); + IfInstruction invertedIfInst = oldIfInst.negate(); + BranchHandle invertedIfHandle = il.append(oldIfHandle, + invertedIfInst); + + // Append an unconditional branch to the target of the + // original IF instruction after the new IF instruction + BranchHandle gotoHandle = il.append(invertedIfHandle, + new GOTO(target)); + + // If the original IF was the last instruction in + // InstructionList, add a new no-op to act as the target + // of the new IF + if (nextHandle == null) { + nextHandle = il.append(gotoHandle, NOP); + } + + // Make the new IF instruction branch around the GOTO + invertedIfHandle.updateTarget(target, nextHandle); + + // If anything still "points" to the old IF instruction, + // make adjustments to refer to either the new IF or GOTO + // instruction + if (oldIfHandle.hasTargeters()) { + InstructionTargeter[] targeters = + oldIfHandle.getTargeters(); + + for (int i = 0; i < targeters.length; i++) { + InstructionTargeter targeter = targeters[i]; + // Ideally, one should simply be able to use + // InstructionTargeter.updateTarget to change + // references to the old IF instruction to the new + // IF instruction. However, if a LocalVariableGen + // indicated the old IF marked the end of the range + // in which the IF variable is in use, the live + // range of the variable must extend to include the + // newly created GOTO instruction. The need for + // this sort of specific knowledge of an + // implementor of the InstructionTargeter interface + // makes the code more fragile. Future implementors + // of the interface might have similar requirements + // which wouldn't be accommodated seemlessly. + if (targeter instanceof LocalVariableGen) { + LocalVariableGen lvg = + (LocalVariableGen) targeter; + if (lvg.getStart() == oldIfHandle) { + lvg.setStart(invertedIfHandle); + } else if (lvg.getEnd() == oldIfHandle) { + lvg.setEnd(gotoHandle); + } + } else { + targeter.updateTarget(oldIfHandle, + invertedIfHandle); + } + } + } + + try { + il.delete(oldIfHandle); + } catch (TargetLostException tle) { + // This can never happen - we updated the list of + // instructions that target the deleted instruction + // prior to deleting it. + String msg = + new ErrorMsg(ErrorMsg.OUTLINE_ERR_DELETED_TARGET, + tle.getMessage()).toString(); + throw new InternalError(msg); + } + + // Adjust the pointer in the InstructionList to point after + // the newly inserted IF instruction + ih = gotoHandle; + + // Indicate that this method rewrote at least one IF + ilChanged = true; + } + } + } + + // Did this method rewrite any IF instructions? + return ilChanged; + } } diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ObjectFactory.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ObjectFactory.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,663 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2001-2004 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. - */ -/* - * $Id: ObjectFactory.java,v 1.2.4.1 2005/09/12 11:45:06 pvedula Exp $ - */ - -package com.sun.org.apache.xalan.internal.xsltc.compiler.util; - -import java.io.InputStream; -import java.io.IOException; -import java.io.File; -import java.io.FileInputStream; - -import java.util.Properties; -import java.io.BufferedReader; -import java.io.InputStreamReader; - -/** - * 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. - *

- * This code is designed to implement the JAXP 1.1 spec pluggability - * feature and is designed to run on JDK version 1.1 and - * later, and to compile on JDK 1.2 and onward. - * The code also runs both as part of an unbundled jar file and - * when bundled as part of the JDK. - *

- * This class was moved from the javax.xml.parsers.ObjectFactory - * class and modified to be used as a general utility for creating objects - * dynamically. - * - * @version $Id: ObjectFactory.java,v 1.9 2008/04/02 00:40:59 joehw Exp $ - */ -class ObjectFactory { - - // - // Constants - // - - // name of default properties file to look for in JDK's jre/lib directory - private static final String DEFAULT_PROPERTIES_FILENAME = - "xalan.properties"; - - private static final String SERVICES_PATH = "META-INF/services/"; - - /** Set to true for debugging */ - private static final boolean DEBUG = false; - - /** cache the contents of the xalan.properties file. - * Until an attempt has been made to read this file, this will - * be null; if the file does not exist or we encounter some other error - * during the read, this will be empty. - */ - private static Properties fXalanProperties = null; - - /*** - * Cache the time stamp of the xalan.properties file so - * that we know if it's been modified and can invalidate - * the cache when necessary. - */ - private static long fLastModified = -1; - - // - // Public static methods - // - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *

    - *
  1. query the system property using System.getProperty - *
  2. read META-INF/services/factoryId file - *
  3. use fallback classname - *
- * - * @return instance of factory, 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 no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Object createObject(String factoryId, String fallbackClassName) - throws ConfigurationError { - return createObject(factoryId, null, fallbackClassName); - } // createObject(String,String):Object - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return instance of factory, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Object createObject(String factoryId, - String propertiesFilename, - String fallbackClassName) - throws ConfigurationError - { - Class factoryClass = lookUpFactoryClass(factoryId, - propertiesFilename, - fallbackClassName); - - if (factoryClass == null) { - throw new ConfigurationError( - "Provider for " + factoryId + " cannot be found", null); - } - - try{ - Object instance = factoryClass.newInstance(); - if (DEBUG) debugPrintln("created new instance of factory " + factoryId); - return instance; - } catch (Exception x) { - throw new ConfigurationError( - "Provider for factory " + factoryId - + " could not be instantiated: " + x, x); - } - } // createObject(String,String,String):Object - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return Class object of factory, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Class lookUpFactoryClass(String factoryId) - throws ConfigurationError - { - return lookUpFactoryClass(factoryId, null, null); - } // lookUpFactoryClass(String):Class - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return Class object that provides factory service, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Class lookUpFactoryClass(String factoryId, - String propertiesFilename, - String fallbackClassName) - throws ConfigurationError - { - String factoryClassName = lookUpFactoryClassName(factoryId, - propertiesFilename, - fallbackClassName); - ClassLoader cl = findClassLoader(); - - if (factoryClassName == null) { - factoryClassName = fallbackClassName; - } - - // assert(className != null); - try{ - Class providerClass = findProviderClass(factoryClassName, - cl, - true); - if (DEBUG) debugPrintln("created new instance of " + providerClass + - " using ClassLoader: " + cl); - return providerClass; - } catch (ClassNotFoundException x) { - throw new ConfigurationError( - "Provider " + factoryClassName + " not found", x); - } catch (Exception x) { - throw new ConfigurationError( - "Provider "+factoryClassName+" could not be instantiated: "+x, - x); - } - } // lookUpFactoryClass(String,String,String):Class - - /** - * Finds the name of the required implementation class in the specified - * order. The specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return name of class that provides factory service, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static String lookUpFactoryClassName(String factoryId, - String propertiesFilename, - String fallbackClassName) - { - SecuritySupport ss = SecuritySupport.getInstance(); - - // Use the system property first - try { - String systemProp = ss.getSystemProperty(factoryId); - if (systemProp != null) { - if (DEBUG) debugPrintln("found system property, value=" + systemProp); - return systemProp; - } - } catch (SecurityException se) { - // Ignore and continue w/ next location - } - - // Try to read from propertiesFilename, or - // $java.home/lib/xalan.properties - String factoryClassName = null; - // no properties file name specified; use - // $JAVA_HOME/lib/xalan.properties: - if (propertiesFilename == null) { - File propertiesFile = null; - boolean propertiesFileExists = false; - try { - String javah = ss.getSystemProperty("java.home"); - propertiesFilename = javah + File.separator + - "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME; - propertiesFile = new File(propertiesFilename); - propertiesFileExists = ss.getFileExists(propertiesFile); - } catch (SecurityException e) { - // try again... - fLastModified = -1; - fXalanProperties = null; - } - - synchronized (ObjectFactory.class) { - boolean loadProperties = false; - FileInputStream fis = null; - try { - // file existed last time - if(fLastModified >= 0) { - if(propertiesFileExists && - (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) { - loadProperties = true; - } else { - // file has stopped existing... - if(!propertiesFileExists) { - fLastModified = -1; - fXalanProperties = null; - } // else, file wasn't modified! - } - } else { - // file has started to exist: - if(propertiesFileExists) { - loadProperties = true; - fLastModified = ss.getLastModified(propertiesFile); - } // else, nothing's changed - } - if(loadProperties) { - // must never have attempted to read xalan.properties - // before (or it's outdeated) - fXalanProperties = new Properties(); - fis = ss.getFileInputStream(propertiesFile); - fXalanProperties.load(fis); - } - } catch (Exception x) { - fXalanProperties = null; - fLastModified = -1; - // assert(x instanceof FileNotFoundException - // || x instanceof SecurityException) - // In both cases, ignore and continue w/ next location - } - finally { - // try to close the input stream if one was opened. - if (fis != null) { - try { - fis.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - } - } - if(fXalanProperties != null) { - factoryClassName = fXalanProperties.getProperty(factoryId); - } - } else { - FileInputStream fis = null; - try { - fis = ss.getFileInputStream(new File(propertiesFilename)); - Properties props = new Properties(); - props.load(fis); - factoryClassName = props.getProperty(factoryId); - } catch (Exception x) { - // assert(x instanceof FileNotFoundException - // || x instanceof SecurityException) - // In both cases, ignore and continue w/ next location - } - finally { - // try to close the input stream if one was opened. - if (fis != null) { - try { - fis.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - } - } - if (factoryClassName != null) { - if (DEBUG) debugPrintln("found in " + propertiesFilename + ", value=" - + factoryClassName); - return factoryClassName; - } - - // Try Jar Service Provider Mechanism - return findJarServiceProviderName(factoryId); - } // lookUpFactoryClass(String,String):String - - // - // Private static methods - // - - /** Prints a message to standard error if debugging is enabled. */ - private static void debugPrintln(String msg) { - if (DEBUG) { - System.err.println("JAXP: " + msg); - } - } // debugPrintln(String) - - /** - * Figure out which ClassLoader to use. For JDK 1.2 and later use - * the context ClassLoader. - */ - static ClassLoader findClassLoader() - 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 context = ss.getContextClassLoader(); - ClassLoader system = ss.getSystemClassLoader(); - - ClassLoader chain = system; - while (true) { - if (context == chain) { - // Assert: we are on JDK 1.1 or we have no Context ClassLoader - // or any Context ClassLoader in chain of system classloader - // (including extension ClassLoader) so extend to widest - // ClassLoader (always look in system ClassLoader if Xalan - // is in boot/extension/system classpath and in current - // ClassLoader otherwise); normal classloaders delegate - // back to system ClassLoader first so this widening doesn't - // change the fact that context ClassLoader will be consulted - ClassLoader current = ObjectFactory.class.getClassLoader(); - - chain = system; - while (true) { - if (current == chain) { - // Assert: Current ClassLoader in chain of - // boot/extension/system ClassLoaders - return system; - } - if (chain == null) { - break; - } - chain = ss.getParentClassLoader(chain); - } - - // Assert: Current ClassLoader not in chain of - // boot/extension/system ClassLoaders - return current; - } - - if (chain == null) { - // boot ClassLoader reached - break; - } - - // Check for any extension ClassLoaders in chain up to - // boot ClassLoader - chain = ss.getParentClassLoader(chain); - }; - - // Assert: Context ClassLoader not in chain of - // boot/extension/system ClassLoaders - return context; - } // findClassLoader():ClassLoader - - /** - * Create an instance of a class using the specified ClassLoader - */ - static Object newInstance(String className, ClassLoader cl, - boolean doFallback) - throws ConfigurationError - { - // assert(className != null); - try{ - Class providerClass = findProviderClass(className, cl, doFallback); - Object instance = providerClass.newInstance(); - if (DEBUG) debugPrintln("created new instance of " + providerClass + - " using ClassLoader: " + cl); - return instance; - } catch (ClassNotFoundException x) { - throw new ConfigurationError( - "Provider " + className + " not found", x); - } catch (Exception x) { - throw new ConfigurationError( - "Provider " + className + " could not be instantiated: " + x, - x); - } - } - - /** - * Find a Class using the specified ClassLoader - */ - static Class findProviderClass(String className, ClassLoader cl, - boolean doFallback) - throws ClassNotFoundException, ConfigurationError - { - //throw security exception if the calling thread is not allowed to access the - //class. Restrict the access to the package classes as specified in java.security policy. - SecurityManager security = System.getSecurityManager(); - try{ - if (security != null){ - final int lastDot = className.lastIndexOf("."); - String packageName = className; - if (lastDot != -1) packageName = className.substring(0, lastDot); - security.checkPackageAccess(packageName); - } - }catch(SecurityException e){ - throw e; - } - - Class providerClass; - 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 { - try { - providerClass = cl.loadClass(className); - } catch (ClassNotFoundException x) { - if (doFallback) { - // Fall back to current classloader - ClassLoader current = ObjectFactory.class.getClassLoader(); - if (current == null) { - providerClass = Class.forName(className); - } else if (cl != current) { - cl = current; - providerClass = cl.loadClass(className); - } else { - throw x; - } - } else { - throw x; - } - } - } - - return providerClass; - } - - /** - * Find the name of service provider using Jar Service Provider Mechanism - * - * @return instance of provider class if found or null - */ - private static String findJarServiceProviderName(String factoryId) - { - SecuritySupport ss = SecuritySupport.getInstance(); - String serviceId = SERVICES_PATH + factoryId; - InputStream is = null; - - // First try the Context ClassLoader - ClassLoader cl = findClassLoader(); - - is = ss.getResourceAsStream(cl, serviceId); - - // If no provider found then try the current ClassLoader - if (is == null) { - ClassLoader current = ObjectFactory.class.getClassLoader(); - if (cl != current) { - cl = current; - is = ss.getResourceAsStream(cl, serviceId); - } - } - - if (is == null) { - // No provider found - return null; - } - - if (DEBUG) debugPrintln("found jar resource=" + serviceId + - " using ClassLoader: " + cl); - - // 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)); - } - - String factoryClassName = null; - try { - // XXX Does not handle all possible input as specified by the - // Jar Service Provider specification - factoryClassName = rd.readLine(); - } catch (IOException x) { - // No provider found - return null; - } - finally { - try { - // try to close the reader. - rd.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - - if (factoryClassName != null && - ! "".equals(factoryClassName)) { - if (DEBUG) debugPrintln("found in resource, value=" - + factoryClassName); - - // Note: here we do not want to fall back to the current - // 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. - return factoryClassName; - } - - // No provider found - return null; - } - - // - // Classes - // - - /** - * A configuration error. - */ - static class ConfigurationError - extends Error { - static final long serialVersionUID = -4417969773510154215L; - // - // Data - // - - /** Exception. */ - private Exception exception; - - // - // Constructors - // - - /** - * Construct a new instance with the specified detail string and - * exception. - */ - ConfigurationError(String msg, Exception x) { - super(msg); - this.exception = x; - } // (String,Exception) - - // - // Public methods - // - - /** Returns the exception associated to this error. */ - Exception getException() { - return exception; - } // getException():Exception - - } // class ConfigurationError - -} // class ObjectFactory diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ObjectType.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ObjectType.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ObjectType.java Tue Apr 17 11:17:59 2012 -0700 @@ -34,6 +34,7 @@ import com.sun.org.apache.bcel.internal.generic.InstructionList; import com.sun.org.apache.bcel.internal.generic.PUSH; import com.sun.org.apache.xalan.internal.xsltc.compiler.Constants; +import com.sun.org.apache.xalan.internal.utils.ObjectFactory; /** * @author Todd Miller @@ -53,8 +54,7 @@ _javaClassName = javaClassName; try { - _clazz = ObjectFactory.findProviderClass( - javaClassName, ObjectFactory.findClassLoader(), true); + _clazz = ObjectFactory.findProviderClass(javaClassName, true); } catch (ClassNotFoundException e) { _clazz = null; diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/OutlineableChunkEnd.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/OutlineableChunkEnd.java Tue Apr 17 11:17:59 2012 -0700 @@ -0,0 +1,70 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Copyright 2001-2004 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. + */ + +/* + * $Id: OutlineableChunkEnd.java,v 1.10 2010-11-01 04:34:19 joehw Exp $ + */ +package com.sun.org.apache.xalan.internal.xsltc.compiler.util; +import com.sun.org.apache.bcel.internal.generic.Instruction; +/** + *

Marks the end of a region of byte code that can be copied into a new + * method. See the {@link OutlineableChunkStart} pseudo-instruction for + * details.

+ */ +class OutlineableChunkEnd extends MarkerInstruction { + /** + * A constant instance of {@link OutlineableChunkEnd}. As it has no fields, + * there should be no need to create an instance of this class. + */ + public static final Instruction OUTLINEABLECHUNKEND = + new OutlineableChunkEnd(); + + /** + * Private default constructor. As it has no fields, + * there should be no need to create an instance of this class. See + * {@link OutlineableChunkEnd#OUTLINEABLECHUNKEND}. + */ + private OutlineableChunkEnd() { + } + + /** + * Get the name of this instruction. Used for debugging. + * @return the instruction name + */ + public String getName() { + return OutlineableChunkEnd.class.getName(); + } + + /** + * Get the name of this instruction. Used for debugging. + * @return the instruction name + */ + public String toString() { + return getName(); + } + + /** + * Get the name of this instruction. Used for debugging. + * @return the instruction name + */ + public String toString(boolean verbose) { + return getName(); + } +} diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/OutlineableChunkStart.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/OutlineableChunkStart.java Tue Apr 17 11:17:59 2012 -0700 @@ -0,0 +1,80 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Copyright 2001-2004 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. + */ + +/* + * $Id: MethodGenerator.java,v 1.10 2010-11-01 04:34:19 joehw Exp $ + */ +package com.sun.org.apache.xalan.internal.xsltc.compiler.util; +import com.sun.org.apache.bcel.internal.generic.Instruction; + +/** + *

This pseudo-instruction marks the beginning of a region of byte code that + * can be copied into a new method, termed an "outlineable" chunk. The size of + * the Java stack must be the same at the start of the region as it is at the + * end of the region, any value on the stack at the start of the region must not + * be consumed by an instruction in the region of code, the region must not + * contain a return instruction, no branch instruction in the region is + * permitted to have a target that is outside the region, and no branch + * instruction outside the region is permitted to have a target that is inside + * the region.

+ *

The end of the region is marked by an {@link OutlineableChunkEnd} + * pseudo-instruction.

+ *

Such a region of code may contain other outlineable regions.

+ */ +class OutlineableChunkStart extends MarkerInstruction { + /** + * A constant instance of {@link OutlineableChunkStart}. As it has no fields, + * there should be no need to create an instance of this class. + */ + public static final Instruction OUTLINEABLECHUNKSTART = + new OutlineableChunkStart(); + + /** + * Private default constructor. As it has no fields, + * there should be no need to create an instance of this class. See + * {@link OutlineableChunkStart#OUTLINEABLECHUNKSTART}. + */ + private OutlineableChunkStart() { + } + + /** + * Get the name of this instruction. Used for debugging. + * @return the instruction name + */ + public String getName() { + return OutlineableChunkStart.class.getName(); + } + + /** + * Get the name of this instruction. Used for debugging. + * @return the instruction name + */ + public String toString() { + return getName(); + } + + /** + * Get the name of this instruction. Used for debugging. + * @return the instruction name + */ + public String toString(boolean verbose) { + return getName(); + } +} diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/RealType.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/RealType.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/RealType.java Tue Apr 17 11:17:59 2012 -0700 @@ -170,8 +170,8 @@ il.append(DUP2); local = methodGen.addLocalVariable("real_to_boolean_tmp", com.sun.org.apache.bcel.internal.generic.Type.DOUBLE, - il.getEnd(), null); - il.append(new DSTORE(local.getIndex())); + null, null); + local.setStart(il.append(new DSTORE(local.getIndex()))); // Compare it to 0.0 il.append(DCONST_0); @@ -181,7 +181,7 @@ //!!! call isNaN // Compare it to itself to see if NaN il.append(new DLOAD(local.getIndex())); - il.append(new DLOAD(local.getIndex())); + local.setEnd(il.append(new DLOAD(local.getIndex()))); il.append(DCMPG); flowlist.add(il.append(new IFNE(null))); // NaN != NaN return flowlist; diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ResultTreeType.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ResultTreeType.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ResultTreeType.java Tue Apr 17 11:17:59 2012 -0700 @@ -180,7 +180,7 @@ methodGen.addLocalVariable("rt_to_string_handler", Util.getJCRefType(STRING_VALUE_HANDLER_SIG), null, null); - il.append(new ASTORE(handler.getIndex())); + handler.setStart(il.append(new ASTORE(handler.getIndex()))); // Call the method that implements this result tree index = cpg.addMethodref(className, _methodName, @@ -188,7 +188,7 @@ il.append(new INVOKEVIRTUAL(index)); // Restore new handler and call getValue() - il.append(new ALOAD(handler.getIndex())); + handler.setEnd(il.append(new ALOAD(handler.getIndex()))); index = cpg.addMethodref(STRING_VALUE_HANDLER, "getValue", "()" + STRING_SIG); @@ -255,7 +255,7 @@ Util.getJCRefType(DOM_INTF_SIG), null, null); il.append(new CHECKCAST(cpg.addClass(DOM_INTF_SIG))); - il.append(new ASTORE(newDom.getIndex())); + newDom.setStart(il.append(new ASTORE(newDom.getIndex()))); // Overwrite old handler with DOM handler index = cpg.addInterfaceMethodref(DOM_INTF, @@ -275,7 +275,7 @@ methodGen.addLocalVariable("rt_to_reference_handler", Util.getJCRefType(TRANSLET_OUTPUT_SIG), null, null); - il.append(new ASTORE(domBuilder.getIndex())); + domBuilder.setStart(il.append(new ASTORE(domBuilder.getIndex()))); // Call startDocument on the new handler index = cpg.addInterfaceMethodref(TRANSLET_OUTPUT_INTERFACE, @@ -292,13 +292,13 @@ il.append(new INVOKEVIRTUAL(index)); // Call endDocument on the DOM handler - il.append(new ALOAD(domBuilder.getIndex())); + domBuilder.setEnd(il.append(new ALOAD(domBuilder.getIndex()))); index = cpg.addInterfaceMethodref(TRANSLET_OUTPUT_INTERFACE, "endDocument", "()V"); il.append(new INVOKEINTERFACE(index, 1)); // Push the new DOM on the stack - il.append(new ALOAD(newDom.getIndex())); + newDom.setEnd(il.append(new ALOAD(newDom.getIndex()))); } } diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/SecuritySupport.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/SecuritySupport.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,127 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2002-2004 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. - */ -/* - * $Id: SecuritySupport.java,v 1.2.4.1 2005/09/05 11:31:37 pvedula Exp $ - */ - -package com.sun.org.apache.xalan.internal.xsltc.compiler.util; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.InputStream; - -import java.util.Properties; - -/** - * This class is duplicated for each Xalan-Java subpackage so keep it in sync. - * It is package private and therefore is not exposed as part of the Xalan-Java - * 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. - */ - static SecuritySupport getInstance() { - return (SecuritySupport)securitySupport; - } - - ClassLoader getContextClassLoader() { - return null; - } - - ClassLoader getSystemClassLoader() { - return null; - } - - ClassLoader getParentClassLoader(ClassLoader cl) { - return null; - } - - String getSystemProperty(String propName) { - return System.getProperty(propName); - } - - FileInputStream getFileInputStream(File file) - throws FileNotFoundException - { - return new FileInputStream(file); - } - - InputStream getResourceAsStream(ClassLoader cl, String name) { - InputStream ris; - if (cl == null) { - ris = ClassLoader.getSystemResourceAsStream(name); - } else { - ris = cl.getResourceAsStream(name); - } - return ris; - } - - boolean getFileExists(File f) { - return f.exists(); - } - - long getLastModified(File f) { - return f.lastModified(); - } -} diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/SecuritySupport12.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/SecuritySupport12.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,148 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2002-2004 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. - */ -/* - * $Id: SecuritySupport12.java,v 1.2.4.1 2005/09/05 11:32:07 pvedula Exp $ - */ - -package com.sun.org.apache.xalan.internal.xsltc.compiler.util; - -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; - -import java.util.Properties; - -/** - * This class is duplicated for each Xalan-Java subpackage so keep it in sync. - * It is package private and therefore is not exposed as part of the Xalan-Java - * API. - * - * Security related methods that only work on J2SE 1.2 and newer. - */ -class SecuritySupport12 extends SecuritySupport { - - ClassLoader getContextClassLoader() { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader cl = null; - try { - cl = Thread.currentThread().getContextClassLoader(); - } catch (SecurityException ex) { } - return cl; - } - }); - } - - ClassLoader getSystemClassLoader() { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader cl = null; - try { - cl = ClassLoader.getSystemClassLoader(); - } catch (SecurityException ex) {} - return cl; - } - }); - } - - ClassLoader getParentClassLoader(final ClassLoader cl) { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader parent = null; - try { - parent = cl.getParent(); - } catch (SecurityException ex) {} - - // eliminate loops in case of the boot - // ClassLoader returning itself as a parent - return (parent == cl) ? null : parent; - } - }); - } - - String getSystemProperty(final String propName) { - return (String) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return System.getProperty(propName); - } - }); - } - - 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(); - } - } - - 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; - } - }); - } - - boolean getFileExists(final File f) { - return ((Boolean) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return new Boolean(f.exists()); - } - })).booleanValue(); - } - - long getLastModified(final File f) { - return ((Long) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return new Long(f.lastModified()); - } - })).longValue(); - } - -} diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/dom/ArrayNodeListIterator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/dom/ArrayNodeListIterator.java Tue Apr 17 11:17:59 2012 -0700 @@ -0,0 +1,91 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Copyright 2001-2004 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. + */ + +/* + * $Id: ArrayNodeListIterator.java,v 1.0 2009-11-25 04:34:24 joehw Exp $ + */ +package com.sun.org.apache.xalan.internal.xsltc.dom; + +import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator; + +public class ArrayNodeListIterator implements DTMAxisIterator { + + private int _pos = 0; + + private int _mark = 0; + + private int _nodes[]; + + private static final int[] EMPTY = { }; + + public ArrayNodeListIterator(int[] nodes) { + _nodes = nodes; + } + + public int next() { + return _pos < _nodes.length ? _nodes[_pos++] : END; + } + + public DTMAxisIterator reset() { + _pos = 0; + return this; + } + + public int getLast() { + return _nodes.length; + } + + public int getPosition() { + return _pos; + } + + public void setMark() { + _mark = _pos; + } + + public void gotoMark() { + _pos = _mark; + } + + public DTMAxisIterator setStartNode(int node) { + if (node == END) _nodes = EMPTY; + return this; + } + + public int getStartNode() { + return END; + } + + public boolean isReverse() { + return false; + } + + public DTMAxisIterator cloneIterator() { + return new ArrayNodeListIterator(_nodes); + } + + public void setRestartable(boolean isRestartable) { + } + + public int getNodeByPosition(int position) { + return _nodes[position - 1]; + } + +} diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/dom/DupFilterIterator.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/dom/DupFilterIterator.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/dom/DupFilterIterator.java Tue Apr 17 11:17:59 2012 -0700 @@ -88,7 +88,9 @@ if (_isRestartable) { // KeyIndex iterators are always relative to the root node, so there // is never any point in re-reading the iterator (and we SHOULD NOT). - if (_source instanceof KeyIndex + boolean sourceIsKeyIndex = _source instanceof KeyIndex; + + if (sourceIsKeyIndex && _startNode == DTMDefaultBase.ROOTNODE) { return this; } @@ -100,7 +102,12 @@ while ((node = _source.next()) != END) { _nodes.add(node); } - _nodes.sort(); + + // Nodes produced by KeyIndex are known to be in document order. + // Take advantage of it. + if (!sourceIsKeyIndex) { + _nodes.sort(); + } _nodesSize = _nodes.cardinality(); _current = 0; _lastNext = END; diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/dom/NodeSortRecord.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/dom/NodeSortRecord.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/dom/NodeSortRecord.java Tue Apr 17 11:17:59 2012 -0700 @@ -32,6 +32,7 @@ import com.sun.org.apache.xalan.internal.xsltc.TransletException; import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet; import com.sun.org.apache.xml.internal.utils.StringComparable; +import com.sun.org.apache.xalan.internal.utils.ObjectFactory; /** * Base class for sort records containing application specific sort keys @@ -119,8 +120,7 @@ if (colFactClassname != null) { try { - Object candObj = ObjectFactory.findProviderClass( - colFactClassname, ObjectFactory.findClassLoader(), true); + Object candObj = ObjectFactory.findProviderClass(colFactClassname, true); _collatorFactory = (CollatorFactory)candObj; } catch (ClassNotFoundException e) { throw new TransletException(e); diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/dom/NodeSortRecordFactory.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/dom/NodeSortRecordFactory.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/dom/NodeSortRecordFactory.java Tue Apr 17 11:17:59 2012 -0700 @@ -28,6 +28,7 @@ import com.sun.org.apache.xalan.internal.xsltc.TransletException; import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet; import com.sun.org.apache.xml.internal.utils.LocaleUtility; +import com.sun.org.apache.xalan.internal.utils.ObjectFactory; import java.util.Locale; import java.text.Collator; @@ -82,8 +83,7 @@ _class = translet.getAuxiliaryClass(className); // This code is only run when the native API is used if (_class == null) { - _class = ObjectFactory.findProviderClass( - className, ObjectFactory.findClassLoader(), true); + _class = ObjectFactory.findProviderClass(className, true); } int levels = order.length; diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/dom/ObjectFactory.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/dom/ObjectFactory.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,663 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2001-2004 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. - */ -/* - * $Id: ObjectFactory.java,v 1.2.4.1 2005/09/12 11:53:33 pvedula Exp $ - */ - -package com.sun.org.apache.xalan.internal.xsltc.dom; - -import java.io.InputStream; -import java.io.IOException; -import java.io.File; -import java.io.FileInputStream; - -import java.util.Properties; -import java.io.BufferedReader; -import java.io.InputStreamReader; - -/** - * 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. - *

- * This code is designed to implement the JAXP 1.1 spec pluggability - * feature and is designed to run on JDK version 1.1 and - * later, and to compile on JDK 1.2 and onward. - * The code also runs both as part of an unbundled jar file and - * when bundled as part of the JDK. - *

- * This class was moved from the javax.xml.parsers.ObjectFactory - * class and modified to be used as a general utility for creating objects - * dynamically. - * - * @version $Id: ObjectFactory.java,v 1.9 2008/04/02 00:41:00 joehw Exp $ - */ -class ObjectFactory { - - // - // Constants - // - - // name of default properties file to look for in JDK's jre/lib directory - private static final String DEFAULT_PROPERTIES_FILENAME = - "xalan.properties"; - - private static final String SERVICES_PATH = "META-INF/services/"; - - /** Set to true for debugging */ - private static final boolean DEBUG = false; - - /** cache the contents of the xalan.properties file. - * Until an attempt has been made to read this file, this will - * be null; if the file does not exist or we encounter some other error - * during the read, this will be empty. - */ - private static Properties fXalanProperties = null; - - /*** - * Cache the time stamp of the xalan.properties file so - * that we know if it's been modified and can invalidate - * the cache when necessary. - */ - private static long fLastModified = -1; - - // - // Public static methods - // - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *

    - *
  1. query the system property using System.getProperty - *
  2. read META-INF/services/factoryId file - *
  3. use fallback classname - *
- * - * @return instance of factory, 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 no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Object createObject(String factoryId, String fallbackClassName) - throws ConfigurationError { - return createObject(factoryId, null, fallbackClassName); - } // createObject(String,String):Object - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return instance of factory, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Object createObject(String factoryId, - String propertiesFilename, - String fallbackClassName) - throws ConfigurationError - { - Class factoryClass = lookUpFactoryClass(factoryId, - propertiesFilename, - fallbackClassName); - - if (factoryClass == null) { - throw new ConfigurationError( - "Provider for " + factoryId + " cannot be found", null); - } - - try{ - Object instance = factoryClass.newInstance(); - if (DEBUG) debugPrintln("created new instance of factory " + factoryId); - return instance; - } catch (Exception x) { - throw new ConfigurationError( - "Provider for factory " + factoryId - + " could not be instantiated: " + x, x); - } - } // createObject(String,String,String):Object - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return Class object of factory, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Class lookUpFactoryClass(String factoryId) - throws ConfigurationError - { - return lookUpFactoryClass(factoryId, null, null); - } // lookUpFactoryClass(String):Class - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return Class object that provides factory service, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Class lookUpFactoryClass(String factoryId, - String propertiesFilename, - String fallbackClassName) - throws ConfigurationError - { - String factoryClassName = lookUpFactoryClassName(factoryId, - propertiesFilename, - fallbackClassName); - ClassLoader cl = findClassLoader(); - - if (factoryClassName == null) { - factoryClassName = fallbackClassName; - } - - // assert(className != null); - try{ - Class providerClass = findProviderClass(factoryClassName, - cl, - true); - if (DEBUG) debugPrintln("created new instance of " + providerClass + - " using ClassLoader: " + cl); - return providerClass; - } catch (ClassNotFoundException x) { - throw new ConfigurationError( - "Provider " + factoryClassName + " not found", x); - } catch (Exception x) { - throw new ConfigurationError( - "Provider "+factoryClassName+" could not be instantiated: "+x, - x); - } - } // lookUpFactoryClass(String,String,String):Class - - /** - * Finds the name of the required implementation class in the specified - * order. The specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return name of class that provides factory service, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static String lookUpFactoryClassName(String factoryId, - String propertiesFilename, - String fallbackClassName) - { - SecuritySupport ss = SecuritySupport.getInstance(); - - // Use the system property first - try { - String systemProp = ss.getSystemProperty(factoryId); - if (systemProp != null) { - if (DEBUG) debugPrintln("found system property, value=" + systemProp); - return systemProp; - } - } catch (SecurityException se) { - // Ignore and continue w/ next location - } - - // Try to read from propertiesFilename, or - // $java.home/lib/xalan.properties - String factoryClassName = null; - // no properties file name specified; use - // $JAVA_HOME/lib/xalan.properties: - if (propertiesFilename == null) { - File propertiesFile = null; - boolean propertiesFileExists = false; - try { - String javah = ss.getSystemProperty("java.home"); - propertiesFilename = javah + File.separator + - "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME; - propertiesFile = new File(propertiesFilename); - propertiesFileExists = ss.getFileExists(propertiesFile); - } catch (SecurityException e) { - // try again... - fLastModified = -1; - fXalanProperties = null; - } - - synchronized (ObjectFactory.class) { - boolean loadProperties = false; - FileInputStream fis = null; - try { - // file existed last time - if(fLastModified >= 0) { - if(propertiesFileExists && - (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) { - loadProperties = true; - } else { - // file has stopped existing... - if(!propertiesFileExists) { - fLastModified = -1; - fXalanProperties = null; - } // else, file wasn't modified! - } - } else { - // file has started to exist: - if(propertiesFileExists) { - loadProperties = true; - fLastModified = ss.getLastModified(propertiesFile); - } // else, nothing's changed - } - if(loadProperties) { - // must never have attempted to read xalan.properties - // before (or it's outdeated) - fXalanProperties = new Properties(); - fis = ss.getFileInputStream(propertiesFile); - fXalanProperties.load(fis); - } - } catch (Exception x) { - fXalanProperties = null; - fLastModified = -1; - // assert(x instanceof FileNotFoundException - // || x instanceof SecurityException) - // In both cases, ignore and continue w/ next location - } - finally { - // try to close the input stream if one was opened. - if (fis != null) { - try { - fis.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - } - } - if(fXalanProperties != null) { - factoryClassName = fXalanProperties.getProperty(factoryId); - } - } else { - FileInputStream fis = null; - try { - fis = ss.getFileInputStream(new File(propertiesFilename)); - Properties props = new Properties(); - props.load(fis); - factoryClassName = props.getProperty(factoryId); - } catch (Exception x) { - // assert(x instanceof FileNotFoundException - // || x instanceof SecurityException) - // In both cases, ignore and continue w/ next location - } - finally { - // try to close the input stream if one was opened. - if (fis != null) { - try { - fis.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - } - } - if (factoryClassName != null) { - if (DEBUG) debugPrintln("found in " + propertiesFilename + ", value=" - + factoryClassName); - return factoryClassName; - } - - // Try Jar Service Provider Mechanism - return findJarServiceProviderName(factoryId); - } // lookUpFactoryClass(String,String):String - - // - // Private static methods - // - - /** Prints a message to standard error if debugging is enabled. */ - private static void debugPrintln(String msg) { - if (DEBUG) { - System.err.println("JAXP: " + msg); - } - } // debugPrintln(String) - - /** - * Figure out which ClassLoader to use. For JDK 1.2 and later use - * the context ClassLoader. - */ - static ClassLoader findClassLoader() - 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 context = ss.getContextClassLoader(); - ClassLoader system = ss.getSystemClassLoader(); - - ClassLoader chain = system; - while (true) { - if (context == chain) { - // Assert: we are on JDK 1.1 or we have no Context ClassLoader - // or any Context ClassLoader in chain of system classloader - // (including extension ClassLoader) so extend to widest - // ClassLoader (always look in system ClassLoader if Xalan - // is in boot/extension/system classpath and in current - // ClassLoader otherwise); normal classloaders delegate - // back to system ClassLoader first so this widening doesn't - // change the fact that context ClassLoader will be consulted - ClassLoader current = ObjectFactory.class.getClassLoader(); - - chain = system; - while (true) { - if (current == chain) { - // Assert: Current ClassLoader in chain of - // boot/extension/system ClassLoaders - return system; - } - if (chain == null) { - break; - } - chain = ss.getParentClassLoader(chain); - } - - // Assert: Current ClassLoader not in chain of - // boot/extension/system ClassLoaders - return current; - } - - if (chain == null) { - // boot ClassLoader reached - break; - } - - // Check for any extension ClassLoaders in chain up to - // boot ClassLoader - chain = ss.getParentClassLoader(chain); - }; - - // Assert: Context ClassLoader not in chain of - // boot/extension/system ClassLoaders - return context; - } // findClassLoader():ClassLoader - - /** - * Create an instance of a class using the specified ClassLoader - */ - static Object newInstance(String className, ClassLoader cl, - boolean doFallback) - throws ConfigurationError - { - // assert(className != null); - try{ - Class providerClass = findProviderClass(className, cl, doFallback); - Object instance = providerClass.newInstance(); - if (DEBUG) debugPrintln("created new instance of " + providerClass + - " using ClassLoader: " + cl); - return instance; - } catch (ClassNotFoundException x) { - throw new ConfigurationError( - "Provider " + className + " not found", x); - } catch (Exception x) { - throw new ConfigurationError( - "Provider " + className + " could not be instantiated: " + x, - x); - } - } - - /** - * Find a Class using the specified ClassLoader - */ - static Class findProviderClass(String className, ClassLoader cl, - boolean doFallback) - throws ClassNotFoundException, ConfigurationError - { - //throw security exception if the calling thread is not allowed to access the - //class. Restrict the access to the package classes as specified in java.security policy. - SecurityManager security = System.getSecurityManager(); - try{ - if (security != null){ - final int lastDot = className.lastIndexOf("."); - String packageName = className; - if (lastDot != -1) packageName = className.substring(0, lastDot); - security.checkPackageAccess(packageName); - } - }catch(SecurityException e){ - throw e; - } - - Class providerClass; - 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 { - try { - providerClass = cl.loadClass(className); - } catch (ClassNotFoundException x) { - if (doFallback) { - // Fall back to current classloader - ClassLoader current = ObjectFactory.class.getClassLoader(); - if (current == null) { - providerClass = Class.forName(className); - } else if (cl != current) { - cl = current; - providerClass = cl.loadClass(className); - } else { - throw x; - } - } else { - throw x; - } - } - } - - return providerClass; - } - - /** - * Find the name of service provider using Jar Service Provider Mechanism - * - * @return instance of provider class if found or null - */ - private static String findJarServiceProviderName(String factoryId) - { - SecuritySupport ss = SecuritySupport.getInstance(); - String serviceId = SERVICES_PATH + factoryId; - InputStream is = null; - - // First try the Context ClassLoader - ClassLoader cl = findClassLoader(); - - is = ss.getResourceAsStream(cl, serviceId); - - // If no provider found then try the current ClassLoader - if (is == null) { - ClassLoader current = ObjectFactory.class.getClassLoader(); - if (cl != current) { - cl = current; - is = ss.getResourceAsStream(cl, serviceId); - } - } - - if (is == null) { - // No provider found - return null; - } - - if (DEBUG) debugPrintln("found jar resource=" + serviceId + - " using ClassLoader: " + cl); - - // 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)); - } - - String factoryClassName = null; - try { - // XXX Does not handle all possible input as specified by the - // Jar Service Provider specification - factoryClassName = rd.readLine(); - } catch (IOException x) { - // No provider found - return null; - } - finally { - try { - // try to close the reader. - rd.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - - if (factoryClassName != null && - ! "".equals(factoryClassName)) { - if (DEBUG) debugPrintln("found in resource, value=" - + factoryClassName); - - // Note: here we do not want to fall back to the current - // 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. - return factoryClassName; - } - - // No provider found - return null; - } - - // - // Classes - // - - /** - * A configuration error. - */ - static class ConfigurationError - extends Error { - static final long serialVersionUID = -5948733402959678002L; - // - // Data - // - - /** Exception. */ - private Exception exception; - - // - // Constructors - // - - /** - * Construct a new instance with the specified detail string and - * exception. - */ - ConfigurationError(String msg, Exception x) { - super(msg); - this.exception = x; - } // (String,Exception) - - // - // Public methods - // - - /** Returns the exception associated to this error. */ - Exception getException() { - return exception; - } // getException():Exception - - } // class ConfigurationError - -} // class ObjectFactory diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/dom/SecuritySupport.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/dom/SecuritySupport.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,127 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2002-2004 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. - */ -/* - * $Id: SecuritySupport.java,v 1.2.4.1 2005/09/06 10:03:40 pvedula Exp $ - */ - -package com.sun.org.apache.xalan.internal.xsltc.dom; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.InputStream; - -import java.util.Properties; - -/** - * This class is duplicated for each Xalan-Java subpackage so keep it in sync. - * It is package private and therefore is not exposed as part of the Xalan-Java - * 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. - */ - static SecuritySupport getInstance() { - return (SecuritySupport)securitySupport; - } - - ClassLoader getContextClassLoader() { - return null; - } - - ClassLoader getSystemClassLoader() { - return null; - } - - ClassLoader getParentClassLoader(ClassLoader cl) { - return null; - } - - String getSystemProperty(String propName) { - return System.getProperty(propName); - } - - FileInputStream getFileInputStream(File file) - throws FileNotFoundException - { - return new FileInputStream(file); - } - - InputStream getResourceAsStream(ClassLoader cl, String name) { - InputStream ris; - if (cl == null) { - ris = ClassLoader.getSystemResourceAsStream(name); - } else { - ris = cl.getResourceAsStream(name); - } - return ris; - } - - boolean getFileExists(File f) { - return f.exists(); - } - - long getLastModified(File f) { - return f.lastModified(); - } -} diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/dom/SecuritySupport12.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/dom/SecuritySupport12.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,148 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2002-2004 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. - */ -/* - * $Id: SecuritySupport12.java,v 1.2.4.1 2005/09/06 10:06:07 pvedula Exp $ - */ - -package com.sun.org.apache.xalan.internal.xsltc.dom; - -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; - -import java.util.Properties; - -/** - * This class is duplicated for each Xalan-Java subpackage so keep it in sync. - * It is package private and therefore is not exposed as part of the Xalan-Java - * API. - * - * Security related methods that only work on J2SE 1.2 and newer. - */ -class SecuritySupport12 extends SecuritySupport { - - ClassLoader getContextClassLoader() { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader cl = null; - try { - cl = Thread.currentThread().getContextClassLoader(); - } catch (SecurityException ex) { } - return cl; - } - }); - } - - ClassLoader getSystemClassLoader() { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader cl = null; - try { - cl = ClassLoader.getSystemClassLoader(); - } catch (SecurityException ex) {} - return cl; - } - }); - } - - ClassLoader getParentClassLoader(final ClassLoader cl) { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader parent = null; - try { - parent = cl.getParent(); - } catch (SecurityException ex) {} - - // eliminate loops in case of the boot - // ClassLoader returning itself as a parent - return (parent == cl) ? null : parent; - } - }); - } - - String getSystemProperty(final String propName) { - return (String) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return System.getProperty(propName); - } - }); - } - - 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(); - } - } - - 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; - } - }); - } - - boolean getFileExists(final File f) { - return ((Boolean) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return new Boolean(f.exists()); - } - })).booleanValue(); - } - - long getLastModified(final File f) { - return ((Long) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return new Long(f.lastModified()); - } - })).longValue(); - } - -} diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/dom/XSLTCDTMManager.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/dom/XSLTCDTMManager.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/dom/XSLTCDTMManager.java Tue Apr 17 11:17:59 2012 -0700 @@ -42,6 +42,7 @@ import com.sun.org.apache.xalan.internal.xsltc.trax.DOM2SAX; import com.sun.org.apache.xalan.internal.xsltc.trax.StAXEvent2SAX; import com.sun.org.apache.xalan.internal.xsltc.trax.StAXStream2SAX; +import com.sun.org.apache.xalan.internal.utils.ObjectFactory; import org.xml.sax.InputSource; import org.xml.sax.SAXNotRecognizedException; @@ -102,9 +103,22 @@ * The default is com.sun.org.apache.xalan.internal.xsltc.dom.XSLTCDTMManager. */ public static Class getDTMManagerClass() { - Class mgrClass = ObjectFactory.lookUpFactoryClass(DEFAULT_PROP_NAME, + return getDTMManagerClass(true); + } + + public static Class getDTMManagerClass(boolean useServicesMechanism) { + Class mgrClass = null; + if (useServicesMechanism) { + mgrClass = ObjectFactory.lookUpFactoryClass(DEFAULT_PROP_NAME, null, DEFAULT_CLASS_NAME); + } else { + try { + mgrClass = ObjectFactory.findProviderClass(DEFAULT_CLASS_NAME, true); + } catch (Exception e) { + //will not happen + } + } // If no class found, default to this one. (This should never happen - // the ObjectFactory has already been told that the current class is // the default). diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet.java Tue Apr 17 11:17:59 2012 -0700 @@ -23,6 +23,7 @@ package com.sun.org.apache.xalan.internal.xsltc.runtime; +import com.sun.org.apache.xalan.internal.utils.FactoryImpl; import java.io.File; import java.io.FileOutputStream; import java.io.BufferedOutputStream; @@ -66,6 +67,8 @@ public String _encoding = "UTF-8"; public boolean _omitHeader = false; public String _standalone = null; + //see OutputPropertiesFactory.ORACLE_IS_STANDALONE + public boolean _isStandalone = false; public String _doctypePublic = null; public String _doctypeSystem = null; public boolean _indent = false; @@ -105,6 +108,7 @@ // This is the name of the index used for ID attributes private final static String ID_INDEX_NAME = "##id"; + private boolean _useServicesMechanism; /************************************************************************ * Debugging @@ -669,6 +673,7 @@ if (_doctypeSystem != null) { handler.setDoctype(_doctypeSystem, _doctypePublic); } + handler.setIsStandalone(_isStandalone); } else if (_method.equals("html")) { handler.setIndent(_indent); @@ -691,6 +696,7 @@ } handler.setIndent(_indent); handler.setDoctype(_doctypeSystem, _doctypePublic); + handler.setIsStandalone(_isStandalone); } } @@ -738,6 +744,19 @@ public void setTemplates(Templates templates) { _templates = templates; } + /** + * Return the state of the services mechanism feature. + */ + public boolean useServicesMechnism() { + return _useServicesMechanism; + } + + /** + * Set the state of the services mechanism feature. + */ + public void setServicesMechnism(boolean flag) { + _useServicesMechanism = flag; + } /************************************************************************ * DOMImplementation caching for basis library @@ -748,8 +767,8 @@ throws ParserConfigurationException { if (_domImplementation == null) { - _domImplementation = DocumentBuilderFactory.newInstance() - .newDocumentBuilder().getDOMImplementation(); + DocumentBuilderFactory dbf = FactoryImpl.getDOMFactory(_useServicesMechanism); + _domImplementation = dbf.newDocumentBuilder().getDOMImplementation(); } return _domImplementation.createDocument(uri, qname, null); } diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/runtime/BasisLibrary.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/runtime/BasisLibrary.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/runtime/BasisLibrary.java Tue Apr 17 11:17:59 2012 -0700 @@ -40,12 +40,17 @@ import com.sun.org.apache.xalan.internal.xsltc.dom.MultiDOM; import com.sun.org.apache.xalan.internal.xsltc.dom.SingletonIterator; import com.sun.org.apache.xalan.internal.xsltc.dom.StepIterator; +import com.sun.org.apache.xalan.internal.xsltc.dom.ArrayNodeListIterator; +import com.sun.org.apache.xml.internal.dtm.DTM; import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator; import com.sun.org.apache.xml.internal.dtm.DTMManager; import com.sun.org.apache.xml.internal.dtm.ref.DTMDefaultBase; +import com.sun.org.apache.xml.internal.dtm.ref.DTMNodeProxy; import org.w3c.dom.DOMException; +import org.w3c.dom.Attr; import org.w3c.dom.Document; +import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; import com.sun.org.apache.xml.internal.serializer.NamespaceMappings; @@ -153,7 +158,7 @@ return dom.getStringValueX(((Node)obj).node); } else if (obj instanceof DOM) { - // When the first argument is a DOM we want the whole fecking + // When the first argument is a DOM we want the whole // DOM and not just a single node - that would not make sense. //return ((DOM)obj).getStringValueX(node); return ((DOM)obj).getStringValue(); @@ -1003,7 +1008,7 @@ } // Convert var/param -> node-set else if (obj instanceof DTMAxisIterator) { - return(((DTMAxisIterator)obj).cloneIterator()); + return(((DTMAxisIterator)obj).cloneIterator().reset()); } else { final String className = obj.getClass().getName(); @@ -1143,90 +1148,42 @@ } /** - * Utility function used to copy a node list to be under a parent node. + * In a perfect world, this would be the implementation for + * nodeList2Iterator. In reality, though, this causes a + * ClassCastException in getDTMHandleFromNode because SAXImpl is + * not an instance of DOM2DTM. So we use the more lengthy + * implementation below until this issue has been addressed. + * + * @see org.apache.xml.dtm.ref.DTMManagerDefault#getDTMHandleFromNode */ - private static void copyNodes(org.w3c.dom.NodeList nodeList, - org.w3c.dom.Document doc, org.w3c.dom.Node parent) + private static DTMAxisIterator nodeList2IteratorUsingHandleFromNode( + org.w3c.dom.NodeList nodeList, + Translet translet, DOM dom) { - final int size = nodeList.getLength(); - - // copy Nodes from NodeList into new w3c DOM - for (int i = 0; i < size; i++) - { - org.w3c.dom.Node curr = nodeList.item(i); - int nodeType = curr.getNodeType(); - String value = null; - try { - value = curr.getNodeValue(); - } catch (DOMException ex) { - runTimeError(RUN_TIME_INTERNAL_ERR, ex.getMessage()); - return; + final int n = nodeList.getLength(); + final int[] dtmHandles = new int[n]; + DTMManager dtmManager = null; + if (dom instanceof MultiDOM) + dtmManager = ((MultiDOM) dom).getDTMManager(); + for (int i = 0; i < n; ++i) { + org.w3c.dom.Node node = nodeList.item(i); + int handle; + if (dtmManager != null) { + handle = dtmManager.getDTMHandleFromNode(node); } - - String nodeName = curr.getNodeName(); - org.w3c.dom.Node newNode = null; - switch (nodeType){ - case org.w3c.dom.Node.ATTRIBUTE_NODE: - newNode = doc.createAttributeNS(curr.getNamespaceURI(), - nodeName); - break; - case org.w3c.dom.Node.CDATA_SECTION_NODE: - newNode = doc.createCDATASection(value); - break; - case org.w3c.dom.Node.COMMENT_NODE: - newNode = doc.createComment(value); - break; - case org.w3c.dom.Node.DOCUMENT_FRAGMENT_NODE: - newNode = doc.createDocumentFragment(); - break; - case org.w3c.dom.Node.DOCUMENT_NODE: - newNode = doc.createElementNS(null, "__document__"); - copyNodes(curr.getChildNodes(), doc, newNode); - break; - case org.w3c.dom.Node.DOCUMENT_TYPE_NODE: - // nothing? - break; - case org.w3c.dom.Node.ELEMENT_NODE: - // For Element node, also copy the children and the - // attributes. - org.w3c.dom.Element element = doc.createElementNS( - curr.getNamespaceURI(), nodeName); - if (curr.hasAttributes()) - { - org.w3c.dom.NamedNodeMap attributes = curr.getAttributes(); - for (int k = 0; k < attributes.getLength(); k++) { - org.w3c.dom.Node attr = attributes.item(k); - element.setAttributeNS(attr.getNamespaceURI(), - attr.getNodeName(), attr.getNodeValue()); - } - } - copyNodes(curr.getChildNodes(), doc, element); - newNode = element; - break; - case org.w3c.dom.Node.ENTITY_NODE: - // nothing ? - break; - case org.w3c.dom.Node.ENTITY_REFERENCE_NODE: - newNode = doc.createEntityReference(nodeName); - break; - case org.w3c.dom.Node.NOTATION_NODE: - // nothing ? - break; - case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE: - newNode = doc.createProcessingInstruction(nodeName, - value); - break; - case org.w3c.dom.Node.TEXT_NODE: - newNode = doc.createTextNode(value); - break; + else if (node instanceof DTMNodeProxy + && ((DTMNodeProxy) node).getDTM() == dom) { + handle = ((DTMNodeProxy) node).getDTMNodeNumber(); } - try { - parent.appendChild(newNode); - } catch (DOMException e) { - runTimeError(RUN_TIME_INTERNAL_ERR, e.getMessage()); - return; + else { + runTimeError(RUN_TIME_INTERNAL_ERR, "need MultiDOM"); + return null; } + dtmHandles[i] = handle; + System.out.println("Node " + i + " has handle 0x" + + Integer.toString(handle, 16)); } + return new ArrayNodeListIterator(dtmHandles); } /** @@ -1237,26 +1194,93 @@ org.w3c.dom.NodeList nodeList, Translet translet, DOM dom) { - // w3c NodeList -> w3c DOM + // First pass: build w3c DOM for all nodes not proxied from our DOM. + // + // Notice: this looses some (esp. parent) context for these nodes, + // so some way to wrap the original nodes inside a DTMAxisIterator + // might be preferable in the long run. + int n = 0; // allow for change in list length, just in case. Document doc = null; - try { - doc = ((AbstractTranslet) translet).newDocument("", "__top__"); - } - catch (javax.xml.parsers.ParserConfigurationException e) { - runTimeError(RUN_TIME_INTERNAL_ERR, e.getMessage()); - return null; + DTMManager dtmManager = null; + int[] proxyNodes = new int[nodeList.getLength()]; + if (dom instanceof MultiDOM) + dtmManager = ((MultiDOM) dom).getDTMManager(); + for (int i = 0; i < nodeList.getLength(); ++i) { + org.w3c.dom.Node node = nodeList.item(i); + if (node instanceof DTMNodeProxy) { + DTMNodeProxy proxy = (DTMNodeProxy)node; + DTM nodeDTM = proxy.getDTM(); + int handle = proxy.getDTMNodeNumber(); + boolean isOurDOM = (nodeDTM == dom); + if (!isOurDOM && dtmManager != null) { + try { + isOurDOM = (nodeDTM == dtmManager.getDTM(handle)); + } + catch (ArrayIndexOutOfBoundsException e) { + // invalid node handle, so definitely not our doc + } + } + if (isOurDOM) { + proxyNodes[i] = handle; + ++n; + continue; + } + } + proxyNodes[i] = DTM.NULL; + int nodeType = node.getNodeType(); + if (doc == null) { + if (dom instanceof MultiDOM == false) { + runTimeError(RUN_TIME_INTERNAL_ERR, "need MultiDOM"); + return null; + } + try { + AbstractTranslet at = (AbstractTranslet) translet; + doc = at.newDocument("", "__top__"); + } + catch (javax.xml.parsers.ParserConfigurationException e) { + runTimeError(RUN_TIME_INTERNAL_ERR, e.getMessage()); + return null; + } + } + // Use one dummy element as container for each node of the + // list. That way, it is easier to detect resp. avoid + // funny things which change the number of nodes, + // e.g. auto-concatenation of text nodes. + Element mid; + switch (nodeType) { + case org.w3c.dom.Node.ELEMENT_NODE: + case org.w3c.dom.Node.TEXT_NODE: + case org.w3c.dom.Node.CDATA_SECTION_NODE: + case org.w3c.dom.Node.COMMENT_NODE: + case org.w3c.dom.Node.ENTITY_REFERENCE_NODE: + case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE: + mid = doc.createElementNS(null, "__dummy__"); + mid.appendChild(doc.importNode(node, true)); + doc.getDocumentElement().appendChild(mid); + ++n; + break; + case org.w3c.dom.Node.ATTRIBUTE_NODE: + // The mid element also serves as a container for + // attributes, avoiding problems with conflicting + // attributes or node order. + mid = doc.createElementNS(null, "__dummy__"); + mid.setAttributeNodeNS((Attr)doc.importNode(node, true)); + doc.getDocumentElement().appendChild(mid); + ++n; + break; + default: + // Better play it safe for all types we aren't sure we know + // how to deal with. + runTimeError(RUN_TIME_INTERNAL_ERR, + "Don't know how to convert node type " + + nodeType); + } } - // Copy all the nodes in the nodelist to be under the top element - copyNodes(nodeList, doc, doc.getDocumentElement()); - // w3cDOM -> DTM -> DOMImpl - if (dom instanceof MultiDOM) { + DTMAxisIterator iter = null, childIter = null, attrIter = null; + if (doc != null) { final MultiDOM multiDOM = (MultiDOM) dom; - - DTMDefaultBase dtm = (DTMDefaultBase)((DOMAdapter)multiDOM.getMain()).getDOMImpl(); - DTMManager dtmManager = dtm.getManager(); - DOM idom = (DOM)dtmManager.getDTM(new DOMSource(doc), false, null, true, false); // Create DOMAdapter and register with MultiDOM @@ -1269,16 +1293,57 @@ DTMAxisIterator iter1 = idom.getAxisIterator(Axis.CHILD); DTMAxisIterator iter2 = idom.getAxisIterator(Axis.CHILD); - DTMAxisIterator iter = new AbsoluteIterator( + iter = new AbsoluteIterator( new StepIterator(iter1, iter2)); iter.setStartNode(DTMDefaultBase.ROOTNODE); - return iter; + + childIter = idom.getAxisIterator(Axis.CHILD); + attrIter = idom.getAxisIterator(Axis.ATTRIBUTE); } - else { - runTimeError(RUN_TIME_INTERNAL_ERR, "nodeList2Iterator()"); - return null; + + // Second pass: find DTM handles for every node in the list. + int[] dtmHandles = new int[n]; + n = 0; + for (int i = 0; i < nodeList.getLength(); ++i) { + if (proxyNodes[i] != DTM.NULL) { + dtmHandles[n++] = proxyNodes[i]; + continue; + } + org.w3c.dom.Node node = nodeList.item(i); + DTMAxisIterator iter3 = null; + int nodeType = node.getNodeType(); + switch (nodeType) { + case org.w3c.dom.Node.ELEMENT_NODE: + case org.w3c.dom.Node.TEXT_NODE: + case org.w3c.dom.Node.CDATA_SECTION_NODE: + case org.w3c.dom.Node.COMMENT_NODE: + case org.w3c.dom.Node.ENTITY_REFERENCE_NODE: + case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE: + iter3 = childIter; + break; + case org.w3c.dom.Node.ATTRIBUTE_NODE: + iter3 = attrIter; + break; + default: + // Should not happen, as first run should have got all these + throw new InternalRuntimeError("Mismatched cases"); + } + if (iter3 != null) { + iter3.setStartNode(iter.next()); + dtmHandles[n] = iter3.next(); + // For now, play it self and perform extra checks: + if (dtmHandles[n] == DTMAxisIterator.END) + throw new InternalRuntimeError("Expected element missing at " + i); + if (iter3.next() != DTMAxisIterator.END) + throw new InternalRuntimeError("Too many elements at " + i); + ++n; + } } + if (n != dtmHandles.length) + throw new InternalRuntimeError("Nodes lost in second pass"); + + return new ArrayNodeListIterator(dtmHandles); } /** diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/runtime/Hashtable.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/runtime/Hashtable.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/runtime/Hashtable.java Tue Apr 17 11:17:59 2012 -0700 @@ -294,7 +294,7 @@ for (i = 0; i <= max; i++) { String s1 = k.nextElement().toString(); String s2 = e.nextElement().toString(); - buf.append(s1 + "=" + s2); + buf.append(s1).append('=').append(s2); if (i < max) buf.append(", "); } buf.append("}"); diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/runtime/InternalRuntimeError.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/runtime/InternalRuntimeError.java Tue Apr 17 11:17:59 2012 -0700 @@ -0,0 +1,36 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Copyright 2001-2004 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. + */ + +/* + * $Id: InternalRuntimeError.java,v 1.0 2009-11-25 04:34:28 joehw Exp $ + */ +package com.sun.org.apache.xalan.internal.xsltc.runtime; + +/** + * Class to express failed assertions and similar for the xsltc runtime. + * As java.lang.AssertionError was introduced in JDK 1.4 we can't use that yet. + */ +public class InternalRuntimeError extends Error { + + public InternalRuntimeError(String message) { + super(message); + } + +} diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/runtime/ObjectFactory.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/runtime/ObjectFactory.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,663 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2001-2004 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. - */ -/* - * $Id: ObjectFactory.java,v 1.2.4.1 2005/09/12 12:01:33 pvedula Exp $ - */ - -package com.sun.org.apache.xalan.internal.xsltc.runtime; - -import java.io.InputStream; -import java.io.IOException; -import java.io.File; -import java.io.FileInputStream; - -import java.util.Properties; -import java.io.BufferedReader; -import java.io.InputStreamReader; - -/** - * 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. - *

- * This code is designed to implement the JAXP 1.1 spec pluggability - * feature and is designed to run on JDK version 1.1 and - * later, and to compile on JDK 1.2 and onward. - * The code also runs both as part of an unbundled jar file and - * when bundled as part of the JDK. - *

- * This class was moved from the javax.xml.parsers.ObjectFactory - * class and modified to be used as a general utility for creating objects - * dynamically. - * - * @version $Id: ObjectFactory.java,v 1.9 2008/04/02 00:40:59 joehw Exp $ - */ -class ObjectFactory { - - // - // Constants - // - - // name of default properties file to look for in JDK's jre/lib directory - private static final String DEFAULT_PROPERTIES_FILENAME = - "xalan.properties"; - - private static final String SERVICES_PATH = "META-INF/services/"; - - /** Set to true for debugging */ - private static final boolean DEBUG = false; - - /** cache the contents of the xalan.properties file. - * Until an attempt has been made to read this file, this will - * be null; if the file does not exist or we encounter some other error - * during the read, this will be empty. - */ - private static Properties fXalanProperties = null; - - /*** - * Cache the time stamp of the xalan.properties file so - * that we know if it's been modified and can invalidate - * the cache when necessary. - */ - private static long fLastModified = -1; - - // - // Public static methods - // - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *

    - *
  1. query the system property using System.getProperty - *
  2. read META-INF/services/factoryId file - *
  3. use fallback classname - *
- * - * @return instance of factory, 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 no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Object createObject(String factoryId, String fallbackClassName) - throws ConfigurationError { - return createObject(factoryId, null, fallbackClassName); - } // createObject(String,String):Object - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return instance of factory, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Object createObject(String factoryId, - String propertiesFilename, - String fallbackClassName) - throws ConfigurationError - { - Class factoryClass = lookUpFactoryClass(factoryId, - propertiesFilename, - fallbackClassName); - - if (factoryClass == null) { - throw new ConfigurationError( - "Provider for " + factoryId + " cannot be found", null); - } - - try{ - Object instance = factoryClass.newInstance(); - if (DEBUG) debugPrintln("created new instance of factory " + factoryId); - return instance; - } catch (Exception x) { - throw new ConfigurationError( - "Provider for factory " + factoryId - + " could not be instantiated: " + x, x); - } - } // createObject(String,String,String):Object - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return Class object of factory, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Class lookUpFactoryClass(String factoryId) - throws ConfigurationError - { - return lookUpFactoryClass(factoryId, null, null); - } // lookUpFactoryClass(String):Class - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return Class object that provides factory service, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Class lookUpFactoryClass(String factoryId, - String propertiesFilename, - String fallbackClassName) - throws ConfigurationError - { - String factoryClassName = lookUpFactoryClassName(factoryId, - propertiesFilename, - fallbackClassName); - ClassLoader cl = findClassLoader(); - - if (factoryClassName == null) { - factoryClassName = fallbackClassName; - } - - // assert(className != null); - try{ - Class providerClass = findProviderClass(factoryClassName, - cl, - true); - if (DEBUG) debugPrintln("created new instance of " + providerClass + - " using ClassLoader: " + cl); - return providerClass; - } catch (ClassNotFoundException x) { - throw new ConfigurationError( - "Provider " + factoryClassName + " not found", x); - } catch (Exception x) { - throw new ConfigurationError( - "Provider "+factoryClassName+" could not be instantiated: "+x, - x); - } - } // lookUpFactoryClass(String,String,String):Class - - /** - * Finds the name of the required implementation class in the specified - * order. The specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return name of class that provides factory service, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static String lookUpFactoryClassName(String factoryId, - String propertiesFilename, - String fallbackClassName) - { - SecuritySupport ss = SecuritySupport.getInstance(); - - // Use the system property first - try { - String systemProp = ss.getSystemProperty(factoryId); - if (systemProp != null) { - if (DEBUG) debugPrintln("found system property, value=" + systemProp); - return systemProp; - } - } catch (SecurityException se) { - // Ignore and continue w/ next location - } - - // Try to read from propertiesFilename, or - // $java.home/lib/xalan.properties - String factoryClassName = null; - // no properties file name specified; use - // $JAVA_HOME/lib/xalan.properties: - if (propertiesFilename == null) { - File propertiesFile = null; - boolean propertiesFileExists = false; - try { - String javah = ss.getSystemProperty("java.home"); - propertiesFilename = javah + File.separator + - "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME; - propertiesFile = new File(propertiesFilename); - propertiesFileExists = ss.getFileExists(propertiesFile); - } catch (SecurityException e) { - // try again... - fLastModified = -1; - fXalanProperties = null; - } - - synchronized (ObjectFactory.class) { - boolean loadProperties = false; - FileInputStream fis = null; - try { - // file existed last time - if(fLastModified >= 0) { - if(propertiesFileExists && - (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) { - loadProperties = true; - } else { - // file has stopped existing... - if(!propertiesFileExists) { - fLastModified = -1; - fXalanProperties = null; - } // else, file wasn't modified! - } - } else { - // file has started to exist: - if(propertiesFileExists) { - loadProperties = true; - fLastModified = ss.getLastModified(propertiesFile); - } // else, nothing's changed - } - if(loadProperties) { - // must never have attempted to read xalan.properties - // before (or it's outdeated) - fXalanProperties = new Properties(); - fis = ss.getFileInputStream(propertiesFile); - fXalanProperties.load(fis); - } - } catch (Exception x) { - fXalanProperties = null; - fLastModified = -1; - // assert(x instanceof FileNotFoundException - // || x instanceof SecurityException) - // In both cases, ignore and continue w/ next location - } - finally { - // try to close the input stream if one was opened. - if (fis != null) { - try { - fis.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - } - } - if(fXalanProperties != null) { - factoryClassName = fXalanProperties.getProperty(factoryId); - } - } else { - FileInputStream fis = null; - try { - fis = ss.getFileInputStream(new File(propertiesFilename)); - Properties props = new Properties(); - props.load(fis); - factoryClassName = props.getProperty(factoryId); - } catch (Exception x) { - // assert(x instanceof FileNotFoundException - // || x instanceof SecurityException) - // In both cases, ignore and continue w/ next location - } - finally { - // try to close the input stream if one was opened. - if (fis != null) { - try { - fis.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - } - } - if (factoryClassName != null) { - if (DEBUG) debugPrintln("found in " + propertiesFilename + ", value=" - + factoryClassName); - return factoryClassName; - } - - // Try Jar Service Provider Mechanism - return findJarServiceProviderName(factoryId); - } // lookUpFactoryClass(String,String):String - - // - // Private static methods - // - - /** Prints a message to standard error if debugging is enabled. */ - private static void debugPrintln(String msg) { - if (DEBUG) { - System.err.println("JAXP: " + msg); - } - } // debugPrintln(String) - - /** - * Figure out which ClassLoader to use. For JDK 1.2 and later use - * the context ClassLoader. - */ - static ClassLoader findClassLoader() - 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 context = ss.getContextClassLoader(); - ClassLoader system = ss.getSystemClassLoader(); - - ClassLoader chain = system; - while (true) { - if (context == chain) { - // Assert: we are on JDK 1.1 or we have no Context ClassLoader - // or any Context ClassLoader in chain of system classloader - // (including extension ClassLoader) so extend to widest - // ClassLoader (always look in system ClassLoader if Xalan - // is in boot/extension/system classpath and in current - // ClassLoader otherwise); normal classloaders delegate - // back to system ClassLoader first so this widening doesn't - // change the fact that context ClassLoader will be consulted - ClassLoader current = ObjectFactory.class.getClassLoader(); - - chain = system; - while (true) { - if (current == chain) { - // Assert: Current ClassLoader in chain of - // boot/extension/system ClassLoaders - return system; - } - if (chain == null) { - break; - } - chain = ss.getParentClassLoader(chain); - } - - // Assert: Current ClassLoader not in chain of - // boot/extension/system ClassLoaders - return current; - } - - if (chain == null) { - // boot ClassLoader reached - break; - } - - // Check for any extension ClassLoaders in chain up to - // boot ClassLoader - chain = ss.getParentClassLoader(chain); - }; - - // Assert: Context ClassLoader not in chain of - // boot/extension/system ClassLoaders - return context; - } // findClassLoader():ClassLoader - - /** - * Create an instance of a class using the specified ClassLoader - */ - static Object newInstance(String className, ClassLoader cl, - boolean doFallback) - throws ConfigurationError - { - // assert(className != null); - try{ - Class providerClass = findProviderClass(className, cl, doFallback); - Object instance = providerClass.newInstance(); - if (DEBUG) debugPrintln("created new instance of " + providerClass + - " using ClassLoader: " + cl); - return instance; - } catch (ClassNotFoundException x) { - throw new ConfigurationError( - "Provider " + className + " not found", x); - } catch (Exception x) { - throw new ConfigurationError( - "Provider " + className + " could not be instantiated: " + x, - x); - } - } - - /** - * Find a Class using the specified ClassLoader - */ - static Class findProviderClass(String className, ClassLoader cl, - boolean doFallback) - throws ClassNotFoundException, ConfigurationError - { - //throw security exception if the calling thread is not allowed to access the - //class. Restrict the access to the package classes as specified in java.security policy. - SecurityManager security = System.getSecurityManager(); - try{ - if (security != null){ - final int lastDot = className.lastIndexOf("."); - String packageName = className; - if (lastDot != -1) packageName = className.substring(0, lastDot); - security.checkPackageAccess(packageName); - } - }catch(SecurityException e){ - throw e; - } - - Class providerClass; - 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 { - try { - providerClass = cl.loadClass(className); - } catch (ClassNotFoundException x) { - if (doFallback) { - // Fall back to current classloader - ClassLoader current = ObjectFactory.class.getClassLoader(); - if (current == null) { - providerClass = Class.forName(className); - } else if (cl != current) { - cl = current; - providerClass = cl.loadClass(className); - } else { - throw x; - } - } else { - throw x; - } - } - } - - return providerClass; - } - - /** - * Find the name of service provider using Jar Service Provider Mechanism - * - * @return instance of provider class if found or null - */ - private static String findJarServiceProviderName(String factoryId) - { - SecuritySupport ss = SecuritySupport.getInstance(); - String serviceId = SERVICES_PATH + factoryId; - InputStream is = null; - - // First try the Context ClassLoader - ClassLoader cl = findClassLoader(); - - is = ss.getResourceAsStream(cl, serviceId); - - // If no provider found then try the current ClassLoader - if (is == null) { - ClassLoader current = ObjectFactory.class.getClassLoader(); - if (cl != current) { - cl = current; - is = ss.getResourceAsStream(cl, serviceId); - } - } - - if (is == null) { - // No provider found - return null; - } - - if (DEBUG) debugPrintln("found jar resource=" + serviceId + - " using ClassLoader: " + cl); - - // 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)); - } - - String factoryClassName = null; - try { - // XXX Does not handle all possible input as specified by the - // Jar Service Provider specification - factoryClassName = rd.readLine(); - } catch (IOException x) { - // No provider found - return null; - } - finally { - try { - // try to close the reader. - rd.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - - if (factoryClassName != null && - ! "".equals(factoryClassName)) { - if (DEBUG) debugPrintln("found in resource, value=" - + factoryClassName); - - // Note: here we do not want to fall back to the current - // 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. - return factoryClassName; - } - - // No provider found - return null; - } - - // - // Classes - // - - /** - * A configuration error. - */ - static class ConfigurationError - extends Error { - static final long serialVersionUID = -2293620736651286953L; - // - // Data - // - - /** Exception. */ - private Exception exception; - - // - // Constructors - // - - /** - * Construct a new instance with the specified detail string and - * exception. - */ - ConfigurationError(String msg, Exception x) { - super(msg); - this.exception = x; - } // (String,Exception) - - // - // Public methods - // - - /** Returns the exception associated to this error. */ - Exception getException() { - return exception; - } // getException():Exception - - } // class ConfigurationError - -} // class ObjectFactory diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/runtime/SecuritySupport.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/runtime/SecuritySupport.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,127 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2002-2004 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. - */ -/* - * $Id: SecuritySupport.java,v 1.2.4.1 2005/09/06 11:28:13 pvedula Exp $ - */ - -package com.sun.org.apache.xalan.internal.xsltc.runtime; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.InputStream; - -import java.util.Properties; - -/** - * This class is duplicated for each Xalan-Java subpackage so keep it in sync. - * It is package private and therefore is not exposed as part of the Xalan-Java - * 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. - */ - static SecuritySupport getInstance() { - return (SecuritySupport)securitySupport; - } - - ClassLoader getContextClassLoader() { - return null; - } - - ClassLoader getSystemClassLoader() { - return null; - } - - ClassLoader getParentClassLoader(ClassLoader cl) { - return null; - } - - String getSystemProperty(String propName) { - return System.getProperty(propName); - } - - FileInputStream getFileInputStream(File file) - throws FileNotFoundException - { - return new FileInputStream(file); - } - - InputStream getResourceAsStream(ClassLoader cl, String name) { - InputStream ris; - if (cl == null) { - ris = ClassLoader.getSystemResourceAsStream(name); - } else { - ris = cl.getResourceAsStream(name); - } - return ris; - } - - boolean getFileExists(File f) { - return f.exists(); - } - - long getLastModified(File f) { - return f.lastModified(); - } -} diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/runtime/SecuritySupport12.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/runtime/SecuritySupport12.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,148 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2002-2004 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. - */ -/* - * $Id: SecuritySupport12.java,v 1.2.4.1 2005/09/06 11:31:16 pvedula Exp $ - */ - -package com.sun.org.apache.xalan.internal.xsltc.runtime; - -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; - -import java.util.Properties; - -/** - * This class is duplicated for each Xalan-Java subpackage so keep it in sync. - * It is package private and therefore is not exposed as part of the Xalan-Java - * API. - * - * Security related methods that only work on J2SE 1.2 and newer. - */ -class SecuritySupport12 extends SecuritySupport { - - ClassLoader getContextClassLoader() { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader cl = null; - try { - cl = Thread.currentThread().getContextClassLoader(); - } catch (SecurityException ex) { } - return cl; - } - }); - } - - ClassLoader getSystemClassLoader() { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader cl = null; - try { - cl = ClassLoader.getSystemClassLoader(); - } catch (SecurityException ex) {} - return cl; - } - }); - } - - ClassLoader getParentClassLoader(final ClassLoader cl) { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader parent = null; - try { - parent = cl.getParent(); - } catch (SecurityException ex) {} - - // eliminate loops in case of the boot - // ClassLoader returning itself as a parent - return (parent == cl) ? null : parent; - } - }); - } - - String getSystemProperty(final String propName) { - return (String) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return System.getProperty(propName); - } - }); - } - - 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(); - } - } - - 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; - } - }); - } - - boolean getFileExists(final File f) { - return ((Boolean) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return new Boolean(f.exists()); - } - })).booleanValue(); - } - - long getLastModified(final File f) { - return ((Long) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return new Long(f.lastModified()); - } - })).longValue(); - } - -} diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/runtime/output/TransletOutputHandlerFactory.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/runtime/output/TransletOutputHandlerFactory.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/runtime/output/TransletOutputHandlerFactory.java Tue Apr 17 11:17:59 2012 -0700 @@ -72,10 +72,18 @@ private ContentHandler _handler = null; private LexicalHandler _lexHandler = null; + private boolean _useServicesMechanism; + static public TransletOutputHandlerFactory newInstance() { - return new TransletOutputHandlerFactory(); + return new TransletOutputHandlerFactory(true); + } + static public TransletOutputHandlerFactory newInstance(boolean useServicesMechanism) { + return new TransletOutputHandlerFactory(useServicesMechanism); } + public TransletOutputHandlerFactory(boolean useServicesMechanism) { + _useServicesMechanism = useServicesMechanism; + } public void setOutputType(int outputType) { _outputType = outputType; } @@ -188,7 +196,7 @@ return result; case DOM : - _handler = (_node != null) ? new SAX2DOM(_node, _nextSibling) : new SAX2DOM(); + _handler = (_node != null) ? new SAX2DOM(_node, _nextSibling, _useServicesMechanism) : new SAX2DOM(_useServicesMechanism); _lexHandler = (LexicalHandler) _handler; // falls through case STAX : diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/trax/ObjectFactory.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/trax/ObjectFactory.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,663 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2001-2004 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. - */ -/* - * $Id: ObjectFactory.java,v 1.2.4.1 2005/09/12 12:05:22 pvedula Exp $ - */ - -package com.sun.org.apache.xalan.internal.xsltc.trax; - -import java.io.InputStream; -import java.io.IOException; -import java.io.File; -import java.io.FileInputStream; - -import java.util.Properties; -import java.io.BufferedReader; -import java.io.InputStreamReader; - -/** - * 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. - *

- * This code is designed to implement the JAXP 1.1 spec pluggability - * feature and is designed to run on JDK version 1.1 and - * later, and to compile on JDK 1.2 and onward. - * The code also runs both as part of an unbundled jar file and - * when bundled as part of the JDK. - *

- * This class was moved from the javax.xml.parsers.ObjectFactory - * class and modified to be used as a general utility for creating objects - * dynamically. - * - * @version $Id: ObjectFactory.java,v 1.9 2008/04/02 00:41:02 joehw Exp $ - */ -class ObjectFactory { - - // - // Constants - // - - // name of default properties file to look for in JDK's jre/lib directory - private static final String DEFAULT_PROPERTIES_FILENAME = - "xalan.properties"; - - private static final String SERVICES_PATH = "META-INF/services/"; - - /** Set to true for debugging */ - private static final boolean DEBUG = false; - - /** cache the contents of the xalan.properties file. - * Until an attempt has been made to read this file, this will - * be null; if the file does not exist or we encounter some other error - * during the read, this will be empty. - */ - private static Properties fXalanProperties = null; - - /*** - * Cache the time stamp of the xalan.properties file so - * that we know if it's been modified and can invalidate - * the cache when necessary. - */ - private static long fLastModified = -1; - - // - // Public static methods - // - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *

    - *
  1. query the system property using System.getProperty - *
  2. read META-INF/services/factoryId file - *
  3. use fallback classname - *
- * - * @return instance of factory, 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 no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Object createObject(String factoryId, String fallbackClassName) - throws ConfigurationError { - return createObject(factoryId, null, fallbackClassName); - } // createObject(String,String):Object - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return instance of factory, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Object createObject(String factoryId, - String propertiesFilename, - String fallbackClassName) - throws ConfigurationError - { - Class factoryClass = lookUpFactoryClass(factoryId, - propertiesFilename, - fallbackClassName); - - if (factoryClass == null) { - throw new ConfigurationError( - "Provider for " + factoryId + " cannot be found", null); - } - - try{ - Object instance = factoryClass.newInstance(); - if (DEBUG) debugPrintln("created new instance of factory " + factoryId); - return instance; - } catch (Exception x) { - throw new ConfigurationError( - "Provider for factory " + factoryId - + " could not be instantiated: " + x, x); - } - } // createObject(String,String,String):Object - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return Class object of factory, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Class lookUpFactoryClass(String factoryId) - throws ConfigurationError - { - return lookUpFactoryClass(factoryId, null, null); - } // lookUpFactoryClass(String):Class - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return Class object that provides factory service, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Class lookUpFactoryClass(String factoryId, - String propertiesFilename, - String fallbackClassName) - throws ConfigurationError - { - String factoryClassName = lookUpFactoryClassName(factoryId, - propertiesFilename, - fallbackClassName); - ClassLoader cl = findClassLoader(); - - if (factoryClassName == null) { - factoryClassName = fallbackClassName; - } - - // assert(className != null); - try{ - Class providerClass = findProviderClass(factoryClassName, - cl, - true); - if (DEBUG) debugPrintln("created new instance of " + providerClass + - " using ClassLoader: " + cl); - return providerClass; - } catch (ClassNotFoundException x) { - throw new ConfigurationError( - "Provider " + factoryClassName + " not found", x); - } catch (Exception x) { - throw new ConfigurationError( - "Provider "+factoryClassName+" could not be instantiated: "+x, - x); - } - } // lookUpFactoryClass(String,String,String):Class - - /** - * Finds the name of the required implementation class in the specified - * order. The specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return name of class that provides factory service, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static String lookUpFactoryClassName(String factoryId, - String propertiesFilename, - String fallbackClassName) - { - SecuritySupport ss = SecuritySupport.getInstance(); - - // Use the system property first - try { - String systemProp = ss.getSystemProperty(factoryId); - if (systemProp != null) { - if (DEBUG) debugPrintln("found system property, value=" + systemProp); - return systemProp; - } - } catch (SecurityException se) { - // Ignore and continue w/ next location - } - - // Try to read from propertiesFilename, or - // $java.home/lib/xalan.properties - String factoryClassName = null; - // no properties file name specified; use - // $JAVA_HOME/lib/xalan.properties: - if (propertiesFilename == null) { - File propertiesFile = null; - boolean propertiesFileExists = false; - try { - String javah = ss.getSystemProperty("java.home"); - propertiesFilename = javah + File.separator + - "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME; - propertiesFile = new File(propertiesFilename); - propertiesFileExists = ss.getFileExists(propertiesFile); - } catch (SecurityException e) { - // try again... - fLastModified = -1; - fXalanProperties = null; - } - - synchronized (ObjectFactory.class) { - boolean loadProperties = false; - FileInputStream fis = null; - try { - // file existed last time - if(fLastModified >= 0) { - if(propertiesFileExists && - (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) { - loadProperties = true; - } else { - // file has stopped existing... - if(!propertiesFileExists) { - fLastModified = -1; - fXalanProperties = null; - } // else, file wasn't modified! - } - } else { - // file has started to exist: - if(propertiesFileExists) { - loadProperties = true; - fLastModified = ss.getLastModified(propertiesFile); - } // else, nothing's changed - } - if(loadProperties) { - // must never have attempted to read xalan.properties - // before (or it's outdeated) - fXalanProperties = new Properties(); - fis = ss.getFileInputStream(propertiesFile); - fXalanProperties.load(fis); - } - } catch (Exception x) { - fXalanProperties = null; - fLastModified = -1; - // assert(x instanceof FileNotFoundException - // || x instanceof SecurityException) - // In both cases, ignore and continue w/ next location - } - finally { - // try to close the input stream if one was opened. - if (fis != null) { - try { - fis.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - } - } - if(fXalanProperties != null) { - factoryClassName = fXalanProperties.getProperty(factoryId); - } - } else { - FileInputStream fis = null; - try { - fis = ss.getFileInputStream(new File(propertiesFilename)); - Properties props = new Properties(); - props.load(fis); - factoryClassName = props.getProperty(factoryId); - } catch (Exception x) { - // assert(x instanceof FileNotFoundException - // || x instanceof SecurityException) - // In both cases, ignore and continue w/ next location - } - finally { - // try to close the input stream if one was opened. - if (fis != null) { - try { - fis.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - } - } - if (factoryClassName != null) { - if (DEBUG) debugPrintln("found in " + propertiesFilename + ", value=" - + factoryClassName); - return factoryClassName; - } - - // Try Jar Service Provider Mechanism - return findJarServiceProviderName(factoryId); - } // lookUpFactoryClass(String,String):String - - // - // Private static methods - // - - /** Prints a message to standard error if debugging is enabled. */ - private static void debugPrintln(String msg) { - if (DEBUG) { - System.err.println("JAXP: " + msg); - } - } // debugPrintln(String) - - /** - * Figure out which ClassLoader to use. For JDK 1.2 and later use - * the context ClassLoader. - */ - static ClassLoader findClassLoader() - 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 context = ss.getContextClassLoader(); - ClassLoader system = ss.getSystemClassLoader(); - - ClassLoader chain = system; - while (true) { - if (context == chain) { - // Assert: we are on JDK 1.1 or we have no Context ClassLoader - // or any Context ClassLoader in chain of system classloader - // (including extension ClassLoader) so extend to widest - // ClassLoader (always look in system ClassLoader if Xalan - // is in boot/extension/system classpath and in current - // ClassLoader otherwise); normal classloaders delegate - // back to system ClassLoader first so this widening doesn't - // change the fact that context ClassLoader will be consulted - ClassLoader current = ObjectFactory.class.getClassLoader(); - - chain = system; - while (true) { - if (current == chain) { - // Assert: Current ClassLoader in chain of - // boot/extension/system ClassLoaders - return system; - } - if (chain == null) { - break; - } - chain = ss.getParentClassLoader(chain); - } - - // Assert: Current ClassLoader not in chain of - // boot/extension/system ClassLoaders - return current; - } - - if (chain == null) { - // boot ClassLoader reached - break; - } - - // Check for any extension ClassLoaders in chain up to - // boot ClassLoader - chain = ss.getParentClassLoader(chain); - }; - - // Assert: Context ClassLoader not in chain of - // boot/extension/system ClassLoaders - return context; - } // findClassLoader():ClassLoader - - /** - * Create an instance of a class using the specified ClassLoader - */ - static Object newInstance(String className, ClassLoader cl, - boolean doFallback) - throws ConfigurationError - { - // assert(className != null); - try{ - Class providerClass = findProviderClass(className, cl, doFallback); - Object instance = providerClass.newInstance(); - if (DEBUG) debugPrintln("created new instance of " + providerClass + - " using ClassLoader: " + cl); - return instance; - } catch (ClassNotFoundException x) { - throw new ConfigurationError( - "Provider " + className + " not found", x); - } catch (Exception x) { - throw new ConfigurationError( - "Provider " + className + " could not be instantiated: " + x, - x); - } - } - - /** - * Find a Class using the specified ClassLoader - */ - static Class findProviderClass(String className, ClassLoader cl, - boolean doFallback) - throws ClassNotFoundException, ConfigurationError - { - //throw security exception if the calling thread is not allowed to access the - //class. Restrict the access to the package classes as specified in java.security policy. - SecurityManager security = System.getSecurityManager(); - try{ - if (security != null){ - final int lastDot = className.lastIndexOf("."); - String packageName = className; - if (lastDot != -1) packageName = className.substring(0, lastDot); - security.checkPackageAccess(packageName); - } - }catch(SecurityException e){ - throw e; - } - - Class providerClass; - 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 { - try { - providerClass = cl.loadClass(className); - } catch (ClassNotFoundException x) { - if (doFallback) { - // Fall back to current classloader - ClassLoader current = ObjectFactory.class.getClassLoader(); - if (current == null) { - providerClass = Class.forName(className); - } else if (cl != current) { - cl = current; - providerClass = cl.loadClass(className); - } else { - throw x; - } - } else { - throw x; - } - } - } - - return providerClass; - } - - /** - * Find the name of service provider using Jar Service Provider Mechanism - * - * @return instance of provider class if found or null - */ - private static String findJarServiceProviderName(String factoryId) - { - SecuritySupport ss = SecuritySupport.getInstance(); - String serviceId = SERVICES_PATH + factoryId; - InputStream is = null; - - // First try the Context ClassLoader - ClassLoader cl = findClassLoader(); - - is = ss.getResourceAsStream(cl, serviceId); - - // If no provider found then try the current ClassLoader - if (is == null) { - ClassLoader current = ObjectFactory.class.getClassLoader(); - if (cl != current) { - cl = current; - is = ss.getResourceAsStream(cl, serviceId); - } - } - - if (is == null) { - // No provider found - return null; - } - - if (DEBUG) debugPrintln("found jar resource=" + serviceId + - " using ClassLoader: " + cl); - - // 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)); - } - - String factoryClassName = null; - try { - // XXX Does not handle all possible input as specified by the - // Jar Service Provider specification - factoryClassName = rd.readLine(); - } catch (IOException x) { - // No provider found - return null; - } - finally { - try { - // try to close the reader. - rd.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - - if (factoryClassName != null && - ! "".equals(factoryClassName)) { - if (DEBUG) debugPrintln("found in resource, value=" - + factoryClassName); - - // Note: here we do not want to fall back to the current - // 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. - return factoryClassName; - } - - // No provider found - return null; - } - - // - // Classes - // - - /** - * A configuration error. - */ - static class ConfigurationError - extends Error { - static final long serialVersionUID = -1877553852268428278L; - // - // Data - // - - /** Exception. */ - private Exception exception; - - // - // Constructors - // - - /** - * Construct a new instance with the specified detail string and - * exception. - */ - ConfigurationError(String msg, Exception x) { - super(msg); - this.exception = x; - } // (String,Exception) - - // - // Public methods - // - - /** Returns the exception associated to this error. */ - Exception getException() { - return exception; - } // getException():Exception - - } // class ConfigurationError - -} // class ObjectFactory diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/trax/SAX2DOM.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/trax/SAX2DOM.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/trax/SAX2DOM.java Tue Apr 17 11:17:59 2012 -0700 @@ -49,6 +49,7 @@ /** * @author G. Todd Miller * @author Sunitha Reddy + * @author Huizhe Wang */ public class SAX2DOM implements ContentHandler, LexicalHandler, Constants { @@ -69,27 +70,16 @@ * synchronization because the Javadoc is not explicit about * thread safety. */ - static final DocumentBuilderFactory _factory = + private DocumentBuilderFactory _factory = DocumentBuilderFactory.newInstance(); - static final DocumentBuilder _internalBuilder; - static { - DocumentBuilder tmpBuilder = null; - try { - if (_factory instanceof com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl) { - tmpBuilder = _factory.newDocumentBuilder(); - } - } catch(Exception e) { - // It's OK. Will create DocumentBuilder every time - } - _internalBuilder = tmpBuilder; - } + private boolean _internal = true; - public SAX2DOM() throws ParserConfigurationException { - _document = createDocument(); + public SAX2DOM(boolean useServicesMachnism) throws ParserConfigurationException { + _document = createDocument(useServicesMachnism); _root = _document; } - public SAX2DOM(Node root, Node nextSibling) throws ParserConfigurationException { + public SAX2DOM(Node root, Node nextSibling, boolean useServicesMachnism) throws ParserConfigurationException { _root = root; if (root instanceof Document) { _document = (Document)root; @@ -98,15 +88,15 @@ _document = root.getOwnerDocument(); } else { - _document = createDocument(); + _document = createDocument(useServicesMachnism); _root = _document; } _nextSibling = nextSibling; } - public SAX2DOM(Node root) throws ParserConfigurationException { - this(root, null); + public SAX2DOM(Node root, boolean useServicesMachnism) throws ParserConfigurationException { + this(root, null, useServicesMachnism); } public Node getDOM() { @@ -318,11 +308,23 @@ public void startDTD(String name, String publicId, String systemId) throws SAXException {} - private static Document createDocument() throws ParserConfigurationException { + private Document createDocument(boolean useServicesMachnism) throws ParserConfigurationException { + if (_factory == null) { + if (useServicesMachnism) + _factory = DocumentBuilderFactory.newInstance(); + if (!(_factory instanceof com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl)) { + _internal = false; + } + else + _factory = DocumentBuilderFactory.newInstance( + "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl", + SAX2DOM.class.getClassLoader() + ); + } Document doc; - if (_internalBuilder != null) { + if (_internal) { //default implementation is thread safe - doc = _internalBuilder.newDocument(); + doc = _factory.newDocumentBuilder().newDocument(); } else { synchronized(SAX2DOM.class) { doc = _factory.newDocumentBuilder().newDocument(); diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/trax/SecuritySupport.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/trax/SecuritySupport.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,127 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2002-2004 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. - */ -/* - * $Id: SecuritySupport.java,v 1.2.4.1 2005/09/06 12:04:10 pvedula Exp $ - */ - -package com.sun.org.apache.xalan.internal.xsltc.trax; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.InputStream; - -import java.util.Properties; - -/** - * This class is duplicated for each Xalan-Java subpackage so keep it in sync. - * It is package private and therefore is not exposed as part of the Xalan-Java - * 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. - */ - static SecuritySupport getInstance() { - return (SecuritySupport)securitySupport; - } - - ClassLoader getContextClassLoader() { - return null; - } - - ClassLoader getSystemClassLoader() { - return null; - } - - ClassLoader getParentClassLoader(ClassLoader cl) { - return null; - } - - String getSystemProperty(String propName) { - return System.getProperty(propName); - } - - FileInputStream getFileInputStream(File file) - throws FileNotFoundException - { - return new FileInputStream(file); - } - - InputStream getResourceAsStream(ClassLoader cl, String name) { - InputStream ris; - if (cl == null) { - ris = ClassLoader.getSystemResourceAsStream(name); - } else { - ris = cl.getResourceAsStream(name); - } - return ris; - } - - boolean getFileExists(File f) { - return f.exists(); - } - - long getLastModified(File f) { - return f.lastModified(); - } -} diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/trax/SecuritySupport12.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/trax/SecuritySupport12.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,148 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2002-2004 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. - */ -/* - * $Id: SecuritySupport12.java,v 1.2.4.1 2005/09/06 12:05:26 pvedula Exp $ - */ - -package com.sun.org.apache.xalan.internal.xsltc.trax; - -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; - -import java.util.Properties; - -/** - * This class is duplicated for each Xalan-Java subpackage so keep it in sync. - * It is package private and therefore is not exposed as part of the Xalan-Java - * API. - * - * Security related methods that only work on J2SE 1.2 and newer. - */ -class SecuritySupport12 extends SecuritySupport { - - ClassLoader getContextClassLoader() { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader cl = null; - try { - cl = Thread.currentThread().getContextClassLoader(); - } catch (SecurityException ex) { } - return cl; - } - }); - } - - ClassLoader getSystemClassLoader() { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader cl = null; - try { - cl = ClassLoader.getSystemClassLoader(); - } catch (SecurityException ex) {} - return cl; - } - }); - } - - ClassLoader getParentClassLoader(final ClassLoader cl) { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader parent = null; - try { - parent = cl.getParent(); - } catch (SecurityException ex) {} - - // eliminate loops in case of the boot - // ClassLoader returning itself as a parent - return (parent == cl) ? null : parent; - } - }); - } - - String getSystemProperty(final String propName) { - return (String) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return System.getProperty(propName); - } - }); - } - - 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(); - } - } - - 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; - } - }); - } - - boolean getFileExists(final File f) { - return ((Boolean) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return new Boolean(f.exists()); - } - })).booleanValue(); - } - - long getLastModified(final File f) { - return ((Long) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return new Long(f.lastModified()); - } - })).longValue(); - } - -} diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/trax/SmartTransformerFactoryImpl.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/trax/SmartTransformerFactoryImpl.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/trax/SmartTransformerFactoryImpl.java Tue Apr 17 11:17:59 2012 -0700 @@ -43,6 +43,7 @@ import javax.xml.transform.stream.StreamSource; import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg; +import com.sun.org.apache.xalan.internal.utils.ObjectFactory; import org.xml.sax.XMLFilter; /** @@ -93,7 +94,7 @@ try { Class xalanFactClass = ObjectFactory.findProviderClass( "com.sun.org.apache.xalan.internal.processor.TransformerFactoryImpl", - ObjectFactory.findClassLoader(), true); + true); _xalanFactory = (SAXTransformerFactory) xalanFactClass.newInstance(); } diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesHandlerImpl.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesHandlerImpl.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesHandlerImpl.java Tue Apr 17 11:17:59 2012 -0700 @@ -95,10 +95,15 @@ _tfactory = tfactory; // Instantiate XSLTC and get reference to parser object - XSLTC xsltc = new XSLTC(); + XSLTC xsltc = new XSLTC(tfactory.useServicesMechnism()); if (tfactory.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING)) xsltc.setSecureProcessing(true); + if ("true".equals(tfactory.getAttribute(TransformerFactoryImpl.ENABLE_INLINING))) + xsltc.setTemplateInlining(true); + else + xsltc.setTemplateInlining(false); + _parser = xsltc.getParser(); } @@ -188,7 +193,7 @@ XSLTC xsltc = _parser.getXSLTC(); // Set the translet class name if not already set - String transletName = null; + String transletName; if (_systemId != null) { transletName = Util.baseName(_systemId); } @@ -210,6 +215,11 @@ stylesheet.setSystemId(_systemId); stylesheet.setParentStylesheet(null); + if (xsltc.getTemplateInlining()) + stylesheet.setTemplateInlining(true); + else + stylesheet.setTemplateInlining(false); + // Set a document loader (for xsl:include/import) if defined if (_uriResolver != null) { stylesheet.setSourceLoader(this); diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesImpl.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesImpl.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesImpl.java Tue Apr 17 11:17:59 2012 -0700 @@ -42,6 +42,7 @@ import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg; import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet; import com.sun.org.apache.xalan.internal.xsltc.runtime.Hashtable; +import com.sun.org.apache.xalan.internal.utils.ObjectFactory; /** * @author Morten Jorgensen @@ -118,6 +119,8 @@ */ private transient TransformerFactoryImpl _tfactory = null; + private boolean _useServicesMechanism; + static final class TransletClassLoader extends ClassLoader { TransletClassLoader(ClassLoader parent) { super(parent); @@ -142,10 +145,7 @@ TransformerFactoryImpl tfactory) { _bytecodes = bytecodes; - _name = transletName; - _outputProperties = outputProperties; - _indentNumber = indentNumber; - _tfactory = tfactory; + init(transletName, outputProperties, indentNumber, tfactory); } /** @@ -156,14 +156,19 @@ TransformerFactoryImpl tfactory) { _class = transletClasses; + _transletIndex = 0; + init(transletName, outputProperties, indentNumber, tfactory); + } + + private void init(String transletName, + Properties outputProperties, int indentNumber, + TransformerFactoryImpl tfactory) { _name = transletName; - _transletIndex = 0; _outputProperties = outputProperties; _indentNumber = indentNumber; _tfactory = tfactory; + _useServicesMechanism = tfactory.useServicesMechnism(); } - - /** * Need for de-serialization, see readObject(). */ @@ -207,6 +212,12 @@ } } + /** + * Return the state of the services mechanism feature. + */ + public boolean useServicesMechnism() { + return _useServicesMechanism; + } /** * Store URIResolver needed for Transformers. @@ -357,6 +368,7 @@ AbstractTranslet translet = (AbstractTranslet) _class[_transletIndex].newInstance(); translet.postInitialization(); translet.setTemplates(this); + translet.setServicesMechnism(_useServicesMechanism); if (_auxClasses != null) { translet.setAuxiliaryClasses(_auxClasses); } diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/trax/TrAXFilter.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/trax/TrAXFilter.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/trax/TrAXFilter.java Tue Apr 17 11:17:59 2012 -0700 @@ -55,6 +55,7 @@ private Templates _templates; private TransformerImpl _transformer; private TransformerHandlerImpl _transformerHandler; + private boolean _useServicesMechanism = true; public TrAXFilter(Templates templates) throws TransformerConfigurationException @@ -62,6 +63,7 @@ _templates = templates; _transformer = (TransformerImpl) templates.newTransformer(); _transformerHandler = new TransformerHandlerImpl(_transformer); + _useServicesMechanism = _transformer.useServicesMechnism(); } public Transformer getTransformer() { @@ -106,7 +108,7 @@ try { if (getParent() == null) { try { - managedReader = XMLReaderManager.getInstance() + managedReader = XMLReaderManager.getInstance(_useServicesMechanism) .getXMLReader(); setParent(managedReader); } catch (SAXException e) { @@ -118,7 +120,7 @@ getParent().parse(input); } finally { if (managedReader != null) { - XMLReaderManager.getInstance().releaseXMLReader(managedReader); + XMLReaderManager.getInstance(_useServicesMechanism).releaseXMLReader(managedReader); } } } diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java Tue Apr 17 11:17:59 2012 -0700 @@ -49,6 +49,7 @@ import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; import javax.xml.transform.URIResolver; import javax.xml.transform.dom.DOMResult; import javax.xml.transform.dom.DOMSource; @@ -64,11 +65,14 @@ import com.sun.org.apache.xml.internal.utils.StylesheetPIHandler; import com.sun.org.apache.xml.internal.utils.StopParseException; +import com.sun.org.apache.xalan.internal.XalanConstants; import com.sun.org.apache.xalan.internal.xsltc.compiler.Constants; import com.sun.org.apache.xalan.internal.xsltc.compiler.SourceLoader; import com.sun.org.apache.xalan.internal.xsltc.compiler.XSLTC; import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg; import com.sun.org.apache.xalan.internal.xsltc.dom.XSLTCDTMManager; +import com.sun.org.apache.xalan.internal.utils.ObjectFactory; +import com.sun.org.apache.xalan.internal.utils.FactoryImpl; import org.xml.sax.InputSource; @@ -212,11 +216,28 @@ *

State of secure mode.

*/ private boolean _isSecureMode = false; + + /** + * Indicates whether implementation parts should use + * service loader (or similar). + * Note the default value (false) is the safe option.. + */ + private boolean _useServicesMechanism; + /** * javax.xml.transform.sax.TransformerFactory implementation. */ public TransformerFactoryImpl() { - m_DTMManagerClass = XSLTCDTMManager.getDTMManagerClass(); + this(true); + } + + public static TransformerFactory newTransformerFactoryNoServiceLoader() { + return new TransformerFactoryImpl(false); + } + + private TransformerFactoryImpl(boolean useServicesMechanism) { + this.m_DTMManagerClass = XSLTCDTMManager.getDTMManagerClass(useServicesMechanism); + this._useServicesMechanism = useServicesMechanism; if (System.getSecurityManager() != null) { _isSecureMode = true; _isNotSecureProcessing = false; @@ -274,6 +295,12 @@ else if (name.equals(AUTO_TRANSLET)) { return new Boolean(_autoTranslet); } + else if (name.equals(ENABLE_INLINING)) { + if (_enableInlining) + return Boolean.TRUE; + else + return Boolean.FALSE; + } // Throw an exception for all other attributes ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_INVALID_ATTR_ERR, name); @@ -420,6 +447,11 @@ // all done processing feature return; } + else if (name.equals(XalanConstants.ORACLE_FEATURE_SERVICE_MECHANISM)) { + //in secure mode, let _useServicesMechanism be determined by the constructor + if (!_isSecureMode) + _useServicesMechanism = value; + } else { // unknown feature ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_UNSUPPORTED_FEATURE, name); @@ -448,7 +480,8 @@ StreamSource.FEATURE, StreamResult.FEATURE, SAXTransformerFactory.FEATURE, - SAXTransformerFactory.FEATURE_XMLFILTER + SAXTransformerFactory.FEATURE_XMLFILTER, + XalanConstants.ORACLE_FEATURE_SERVICE_MECHANISM }; // feature name cannot be null @@ -471,6 +504,12 @@ // Feature not supported return false; } + /** + * Return the state of the services mechanism feature. + */ + public boolean useServicesMechnism() { + return _useServicesMechanism; + } /** * javax.xml.transform.sax.TransformerFactory implementation. @@ -543,7 +582,7 @@ isource = SAXSource.sourceToInputSource(source); baseId = isource.getSystemId(); - SAXParserFactory factory = SAXParserFactory.newInstance(); + SAXParserFactory factory = FactoryImpl.getSAXFactory(_useServicesMechanism); factory.setNamespaceAware(true); if (!_isNotSecureProcessing) { @@ -702,8 +741,7 @@ transletName = _packageName + "." + transletName; try { - final Class clazz = ObjectFactory.findProviderClass( - transletName, ObjectFactory.findClassLoader(), true); + final Class clazz = ObjectFactory.findProviderClass(transletName, true); resetTransientAttributes(); return new TemplatesImpl(new Class[]{clazz}, transletName, null, _indentNumber, this); @@ -753,9 +791,13 @@ } // Create and initialize a stylesheet compiler - final XSLTC xsltc = new XSLTC(); + final XSLTC xsltc = new XSLTC(_useServicesMechanism); if (_debug) xsltc.setDebug(true); - if (_enableInlining) xsltc.setTemplateInlining(true); + if (_enableInlining) + xsltc.setTemplateInlining(true); + else + xsltc.setTemplateInlining(false); + if (!_isNotSecureProcessing) xsltc.setSecureProcessing(true); xsltc.init(); diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java Tue Apr 17 11:17:59 2012 -0700 @@ -23,6 +23,7 @@ package com.sun.org.apache.xalan.internal.xsltc.trax; +import com.sun.org.apache.xalan.internal.utils.FactoryImpl; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -182,7 +183,7 @@ /** * A reference to an object that creates and caches XMLReader objects. */ - private XMLReaderManager _readerManager = XMLReaderManager.getInstance(); + private XMLReaderManager _readerManager; /** * A flag indicating whether we use incremental building of the DTM. @@ -201,6 +202,13 @@ private boolean _isSecureProcessing = false; /** + * Indicates whether implementation parts should use + * service loader (or similar). + * Note the default value (false) is the safe option.. + */ + private boolean _useServicesMechanism; + + /** * A hashtable to store parameters for the identity transform. These * are not needed during the transformation, but we must keep track of * them to be fully complaint with the JAXP API. @@ -251,6 +259,8 @@ _propertiesClone = (Properties) _properties.clone(); _indentNumber = indentNumber; _tfactory = tfactory; + _useServicesMechanism = _tfactory.useServicesMechnism(); + _readerManager = XMLReaderManager.getInstance(_useServicesMechanism); //_isIncremental = tfactory._incremental; } @@ -267,6 +277,19 @@ public void setSecureProcessing(boolean flag) { _isSecureProcessing = flag; } + /** + * Return the state of the services mechanism feature. + */ + public boolean useServicesMechnism() { + return _useServicesMechanism; + } + + /** + * Set the state of the services mechanism feature. + */ + public void setServicesMechnism(boolean flag) { + _useServicesMechanism = flag; + } /** * Returns the translet wrapped inside this Transformer or @@ -347,7 +370,7 @@ // Get encoding using getProperty() to use defaults _encoding = (String) _properties.getProperty(OutputKeys.ENCODING); - _tohFactory = TransletOutputHandlerFactory.newInstance(); + _tohFactory = TransletOutputHandlerFactory.newInstance(_useServicesMechanism); _tohFactory.setEncoding(_encoding); if (_method != null) { _tohFactory.setOutputMethod(_method); @@ -435,9 +458,7 @@ // the systemId will be URI encoded as a result of File.toURI(), // it must be decoded for use by URL try{ - Class clazz = ObjectFactory.findProviderClass("java.net.URI", ObjectFactory.findClassLoader(), true); - Constructor construct = clazz.getConstructor(new Class[] {java.lang.String.class} ); - URI uri = (URI) construct.newInstance(new Object[]{systemId}) ; + URI uri = new URI(systemId) ; systemId = "file:"; String host = uri.getHost(); // decoded String @@ -454,10 +475,6 @@ systemId += "//" + path; } } - catch(ClassNotFoundException e){ - // running on J2SE 1.3 which doesn't have URI Class so OK to ignore - //ClassNotFoundException. - } catch (Exception exception) { // URI exception which means nothing can be done so OK to ignore } @@ -524,6 +541,7 @@ _dtmManager = (XSLTCDTMManager)_tfactory.getDTMManagerClass() .newInstance(); + _dtmManager.setServicesMechnism(_useServicesMechanism); } dom = (DOM)_dtmManager.getDTM(source, false, wsfilter, true, false, false, 0, hasIdCall); @@ -695,10 +713,8 @@ ((SAXSource)source).getXMLReader()==null )|| (source instanceof DOMSource && ((DOMSource)source).getNode()==null)){ - DocumentBuilderFactory builderF = - DocumentBuilderFactory.newInstance(); - DocumentBuilder builder = - builderF.newDocumentBuilder(); + DocumentBuilderFactory builderF = FactoryImpl.getDOMFactory(_useServicesMechanism); + DocumentBuilder builder = builderF.newDocumentBuilder(); String systemID = source.getSystemId(); source = new DOMSource(builder.newDocument()); @@ -974,6 +990,11 @@ } } } + else if (name.equals(OutputPropertiesFactory.ORACLE_IS_STANDALONE)) { + if (value != null && value.equals("yes")) { + translet._isStandalone = true; + } + } } } @@ -1033,6 +1054,11 @@ handler.setIndentAmount(Integer.parseInt(value)); } } + else if (name.equals(OutputPropertiesFactory.ORACLE_IS_STANDALONE)) { + if (value != null && value.equals("yes")) { + handler.setIsStandalone(true); + } + } else if (name.equals(OutputKeys.CDATA_SECTION_ELEMENTS)) { if (value != null) { StringTokenizer e = new StringTokenizer(value); @@ -1146,6 +1172,7 @@ name.equals(OutputKeys.OMIT_XML_DECLARATION) || name.equals(OutputKeys.STANDALONE) || name.equals(OutputKeys.VERSION) || + name.equals(OutputPropertiesFactory.ORACLE_IS_STANDALONE) || name.charAt(0) == '{'); } @@ -1252,7 +1279,7 @@ try { // Argument to document function was: document(''); if (href.length() == 0) { - href = new String(baseURI); + href = baseURI; } /* diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java --- a/src/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java Tue Apr 17 11:17:59 2012 -0700 @@ -42,6 +42,7 @@ import javax.xml.transform.stax.StAXSource; import javax.xml.transform.stream.StreamSource; +import com.sun.org.apache.xalan.internal.utils.FactoryImpl; import com.sun.org.apache.xalan.internal.xsltc.compiler.XSLTC; import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg; @@ -109,8 +110,7 @@ //Incase there is an exception thrown // resort to JAXP - SAXParserFactory parserFactory = - SAXParserFactory.newInstance(); + SAXParserFactory parserFactory = FactoryImpl.getSAXFactory(xsltc.useServicesMechnism()); parserFactory.setNamespaceAware(true); if (xsltc.isSecureProcessing()) { diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xerces/internal/dom/CoreDOMImplementationImpl.java --- a/src/com/sun/org/apache/xerces/internal/dom/CoreDOMImplementationImpl.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xerces/internal/dom/CoreDOMImplementationImpl.java Tue Apr 17 11:17:59 2012 -0700 @@ -21,7 +21,10 @@ import com.sun.org.apache.xerces.internal.impl.RevalidationHandler; import com.sun.org.apache.xerces.internal.parsers.DOMParserImpl; +import com.sun.org.apache.xerces.internal.parsers.DTDConfiguration; +import com.sun.org.apache.xerces.internal.parsers.XIncludeAwareParserConfiguration; import com.sun.org.apache.xerces.internal.util.XMLChar; +import com.sun.org.apache.xerces.internal.utils.ObjectFactory; import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription; import com.sun.org.apache.xml.internal.serialize.DOMSerializerImpl; import org.w3c.dom.DOMException; @@ -49,6 +52,7 @@ * * @xerces.internal * + * @version $Id: CoreDOMImplementationImpl.java,v 1.6 2010-11-01 04:39:37 joehw Exp $ * @since PR-DOM-Level-1-19980818. */ public class CoreDOMImplementationImpl @@ -114,8 +118,7 @@ && (anyVersion || version.equals("3.0"))) { try { Class xpathClass = ObjectFactory.findProviderClass( - "com.sun.org.apache.xpath.internal.domapi.XPathEvaluatorImpl", - ObjectFactory.findClassLoader(), true); + "com.sun.org.apache.xpath.internal.domapi.XPathEvaluatorImpl", true); // Check if the DOM XPath implementation implements // the interface org.w3c.dom.XPathEvaluator @@ -281,9 +284,7 @@ if ((feature.equalsIgnoreCase("+XPath"))) { try { Class xpathClass = ObjectFactory.findProviderClass( - "com.sun.org.apache.xpath.internal.domapi.XPathEvaluatorImpl", - ObjectFactory.findClassLoader(), true); - + "com.sun.org.apache.xpath.internal.domapi.XPathEvaluatorImpl", true); // Check if the DOM XPath implementation implements // the interface org.w3c.dom.XPathEvaluator Class interfaces[] = xpathClass.getInterfaces(); @@ -361,14 +362,12 @@ } if (schemaType != null && schemaType.equals("http://www.w3.org/TR/REC-xml")) { - return new DOMParserImpl( - "com.sun.org.apache.xerces.internal.parsers.DTDConfiguration", + return new DOMParserImpl(new DTDConfiguration(), schemaType); } else { // create default parser configuration validating against XMLSchemas - return new DOMParserImpl( - "com.sun.org.apache.xerces.internal.parsers.XIncludeAwareParserConfiguration", + return new DOMParserImpl(new XIncludeAwareParserConfiguration(), schemaType); } } diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xerces/internal/dom/CoreDocumentImpl.java --- a/src/com/sun/org/apache/xerces/internal/dom/CoreDocumentImpl.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xerces/internal/dom/CoreDocumentImpl.java Tue Apr 17 11:17:59 2012 -0700 @@ -31,6 +31,8 @@ import com.sun.org.apache.xerces.internal.util.XMLChar; import com.sun.org.apache.xerces.internal.util.XML11Char; import com.sun.org.apache.xerces.internal.xni.NamespaceContext; +import com.sun.org.apache.xerces.internal.utils.ObjectFactory; +import com.sun.org.apache.xerces.internal.utils.SecuritySupport; import org.w3c.dom.Attr; import org.w3c.dom.CDATASection; import org.w3c.dom.Comment; @@ -77,7 +79,7 @@ * @author Joe Kesselman, IBM * @author Andy Clark, IBM * @author Ralf Pfeiffer, IBM - * @version $Id: CoreDocumentImpl.java,v 1.7 2009/08/04 05:07:20 joehw Exp $ + * @version $Id: CoreDocumentImpl.java,v 1.9 2010-11-01 04:39:37 joehw Exp $ * @since PR-DOM-Level-1-19980818. */ @@ -258,8 +260,7 @@ super(null); ownerDocument = this; allowGrammarAccess = grammarAccess; - SecuritySupport ss = SecuritySupport.getInstance(); - String systemProp = ss.getSystemProperty(Constants.SUN_DOM_PROPERTY_PREFIX+Constants.SUN_DOM_ANCESTOR_CHECCK); + String systemProp = SecuritySupport.getSystemProperty(Constants.SUN_DOM_PROPERTY_PREFIX+Constants.SUN_DOM_ANCESTOR_CHECCK); if (systemProp != null) { if (systemProp.equalsIgnoreCase("false")) { ancestorChecking = false; @@ -516,9 +517,8 @@ } try { - Class xpathClass = ObjectFactory.findProviderClass( - "com.sun.org.apache.xpath.internal.domapi.XPathEvaluatorImpl", - ObjectFactory.findClassLoader(), true); + Class xpathClass = ObjectFactory.findProviderClass ( + "com.sun.org.apache.xpath.internal.domapi.XPathEvaluatorImpl", true); Constructor xpathClassConstr = xpathClass.getConstructor(new Class[] { Document.class }); diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xerces/internal/dom/DOMConfigurationImpl.java --- a/src/com/sun/org/apache/xerces/internal/dom/DOMConfigurationImpl.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xerces/internal/dom/DOMConfigurationImpl.java Tue Apr 17 11:17:59 2012 -0700 @@ -55,6 +55,7 @@ import com.sun.org.apache.xerces.internal.xni.parser.XMLErrorHandler; import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource; import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration; +import com.sun.org.apache.xerces.internal.utils.ObjectFactory; import org.w3c.dom.DOMException; import org.w3c.dom.ls.LSResourceResolver; @@ -324,8 +325,7 @@ MessageFormatter xmft = null; try { xmft = (MessageFormatter)( - ObjectFactory.newInstance("com.sun.org.apache.xerces.internal.impl.xs.XSMessageFormatter", - ObjectFactory.findClassLoader(), true)); + ObjectFactory.newInstance("com.sun.org.apache.xerces.internal.impl.xs.XSMessageFormatter", true)); } catch (Exception exception){ } diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xerces/internal/dom/ObjectFactory.java --- a/src/com/sun/org/apache/xerces/internal/dom/ObjectFactory.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,555 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2001-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 com.sun.org.apache.xerces.internal.dom; - -import java.io.InputStream; -import java.io.IOException; -import java.io.File; -import java.io.FileInputStream; - -import java.util.Properties; -import java.io.BufferedReader; -import java.io.InputStreamReader; - -/** - * 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. - *

- * This code is designed to implement the JAXP 1.1 spec pluggability - * feature and is designed to run on JDK version 1.1 and - * later, and to compile on JDK 1.2 and onward. - * The code also runs both as part of an unbundled jar file and - * when bundled as part of the JDK. - *

- * - * @xerces.internal - * - */ -final class ObjectFactory { - - // - // Constants - // - - // name of default properties file to look for in JDK's jre/lib directory - private static final String DEFAULT_PROPERTIES_FILENAME = "xerces.properties"; - - /** Set to true for debugging */ - private static final boolean DEBUG = false; - - /** - * Default columns per line. - */ - private static final int DEFAULT_LINE_LENGTH = 80; - - /** cache the contents of the xerces.properties file. - * Until an attempt has been made to read this file, this will - * be null; if the file does not exist or we encounter some other error - * during the read, this will be empty. - */ - private static Properties fXercesProperties = null; - - /*** - * Cache the time stamp of the xerces.properties file so - * that we know if it's been modified and can invalidate - * the cache when necessary. - */ - private static long fLastModified = -1; - - // - // static methods - // - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *

    - *
  1. query the system property using System.getProperty - *
  2. read META-INF/services/factoryId file - *
  3. use fallback classname - *
- * - * @return Class object of factory, 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 no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Object createObject(String factoryId, String fallbackClassName) - throws ConfigurationError { - return createObject(factoryId, null, fallbackClassName); - } // createObject(String,String):Object - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return Class object of factory, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xerces.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Object createObject(String factoryId, - String propertiesFilename, - String fallbackClassName) - throws ConfigurationError - { - if (DEBUG) debugPrintln("debug is on"); - - SecuritySupport ss = SecuritySupport.getInstance(); - ClassLoader cl = findClassLoader(); - - // Use the system property first - try { - String systemProp = ss.getSystemProperty(factoryId); - if (systemProp != null) { - if (DEBUG) debugPrintln("found system property, value=" + systemProp); - return newInstance(systemProp, cl, true); - } - } catch (SecurityException se) { - // Ignore and continue w/ next location - } - - // JAXP specific change - // always use fallback class to avoid the expense of constantly - // "stat"ing a non-existent "xerces.properties" and jar SPI entry - // see CR 6400863: Expensive creating of SAX parser in Mustang - if (true) { - if (fallbackClassName == null) { - throw new ConfigurationError( - "Provider for " + factoryId + " cannot be found", null); - } - - if (DEBUG) debugPrintln("using fallback, value=" + fallbackClassName); - return newInstance(fallbackClassName, cl, true); - } - - // Try to read from propertiesFilename, or $java.home/lib/xerces.properties - String factoryClassName = null; - // no properties file name specified; use $JAVA_HOME/lib/xerces.properties: - if (propertiesFilename == null) { - File propertiesFile = null; - boolean propertiesFileExists = false; - try { - String javah = ss.getSystemProperty("java.home"); - propertiesFilename = javah + File.separator + - "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME; - propertiesFile = new File(propertiesFilename); - propertiesFileExists = ss.getFileExists(propertiesFile); - } catch (SecurityException e) { - // try again... - fLastModified = -1; - fXercesProperties = null; - } - - synchronized (ObjectFactory.class) { - boolean loadProperties = false; - FileInputStream fis = null; - try { - // file existed last time - if(fLastModified >= 0) { - if(propertiesFileExists && - (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) { - loadProperties = true; - } else { - // file has stopped existing... - if(!propertiesFileExists) { - fLastModified = -1; - fXercesProperties = null; - } // else, file wasn't modified! - } - } else { - // file has started to exist: - if(propertiesFileExists) { - loadProperties = true; - fLastModified = ss.getLastModified(propertiesFile); - } // else, nothing's changed - } - if(loadProperties) { - // must never have attempted to read xerces.properties before (or it's outdeated) - fXercesProperties = new Properties(); - fis = ss.getFileInputStream(propertiesFile); - fXercesProperties.load(fis); - } - } catch (Exception x) { - fXercesProperties = null; - fLastModified = -1; - // assert(x instanceof FileNotFoundException - // || x instanceof SecurityException) - // In both cases, ignore and continue w/ next location - } - finally { - // try to close the input stream if one was opened. - if (fis != null) { - try { - fis.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - } - } - if(fXercesProperties != null) { - factoryClassName = fXercesProperties.getProperty(factoryId); - } - } else { - FileInputStream fis = null; - try { - fis = ss.getFileInputStream(new File(propertiesFilename)); - Properties props = new Properties(); - props.load(fis); - factoryClassName = props.getProperty(factoryId); - } catch (Exception x) { - // assert(x instanceof FileNotFoundException - // || x instanceof SecurityException) - // In both cases, ignore and continue w/ next location - } - finally { - // try to close the input stream if one was opened. - if (fis != null) { - try { - fis.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - } - } - if (factoryClassName != null) { - if (DEBUG) debugPrintln("found in " + propertiesFilename + ", value=" + factoryClassName); - return newInstance(factoryClassName, cl, true); - } - - // 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); - } - - if (DEBUG) debugPrintln("using fallback, value=" + fallbackClassName); - return newInstance(fallbackClassName, cl, true); - } // createObject(String,String,String):Object - - // - // Private static methods - // - - /** Prints a message to standard error if debugging is enabled. */ - private static void debugPrintln(String msg) { - if (DEBUG) { - System.err.println("JAXP: " + msg); - } - } // debugPrintln(String) - - /** - * Figure out which ClassLoader to use. For JDK 1.2 and later use - * the context ClassLoader. - */ - static ClassLoader findClassLoader() - 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 context = ss.getContextClassLoader(); - ClassLoader system = ss.getSystemClassLoader(); - - ClassLoader chain = system; - while (true) { - if (context == chain) { - // Assert: we are on JDK 1.1 or we have no Context ClassLoader - // or any Context ClassLoader in chain of system classloader - // (including extension ClassLoader) so extend to widest - // ClassLoader (always look in system ClassLoader if Xerces - // is in boot/extension/system classpath and in current - // ClassLoader otherwise); normal classloaders delegate - // back to system ClassLoader first so this widening doesn't - // change the fact that context ClassLoader will be consulted - ClassLoader current = ObjectFactory.class.getClassLoader(); - - chain = system; - while (true) { - if (current == chain) { - // Assert: Current ClassLoader in chain of - // boot/extension/system ClassLoaders - return system; - } - if (chain == null) { - break; - } - chain = ss.getParentClassLoader(chain); - } - - // Assert: Current ClassLoader not in chain of - // boot/extension/system ClassLoaders - return current; - } - - if (chain == null) { - // boot ClassLoader reached - break; - } - - // Check for any extension ClassLoaders in chain up to - // boot ClassLoader - chain = ss.getParentClassLoader(chain); - }; - - // Assert: Context ClassLoader not in chain of - // boot/extension/system ClassLoaders - return context; - } // findClassLoader():ClassLoader - - /** - * Create an instance of a class using the specified ClassLoader - */ - static Object newInstance(String className, ClassLoader cl, - boolean doFallback) - throws ConfigurationError - { - // assert(className != null); - try{ - Class providerClass = findProviderClass(className, cl, doFallback); - Object instance = providerClass.newInstance(); - if (DEBUG) debugPrintln("created new instance of " + providerClass + - " using ClassLoader: " + cl); - return instance; - } catch (ClassNotFoundException x) { - throw new ConfigurationError( - "Provider " + className + " not found", x); - } catch (Exception x) { - throw new ConfigurationError( - "Provider " + className + " could not be instantiated: " + x, - x); - } - } - - /** - * Find a Class using the specified ClassLoader - */ - static Class findProviderClass(String className, ClassLoader cl, - boolean doFallback) - throws ClassNotFoundException, ConfigurationError - { - //throw security exception if the calling thread is not allowed to access the package - //restrict the access to package as speicified in java.security policy - SecurityManager security = System.getSecurityManager(); - if (security != null) { - final int lastDot = className.lastIndexOf("."); - String packageName = className; - if (lastDot != -1) packageName = className.substring(0, lastDot); - security.checkPackageAccess(packageName); - } - Class providerClass; - 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 { - try { - providerClass = cl.loadClass(className); - } catch (ClassNotFoundException x) { - if (doFallback) { - // Fall back to current classloader - ClassLoader current = ObjectFactory.class.getClassLoader(); - if (current == null) { - providerClass = Class.forName(className); - } else if (cl != current) { - cl = current; - providerClass = cl.loadClass(className); - } else { - throw x; - } - } else { - throw x; - } - } - } - - return providerClass; - } - - /* - * Try to find provider using Jar Service Provider Mechanism - * - * @return instance of provider class if found or null - */ - private static Object findJarServiceProvider(String factoryId) - throws ConfigurationError - { - SecuritySupport ss = SecuritySupport.getInstance(); - String serviceId = "META-INF/services/" + factoryId; - InputStream is = null; - - // First try the Context ClassLoader - ClassLoader cl = findClassLoader(); - - is = ss.getResourceAsStream(cl, serviceId); - - // If no provider found then try the current ClassLoader - if (is == null) { - ClassLoader current = ObjectFactory.class.getClassLoader(); - if (cl != current) { - cl = current; - is = ss.getResourceAsStream(cl, serviceId); - } - } - - if (is == null) { - // No provider found - return null; - } - - if (DEBUG) debugPrintln("found jar resource=" + serviceId + - " using ClassLoader: " + cl); - - // 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"), DEFAULT_LINE_LENGTH); - } catch (java.io.UnsupportedEncodingException e) { - rd = new BufferedReader(new InputStreamReader(is), DEFAULT_LINE_LENGTH); - } - - String factoryClassName = null; - try { - // XXX Does not handle all possible input as specified by the - // Jar Service Provider specification - factoryClassName = rd.readLine(); - } catch (IOException x) { - // No provider found - return null; - } - finally { - try { - // try to close the reader. - rd.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - - if (factoryClassName != null && - ! "".equals(factoryClassName)) { - if (DEBUG) debugPrintln("found in resource, value=" - + factoryClassName); - - // Note: here we do not want to fall back to the current - // 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. - return newInstance(factoryClassName, cl, false); - } - - // No provider found - return null; - } - - // - // Classes - // - - /** - * A configuration error. - */ - static final class ConfigurationError - extends Error { - - /** Serialization version. */ - static final long serialVersionUID = 1914065341994951202L; - - // - // Data - // - - /** Exception. */ - private Exception exception; - - // - // Constructors - // - - /** - * Construct a new instance with the specified detail string and - * exception. - */ - ConfigurationError(String msg, Exception x) { - super(msg); - this.exception = x; - } // (String,Exception) - - // - // methods - // - - /** Returns the exception associated to this error. */ - Exception getException() { - return exception; - } // getException():Exception - - } // class ConfigurationError - -} // class ObjectFactory diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xerces/internal/dom/SecuritySupport.java --- a/src/com/sun/org/apache/xerces/internal/dom/SecuritySupport.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,152 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2002,2004 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 com.sun.org.apache.xerces.internal.dom; - -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 subpackage so keep it in sync. - * It is package private and therefore is not exposed as part of any API. - * - * @xerces.internal - */ -final class SecuritySupport { - - private static final SecuritySupport securitySupport = new SecuritySupport(); - - /** - * Return an instance of this class. - */ - static SecuritySupport getInstance() { - return securitySupport; - } - - ClassLoader getContextClassLoader() { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader cl = null; - try { - cl = Thread.currentThread().getContextClassLoader(); - } catch (SecurityException ex) { } - return cl; - } - }); - } - - ClassLoader getSystemClassLoader() { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader cl = null; - try { - cl = ClassLoader.getSystemClassLoader(); - } catch (SecurityException ex) {} - return cl; - } - }); - } - - ClassLoader getParentClassLoader(final ClassLoader cl) { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader parent = null; - try { - parent = cl.getParent(); - } catch (SecurityException ex) {} - - // eliminate loops in case of the boot - // ClassLoader returning itself as a parent - return (parent == cl) ? null : parent; - } - }); - } - - String getSystemProperty(final String propName) { - return (String) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return System.getProperty(propName); - } - }); - } - - 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(); - } - } - - 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; - } - }); - } - - boolean getFileExists(final File f) { - return ((Boolean) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return new Boolean(f.exists()); - } - })).booleanValue(); - } - - long getLastModified(final File f) { - return ((Long) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return new Long(f.lastModified()); - } - })).longValue(); - } - - private SecuritySupport () {} -} diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xerces/internal/impl/Constants.java --- a/src/com/sun/org/apache/xerces/internal/impl/Constants.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xerces/internal/impl/Constants.java Tue Apr 17 11:17:59 2012 -0700 @@ -136,7 +136,9 @@ /** XML string property ("xml-string"). */ public static final String XML_STRING_PROPERTY = "xml-string"; - public static final String FEATURE_SECURE_PROCESSING = "http://javax.xml.XMLConstants/feature/secure-processing"; + public static final String FEATURE_SECURE_PROCESSING = "http://javax.xml.XMLConstants/feature/secure-processing"; + + public static final String ORACLE_FEATURE_SERVICE_MECHANISM = "http://www.oracle.com/feature/use-service-mechanism"; /** Document XML version property ("document-xml-version"). */ public static final String DOCUMENT_XML_VERSION_PROPERTY = "document-xml-version"; diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java --- a/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java Tue Apr 17 11:17:59 2012 -0700 @@ -1803,6 +1803,7 @@ String name = fEntityScanner.scanName(); if (name == null) { reportFatalError("NameRequiredInReference", null); + return; } if (!fEntityScanner.skipChar(';')) { reportFatalError("SemicolonRequiredInReference", new Object []{name}); diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java --- a/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java Tue Apr 17 11:17:59 2012 -0700 @@ -365,11 +365,6 @@ // shared context - /** Shared declared entities. - * XXX understand it more deeply, why are we doing this ?? Is it really required ? - */ - protected Hashtable fDeclaredEntities; - protected XMLEntityStorage fEntityStorage ; protected final Object [] defaultEncoding = new Object[]{"UTF-8", null}; @@ -409,24 +404,6 @@ } // () /** - * Constructs an entity manager that shares the specified entity - * declarations during each parse. - *

- * REVISIT: We might want to think about the "right" - * way to expose the list of declared entities. For now, the knowledge - * how to access the entity declarations is implicit. - */ - public XMLEntityManager(XMLEntityManager entityManager) { - - - // save shared entity declarations - fDeclaredEntities = entityManager != null - ? entityManager.getEntityStore().getDeclaredEntities() : null; - - setScannerVersion(Constants.XML_VERSION_1_0); - } // (XMLEntityManager) - - /** * Adds an internal entity declaration. *

* Note: This method ignores subsequent entity @@ -1111,7 +1088,7 @@ throws IOException, XNIException { // was entity declared? - Entity entity = (Entity)fEntityStorage.getDeclaredEntities().get(entityName); + Entity entity = (Entity)fEntityStorage.getEntity(entityName); if (entity == null) { if (fEntityHandler != null) { String encoding = null; @@ -1331,23 +1308,16 @@ (fEntityStack.empty() ? null : fEntityStack.elementAt(0)); } - // a list of Readers ever seen - protected Vector fOwnReaders = new Vector(); /** * Close all opened InputStreams and Readers opened by this parser. */ public void closeReaders() { - // close all readers - for (int i = fOwnReaders.size()-1; i >= 0; i--) { - try { - ((Reader)fOwnReaders.elementAt(i)).close(); - } catch (IOException e) { - // ignore - } - } - // and clear the list - fOwnReaders.removeAllElements(); + /** this call actually does nothing, readers are closed in the endEntity method + * through the current entity. + * The change seems to have happened during the jdk6 development with the + * addition of StAX + **/ } public void endEntity() throws IOException, XNIException { @@ -1361,6 +1331,20 @@ //pop the entity from the stack Entity.ScannedEntity entity = fEntityStack.size() > 0 ? (Entity.ScannedEntity)fEntityStack.pop() : null ; + /** need to close the reader first since the program can end + * prematurely (e.g. fEntityHandler.endEntity may throw exception) + * leaving the reader open + */ + //close the reader + if(fCurrentEntity != null){ + //close the reader + try{ + fCurrentEntity.close(); + }catch(IOException ex){ + throw new XNIException(ex); + } + } + if (fEntityHandler != null) { //so this is the last opened entity, signal it to current fEntityHandler using Augmentation if(entity == null){ @@ -1375,16 +1359,6 @@ //check if it is a document entity boolean documentEntity = fCurrentEntity.name == XMLEntity; - //close the reader - if(fCurrentEntity != null){ - //close the reader - try{ - fCurrentEntity.close(); - }catch(IOException ex){ - throw new XNIException(ex); - } - } - //set popped entity as current entity fCurrentEntity = entity; fEntityScanner.setCurrentEntity(fCurrentEntity); @@ -1536,15 +1510,6 @@ } } - // copy declared entities - if (fDeclaredEntities != null) { - java.util.Enumeration keys = fDeclaredEntities.keys(); - while (keys.hasMoreElements()) { - Object key = keys.nextElement(); - Object value = fDeclaredEntities.get(key); - fEntities.put(key, value); - } - } fEntityHandler = null; // reset scanner diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xerces/internal/impl/XMLEntityScanner.java --- a/src/com/sun/org/apache/xerces/internal/impl/XMLEntityScanner.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xerces/internal/impl/XMLEntityScanner.java Tue Apr 17 11:17:59 2012 -0700 @@ -136,7 +136,9 @@ VALID_NAMES[58]=true; VALID_NAMES[95]=true; } - + // SAPJVM: Remember, that the XML version has explicitly been set, + // so that XMLStreamReader.getVersion() can find that out. + boolean xmlVersionSetExplicitly = false; // // Constructors // @@ -248,6 +250,7 @@ * @param xmlVersion the XML version of the current entity */ public final void setXMLVersion(String xmlVersion) { + xmlVersionSetExplicitly = true; // SAPJVM fCurrentEntity.xmlVersion = xmlVersion; } // setXMLVersion(String) diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xerces/internal/impl/XMLStreamReaderImpl.java --- a/src/com/sun/org/apache/xerces/internal/impl/XMLStreamReaderImpl.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xerces/internal/impl/XMLStreamReaderImpl.java Tue Apr 17 11:17:59 2012 -0700 @@ -447,7 +447,13 @@ /** Get the XML language version of the current document being parsed */ public String getVersion() { - return fEntityScanner.getXMLVersion(); + //apply SAP's patch: the default version in the scanner was set to 1.0 because of DOM and SAX + //so this patch is a workaround of the difference between StAX and DOM + // SAPJVM: Return null if the XML version has not been declared (as specified in the JavaDoc). + + String version = fEntityScanner.getXMLVersion(); + + return "1.0".equals(version) && !fEntityScanner.xmlVersionSetExplicitly ? null : version; } /** @@ -1045,11 +1051,10 @@ return fScanner.getCharacterData().toString(); XMLEntityStorage entityStore = fEntityManager.getEntityStore(); - Hashtable ht = entityStore.getDeclaredEntities(); - Entity en = (Entity)ht.get(name); - if(en == null) - return null; - if(en.isExternal()) + Entity en = entityStore.getEntity(name); + if(en == null) + return null; + if(en.isExternal()) return ((Entity.ExternalEntity)en).entityLocation.getExpandedSystemId(); else return ((Entity.InternalEntity)en).text; @@ -1176,8 +1181,7 @@ return true; XMLEntityStorage entityStore = fEntityManager.getEntityStore(); - Hashtable ht = entityStore.getDeclaredEntities(); - Entity en =(Entity)ht.get(name); + Entity en = entityStore.getEntity(name); if(en == null) return false; if(en.isExternal()){ @@ -1318,15 +1322,14 @@ protected List getEntityDecls(){ if(fEventType == XMLStreamConstants.DTD){ XMLEntityStorage entityStore = fEntityManager.getEntityStore(); - Hashtable ht = entityStore.getDeclaredEntities(); ArrayList list = null; - if(ht != null){ + if(entityStore.hasEntities()){ EntityDeclarationImpl decl = null; - list = new ArrayList(ht.size()); - Enumeration enu = ht.keys(); + list = new ArrayList(entityStore.getEntitySize()); + Enumeration enu = entityStore.getEntityKeys(); while(enu.hasMoreElements()){ String key = (String)enu.nextElement(); - Entity en = (Entity)ht.get(key); + Entity en = (Entity)entityStore.getEntity(key); decl = new EntityDeclarationImpl(); decl.setEntityName(key); if(en.isExternal()){ diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xerces/internal/impl/dv/DTDDVFactory.java --- a/src/com/sun/org/apache/xerces/internal/impl/dv/DTDDVFactory.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xerces/internal/impl/dv/DTDDVFactory.java Tue Apr 17 11:17:59 2012 -0700 @@ -21,6 +21,7 @@ package com.sun.org.apache.xerces.internal.impl.dv; import java.util.Hashtable; +import com.sun.org.apache.xerces.internal.utils.ObjectFactory; /** * The factory to create and return DTD types. The implementation should @@ -31,6 +32,7 @@ * * @author Sandy Gao, IBM * + * @version $Id: DTDDVFactory.java,v 1.6 2010-11-01 04:39:43 joehw Exp $ */ public abstract class DTDDVFactory { @@ -43,7 +45,7 @@ * @exception DVFactoryException cannot create an instance of the specified * class name or the default class name */ - public static synchronized final DTDDVFactory getInstance() throws DVFactoryException { + public static final DTDDVFactory getInstance() throws DVFactoryException { return getInstance(DEFAULT_FACTORY_CLASS); } @@ -55,19 +57,19 @@ * @exception DVFactoryException cannot create an instance of the specified * class name or the default class name */ - public static synchronized final DTDDVFactory getInstance(String factoryClass) throws DVFactoryException { - + public static final DTDDVFactory getInstance(String factoryClass) throws DVFactoryException { try { // if the class name is not specified, use the default one return (DTDDVFactory) - (ObjectFactory.newInstance(factoryClass, ObjectFactory.findClassLoader(), true)); - } catch (ClassCastException e) { + (ObjectFactory.newInstance(factoryClass, true)); + } + catch (ClassCastException e) { throw new DVFactoryException("DTD factory class " + factoryClass + " does not extend from DTDDVFactory."); } } // can't create a new object of this class - protected DTDDVFactory(){} + protected DTDDVFactory() {} /** * return a dtd type of the given name diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xerces/internal/impl/dv/ObjectFactory.java --- a/src/com/sun/org/apache/xerces/internal/impl/dv/ObjectFactory.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,555 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2001-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 com.sun.org.apache.xerces.internal.impl.dv; - -import java.io.InputStream; -import java.io.IOException; -import java.io.File; -import java.io.FileInputStream; - -import java.util.Properties; -import java.io.BufferedReader; -import java.io.InputStreamReader; - -/** - * 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. - *

- * This code is designed to implement the JAXP 1.1 spec pluggability - * feature and is designed to run on JDK version 1.1 and - * later, and to compile on JDK 1.2 and onward. - * The code also runs both as part of an unbundled jar file and - * when bundled as part of the JDK. - *

- * - * @xerces.internal - * - */ -final class ObjectFactory { - - // - // Constants - // - - // name of default properties file to look for in JDK's jre/lib directory - private static final String DEFAULT_PROPERTIES_FILENAME = "xerces.properties"; - - /** Set to true for debugging */ - private static final boolean DEBUG = false; - - /** - * Default columns per line. - */ - private static final int DEFAULT_LINE_LENGTH = 80; - - /** cache the contents of the xerces.properties file. - * Until an attempt has been made to read this file, this will - * be null; if the file does not exist or we encounter some other error - * during the read, this will be empty. - */ - private static Properties fXercesProperties = null; - - /*** - * Cache the time stamp of the xerces.properties file so - * that we know if it's been modified and can invalidate - * the cache when necessary. - */ - private static long fLastModified = -1; - - // - // static methods - // - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *

    - *
  1. query the system property using System.getProperty - *
  2. read META-INF/services/factoryId file - *
  3. use fallback classname - *
- * - * @return Class object of factory, 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 no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Object createObject(String factoryId, String fallbackClassName) - throws ConfigurationError { - return createObject(factoryId, null, fallbackClassName); - } // createObject(String,String):Object - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return Class object of factory, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xerces.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Object createObject(String factoryId, - String propertiesFilename, - String fallbackClassName) - throws ConfigurationError - { - if (DEBUG) debugPrintln("debug is on"); - - SecuritySupport ss = SecuritySupport.getInstance(); - ClassLoader cl = findClassLoader(); - - // Use the system property first - try { - String systemProp = ss.getSystemProperty(factoryId); - if (systemProp != null) { - if (DEBUG) debugPrintln("found system property, value=" + systemProp); - return newInstance(systemProp, cl, true); - } - } catch (SecurityException se) { - // Ignore and continue w/ next location - } - - // JAXP specific change - // always use fallback class to avoid the expense of constantly - // "stat"ing a non-existent "xerces.properties" and jar SPI entry - // see CR 6400863: Expensive creating of SAX parser in Mustang - if (true) { - if (fallbackClassName == null) { - throw new ConfigurationError( - "Provider for " + factoryId + " cannot be found", null); - } - - if (DEBUG) debugPrintln("using fallback, value=" + fallbackClassName); - return newInstance(fallbackClassName, cl, true); - } - - // Try to read from propertiesFilename, or $java.home/lib/xerces.properties - String factoryClassName = null; - // no properties file name specified; use $JAVA_HOME/lib/xerces.properties: - if (propertiesFilename == null) { - File propertiesFile = null; - boolean propertiesFileExists = false; - try { - String javah = ss.getSystemProperty("java.home"); - propertiesFilename = javah + File.separator + - "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME; - propertiesFile = new File(propertiesFilename); - propertiesFileExists = ss.getFileExists(propertiesFile); - } catch (SecurityException e) { - // try again... - fLastModified = -1; - fXercesProperties = null; - } - - synchronized (ObjectFactory.class) { - boolean loadProperties = false; - FileInputStream fis = null; - try { - // file existed last time - if(fLastModified >= 0) { - if(propertiesFileExists && - (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) { - loadProperties = true; - } else { - // file has stopped existing... - if(!propertiesFileExists) { - fLastModified = -1; - fXercesProperties = null; - } // else, file wasn't modified! - } - } else { - // file has started to exist: - if(propertiesFileExists) { - loadProperties = true; - fLastModified = ss.getLastModified(propertiesFile); - } // else, nothing's changed - } - if(loadProperties) { - // must never have attempted to read xerces.properties before (or it's outdeated) - fXercesProperties = new Properties(); - fis = ss.getFileInputStream(propertiesFile); - fXercesProperties.load(fis); - } - } catch (Exception x) { - fXercesProperties = null; - fLastModified = -1; - // assert(x instanceof FileNotFoundException - // || x instanceof SecurityException) - // In both cases, ignore and continue w/ next location - } - finally { - // try to close the input stream if one was opened. - if (fis != null) { - try { - fis.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - } - } - if(fXercesProperties != null) { - factoryClassName = fXercesProperties.getProperty(factoryId); - } - } else { - FileInputStream fis = null; - try { - fis = ss.getFileInputStream(new File(propertiesFilename)); - Properties props = new Properties(); - props.load(fis); - factoryClassName = props.getProperty(factoryId); - } catch (Exception x) { - // assert(x instanceof FileNotFoundException - // || x instanceof SecurityException) - // In both cases, ignore and continue w/ next location - } - finally { - // try to close the input stream if one was opened. - if (fis != null) { - try { - fis.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - } - } - if (factoryClassName != null) { - if (DEBUG) debugPrintln("found in " + propertiesFilename + ", value=" + factoryClassName); - return newInstance(factoryClassName, cl, true); - } - - // 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); - } - - if (DEBUG) debugPrintln("using fallback, value=" + fallbackClassName); - return newInstance(fallbackClassName, cl, true); - } // createObject(String,String,String):Object - - // - // Private static methods - // - - /** Prints a message to standard error if debugging is enabled. */ - private static void debugPrintln(String msg) { - if (DEBUG) { - System.err.println("JAXP: " + msg); - } - } // debugPrintln(String) - - /** - * Figure out which ClassLoader to use. For JDK 1.2 and later use - * the context ClassLoader. - */ - static ClassLoader findClassLoader() - 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 context = ss.getContextClassLoader(); - ClassLoader system = ss.getSystemClassLoader(); - - ClassLoader chain = system; - while (true) { - if (context == chain) { - // Assert: we are on JDK 1.1 or we have no Context ClassLoader - // or any Context ClassLoader in chain of system classloader - // (including extension ClassLoader) so extend to widest - // ClassLoader (always look in system ClassLoader if Xerces - // is in boot/extension/system classpath and in current - // ClassLoader otherwise); normal classloaders delegate - // back to system ClassLoader first so this widening doesn't - // change the fact that context ClassLoader will be consulted - ClassLoader current = ObjectFactory.class.getClassLoader(); - - chain = system; - while (true) { - if (current == chain) { - // Assert: Current ClassLoader in chain of - // boot/extension/system ClassLoaders - return system; - } - if (chain == null) { - break; - } - chain = ss.getParentClassLoader(chain); - } - - // Assert: Current ClassLoader not in chain of - // boot/extension/system ClassLoaders - return current; - } - - if (chain == null) { - // boot ClassLoader reached - break; - } - - // Check for any extension ClassLoaders in chain up to - // boot ClassLoader - chain = ss.getParentClassLoader(chain); - }; - - // Assert: Context ClassLoader not in chain of - // boot/extension/system ClassLoaders - return context; - } // findClassLoader():ClassLoader - - /** - * Create an instance of a class using the specified ClassLoader - */ - static Object newInstance(String className, ClassLoader cl, - boolean doFallback) - throws ConfigurationError - { - // assert(className != null); - try{ - Class providerClass = findProviderClass(className, cl, doFallback); - Object instance = providerClass.newInstance(); - if (DEBUG) debugPrintln("created new instance of " + providerClass + - " using ClassLoader: " + cl); - return instance; - } catch (ClassNotFoundException x) { - throw new ConfigurationError( - "Provider " + className + " not found", x); - } catch (Exception x) { - throw new ConfigurationError( - "Provider " + className + " could not be instantiated: " + x, - x); - } - } - - /** - * Find a Class using the specified ClassLoader - */ - static Class findProviderClass(String className, ClassLoader cl, - boolean doFallback) - throws ClassNotFoundException, ConfigurationError - { - //throw security exception if the calling thread is not allowed to access the package - //restrict the access to package as speicified in java.security policy - SecurityManager security = System.getSecurityManager(); - if (security != null) { - final int lastDot = className.lastIndexOf("."); - String packageName = className; - if (lastDot != -1) packageName = className.substring(0, lastDot); - security.checkPackageAccess(packageName); - } - Class providerClass; - 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 { - try { - providerClass = cl.loadClass(className); - } catch (ClassNotFoundException x) { - if (doFallback) { - // Fall back to current classloader - ClassLoader current = ObjectFactory.class.getClassLoader(); - if (current == null) { - providerClass = Class.forName(className); - } else if (cl != current) { - cl = current; - providerClass = cl.loadClass(className); - } else { - throw x; - } - } else { - throw x; - } - } - } - - return providerClass; - } - - /* - * Try to find provider using Jar Service Provider Mechanism - * - * @return instance of provider class if found or null - */ - private static Object findJarServiceProvider(String factoryId) - throws ConfigurationError - { - SecuritySupport ss = SecuritySupport.getInstance(); - String serviceId = "META-INF/services/" + factoryId; - InputStream is = null; - - // First try the Context ClassLoader - ClassLoader cl = findClassLoader(); - - is = ss.getResourceAsStream(cl, serviceId); - - // If no provider found then try the current ClassLoader - if (is == null) { - ClassLoader current = ObjectFactory.class.getClassLoader(); - if (cl != current) { - cl = current; - is = ss.getResourceAsStream(cl, serviceId); - } - } - - if (is == null) { - // No provider found - return null; - } - - if (DEBUG) debugPrintln("found jar resource=" + serviceId + - " using ClassLoader: " + cl); - - // 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"), DEFAULT_LINE_LENGTH); - } catch (java.io.UnsupportedEncodingException e) { - rd = new BufferedReader(new InputStreamReader(is), DEFAULT_LINE_LENGTH); - } - - String factoryClassName = null; - try { - // XXX Does not handle all possible input as specified by the - // Jar Service Provider specification - factoryClassName = rd.readLine(); - } catch (IOException x) { - // No provider found - return null; - } - finally { - try { - // try to close the reader. - rd.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - - if (factoryClassName != null && - ! "".equals(factoryClassName)) { - if (DEBUG) debugPrintln("found in resource, value=" - + factoryClassName); - - // Note: here we do not want to fall back to the current - // 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. - return newInstance(factoryClassName, cl, false); - } - - // No provider found - return null; - } - - // - // Classes - // - - /** - * A configuration error. - */ - static final class ConfigurationError - extends Error { - - /** Serialization version. */ - static final long serialVersionUID = 8521878292694272124L; - - // - // Data - // - - /** Exception. */ - private Exception exception; - - // - // Constructors - // - - /** - * Construct a new instance with the specified detail string and - * exception. - */ - ConfigurationError(String msg, Exception x) { - super(msg); - this.exception = x; - } // (String,Exception) - - // - // methods - // - - /** Returns the exception associated to this error. */ - Exception getException() { - return exception; - } // getException():Exception - - } // class ConfigurationError - -} // class ObjectFactory diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xerces/internal/impl/dv/SchemaDVFactory.java --- a/src/com/sun/org/apache/xerces/internal/impl/dv/SchemaDVFactory.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xerces/internal/impl/dv/SchemaDVFactory.java Tue Apr 17 11:17:59 2012 -0700 @@ -22,6 +22,7 @@ import com.sun.org.apache.xerces.internal.util.SymbolHash; import com.sun.org.apache.xerces.internal.xs.XSObjectList; +import com.sun.org.apache.xerces.internal.utils.ObjectFactory; /** * Defines a factory API that enables applications to

@@ -39,6 +40,7 @@ * * @author Sandy Gao, IBM * + * @version $Id: SchemaDVFactory.java,v 1.6 2010-11-01 04:39:43 joehw Exp $ */ public abstract class SchemaDVFactory { @@ -68,8 +70,7 @@ try { // if the class name is not specified, use the default one - return (SchemaDVFactory)(ObjectFactory.newInstance( - factoryClass, ObjectFactory.findClassLoader(), true)); + return (SchemaDVFactory)(ObjectFactory.newInstance(factoryClass, true)); } catch (ClassCastException e4) { throw new DVFactoryException("Schema factory class " + factoryClass + " does not extend from SchemaDVFactory."); } diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xerces/internal/impl/dv/SecuritySupport.java --- a/src/com/sun/org/apache/xerces/internal/impl/dv/SecuritySupport.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,152 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2002,2004 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 com.sun.org.apache.xerces.internal.impl.dv; - -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 subpackage so keep it in sync. - * It is package private and therefore is not exposed as part of any API. - * - * @xerces.internal - */ -final class SecuritySupport { - - private static final SecuritySupport securitySupport = new SecuritySupport(); - - /** - * Return an instance of this class. - */ - static SecuritySupport getInstance() { - return securitySupport; - } - - ClassLoader getContextClassLoader() { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader cl = null; - try { - cl = Thread.currentThread().getContextClassLoader(); - } catch (SecurityException ex) { } - return cl; - } - }); - } - - ClassLoader getSystemClassLoader() { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader cl = null; - try { - cl = ClassLoader.getSystemClassLoader(); - } catch (SecurityException ex) {} - return cl; - } - }); - } - - ClassLoader getParentClassLoader(final ClassLoader cl) { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader parent = null; - try { - parent = cl.getParent(); - } catch (SecurityException ex) {} - - // eliminate loops in case of the boot - // ClassLoader returning itself as a parent - return (parent == cl) ? null : parent; - } - }); - } - - String getSystemProperty(final String propName) { - return (String) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return System.getProperty(propName); - } - }); - } - - 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(); - } - } - - 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; - } - }); - } - - boolean getFileExists(final File f) { - return ((Boolean) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return new Boolean(f.exists()); - } - })).booleanValue(); - } - - long getLastModified(final File f) { - return ((Long) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return new Long(f.lastModified()); - } - })).longValue(); - } - - private SecuritySupport () {} -} diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages.properties --- a/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages.properties Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages.properties Tue Apr 17 11:17:59 2012 -0700 @@ -289,3 +289,6 @@ TargetNamespace.2 = TargetNamespace.2: Expecting no namespace, but the schema document has a target namespace of ''{1}''. UndeclaredEntity = UndeclaredEntity: Entity ''{0}'' is not declared. UndeclaredPrefix = UndeclaredPrefix: Cannot resolve ''{0}'' as a QName: the prefix ''{1}'' is not declared. +null +null +null diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xerces/internal/impl/xpath/regex/ParserForXMLSchema.java --- a/src/com/sun/org/apache/xerces/internal/impl/xpath/regex/ParserForXMLSchema.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xerces/internal/impl/xpath/regex/ParserForXMLSchema.java Tue Apr 17 11:17:59 2012 -0700 @@ -383,16 +383,13 @@ tok = Token.createRange(); setupRange(tok, DIGITS); - ranges.put("xml:isDigit", tok); - ranges2.put("xml:isDigit", Token.complementRanges(tok)); - - tok = Token.createRange(); - setupRange(tok, DIGITS); + setupRange(tok, DIGITS_INT); ranges.put("xml:isDigit", tok); ranges2.put("xml:isDigit", Token.complementRanges(tok)); tok = Token.createRange(); setupRange(tok, LETTERS); + setupRange(tok, LETTERS_INT); tok.mergeRanges((Token)ranges.get("xml:isDigit")); ranges.put("xml:isWord", tok); ranges2.put("xml:isWord", Token.complementRanges(tok)); @@ -420,6 +417,12 @@ range.addRange(src.charAt(i), src.charAt(i+1)); } + static void setupRange(Token range, int[] src) { + int len = src.length; + for (int i = 0; i < len; i += 2) + range.addRange(src[i], src[i+1]); + } + private static final String SPACES = "\t\n\r\r "; private static final String NAMECHARS = "\u002d\u002e\u0030\u003a\u0041\u005a\u005f\u005f\u0061\u007a\u00b7\u00b7\u00c0\u00d6" @@ -466,7 +469,8 @@ +""; private static final String LETTERS = "\u0041\u005a\u0061\u007a\u00c0\u00d6\u00d8\u00f6\u00f8\u0131\u0134\u013e\u0141\u0148" - +"\u014a\u017e\u0180\u01c3\u01cd\u01f0\u01f4\u01f5\u01fa\u0217\u0250\u02a8\u02bb\u02c1" + +"\u014a\u017e\u0180\u01f0\u01f4\u01f5\u01fa\u0217\u0250\u02a8\u02bb\u02c1" + +"\u02b0\u02d1" +"\u0386\u0386\u0388\u038a\u038c\u038c\u038e\u03a1\u03a3\u03ce\u03d0\u03d6\u03da\u03da" +"\u03dc\u03dc\u03de\u03de\u03e0\u03e0\u03e2\u03f3\u0401\u040c\u040e\u044f\u0451\u045c" +"\u045e\u0481\u0490\u04c4\u04c7\u04c8\u04cb\u04cc\u04d0\u04eb\u04ee\u04f5\u04f8\u04f9" @@ -494,9 +498,15 @@ +"\u1f5f\u1f7d\u1f80\u1fb4\u1fb6\u1fbc\u1fbe\u1fbe\u1fc2\u1fc4\u1fc6\u1fcc\u1fd0\u1fd3" +"\u1fd6\u1fdb\u1fe0\u1fec\u1ff2\u1ff4\u1ff6\u1ffc\u2126\u2126\u212a\u212b\u212e\u212e" +"\u2180\u2182\u3007\u3007\u3021\u3029\u3041\u3094\u30a1\u30fa\u3105\u312c\u4e00\u9fa5" - +"\uac00\ud7a3"; + +"\uac00\ud7a3\uff66\uff9f"; + + private static final int[] LETTERS_INT = {0x1d790, 0x1d7a8, 0x1d7aa, 0x1d7c9, 0x2fa1b, 0x2fa1d}; + private static final String DIGITS = "\u0030\u0039\u0660\u0669\u06F0\u06F9\u0966\u096F\u09E6\u09EF\u0A66\u0A6F\u0AE6\u0AEF" +"\u0B66\u0B6F\u0BE7\u0BEF\u0C66\u0C6F\u0CE6\u0CEF\u0D66\u0D6F\u0E50\u0E59\u0ED0\u0ED9" +"\u0F20\u0F29\u1040\u1049\u1369\u1371\u17E0\u17E9\u1810\u1819\uFF10\uFF19"; + + private static final int[] DIGITS_INT = {0x1D7CE, 0x1D7FF}; + } diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaLoader.java --- a/src/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaLoader.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaLoader.java Tue Apr 17 11:17:59 2012 -0700 @@ -154,6 +154,8 @@ protected static final String SCHEMA_DV_FACTORY = Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_DV_FACTORY_PROPERTY; + protected static final String USE_SERVICE_MECHANISM = Constants.ORACLE_FEATURE_SERVICE_MECHANISM; + // recognized features: private static final String[] RECOGNIZED_FEATURES = { SCHEMA_FULL_CHECKING, @@ -166,7 +168,8 @@ VALIDATE_ANNOTATIONS, HONOUR_ALL_SCHEMALOCATIONS, NAMESPACE_GROWTH, - TOLERATE_DUPLICATES + TOLERATE_DUPLICATES, + USE_SERVICE_MECHANISM }; // property identifiers @@ -1148,7 +1151,8 @@ name.equals(GENERATE_SYNTHETIC_ANNOTATIONS) || name.equals(HONOUR_ALL_SCHEMALOCATIONS) || name.equals(NAMESPACE_GROWTH) || - name.equals(TOLERATE_DUPLICATES)) { + name.equals(TOLERATE_DUPLICATES) || + name.equals(USE_SERVICE_MECHANISM)) { return true; } @@ -1227,6 +1231,7 @@ v.add(HONOUR_ALL_SCHEMALOCATIONS); v.add(NAMESPACE_GROWTH); v.add(TOLERATE_DUPLICATES); + v.add(USE_SERVICE_MECHANISM); fRecognizedParameters = new DOMStringListImpl(v); } return fRecognizedParameters; diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaValidator.java --- a/src/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaValidator.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaValidator.java Tue Apr 17 11:17:59 2012 -0700 @@ -233,6 +233,8 @@ protected static final String SCHEMA_DV_FACTORY = Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_DV_FACTORY_PROPERTY; + protected static final String USE_SERVICE_MECHANISM = Constants.ORACLE_FEATURE_SERVICE_MECHANISM; + // recognized features and properties /** Recognized features. */ @@ -250,7 +252,8 @@ HONOUR_ALL_SCHEMALOCATIONS, USE_GRAMMAR_POOL_ONLY, NAMESPACE_GROWTH, - TOLERATE_DUPLICATES + TOLERATE_DUPLICATES, + USE_SERVICE_MECHANISM }; /** Feature defaults. */ @@ -272,7 +275,8 @@ null, null, null, - null + null, + Boolean.TRUE }; /** Recognized properties. */ @@ -3488,7 +3492,8 @@ if (fIdentityConstraint.getCategory() == IdentityConstraint.IC_KEY) { String code = "AbsentKeyValue"; String eName = fIdentityConstraint.getElementName(); - reportSchemaError(code, new Object[] { eName }); + String cName = fIdentityConstraint.getIdentityConstraintName(); + reportSchemaError(code, new Object[] { eName, cName }); } return; } @@ -3503,9 +3508,9 @@ if (fIdentityConstraint.getCategory() == IdentityConstraint.IC_KEY) { String code = "KeyNotEnoughValues"; UniqueOrKey key = (UniqueOrKey) fIdentityConstraint; - String ename = fIdentityConstraint.getElementName(); - String kname = key.getIdentityConstraintName(); - reportSchemaError(code, new Object[] { ename, kname }); + String eName = fIdentityConstraint.getElementName(); + String cName = key.getIdentityConstraintName(); + reportSchemaError(code, new Object[] { eName, cName }); } return; } @@ -3558,12 +3563,15 @@ // do we even know this field? if (i == -1) { String code = "UnknownField"; - reportSchemaError(code, new Object[] { field.toString()}); + String eName = fIdentityConstraint.getElementName(); + String cName = fIdentityConstraint.getIdentityConstraintName(); + reportSchemaError(code, new Object[] { field.toString(), eName, cName }); return; } if (Boolean.TRUE != mayMatch(field)) { String code = "FieldMultipleMatch"; - reportSchemaError(code, new Object[] { field.toString()}); + String cName = fIdentityConstraint.getIdentityConstraintName(); + reportSchemaError(code, new Object[] { field.toString(), cName }); } else { fValuesCount++; } @@ -3844,8 +3852,9 @@ if (contains()) { String code = "DuplicateUnique"; String value = toString(fLocalValues); - String ename = fIdentityConstraint.getElementName(); - reportSchemaError(code, new Object[] { value, ename }); + String eName = fIdentityConstraint.getElementName(); + String cName = fIdentityConstraint.getIdentityConstraintName(); + reportSchemaError(code, new Object[] { value, eName, cName }); } } // duplicateValue(Hashtable) @@ -3880,8 +3889,9 @@ if (contains()) { String code = "DuplicateKey"; String value = toString(fLocalValues); - String ename = fIdentityConstraint.getElementName(); - reportSchemaError(code, new Object[] { value, ename }); + String eName = fIdentityConstraint.getElementName(); + String cName = fIdentityConstraint.getIdentityConstraintName(); + reportSchemaError(code, new Object[] { value, eName, cName }); } } // duplicateValue(Hashtable) diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xerces/internal/impl/xs/identity/Field.java --- a/src/com/sun/org/apache/xerces/internal/impl/xs/identity/Field.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xerces/internal/impl/xs/identity/Field.java Tue Apr 17 11:17:59 2012 -0700 @@ -35,6 +35,7 @@ * @xerces.internal * * @author Andy Clark, IBM + * @version $Id: Field.java,v 1.6 2010-11-01 04:39:57 joehw Exp $ */ public class Field { @@ -176,7 +177,8 @@ super.matched(actualValue, valueType, itemValueType, isNil); if(isNil && (fIdentityConstraint.getCategory() == IdentityConstraint.IC_KEY)) { String code = "KeyMatchesNillable"; - fStore.reportError(code, new Object[]{fIdentityConstraint.getElementName()}); + fStore.reportError(code, + new Object[]{fIdentityConstraint.getElementName(), fIdentityConstraint.getIdentityConstraintName()}); } fStore.addValue(Field.this, actualValue, convertToPrimitiveKind(valueType), convertToPrimitiveKind(itemValueType)); // once we've stored the value for this field, we set the mayMatch diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xerces/internal/jaxp/datatype/XMLGregorianCalendarImpl.java --- a/src/com/sun/org/apache/xerces/internal/jaxp/datatype/XMLGregorianCalendarImpl.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xerces/internal/jaxp/datatype/XMLGregorianCalendarImpl.java Tue Apr 17 11:17:59 2012 -0700 @@ -39,7 +39,7 @@ import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.namespace.QName; import com.sun.org.apache.xerces.internal.util.DatatypeMessageFormatter; - +import com.sun.org.apache.xerces.internal.utils.SecuritySupport; /** *

Representation for W3C XML Schema 1.0 date/time datatypes. @@ -2394,7 +2394,10 @@ GregorianCalendar result = null; final int DEFAULT_TIMEZONE_OFFSET = DatatypeConstants.FIELD_UNDEFINED; TimeZone tz = getTimeZone(DEFAULT_TIMEZONE_OFFSET); - Locale locale = Locale.getDefault(); + /** Use the following instead for JDK7 only: + * Locale locale = Locale.getDefault(Locale.Category.FORMAT); + */ + Locale locale = getDefaultLocale(); result = new GregorianCalendar(tz, locale); result.clear(); @@ -2442,6 +2445,33 @@ } /** + * + * @return default locale + */ + private Locale getDefaultLocale() { + + String lang = SecuritySupport.getSystemProperty("user.language.format"); + String country = SecuritySupport.getSystemProperty("user.country.format"); + String variant = SecuritySupport.getSystemProperty("user.variant.format"); + Locale locale = null; + if (lang != null) { + if (country != null) { + if (variant != null) { + locale = new Locale(lang, country, variant); + } else { + locale = new Locale(lang, country); + } + } else { + locale = new Locale(lang); + } + } + if (locale == null) { + locale = Locale.getDefault(); + } + return locale; + } + + /** *

Convert this along with provided parameters * to java.util.GregorianCalendar instance.

* diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xerces/internal/jaxp/validation/DOMValidatorHelper.java --- a/src/com/sun/org/apache/xerces/internal/jaxp/validation/DOMValidatorHelper.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xerces/internal/jaxp/validation/DOMValidatorHelper.java Tue Apr 17 11:17:59 2012 -0700 @@ -37,6 +37,7 @@ import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager; import com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator; import com.sun.org.apache.xerces.internal.impl.xs.util.SimpleLocator; +import com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl; import com.sun.org.apache.xerces.internal.util.NamespaceSupport; import com.sun.org.apache.xerces.internal.util.SymbolTable; import com.sun.org.apache.xerces.internal.util.XMLAttributesImpl; @@ -62,7 +63,7 @@ *

A validator helper for DOMSources.

* * @author Michael Glavassevich, IBM - * @version $Id: DOMValidatorHelper.java,v 1.8 2010/07/23 02:09:26 joehw Exp $ + * @version $Id: DOMValidatorHelper.java,v 1.9 2010-11-01 04:40:08 joehw Exp $ */ final class DOMValidatorHelper implements ValidatorHelper, EntityState { @@ -381,7 +382,8 @@ } if (result.getNode() == null) { try { - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilderFactory factory = fComponentManager.getFeature(Constants.ORACLE_FEATURE_SERVICE_MECHANISM) ? + DocumentBuilderFactory.newInstance() : new DocumentBuilderFactoryImpl(); factory.setNamespaceAware(true); DocumentBuilder builder = factory.newDocumentBuilder(); result.setNode(builder.newDocument()); diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xerces/internal/jaxp/validation/StAXValidatorHelper.java --- a/src/com/sun/org/apache/xerces/internal/jaxp/validation/StAXValidatorHelper.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xerces/internal/jaxp/validation/StAXValidatorHelper.java Tue Apr 17 11:17:59 2012 -0700 @@ -25,6 +25,7 @@ package com.sun.org.apache.xerces.internal.jaxp.validation; +import com.sun.org.apache.xerces.internal.impl.Constants; import java.io.IOException; import javax.xml.transform.Result; @@ -32,6 +33,7 @@ import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; import javax.xml.transform.TransformerFactoryConfigurationError; import javax.xml.transform.sax.SAXResult; import javax.xml.transform.sax.SAXTransformerFactory; @@ -47,6 +49,7 @@ * @author Sunitha Reddy */ public final class StAXValidatorHelper implements ValidatorHelper { + private static final String DEFAULT_TRANSFORMER_IMPL = "com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl"; /** Component manager. **/ private XMLSchemaValidatorComponentManager fComponentManager; @@ -67,7 +70,9 @@ if( identityTransformer1==null ) { try { - SAXTransformerFactory tf = (SAXTransformerFactory)SAXTransformerFactory.newInstance(); + SAXTransformerFactory tf = fComponentManager.getFeature(Constants.ORACLE_FEATURE_SERVICE_MECHANISM) ? + (SAXTransformerFactory)SAXTransformerFactory.newInstance() + : (SAXTransformerFactory) TransformerFactory.newInstance(DEFAULT_TRANSFORMER_IMPL, StAXValidatorHelper.class.getClassLoader()); identityTransformer1 = tf.newTransformer(); identityTransformer2 = tf.newTransformerHandler(); } catch (TransformerConfigurationException e) { diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xerces/internal/jaxp/validation/StreamValidatorHelper.java --- a/src/com/sun/org/apache/xerces/internal/jaxp/validation/StreamValidatorHelper.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xerces/internal/jaxp/validation/StreamValidatorHelper.java Tue Apr 17 11:17:59 2012 -0700 @@ -30,7 +30,7 @@ import javax.xml.transform.stream.StreamSource; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; import javax.xml.transform.TransformerFactoryConfigurationError; import com.sun.org.apache.xerces.internal.impl.Constants; @@ -48,7 +48,7 @@ * * @author Michael Glavassevich, IBM * @author Sunitha Reddy - * @version $Id: StreamValidatorHelper.java,v 1.6 2010/07/23 02:09:26 joehw Exp $ + * @version $Id: StreamValidatorHelper.java,v 1.7 2010-11-01 04:40:08 joehw Exp $ */ final class StreamValidatorHelper implements ValidatorHelper { @@ -84,6 +84,7 @@ private static final String VALIDATION_MANAGER = Constants.XERCES_PROPERTY_PREFIX + Constants.VALIDATION_MANAGER_PROPERTY; + private static final String DEFAULT_TRANSFORMER_IMPL = "com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl"; // // Data // @@ -112,7 +113,9 @@ if( result!=null ) { try { - SAXTransformerFactory tf = (SAXTransformerFactory)SAXTransformerFactory.newInstance(); + SAXTransformerFactory tf = fComponentManager.getFeature(Constants.ORACLE_FEATURE_SERVICE_MECHANISM) ? + (SAXTransformerFactory)SAXTransformerFactory.newInstance() + : (SAXTransformerFactory) TransformerFactory.newInstance(DEFAULT_TRANSFORMER_IMPL, StreamValidatorHelper.class.getClassLoader()); identityTransformerHandler = tf.newTransformerHandler(); } catch (TransformerConfigurationException e) { throw new TransformerFactoryConfigurationError(e); diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xerces/internal/jaxp/validation/ValidatorHandlerImpl.java --- a/src/com/sun/org/apache/xerces/internal/jaxp/validation/ValidatorHandlerImpl.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xerces/internal/jaxp/validation/ValidatorHandlerImpl.java Tue Apr 17 11:17:59 2012 -0700 @@ -43,6 +43,7 @@ import com.sun.org.apache.xerces.internal.impl.validation.EntityState; import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager; import com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator; +import com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl; import com.sun.org.apache.xerces.internal.util.AttributesProxy; import com.sun.org.apache.xerces.internal.util.SAXLocatorWrapper; import com.sun.org.apache.xerces.internal.util.SAXMessageFormatter; @@ -669,7 +670,8 @@ XMLReader reader = saxSource.getXMLReader(); if( reader==null ) { // create one now - SAXParserFactory spf = SAXParserFactory.newInstance(); + SAXParserFactory spf = fComponentManager.getFeature(Constants.ORACLE_FEATURE_SERVICE_MECHANISM) ? + SAXParserFactory.newInstance() : new SAXParserFactoryImpl(); spf.setNamespaceAware(true); try { reader = spf.newSAXParser().getXMLReader(); diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java --- a/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java Tue Apr 17 11:17:59 2012 -0700 @@ -107,7 +107,20 @@ /** The container for the real grammar pool. */ private XMLGrammarPoolWrapper fXMLGrammarPoolWrapper; + /** + * Indicates whether implementation parts should use + * service loader (or similar). + * Note the default value (false) is the safe option.. + */ + private final boolean fUseServicesMechanism; public XMLSchemaFactory() { + this(true); + } + public static XMLSchemaFactory newXMLSchemaFactoryNoServiceLoader() { + return new XMLSchemaFactory(false); + } + private XMLSchemaFactory(boolean useServicesMechanism) { + fUseServicesMechanism = useServicesMechanism; fErrorHandlerWrapper = new ErrorHandlerWrapper(DraconianErrorHandler.getInstance()); fDOMEntityResolverWrapper = new DOMEntityResolverWrapper(); fXMLGrammarPoolWrapper = new XMLGrammarPoolWrapper(); @@ -338,6 +351,10 @@ fSecurityManager = value ? new SecurityManager() : null; fXMLSchemaLoader.setProperty(SECURITY_MANAGER, fSecurityManager); return; + } else if (name.equals(Constants.ORACLE_FEATURE_SERVICE_MECHANISM)) { + //in secure mode, let _useServicesMechanism be determined by the constructor + if (System.getSecurityManager() != null) + return; } try { fXMLSchemaLoader.setFeature(name, value); @@ -393,6 +410,7 @@ private void propagateFeatures(AbstractXMLSchema schema) { schema.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, fSecurityManager != null); + schema.setFeature(Constants.ORACLE_FEATURE_SERVICE_MECHANISM, fUseServicesMechanism); String[] features = fXMLSchemaLoader.getRecognizedFeatures(); for (int i = 0; i < features.length; ++i) { boolean state = fXMLSchemaLoader.getFeature(features[i]); diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xerces/internal/parsers/AbstractDOMParser.java --- a/src/com/sun/org/apache/xerces/internal/parsers/AbstractDOMParser.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xerces/internal/parsers/AbstractDOMParser.java Tue Apr 17 11:17:59 2012 -0700 @@ -56,6 +56,7 @@ import com.sun.org.apache.xerces.internal.xs.AttributePSVI; import com.sun.org.apache.xerces.internal.xs.ElementPSVI; import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition; +import com.sun.org.apache.xerces.internal.utils.ObjectFactory; import org.w3c.dom.Attr; import org.w3c.dom.CDATASection; import org.w3c.dom.Comment; @@ -314,7 +315,7 @@ } // (XMLParserConfiguration) /** - * This method retreives the name of current document class. + * This method retrieves the name of current document class. */ protected String getDocumentClassName () { return fDocumentClassName; @@ -345,8 +346,7 @@ !documentClassName.equals(PSVI_DOCUMENT_CLASS_NAME)) { // verify that this class exists and is of the right type try { - Class _class = ObjectFactory.findProviderClass (documentClassName, - ObjectFactory.findClassLoader (), true); + Class _class = ObjectFactory.findProviderClass (documentClassName, true); //if (!_class.isAssignableFrom(Document.class)) { if (!Document.class.isAssignableFrom (_class)) { throw new IllegalArgumentException ( @@ -789,20 +789,16 @@ else { // use specified document class try { - ClassLoader cl = ObjectFactory.findClassLoader(); - Class documentClass = ObjectFactory.findProviderClass (fDocumentClassName, - cl, true); + Class documentClass = ObjectFactory.findProviderClass (fDocumentClassName, true); fDocument = (Document)documentClass.newInstance (); // if subclass of our own class that's cool too Class defaultDocClass = - ObjectFactory.findProviderClass (CORE_DOCUMENT_CLASS_NAME, - cl, true); + ObjectFactory.findProviderClass (CORE_DOCUMENT_CLASS_NAME, true); if (defaultDocClass.isAssignableFrom (documentClass)) { fDocumentImpl = (CoreDocumentImpl)fDocument; - Class psviDocClass = ObjectFactory.findProviderClass (PSVI_DOCUMENT_CLASS_NAME, - cl, true); + Class psviDocClass = ObjectFactory.findProviderClass (PSVI_DOCUMENT_CLASS_NAME, true); if (psviDocClass.isAssignableFrom (documentClass)) { fStorePSVI = true; } diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xerces/internal/parsers/DOMParser.java --- a/src/com/sun/org/apache/xerces/internal/parsers/DOMParser.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xerces/internal/parsers/DOMParser.java Tue Apr 17 11:17:59 2012 -0700 @@ -135,10 +135,7 @@ * grammar pool. */ public DOMParser(SymbolTable symbolTable, XMLGrammarPool grammarPool) { - super((XMLParserConfiguration)ObjectFactory.createObject( - "com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration", - "com.sun.org.apache.xerces.internal.parsers.XIncludeAwareParserConfiguration" - )); + super(new XIncludeAwareParserConfiguration()); // set properties fConfiguration.addRecognizedProperties(RECOGNIZED_PROPERTIES); diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xerces/internal/parsers/DOMParserImpl.java --- a/src/com/sun/org/apache/xerces/internal/parsers/DOMParserImpl.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xerces/internal/parsers/DOMParserImpl.java Tue Apr 17 11:17:59 2012 -0700 @@ -55,6 +55,7 @@ import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource; import com.sun.org.apache.xerces.internal.xni.parser.XMLParseException; import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration; +import com.sun.org.apache.xerces.internal.parsers.XIncludeAwareParserConfiguration; import org.w3c.dom.DOMConfiguration; import org.w3c.dom.DOMError; import org.w3c.dom.DOMErrorHandler; @@ -165,11 +166,8 @@ /** * Constructs a DOM Builder using the standard parser configuration. */ - public DOMParserImpl (String configuration, String schemaType) { - this ( - (XMLParserConfiguration) ObjectFactory.createObject ( - "com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration", - configuration)); + public DOMParserImpl (XMLParserConfiguration config, String schemaType) { + this (config); if (schemaType != null) { if (schemaType.equals (Constants.NS_DTD)) { //Schema validation is false by default and hence there is no @@ -261,10 +259,7 @@ * Constructs a DOM Builder using the specified symbol table. */ public DOMParserImpl (SymbolTable symbolTable) { - this ( - (XMLParserConfiguration) ObjectFactory.createObject ( - "com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration", - "com.sun.org.apache.xerces.internal.parsers.XIncludeAwareParserConfiguration")); + this (new XIncludeAwareParserConfiguration()); fConfiguration.setProperty ( Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY, symbolTable); @@ -276,10 +271,7 @@ * grammar pool. */ public DOMParserImpl (SymbolTable symbolTable, XMLGrammarPool grammarPool) { - this ( - (XMLParserConfiguration) ObjectFactory.createObject ( - "com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration", - "com.sun.org.apache.xerces.internal.parsers.XIncludeAwareParserConfiguration")); + this (new XIncludeAwareParserConfiguration()); fConfiguration.setProperty ( Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY, symbolTable); diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xerces/internal/parsers/ObjectFactory.java --- a/src/com/sun/org/apache/xerces/internal/parsers/ObjectFactory.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,553 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2001-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 com.sun.org.apache.xerces.internal.parsers; - -import java.io.InputStream; -import java.io.IOException; -import java.io.File; -import java.io.FileInputStream; - -import java.util.Properties; -import java.io.BufferedReader; -import java.io.InputStreamReader; - -/** - * 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. - *

- * This code is designed to implement the JAXP 1.1 spec pluggability - * feature and is designed to run on JDK version 1.1 and - * later, and to compile on JDK 1.2 and onward. - * The code also runs both as part of an unbundled jar file and - * when bundled as part of the JDK. - *

- * - */ -final class ObjectFactory { - - // - // Constants - // - - // name of default properties file to look for in JDK's jre/lib directory - private static final String DEFAULT_PROPERTIES_FILENAME = "xerces.properties"; - - /** Set to true for debugging */ - private static final boolean DEBUG = false; - - /** - * Default columns per line. - */ - private static final int DEFAULT_LINE_LENGTH = 80; - - /** cache the contents of the xerces.properties file. - * Until an attempt has been made to read this file, this will - * be null; if the file does not exist or we encounter some other error - * during the read, this will be empty. - */ - private static Properties fXercesProperties = null; - - /*** - * Cache the time stamp of the xerces.properties file so - * that we know if it's been modified and can invalidate - * the cache when necessary. - */ - private static long fLastModified = -1; - - // - // static methods - // - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *

    - *
  1. query the system property using System.getProperty - *
  2. read META-INF/services/factoryId file - *
  3. use fallback classname - *
- * - * @return Class object of factory, 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 no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Object createObject(String factoryId, String fallbackClassName) - throws ConfigurationError { - return createObject(factoryId, null, fallbackClassName); - } // createObject(String,String):Object - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return Class object of factory, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xerces.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Object createObject(String factoryId, - String propertiesFilename, - String fallbackClassName) - throws ConfigurationError - { - if (DEBUG) debugPrintln("debug is on"); - - SecuritySupport ss = SecuritySupport.getInstance(); - ClassLoader cl = findClassLoader(); - - // Use the system property first - try { - String systemProp = ss.getSystemProperty(factoryId); - if (systemProp != null) { - if (DEBUG) debugPrintln("found system property, value=" + systemProp); - return newInstance(systemProp, cl, true); - } - } catch (SecurityException se) { - // Ignore and continue w/ next location - } - - // JAXP specific change - // always use fallback class to avoid the expense of constantly - // "stat"ing a non-existent "xerces.properties" and jar SPI entry - // see CR 6400863: Expensive creating of SAX parser in Mustang - if (true) { - if (fallbackClassName == null) { - throw new ConfigurationError( - "Provider for " + factoryId + " cannot be found", null); - } - - if (DEBUG) debugPrintln("using fallback, value=" + fallbackClassName); - return newInstance(fallbackClassName, cl, true); - } - - // Try to read from propertiesFilename, or $java.home/lib/xerces.properties - String factoryClassName = null; - // no properties file name specified; use $JAVA_HOME/lib/xerces.properties: - if (propertiesFilename == null) { - File propertiesFile = null; - boolean propertiesFileExists = false; - try { - String javah = ss.getSystemProperty("java.home"); - propertiesFilename = javah + File.separator + - "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME; - propertiesFile = new File(propertiesFilename); - propertiesFileExists = ss.getFileExists(propertiesFile); - } catch (SecurityException e) { - // try again... - fLastModified = -1; - fXercesProperties = null; - } - - synchronized (ObjectFactory.class) { - boolean loadProperties = false; - FileInputStream fis = null; - try { - // file existed last time - if(fLastModified >= 0) { - if(propertiesFileExists && - (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) { - loadProperties = true; - } else { - // file has stopped existing... - if(!propertiesFileExists) { - fLastModified = -1; - fXercesProperties = null; - } // else, file wasn't modified! - } - } else { - // file has started to exist: - if(propertiesFileExists) { - loadProperties = true; - fLastModified = ss.getLastModified(propertiesFile); - } // else, nothing's changed - } - if(loadProperties) { - // must never have attempted to read xerces.properties before (or it's outdeated) - fXercesProperties = new Properties(); - fis = ss.getFileInputStream(propertiesFile); - fXercesProperties.load(fis); - } - } catch (Exception x) { - fXercesProperties = null; - fLastModified = -1; - // assert(x instanceof FileNotFoundException - // || x instanceof SecurityException) - // In both cases, ignore and continue w/ next location - } - finally { - // try to close the input stream if one was opened. - if (fis != null) { - try { - fis.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - } - } - if(fXercesProperties != null) { - factoryClassName = fXercesProperties.getProperty(factoryId); - } - } else { - FileInputStream fis = null; - try { - fis = ss.getFileInputStream(new File(propertiesFilename)); - Properties props = new Properties(); - props.load(fis); - factoryClassName = props.getProperty(factoryId); - } catch (Exception x) { - // assert(x instanceof FileNotFoundException - // || x instanceof SecurityException) - // In both cases, ignore and continue w/ next location - } - finally { - // try to close the input stream if one was opened. - if (fis != null) { - try { - fis.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - } - } - if (factoryClassName != null) { - if (DEBUG) debugPrintln("found in " + propertiesFilename + ", value=" + factoryClassName); - return newInstance(factoryClassName, cl, true); - } - - // 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); - } - - if (DEBUG) debugPrintln("using fallback, value=" + fallbackClassName); - return newInstance(fallbackClassName, cl, true); - } // createObject(String,String,String):Object - - // - // Private static methods - // - - /** Prints a message to standard error if debugging is enabled. */ - private static void debugPrintln(String msg) { - if (DEBUG) { - System.err.println("JAXP: " + msg); - } - } // debugPrintln(String) - - /** - * Figure out which ClassLoader to use. For JDK 1.2 and later use - * the context ClassLoader. - */ - static ClassLoader findClassLoader() - 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 context = ss.getContextClassLoader(); - ClassLoader system = ss.getSystemClassLoader(); - - ClassLoader chain = system; - while (true) { - if (context == chain) { - // Assert: we are on JDK 1.1 or we have no Context ClassLoader - // or any Context ClassLoader in chain of system classloader - // (including extension ClassLoader) so extend to widest - // ClassLoader (always look in system ClassLoader if Xerces - // is in boot/extension/system classpath and in current - // ClassLoader otherwise); normal classloaders delegate - // back to system ClassLoader first so this widening doesn't - // change the fact that context ClassLoader will be consulted - ClassLoader current = ObjectFactory.class.getClassLoader(); - - chain = system; - while (true) { - if (current == chain) { - // Assert: Current ClassLoader in chain of - // boot/extension/system ClassLoaders - return system; - } - if (chain == null) { - break; - } - chain = ss.getParentClassLoader(chain); - } - - // Assert: Current ClassLoader not in chain of - // boot/extension/system ClassLoaders - return current; - } - - if (chain == null) { - // boot ClassLoader reached - break; - } - - // Check for any extension ClassLoaders in chain up to - // boot ClassLoader - chain = ss.getParentClassLoader(chain); - }; - - // Assert: Context ClassLoader not in chain of - // boot/extension/system ClassLoaders - return context; - } // findClassLoader():ClassLoader - - /** - * Create an instance of a class using the specified ClassLoader - */ - static Object newInstance(String className, ClassLoader cl, - boolean doFallback) - throws ConfigurationError - { - // assert(className != null); - try{ - Class providerClass = findProviderClass(className, cl, doFallback); - Object instance = providerClass.newInstance(); - if (DEBUG) debugPrintln("created new instance of " + providerClass + - " using ClassLoader: " + cl); - return instance; - } catch (ClassNotFoundException x) { - throw new ConfigurationError( - "Provider " + className + " not found", x); - } catch (Exception x) { - throw new ConfigurationError( - "Provider " + className + " could not be instantiated: " + x, - x); - } - } - - /** - * Find a Class using the specified ClassLoader - */ - static Class findProviderClass(String className, ClassLoader cl, - boolean doFallback) - throws ClassNotFoundException, ConfigurationError - { - //throw security exception if the calling thread is not allowed to access the package - //restrict the access to package as speicified in java.security policy - SecurityManager security = System.getSecurityManager(); - if (security != null) { - final int lastDot = className.lastIndexOf("."); - String packageName = className; - if (lastDot != -1) packageName = className.substring(0, lastDot); - security.checkPackageAccess(packageName); - } - Class providerClass; - 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 { - try { - providerClass = cl.loadClass(className); - } catch (ClassNotFoundException x) { - if (doFallback) { - // Fall back to current classloader - ClassLoader current = ObjectFactory.class.getClassLoader(); - if (current == null) { - providerClass = Class.forName(className); - } else if (cl != current) { - cl = current; - providerClass = cl.loadClass(className); - } else { - throw x; - } - } else { - throw x; - } - } - } - - return providerClass; - } - - /* - * Try to find provider using Jar Service Provider Mechanism - * - * @return instance of provider class if found or null - */ - private static Object findJarServiceProvider(String factoryId) - throws ConfigurationError - { - SecuritySupport ss = SecuritySupport.getInstance(); - String serviceId = "META-INF/services/" + factoryId; - InputStream is = null; - - // First try the Context ClassLoader - ClassLoader cl = findClassLoader(); - - is = ss.getResourceAsStream(cl, serviceId); - - // If no provider found then try the current ClassLoader - if (is == null) { - ClassLoader current = ObjectFactory.class.getClassLoader(); - if (cl != current) { - cl = current; - is = ss.getResourceAsStream(cl, serviceId); - } - } - - if (is == null) { - // No provider found - return null; - } - - if (DEBUG) debugPrintln("found jar resource=" + serviceId + - " using ClassLoader: " + cl); - - // 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"), DEFAULT_LINE_LENGTH); - } catch (java.io.UnsupportedEncodingException e) { - rd = new BufferedReader(new InputStreamReader(is), DEFAULT_LINE_LENGTH); - } - - String factoryClassName = null; - try { - // XXX Does not handle all possible input as specified by the - // Jar Service Provider specification - factoryClassName = rd.readLine(); - } catch (IOException x) { - // No provider found - return null; - } - finally { - try { - // try to close the reader. - rd.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - - if (factoryClassName != null && - ! "".equals(factoryClassName)) { - if (DEBUG) debugPrintln("found in resource, value=" - + factoryClassName); - - // Note: here we do not want to fall back to the current - // 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. - return newInstance(factoryClassName, cl, false); - } - - // No provider found - return null; - } - - // - // Classes - // - - /** - * A configuration error. - */ - static final class ConfigurationError - extends Error { - - /** Serialization version. */ - static final long serialVersionUID = -7285495612271660427L; - - // - // Data - // - - /** Exception. */ - private Exception exception; - - // - // Constructors - // - - /** - * Construct a new instance with the specified detail string and - * exception. - */ - ConfigurationError(String msg, Exception x) { - super(msg); - this.exception = x; - } // (String,Exception) - - // - // methods - // - - /** Returns the exception associated to this error. */ - Exception getException() { - return exception; - } // getException():Exception - - } // class ConfigurationError - -} // class ObjectFactory diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xerces/internal/parsers/SAXParser.java --- a/src/com/sun/org/apache/xerces/internal/parsers/SAXParser.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xerces/internal/parsers/SAXParser.java Tue Apr 17 11:17:59 2012 -0700 @@ -33,7 +33,7 @@ * @author Arnaud Le Hors, IBM * @author Andy Clark, IBM * - * @version $Id: SAXParser.java,v 1.5 2007/07/19 04:38:54 ofung Exp $ + * @version $Id: SAXParser.java,v 1.7 2010-11-01 04:40:09 joehw Exp $ */ public class SAXParser extends AbstractSAXParser { @@ -103,10 +103,7 @@ * grammar pool. */ public SAXParser(SymbolTable symbolTable, XMLGrammarPool grammarPool) { - super((XMLParserConfiguration)ObjectFactory.createObject( - "com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration", - "com.sun.org.apache.xerces.internal.parsers.XIncludeAwareParserConfiguration" - )); + super(new XIncludeAwareParserConfiguration()); // set features fConfiguration.addRecognizedFeatures(RECOGNIZED_FEATURES); diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xerces/internal/parsers/SecuritySupport.java --- a/src/com/sun/org/apache/xerces/internal/parsers/SecuritySupport.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,152 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2002,2004 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 com.sun.org.apache.xerces.internal.parsers; - -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 subpackage so keep it in sync. - * It is package private and therefore is not exposed as part of any API. - * - * @xerces.internal - */ -final class SecuritySupport { - - private static final SecuritySupport securitySupport = new SecuritySupport(); - - /** - * Return an instance of this class. - */ - static SecuritySupport getInstance() { - return securitySupport; - } - - ClassLoader getContextClassLoader() { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader cl = null; - try { - cl = Thread.currentThread().getContextClassLoader(); - } catch (SecurityException ex) { } - return cl; - } - }); - } - - ClassLoader getSystemClassLoader() { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader cl = null; - try { - cl = ClassLoader.getSystemClassLoader(); - } catch (SecurityException ex) {} - return cl; - } - }); - } - - ClassLoader getParentClassLoader(final ClassLoader cl) { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader parent = null; - try { - parent = cl.getParent(); - } catch (SecurityException ex) {} - - // eliminate loops in case of the boot - // ClassLoader returning itself as a parent - return (parent == cl) ? null : parent; - } - }); - } - - String getSystemProperty(final String propName) { - return (String) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return System.getProperty(propName); - } - }); - } - - 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(); - } - } - - 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; - } - }); - } - - boolean getFileExists(final File f) { - return ((Boolean) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return new Boolean(f.exists()); - } - })).booleanValue(); - } - - long getLastModified(final File f) { - return ((Long) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return new Long(f.lastModified()); - } - })).longValue(); - } - - private SecuritySupport () {} -} diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xerces/internal/parsers/XMLDocumentParser.java --- a/src/com/sun/org/apache/xerces/internal/parsers/XMLDocumentParser.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xerces/internal/parsers/XMLDocumentParser.java Tue Apr 17 11:17:59 2012 -0700 @@ -33,6 +33,7 @@ * @author Arnaud Le Hors, IBM * @author Andy Clark, IBM * + * @version $Id: XMLDocumentParser.java,v 1.6 2010-11-01 04:40:10 joehw Exp $ */ public class XMLDocumentParser extends AbstractXMLDocumentParser { @@ -46,10 +47,7 @@ * configuration. */ public XMLDocumentParser() { - super((XMLParserConfiguration)ObjectFactory.createObject( - "com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration", - "com.sun.org.apache.xerces.internal.parsers.XIncludeAwareParserConfiguration" - )); + super(new XIncludeAwareParserConfiguration()); } // () /** @@ -63,10 +61,7 @@ * Constructs a document parser using the specified symbol table. */ public XMLDocumentParser(SymbolTable symbolTable) { - super((XMLParserConfiguration)ObjectFactory.createObject( - "com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration", - "com.sun.org.apache.xerces.internal.parsers.XIncludeAwareParserConfiguration" - )); + super(new XIncludeAwareParserConfiguration()); fConfiguration.setProperty(Constants.XERCES_PROPERTY_PREFIX+Constants.SYMBOL_TABLE_PROPERTY, symbolTable); } // (SymbolTable) @@ -76,10 +71,7 @@ */ public XMLDocumentParser(SymbolTable symbolTable, XMLGrammarPool grammarPool) { - super((XMLParserConfiguration)ObjectFactory.createObject( - "com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration", - "com.sun.org.apache.xerces.internal.parsers.XIncludeAwareParserConfiguration" - )); + super(new XIncludeAwareParserConfiguration()); fConfiguration.setProperty(Constants.XERCES_PROPERTY_PREFIX+Constants.SYMBOL_TABLE_PROPERTY, symbolTable); fConfiguration.setProperty(Constants.XERCES_PROPERTY_PREFIX+Constants.XMLGRAMMAR_POOL_PROPERTY, grammarPool); } diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xerces/internal/parsers/XMLGrammarParser.java --- a/src/com/sun/org/apache/xerces/internal/parsers/XMLGrammarParser.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xerces/internal/parsers/XMLGrammarParser.java Tue Apr 17 11:17:59 2012 -0700 @@ -23,9 +23,9 @@ import com.sun.org.apache.xerces.internal.impl.Constants; import com.sun.org.apache.xerces.internal.impl.dv.DTDDVFactory; import com.sun.org.apache.xerces.internal.util.SymbolTable; -import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration; /** + * @version $Id: XMLGrammarParser.java,v 1.6 2010-11-01 04:40:10 joehw Exp $ */ public abstract class XMLGrammarParser extends XMLParser { @@ -47,10 +47,7 @@ * @param symbolTable */ protected XMLGrammarParser(SymbolTable symbolTable) { - super((XMLParserConfiguration)ObjectFactory.createObject( - "com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration", - "com.sun.org.apache.xerces.internal.parsers.XIncludeAwareParserConfiguration" - )); + super(new XIncludeAwareParserConfiguration()); fConfiguration.setProperty(Constants.XERCES_PROPERTY_PREFIX+Constants.SYMBOL_TABLE_PROPERTY, symbolTable); } diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xerces/internal/parsers/XMLGrammarPreparser.java --- a/src/com/sun/org/apache/xerces/internal/parsers/XMLGrammarPreparser.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xerces/internal/parsers/XMLGrammarPreparser.java Tue Apr 17 11:17:59 2012 -0700 @@ -37,6 +37,7 @@ import com.sun.org.apache.xerces.internal.xni.parser.XMLEntityResolver; import com.sun.org.apache.xerces.internal.xni.parser.XMLErrorHandler; import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource; +import com.sun.org.apache.xerces.internal.utils.ObjectFactory; /** *

This class provides an easy way for a user to preparse grammars @@ -48,7 +49,7 @@ * * @author Neil Graham, IBM * - * @version $Id: XMLGrammarPreparser.java,v 1.6 2010/07/23 02:09:28 joehw Exp $ + * @version $Id: XMLGrammarPreparser.java,v 1.7 2010-11-01 04:40:10 joehw Exp $ */ public class XMLGrammarPreparser { @@ -155,8 +156,7 @@ // got one; just instantiate it... String loaderName = (String)KNOWN_LOADERS.get(grammarType); try { - ClassLoader cl = ObjectFactory.findClassLoader(); - XMLGrammarLoader gl = (XMLGrammarLoader)(ObjectFactory.newInstance(loaderName, cl, true)); + XMLGrammarLoader gl = (XMLGrammarLoader)(ObjectFactory.newInstance(loaderName, true)); fLoaders.put(grammarType, gl); } catch (Exception e) { return false; diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xerces/internal/util/ParserConfigurationSettings.java --- a/src/com/sun/org/apache/xerces/internal/util/ParserConfigurationSettings.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xerces/internal/util/ParserConfigurationSettings.java Tue Apr 17 11:17:59 2012 -0700 @@ -112,7 +112,16 @@ * to be recognized. */ public void addRecognizedFeatures(String[] featureIds) { - fRecognizedFeatures.addAll(Arrays.asList(featureIds)); + + // add recognized features + int featureIdsCount = featureIds != null ? featureIds.length : 0; + for (int i = 0; i < featureIdsCount; i++) { + String featureId = featureIds[i]; + if (!fRecognizedFeatures.contains(featureId)) { + fRecognizedFeatures.add(featureId); + } + } + } // addRecognizedFeatures(String[]) /** diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xerces/internal/utils/ConfigurationError.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/com/sun/org/apache/xerces/internal/utils/ConfigurationError.java Tue Apr 17 11:17:59 2012 -0700 @@ -0,0 +1,58 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Copyright 2001-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 com.sun.org.apache.xerces.internal.utils; + +/** + * A configuration error. This was an internal class in ObjectFactory previously + */ +public final class ConfigurationError + extends Error { + + // + // Data + // + + /** Exception. */ + private Exception exception; + + // + // Constructors + // + + /** + * Construct a new instance with the specified detail string and + * exception. + */ + ConfigurationError(String msg, Exception x) { + super(msg); + this.exception = x; + } // (String,Exception) + + // + // methods + // + + /** Returns the exception associated to this error. */ + public Exception getException() { + return exception; + } // getException():Exception + +} // class ConfigurationError diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xerces/internal/utils/ObjectFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/com/sun/org/apache/xerces/internal/utils/ObjectFactory.java Tue Apr 17 11:17:59 2012 -0700 @@ -0,0 +1,431 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Copyright 2001-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 com.sun.org.apache.xerces.internal.utils; + +import java.io.InputStream; +import java.io.IOException; +import java.io.File; +import java.io.FileInputStream; + +import java.util.Properties; +import java.io.BufferedReader; +import java.io.InputStreamReader; + +/** + * 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. + *

+ * This code is designed to implement the JAXP 1.1 spec pluggability + * feature and is designed to run on JDK version 1.1 and + * later, and to compile on JDK 1.2 and onward. + * The code also runs both as part of an unbundled jar file and + * when bundled as part of the JDK. + *

+ * + * @version $Id: ObjectFactory.java,v 1.6 2010/04/23 01:44:34 joehw Exp $ + */ +public final class ObjectFactory { + + // + // Constants + // + + // name of default properties file to look for in JDK's jre/lib directory + private static final String DEFAULT_PROPERTIES_FILENAME = "xerces.properties"; + + /** Set to true for debugging */ + private static final boolean DEBUG = isDebugEnabled(); + + /** + * Default columns per line. + */ + private static final int DEFAULT_LINE_LENGTH = 80; + + /** cache the contents of the xerces.properties file. + * Until an attempt has been made to read this file, this will + * be null; if the file does not exist or we encounter some other error + * during the read, this will be empty. + */ + private static Properties fXercesProperties = null; + + /*** + * Cache the time stamp of the xerces.properties file so + * that we know if it's been modified and can invalidate + * the cache when necessary. + */ + private static long fLastModified = -1; + + // + // static methods + // + + /** + * Finds the implementation Class object in the specified order. The + * specified order is the following: + *

    + *
  1. query the system property using System.getProperty + *
  2. read META-INF/services/factoryId file + *
  3. use fallback classname + *
+ * + * @return Class object of factory, 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 no fallback. + * + * @exception ObjectFactory.ConfigurationError + */ + public static Object createObject(String factoryId, String fallbackClassName) + throws ConfigurationError { + return createObject(factoryId, null, fallbackClassName); + } // createObject(String,String):Object + + /** + * Finds the implementation Class object in the specified order. The + * specified order is the following: + *
    + *
  1. query the system property using System.getProperty + *
  2. read $java.home/lib/propertiesFilename file + *
  3. read META-INF/services/factoryId file + *
  4. use fallback classname + *
+ * + * @return Class object of factory, never null + * + * @param factoryId Name of the factory to find, same as + * a property name + * @param propertiesFilename The filename in the $java.home/lib directory + * of the properties file. If none specified, + * ${java.home}/lib/xerces.properties will be used. + * @param fallbackClassName Implementation class name, if nothing else + * is found. Use null to mean no fallback. + * + * @exception ObjectFactory.ConfigurationError + */ + public static Object createObject(String factoryId, + String propertiesFilename, + String fallbackClassName) + throws ConfigurationError + { + if (DEBUG) debugPrintln("debug is on"); + + ClassLoader cl = findClassLoader(); + + // Use the system property first + try { + String systemProp = SecuritySupport.getSystemProperty(factoryId); + if (systemProp != null && systemProp.length() > 0) { + if (DEBUG) debugPrintln("found system property, value=" + systemProp); + return newInstance(systemProp, cl, true); + } + } catch (SecurityException se) { + // Ignore and continue w/ next location + } + + // JAXP specific change + // always use fallback class to avoid the expense of constantly + // "stat"ing a non-existent "xerces.properties" and jar SPI entry + // see CR 6400863: Expensive creating of SAX parser in Mustang + if (fallbackClassName == null) { + throw new ConfigurationError( + "Provider for " + factoryId + " cannot be found", null); + } + + if (DEBUG) debugPrintln("using fallback, value=" + fallbackClassName); + return newInstance(fallbackClassName, cl, true); + + } // createObject(String,String,String):Object + + // + // Private static methods + // + + /** Returns true if debug has been enabled. */ + private static boolean isDebugEnabled() { + try { + String val = SecuritySupport.getSystemProperty("xerces.debug"); + // Allow simply setting the prop to turn on debug + return (val != null && (!"false".equals(val))); + } + catch (SecurityException se) {} + return false; + } // isDebugEnabled() + + /** Prints a message to standard error if debugging is enabled. */ + private static void debugPrintln(String msg) { + if (DEBUG) { + System.err.println("XERCES: " + msg); + } + } // debugPrintln(String) + + /** + * Figure out which ClassLoader to use. For JDK 1.2 and later use + * the context ClassLoader. + */ + public static ClassLoader findClassLoader() + throws ConfigurationError + { + if (System.getSecurityManager()!=null) { + //this will ensure bootclassloader is used + return null; + } + // Figure out which ClassLoader to use for loading the provider + // class. If there is a Context ClassLoader then use it. + ClassLoader context = SecuritySupport.getContextClassLoader(); + ClassLoader system = SecuritySupport.getSystemClassLoader(); + + ClassLoader chain = system; + while (true) { + if (context == chain) { + // Assert: we are on JDK 1.1 or we have no Context ClassLoader + // or any Context ClassLoader in chain of system classloader + // (including extension ClassLoader) so extend to widest + // ClassLoader (always look in system ClassLoader if Xerces + // is in boot/extension/system classpath and in current + // ClassLoader otherwise); normal classloaders delegate + // back to system ClassLoader first so this widening doesn't + // change the fact that context ClassLoader will be consulted + ClassLoader current = ObjectFactory.class.getClassLoader(); + + chain = system; + while (true) { + if (current == chain) { + // Assert: Current ClassLoader in chain of + // boot/extension/system ClassLoaders + return system; + } + if (chain == null) { + break; + } + chain = SecuritySupport.getParentClassLoader(chain); + } + + // Assert: Current ClassLoader not in chain of + // boot/extension/system ClassLoaders + return current; + } + + if (chain == null) { + // boot ClassLoader reached + break; + } + + // Check for any extension ClassLoaders in chain up to + // boot ClassLoader + chain = SecuritySupport.getParentClassLoader(chain); + }; + + // Assert: Context ClassLoader not in chain of + // boot/extension/system ClassLoaders + return context; + } // findClassLoader():ClassLoader + + /** + * Create an instance of a class using the same classloader for the ObjectFactory by default + * or bootclassloader when Security Manager is in place + */ + public static Object newInstance(String className, boolean doFallback) + throws ConfigurationError + { + if (System.getSecurityManager()!=null) { + return newInstance(className, null, doFallback); + } else { + return newInstance(className, + findClassLoader (), doFallback); + } + } + + /** + * Create an instance of a class using the specified ClassLoader + */ + public static Object newInstance(String className, ClassLoader cl, + boolean doFallback) + throws ConfigurationError + { + // assert(className != null); + try{ + Class providerClass = findProviderClass(className, cl, doFallback); + Object instance = providerClass.newInstance(); + if (DEBUG) debugPrintln("created new instance of " + providerClass + + " using ClassLoader: " + cl); + return instance; + } catch (ClassNotFoundException x) { + throw new ConfigurationError( + "Provider " + className + " not found", x); + } catch (Exception x) { + throw new ConfigurationError( + "Provider " + className + " could not be instantiated: " + x, + x); + } + } + + /** + * Find a Class using the same classloader for the ObjectFactory by default + * or bootclassloader when Security Manager is in place + */ + public static Class findProviderClass(String className, boolean doFallback) + throws ClassNotFoundException, ConfigurationError + { + if (System.getSecurityManager()!=null) { + return Class.forName(className); + } else { + return findProviderClass (className, + findClassLoader (), doFallback); + } + } + /** + * Find a Class using the specified ClassLoader + */ + public static Class findProviderClass(String className, ClassLoader cl, + boolean doFallback) + throws ClassNotFoundException, ConfigurationError + { + //throw security exception if the calling thread is not allowed to access the package + //restrict the access to package as speicified in java.security policy + SecurityManager security = System.getSecurityManager(); + if (security != null) { + final int lastDot = className.lastIndexOf("."); + String packageName = className; + if (lastDot != -1) packageName = className.substring(0, lastDot); + security.checkPackageAccess(packageName); + } + Class providerClass; + if (cl == null) { + //use the bootstrap ClassLoader. + providerClass = Class.forName(className); + } else { + try { + providerClass = cl.loadClass(className); + } catch (ClassNotFoundException x) { + if (doFallback) { + // Fall back to current classloader + ClassLoader current = ObjectFactory.class.getClassLoader(); + if (current == null) { + providerClass = Class.forName(className); + } else if (cl != current) { + cl = current; + providerClass = cl.loadClass(className); + } else { + throw x; + } + } else { + throw x; + } + } + } + + return providerClass; + } + + /* + * Try to find provider using Jar Service Provider Mechanism + * + * @return instance of provider class if found or null + */ + private static Object findJarServiceProvider(String factoryId) + throws ConfigurationError + { + String serviceId = "META-INF/services/" + factoryId; + InputStream is = null; + + // First try the Context ClassLoader + ClassLoader cl = findClassLoader(); + + is = SecuritySupport.getResourceAsStream(cl, serviceId); + + // If no provider found then try the current ClassLoader + if (is == null) { + ClassLoader current = ObjectFactory.class.getClassLoader(); + if (cl != current) { + cl = current; + is = SecuritySupport.getResourceAsStream(cl, serviceId); + } + } + + if (is == null) { + // No provider found + return null; + } + + if (DEBUG) debugPrintln("found jar resource=" + serviceId + + " using ClassLoader: " + cl); + + // 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"), DEFAULT_LINE_LENGTH); + } catch (java.io.UnsupportedEncodingException e) { + rd = new BufferedReader(new InputStreamReader(is), DEFAULT_LINE_LENGTH); + } + + String factoryClassName = null; + try { + // XXX Does not handle all possible input as specified by the + // Jar Service Provider specification + factoryClassName = rd.readLine(); + } catch (IOException x) { + // No provider found + return null; + } + finally { + try { + // try to close the reader. + rd.close(); + } + // Ignore the exception. + catch (IOException exc) {} + } + + if (factoryClassName != null && + ! "".equals(factoryClassName)) { + if (DEBUG) debugPrintln("found in resource, value=" + + factoryClassName); + + // Note: here we do not want to fall back to the current + // 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. + return newInstance(factoryClassName, cl, false); + } + + // No provider found + return null; + } + +} // class ObjectFactory diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xerces/internal/utils/SecuritySupport.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/com/sun/org/apache/xerces/internal/utils/SecuritySupport.java Tue Apr 17 11:17:59 2012 -0700 @@ -0,0 +1,163 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Copyright 2002,2004 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 com.sun.org.apache.xerces.internal.utils; + +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 subpackage so keep it in sync. + * It is package private and therefore is not exposed as part of any API. + * + * @xerces.internal + */ +public final class SecuritySupport { + + private static final SecuritySupport securitySupport = new SecuritySupport(); + + /** + * Return an instance of this class. + */ + public static SecuritySupport getInstance() { + return securitySupport; + } + + static ClassLoader getContextClassLoader() { + return (ClassLoader) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + ClassLoader cl = null; + try { + cl = Thread.currentThread().getContextClassLoader(); + } catch (SecurityException ex) { } + return cl; + } + }); + } + + static ClassLoader getSystemClassLoader() { + return (ClassLoader) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + ClassLoader cl = null; + try { + cl = ClassLoader.getSystemClassLoader(); + } catch (SecurityException ex) {} + return cl; + } + }); + } + + static ClassLoader getParentClassLoader(final ClassLoader cl) { + return (ClassLoader) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + ClassLoader parent = null; + try { + parent = cl.getParent(); + } catch (SecurityException ex) {} + + // eliminate loops in case of the boot + // ClassLoader returning itself as a parent + return (parent == cl) ? null : parent; + } + }); + } + + public static String getSystemProperty(final String propName) { + return (String) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + return System.getProperty(propName); + } + }); + } + + static 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(); + } + } + /** + * Return resource using the same classloader for the ObjectFactory by default + * or bootclassloader when Security Manager is in place + */ + public static InputStream getResourceAsStream(final String name) { + if (System.getSecurityManager()!=null) { + return getResourceAsStream(null, name); + } else { + return getResourceAsStream(ObjectFactory.findClassLoader(), name); + } + } + + public static InputStream getResourceAsStream(final ClassLoader cl, + final String name) + { + return (InputStream) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + InputStream ris; + if (cl == null) { + ris = Object.class.getResourceAsStream("/"+name); + } else { + ris = cl.getResourceAsStream(name); + } + return ris; + } + }); + } + + static boolean getFileExists(final File f) { + return ((Boolean) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + return f.exists() ? Boolean.TRUE : Boolean.FALSE; + } + })).booleanValue(); + } + + static long getLastModified(final File f) { + return ((Long) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + return new Long(f.lastModified()); + } + })).longValue(); + } + + private SecuritySupport () {} +} diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xerces/internal/xinclude/XIncludeHandler.java --- a/src/com/sun/org/apache/xerces/internal/xinclude/XIncludeHandler.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xerces/internal/xinclude/XIncludeHandler.java Tue Apr 17 11:17:59 2012 -0700 @@ -66,6 +66,7 @@ import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration; import com.sun.org.apache.xerces.internal.xpointer.XPointerHandler; import com.sun.org.apache.xerces.internal.xpointer.XPointerProcessor; +import com.sun.org.apache.xerces.internal.utils.ObjectFactory; /** *

@@ -111,6 +112,7 @@ * @author Peter McCracken, IBM * @author Michael Glavassevich, IBM * + * @version $Id: XIncludeHandler.java,v 1.7 2010-11-01 04:40:18 joehw Exp $ * * @see XIncludeNamespaceSupport */ @@ -943,7 +945,8 @@ setState(STATE_IGNORE); } else { - reportFatalError("NoFallback"); + reportFatalError("NoFallback", + new Object[] { attributes.getValue(null, "href") }); } } else if (isFallbackElement(element)) { @@ -1001,7 +1004,8 @@ // we check to see if the children of this include element contained a fallback if (getState() == STATE_EXPECT_FALLBACK && !getSawFallback(fDepth + 1)) { - reportFatalError("NoFallback"); + reportFatalError("NoFallback", + new Object[] { "unknown" }); } } if (isFallbackElement(element)) { @@ -1567,7 +1571,6 @@ fChildConfig = (XMLParserConfiguration)ObjectFactory.newInstance( parserName, - ObjectFactory.findClassLoader(), true); // use the same symbol table, error reporter, entity resolver, security manager and buffer size. diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xml/internal/dtm/DTMManager.java --- a/src/com/sun/org/apache/xml/internal/dtm/DTMManager.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xml/internal/dtm/DTMManager.java Tue Apr 17 11:17:59 2012 -0700 @@ -26,6 +26,7 @@ import com.sun.org.apache.xml.internal.res.XMLMessages; import com.sun.org.apache.xml.internal.utils.PrefixResolver; import com.sun.org.apache.xml.internal.utils.XMLStringFactory; +import com.sun.org.apache.xalan.internal.utils.ObjectFactory; /** * A DTMManager instance can be used to create DTM and @@ -64,6 +65,7 @@ */ protected XMLStringFactory m_xsf = null; + private boolean _useServicesMechanism; /** * Default constructor is protected on purpose. */ @@ -133,13 +135,23 @@ public static DTMManager newInstance(XMLStringFactory xsf) throws DTMConfigurationException { + return newInstance(xsf, true); + } + + public static DTMManager newInstance(XMLStringFactory xsf, boolean useServicesMechanism) + throws DTMConfigurationException + { DTMManager factoryImpl = null; try { - factoryImpl = (DTMManager) ObjectFactory - .createObject(defaultPropName, defaultClassName); + if (useServicesMechanism) { + factoryImpl = (DTMManager) ObjectFactory + .createObject(defaultPropName, defaultClassName); + } else { + factoryImpl = new com.sun.org.apache.xml.internal.dtm.ref.DTMManagerDefault(); + } } - catch (ObjectFactory.ConfigurationError e) + catch (ConfigurationError e) { throw new DTMConfigurationException(XMLMessages.createXMLMessage( XMLErrorResources.ER_NO_DEFAULT_IMPL, null), e.getException()); @@ -346,6 +358,19 @@ m_source_location = sourceLocation; } + /** + * Return the state of the services mechanism feature. + */ + public boolean useServicesMechnism() { + return _useServicesMechanism; + } + + /** + * Set the state of the services mechanism feature. + */ + public void setServicesMechnism(boolean flag) { + _useServicesMechanism = flag; + } // -------------------- private methods -------------------- @@ -429,4 +454,46 @@ return IDENT_NODE_DEFAULT; } + // + // Classes + // + + /** + * A configuration error. + * Originally in ObjectFactory. This is the only portion used in this package + */ + static class ConfigurationError + extends Error { + static final long serialVersionUID = 5122054096615067992L; + // + // Data + // + + /** Exception. */ + private Exception exception; + + // + // Constructors + // + + /** + * Construct a new instance with the specified detail string and + * exception. + */ + ConfigurationError(String msg, Exception x) { + super(msg); + this.exception = x; + } // (String,Exception) + + // + // Public methods + // + + /** Returns the exception associated to this error. */ + Exception getException() { + return exception; + } // getException():Exception + + } // class ConfigurationError + } diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xml/internal/dtm/ObjectFactory.java --- a/src/com/sun/org/apache/xml/internal/dtm/ObjectFactory.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,663 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2001-2004 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. - */ -/* - * $Id: ObjectFactory.java,v 1.2.4.1 2005/09/15 08:14:55 suresh_emailid Exp $ - */ - -package com.sun.org.apache.xml.internal.dtm; - -import java.io.InputStream; -import java.io.IOException; -import java.io.File; -import java.io.FileInputStream; - -import java.util.Properties; -import java.io.BufferedReader; -import java.io.InputStreamReader; - -/** - * 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. - *

- * This code is designed to implement the JAXP 1.1 spec pluggability - * feature and is designed to run on JDK version 1.1 and - * later, and to compile on JDK 1.2 and onward. - * The code also runs both as part of an unbundled jar file and - * when bundled as part of the JDK. - *

- * This class was moved from the javax.xml.parsers.ObjectFactory - * class and modified to be used as a general utility for creating objects - * dynamically. - * - * @version $Id: ObjectFactory.java,v 1.7 2008/04/02 00:41:00 joehw Exp $ - */ -class ObjectFactory { - - // - // Constants - // - - // name of default properties file to look for in JDK's jre/lib directory - private static final String DEFAULT_PROPERTIES_FILENAME = - "xalan.properties"; - - private static final String SERVICES_PATH = "META-INF/services/"; - - /** Set to true for debugging */ - private static final boolean DEBUG = false; - - /** cache the contents of the xalan.properties file. - * Until an attempt has been made to read this file, this will - * be null; if the file does not exist or we encounter some other error - * during the read, this will be empty. - */ - private static Properties fXalanProperties = null; - - /*** - * Cache the time stamp of the xalan.properties file so - * that we know if it's been modified and can invalidate - * the cache when necessary. - */ - private static long fLastModified = -1; - - // - // Public static methods - // - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *

    - *
  1. query the system property using System.getProperty - *
  2. read META-INF/services/factoryId file - *
  3. use fallback classname - *
- * - * @return instance of factory, 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 no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Object createObject(String factoryId, String fallbackClassName) - throws ConfigurationError { - return createObject(factoryId, null, fallbackClassName); - } // createObject(String,String):Object - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return instance of factory, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Object createObject(String factoryId, - String propertiesFilename, - String fallbackClassName) - throws ConfigurationError - { - Class factoryClass = lookUpFactoryClass(factoryId, - propertiesFilename, - fallbackClassName); - - if (factoryClass == null) { - throw new ConfigurationError( - "Provider for " + factoryId + " cannot be found", null); - } - - try{ - Object instance = factoryClass.newInstance(); - if (DEBUG) debugPrintln("created new instance of factory " + factoryId); - return instance; - } catch (Exception x) { - throw new ConfigurationError( - "Provider for factory " + factoryId - + " could not be instantiated: " + x, x); - } - } // createObject(String,String,String):Object - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return Class object of factory, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Class lookUpFactoryClass(String factoryId) - throws ConfigurationError - { - return lookUpFactoryClass(factoryId, null, null); - } // lookUpFactoryClass(String):Class - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return Class object that provides factory service, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Class lookUpFactoryClass(String factoryId, - String propertiesFilename, - String fallbackClassName) - throws ConfigurationError - { - String factoryClassName = lookUpFactoryClassName(factoryId, - propertiesFilename, - fallbackClassName); - ClassLoader cl = findClassLoader(); - - if (factoryClassName == null) { - factoryClassName = fallbackClassName; - } - - // assert(className != null); - try{ - Class providerClass = findProviderClass(factoryClassName, - cl, - true); - if (DEBUG) debugPrintln("created new instance of " + providerClass + - " using ClassLoader: " + cl); - return providerClass; - } catch (ClassNotFoundException x) { - throw new ConfigurationError( - "Provider " + factoryClassName + " not found", x); - } catch (Exception x) { - throw new ConfigurationError( - "Provider "+factoryClassName+" could not be instantiated: "+x, - x); - } - } // lookUpFactoryClass(String,String,String):Class - - /** - * Finds the name of the required implementation class in the specified - * order. The specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return name of class that provides factory service, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static String lookUpFactoryClassName(String factoryId, - String propertiesFilename, - String fallbackClassName) - { - SecuritySupport ss = SecuritySupport.getInstance(); - - // Use the system property first - try { - String systemProp = ss.getSystemProperty(factoryId); - if (systemProp != null) { - if (DEBUG) debugPrintln("found system property, value=" + systemProp); - return systemProp; - } - } catch (SecurityException se) { - // Ignore and continue w/ next location - } - - // Try to read from propertiesFilename, or - // $java.home/lib/xalan.properties - String factoryClassName = null; - // no properties file name specified; use - // $JAVA_HOME/lib/xalan.properties: - if (propertiesFilename == null) { - File propertiesFile = null; - boolean propertiesFileExists = false; - try { - String javah = ss.getSystemProperty("java.home"); - propertiesFilename = javah + File.separator + - "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME; - propertiesFile = new File(propertiesFilename); - propertiesFileExists = ss.getFileExists(propertiesFile); - } catch (SecurityException e) { - // try again... - fLastModified = -1; - fXalanProperties = null; - } - - synchronized (ObjectFactory.class) { - boolean loadProperties = false; - FileInputStream fis = null; - try { - // file existed last time - if(fLastModified >= 0) { - if(propertiesFileExists && - (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) { - loadProperties = true; - } else { - // file has stopped existing... - if(!propertiesFileExists) { - fLastModified = -1; - fXalanProperties = null; - } // else, file wasn't modified! - } - } else { - // file has started to exist: - if(propertiesFileExists) { - loadProperties = true; - fLastModified = ss.getLastModified(propertiesFile); - } // else, nothing's changed - } - if(loadProperties) { - // must never have attempted to read xalan.properties - // before (or it's outdeated) - fXalanProperties = new Properties(); - fis = ss.getFileInputStream(propertiesFile); - fXalanProperties.load(fis); - } - } catch (Exception x) { - fXalanProperties = null; - fLastModified = -1; - // assert(x instanceof FileNotFoundException - // || x instanceof SecurityException) - // In both cases, ignore and continue w/ next location - } - finally { - // try to close the input stream if one was opened. - if (fis != null) { - try { - fis.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - } - } - if(fXalanProperties != null) { - factoryClassName = fXalanProperties.getProperty(factoryId); - } - } else { - FileInputStream fis = null; - try { - fis = ss.getFileInputStream(new File(propertiesFilename)); - Properties props = new Properties(); - props.load(fis); - factoryClassName = props.getProperty(factoryId); - } catch (Exception x) { - // assert(x instanceof FileNotFoundException - // || x instanceof SecurityException) - // In both cases, ignore and continue w/ next location - } - finally { - // try to close the input stream if one was opened. - if (fis != null) { - try { - fis.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - } - } - if (factoryClassName != null) { - if (DEBUG) debugPrintln("found in " + propertiesFilename + ", value=" - + factoryClassName); - return factoryClassName; - } - - // Try Jar Service Provider Mechanism - return findJarServiceProviderName(factoryId); - } // lookUpFactoryClass(String,String):String - - // - // Private static methods - // - - /** Prints a message to standard error if debugging is enabled. */ - private static void debugPrintln(String msg) { - if (DEBUG) { - System.err.println("JAXP: " + msg); - } - } // debugPrintln(String) - - /** - * Figure out which ClassLoader to use. For JDK 1.2 and later use - * the context ClassLoader. - */ - static ClassLoader findClassLoader() - 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 context = ss.getContextClassLoader(); - ClassLoader system = ss.getSystemClassLoader(); - - ClassLoader chain = system; - while (true) { - if (context == chain) { - // Assert: we are on JDK 1.1 or we have no Context ClassLoader - // or any Context ClassLoader in chain of system classloader - // (including extension ClassLoader) so extend to widest - // ClassLoader (always look in system ClassLoader if Xalan - // is in boot/extension/system classpath and in current - // ClassLoader otherwise); normal classloaders delegate - // back to system ClassLoader first so this widening doesn't - // change the fact that context ClassLoader will be consulted - ClassLoader current = ObjectFactory.class.getClassLoader(); - - chain = system; - while (true) { - if (current == chain) { - // Assert: Current ClassLoader in chain of - // boot/extension/system ClassLoaders - return system; - } - if (chain == null) { - break; - } - chain = ss.getParentClassLoader(chain); - } - - // Assert: Current ClassLoader not in chain of - // boot/extension/system ClassLoaders - return current; - } - - if (chain == null) { - // boot ClassLoader reached - break; - } - - // Check for any extension ClassLoaders in chain up to - // boot ClassLoader - chain = ss.getParentClassLoader(chain); - }; - - // Assert: Context ClassLoader not in chain of - // boot/extension/system ClassLoaders - return context; - } // findClassLoader():ClassLoader - - /** - * Create an instance of a class using the specified ClassLoader - */ - static Object newInstance(String className, ClassLoader cl, - boolean doFallback) - throws ConfigurationError - { - // assert(className != null); - try{ - Class providerClass = findProviderClass(className, cl, doFallback); - Object instance = providerClass.newInstance(); - if (DEBUG) debugPrintln("created new instance of " + providerClass + - " using ClassLoader: " + cl); - return instance; - } catch (ClassNotFoundException x) { - throw new ConfigurationError( - "Provider " + className + " not found", x); - } catch (Exception x) { - throw new ConfigurationError( - "Provider " + className + " could not be instantiated: " + x, - x); - } - } - - /** - * Find a Class using the specified ClassLoader - */ - static Class findProviderClass(String className, ClassLoader cl, - boolean doFallback) - throws ClassNotFoundException, ConfigurationError - { - //throw security exception if the calling thread is not allowed to access the - //class. Restrict the access to the package classes as specified in java.security policy. - SecurityManager security = System.getSecurityManager(); - try{ - if (security != null){ - final int lastDot = className.lastIndexOf("."); - String packageName = className; - if (lastDot != -1) packageName = className.substring(0, lastDot); - security.checkPackageAccess(packageName); - } - }catch(SecurityException e){ - throw e; - } - - Class providerClass; - 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 { - try { - providerClass = cl.loadClass(className); - } catch (ClassNotFoundException x) { - if (doFallback) { - // Fall back to current classloader - ClassLoader current = ObjectFactory.class.getClassLoader(); - if (current == null) { - providerClass = Class.forName(className); - } else if (cl != current) { - cl = current; - providerClass = cl.loadClass(className); - } else { - throw x; - } - } else { - throw x; - } - } - } - - return providerClass; - } - - /** - * Find the name of service provider using Jar Service Provider Mechanism - * - * @return instance of provider class if found or null - */ - private static String findJarServiceProviderName(String factoryId) - { - SecuritySupport ss = SecuritySupport.getInstance(); - String serviceId = SERVICES_PATH + factoryId; - InputStream is = null; - - // First try the Context ClassLoader - ClassLoader cl = findClassLoader(); - - is = ss.getResourceAsStream(cl, serviceId); - - // If no provider found then try the current ClassLoader - if (is == null) { - ClassLoader current = ObjectFactory.class.getClassLoader(); - if (cl != current) { - cl = current; - is = ss.getResourceAsStream(cl, serviceId); - } - } - - if (is == null) { - // No provider found - return null; - } - - if (DEBUG) debugPrintln("found jar resource=" + serviceId + - " using ClassLoader: " + cl); - - // 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)); - } - - String factoryClassName = null; - try { - // XXX Does not handle all possible input as specified by the - // Jar Service Provider specification - factoryClassName = rd.readLine(); - } catch (IOException x) { - // No provider found - return null; - } - finally { - try { - // try to close the reader. - rd.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - - if (factoryClassName != null && - ! "".equals(factoryClassName)) { - if (DEBUG) debugPrintln("found in resource, value=" - + factoryClassName); - - // Note: here we do not want to fall back to the current - // 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. - return factoryClassName; - } - - // No provider found - return null; - } - - // - // Classes - // - - /** - * A configuration error. - */ - static class ConfigurationError - extends Error { - static final long serialVersionUID = 5122054096615067992L; - // - // Data - // - - /** Exception. */ - private Exception exception; - - // - // Constructors - // - - /** - * Construct a new instance with the specified detail string and - * exception. - */ - ConfigurationError(String msg, Exception x) { - super(msg); - this.exception = x; - } // (String,Exception) - - // - // Public methods - // - - /** Returns the exception associated to this error. */ - Exception getException() { - return exception; - } // getException():Exception - - } // class ConfigurationError - -} // class ObjectFactory diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xml/internal/dtm/SecuritySupport.java --- a/src/com/sun/org/apache/xml/internal/dtm/SecuritySupport.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,127 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2002-2004 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. - */ -/* - * $Id: SecuritySupport.java,v 1.2.4.1 2005/09/15 08:14:55 suresh_emailid Exp $ - */ - -package com.sun.org.apache.xml.internal.dtm; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.InputStream; - -import java.util.Properties; - -/** - * This class is duplicated for each Xalan-Java subpackage so keep it in sync. - * It is package private and therefore is not exposed as part of the Xalan-Java - * 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. - */ - static SecuritySupport getInstance() { - return (SecuritySupport)securitySupport; - } - - ClassLoader getContextClassLoader() { - return null; - } - - ClassLoader getSystemClassLoader() { - return null; - } - - ClassLoader getParentClassLoader(ClassLoader cl) { - return null; - } - - String getSystemProperty(String propName) { - return System.getProperty(propName); - } - - FileInputStream getFileInputStream(File file) - throws FileNotFoundException - { - return new FileInputStream(file); - } - - InputStream getResourceAsStream(ClassLoader cl, String name) { - InputStream ris; - if (cl == null) { - ris = ClassLoader.getSystemResourceAsStream(name); - } else { - ris = cl.getResourceAsStream(name); - } - return ris; - } - - boolean getFileExists(File f) { - return f.exists(); - } - - long getLastModified(File f) { - return f.lastModified(); - } -} diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xml/internal/dtm/SecuritySupport12.java --- a/src/com/sun/org/apache/xml/internal/dtm/SecuritySupport12.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,148 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2002-2004 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. - */ -/* - * $Id: SecuritySupport12.java,v 1.2.4.1 2005/09/15 08:14:56 suresh_emailid Exp $ - */ - -package com.sun.org.apache.xml.internal.dtm; - -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; - -import java.util.Properties; - -/** - * This class is duplicated for each Xalan-Java subpackage so keep it in sync. - * It is package private and therefore is not exposed as part of the Xalan-Java - * API. - * - * Security related methods that only work on J2SE 1.2 and newer. - */ -class SecuritySupport12 extends SecuritySupport { - - ClassLoader getContextClassLoader() { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader cl = null; - try { - cl = Thread.currentThread().getContextClassLoader(); - } catch (SecurityException ex) { } - return cl; - } - }); - } - - ClassLoader getSystemClassLoader() { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader cl = null; - try { - cl = ClassLoader.getSystemClassLoader(); - } catch (SecurityException ex) {} - return cl; - } - }); - } - - ClassLoader getParentClassLoader(final ClassLoader cl) { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader parent = null; - try { - parent = cl.getParent(); - } catch (SecurityException ex) {} - - // eliminate loops in case of the boot - // ClassLoader returning itself as a parent - return (parent == cl) ? null : parent; - } - }); - } - - String getSystemProperty(final String propName) { - return (String) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return System.getProperty(propName); - } - }); - } - - 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(); - } - } - - 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; - } - }); - } - - boolean getFileExists(final File f) { - return ((Boolean) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return new Boolean(f.exists()); - } - })).booleanValue(); - } - - long getLastModified(final File f) { - return ((Long) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return new Long(f.lastModified()); - } - })).longValue(); - } - -} diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xml/internal/dtm/ref/DTMDefaultBase.java --- a/src/com/sun/org/apache/xml/internal/dtm/ref/DTMDefaultBase.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xml/internal/dtm/ref/DTMDefaultBase.java Tue Apr 17 11:17:59 2012 -0700 @@ -844,12 +844,10 @@ break; } - StringBuffer sb=new StringBuffer(); - sb.append("["+nodeHandle+": "+typestring+ - "(0x"+Integer.toHexString(getExpandedTypeID(nodeHandle))+") "+ - getNodeNameX(nodeHandle)+" {"+getNamespaceURI(nodeHandle)+"}"+ - "=\""+ getNodeValue(nodeHandle)+"\"]"); - return sb.toString(); + return "[" + nodeHandle + ": " + typestring + + "(0x" + Integer.toHexString(getExpandedTypeID(nodeHandle)) + ") " + + getNodeNameX(nodeHandle) + " {" + getNamespaceURI(nodeHandle) + "}" + + "=\"" + getNodeValue(nodeHandle) + "\"]"; } // ========= DTM Implementation Control Functions. ============== diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xml/internal/dtm/ref/DTMManagerDefault.java --- a/src/com/sun/org/apache/xml/internal/dtm/ref/DTMManagerDefault.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xml/internal/dtm/ref/DTMManagerDefault.java Tue Apr 17 11:17:59 2012 -0700 @@ -22,6 +22,7 @@ */ package com.sun.org.apache.xml.internal.dtm.ref; +import com.sun.org.apache.xalan.internal.utils.FactoryImpl; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.Source; @@ -606,7 +607,7 @@ // If user did not supply a reader, ask for one from the reader manager if (null == reader) { if (m_readerManager == null) { - m_readerManager = XMLReaderManager.getInstance(); + m_readerManager = XMLReaderManager.getInstance(super.useServicesMechnism()); } reader = m_readerManager.getXMLReader(); @@ -765,8 +766,7 @@ try { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - + DocumentBuilderFactory dbf = FactoryImpl.getDOMFactory(super.useServicesMechnism()); dbf.setNamespaceAware(true); DocumentBuilder db = dbf.newDocumentBuilder(); diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xml/internal/dtm/ref/IncrementalSAXSource_Xerces.java --- a/src/com/sun/org/apache/xml/internal/dtm/ref/IncrementalSAXSource_Xerces.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xml/internal/dtm/ref/IncrementalSAXSource_Xerces.java Tue Apr 17 11:17:59 2012 -0700 @@ -30,6 +30,7 @@ import com.sun.org.apache.xerces.internal.parsers.SAXParser; import com.sun.org.apache.xml.internal.res.XMLErrorResources; import com.sun.org.apache.xml.internal.res.XMLMessages; +import com.sun.org.apache.xalan.internal.utils.ObjectFactory; import org.xml.sax.InputSource; import org.xml.sax.SAXException; @@ -101,7 +102,7 @@ // If we can't get the magic constructor, no need to look further. Class xniConfigClass=ObjectFactory.findProviderClass( "com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration", - ObjectFactory.findClassLoader(), true); + true); Class[] args1={xniConfigClass}; Constructor ctor=SAXParser.class.getConstructor(args1); @@ -110,7 +111,7 @@ // we're going to want to use. Class xniStdConfigClass=ObjectFactory.findProviderClass( "com.sun.org.apache.xerces.internal.parsers.StandardParserConfiguration", - ObjectFactory.findClassLoader(), true); + true); fPullParserConfig=xniStdConfigClass.newInstance(); Object[] args2={fPullParserConfig}; fIncrementalParser = (SAXParser)ctor.newInstance(args2); @@ -120,7 +121,7 @@ // API changes again. Class fXniInputSourceClass=ObjectFactory.findProviderClass( "com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource", - ObjectFactory.findClassLoader(), true); + true); Class[] args3={fXniInputSourceClass}; fConfigSetInput=xniStdConfigClass.getMethod("setInputSource",args3); diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xml/internal/dtm/ref/ObjectFactory.java --- a/src/com/sun/org/apache/xml/internal/dtm/ref/ObjectFactory.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,663 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2001-2004 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. - */ -/* - * $Id: ObjectFactory.java,v 1.2.4.1 2005/09/15 08:15:08 suresh_emailid Exp $ - */ - -package com.sun.org.apache.xml.internal.dtm.ref; - -import java.io.InputStream; -import java.io.IOException; -import java.io.File; -import java.io.FileInputStream; - -import java.util.Properties; -import java.io.BufferedReader; -import java.io.InputStreamReader; - -/** - * 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. - *

- * This code is designed to implement the JAXP 1.1 spec pluggability - * feature and is designed to run on JDK version 1.1 and - * later, and to compile on JDK 1.2 and onward. - * The code also runs both as part of an unbundled jar file and - * when bundled as part of the JDK. - *

- * This class was moved from the javax.xml.parsers.ObjectFactory - * class and modified to be used as a general utility for creating objects - * dynamically. - * - * @version $Id: ObjectFactory.java,v 1.7 2008/04/02 00:41:01 joehw Exp $ - */ -class ObjectFactory { - - // - // Constants - // - - // name of default properties file to look for in JDK's jre/lib directory - private static final String DEFAULT_PROPERTIES_FILENAME = - "xalan.properties"; - - private static final String SERVICES_PATH = "META-INF/services/"; - - /** Set to true for debugging */ - private static final boolean DEBUG = false; - - /** cache the contents of the xalan.properties file. - * Until an attempt has been made to read this file, this will - * be null; if the file does not exist or we encounter some other error - * during the read, this will be empty. - */ - private static Properties fXalanProperties = null; - - /*** - * Cache the time stamp of the xalan.properties file so - * that we know if it's been modified and can invalidate - * the cache when necessary. - */ - private static long fLastModified = -1; - - // - // Public static methods - // - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *

    - *
  1. query the system property using System.getProperty - *
  2. read META-INF/services/factoryId file - *
  3. use fallback classname - *
- * - * @return instance of factory, 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 no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Object createObject(String factoryId, String fallbackClassName) - throws ConfigurationError { - return createObject(factoryId, null, fallbackClassName); - } // createObject(String,String):Object - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return instance of factory, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Object createObject(String factoryId, - String propertiesFilename, - String fallbackClassName) - throws ConfigurationError - { - Class factoryClass = lookUpFactoryClass(factoryId, - propertiesFilename, - fallbackClassName); - - if (factoryClass == null) { - throw new ConfigurationError( - "Provider for " + factoryId + " cannot be found", null); - } - - try{ - Object instance = factoryClass.newInstance(); - if (DEBUG) debugPrintln("created new instance of factory " + factoryId); - return instance; - } catch (Exception x) { - throw new ConfigurationError( - "Provider for factory " + factoryId - + " could not be instantiated: " + x, x); - } - } // createObject(String,String,String):Object - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return Class object of factory, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Class lookUpFactoryClass(String factoryId) - throws ConfigurationError - { - return lookUpFactoryClass(factoryId, null, null); - } // lookUpFactoryClass(String):Class - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return Class object that provides factory service, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Class lookUpFactoryClass(String factoryId, - String propertiesFilename, - String fallbackClassName) - throws ConfigurationError - { - String factoryClassName = lookUpFactoryClassName(factoryId, - propertiesFilename, - fallbackClassName); - ClassLoader cl = findClassLoader(); - - if (factoryClassName == null) { - factoryClassName = fallbackClassName; - } - - // assert(className != null); - try{ - Class providerClass = findProviderClass(factoryClassName, - cl, - true); - if (DEBUG) debugPrintln("created new instance of " + providerClass + - " using ClassLoader: " + cl); - return providerClass; - } catch (ClassNotFoundException x) { - throw new ConfigurationError( - "Provider " + factoryClassName + " not found", x); - } catch (Exception x) { - throw new ConfigurationError( - "Provider "+factoryClassName+" could not be instantiated: "+x, - x); - } - } // lookUpFactoryClass(String,String,String):Class - - /** - * Finds the name of the required implementation class in the specified - * order. The specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return name of class that provides factory service, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static String lookUpFactoryClassName(String factoryId, - String propertiesFilename, - String fallbackClassName) - { - SecuritySupport ss = SecuritySupport.getInstance(); - - // Use the system property first - try { - String systemProp = ss.getSystemProperty(factoryId); - if (systemProp != null) { - if (DEBUG) debugPrintln("found system property, value=" + systemProp); - return systemProp; - } - } catch (SecurityException se) { - // Ignore and continue w/ next location - } - - // Try to read from propertiesFilename, or - // $java.home/lib/xalan.properties - String factoryClassName = null; - // no properties file name specified; use - // $JAVA_HOME/lib/xalan.properties: - if (propertiesFilename == null) { - File propertiesFile = null; - boolean propertiesFileExists = false; - try { - String javah = ss.getSystemProperty("java.home"); - propertiesFilename = javah + File.separator + - "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME; - propertiesFile = new File(propertiesFilename); - propertiesFileExists = ss.getFileExists(propertiesFile); - } catch (SecurityException e) { - // try again... - fLastModified = -1; - fXalanProperties = null; - } - - synchronized (ObjectFactory.class) { - boolean loadProperties = false; - FileInputStream fis = null; - try { - // file existed last time - if(fLastModified >= 0) { - if(propertiesFileExists && - (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) { - loadProperties = true; - } else { - // file has stopped existing... - if(!propertiesFileExists) { - fLastModified = -1; - fXalanProperties = null; - } // else, file wasn't modified! - } - } else { - // file has started to exist: - if(propertiesFileExists) { - loadProperties = true; - fLastModified = ss.getLastModified(propertiesFile); - } // else, nothing's changed - } - if(loadProperties) { - // must never have attempted to read xalan.properties - // before (or it's outdeated) - fXalanProperties = new Properties(); - fis = ss.getFileInputStream(propertiesFile); - fXalanProperties.load(fis); - } - } catch (Exception x) { - fXalanProperties = null; - fLastModified = -1; - // assert(x instanceof FileNotFoundException - // || x instanceof SecurityException) - // In both cases, ignore and continue w/ next location - } - finally { - // try to close the input stream if one was opened. - if (fis != null) { - try { - fis.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - } - } - if(fXalanProperties != null) { - factoryClassName = fXalanProperties.getProperty(factoryId); - } - } else { - FileInputStream fis = null; - try { - fis = ss.getFileInputStream(new File(propertiesFilename)); - Properties props = new Properties(); - props.load(fis); - factoryClassName = props.getProperty(factoryId); - } catch (Exception x) { - // assert(x instanceof FileNotFoundException - // || x instanceof SecurityException) - // In both cases, ignore and continue w/ next location - } - finally { - // try to close the input stream if one was opened. - if (fis != null) { - try { - fis.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - } - } - if (factoryClassName != null) { - if (DEBUG) debugPrintln("found in " + propertiesFilename + ", value=" - + factoryClassName); - return factoryClassName; - } - - // Try Jar Service Provider Mechanism - return findJarServiceProviderName(factoryId); - } // lookUpFactoryClass(String,String):String - - // - // Private static methods - // - - /** Prints a message to standard error if debugging is enabled. */ - private static void debugPrintln(String msg) { - if (DEBUG) { - System.err.println("JAXP: " + msg); - } - } // debugPrintln(String) - - /** - * Figure out which ClassLoader to use. For JDK 1.2 and later use - * the context ClassLoader. - */ - static ClassLoader findClassLoader() - 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 context = ss.getContextClassLoader(); - ClassLoader system = ss.getSystemClassLoader(); - - ClassLoader chain = system; - while (true) { - if (context == chain) { - // Assert: we are on JDK 1.1 or we have no Context ClassLoader - // or any Context ClassLoader in chain of system classloader - // (including extension ClassLoader) so extend to widest - // ClassLoader (always look in system ClassLoader if Xalan - // is in boot/extension/system classpath and in current - // ClassLoader otherwise); normal classloaders delegate - // back to system ClassLoader first so this widening doesn't - // change the fact that context ClassLoader will be consulted - ClassLoader current = ObjectFactory.class.getClassLoader(); - - chain = system; - while (true) { - if (current == chain) { - // Assert: Current ClassLoader in chain of - // boot/extension/system ClassLoaders - return system; - } - if (chain == null) { - break; - } - chain = ss.getParentClassLoader(chain); - } - - // Assert: Current ClassLoader not in chain of - // boot/extension/system ClassLoaders - return current; - } - - if (chain == null) { - // boot ClassLoader reached - break; - } - - // Check for any extension ClassLoaders in chain up to - // boot ClassLoader - chain = ss.getParentClassLoader(chain); - }; - - // Assert: Context ClassLoader not in chain of - // boot/extension/system ClassLoaders - return context; - } // findClassLoader():ClassLoader - - /** - * Create an instance of a class using the specified ClassLoader - */ - static Object newInstance(String className, ClassLoader cl, - boolean doFallback) - throws ConfigurationError - { - // assert(className != null); - try{ - Class providerClass = findProviderClass(className, cl, doFallback); - Object instance = providerClass.newInstance(); - if (DEBUG) debugPrintln("created new instance of " + providerClass + - " using ClassLoader: " + cl); - return instance; - } catch (ClassNotFoundException x) { - throw new ConfigurationError( - "Provider " + className + " not found", x); - } catch (Exception x) { - throw new ConfigurationError( - "Provider " + className + " could not be instantiated: " + x, - x); - } - } - - /** - * Find a Class using the specified ClassLoader - */ - static Class findProviderClass(String className, ClassLoader cl, - boolean doFallback) - throws ClassNotFoundException, ConfigurationError - { - //throw security exception if the calling thread is not allowed to access the - //class. Restrict the access to the package classes as specified in java.security policy. - SecurityManager security = System.getSecurityManager(); - try{ - if (security != null){ - final int lastDot = className.lastIndexOf("."); - String packageName = className; - if (lastDot != -1) packageName = className.substring(0, lastDot); - security.checkPackageAccess(packageName); - } - }catch(SecurityException e){ - throw e; - } - - Class providerClass; - 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 { - try { - providerClass = cl.loadClass(className); - } catch (ClassNotFoundException x) { - if (doFallback) { - // Fall back to current classloader - ClassLoader current = ObjectFactory.class.getClassLoader(); - if (current == null) { - providerClass = Class.forName(className); - } else if (cl != current) { - cl = current; - providerClass = cl.loadClass(className); - } else { - throw x; - } - } else { - throw x; - } - } - } - - return providerClass; - } - - /** - * Find the name of service provider using Jar Service Provider Mechanism - * - * @return instance of provider class if found or null - */ - private static String findJarServiceProviderName(String factoryId) - { - SecuritySupport ss = SecuritySupport.getInstance(); - String serviceId = SERVICES_PATH + factoryId; - InputStream is = null; - - // First try the Context ClassLoader - ClassLoader cl = findClassLoader(); - - is = ss.getResourceAsStream(cl, serviceId); - - // If no provider found then try the current ClassLoader - if (is == null) { - ClassLoader current = ObjectFactory.class.getClassLoader(); - if (cl != current) { - cl = current; - is = ss.getResourceAsStream(cl, serviceId); - } - } - - if (is == null) { - // No provider found - return null; - } - - if (DEBUG) debugPrintln("found jar resource=" + serviceId + - " using ClassLoader: " + cl); - - // 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)); - } - - String factoryClassName = null; - try { - // XXX Does not handle all possible input as specified by the - // Jar Service Provider specification - factoryClassName = rd.readLine(); - } catch (IOException x) { - // No provider found - return null; - } - finally { - try { - // try to close the reader. - rd.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - - if (factoryClassName != null && - ! "".equals(factoryClassName)) { - if (DEBUG) debugPrintln("found in resource, value=" - + factoryClassName); - - // Note: here we do not want to fall back to the current - // 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. - return factoryClassName; - } - - // No provider found - return null; - } - - // - // Classes - // - - /** - * A configuration error. - */ - static class ConfigurationError - extends Error { - static final long serialVersionUID = 7772782876036961354L; - // - // Data - // - - /** Exception. */ - private Exception exception; - - // - // Constructors - // - - /** - * Construct a new instance with the specified detail string and - * exception. - */ - ConfigurationError(String msg, Exception x) { - super(msg); - this.exception = x; - } // (String,Exception) - - // - // Public methods - // - - /** Returns the exception associated to this error. */ - Exception getException() { - return exception; - } // getException():Exception - - } // class ConfigurationError - -} // class ObjectFactory diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xml/internal/dtm/ref/SecuritySupport.java --- a/src/com/sun/org/apache/xml/internal/dtm/ref/SecuritySupport.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,127 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2002-2004 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. - */ -/* - * $Id: SecuritySupport.java,v 1.2.4.1 2005/09/15 08:15:09 suresh_emailid Exp $ - */ - -package com.sun.org.apache.xml.internal.dtm.ref; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.InputStream; - -import java.util.Properties; - -/** - * This class is duplicated for each Xalan-Java subpackage so keep it in sync. - * It is package private and therefore is not exposed as part of the Xalan-Java - * 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. - */ - static SecuritySupport getInstance() { - return (SecuritySupport)securitySupport; - } - - ClassLoader getContextClassLoader() { - return null; - } - - ClassLoader getSystemClassLoader() { - return null; - } - - ClassLoader getParentClassLoader(ClassLoader cl) { - return null; - } - - String getSystemProperty(String propName) { - return System.getProperty(propName); - } - - FileInputStream getFileInputStream(File file) - throws FileNotFoundException - { - return new FileInputStream(file); - } - - InputStream getResourceAsStream(ClassLoader cl, String name) { - InputStream ris; - if (cl == null) { - ris = ClassLoader.getSystemResourceAsStream(name); - } else { - ris = cl.getResourceAsStream(name); - } - return ris; - } - - boolean getFileExists(File f) { - return f.exists(); - } - - long getLastModified(File f) { - return f.lastModified(); - } -} diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xml/internal/dtm/ref/SecuritySupport12.java --- a/src/com/sun/org/apache/xml/internal/dtm/ref/SecuritySupport12.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,148 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2002-2004 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. - */ -/* - * $Id: SecuritySupport12.java,v 1.2.4.1 2005/09/15 08:15:09 suresh_emailid Exp $ - */ - -package com.sun.org.apache.xml.internal.dtm.ref; - -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; - -import java.util.Properties; - -/** - * This class is duplicated for each Xalan-Java subpackage so keep it in sync. - * It is package private and therefore is not exposed as part of the Xalan-Java - * API. - * - * Security related methods that only work on J2SE 1.2 and newer. - */ -class SecuritySupport12 extends SecuritySupport { - - ClassLoader getContextClassLoader() { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader cl = null; - try { - cl = Thread.currentThread().getContextClassLoader(); - } catch (SecurityException ex) { } - return cl; - } - }); - } - - ClassLoader getSystemClassLoader() { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader cl = null; - try { - cl = ClassLoader.getSystemClassLoader(); - } catch (SecurityException ex) {} - return cl; - } - }); - } - - ClassLoader getParentClassLoader(final ClassLoader cl) { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader parent = null; - try { - parent = cl.getParent(); - } catch (SecurityException ex) {} - - // eliminate loops in case of the boot - // ClassLoader returning itself as a parent - return (parent == cl) ? null : parent; - } - }); - } - - String getSystemProperty(final String propName) { - return (String) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return System.getProperty(propName); - } - }); - } - - 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(); - } - } - - 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; - } - }); - } - - boolean getFileExists(final File f) { - return ((Boolean) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return new Boolean(f.exists()); - } - })).booleanValue(); - } - - long getLastModified(final File f) { - return ((Long) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return new Long(f.lastModified()); - } - })).longValue(); - } - -} diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xml/internal/dtm/ref/dom2dtm/DOM2DTM.java --- a/src/com/sun/org/apache/xml/internal/dtm/ref/dom2dtm/DOM2DTM.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xml/internal/dtm/ref/dom2dtm/DOM2DTM.java Tue Apr 17 11:17:59 2012 -0700 @@ -1725,7 +1725,7 @@ try { Node node = getNode(nodeHandle); - treeWalker.traverse(node); + treeWalker.traverseFragment(node); } finally { diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xml/internal/resolver/Catalog.java --- a/src/com/sun/org/apache/xml/internal/resolver/Catalog.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xml/internal/resolver/Catalog.java Tue Apr 17 11:17:59 2012 -0700 @@ -23,6 +23,7 @@ package com.sun.org.apache.xml.internal.resolver; +import com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl; import java.io.IOException; import java.io.FileNotFoundException; import java.io.InputStream; @@ -399,7 +400,8 @@ * Setup readers. */ public void setupReaders() { - SAXParserFactory spf = SAXParserFactory.newInstance(); + SAXParserFactory spf = catalogManager.useServicesMechanism() ? + SAXParserFactory.newInstance() : new SAXParserFactoryImpl(); spf.setNamespaceAware(true); spf.setValidating(false); diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xml/internal/resolver/CatalogManager.java --- a/src/com/sun/org/apache/xml/internal/resolver/CatalogManager.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xml/internal/resolver/CatalogManager.java Tue Apr 17 11:17:59 2012 -0700 @@ -122,6 +122,7 @@ * @author Norman Walsh * Norman.Walsh@Sun.COM * + * @version 1.0 */ public class CatalogManager { @@ -197,6 +198,12 @@ /** Current catalog class name. */ private String catalogClassName = null; + /** + * Indicates whether implementation parts should use + * service loader (or similar). + * Note the default value (false) is the safe option.. + */ + private boolean useServicesMechanism; /** The manager's debug object. Used for printing debugging messages. * @@ -207,26 +214,26 @@ /** Constructor. */ public CatalogManager() { + init(); + } + + /** Constructor that specifies an explicit property file. */ + public CatalogManager(String propertyFile) { + this.propertyFile = propertyFile; + init(); + } + + private void init() { debug = new Debug(); // Note that we don't setDebug() here; we do that lazily. Either the // user will set it explicitly, or we'll do it automagically if they // read from the propertyFile for some other reason. That way, there's // no attempt to read from the file before the caller has had a chance // to avoid it. + if (System.getSecurityManager() == null) { + useServicesMechanism = true; + } } - - /** Constructor that specifies an explicit property file. */ - public CatalogManager(String propertyFile) { - this.propertyFile = propertyFile; - - debug = new Debug(); - // Note that we don't setDebug() here; we do that lazily. Either the - // user will set it explicitly, or we'll do it automagically if they - // read from the propertyFile for some other reason. That way, there's - // no attempt to read from the file before the caller has had a chance - // to avoid it. - } - /** Set the bootstrap resolver.*/ public void setBootstrapResolver(BootstrapResolver resolver) { bResolver = resolver; @@ -773,6 +780,9 @@ return oasisXMLCatalogPI.booleanValue(); } + public boolean useServicesMechanism() { + return useServicesMechanism; + } /** * Set the XML Catalog PI setting */ diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xml/internal/resolver/Resolver.java --- a/src/com/sun/org/apache/xml/internal/resolver/Resolver.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xml/internal/resolver/Resolver.java Tue Apr 17 11:17:59 2012 -0700 @@ -31,10 +31,11 @@ import java.net.URL; import java.net.URLConnection; import java.net.MalformedURLException; +import javax.xml.parsers.SAXParserFactory; +import com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl; import com.sun.org.apache.xml.internal.resolver.readers.SAXCatalogReader; import com.sun.org.apache.xml.internal.resolver.readers.OASISXMLCatalogReader; import com.sun.org.apache.xml.internal.resolver.readers.TR9401CatalogReader; -import javax.xml.parsers.SAXParserFactory; /** * An extension to OASIS Open Catalog files, this class supports @@ -45,6 +46,7 @@ * @author Norman Walsh * Norman.Walsh@Sun.COM * + * @version 1.0 */ public class Resolver extends Catalog { /** @@ -84,7 +86,8 @@ * Setup readers. */ public void setupReaders() { - SAXParserFactory spf = SAXParserFactory.newInstance(); + SAXParserFactory spf = catalogManager.useServicesMechanism() ? + SAXParserFactory.newInstance() : new SAXParserFactoryImpl(); spf.setNamespaceAware(true); spf.setValidating(false); diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xml/internal/resolver/tools/CatalogResolver.java --- a/src/com/sun/org/apache/xml/internal/resolver/tools/CatalogResolver.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xml/internal/resolver/tools/CatalogResolver.java Tue Apr 17 11:17:59 2012 -0700 @@ -23,6 +23,7 @@ package com.sun.org.apache.xml.internal.resolver.tools; +import com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl; import java.io.IOException; import java.io.InputStream; import java.net.URL; @@ -61,6 +62,7 @@ * @author Norman Walsh * Norman.Walsh@Sun.COM * + * @version 1.0 */ public class CatalogResolver implements EntityResolver, URIResolver { /** Make the parser Namespace aware? */ @@ -302,7 +304,8 @@ private void setEntityResolver(SAXSource source) throws TransformerException { XMLReader reader = source.getXMLReader(); if (reader == null) { - SAXParserFactory spFactory = SAXParserFactory.newInstance(); + SAXParserFactory spFactory = catalogManager.useServicesMechanism() ? + SAXParserFactory.newInstance() : new SAXParserFactoryImpl(); spFactory.setNamespaceAware(true); try { reader = spFactory.newSAXParser().getXMLReader(); diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xml/internal/resolver/tools/ResolvingParser.java --- a/src/com/sun/org/apache/xml/internal/resolver/tools/ResolvingParser.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xml/internal/resolver/tools/ResolvingParser.java Tue Apr 17 11:17:59 2012 -0700 @@ -42,6 +42,7 @@ import javax.xml.parsers.SAXParserFactory; import javax.xml.parsers.SAXParser; +import com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl; import com.sun.org.apache.xml.internal.resolver.Catalog; import com.sun.org.apache.xml.internal.resolver.CatalogManager; import com.sun.org.apache.xml.internal.resolver.helpers.FileURL; @@ -62,6 +63,7 @@ * @author Norman Walsh * Norman.Walsh@Sun.COM * + * @version 1.0 */ public class ResolvingParser implements Parser, DTDHandler, DocumentHandler, EntityResolver { @@ -121,8 +123,8 @@ /** Initialize the parser. */ private void initParser() { catalogResolver = new CatalogResolver(catalogManager); - - SAXParserFactory spf = SAXParserFactory.newInstance(); + SAXParserFactory spf = catalogManager.useServicesMechanism() ? + SAXParserFactory.newInstance() : new SAXParserFactoryImpl(); spf.setNamespaceAware(namespaceAware); spf.setValidating(validating); diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xml/internal/resolver/tools/ResolvingXMLFilter.java --- a/src/com/sun/org/apache/xml/internal/resolver/tools/ResolvingXMLFilter.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xml/internal/resolver/tools/ResolvingXMLFilter.java Tue Apr 17 11:17:59 2012 -0700 @@ -53,6 +53,7 @@ * @author Norman Walsh * Norman.Walsh@Sun.COM * + * @version 1.0 */ public class ResolvingXMLFilter extends XMLFilterImpl { /** @@ -63,7 +64,7 @@ public static boolean suppressExplanation = false; /** The manager for the underlying resolver. */ - private CatalogManager catalogManager = CatalogManager.getStaticManager(); + CatalogManager catalogManager = CatalogManager.getStaticManager(); /** The underlying catalog resolver. */ private CatalogResolver catalogResolver = null; diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xml/internal/resolver/tools/ResolvingXMLReader.java --- a/src/com/sun/org/apache/xml/internal/resolver/tools/ResolvingXMLReader.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xml/internal/resolver/tools/ResolvingXMLReader.java Tue Apr 17 11:17:59 2012 -0700 @@ -27,6 +27,7 @@ import javax.xml.parsers.*; +import com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl; import com.sun.org.apache.xml.internal.resolver.*; /** @@ -43,6 +44,7 @@ * @author Norman Walsh * Norman.Walsh@Sun.COM * + * @version 1.0 */ public class ResolvingXMLReader extends ResolvingXMLFilter { /** Make the parser Namespace aware? */ @@ -60,7 +62,8 @@ */ public ResolvingXMLReader() { super(); - SAXParserFactory spf = SAXParserFactory.newInstance(); + SAXParserFactory spf = catalogManager.useServicesMechanism() ? + SAXParserFactory.newInstance() : new SAXParserFactoryImpl(); spf.setNamespaceAware(namespaceAware); spf.setValidating(validating); try { @@ -80,7 +83,8 @@ */ public ResolvingXMLReader(CatalogManager manager) { super(manager); - SAXParserFactory spf = SAXParserFactory.newInstance(); + SAXParserFactory spf = catalogManager.useServicesMechanism() ? + SAXParserFactory.newInstance() : new SAXParserFactoryImpl(); spf.setNamespaceAware(namespaceAware); spf.setValidating(validating); try { diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xml/internal/serialize/SerializerFactory.java --- a/src/com/sun/org/apache/xml/internal/serialize/SerializerFactory.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xml/internal/serialize/SerializerFactory.java Tue Apr 17 11:17:59 2012 -0700 @@ -21,7 +21,7 @@ package com.sun.org.apache.xml.internal.serialize; - +import com.sun.org.apache.xerces.internal.utils.ObjectFactory; import java.io.OutputStream; import java.io.Writer; import java.io.UnsupportedEncodingException; @@ -31,6 +31,7 @@ /** * * + * @version $Revision: 1.6 $ $Date: 2010-11-01 04:40:36 $ * @author Scott Boag * @author Assaf Arkin */ @@ -69,8 +70,7 @@ while ( token.hasMoreTokens() ) { className = token.nextToken(); try { - factory = (SerializerFactory) ObjectFactory.newInstance( className, - SerializerFactory.class.getClassLoader(), true); + factory = (SerializerFactory) ObjectFactory.newInstance( className, true); if ( _factories.containsKey( factory.getSupportedMethod() ) ) _factories.put( factory.getSupportedMethod(), factory ); } catch ( Exception except ) { } diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xml/internal/serializer/CharInfo.java --- a/src/com/sun/org/apache/xml/internal/serializer/CharInfo.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xml/internal/serializer/CharInfo.java Tue Apr 17 11:17:59 2012 -0700 @@ -40,6 +40,7 @@ import com.sun.org.apache.xml.internal.serializer.utils.SystemIDResolver; import com.sun.org.apache.xml.internal.serializer.utils.Utils; import com.sun.org.apache.xml.internal.serializer.utils.WrappedRuntimeException; +import com.sun.org.apache.xalan.internal.utils.ObjectFactory; /** * This class provides services that tell if a character should have @@ -54,7 +55,7 @@ final class CharInfo { /** Given a character, lookup a String to output (e.g. a decorated entity reference). */ - private HashMap m_charToString = new HashMap(); + private HashMap m_charToString; /** * The name of the HTML entities file. @@ -71,42 +72,50 @@ "com.sun.org.apache.xml.internal.serializer.XMLEntities"; /** The horizontal tab character, which the parser should always normalize. */ - public static final char S_HORIZONAL_TAB = 0x09; + static final char S_HORIZONAL_TAB = 0x09; /** The linefeed character, which the parser should always normalize. */ - public static final char S_LINEFEED = 0x0A; + static final char S_LINEFEED = 0x0A; /** The carriage return character, which the parser should always normalize. */ - public static final char S_CARRIAGERETURN = 0x0D; + static final char S_CARRIAGERETURN = 0x0D; + static final char S_SPACE = 0x20; + static final char S_QUOTE = 0x22; + static final char S_LT = 0x3C; + static final char S_GT = 0x3E; + static final char S_NEL = 0x85; + static final char S_LINE_SEPARATOR = 0x2028; /** This flag is an optimization for HTML entities. It false if entities * other than quot (34), amp (38), lt (60) and gt (62) are defined * in the range 0 to 127. * @xsl.usage internal */ - final boolean onlyQuotAmpLtGt; + boolean onlyQuotAmpLtGt; /** Copy the first 0,1 ... ASCII_MAX values into an array */ - private static final int ASCII_MAX = 128; + static final int ASCII_MAX = 128; /** Array of values is faster access than a set of bits - * to quickly check ASCII characters in attribute values. + * to quickly check ASCII characters in attribute values, + * the value is true if the character in an attribute value + * should be mapped to a String. */ - private boolean[] isSpecialAttrASCII = new boolean[ASCII_MAX]; + private final boolean[] shouldMapAttrChar_ASCII; /** Array of values is faster access than a set of bits - * to quickly check ASCII characters in text nodes. + * to quickly check ASCII characters in text nodes, + * the value is true if the character in a text node + * should be mapped to a String. */ - private boolean[] isSpecialTextASCII = new boolean[ASCII_MAX]; - - private boolean[] isCleanTextASCII = new boolean[ASCII_MAX]; + private final boolean[] shouldMapTextChar_ASCII; /** An array of bits to record if the character is in the set. * Although information in this array is complete, the * isSpecialAttrASCII array is used first because access to its values * is common and faster. */ - private int array_of_bits[] = createEmptySetOfIntegers(65535); + private final int array_of_bits[]; // 5 for 32 bit words, 6 for 64 bit words ... @@ -137,33 +146,38 @@ /** - * Constructor that reads in a resource file that describes the mapping of - * characters to entity references. - * This constructor is private, just to force the use - * of the getCharInfo(entitiesResource) factory - * - * Resource files must be encoded in UTF-8 and can either be properties - * files with a .properties extension assumed. Alternatively, they can - * have the following form, with no particular extension assumed: + * A base constructor just to explicitly create the fields, + * with the exception of m_charToString which is handled + * by the constructor that delegates base construction to this one. + *

+ * m_charToString is not created here only for performance reasons, + * to avoid creating a Hashtable that will be replaced when + * making a mutable copy, {@link #mutableCopyOf(CharInfo)}. * - *

-     * # First char # is a comment
-     * Entity numericValue
-     * quot 34
-     * amp 38
-     * 
- * - * @param entitiesResource Name of properties or resource file that should - * be loaded, which describes that mapping of characters to entity - * references. */ - private CharInfo(String entitiesResource, String method) + private CharInfo() { - this(entitiesResource, method, false); + this.array_of_bits = createEmptySetOfIntegers(65535); + this.firstWordNotUsed = 0; + this.shouldMapAttrChar_ASCII = new boolean[ASCII_MAX]; + this.shouldMapTextChar_ASCII = new boolean[ASCII_MAX]; + this.m_charKey = new CharKey(); + + // Not set here, but in a constructor that uses this one + // this.m_charToString = new Hashtable(); + + this.onlyQuotAmpLtGt = true; + + + return; } private CharInfo(String entitiesResource, String method, boolean internal) { + // call the default constructor to create the fields + this(); + m_charToString = new HashMap(); + ResourceBundle entities = null; boolean noExtraEntities = true; @@ -189,12 +203,10 @@ String name = (String) keys.nextElement(); String value = entities.getString(name); int code = Integer.parseInt(value); - defineEntity(name, (char) code); - if (extraEntity(code)) + boolean extra = defineEntity(name, (char) code); + if (extra) noExtraEntities = false; } - set(S_LINEFEED); - set(S_CARRIAGERETURN); } else { InputStream is = null; @@ -278,8 +290,8 @@ int code = Integer.parseInt(value); - defineEntity(name, (char) code); - if (extraEntity(code)) + boolean extra = defineEntity(name, (char) code); + if (extra) noExtraEntities = false; } } @@ -288,8 +300,6 @@ } is.close(); - set(S_LINEFEED); - set(S_CARRIAGERETURN); } catch (Exception e) { throw new RuntimeException( Utils.messages.createMessage( @@ -307,31 +317,8 @@ } } - /* initialize the array isCleanTextASCII[] with a cache of values - * for use by ToStream.character(char[], int , int) - * and the array isSpecialTextASCII[] with the opposite values - * (all in the name of performance!) - */ - for (int ch = 0; ch Unlike internal entities, character references are a string to single * character mapping. They are used to map non-ASCII characters both on - * parsing and printing, primarily for HTML documents. '<amp;' is an + * parsing and printing, primarily for HTML documents. '&lt;' is an * example of a character reference.

* * @param name The entity's name * @param value The entity's value + * @return true if the mapping is not one of: + *
    + *
  • '<' to "<" + *
  • '>' to ">" + *
  • '&' to "&" + *
  • '"' to """ + *
*/ - private void defineEntity(String name, char value) + private boolean defineEntity(String name, char value) { StringBuilder sb = new StringBuilder("&"); sb.append(name); sb.append(';'); String entityString = sb.toString(); - defineChar2StringMapping(entityString, value); + boolean extra = defineChar2StringMapping(entityString, value); + return extra; } /** + * A utility object, just used to map characters to output Strings, + * needed because a HashMap needs to map an object as a key, not a + * Java primitive type, like a char, so this object gets around that + * and it is reusable. + */ + private final CharKey m_charKey; + + /** * Map a character to a String. For example given * the character '>' this method would return the fully decorated * entity name "<". @@ -399,21 +413,21 @@ /** * Tell if the character argument that is from - * an attribute value should have special treatment. + * an attribute value has a mapping to a String. * * @param value the value of a character that is in an attribute value * @return true if the character should have any special treatment, * such as when writing out attribute values, - * or entity references. + * such as when writing out entity references. * @xsl.usage internal */ - final boolean isSpecialAttrChar(int value) + final boolean shouldMapAttrChar(int value) { // for performance try the values in the boolean array first, // this is faster access than the BitSet for common ASCII values if (value < ASCII_MAX) - return isSpecialAttrASCII[value]; + return shouldMapAttrChar_ASCII[value]; // rather than java.util.BitSet, our private // implementation is faster (and less general). @@ -422,48 +436,27 @@ /** * Tell if the character argument that is from a - * text node should have special treatment. + * text node has a mapping to a String, for example + * to map '<' to "<". * * @param value the value of a character that is in a text node - * @return true if the character should have any special treatment, - * such as when writing out attribute values, - * or entity references. + * @return true if the character has a mapping to a String, + * such as when writing out entity references. * @xsl.usage internal */ - final boolean isSpecialTextChar(int value) + final boolean shouldMapTextChar(int value) { // for performance try the values in the boolean array first, // this is faster access than the BitSet for common ASCII values if (value < ASCII_MAX) - return isSpecialTextASCII[value]; + return shouldMapTextChar_ASCII[value]; // rather than java.util.BitSet, our private // implementation is faster (and less general). return get(value); } - /** - * This method is used to determine if an ASCII character in - * a text node (not an attribute value) is "clean". - * @param value the character to check (0 to 127). - * @return true if the character can go to the writer as-is - * @xsl.usage internal - */ - final boolean isTextASCIIClean(int value) - { - return isCleanTextASCII[value]; - } - -// In the future one might want to use the array directly and avoid -// the method call, but I think the JIT alreay inlines this well enough -// so don't do it (for now) - bjm -// public final boolean[] getASCIIClean() -// { -// return isCleanTextASCII; -// } - - private static CharInfo getCharInfoBasedOnPrivilege( final String entitiesFileName, final String method, final boolean internal){ @@ -498,15 +491,17 @@ { CharInfo charInfo = (CharInfo) m_getCharInfoCache.get(entitiesFileName); if (charInfo != null) { - return charInfo; + return mutableCopyOf(charInfo); } // try to load it internally - cache try { charInfo = getCharInfoBasedOnPrivilege(entitiesFileName, method, true); + // Put the common copy of charInfo in the cache, but return + // a copy of it. m_getCharInfoCache.put(entitiesFileName, charInfo); - return charInfo; + return mutableCopyOf(charInfo); } catch (Exception e) {} // try to load it externally - do not cache @@ -533,7 +528,41 @@ method, false); } - /** Table of user-specified char infos. */ + /** + * Create a mutable copy of the cached one. + * @param charInfo The cached one. + * @return + */ + private static CharInfo mutableCopyOf(CharInfo charInfo) { + CharInfo copy = new CharInfo(); + + int max = charInfo.array_of_bits.length; + System.arraycopy(charInfo.array_of_bits,0,copy.array_of_bits,0,max); + + copy.firstWordNotUsed = charInfo.firstWordNotUsed; + + max = charInfo.shouldMapAttrChar_ASCII.length; + System.arraycopy(charInfo.shouldMapAttrChar_ASCII,0,copy.shouldMapAttrChar_ASCII,0,max); + + max = charInfo.shouldMapTextChar_ASCII.length; + System.arraycopy(charInfo.shouldMapTextChar_ASCII,0,copy.shouldMapTextChar_ASCII,0,max); + + // utility field copy.m_charKey is already created in the default constructor + + copy.m_charToString = (HashMap) charInfo.m_charToString.clone(); + + copy.onlyQuotAmpLtGt = charInfo.onlyQuotAmpLtGt; + + return copy; + } + + /** + * Table of user-specified char infos. + * The table maps entify file names (the name of the + * property file without the .properties extension) + * to CharInfo objects populated with entities defined in + * corresponding property file. + */ private static HashMap m_getCharInfoCache = new HashMap(); /** @@ -575,7 +604,8 @@ * the creation of the set. */ private final void set(int i) { - setASCIIdirty(i); + setASCIItextDirty(i); + setASCIIattrDirty(i); int j = (i >> SHIFT_PER_WORD); // this word is used int k = j + 1; @@ -610,24 +640,43 @@ return in_the_set; } - // record if there are any entities other than - // quot, amp, lt, gt (probably user defined) /** - * @return true if the entity - * @param code The value of the character that has an entity defined - * for it. + * This method returns true if there are some non-standard mappings to + * entities other than quot, amp, lt, gt, and its only purpose is for + * performance. + * @param charToMap The value of the character that is mapped to a String + * @param outputString The String to which the character is mapped, usually + * an entity reference such as "<". + * @return true if the mapping is not one of: + *
    + *
  • '<' to "<" + *
  • '>' to ">" + *
  • '&' to "&" + *
  • '"' to """ + *
*/ - private boolean extraEntity(int entityValue) + private boolean extraEntity(String outputString, int charToMap) { boolean extra = false; - if (entityValue < 128) + if (charToMap < ASCII_MAX) { - switch (entityValue) + switch (charToMap) { - case 34 : // quot - case 38 : // amp - case 60 : // lt - case 62 : // gt + case '"' : // quot + if (!outputString.equals(""")) + extra = true; + break; + case '&' : // amp + if (!outputString.equals("&")) + extra = true; + break; + case '<' : // lt + if (!outputString.equals("<")) + extra = true; + break; + case '>' : // gt + if (!outputString.equals(">")) + extra = true; break; default : // other entity in range 0 to 127 extra = true; @@ -637,49 +686,61 @@ } /** - * If the character is a printable ASCII character then - * mark it as not clean and needing replacement with - * a String on output. + * If the character is in the ASCII range then + * mark it as needing replacement with + * a String on output if it occurs in a text node. * @param ch */ - private void setASCIIdirty(int j) + private void setASCIItextDirty(int j) { if (0 <= j && j < ASCII_MAX) { - isCleanTextASCII[j] = false; - isSpecialTextASCII[j] = true; + shouldMapTextChar_ASCII[j] = true; } } /** - * If the character is a printable ASCII character then - * mark it as and not needing replacement with - * a String on output. + * If the character is in the ASCII range then + * mark it as needing replacement with + * a String on output if it occurs in a attribute value. * @param ch */ - private void setASCIIclean(int j) + private void setASCIIattrDirty(int j) { if (0 <= j && j < ASCII_MAX) { - isCleanTextASCII[j] = true; - isSpecialTextASCII[j] = false; + shouldMapAttrChar_ASCII[j] = true; } } - private void defineChar2StringMapping(String outputString, char inputChar) + /** + * Call this method to register a char to String mapping, for example + * to map '<' to "<". + * @param outputString The String to map to. + * @param inputChar The char to map from. + * @return true if the mapping is not one of: + *
    + *
  • '<' to "<" + *
  • '>' to ">" + *
  • '&' to "&" + *
  • '"' to """ + *
+ */ + boolean defineChar2StringMapping(String outputString, char inputChar) { CharKey character = new CharKey(inputChar); m_charToString.put(character, outputString); - set(inputChar); + set(inputChar); // mark the character has having a mapping to a String + + boolean extraMapping = extraEntity(outputString, inputChar); + return extraMapping; + } /** * Simple class for fast lookup of char values, when used with * hashtables. You can set the char, then use it as a key. * - * This class is a copy of the one in com.sun.org.apache.xml.internal.utils. - * It exists to cut the serializers dependancy on that package. - * * @xsl.usage internal */ private static class CharKey extends Object diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xml/internal/serializer/EmptySerializer.java --- a/src/com/sun/org/apache/xml/internal/serializer/EmptySerializer.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xml/internal/serializer/EmptySerializer.java Tue Apr 17 11:17:59 2012 -0700 @@ -179,6 +179,13 @@ aMethodIsCalled(); } /** + * @see SerializationHandler#setIsStandalone(boolean) + */ + public void setIsStandalone(boolean isStandalone) + { + aMethodIsCalled(); + } + /** * @see SerializationHandler#setOutputFormat(java.util.Properties) */ public void setOutputFormat(Properties format) diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xml/internal/serializer/Encodings.java --- a/src/com/sun/org/apache/xml/internal/serializer/Encodings.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xml/internal/serializer/Encodings.java Tue Apr 17 11:17:59 2012 -0700 @@ -34,6 +34,7 @@ import java.util.Properties; import java.util.StringTokenizer; +import com.sun.org.apache.xalan.internal.utils.SecuritySupport; /** * Provides information about encodings. Depends on the Java runtime @@ -41,7 +42,7 @@ * to override encoding names and provide the last printable character * for each encoding. * - * @version $Revision: 1.9 $ $Date: 2009/12/01 22:17:31 $ + * @version $Revision: 1.11 $ $Date: 2010-11-01 04:34:44 $ * @author Assaf Arkin */ @@ -324,9 +325,7 @@ } if (is == null) { - SecuritySupport ss = SecuritySupport.getInstance(); - is = ss.getResourceAsStream(ObjectFactory.findClassLoader(), - ENCODINGS_FILE); + is = SecuritySupport.getResourceAsStream(ENCODINGS_FILE); } Properties props = new Properties(); diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xml/internal/serializer/ObjectFactory.java --- a/src/com/sun/org/apache/xml/internal/serializer/ObjectFactory.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,662 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2001-2004 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. - */ -/* - * $Id: ObjectFactory.java,v 1.2.4.1 2005/09/15 08:15:20 suresh_emailid Exp $ - */ - -package com.sun.org.apache.xml.internal.serializer; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.Properties; - -/** - * 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. - *

- * This code is designed to implement the JAXP 1.1 spec pluggability - * feature and is designed to run on JDK version 1.1 and - * later, and to compile on JDK 1.2 and onward. - * The code also runs both as part of an unbundled jar file and - * when bundled as part of the JDK. - *

- * This class was moved from the javax.xml.parsers.ObjectFactory - * class and modified to be used as a general utility for creating objects - * dynamically. - * - * @xsl.usage internal - */ -class ObjectFactory { - - // - // Constants - // - - // name of default properties file to look for in JDK's jre/lib directory - private static final String DEFAULT_PROPERTIES_FILENAME = - "xalan.properties"; - - private static final String SERVICES_PATH = "META-INF/services/"; - - /** Set to true for debugging */ - private static final boolean DEBUG = false; - - /** cache the contents of the xalan.properties file. - * Until an attempt has been made to read this file, this will - * be null; if the file does not exist or we encounter some other error - * during the read, this will be empty. - */ - private static Properties fXalanProperties = null; - - /*** - * Cache the time stamp of the xalan.properties file so - * that we know if it's been modified and can invalidate - * the cache when necessary. - */ - private static long fLastModified = -1; - - // - // Public static methods - // - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *

    - *
  1. query the system property using System.getProperty - *
  2. read META-INF/services/factoryId file - *
  3. use fallback classname - *
- * - * @return instance of factory, 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 no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Object createObject(String factoryId, String fallbackClassName) - throws ConfigurationError { - return createObject(factoryId, null, fallbackClassName); - } // createObject(String,String):Object - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return instance of factory, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Object createObject(String factoryId, - String propertiesFilename, - String fallbackClassName) - throws ConfigurationError - { - Class factoryClass = lookUpFactoryClass(factoryId, - propertiesFilename, - fallbackClassName); - - if (factoryClass == null) { - throw new ConfigurationError( - "Provider for " + factoryId + " cannot be found", null); - } - - try{ - Object instance = factoryClass.newInstance(); - if (DEBUG) debugPrintln("created new instance of factory " + factoryId); - return instance; - } catch (Exception x) { - throw new ConfigurationError( - "Provider for factory " + factoryId - + " could not be instantiated: " + x, x); - } - } // createObject(String,String,String):Object - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return Class object of factory, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Class lookUpFactoryClass(String factoryId) - throws ConfigurationError - { - return lookUpFactoryClass(factoryId, null, null); - } // lookUpFactoryClass(String):Class - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return Class object that provides factory service, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Class lookUpFactoryClass(String factoryId, - String propertiesFilename, - String fallbackClassName) - throws ConfigurationError - { - String factoryClassName = lookUpFactoryClassName(factoryId, - propertiesFilename, - fallbackClassName); - ClassLoader cl = findClassLoader(); - - if (factoryClassName == null) { - factoryClassName = fallbackClassName; - } - - // assert(className != null); - try{ - Class providerClass = findProviderClass(factoryClassName, - cl, - true); - if (DEBUG) debugPrintln("created new instance of " + providerClass + - " using ClassLoader: " + cl); - return providerClass; - } catch (ClassNotFoundException x) { - throw new ConfigurationError( - "Provider " + factoryClassName + " not found", x); - } catch (Exception x) { - throw new ConfigurationError( - "Provider "+factoryClassName+" could not be instantiated: "+x, - x); - } - } // lookUpFactoryClass(String,String,String):Class - - /** - * Finds the name of the required implementation class in the specified - * order. The specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return name of class that provides factory service, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static String lookUpFactoryClassName(String factoryId, - String propertiesFilename, - String fallbackClassName) - { - SecuritySupport ss = SecuritySupport.getInstance(); - - // Use the system property first - try { - String systemProp = ss.getSystemProperty(factoryId); - if (systemProp != null) { - if (DEBUG) debugPrintln("found system property, value=" + systemProp); - return systemProp; - } - } catch (SecurityException se) { - // Ignore and continue w/ next location - } - - // Try to read from propertiesFilename, or - // $java.home/lib/xalan.properties - String factoryClassName = null; - // no properties file name specified; use - // $JAVA_HOME/lib/xalan.properties: - if (propertiesFilename == null) { - File propertiesFile = null; - boolean propertiesFileExists = false; - try { - String javah = ss.getSystemProperty("java.home"); - propertiesFilename = javah + File.separator + - "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME; - propertiesFile = new File(propertiesFilename); - propertiesFileExists = ss.getFileExists(propertiesFile); - } catch (SecurityException e) { - // try again... - fLastModified = -1; - fXalanProperties = null; - } - - synchronized (ObjectFactory.class) { - boolean loadProperties = false; - FileInputStream fis = null; - try { - // file existed last time - if(fLastModified >= 0) { - if(propertiesFileExists && - (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) { - loadProperties = true; - } else { - // file has stopped existing... - if(!propertiesFileExists) { - fLastModified = -1; - fXalanProperties = null; - } // else, file wasn't modified! - } - } else { - // file has started to exist: - if(propertiesFileExists) { - loadProperties = true; - fLastModified = ss.getLastModified(propertiesFile); - } // else, nothing's changed - } - if(loadProperties) { - // must never have attempted to read xalan.properties - // before (or it's outdeated) - fXalanProperties = new Properties(); - fis = ss.getFileInputStream(propertiesFile); - fXalanProperties.load(fis); - } - } catch (Exception x) { - fXalanProperties = null; - fLastModified = -1; - // assert(x instanceof FileNotFoundException - // || x instanceof SecurityException) - // In both cases, ignore and continue w/ next location - } - finally { - // try to close the input stream if one was opened. - if (fis != null) { - try { - fis.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - } - } - if(fXalanProperties != null) { - factoryClassName = fXalanProperties.getProperty(factoryId); - } - } else { - FileInputStream fis = null; - try { - fis = ss.getFileInputStream(new File(propertiesFilename)); - Properties props = new Properties(); - props.load(fis); - factoryClassName = props.getProperty(factoryId); - } catch (Exception x) { - // assert(x instanceof FileNotFoundException - // || x instanceof SecurityException) - // In both cases, ignore and continue w/ next location - } - finally { - // try to close the input stream if one was opened. - if (fis != null) { - try { - fis.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - } - } - if (factoryClassName != null) { - if (DEBUG) debugPrintln("found in " + propertiesFilename + ", value=" - + factoryClassName); - return factoryClassName; - } - - // Try Jar Service Provider Mechanism - return findJarServiceProviderName(factoryId); - } // lookUpFactoryClass(String,String):String - - // - // Private static methods - // - - /** Prints a message to standard error if debugging is enabled. */ - private static void debugPrintln(String msg) { - if (DEBUG) { - System.err.println("JAXP: " + msg); - } - } // debugPrintln(String) - - /** - * Figure out which ClassLoader to use. For JDK 1.2 and later use - * the context ClassLoader. - */ - static ClassLoader findClassLoader() - 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 context = ss.getContextClassLoader(); - ClassLoader system = ss.getSystemClassLoader(); - - ClassLoader chain = system; - while (true) { - if (context == chain) { - // Assert: we are on JDK 1.1 or we have no Context ClassLoader - // or any Context ClassLoader in chain of system classloader - // (including extension ClassLoader) so extend to widest - // ClassLoader (always look in system ClassLoader if Xalan - // is in boot/extension/system classpath and in current - // ClassLoader otherwise); normal classloaders delegate - // back to system ClassLoader first so this widening doesn't - // change the fact that context ClassLoader will be consulted - ClassLoader current = ObjectFactory.class.getClassLoader(); - - chain = system; - while (true) { - if (current == chain) { - // Assert: Current ClassLoader in chain of - // boot/extension/system ClassLoaders - return system; - } - if (chain == null) { - break; - } - chain = ss.getParentClassLoader(chain); - } - - // Assert: Current ClassLoader not in chain of - // boot/extension/system ClassLoaders - return current; - } - - if (chain == null) { - // boot ClassLoader reached - break; - } - - // Check for any extension ClassLoaders in chain up to - // boot ClassLoader - chain = ss.getParentClassLoader(chain); - }; - - // Assert: Context ClassLoader not in chain of - // boot/extension/system ClassLoaders - return context; - } // findClassLoader():ClassLoader - - /** - * Create an instance of a class using the specified ClassLoader - */ - static Object newInstance(String className, ClassLoader cl, - boolean doFallback) - throws ConfigurationError - { - // assert(className != null); - try{ - Class providerClass = findProviderClass(className, cl, doFallback); - Object instance = providerClass.newInstance(); - if (DEBUG) debugPrintln("created new instance of " + providerClass + - " using ClassLoader: " + cl); - return instance; - } catch (ClassNotFoundException x) { - throw new ConfigurationError( - "Provider " + className + " not found", x); - } catch (Exception x) { - throw new ConfigurationError( - "Provider " + className + " could not be instantiated: " + x, - x); - } - } - - /** - * Find a Class using the specified ClassLoader - */ - static Class findProviderClass(String className, ClassLoader cl, - boolean doFallback) - throws ClassNotFoundException, ConfigurationError - { - //throw security exception if the calling thread is not allowed to access the - //class. Restrict the access to the package classes as specified in java.security policy. - SecurityManager security = System.getSecurityManager(); - try{ - if (security != null){ - final int lastDot = className.lastIndexOf("."); - String packageName = className; - if (lastDot != -1) packageName = className.substring(0, lastDot); - security.checkPackageAccess(packageName); - } - }catch(SecurityException e){ - throw e; - } - - Class providerClass; - 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 { - try { - providerClass = cl.loadClass(className); - } catch (ClassNotFoundException x) { - if (doFallback) { - // Fall back to current classloader - ClassLoader current = ObjectFactory.class.getClassLoader(); - if (current == null) { - providerClass = Class.forName(className); - } else if (cl != current) { - cl = current; - providerClass = cl.loadClass(className); - } else { - throw x; - } - } else { - throw x; - } - } - } - - return providerClass; - } - - /** - * Find the name of service provider using Jar Service Provider Mechanism - * - * @return instance of provider class if found or null - */ - private static String findJarServiceProviderName(String factoryId) - { - SecuritySupport ss = SecuritySupport.getInstance(); - String serviceId = SERVICES_PATH + factoryId; - InputStream is = null; - - // First try the Context ClassLoader - ClassLoader cl = findClassLoader(); - - is = ss.getResourceAsStream(cl, serviceId); - - // If no provider found then try the current ClassLoader - if (is == null) { - ClassLoader current = ObjectFactory.class.getClassLoader(); - if (cl != current) { - cl = current; - is = ss.getResourceAsStream(cl, serviceId); - } - } - - if (is == null) { - // No provider found - return null; - } - - if (DEBUG) debugPrintln("found jar resource=" + serviceId + - " using ClassLoader: " + cl); - - // 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)); - } - - String factoryClassName = null; - try { - // XXX Does not handle all possible input as specified by the - // Jar Service Provider specification - factoryClassName = rd.readLine(); - } catch (IOException x) { - // No provider found - return null; - } - finally { - try { - // try to close the reader. - rd.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - - if (factoryClassName != null && - ! "".equals(factoryClassName)) { - if (DEBUG) debugPrintln("found in resource, value=" - + factoryClassName); - - // Note: here we do not want to fall back to the current - // 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. - return factoryClassName; - } - - // No provider found - return null; - } - - // - // Classes - // - - /** - * A configuration error. - */ - static class ConfigurationError - extends Error { - static final long serialVersionUID = 8859254254255146542L; - // - // Data - // - - /** Exception. */ - private Exception exception; - - // - // Constructors - // - - /** - * Construct a new instance with the specified detail string and - * exception. - */ - ConfigurationError(String msg, Exception x) { - super(msg); - this.exception = x; - } // (String,Exception) - - // - // Public methods - // - - /** Returns the exception associated to this error. */ - Exception getException() { - return exception; - } // getException():Exception - - } // class ConfigurationError - -} // class ObjectFactory diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xml/internal/serializer/OutputPropertiesFactory.java --- a/src/com/sun/org/apache/xml/internal/serializer/OutputPropertiesFactory.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xml/internal/serializer/OutputPropertiesFactory.java Tue Apr 17 11:17:59 2012 -0700 @@ -175,6 +175,26 @@ public static final int S_BUILTIN_OLD_EXTENSIONS_UNIVERSAL_LEN = S_BUILTIN_OLD_EXTENSIONS_UNIVERSAL.length(); + /** + * This non-standard, Oracle-impl only property key is used as if OutputKeys.STANDALONE is specified but + * without writing it out in the declaration; It can be used to reverse the change by Xalan patch 1495. + * Since Xalan patch 1495 can cause incompatible behavior, this property is add for application to neutralize + * the effect of Xalan patch 1495 + */ + /** + *

Is Standalone

+ * + *
    + *
  • + * yes to indicate the output is intended to be used as standalone + *
  • + *
  • + * no has no effect. + *
  • + *
+ */ + public static final String ORACLE_IS_STANDALONE = "http://www.oracle.com/xml/is-standalone"; + //************************************************************ //* PRIVATE CONSTANTS //************************************************************ diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xml/internal/serializer/SecuritySupport.java --- a/src/com/sun/org/apache/xml/internal/serializer/SecuritySupport.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,125 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2002-2004 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. - */ -/* - * $Id: SecuritySupport.java,v 1.2.4.1 2005/09/15 08:15:21 suresh_emailid Exp $ - */ - -package com.sun.org.apache.xml.internal.serializer; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.InputStream; - -/** - * This class is duplicated for each Xalan-Java subpackage so keep it in sync. - * It is package private and therefore is not exposed as part of the Xalan-Java - * 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. - */ - static SecuritySupport getInstance() { - return (SecuritySupport)securitySupport; - } - - ClassLoader getContextClassLoader() { - return null; - } - - ClassLoader getSystemClassLoader() { - return null; - } - - ClassLoader getParentClassLoader(ClassLoader cl) { - return null; - } - - String getSystemProperty(String propName) { - return System.getProperty(propName); - } - - FileInputStream getFileInputStream(File file) - throws FileNotFoundException - { - return new FileInputStream(file); - } - - InputStream getResourceAsStream(ClassLoader cl, String name) { - InputStream ris; - if (cl == null) { - ris = ClassLoader.getSystemResourceAsStream(name); - } else { - ris = cl.getResourceAsStream(name); - } - return ris; - } - - boolean getFileExists(File f) { - return f.exists(); - } - - long getLastModified(File f) { - return f.lastModified(); - } -} diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xml/internal/serializer/SecuritySupport12.java --- a/src/com/sun/org/apache/xml/internal/serializer/SecuritySupport12.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,145 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2002-2004 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. - */ -/* - * $Id: SecuritySupport12.java,v 1.2.4.1 2005/09/15 08:15:22 suresh_emailid Exp $ - */ - -package com.sun.org.apache.xml.internal.serializer; - -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 Xalan-Java subpackage so keep it in sync. - * It is package private and therefore is not exposed as part of the Xalan-Java - * API. - * - * Security related methods that only work on J2SE 1.2 and newer. - */ -class SecuritySupport12 extends SecuritySupport { - - ClassLoader getContextClassLoader() { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader cl = null; - try { - cl = Thread.currentThread().getContextClassLoader(); - } catch (SecurityException ex) { } - return cl; - } - }); - } - - ClassLoader getSystemClassLoader() { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader cl = null; - try { - cl = ClassLoader.getSystemClassLoader(); - } catch (SecurityException ex) {} - return cl; - } - }); - } - - ClassLoader getParentClassLoader(final ClassLoader cl) { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader parent = null; - try { - parent = cl.getParent(); - } catch (SecurityException ex) {} - - // eliminate loops in case of the boot - // ClassLoader returning itself as a parent - return (parent == cl) ? null : parent; - } - }); - } - - String getSystemProperty(final String propName) { - return (String) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return System.getProperty(propName); - } - }); - } - - 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(); - } - } - - 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; - } - }); - } - - boolean getFileExists(final File f) { - return ((Boolean) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return new Boolean(f.exists()); - } - })).booleanValue(); - } - - long getLastModified(final File f) { - return ((Long) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return new Long(f.lastModified()); - } - })).longValue(); - } - -} diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xml/internal/serializer/SerializationHandler.java --- a/src/com/sun/org/apache/xml/internal/serializer/SerializationHandler.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xml/internal/serializer/SerializationHandler.java Tue Apr 17 11:17:59 2012 -0700 @@ -124,5 +124,11 @@ */ public void setDTDEntityExpansion(boolean expand); + /** + * Specify if the output will be treated as a standalone property + * @param isStandalone true if the http://www.oracle.com/xml/is-standalone is set to yes + * @see OutputPropertiesFactory ORACLE_IS_STANDALONE + */ + public void setIsStandalone(boolean b); } diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xml/internal/serializer/SerializerBase.java --- a/src/com/sun/org/apache/xml/internal/serializer/SerializerBase.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xml/internal/serializer/SerializerBase.java Tue Apr 17 11:17:59 2012 -0700 @@ -143,6 +143,11 @@ protected boolean m_standaloneWasSpecified = false; /** + * Determine if the output is a standalone. + */ + protected boolean m_isStandalone = false; + + /** * Flag to tell if indenting (pretty-printing) is on. */ protected boolean m_doIndent = false; @@ -740,6 +745,16 @@ } /** + * Sets the isStandalone property + * @param isStandalone true if the ORACLE_IS_STANDALONE is set to yes + * @see OutputPropertiesFactory ORACLE_IS_STANDALONE + */ + public void setIsStandalone(boolean isStandalone) + { + m_isStandalone = isStandalone; + } + + /** * This method is used when a prefix/uri namespace mapping * is indicated after the element was started with a * startElement() and before and endElement(). diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xml/internal/serializer/SerializerFactory.java --- a/src/com/sun/org/apache/xml/internal/serializer/SerializerFactory.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xml/internal/serializer/SerializerFactory.java Tue Apr 17 11:17:59 2012 -0700 @@ -29,6 +29,7 @@ import com.sun.org.apache.xml.internal.serializer.utils.MsgKey; import com.sun.org.apache.xml.internal.serializer.utils.Utils; +import com.sun.org.apache.xalan.internal.utils.ObjectFactory; import org.xml.sax.ContentHandler; /** @@ -126,9 +127,7 @@ - ClassLoader loader = ObjectFactory.findClassLoader(); - - Class cls = ObjectFactory.findProviderClass(className, loader, true); + Class cls = ObjectFactory.findProviderClass(className, true); // _serializers.put(method, cls); @@ -156,7 +155,7 @@ * SAX ContentHandler events to the users handler. */ className = SerializerConstants.DEFAULT_SAX_SERIALIZER; - cls = ObjectFactory.findProviderClass(className, loader, true); + cls = ObjectFactory.findProviderClass(className, true); SerializationHandler sh = (SerializationHandler) cls.newInstance(); sh.setContentHandler( (ContentHandler) obj); diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xml/internal/serializer/ToHTMLSAXHandler.java --- a/src/com/sun/org/apache/xml/internal/serializer/ToHTMLSAXHandler.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xml/internal/serializer/ToHTMLSAXHandler.java Tue Apr 17 11:17:59 2012 -0700 @@ -56,7 +56,7 @@ /** * Keeps track of whether output escaping is currently enabled */ - protected boolean m_escapeSetting = false; + protected boolean m_escapeSetting = true; /** * Returns null. @@ -742,6 +742,6 @@ */ private void resetToHTMLSAXHandler() { - this.m_escapeSetting = false; + this.m_escapeSetting = true; } } diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xml/internal/serializer/ToHTMLStream.java --- a/src/com/sun/org/apache/xml/internal/serializer/ToHTMLStream.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xml/internal/serializer/ToHTMLStream.java Tue Apr 17 11:17:59 2012 -0700 @@ -58,7 +58,7 @@ * Map that tells which XML characters should have special treatment, and it * provides character to entity name lookup. */ - private static final CharInfo m_htmlcharInfo = + private final CharInfo m_htmlcharInfo = // new CharInfo(CharInfo.HTML_ENTITIES_RESOURCE); CharInfo.getCharInfo(CharInfo.HTML_ENTITIES_RESOURCE, Method.HTML); @@ -1369,7 +1369,7 @@ // System.out.println("ch: "+(int)ch); // System.out.println("m_maxCharacter: "+(int)m_maxCharacter); // System.out.println("m_attrCharsMap[ch]: "+(int)m_attrCharsMap[ch]); - if (escapingNotNeeded(ch) && (!m_charInfo.isSpecialAttrChar(ch))) + if (escapingNotNeeded(ch) && (!m_charInfo.shouldMapAttrChar(ch))) { cleanLength++; } diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xml/internal/serializer/ToStream.java --- a/src/com/sun/org/apache/xml/internal/serializer/ToStream.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xml/internal/serializer/ToStream.java Tue Apr 17 11:17:59 2012 -0700 @@ -919,7 +919,8 @@ { // This is the old/fast code here, but is this // correct for all encodings? - if (ch >= 0x20 || (0x0A == ch || 0x0D == ch || 0x09 == ch)) + if (ch >= CharInfo.S_SPACE || (CharInfo.S_LINEFEED == ch || + CharInfo.S_CARRIAGERETURN == ch || CharInfo.S_HORIZONAL_TAB == ch)) ret= true; else ret = false; @@ -1028,7 +1029,7 @@ * * @throws java.io.IOException */ - protected int accumDefaultEntity( + int accumDefaultEntity( java.io.Writer writer, char ch, int i, @@ -1047,7 +1048,7 @@ { // if this is text node character and a special one of those, // or if this is a character from attribute value and a special one of those - if ((fromTextNode && m_charInfo.isSpecialTextChar(ch)) || (!fromTextNode && m_charInfo.isSpecialAttrChar(ch))) + if ((fromTextNode && m_charInfo.shouldMapTextChar(ch)) || (!fromTextNode && m_charInfo.shouldMapAttrChar(ch))) { String outputStringForChar = m_charInfo.getOutputStringForChar(ch); @@ -1398,7 +1399,6 @@ if (m_cdataTagOpen) closeCDATA(); - // the check with _escaping is a bit of a hack for XLSTC if (m_disableOutputEscapingStates.peekOrFalse() || (!m_escaping)) { @@ -1421,82 +1421,173 @@ try { int i; - char ch1; int startClean; // skip any leading whitspace // don't go off the end and use a hand inlined version // of isWhitespace(ch) final int end = start + length; - int lastDirty = start - 1; // last character that needed processing - for (i = start; - ((i < end) - && ((ch1 = chars[i]) == 0x20 - || (ch1 == 0xA && m_lineSepUse) - || ch1 == 0xD - || ch1 == 0x09)); - i++) - { - /* - * We are processing leading whitespace, but are doing the same - * processing for dirty characters here as for non-whitespace. - * - */ - if (!m_charInfo.isTextASCIIClean(ch1)) - { - lastDirty = processDirty(chars,end, i,ch1, lastDirty, true); - i = lastDirty; + int lastDirtyCharProcessed = start - 1; // last non-clean character that was processed + // that was processed + final Writer writer = m_writer; + boolean isAllWhitespace = true; + + // process any leading whitspace + i = start; + while (i < end && isAllWhitespace) { + char ch1 = chars[i]; + + if (m_charInfo.shouldMapTextChar(ch1)) { + // The character is supposed to be replaced by a String + // so write out the clean whitespace characters accumulated + // so far + // then the String. + writeOutCleanChars(chars, i, lastDirtyCharProcessed); + String outputStringForChar = m_charInfo + .getOutputStringForChar(ch1); + writer.write(outputStringForChar); + // We can't say that everything we are writing out is + // all whitespace, we just wrote out a String. + isAllWhitespace = false; + lastDirtyCharProcessed = i; // mark the last non-clean + // character processed + i++; + } else { + // The character is clean, but is it a whitespace ? + switch (ch1) { + // TODO: Any other whitespace to consider? + case CharInfo.S_SPACE: + // Just accumulate the clean whitespace + i++; + break; + case CharInfo.S_LINEFEED: + lastDirtyCharProcessed = processLineFeed(chars, i, + lastDirtyCharProcessed, writer); + i++; + break; + case CharInfo.S_CARRIAGERETURN: + writeOutCleanChars(chars, i, lastDirtyCharProcessed); + writer.write(" "); + lastDirtyCharProcessed = i; + i++; + break; + case CharInfo.S_HORIZONAL_TAB: + // Just accumulate the clean whitespace + i++; + break; + default: + // The character was clean, but not a whitespace + // so break the loop to continue with this character + // (we don't increment index i !!) + isAllWhitespace = false; + break; } } + } /* If there is some non-whitespace, mark that we may need * to preserve this. This is only important if we have indentation on. */ - if (i < end) + if (i < end || !isAllWhitespace) m_ispreserve = true; - -// int lengthClean; // number of clean characters in a row -// final boolean[] isAsciiClean = m_charInfo.getASCIIClean(); - - final boolean isXML10 = XMLVERSION10.equals(getVersion()); - // we've skipped the leading whitespace, now deal with the rest for (; i < end; i++) { - { - // A tight loop to skip over common clean chars - // This tight loop makes it easier for the JIT - // to optimize. - char ch2; - while (i "&" + // e.g. '<' --> "<" + writeOutCleanChars(chars, i, lastDirtyCharProcessed); + String outputStringForChar = m_charInfo.getOutputStringForChar(ch); + writer.write(outputStringForChar); + lastDirtyCharProcessed = i; } - - final char ch = chars[i]; - /* The check for isCharacterInC0orC1Ranger and - * isNELorLSEPCharacter has been added - * to support Control Characters in XML 1.1 - */ - if (!isCharacterInC0orC1Range(ch) && - (isXML10 || !isNELorLSEPCharacter(ch)) && - (escapingNotNeeded(ch) && (!m_charInfo.isSpecialTextChar(ch))) - || ('"' == ch)) - { - ; // a character needing no special processing + else { + if (ch <= 0x1F) { + // Range 0x00 through 0x1F inclusive + // + // This covers the non-whitespace control characters + // in the range 0x1 to 0x1F inclusive. + // It also covers the whitespace control characters in the same way: + // 0x9 TAB + // 0xA NEW LINE + // 0xD CARRIAGE RETURN + // + // We also cover 0x0 ... It isn't valid + // but we will output "�" + + // The default will handle this just fine, but this + // is a little performance boost to handle the more + // common TAB, NEW-LINE, CARRIAGE-RETURN + switch (ch) { + + case CharInfo.S_HORIZONAL_TAB: + // Leave whitespace TAB as a real character + break; + case CharInfo.S_LINEFEED: + lastDirtyCharProcessed = processLineFeed(chars, i, lastDirtyCharProcessed, writer); + break; + case CharInfo.S_CARRIAGERETURN: + writeOutCleanChars(chars, i, lastDirtyCharProcessed); + writer.write(" "); + lastDirtyCharProcessed = i; + // Leave whitespace carriage return as a real character + break; + default: + writeOutCleanChars(chars, i, lastDirtyCharProcessed); + writer.write("&#"); + writer.write(Integer.toString(ch)); + writer.write(';'); + lastDirtyCharProcessed = i; + break; + } - else - { - lastDirty = processDirty(chars,end, i, ch, lastDirty, true); - i = lastDirty; + } + else if (ch < 0x7F) { + // Range 0x20 through 0x7E inclusive + // Normal ASCII chars, do nothing, just add it to + // the clean characters + + } + else if (ch <= 0x9F){ + // Range 0x7F through 0x9F inclusive + // More control characters, including NEL (0x85) + writeOutCleanChars(chars, i, lastDirtyCharProcessed); + writer.write("&#"); + writer.write(Integer.toString(ch)); + writer.write(';'); + lastDirtyCharProcessed = i; + } + else if (ch == CharInfo.S_LINE_SEPARATOR) { + // LINE SEPARATOR + writeOutCleanChars(chars, i, lastDirtyCharProcessed); + writer.write("
"); + lastDirtyCharProcessed = i; + } + else if (m_encodingInfo.isInEncoding(ch)) { + // If the character is in the encoding, and + // not in the normal ASCII range, we also + // just leave it get added on to the clean characters + + } + else { + // This is a fallback plan, we should never get here + // but if the character wasn't previously handled + // (i.e. isn't in the encoding, etc.) then what + // should we do? We choose to write out an entity + writeOutCleanChars(chars, i, lastDirtyCharProcessed); + writer.write("&#"); + writer.write(Integer.toString(ch)); + writer.write(';'); + lastDirtyCharProcessed = i; + } } } // we've reached the end. Any clean characters at the // end of the array than need to be written out? - startClean = lastDirty + 1; + startClean = lastDirtyCharProcessed + 1; if (i > startClean) { int lengthClean = i - startClean; @@ -1515,6 +1606,32 @@ if (m_tracer != null) super.fireCharEvent(chars, start, length); } + + private int processLineFeed(final char[] chars, int i, int lastProcessed, final Writer writer) throws IOException { + if (!m_lineSepUse + || (m_lineSepLen ==1 && m_lineSep[0] == CharInfo.S_LINEFEED)){ + // We are leaving the new-line alone, and it is just + // being added to the 'clean' characters, + // so the last dirty character processed remains unchanged + } + else { + writeOutCleanChars(chars, i, lastProcessed); + writer.write(m_lineSep, 0, m_lineSepLen); + lastProcessed = i; + } + return lastProcessed; + } + + private void writeOutCleanChars(final char[] chars, int i, int lastProcessed) throws IOException { + int startClean; + startClean = lastProcessed + 1; + if (startClean < i) + { + int lengthClean = i - startClean; + m_writer.write(chars, startClean, lengthClean); + } + } + /** * This method checks if a given character is between C0 or C1 range * of Control characters. @@ -1634,7 +1751,7 @@ * * @throws org.xml.sax.SAXException */ - protected int accumDefaultEscape( + private int accumDefaultEscape( Writer writer, char ch, int i, @@ -1698,16 +1815,15 @@ * to write it out as Numeric Character Reference(NCR) regardless of XML Version * being used for output document. */ - if (isCharacterInC0orC1Range(ch) || - (XMLVERSION11.equals(getVersion()) && isNELorLSEPCharacter(ch))) + if (isCharacterInC0orC1Range(ch) || isNELorLSEPCharacter(ch)) { writer.write("&#"); writer.write(Integer.toString(ch)); writer.write(';'); } else if ((!escapingNotNeeded(ch) || - ( (fromTextNode && m_charInfo.isSpecialTextChar(ch)) - || (!fromTextNode && m_charInfo.isSpecialAttrChar(ch)))) + ( (fromTextNode && m_charInfo.shouldMapTextChar(ch)) + || (!fromTextNode && m_charInfo.shouldMapAttrChar(ch)))) && m_elemContext.m_currentElemDepth > 0) { writer.write("&#"); @@ -1971,28 +2087,86 @@ string.getChars(0,len, m_attrBuff, 0); final char[] stringChars = m_attrBuff; - for (int i = 0; i < len; ) + for (int i = 0; i < len;) { char ch = stringChars[i]; - if (escapingNotNeeded(ch) && (!m_charInfo.isSpecialAttrChar(ch))) - { - writer.write(ch); - i++; - } - else - { // I guess the parser doesn't normalize cr/lf in attributes. -sb -// if ((CharInfo.S_CARRIAGERETURN == ch) -// && ((i + 1) < len) -// && (CharInfo.S_LINEFEED == stringChars[i + 1])) -// { -// i++; -// ch = CharInfo.S_LINEFEED; -// } - + + if (m_charInfo.shouldMapAttrChar(ch) || !(escapingNotNeeded(ch))) { + // The character is supposed to be replaced by a String + // e.g. '&' --> "&" + // e.g. '<' --> "<" i = accumDefaultEscape(writer, ch, i, stringChars, len, false, true); } + else { + i++; + if (0x0 <= ch && ch <= 0x1F) { + // Range 0x00 through 0x1F inclusive + // This covers the non-whitespace control characters + // in the range 0x1 to 0x1F inclusive. + // It also covers the whitespace control characters in the same way: + // 0x9 TAB + // 0xA NEW LINE + // 0xD CARRIAGE RETURN + // + // We also cover 0x0 ... It isn't valid + // but we will output "�" + + // The default will handle this just fine, but this + // is a little performance boost to handle the more + // common TAB, NEW-LINE, CARRIAGE-RETURN + switch (ch) { + + case CharInfo.S_HORIZONAL_TAB: + writer.write(" "); + break; + case CharInfo.S_LINEFEED: + writer.write(" "); + break; + case CharInfo.S_CARRIAGERETURN: + writer.write(" "); + break; + default: + writer.write("&#"); + writer.write(Integer.toString(ch)); + writer.write(';'); + break; + } - + } + else if (ch < 0x7F) { + // Range 0x20 through 0x7E inclusive + // Normal ASCII chars + writer.write(ch); + } + else if (ch <= 0x9F){ + // Range 0x7F through 0x9F inclusive + // More control characters + writer.write("&#"); + writer.write(Integer.toString(ch)); + writer.write(';'); + } + else if (ch == CharInfo.S_LINE_SEPARATOR) { + // LINE SEPARATOR + writer.write("
"); + } + else if (m_encodingInfo.isInEncoding(ch)) { + // If the character is in the encoding, and + // not in the normal ASCII range, we also + // just write it out + writer.write(ch); + } + else { + // This is a fallback plan, we should never get here + // but if the character wasn't previously handled + // (i.e. isn't in the encoding, etc.) then what + // should we do? We choose to write out a character ref + writer.write("&#"); + writer.write(Integer.toString(ch)); + writer.write(';'); + } + + } + } } /** @@ -2219,13 +2393,17 @@ try { - if (shouldIndent()) + if (shouldIndent() && m_isStandalone) indent(); final int limit = start + length; boolean wasDash = false; if (m_cdataTagOpen) closeCDATA(); + + if (shouldIndent() && !m_isStandalone) + indent(); + final java.io.Writer writer = m_writer; writer.write(COMMENT_BEGIN); // Detect occurrences of two consecutive dashes, handle as necessary. @@ -2258,6 +2436,15 @@ throw new SAXException(e); } + /* + * Don't write out any indentation whitespace now, + * because there may be non-whitespace text after this. + * + * Simply mark that at this point if we do decide + * to indent that we should + * add a newline on the end of the current line before + * the indentation at the start of the next line. + */ m_startNewLine = true; // time to generate comment event if (m_tracer != null) @@ -2506,7 +2693,7 @@ */ protected boolean shouldIndent() { - return m_doIndent && (!m_ispreserve && !m_isprevtext); + return m_doIndent && (!m_ispreserve && !m_isprevtext) && (m_elemContext.m_currentElemDepth > 0 || m_isStandalone); } /** @@ -2749,6 +2936,14 @@ closeCDATA(); m_cdataTagOpen = false; } + if (m_writer != null) { + try { + m_writer.flush(); + } + catch(IOException e) { + // what? me worry? + } + } } public void setContentHandler(ContentHandler ch) diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xml/internal/serializer/ToXMLSAXHandler.java --- a/src/com/sun/org/apache/xml/internal/serializer/ToXMLSAXHandler.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xml/internal/serializer/ToXMLSAXHandler.java Tue Apr 17 11:17:59 2012 -0700 @@ -50,7 +50,7 @@ /** * Keeps track of whether output escaping is currently enabled */ - protected boolean m_escapeSetting = false; + protected boolean m_escapeSetting = true; public ToXMLSAXHandler() { @@ -772,7 +772,7 @@ */ private void resetToXMLSAXHandler() { - this.m_escapeSetting = false; + this.m_escapeSetting = true; } } diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xml/internal/serializer/ToXMLStream.java --- a/src/com/sun/org/apache/xml/internal/serializer/ToXMLStream.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xml/internal/serializer/ToXMLStream.java Tue Apr 17 11:17:59 2012 -0700 @@ -56,7 +56,7 @@ * Map that tells which XML characters should have special treatment, and it * provides character to entity name lookup. */ - private static CharInfo m_xmlcharInfo = + private CharInfo m_xmlcharInfo = // new CharInfo(CharInfo.XML_ENTITIES_RESOURCE); CharInfo.getCharInfo(CharInfo.XML_ENTITIES_RESOURCE, Method.XML); @@ -160,8 +160,23 @@ writer.write('\"'); writer.write(standalone); writer.write("?>"); - if (m_doIndent) - writer.write(m_lineSep, 0, m_lineSepLen); + if (m_doIndent) { + if (m_standaloneWasSpecified + || getDoctypePublic() != null + || getDoctypeSystem() != null + || m_isStandalone) { + // We almost never put a newline after the XML + // header because this XML could be used as + // an extenal general parsed entity + // and we don't know the context into which it + // will be used in the future. Only when + // standalone, or a doctype system or public is + // specified are we free to insert a new line + // after the header. Is it even worth bothering + // in these rare cases? + writer.write(m_lineSep, 0, m_lineSepLen); + } + } } catch(IOException e) { @@ -312,12 +327,22 @@ writer.write('?'); writer.write('>'); - // Always output a newline char if not inside of an - // element. The whitespace is not significant in that - // case. - if (m_elemContext.m_currentElemDepth <= 0) + /** + * Before Xalan 1497, a newline char was printed out if not inside of an + * element. The whitespace is not significant if the output is standalone + */ + if (m_elemContext.m_currentElemDepth <= 0 && m_isStandalone) writer.write(m_lineSep, 0, m_lineSepLen); + /* + * Don't write out any indentation whitespace now, + * because there may be non-whitespace text after this. + * + * Simply mark that at this point if we do decide + * to indent that we should + * add a newline on the end of the current line before + * the indentation at the start of the next line. + */ m_startNewLine = true; } catch(IOException e) diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xml/internal/serializer/WriterToUTF8Buffered.java --- a/src/com/sun/org/apache/xml/internal/serializer/WriterToUTF8Buffered.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xml/internal/serializer/WriterToUTF8Buffered.java Tue Apr 17 11:17:59 2012 -0700 @@ -204,10 +204,10 @@ */ int split = length/CHARS_MAX; final int chunks; - if (split > 1) + if (length % CHARS_MAX > 0) + chunks = split + 1; + else chunks = split; - else - chunks = 2; int end_chunk = start; for (int chunk = 1; chunk <= chunks; chunk++) { @@ -339,10 +339,10 @@ final int start = 0; int split = length/CHARS_MAX; final int chunks; - if (split > 1) + if (length % CHARS_MAX > 0) + chunks = split + 1; + else chunks = split; - else - chunks = 2; int end_chunk = 0; for (int chunk = 1; chunk <= chunks; chunk++) { diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xml/internal/serializer/utils/URI.java --- a/src/com/sun/org/apache/xml/internal/serializer/utils/URI.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xml/internal/serializer/utils/URI.java Tue Apr 17 11:17:59 2012 -0700 @@ -502,7 +502,7 @@ // if we get to this point, we need to resolve relative path // RFC 2396 5.2 #6 - String path = new String(); + String path = ""; String basePath = p_base.getPath(); // 6a - get all but the last segment of the base URI path diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xml/internal/utils/ObjectFactory.java --- a/src/com/sun/org/apache/xml/internal/utils/ObjectFactory.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,658 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2001-2004 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. - */ -/* - * $Id: ObjectFactory.java,v 1.3 2005/09/28 13:49:20 pvedula Exp $ - */ - -package com.sun.org.apache.xml.internal.utils; - -import java.io.InputStream; -import java.io.IOException; -import java.io.File; -import java.io.FileInputStream; - -import java.util.Properties; -import java.io.BufferedReader; -import java.io.InputStreamReader; - -/** - * 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. - *

- * This code is designed to implement the JAXP 1.1 spec pluggability - * feature and is designed to run on JDK version 1.1 and - * later, and to compile on JDK 1.2 and onward. - * The code also runs both as part of an unbundled jar file and - * when bundled as part of the JDK. - *

- * This class was moved from the javax.xml.parsers.ObjectFactory - * class and modified to be used as a general utility for creating objects - * dynamically. - * - * @version $Id: ObjectFactory.java,v 1.8 2008/04/02 00:41:01 joehw Exp $ - */ -class ObjectFactory { - - // - // Constants - // - - // name of default properties file to look for in JDK's jre/lib directory - private static final String DEFAULT_PROPERTIES_FILENAME = - "xalan.properties"; - - private static final String SERVICES_PATH = "META-INF/services/"; - - /** Set to true for debugging */ - private static final boolean DEBUG = false; - - /** cache the contents of the xalan.properties file. - * Until an attempt has been made to read this file, this will - * be null; if the file does not exist or we encounter some other error - * during the read, this will be empty. - */ - private static Properties fXalanProperties = null; - - /*** - * Cache the time stamp of the xalan.properties file so - * that we know if it's been modified and can invalidate - * the cache when necessary. - */ - private static long fLastModified = -1; - - // - // Public static methods - // - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *

    - *
  1. query the system property using System.getProperty - *
  2. read META-INF/services/factoryId file - *
  3. use fallback classname - *
- * - * @return instance of factory, 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 no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Object createObject(String factoryId, String fallbackClassName) - throws ConfigurationError { - return createObject(factoryId, null, fallbackClassName); - } // createObject(String,String):Object - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return instance of factory, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Object createObject(String factoryId, - String propertiesFilename, - String fallbackClassName) - throws ConfigurationError - { - Class factoryClass = lookUpFactoryClass(factoryId, - propertiesFilename, - fallbackClassName); - - if (factoryClass == null) { - throw new ConfigurationError( - "Provider for " + factoryId + " cannot be found", null); - } - - try{ - Object instance = factoryClass.newInstance(); - if (DEBUG) debugPrintln("created new instance of factory " + factoryId); - return instance; - } catch (Exception x) { - throw new ConfigurationError( - "Provider for factory " + factoryId - + " could not be instantiated: " + x, x); - } - } // createObject(String,String,String):Object - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return Class object of factory, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * - * @exception ObjectFactory.ConfigurationError - */ - static Class lookUpFactoryClass(String factoryId) - throws ConfigurationError - { - return lookUpFactoryClass(factoryId, null, null); - } // lookUpFactoryClass(String):Class - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return Class object that provides factory service, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Class lookUpFactoryClass(String factoryId, - String propertiesFilename, - String fallbackClassName) - throws ConfigurationError - { - String factoryClassName = lookUpFactoryClassName(factoryId, - propertiesFilename, - fallbackClassName); - ClassLoader cl = findClassLoader(); - - if (factoryClassName == null) { - factoryClassName = fallbackClassName; - } - - // assert(className != null); - try{ - Class providerClass = findProviderClass(factoryClassName, - cl, - true); - if (DEBUG) debugPrintln("created new instance of " + providerClass + - " using ClassLoader: " + cl); - return providerClass; - } catch (ClassNotFoundException x) { - throw new ConfigurationError( - "Provider " + factoryClassName + " not found", x); - } catch (Exception x) { - throw new ConfigurationError( - "Provider "+factoryClassName+" could not be instantiated: "+x, - x); - } - } // lookUpFactoryClass(String,String,String):Class - - /** - * Finds the name of the required implementation class in the specified - * order. The specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return name of class that provides factory service, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static String lookUpFactoryClassName(String factoryId, - String propertiesFilename, - String fallbackClassName) - { - SecuritySupport ss = SecuritySupport.getInstance(); - - // Use the system property first - try { - String systemProp = ss.getSystemProperty(factoryId); - if (systemProp != null) { - if (DEBUG) debugPrintln("found system property, value=" + systemProp); - return systemProp; - } - } catch (SecurityException se) { - // Ignore and continue w/ next location - } - - // Try to read from propertiesFilename, or - // $java.home/lib/xalan.properties - String factoryClassName = null; - // no properties file name specified; use - // $JAVA_HOME/lib/xalan.properties: - if (propertiesFilename == null) { - File propertiesFile = null; - boolean propertiesFileExists = false; - try { - String javah = ss.getSystemProperty("java.home"); - propertiesFilename = javah + File.separator + - "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME; - propertiesFile = new File(propertiesFilename); - propertiesFileExists = ss.getFileExists(propertiesFile); - } catch (SecurityException e) { - // try again... - fLastModified = -1; - fXalanProperties = null; - } - - synchronized (ObjectFactory.class) { - boolean loadProperties = false; - FileInputStream fis = null; - try { - // file existed last time - if(fLastModified >= 0) { - if(propertiesFileExists && - (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) { - loadProperties = true; - } else { - // file has stopped existing... - if(!propertiesFileExists) { - fLastModified = -1; - fXalanProperties = null; - } // else, file wasn't modified! - } - } else { - // file has started to exist: - if(propertiesFileExists) { - loadProperties = true; - fLastModified = ss.getLastModified(propertiesFile); - } // else, nothing's changed - } - if(loadProperties) { - // must never have attempted to read xalan.properties - // before (or it's outdeated) - fXalanProperties = new Properties(); - fis = ss.getFileInputStream(propertiesFile); - fXalanProperties.load(fis); - } - } catch (Exception x) { - fXalanProperties = null; - fLastModified = -1; - // assert(x instanceof FileNotFoundException - // || x instanceof SecurityException) - // In both cases, ignore and continue w/ next location - } - finally { - // try to close the input stream if one was opened. - if (fis != null) { - try { - fis.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - } - } - if(fXalanProperties != null) { - factoryClassName = fXalanProperties.getProperty(factoryId); - } - } else { - FileInputStream fis = null; - try { - fis = ss.getFileInputStream(new File(propertiesFilename)); - Properties props = new Properties(); - props.load(fis); - factoryClassName = props.getProperty(factoryId); - } catch (Exception x) { - // assert(x instanceof FileNotFoundException - // || x instanceof SecurityException) - // In both cases, ignore and continue w/ next location - } - finally { - // try to close the input stream if one was opened. - if (fis != null) { - try { - fis.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - } - } - if (factoryClassName != null) { - if (DEBUG) debugPrintln("found in " + propertiesFilename + ", value=" - + factoryClassName); - return factoryClassName; - } - - // Try Jar Service Provider Mechanism - return findJarServiceProviderName(factoryId); - } // lookUpFactoryClass(String,String):String - - // - // Private static methods - // - - /** Prints a message to standard error if debugging is enabled. */ - private static void debugPrintln(String msg) { - if (DEBUG) { - System.err.println("JAXP: " + msg); - } - } // debugPrintln(String) - - /** - * Figure out which ClassLoader to use. For JDK 1.2 and later use - * the context ClassLoader. - */ - static ClassLoader findClassLoader() - 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 context = ss.getContextClassLoader(); - ClassLoader system = ss.getSystemClassLoader(); - - ClassLoader chain = system; - while (true) { - if (context == chain) { - // Assert: we are on JDK 1.1 or we have no Context ClassLoader - // or any Context ClassLoader in chain of system classloader - // (including extension ClassLoader) so extend to widest - // ClassLoader (always look in system ClassLoader if Xalan - // is in boot/extension/system classpath and in current - // ClassLoader otherwise); normal classloaders delegate - // back to system ClassLoader first so this widening doesn't - // change the fact that context ClassLoader will be consulted - ClassLoader current = ObjectFactory.class.getClassLoader(); - - chain = system; - while (true) { - if (current == chain) { - // Assert: Current ClassLoader in chain of - // boot/extension/system ClassLoaders - return system; - } - if (chain == null) { - break; - } - chain = ss.getParentClassLoader(chain); - } - - // Assert: Current ClassLoader not in chain of - // boot/extension/system ClassLoaders - return current; - } - - if (chain == null) { - // boot ClassLoader reached - break; - } - - // Check for any extension ClassLoaders in chain up to - // boot ClassLoader - chain = ss.getParentClassLoader(chain); - }; - - // Assert: Context ClassLoader not in chain of - // boot/extension/system ClassLoaders - return context; - } // findClassLoader():ClassLoader - - /** - * Create an instance of a class using the specified ClassLoader - */ - static Object newInstance(String className, ClassLoader cl, - boolean doFallback) - throws ConfigurationError - { - // assert(className != null); - try{ - Class providerClass = findProviderClass(className, cl, doFallback); - Object instance = providerClass.newInstance(); - if (DEBUG) debugPrintln("created new instance of " + providerClass + - " using ClassLoader: " + cl); - return instance; - } catch (ClassNotFoundException x) { - throw new ConfigurationError( - "Provider " + className + " not found", x); - } catch (Exception x) { - throw new ConfigurationError( - "Provider " + className + " could not be instantiated: " + x, - x); - } - } - - /** - * Find a Class using the specified ClassLoader - */ - static Class findProviderClass(String className, ClassLoader cl, - boolean doFallback) - throws ClassNotFoundException, ConfigurationError - { - //throw security exception if the calling thread is not allowed to access the - //class. Restrict the access to the package classes as specified in java.security policy. - SecurityManager security = System.getSecurityManager(); - try{ - if (security != null){ - final int lastDot = className.lastIndexOf("."); - String packageName = className; - if (lastDot != -1) packageName = className.substring(0, lastDot); - security.checkPackageAccess(packageName); - } - }catch(SecurityException e){ - throw e; - } - - Class providerClass; - 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 { - try { - providerClass = cl.loadClass(className); - } catch (ClassNotFoundException x) { - if (doFallback) { - // Fall back to current classloader - ClassLoader current = ObjectFactory.class.getClassLoader(); - if (current == null) { - providerClass = Class.forName(className); - } else if (cl != current) { - cl = current; - providerClass = cl.loadClass(className); - } else { - throw x; - } - } else { - throw x; - } - } - } - - return providerClass; - } - - /** - * Find the name of service provider using Jar Service Provider Mechanism - * - * @return instance of provider class if found or null - */ - private static String findJarServiceProviderName(String factoryId) - { - SecuritySupport ss = SecuritySupport.getInstance(); - String serviceId = SERVICES_PATH + factoryId; - InputStream is = null; - - // First try the Context ClassLoader - ClassLoader cl = findClassLoader(); - - is = ss.getResourceAsStream(cl, serviceId); - - // If no provider found then try the current ClassLoader - if (is == null) { - ClassLoader current = ObjectFactory.class.getClassLoader(); - if (cl != current) { - cl = current; - is = ss.getResourceAsStream(cl, serviceId); - } - } - - if (is == null) { - // No provider found - return null; - } - - if (DEBUG) debugPrintln("found jar resource=" + serviceId + - " using ClassLoader: " + cl); - - // 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)); - } - - String factoryClassName = null; - try { - // XXX Does not handle all possible input as specified by the - // Jar Service Provider specification - factoryClassName = rd.readLine(); - } catch (IOException x) { - // No provider found - return null; - } - finally { - try { - // try to close the reader. - rd.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - - if (factoryClassName != null && - ! "".equals(factoryClassName)) { - if (DEBUG) debugPrintln("found in resource, value=" - + factoryClassName); - - // Note: here we do not want to fall back to the current - // 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. - return factoryClassName; - } - - // No provider found - return null; - } - - // - // Classes - // - - /** - * A configuration error. - */ - static class ConfigurationError - extends Error { - static final long serialVersionUID = 2036619216663421552L; - // - // Data - // - - /** Exception. */ - private Exception exception; - - // - // Constructors - // - - /** - * Construct a new instance with the specified detail string and - * exception. - */ - ConfigurationError(String msg, Exception x) { - super(msg); - this.exception = x; - } // (String,Exception) - - // - // Public methods - // - - /** Returns the exception associated to this error. */ - Exception getException() { - return exception; - } // getException():Exception - - } // class ConfigurationError - -} // class ObjectFactory diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xml/internal/utils/ObjectPool.java --- a/src/com/sun/org/apache/xml/internal/utils/ObjectPool.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xml/internal/utils/ObjectPool.java Tue Apr 17 11:17:59 2012 -0700 @@ -22,10 +22,11 @@ */ package com.sun.org.apache.xml.internal.utils; -import java.util.Vector; +import java.util.ArrayList; import com.sun.org.apache.xml.internal.res.XMLErrorResources; import com.sun.org.apache.xml.internal.res.XMLMessages; +import com.sun.org.apache.xalan.internal.utils.ObjectFactory; /** @@ -40,9 +41,9 @@ * @serial */ private final Class objectType; - /** Vector of given objects this points to. + /** Stack of given objects this points to. * @serial */ - private final Vector freeStack; + private final ArrayList freeStack; /** * Constructor ObjectPool @@ -52,7 +53,7 @@ public ObjectPool(Class type) { objectType = type; - freeStack = new Vector(); + freeStack = new ArrayList(); } /** @@ -64,14 +65,13 @@ { try { - objectType = ObjectFactory.findProviderClass( - className, ObjectFactory.findClassLoader(), true); + objectType = ObjectFactory.findProviderClass(className, true); } catch(ClassNotFoundException cnfe) { throw new WrappedRuntimeException(cnfe); } - freeStack = new Vector(); + freeStack = new ArrayList(); } @@ -85,7 +85,7 @@ public ObjectPool(Class type, int size) { objectType = type; - freeStack = new Vector(size); + freeStack = new ArrayList(size); } /** @@ -95,7 +95,7 @@ public ObjectPool() { objectType = null; - freeStack = new Vector(); + freeStack = new ArrayList(); } /** @@ -112,10 +112,7 @@ { // Remove object from end of free pool. - Object result = freeStack.lastElement(); - - freeStack.setSize(freeStack.size() - 1); - + Object result = freeStack.remove(freeStack.size() - 1); return result; } @@ -150,10 +147,7 @@ { // Remove object from end of free pool. - Object result = freeStack.lastElement(); - - freeStack.setSize(freeStack.size() - 1); - + Object result = freeStack.remove(freeStack.size() - 1); return result; } } @@ -171,7 +165,7 @@ // Remove safety. -sb // if (objectType.isInstance(obj)) // { - freeStack.addElement(obj); + freeStack.add(obj); // } // else // { diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xml/internal/utils/SecuritySupport.java --- a/src/com/sun/org/apache/xml/internal/utils/SecuritySupport.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,127 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2002-2004 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. - */ -/* - * $Id: SecuritySupport.java,v 1.2.4.1 2005/09/15 08:15:53 suresh_emailid Exp $ - */ - -package com.sun.org.apache.xml.internal.utils; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.InputStream; - -import java.util.Properties; - -/** - * This class is duplicated for each Xalan-Java subpackage so keep it in sync. - * It is package private and therefore is not exposed as part of the Xalan-Java - * 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. - */ - static SecuritySupport getInstance() { - return (SecuritySupport)securitySupport; - } - - ClassLoader getContextClassLoader() { - return null; - } - - ClassLoader getSystemClassLoader() { - return null; - } - - ClassLoader getParentClassLoader(ClassLoader cl) { - return null; - } - - String getSystemProperty(String propName) { - return System.getProperty(propName); - } - - FileInputStream getFileInputStream(File file) - throws FileNotFoundException - { - return new FileInputStream(file); - } - - InputStream getResourceAsStream(ClassLoader cl, String name) { - InputStream ris; - if (cl == null) { - ris = ClassLoader.getSystemResourceAsStream(name); - } else { - ris = cl.getResourceAsStream(name); - } - return ris; - } - - boolean getFileExists(File f) { - return f.exists(); - } - - long getLastModified(File f) { - return f.lastModified(); - } -} diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xml/internal/utils/SecuritySupport12.java --- a/src/com/sun/org/apache/xml/internal/utils/SecuritySupport12.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,148 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2002-2004 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. - */ -/* - * $Id: SecuritySupport12.java,v 1.2.4.1 2005/09/15 08:15:53 suresh_emailid Exp $ - */ - -package com.sun.org.apache.xml.internal.utils; - -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; - -import java.util.Properties; - -/** - * This class is duplicated for each Xalan-Java subpackage so keep it in sync. - * It is package private and therefore is not exposed as part of the Xalan-Java - * API. - * - * Security related methods that only work on J2SE 1.2 and newer. - */ -class SecuritySupport12 extends SecuritySupport { - - ClassLoader getContextClassLoader() { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader cl = null; - try { - cl = Thread.currentThread().getContextClassLoader(); - } catch (SecurityException ex) { } - return cl; - } - }); - } - - ClassLoader getSystemClassLoader() { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader cl = null; - try { - cl = ClassLoader.getSystemClassLoader(); - } catch (SecurityException ex) {} - return cl; - } - }); - } - - ClassLoader getParentClassLoader(final ClassLoader cl) { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader parent = null; - try { - parent = cl.getParent(); - } catch (SecurityException ex) {} - - // eliminate loops in case of the boot - // ClassLoader returning itself as a parent - return (parent == cl) ? null : parent; - } - }); - } - - String getSystemProperty(final String propName) { - return (String) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return System.getProperty(propName); - } - }); - } - - 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(); - } - } - - 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; - } - }); - } - - boolean getFileExists(final File f) { - return ((Boolean) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return new Boolean(f.exists()); - } - })).booleanValue(); - } - - long getLastModified(final File f) { - return ((Long) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return new Long(f.lastModified()); - } - })).longValue(); - } - -} diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xml/internal/utils/TreeWalker.java --- a/src/com/sun/org/apache/xml/internal/utils/TreeWalker.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xml/internal/utils/TreeWalker.java Tue Apr 17 11:17:59 2012 -0700 @@ -153,9 +153,25 @@ */ public void traverse(Node pos) throws org.xml.sax.SAXException { - this.m_contentHandler.startDocument(); + traverseFragment(pos); + + this.m_contentHandler.endDocument(); + } + + /** + * Perform a pre-order traversal non-recursive style. + * + * In contrast to the traverse() method this method will not issue + * startDocument() and endDocument() events to the SAX listener. + * + * @param pos Node in the tree where to start traversal + * + * @throws TransformerException + */ + public void traverseFragment(Node pos) throws org.xml.sax.SAXException + { Node top = pos; while (null != pos) @@ -191,7 +207,6 @@ pos = nextNode; } - this.m_contentHandler.endDocument(); } /** diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xml/internal/utils/URI.java --- a/src/com/sun/org/apache/xml/internal/utils/URI.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xml/internal/utils/URI.java Tue Apr 17 11:17:59 2012 -0700 @@ -522,7 +522,7 @@ // if we get to this point, we need to resolve relative path // RFC 2396 5.2 #6 - String path = new String(); + String path = ""; String basePath = p_base.getPath(); // 6a - get all but the last segment of the base URI path diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java --- a/src/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java Tue Apr 17 11:17:59 2012 -0700 @@ -22,6 +22,8 @@ */ package com.sun.org.apache.xml.internal.utils; +import com.sun.org.apache.xalan.internal.utils.SecuritySupport; +import com.sun.org.apache.xalan.internal.utils.FactoryImpl; import java.util.HashMap; import javax.xml.parsers.FactoryConfigurationError; @@ -60,6 +62,7 @@ */ private HashMap m_inUse; + private boolean m_useServicesMechanism = true; /** * Hidden constructor */ @@ -69,7 +72,8 @@ /** * Retrieves the singleton reader manager */ - public static XMLReaderManager getInstance() { + public static XMLReaderManager getInstance(boolean useServicesMechanism) { + m_singletonManager.setServicesMechnism(useServicesMechanism); return m_singletonManager; } @@ -97,7 +101,7 @@ // instance of the class set in the 'org.xml.sax.driver' property reader = (XMLReader) m_readers.get(); boolean threadHasReader = (reader != null); - String factory = SecuritySupport.getInstance().getSystemProperty(property); + String factory = SecuritySupport.getSystemProperty(property); if (threadHasReader && m_inUse.get(reader) != Boolean.TRUE && ( factory == null || reader.getClass().getName().equals(factory))) { m_inUse.put(reader, Boolean.TRUE); @@ -115,7 +119,7 @@ // If unable to create an instance, let's try to use // the XMLReader from JAXP if (m_parserFactory == null) { - m_parserFactory = SAXParserFactory.newInstance(); + m_parserFactory = FactoryImpl.getSAXFactory(m_useServicesMechanism); m_parserFactory.setNamespaceAware(true); } @@ -163,4 +167,18 @@ m_inUse.remove(reader); } } + /** + * Return the state of the services mechanism feature. + */ + public boolean useServicesMechnism() { + return m_useServicesMechanism; + } + + /** + * Set the state of the services mechanism feature. + */ + public void setServicesMechnism(boolean flag) { + m_useServicesMechanism = flag; + } + } diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xml/internal/utils/XMLString.java --- a/src/com/sun/org/apache/xml/internal/utils/XMLString.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xml/internal/utils/XMLString.java Tue Apr 17 11:17:59 2012 -0700 @@ -127,7 +127,7 @@ /** * Compares this string to the specified object. * The result is true if and only if the argument is not - * null and is a String object that represents + * null and is an XMLString object that represents * the same sequence of characters as this object. * * @param anObject the object to compare this String @@ -139,6 +139,20 @@ */ public abstract boolean equals(XMLString anObject); + /** + * Compares this string to the specified String. + * The result is true if and only if the argument is not + * null and is a String object that represents + * the same sequence of characters as this object. + * + * @param anotherString the object to compare this String + * against. + * @return true if the Strings are equal; + * false otherwise. + * @see java.lang.String#compareTo(java.lang.String) + * @see java.lang.String#equalsIgnoreCase(java.lang.String) + */ + public abstract boolean equals(String anotherString); /** * Compares this string to the specified object. diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xml/internal/utils/XMLStringDefault.java --- a/src/com/sun/org/apache/xml/internal/utils/XMLStringDefault.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xml/internal/utils/XMLStringDefault.java Tue Apr 17 11:17:59 2012 -0700 @@ -152,6 +152,22 @@ } } + /** + * Compares this string to the specified String. + * The result is true if and only if the argument is not + * null and is a String object that represents + * the same sequence of characters as this object. + * + * @param obj2 the object to compare this String against. + * @return true if the Strings are equal; + * false otherwise. + * @see java.lang.String#compareTo(java.lang.String) + * @see java.lang.String#equalsIgnoreCase(java.lang.String) + */ + public boolean equals(String obj2) { + return m_str.equals(obj2); + } + /** * Compares this string to the specified object. * The result is true if and only if the argument is not diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xpath/internal/XPathContext.java --- a/src/com/sun/org/apache/xpath/internal/XPathContext.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xpath/internal/XPathContext.java Tue Apr 17 11:17:59 2012 -0700 @@ -96,6 +96,8 @@ */ private boolean m_isSecureProcessing = false; + private boolean m_useServicesMechanism = true; + /** * Though XPathContext context extends * the DTMManager, it really is a proxy for this object, which @@ -308,13 +310,14 @@ */ public XPathContext() { - m_prefixResolvers.push(null); - m_currentNodes.push(DTM.NULL); - m_currentExpressionNodes.push(DTM.NULL); - m_saxLocations.push(null); + this(true); } + public XPathContext(boolean useServicesMechanism) { + init(useServicesMechanism); + } /** + **This constructor doesn't seem to be used anywhere -- huizhe wang** * Create an XPathContext instance. * @param owner Value that can be retrieved via the getOwnerObject() method. * @see #getOwnerObject @@ -326,10 +329,18 @@ m_ownerGetErrorListener = m_owner.getClass().getMethod("getErrorListener", new Class[] {}); } catch (NoSuchMethodException nsme) {} + init(true); + } + + private void init(boolean useServicesMechanism) { m_prefixResolvers.push(null); m_currentNodes.push(DTM.NULL); m_currentExpressionNodes.push(DTM.NULL); m_saxLocations.push(null); + m_useServicesMechanism = useServicesMechanism; + m_dtmManager = DTMManager.newInstance( + com.sun.org.apache.xpath.internal.objects.XMLStringFactoryImpl.getFactory(), + m_useServicesMechanism); } /** @@ -352,7 +363,8 @@ m_dtmManager = DTMManager.newInstance( - com.sun.org.apache.xpath.internal.objects.XMLStringFactoryImpl.getFactory()); + com.sun.org.apache.xpath.internal.objects.XMLStringFactoryImpl.getFactory(), + m_useServicesMechanism); m_saxLocations.removeAllElements(); m_axesIteratorStack.removeAllElements(); @@ -1098,6 +1110,19 @@ { return XPathContext.this.getErrorListener(); } + /** + * Return the state of the services mechanism feature. + */ + public boolean useServicesMechnism() { + return m_useServicesMechanism; + } + + /** + * Set the state of the services mechanism feature. + */ + public void setServicesMechnism(boolean flag) { + m_useServicesMechanism = flag; + } /** * Get the value of a node as a number. diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xpath/internal/axes/AxesWalker.java --- a/src/com/sun/org/apache/xpath/internal/axes/AxesWalker.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xpath/internal/axes/AxesWalker.java Tue Apr 17 11:17:59 2012 -0700 @@ -427,7 +427,7 @@ return -1; } - walker.setPredicateCount(walker.getPredicateCount() - 1); + walker.setPredicateCount(m_predicateIndex); walker.setNextWalker(null); walker.setPrevWalker(null); diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xpath/internal/axes/BasicTestIterator.java --- a/src/com/sun/org/apache/xpath/internal/axes/BasicTestIterator.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xpath/internal/axes/BasicTestIterator.java Tue Apr 17 11:17:59 2012 -0700 @@ -27,6 +27,7 @@ import com.sun.org.apache.xml.internal.dtm.DTMIterator; import com.sun.org.apache.xml.internal.utils.PrefixResolver; import com.sun.org.apache.xpath.internal.compiler.Compiler; +import com.sun.org.apache.xpath.internal.compiler.OpMap; /** * Base for iterators that handle predicates. Does the basic next @@ -76,7 +77,7 @@ { super(compiler, opPos, analysis, false); - int firstStepPos = compiler.getFirstChildPos(opPos); + int firstStepPos = OpMap.getFirstChildPos(opPos); int whatToShow = compiler.getWhatToShow(firstStepPos); if ((0 == (whatToShow diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xpath/internal/axes/DescendantIterator.java --- a/src/com/sun/org/apache/xpath/internal/axes/DescendantIterator.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xpath/internal/axes/DescendantIterator.java Tue Apr 17 11:17:59 2012 -0700 @@ -31,7 +31,9 @@ import com.sun.org.apache.xpath.internal.XPathContext; import com.sun.org.apache.xpath.internal.compiler.Compiler; import com.sun.org.apache.xpath.internal.compiler.OpCodes; +import com.sun.org.apache.xpath.internal.compiler.OpMap; import com.sun.org.apache.xpath.internal.patterns.NodeTest; +import org.w3c.dom.DOMException; /** * This class implements an optimized iterator for @@ -57,7 +59,7 @@ super(compiler, opPos, analysis, false); - int firstStepPos = compiler.getFirstChildPos(opPos); + int firstStepPos = OpMap.getFirstChildPos(opPos); int stepType = compiler.getOp(firstStepPos); boolean orSelf = (OpCodes.FROM_DESCENDANTS_OR_SELF == stepType); diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xpath/internal/axes/IteratorPool.java --- a/src/com/sun/org/apache/xpath/internal/axes/IteratorPool.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xpath/internal/axes/IteratorPool.java Tue Apr 17 11:17:59 2012 -0700 @@ -22,7 +22,7 @@ */ package com.sun.org.apache.xpath.internal.axes; -import java.util.Vector; +import java.util.ArrayList; import com.sun.org.apache.xml.internal.dtm.DTMIterator; import com.sun.org.apache.xml.internal.utils.WrappedRuntimeException; @@ -31,17 +31,19 @@ * Pool of object of a given type to pick from to help memory usage * @xsl.usage internal */ -public class IteratorPool implements java.io.Serializable +public final class IteratorPool implements java.io.Serializable { static final long serialVersionUID = -460927331149566998L; - /** Type of objects in this pool. - * @serial */ + /** + * Type of objects in this pool. + */ private final DTMIterator m_orig; - /** Vector of given objects this points to. - * @serial */ - private final Vector m_freeStack; + /** + * Stack of given objects this points to. + */ + private final ArrayList m_freeStack; /** * Constructor IteratorPool @@ -51,7 +53,7 @@ public IteratorPool(DTMIterator original) { m_orig = original; - m_freeStack = new Vector(); + m_freeStack = new ArrayList(); } /** @@ -72,10 +74,7 @@ else { // Remove object from end of free pool. - DTMIterator result = (DTMIterator)m_freeStack.lastElement(); - - m_freeStack.setSize(m_freeStack.size() - 1); - + DTMIterator result = (DTMIterator)m_freeStack.remove(m_freeStack.size() - 1); return result; } } @@ -104,10 +103,7 @@ else { // Remove object from end of free pool. - DTMIterator result = (DTMIterator)m_freeStack.lastElement(); - - m_freeStack.setSize(m_freeStack.size() - 1); - + DTMIterator result = (DTMIterator)m_freeStack.remove(m_freeStack.size() - 1); return result; } } @@ -120,6 +116,6 @@ */ public synchronized void freeInstance(DTMIterator obj) { - m_freeStack.addElement(obj); + m_freeStack.add(obj); } } diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xpath/internal/axes/MatchPatternIterator.java --- a/src/com/sun/org/apache/xpath/internal/axes/MatchPatternIterator.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xpath/internal/axes/MatchPatternIterator.java Tue Apr 17 11:17:59 2012 -0700 @@ -28,6 +28,7 @@ import com.sun.org.apache.xml.internal.dtm.DTMIterator; import com.sun.org.apache.xpath.internal.XPathContext; import com.sun.org.apache.xpath.internal.compiler.Compiler; +import com.sun.org.apache.xpath.internal.compiler.OpMap; import com.sun.org.apache.xpath.internal.objects.XObject; import com.sun.org.apache.xpath.internal.patterns.NodeTest; import com.sun.org.apache.xpath.internal.patterns.StepPattern; @@ -78,7 +79,7 @@ super(compiler, opPos, analysis, false); - int firstStepPos = compiler.getFirstChildPos(opPos); + int firstStepPos = OpMap.getFirstChildPos(opPos); m_pattern = WalkerFactory.loadSteps(this, compiler, firstStepPos, 0); diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xpath/internal/axes/OneStepIterator.java --- a/src/com/sun/org/apache/xpath/internal/axes/OneStepIterator.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xpath/internal/axes/OneStepIterator.java Tue Apr 17 11:17:59 2012 -0700 @@ -29,6 +29,7 @@ import com.sun.org.apache.xpath.internal.Expression; import com.sun.org.apache.xpath.internal.XPathContext; import com.sun.org.apache.xpath.internal.compiler.Compiler; +import com.sun.org.apache.xpath.internal.compiler.OpMap; /** * This class implements a general iterator for @@ -58,7 +59,7 @@ throws javax.xml.transform.TransformerException { super(compiler, opPos, analysis); - int firstStepPos = compiler.getFirstChildPos(opPos); + int firstStepPos = OpMap.getFirstChildPos(opPos); m_axis = WalkerFactory.getAxisFromStep(compiler, firstStepPos); diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xpath/internal/axes/OneStepIteratorForward.java --- a/src/com/sun/org/apache/xpath/internal/axes/OneStepIteratorForward.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xpath/internal/axes/OneStepIteratorForward.java Tue Apr 17 11:17:59 2012 -0700 @@ -26,6 +26,7 @@ import com.sun.org.apache.xml.internal.dtm.DTMFilter; import com.sun.org.apache.xpath.internal.Expression; import com.sun.org.apache.xpath.internal.compiler.Compiler; +import com.sun.org.apache.xpath.internal.compiler.OpMap; /** * This class implements a general iterator for @@ -54,7 +55,7 @@ throws javax.xml.transform.TransformerException { super(compiler, opPos, analysis); - int firstStepPos = compiler.getFirstChildPos(opPos); + int firstStepPos = OpMap.getFirstChildPos(opPos); m_axis = WalkerFactory.getAxisFromStep(compiler, firstStepPos); diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xpath/internal/axes/UnionPathIterator.java --- a/src/com/sun/org/apache/xpath/internal/axes/UnionPathIterator.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xpath/internal/axes/UnionPathIterator.java Tue Apr 17 11:17:59 2012 -0700 @@ -30,6 +30,7 @@ import com.sun.org.apache.xpath.internal.XPathVisitor; import com.sun.org.apache.xpath.internal.compiler.Compiler; import com.sun.org.apache.xpath.internal.compiler.OpCodes; +import com.sun.org.apache.xpath.internal.compiler.OpMap; /** * This class extends NodeSetDTM, which implements DTMIterator, @@ -160,7 +161,7 @@ super(); - opPos = compiler.getFirstChildPos(opPos); + opPos = OpMap.getFirstChildPos(opPos); loadLocationPaths(compiler, opPos, 0); } diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xpath/internal/axes/WalkerFactory.java --- a/src/com/sun/org/apache/xpath/internal/axes/WalkerFactory.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xpath/internal/axes/WalkerFactory.java Tue Apr 17 11:17:59 2012 -0700 @@ -30,6 +30,7 @@ import com.sun.org.apache.xpath.internal.compiler.Compiler; import com.sun.org.apache.xpath.internal.compiler.FunctionTable; import com.sun.org.apache.xpath.internal.compiler.OpCodes; +import com.sun.org.apache.xpath.internal.compiler.OpMap; import com.sun.org.apache.xpath.internal.objects.XNumber; import com.sun.org.apache.xpath.internal.patterns.ContextMatchStepPattern; import com.sun.org.apache.xpath.internal.patterns.FunctionPattern; @@ -162,7 +163,7 @@ throws javax.xml.transform.TransformerException { - int firstStepPos = compiler.getFirstChildPos(opPos); + int firstStepPos = OpMap.getFirstChildPos(opPos); int analysis = analyze(compiler, firstStepPos, 0); boolean isOneStep = isOneStep(analysis); DTMIterator iter; @@ -402,7 +403,7 @@ int opPos) { int endFunc = opPos + compiler.getOp(opPos + 1) - 1; - opPos = compiler.getFirstChildPos(opPos); + opPos = OpMap.getFirstChildPos(opPos); int funcID = compiler.getOp(opPos); // System.out.println("funcID: "+funcID); // System.out.println("opPos: "+opPos); @@ -453,7 +454,7 @@ case OpCodes.OP_LT: case OpCodes.OP_LTE: case OpCodes.OP_EQUALS: - int leftPos = compiler.getFirstChildPos(op); + int leftPos = OpMap.getFirstChildPos(op); int rightPos = compiler.getNextOpPos(leftPos); isProx = isProximateInnerExpr(compiler, leftPos); if(isProx) @@ -521,7 +522,7 @@ case OpCodes.OP_LT: case OpCodes.OP_LTE: case OpCodes.OP_EQUALS: - int leftPos = compiler.getFirstChildPos(innerExprOpPos); + int leftPos = OpMap.getFirstChildPos(innerExprOpPos); int rightPos = compiler.getNextOpPos(leftPos); isProx = isProximateInnerExpr(compiler, leftPos); if(isProx) @@ -984,9 +985,7 @@ int stepType = compiler.getOp(opPos); boolean simpleInit = false; - int totalNumberWalkers = (analysis & BITS_COUNT); boolean prevIsOneStepDown = true; - int firstStepPos = compiler.getFirstChildPos(opPos); int whatToShow = compiler.getWhatToShow(opPos); StepPattern ai = null; @@ -1286,7 +1285,7 @@ public static String getAnalysisString(int analysis) { StringBuffer buf = new StringBuffer(); - buf.append("count: "+getStepCount(analysis)+" "); + buf.append("count: ").append(getStepCount(analysis)).append(' '); if((analysis & BIT_NODETEST_ANY) != 0) { buf.append("NTANY|"); diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xpath/internal/axes/WalkingIterator.java --- a/src/com/sun/org/apache/xpath/internal/axes/WalkingIterator.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xpath/internal/axes/WalkingIterator.java Tue Apr 17 11:17:59 2012 -0700 @@ -29,6 +29,7 @@ import com.sun.org.apache.xpath.internal.VariableStack; import com.sun.org.apache.xpath.internal.XPathVisitor; import com.sun.org.apache.xpath.internal.compiler.Compiler; +import com.sun.org.apache.xpath.internal.compiler.OpMap; /** * Location path iterator that uses Walkers. @@ -58,7 +59,7 @@ { super(compiler, opPos, analysis, shouldLoadWalkers); - int firstStepPos = compiler.getFirstChildPos(opPos); + int firstStepPos = OpMap.getFirstChildPos(opPos); if (shouldLoadWalkers) { diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xpath/internal/compiler/FuncLoader.java --- a/src/com/sun/org/apache/xpath/internal/compiler/FuncLoader.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xpath/internal/compiler/FuncLoader.java Tue Apr 17 11:17:59 2012 -0700 @@ -25,6 +25,8 @@ import javax.xml.transform.TransformerException; import com.sun.org.apache.xpath.internal.functions.Function; +import com.sun.org.apache.xalan.internal.utils.ObjectFactory; +import com.sun.org.apache.xalan.internal.utils.ConfigurationError; /** * Lazy load of functions into the function table as needed, so we don't @@ -96,11 +98,10 @@ throw new TransformerException("Application can't install his own xpath function."); } - return (Function) ObjectFactory.newInstance( - className, ObjectFactory.findClassLoader(), true); + return (Function) ObjectFactory.newInstance(className, true); } - catch (ObjectFactory.ConfigurationError e) + catch (ConfigurationError e) { throw new TransformerException(e.getException()); } diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xpath/internal/compiler/ObjectFactory.java --- a/src/com/sun/org/apache/xpath/internal/compiler/ObjectFactory.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,635 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2001-2004 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. - */ -/* - * $Id: ObjectFactory.java,v 1.1.2.1 2005/08/01 01:30:35 jeffsuttor Exp $ - */ - -package com.sun.org.apache.xpath.internal.compiler; - -import java.io.InputStream; -import java.io.IOException; -import java.io.File; -import java.io.FileInputStream; - -import java.util.Properties; -import java.io.BufferedReader; -import java.io.InputStreamReader; - -/** - * 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. - *

- * This code is designed to implement the JAXP 1.1 spec pluggability - * feature and is designed to run on JDK version 1.1 and - * later, and to compile on JDK 1.2 and onward. - * The code also runs both as part of an unbundled jar file and - * when bundled as part of the JDK. - *

- * This class was moved from the javax.xml.parsers.ObjectFactory - * class and modified to be used as a general utility for creating objects - * dynamically. - * - * @version $Id: ObjectFactory.java,v 1.6 2008/04/02 00:41:02 joehw Exp $ - */ -class ObjectFactory { - - // - // Constants - // - - // name of default properties file to look for in JDK's jre/lib directory - private static final String DEFAULT_PROPERTIES_FILENAME = - "xalan.properties"; - - private static final String SERVICES_PATH = "META-INF/services/"; - - /** Set to true for debugging */ - private static final boolean DEBUG = false; - - /** cache the contents of the xalan.properties file. - * Until an attempt has been made to read this file, this will - * be null; if the file does not exist or we encounter some other error - * during the read, this will be empty. - */ - private static Properties fXalanProperties = null; - - /*** - * Cache the time stamp of the xalan.properties file so - * that we know if it's been modified and can invalidate - * the cache when necessary. - */ - private static long fLastModified = -1; - - // - // Public static methods - // - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *

    - *
  1. query the system property using System.getProperty - *
  2. read META-INF/services/factoryId file - *
  3. use fallback classname - *
- * - * @return instance of factory, 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 no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Object createObject(String factoryId, String fallbackClassName) - throws ConfigurationError { - return createObject(factoryId, null, fallbackClassName); - } // createObject(String,String):Object - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return instance of factory, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Object createObject(String factoryId, - String propertiesFilename, - String fallbackClassName) - throws ConfigurationError - { - Class factoryClass = lookUpFactoryClass(factoryId, - propertiesFilename, - fallbackClassName); - - if (factoryClass == null) { - throw new ConfigurationError( - "Provider for " + factoryId + " cannot be found", null); - } - - try{ - Object instance = factoryClass.newInstance(); - if (DEBUG) debugPrintln("created new instance of factory " + factoryId); - return instance; - } catch (Exception x) { - throw new ConfigurationError( - "Provider for factory " + factoryId - + " could not be instantiated: " + x, x); - } - } // createObject(String,String,String):Object - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return Class object of factory, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Class lookUpFactoryClass(String factoryId) - throws ConfigurationError - { - return lookUpFactoryClass(factoryId, null, null); - } // lookUpFactoryClass(String):Class - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return Class object that provides factory service, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Class lookUpFactoryClass(String factoryId, - String propertiesFilename, - String fallbackClassName) - throws ConfigurationError - { - String factoryClassName = lookUpFactoryClassName(factoryId, - propertiesFilename, - fallbackClassName); - ClassLoader cl = findClassLoader(); - - if (factoryClassName == null) { - factoryClassName = fallbackClassName; - } - - // assert(className != null); - try{ - Class providerClass = findProviderClass(factoryClassName, - cl, - true); - if (DEBUG) debugPrintln("created new instance of " + providerClass + - " using ClassLoader: " + cl); - return providerClass; - } catch (ClassNotFoundException x) { - throw new ConfigurationError( - "Provider " + factoryClassName + " not found", x); - } catch (Exception x) { - throw new ConfigurationError( - "Provider "+factoryClassName+" could not be instantiated: "+x, - x); - } - } // lookUpFactoryClass(String,String,String):Class - - /** - * Finds the name of the required implementation class in the specified - * order. The specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return name of class that provides factory service, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static String lookUpFactoryClassName(String factoryId, - String propertiesFilename, - String fallbackClassName) - { - SecuritySupport ss = SecuritySupport.getInstance(); - - // Use the system property first - try { - String systemProp = ss.getSystemProperty(factoryId); - if (systemProp != null) { - if (DEBUG) debugPrintln("found system property, value=" + systemProp); - return systemProp; - } - } catch (SecurityException se) { - // Ignore and continue w/ next location - } - - // Try to read from propertiesFilename, or - // $java.home/lib/xalan.properties - String factoryClassName = null; - // no properties file name specified; use - // $JAVA_HOME/lib/xalan.properties: - if (propertiesFilename == null) { - File propertiesFile = null; - boolean propertiesFileExists = false; - try { - String javah = ss.getSystemProperty("java.home"); - propertiesFilename = javah + File.separator + - "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME; - propertiesFile = new File(propertiesFilename); - propertiesFileExists = ss.getFileExists(propertiesFile); - } catch (SecurityException e) { - // try again... - fLastModified = -1; - fXalanProperties = null; - } - - synchronized (ObjectFactory.class) { - boolean loadProperties = false; - try { - // file existed last time - if(fLastModified >= 0) { - if(propertiesFileExists && - (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) { - loadProperties = true; - } else { - // file has stopped existing... - if(!propertiesFileExists) { - fLastModified = -1; - fXalanProperties = null; - } // else, file wasn't modified! - } - } else { - // file has started to exist: - if(propertiesFileExists) { - loadProperties = true; - fLastModified = ss.getLastModified(propertiesFile); - } // else, nothing's changed - } - if(loadProperties) { - // must never have attempted to read xalan.properties - // before (or it's outdeated) - fXalanProperties = new Properties(); - FileInputStream fis = - ss.getFileInputStream(propertiesFile); - fXalanProperties.load(fis); - fis.close(); - } - } catch (Exception x) { - fXalanProperties = null; - fLastModified = -1; - // assert(x instanceof FileNotFoundException - // || x instanceof SecurityException) - // In both cases, ignore and continue w/ next location - } - } - if(fXalanProperties != null) { - factoryClassName = fXalanProperties.getProperty(factoryId); - } - } else { - try { - FileInputStream fis = - ss.getFileInputStream(new File(propertiesFilename)); - Properties props = new Properties(); - props.load(fis); - fis.close(); - factoryClassName = props.getProperty(factoryId); - } catch (Exception x) { - // assert(x instanceof FileNotFoundException - // || x instanceof SecurityException) - // In both cases, ignore and continue w/ next location - } - } - if (factoryClassName != null) { - if (DEBUG) debugPrintln("found in " + propertiesFilename + ", value=" - + factoryClassName); - return factoryClassName; - } - - // Try Jar Service Provider Mechanism - return findJarServiceProviderName(factoryId); - } // lookUpFactoryClass(String,String):String - - // - // Private static methods - // - - /** Prints a message to standard error if debugging is enabled. */ - private static void debugPrintln(String msg) { - if (DEBUG) { - System.err.println("JAXP: " + msg); - } - } // debugPrintln(String) - - /** - * Figure out which ClassLoader to use. For JDK 1.2 and later use - * the context ClassLoader. - */ - static ClassLoader findClassLoader() - 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 context = ss.getContextClassLoader(); - ClassLoader system = ss.getSystemClassLoader(); - - ClassLoader chain = system; - while (true) { - if (context == chain) { - // Assert: we are on JDK 1.1 or we have no Context ClassLoader - // or any Context ClassLoader in chain of system classloader - // (including extension ClassLoader) so extend to widest - // ClassLoader (always look in system ClassLoader if Xalan - // is in boot/extension/system classpath and in current - // ClassLoader otherwise); normal classloaders delegate - // back to system ClassLoader first so this widening doesn't - // change the fact that context ClassLoader will be consulted - ClassLoader current = ObjectFactory.class.getClassLoader(); - - chain = system; - while (true) { - if (current == chain) { - // Assert: Current ClassLoader in chain of - // boot/extension/system ClassLoaders - return system; - } - if (chain == null) { - break; - } - chain = ss.getParentClassLoader(chain); - } - - // Assert: Current ClassLoader not in chain of - // boot/extension/system ClassLoaders - return current; - } - - if (chain == null) { - // boot ClassLoader reached - break; - } - - // Check for any extension ClassLoaders in chain up to - // boot ClassLoader - chain = ss.getParentClassLoader(chain); - }; - - // Assert: Context ClassLoader not in chain of - // boot/extension/system ClassLoaders - return context; - } // findClassLoader():ClassLoader - - /** - * Create an instance of a class using the specified ClassLoader - */ - static Object newInstance(String className, ClassLoader cl, - boolean doFallback) - throws ConfigurationError - { - // assert(className != null); - try{ - Class providerClass = findProviderClass(className, cl, doFallback); - Object instance = providerClass.newInstance(); - if (DEBUG) debugPrintln("created new instance of " + providerClass + - " using ClassLoader: " + cl); - return instance; - } catch (ClassNotFoundException x) { - throw new ConfigurationError( - "Provider " + className + " not found", x); - } catch (Exception x) { - throw new ConfigurationError( - "Provider " + className + " could not be instantiated: " + x, - x); - } - } - - /** - * Find a Class using the specified ClassLoader - */ - static Class findProviderClass(String className, ClassLoader cl, - boolean doFallback) - throws ClassNotFoundException, ConfigurationError - { - //throw security exception if the calling thread is not allowed to access the - //class. Restrict the access to the package classes as specified in java.security policy. - SecurityManager security = System.getSecurityManager(); - if (security != null){ - final int lastDot = className.lastIndexOf("."); - String packageName = className; - if (lastDot != -1) - packageName = className.substring(0, lastDot); - security.checkPackageAccess(packageName); - } - - Class providerClass; - 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 { - try { - providerClass = cl.loadClass(className); - } catch (ClassNotFoundException x) { - if (doFallback) { - // Fall back to current classloader - ClassLoader current = ObjectFactory.class.getClassLoader(); - if (current == null) { - providerClass = Class.forName(className); - } else if (cl != current) { - cl = current; - providerClass = cl.loadClass(className); - } else { - throw x; - } - } else { - throw x; - } - } - } - - return providerClass; - } - - /** - * Find the name of service provider using Jar Service Provider Mechanism - * - * @return instance of provider class if found or null - */ - private static String findJarServiceProviderName(String factoryId) - { - SecuritySupport ss = SecuritySupport.getInstance(); - String serviceId = SERVICES_PATH + factoryId; - InputStream is = null; - - // First try the Context ClassLoader - ClassLoader cl = findClassLoader(); - - is = ss.getResourceAsStream(cl, serviceId); - - // If no provider found then try the current ClassLoader - if (is == null) { - ClassLoader current = ObjectFactory.class.getClassLoader(); - if (cl != current) { - cl = current; - is = ss.getResourceAsStream(cl, serviceId); - } - } - - if (is == null) { - // No provider found - return null; - } - - if (DEBUG) debugPrintln("found jar resource=" + serviceId + - " using ClassLoader: " + cl); - - // 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)); - } - - String factoryClassName = null; - try { - // XXX Does not handle all possible input as specified by the - // Jar Service Provider specification - factoryClassName = rd.readLine(); - rd.close(); - } catch (IOException x) { - // No provider found - return null; - } - - if (factoryClassName != null && - ! "".equals(factoryClassName)) { - if (DEBUG) debugPrintln("found in resource, value=" - + factoryClassName); - - // Note: here we do not want to fall back to the current - // 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. - return factoryClassName; - } - - // No provider found - return null; - } - - // - // Classes - // - - /** - * A configuration error. - */ - static class ConfigurationError - extends Error { - - // - // Data - // - - /** Exception. */ - private Exception exception; - - // - // Constructors - // - - /** - * Construct a new instance with the specified detail string and - * exception. - */ - ConfigurationError(String msg, Exception x) { - super(msg); - this.exception = x; - } // (String,Exception) - - // - // Public methods - // - - /** Returns the exception associated to this error. */ - Exception getException() { - return exception; - } // getException():Exception - - } // class ConfigurationError - -} // class ObjectFactory diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xpath/internal/compiler/OpMap.java --- a/src/com/sun/org/apache/xpath/internal/compiler/OpMap.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xpath/internal/compiler/OpMap.java Tue Apr 17 11:17:59 2012 -0700 @@ -242,7 +242,7 @@ else { throw new RuntimeException( - XSLMessages.createXPATHMessage(XPATHErrorResources.ER_UNKNOWN_STEP, new Object[]{new Integer(stepType).toString()})); + XSLMessages.createXPATHMessage(XPATHErrorResources.ER_UNKNOWN_STEP, new Object[]{String.valueOf(stepType)})); //"Programmer's assertion in getNextStepPos: unknown stepType: " + stepType); } } diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xpath/internal/compiler/SecuritySupport.java --- a/src/com/sun/org/apache/xpath/internal/compiler/SecuritySupport.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,127 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2002-2004 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. - */ -/* - * $Id: SecuritySupport.java,v 1.1.2.1 2005/08/01 01:30:35 jeffsuttor Exp $ - */ - -package com.sun.org.apache.xpath.internal.compiler; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.InputStream; - -import java.util.Properties; - -/** - * This class is duplicated for each Xalan-Java subpackage so keep it in sync. - * It is package private and therefore is not exposed as part of the Xalan-Java - * 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. - */ - static SecuritySupport getInstance() { - return (SecuritySupport)securitySupport; - } - - ClassLoader getContextClassLoader() { - return null; - } - - ClassLoader getSystemClassLoader() { - return null; - } - - ClassLoader getParentClassLoader(ClassLoader cl) { - return null; - } - - String getSystemProperty(String propName) { - return System.getProperty(propName); - } - - FileInputStream getFileInputStream(File file) - throws FileNotFoundException - { - return new FileInputStream(file); - } - - InputStream getResourceAsStream(ClassLoader cl, String name) { - InputStream ris; - if (cl == null) { - ris = ClassLoader.getSystemResourceAsStream(name); - } else { - ris = cl.getResourceAsStream(name); - } - return ris; - } - - boolean getFileExists(File f) { - return f.exists(); - } - - long getLastModified(File f) { - return f.lastModified(); - } -} diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xpath/internal/compiler/SecuritySupport12.java --- a/src/com/sun/org/apache/xpath/internal/compiler/SecuritySupport12.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,148 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2002-2004 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. - */ -/* - * $Id: SecuritySupport12.java,v 1.1.2.1 2005/08/01 01:30:31 jeffsuttor Exp $ - */ - -package com.sun.org.apache.xpath.internal.compiler; - -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; - -import java.util.Properties; - -/** - * This class is duplicated for each Xalan-Java subpackage so keep it in sync. - * It is package private and therefore is not exposed as part of the Xalan-Java - * API. - * - * Security related methods that only work on J2SE 1.2 and newer. - */ -class SecuritySupport12 extends SecuritySupport { - - ClassLoader getContextClassLoader() { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader cl = null; - try { - cl = Thread.currentThread().getContextClassLoader(); - } catch (SecurityException ex) { } - return cl; - } - }); - } - - ClassLoader getSystemClassLoader() { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader cl = null; - try { - cl = ClassLoader.getSystemClassLoader(); - } catch (SecurityException ex) {} - return cl; - } - }); - } - - ClassLoader getParentClassLoader(final ClassLoader cl) { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader parent = null; - try { - parent = cl.getParent(); - } catch (SecurityException ex) {} - - // eliminate loops in case of the boot - // ClassLoader returning itself as a parent - return (parent == cl) ? null : parent; - } - }); - } - - String getSystemProperty(final String propName) { - return (String) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return System.getProperty(propName); - } - }); - } - - 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(); - } - } - - 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; - } - }); - } - - boolean getFileExists(final File f) { - return ((Boolean) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return new Boolean(f.exists()); - } - })).booleanValue(); - } - - long getLastModified(final File f) { - return ((Long) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return new Long(f.lastModified()); - } - })).longValue(); - } - -} diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xpath/internal/functions/FuncSystemProperty.java --- a/src/com/sun/org/apache/xpath/internal/functions/FuncSystemProperty.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xpath/internal/functions/FuncSystemProperty.java Tue Apr 17 11:17:59 2012 -0700 @@ -31,6 +31,8 @@ import com.sun.org.apache.xpath.internal.objects.XObject; import com.sun.org.apache.xpath.internal.objects.XString; import com.sun.org.apache.xpath.internal.res.XPATHErrorResources; +import com.sun.org.apache.xalan.internal.utils.ObjectFactory; +import com.sun.org.apache.xalan.internal.utils.SecuritySupport; /** * Execute the SystemProperty() function. @@ -168,9 +170,8 @@ try { // Use SecuritySupport class to provide priveleged access to property file - SecuritySupport ss = SecuritySupport.getInstance(); - InputStream is = ss.getResourceAsStream(ObjectFactory.findClassLoader(), + InputStream is = SecuritySupport.getResourceAsStream(ObjectFactory.findClassLoader(), file); // get a buffered version diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xpath/internal/functions/ObjectFactory.java --- a/src/com/sun/org/apache/xpath/internal/functions/ObjectFactory.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,663 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2001-2004 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. - */ -/* - * $Id: ObjectFactory.java,v 1.2.4.1 2005/09/14 20:25:54 jeffsuttor Exp $ - */ - -package com.sun.org.apache.xpath.internal.functions; - -import java.io.InputStream; -import java.io.IOException; -import java.io.File; -import java.io.FileInputStream; - -import java.util.Properties; -import java.io.BufferedReader; -import java.io.InputStreamReader; - -/** - * 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. - *

- * This code is designed to implement the JAXP 1.1 spec pluggability - * feature and is designed to run on JDK version 1.1 and - * later, and to compile on JDK 1.2 and onward. - * The code also runs both as part of an unbundled jar file and - * when bundled as part of the JDK. - *

- * This class was moved from the javax.xml.parsers.ObjectFactory - * class and modified to be used as a general utility for creating objects - * dynamically. - * - * @version $Id: ObjectFactory.java,v 1.7 2008/04/02 00:40:59 joehw Exp $ - */ -class ObjectFactory { - - // - // Constants - // - - // name of default properties file to look for in JDK's jre/lib directory - private static final String DEFAULT_PROPERTIES_FILENAME = - "xalan.properties"; - - private static final String SERVICES_PATH = "META-INF/services/"; - - /** Set to true for debugging */ - private static final boolean DEBUG = false; - - /** cache the contents of the xalan.properties file. - * Until an attempt has been made to read this file, this will - * be null; if the file does not exist or we encounter some other error - * during the read, this will be empty. - */ - private static Properties fXalanProperties = null; - - /*** - * Cache the time stamp of the xalan.properties file so - * that we know if it's been modified and can invalidate - * the cache when necessary. - */ - private static long fLastModified = -1; - - // - // Public static methods - // - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *

    - *
  1. query the system property using System.getProperty - *
  2. read META-INF/services/factoryId file - *
  3. use fallback classname - *
- * - * @return instance of factory, 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 no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Object createObject(String factoryId, String fallbackClassName) - throws ConfigurationError { - return createObject(factoryId, null, fallbackClassName); - } // createObject(String,String):Object - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return instance of factory, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Object createObject(String factoryId, - String propertiesFilename, - String fallbackClassName) - throws ConfigurationError - { - Class factoryClass = lookUpFactoryClass(factoryId, - propertiesFilename, - fallbackClassName); - - if (factoryClass == null) { - throw new ConfigurationError( - "Provider for " + factoryId + " cannot be found", null); - } - - try{ - Object instance = factoryClass.newInstance(); - if (DEBUG) debugPrintln("created new instance of factory " + factoryId); - return instance; - } catch (Exception x) { - throw new ConfigurationError( - "Provider for factory " + factoryId - + " could not be instantiated: " + x, x); - } - } // createObject(String,String,String):Object - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return Class object of factory, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Class lookUpFactoryClass(String factoryId) - throws ConfigurationError - { - return lookUpFactoryClass(factoryId, null, null); - } // lookUpFactoryClass(String):Class - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return Class object that provides factory service, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Class lookUpFactoryClass(String factoryId, - String propertiesFilename, - String fallbackClassName) - throws ConfigurationError - { - String factoryClassName = lookUpFactoryClassName(factoryId, - propertiesFilename, - fallbackClassName); - ClassLoader cl = findClassLoader(); - - if (factoryClassName == null) { - factoryClassName = fallbackClassName; - } - - // assert(className != null); - try{ - Class providerClass = findProviderClass(factoryClassName, - cl, - true); - if (DEBUG) debugPrintln("created new instance of " + providerClass + - " using ClassLoader: " + cl); - return providerClass; - } catch (ClassNotFoundException x) { - throw new ConfigurationError( - "Provider " + factoryClassName + " not found", x); - } catch (Exception x) { - throw new ConfigurationError( - "Provider "+factoryClassName+" could not be instantiated: "+x, - x); - } - } // lookUpFactoryClass(String,String,String):Class - - /** - * Finds the name of the required implementation class in the specified - * order. The specified order is the following: - *
    - *
  1. query the system property using System.getProperty - *
  2. read $java.home/lib/propertiesFilename file - *
  3. read META-INF/services/factoryId file - *
  4. use fallback classname - *
- * - * @return name of class that provides factory service, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xalan.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static String lookUpFactoryClassName(String factoryId, - String propertiesFilename, - String fallbackClassName) - { - SecuritySupport ss = SecuritySupport.getInstance(); - - // Use the system property first - try { - String systemProp = ss.getSystemProperty(factoryId); - if (systemProp != null) { - if (DEBUG) debugPrintln("found system property, value=" + systemProp); - return systemProp; - } - } catch (SecurityException se) { - // Ignore and continue w/ next location - } - - // Try to read from propertiesFilename, or - // $java.home/lib/xalan.properties - String factoryClassName = null; - // no properties file name specified; use - // $JAVA_HOME/lib/xalan.properties: - if (propertiesFilename == null) { - File propertiesFile = null; - boolean propertiesFileExists = false; - try { - String javah = ss.getSystemProperty("java.home"); - propertiesFilename = javah + File.separator + - "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME; - propertiesFile = new File(propertiesFilename); - propertiesFileExists = ss.getFileExists(propertiesFile); - } catch (SecurityException e) { - // try again... - fLastModified = -1; - fXalanProperties = null; - } - - synchronized (ObjectFactory.class) { - boolean loadProperties = false; - FileInputStream fis = null; - try { - // file existed last time - if(fLastModified >= 0) { - if(propertiesFileExists && - (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) { - loadProperties = true; - } else { - // file has stopped existing... - if(!propertiesFileExists) { - fLastModified = -1; - fXalanProperties = null; - } // else, file wasn't modified! - } - } else { - // file has started to exist: - if(propertiesFileExists) { - loadProperties = true; - fLastModified = ss.getLastModified(propertiesFile); - } // else, nothing's changed - } - if(loadProperties) { - // must never have attempted to read xalan.properties - // before (or it's outdeated) - fXalanProperties = new Properties(); - fis = ss.getFileInputStream(propertiesFile); - fXalanProperties.load(fis); - } - } catch (Exception x) { - fXalanProperties = null; - fLastModified = -1; - // assert(x instanceof FileNotFoundException - // || x instanceof SecurityException) - // In both cases, ignore and continue w/ next location - } - finally { - // try to close the input stream if one was opened. - if (fis != null) { - try { - fis.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - } - } - if(fXalanProperties != null) { - factoryClassName = fXalanProperties.getProperty(factoryId); - } - } else { - FileInputStream fis = null; - try { - fis = ss.getFileInputStream(new File(propertiesFilename)); - Properties props = new Properties(); - props.load(fis); - factoryClassName = props.getProperty(factoryId); - } catch (Exception x) { - // assert(x instanceof FileNotFoundException - // || x instanceof SecurityException) - // In both cases, ignore and continue w/ next location - } - finally { - // try to close the input stream if one was opened. - if (fis != null) { - try { - fis.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - } - } - if (factoryClassName != null) { - if (DEBUG) debugPrintln("found in " + propertiesFilename + ", value=" - + factoryClassName); - return factoryClassName; - } - - // Try Jar Service Provider Mechanism - return findJarServiceProviderName(factoryId); - } // lookUpFactoryClass(String,String):String - - // - // Private static methods - // - - /** Prints a message to standard error if debugging is enabled. */ - private static void debugPrintln(String msg) { - if (DEBUG) { - System.err.println("JAXP: " + msg); - } - } // debugPrintln(String) - - /** - * Figure out which ClassLoader to use. For JDK 1.2 and later use - * the context ClassLoader. - */ - static ClassLoader findClassLoader() - 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 context = ss.getContextClassLoader(); - ClassLoader system = ss.getSystemClassLoader(); - - ClassLoader chain = system; - while (true) { - if (context == chain) { - // Assert: we are on JDK 1.1 or we have no Context ClassLoader - // or any Context ClassLoader in chain of system classloader - // (including extension ClassLoader) so extend to widest - // ClassLoader (always look in system ClassLoader if Xalan - // is in boot/extension/system classpath and in current - // ClassLoader otherwise); normal classloaders delegate - // back to system ClassLoader first so this widening doesn't - // change the fact that context ClassLoader will be consulted - ClassLoader current = ObjectFactory.class.getClassLoader(); - - chain = system; - while (true) { - if (current == chain) { - // Assert: Current ClassLoader in chain of - // boot/extension/system ClassLoaders - return system; - } - if (chain == null) { - break; - } - chain = ss.getParentClassLoader(chain); - } - - // Assert: Current ClassLoader not in chain of - // boot/extension/system ClassLoaders - return current; - } - - if (chain == null) { - // boot ClassLoader reached - break; - } - - // Check for any extension ClassLoaders in chain up to - // boot ClassLoader - chain = ss.getParentClassLoader(chain); - }; - - // Assert: Context ClassLoader not in chain of - // boot/extension/system ClassLoaders - return context; - } // findClassLoader():ClassLoader - - /** - * Create an instance of a class using the specified ClassLoader - */ - static Object newInstance(String className, ClassLoader cl, - boolean doFallback) - throws ConfigurationError - { - // assert(className != null); - try{ - Class providerClass = findProviderClass(className, cl, doFallback); - Object instance = providerClass.newInstance(); - if (DEBUG) debugPrintln("created new instance of " + providerClass + - " using ClassLoader: " + cl); - return instance; - } catch (ClassNotFoundException x) { - throw new ConfigurationError( - "Provider " + className + " not found", x); - } catch (Exception x) { - throw new ConfigurationError( - "Provider " + className + " could not be instantiated: " + x, - x); - } - } - - /** - * Find a Class using the specified ClassLoader - */ - static Class findProviderClass(String className, ClassLoader cl, - boolean doFallback) - throws ClassNotFoundException, ConfigurationError - { - //throw security exception if the calling thread is not allowed to access the - //class. Restrict the access to the package classes as specified in java.security policy. - SecurityManager security = System.getSecurityManager(); - try{ - if (security != null){ - final int lastDot = className.lastIndexOf("."); - String packageName = className; - if (lastDot != -1) packageName = className.substring(0, lastDot); - security.checkPackageAccess(packageName); - } - }catch(SecurityException e){ - throw e; - } - - Class providerClass; - 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 { - try { - providerClass = cl.loadClass(className); - } catch (ClassNotFoundException x) { - if (doFallback) { - // Fall back to current classloader - ClassLoader current = ObjectFactory.class.getClassLoader(); - if (current == null) { - providerClass = Class.forName(className); - } else if (cl != current) { - cl = current; - providerClass = cl.loadClass(className); - } else { - throw x; - } - } else { - throw x; - } - } - } - - return providerClass; - } - - /** - * Find the name of service provider using Jar Service Provider Mechanism - * - * @return instance of provider class if found or null - */ - private static String findJarServiceProviderName(String factoryId) - { - SecuritySupport ss = SecuritySupport.getInstance(); - String serviceId = SERVICES_PATH + factoryId; - InputStream is = null; - - // First try the Context ClassLoader - ClassLoader cl = findClassLoader(); - - is = ss.getResourceAsStream(cl, serviceId); - - // If no provider found then try the current ClassLoader - if (is == null) { - ClassLoader current = ObjectFactory.class.getClassLoader(); - if (cl != current) { - cl = current; - is = ss.getResourceAsStream(cl, serviceId); - } - } - - if (is == null) { - // No provider found - return null; - } - - if (DEBUG) debugPrintln("found jar resource=" + serviceId + - " using ClassLoader: " + cl); - - // 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)); - } - - String factoryClassName = null; - try { - // XXX Does not handle all possible input as specified by the - // Jar Service Provider specification - factoryClassName = rd.readLine(); - } catch (IOException x) { - // No provider found - return null; - } - finally { - try { - // try to close the reader. - rd.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - - if (factoryClassName != null && - ! "".equals(factoryClassName)) { - if (DEBUG) debugPrintln("found in resource, value=" - + factoryClassName); - - // Note: here we do not want to fall back to the current - // 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. - return factoryClassName; - } - - // No provider found - return null; - } - - // - // Classes - // - - /** - * A configuration error. - */ - static class ConfigurationError - extends Error { - static final long serialVersionUID = -5782303800588797207L; - // - // Data - // - - /** Exception. */ - private Exception exception; - - // - // Constructors - // - - /** - * Construct a new instance with the specified detail string and - * exception. - */ - ConfigurationError(String msg, Exception x) { - super(msg); - this.exception = x; - } // (String,Exception) - - // - // Public methods - // - - /** Returns the exception associated to this error. */ - Exception getException() { - return exception; - } // getException():Exception - - } // class ConfigurationError - -} // class ObjectFactory diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xpath/internal/functions/SecuritySupport.java --- a/src/com/sun/org/apache/xpath/internal/functions/SecuritySupport.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,127 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2002-2004 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. - */ -/* - * $Id: SecuritySupport.java,v 1.1.2.1 2005/08/01 01:29:39 jeffsuttor Exp $ - */ - -package com.sun.org.apache.xpath.internal.functions; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.InputStream; - -import java.util.Properties; - -/** - * This class is duplicated for each Xalan-Java subpackage so keep it in sync. - * It is package private and therefore is not exposed as part of the Xalan-Java - * 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. - */ - static SecuritySupport getInstance() { - return (SecuritySupport)securitySupport; - } - - ClassLoader getContextClassLoader() { - return null; - } - - ClassLoader getSystemClassLoader() { - return null; - } - - ClassLoader getParentClassLoader(ClassLoader cl) { - return null; - } - - String getSystemProperty(String propName) { - return System.getProperty(propName); - } - - FileInputStream getFileInputStream(File file) - throws FileNotFoundException - { - return new FileInputStream(file); - } - - InputStream getResourceAsStream(ClassLoader cl, String name) { - InputStream ris; - if (cl == null) { - ris = ClassLoader.getSystemResourceAsStream(name); - } else { - ris = cl.getResourceAsStream(name); - } - return ris; - } - - boolean getFileExists(File f) { - return f.exists(); - } - - long getLastModified(File f) { - return f.lastModified(); - } -} diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xpath/internal/functions/SecuritySupport12.java --- a/src/com/sun/org/apache/xpath/internal/functions/SecuritySupport12.java Thu Apr 12 08:38:26 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,148 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2002-2004 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. - */ -/* - * $Id: SecuritySupport12.java,v 1.1.2.1 2005/08/01 01:29:45 jeffsuttor Exp $ - */ - -package com.sun.org.apache.xpath.internal.functions; - -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; - -import java.util.Properties; - -/** - * This class is duplicated for each Xalan-Java subpackage so keep it in sync. - * It is package private and therefore is not exposed as part of the Xalan-Java - * API. - * - * Security related methods that only work on J2SE 1.2 and newer. - */ -class SecuritySupport12 extends SecuritySupport { - - ClassLoader getContextClassLoader() { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader cl = null; - try { - cl = Thread.currentThread().getContextClassLoader(); - } catch (SecurityException ex) { } - return cl; - } - }); - } - - ClassLoader getSystemClassLoader() { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader cl = null; - try { - cl = ClassLoader.getSystemClassLoader(); - } catch (SecurityException ex) {} - return cl; - } - }); - } - - ClassLoader getParentClassLoader(final ClassLoader cl) { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader parent = null; - try { - parent = cl.getParent(); - } catch (SecurityException ex) {} - - // eliminate loops in case of the boot - // ClassLoader returning itself as a parent - return (parent == cl) ? null : parent; - } - }); - } - - String getSystemProperty(final String propName) { - return (String) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return System.getProperty(propName); - } - }); - } - - 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(); - } - } - - 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; - } - }); - } - - boolean getFileExists(final File f) { - return ((Boolean) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return new Boolean(f.exists()); - } - })).booleanValue(); - } - - long getLastModified(final File f) { - return ((Long) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return new Long(f.lastModified()); - } - })).longValue(); - } - -} diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xpath/internal/jaxp/XPathExpressionImpl.java --- a/src/com/sun/org/apache/xpath/internal/jaxp/XPathExpressionImpl.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xpath/internal/jaxp/XPathExpressionImpl.java Tue Apr 17 11:17:59 2012 -0700 @@ -29,6 +29,7 @@ import com.sun.org.apache.xml.internal.utils.PrefixResolver; import com.sun.org.apache.xpath.internal.res.XPATHErrorResources; import com.sun.org.apache.xalan.internal.res.XSLMessages; +import com.sun.org.apache.xalan.internal.utils.FactoryImpl; import javax.xml.namespace.NamespaceContext; import javax.xml.namespace.QName; @@ -50,6 +51,7 @@ /** * The XPathExpression interface encapsulates a (compiled) XPath expression. * + * @version $Revision: 1.10 $ * @author Ramesh Mandava */ public class XPathExpressionImpl implements javax.xml.xpath.XPathExpression{ @@ -64,6 +66,7 @@ // extensions function need to throw XPathFunctionException private boolean featureSecureProcessing = false; + private boolean useServicesMechanism = true; /** Protected constructor to prevent direct instantiation; use compile() * from the context. */ @@ -84,12 +87,13 @@ JAXPPrefixResolver prefixResolver, XPathFunctionResolver functionResolver, XPathVariableResolver variableResolver, - boolean featureSecureProcessing ) { + boolean featureSecureProcessing, boolean useServicesMechanism ) { this.xpath = xpath; this.prefixResolver = prefixResolver; this.functionResolver = functionResolver; this.variableResolver = variableResolver; this.featureSecureProcessing = featureSecureProcessing; + this.useServicesMechanism = useServicesMechanism; }; public void setXPath (com.sun.org.apache.xpath.internal.XPath xpath ) { @@ -286,7 +290,7 @@ } try { if ( dbf == null ) { - dbf = DocumentBuilderFactory.newInstance(); + dbf = FactoryImpl.getDOMFactory(useServicesMechanism); dbf.setNamespaceAware( true ); dbf.setValidating( false ); } diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xpath/internal/jaxp/XPathFactoryImpl.java --- a/src/com/sun/org/apache/xpath/internal/jaxp/XPathFactoryImpl.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xpath/internal/jaxp/XPathFactoryImpl.java Tue Apr 17 11:17:59 2012 -0700 @@ -21,6 +21,7 @@ package com.sun.org.apache.xpath.internal.jaxp; +import com.sun.org.apache.xalan.internal.XalanConstants; import com.sun.org.apache.xpath.internal.res.XPATHErrorResources; import com.sun.org.apache.xalan.internal.res.XSLMessages; @@ -33,7 +34,7 @@ /** * The XPathFactory builds XPaths. * - * @version $Revision: 1.9 $ + * @version $Revision: 1.11 $ * @author Ramesh Mandava */ public class XPathFactoryImpl extends XPathFactory { @@ -64,13 +65,24 @@ /** * javax.xml.xpath.XPathFactory implementation. */ + + private boolean _useServicesMechanism = true; + public XPathFactoryImpl() { + this(true); + } + + public static XPathFactory newXPathFactoryNoServiceLoader() { + return new XPathFactoryImpl(false); + } + + public XPathFactoryImpl(boolean useServicesMechanism) { if (System.getSecurityManager() != null) { _isSecureMode = true; _isNotSecureProcessing = false; } + this._useServicesMechanism = useServicesMechanism; } - /** *

Is specified object model supported by this * XPathFactory?

@@ -119,7 +131,7 @@ public javax.xml.xpath.XPath newXPath() { return new com.sun.org.apache.xpath.internal.jaxp.XPathImpl( xPathVariableResolver, xPathFunctionResolver, - !_isNotSecureProcessing ); + !_isNotSecureProcessing, _useServicesMechanism ); } /** @@ -173,6 +185,12 @@ // all done processing feature return; } + if (name.equals(XalanConstants.ORACLE_FEATURE_SERVICE_MECHANISM)) { + //in secure mode, let _useServicesMechanism be determined by the constructor + if (!_isSecureMode) + _useServicesMechanism = value; + return; + } // unknown feature String fmsg = XSLMessages.createXPATHMessage( @@ -219,7 +237,9 @@ if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) { return !_isNotSecureProcessing; } - + if (name.equals(XalanConstants.ORACLE_FEATURE_SERVICE_MECHANISM)) { + return _useServicesMechanism; + } // unknown feature String fmsg = XSLMessages.createXPATHMessage( XPATHErrorResources.ER_GETTING_UNKNOWN_FEATURE, diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xpath/internal/jaxp/XPathImpl.java --- a/src/com/sun/org/apache/xpath/internal/jaxp/XPathImpl.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xpath/internal/jaxp/XPathImpl.java Tue Apr 17 11:17:59 2012 -0700 @@ -34,9 +34,9 @@ import com.sun.org.apache.xpath.internal.objects.XObject; import com.sun.org.apache.xpath.internal.res.XPATHErrorResources; import com.sun.org.apache.xalan.internal.res.XSLMessages; +import com.sun.org.apache.xalan.internal.utils.FactoryImpl; import org.w3c.dom.Node; -import org.w3c.dom.DOMImplementation; import org.w3c.dom.Document; import org.w3c.dom.traversal.NodeIterator; @@ -53,6 +53,7 @@ * of an XPath expression. * * + * @version $Revision: 1.10 $ * @author Ramesh Mandava */ public class XPathImpl implements javax.xml.xpath.XPath { @@ -68,6 +69,7 @@ // Secure Processing Feature is set on XPathFactory then the invocation of // extensions function need to throw XPathFunctionException private boolean featureSecureProcessing = false; + private boolean useServiceMechanism = true; XPathImpl( XPathVariableResolver vr, XPathFunctionResolver fr ) { this.origVariableResolver = this.variableResolver = vr; @@ -75,10 +77,11 @@ } XPathImpl( XPathVariableResolver vr, XPathFunctionResolver fr, - boolean featureSecureProcessing ) { + boolean featureSecureProcessing, boolean useServiceMechanism ) { this.origVariableResolver = this.variableResolver = vr; this.origFunctionResolver = this.functionResolver = fr; this.featureSecureProcessing = featureSecureProcessing; + this.useServiceMechanism = useServiceMechanism; } /** @@ -156,7 +159,7 @@ private static Document d = null; - private static DocumentBuilder getParser() { + private DocumentBuilder getParser() { try { // we'd really like to cache those DocumentBuilders, but we can't because: // 1. thread safety. parsers are not thread-safe, so at least @@ -169,7 +172,7 @@ // // so we really have to create a fresh DocumentBuilder every time we need one // - KK - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilderFactory dbf = FactoryImpl.getDOMFactory(useServiceMechanism); dbf.setNamespaceAware( true ); dbf.setValidating( false ); return dbf.newDocumentBuilder(); @@ -179,17 +182,6 @@ } } - private static Document getDummyDocument( ) { - // we don't need synchronization here; even if two threads - // enter this code at the same time, we just waste a little time - if(d==null) { - DOMImplementation dim = getParser().getDOMImplementation(); - d = dim.createDocument("http://java.sun.com/jaxp/xpath", - "dummyroot", null); - } - return d; - } - private XObject eval(String expression, Object contextItem) throws javax.xml.transform.TransformerException { @@ -399,7 +391,7 @@ // Can have errorListener XPathExpressionImpl ximpl = new XPathExpressionImpl (xpath, prefixResolver, functionResolver, variableResolver, - featureSecureProcessing ); + featureSecureProcessing, useServiceMechanism ); return ximpl; } catch ( javax.xml.transform.TransformerException te ) { throw new XPathExpressionException ( te ) ; diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xpath/internal/objects/XString.java --- a/src/com/sun/org/apache/xpath/internal/objects/XString.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xpath/internal/objects/XString.java Tue Apr 17 11:17:59 2012 -0700 @@ -321,6 +321,22 @@ return xstr().equals(obj2.xstr()); } + /** + * Compares this string to the specified String. + * The result is true if and only if the argument is not + * null and is a String object that represents + * the same sequence of characters as this object. + * + * @param obj2 the object to compare this String against. + * @return true if the Strings are equal; + * false otherwise. + * @see java.lang.String#compareTo(java.lang.String) + * @see java.lang.String#equalsIgnoreCase(java.lang.String) + */ + public boolean equals(String obj2) { + return str().equals(obj2); + } + /** * Compares this string to the specified object. * The result is true if and only if the argument is not @@ -336,11 +352,14 @@ */ public boolean equals(XMLString obj2) { - - if (!obj2.hasString()) - return obj2.equals(this); - else - return str().equals(obj2.toString()); + if (obj2 != null) { + if (!obj2.hasString()) { + return obj2.equals(str()); + } else { + return str().equals(obj2.toString()); + } + } + return false; } /** diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xpath/internal/objects/XStringForFSB.java --- a/src/com/sun/org/apache/xpath/internal/objects/XStringForFSB.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xpath/internal/objects/XStringForFSB.java Tue Apr 17 11:17:59 2012 -0700 @@ -979,7 +979,7 @@ return Double.NaN; try { - return new Double(valueString).doubleValue(); + return Double.parseDouble(valueString); } catch (NumberFormatException nfe) { // This should catch double periods, empty strings. return Double.NaN; diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/org/apache/xpath/internal/patterns/StepPattern.java --- a/src/com/sun/org/apache/xpath/internal/patterns/StepPattern.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/org/apache/xpath/internal/patterns/StepPattern.java Tue Apr 17 11:17:59 2012 -0700 @@ -857,7 +857,7 @@ } else { - buf.append("?" + Integer.toHexString(pat.m_whatToShow)); + buf.append('?').append(Integer.toHexString(pat.m_whatToShow)); } if (null != pat.m_predicates) diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/xml/internal/stream/XMLEntityStorage.java --- a/src/com/sun/xml/internal/stream/XMLEntityStorage.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/xml/internal/stream/XMLEntityStorage.java Tue Apr 17 11:17:59 2012 -0700 @@ -36,6 +36,7 @@ import com.sun.org.apache.xerces.internal.impl.PropertyManager; import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter; import com.sun.org.apache.xerces.internal.impl.Constants; +import java.util.Enumeration; /** * @@ -129,19 +130,27 @@ } // reset(XMLComponentManager) /** - * Returns the hashtable of declared entities. - *

- * REVISIT: - * This should be done the "right" way by designing a better way to - * enumerate the declared entities. For now, this method is needed - * by the constructor that takes an XMLEntityManager parameter. - * XXX Making this method public, return all the declared entities. - * @return Hashtable hastable containing all the declared entities. + * Returns entity declaration. + * + * @param name The name of the entity. + * + * @see SymbolTable */ - public Hashtable getDeclaredEntities() { - return fEntities; - } // getDeclaredEntities():Hashtable + public Entity getEntity(String name) { + return (Entity)fEntities.get(name); + } // getEntity(String) + + public boolean hasEntities() { + return (fEntities!=null); + } // getEntity(String) + public int getEntitySize() { + return fEntities.size(); + } // getEntity(String) + + public Enumeration getEntityKeys() { + return fEntities.keys(); + } /** * Adds an internal entity declaration. *

diff -r 7b89fed7212b -r ceae213d9812 src/com/sun/xml/internal/stream/writers/XMLStreamWriterImpl.java --- a/src/com/sun/xml/internal/stream/writers/XMLStreamWriterImpl.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/com/sun/xml/internal/stream/writers/XMLStreamWriterImpl.java Tue Apr 17 11:17:59 2012 -0700 @@ -233,6 +233,7 @@ fPrefixGen = new Random(); fAttributeCache = new ArrayList(); fInternalNamespaceContext = new NamespaceSupport(); + fInternalNamespaceContext.reset(); fNamespaceContext = new NamespaceContextImpl(); fNamespaceContext.internalContext = fInternalNamespaceContext; @@ -383,6 +384,8 @@ fElementStack.clear(); fInternalNamespaceContext.reset(); fReuse = true; + fStartTagOpened = false; + fNamespaceContext.userContext = null; } /** diff -r 7b89fed7212b -r ceae213d9812 src/javax/xml/datatype/FactoryFinder.java --- a/src/javax/xml/datatype/FactoryFinder.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/javax/xml/datatype/FactoryFinder.java Tue Apr 17 11:17:59 2012 -0700 @@ -59,7 +59,7 @@ * Flag indicating if properties from java.home/lib/jaxp.properties * have been cached. */ - static boolean firstTime = true; + static volatile boolean firstTime = true; /** * Security support class use to check access control before diff -r 7b89fed7212b -r ceae213d9812 src/javax/xml/parsers/FactoryFinder.java --- a/src/javax/xml/parsers/FactoryFinder.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/javax/xml/parsers/FactoryFinder.java Tue Apr 17 11:17:59 2012 -0700 @@ -25,15 +25,12 @@ package javax.xml.parsers; +import java.io.BufferedReader; import java.io.File; -import java.io.FileInputStream; - -import java.util.Properties; -import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import java.net.URL; +import java.util.Properties; /** *

Implements pluggable Datatypes.

@@ -42,6 +39,7 @@ * sync. It is package private for secure class loading.

* * @author Santiago.PericasGeertsen@sun.com + * @author Huizhe.Wang@oracle.com */ class FactoryFinder { @@ -59,7 +57,7 @@ * Flag indicating if properties from java.home/lib/jaxp.properties * have been cached. */ - static boolean firstTime = true; + static volatile boolean firstTime = true; /** * Security support class use to check access control before @@ -95,18 +93,24 @@ * If the class loader supplied is null, first try using the * context class loader followed by the current (i.e. bootstrap) class * loader. + * + * Use bootstrap classLoader if cl = null and useBSClsLoader is true */ static private Class getProviderClass(String className, ClassLoader cl, - boolean doFallback) throws ClassNotFoundException + boolean doFallback, boolean useBSClsLoader) throws ClassNotFoundException { try { if (cl == null) { - cl = ss.getContextClassLoader(); - if (cl == null) { - throw new ClassNotFoundException(); - } - else { - return cl.loadClass(className); + if (useBSClsLoader) { + return Class.forName(className, true, FactoryFinder.class.getClassLoader()); + } else { + cl = ss.getContextClassLoader(); + if (cl == null) { + throw new ClassNotFoundException(); + } + else { + return cl.loadClass(className); + } } } else { @@ -131,8 +135,8 @@ * @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 cl ClassLoader used to load the factory class. If null + * current Thread's context classLoader is used to load the factory class. * * @param doFallback True if the current ClassLoader should be tried as * a fallback if the class is not found using cl @@ -140,8 +144,30 @@ static Object newInstance(String className, ClassLoader cl, boolean doFallback) throws ConfigurationError { + return newInstance(className, cl, doFallback, false); + } + + /** + * Create an instance of a class. Delegates to method + * getProviderClass() in order to load the class. + * + * @param className Name of the concrete class corresponding to the + * service provider + * + * @param cl ClassLoader used to load the factory class. If null + * current Thread's context classLoader is used to load the factory class. + * + * @param doFallback True if the current ClassLoader should be tried as + * a fallback if the class is not found using cl + * + * @param useBSClsLoader True if cl=null actually meant bootstrap classLoader. This parameter + * is needed since DocumentBuilderFactory/SAXParserFactory defined null as context classLoader. + */ + static Object newInstance(String className, ClassLoader cl, boolean doFallback, boolean useBSClsLoader) + throws ConfigurationError + { try { - Class providerClass = getProviderClass(className, cl, doFallback); + Class providerClass = getProviderClass(className, cl, doFallback, useBSClsLoader); Object instance = providerClass.newInstance(); if (debug) { // Extra check to avoid computing cl strings dPrint("created new instance of " + providerClass + @@ -244,6 +270,7 @@ // First try the Context ClassLoader ClassLoader cl = ss.getContextClassLoader(); + boolean useBSClsLoader = false; if (cl != null) { is = ss.getResourceAsStream(cl, serviceId); @@ -251,11 +278,13 @@ if (is == null) { cl = FactoryFinder.class.getClassLoader(); is = ss.getResourceAsStream(cl, serviceId); + useBSClsLoader = true; } } else { // No Context ClassLoader, try the current ClassLoader cl = FactoryFinder.class.getClassLoader(); is = ss.getResourceAsStream(cl, serviceId); + useBSClsLoader = true; } if (is == null) { @@ -293,7 +322,7 @@ // 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. - return newInstance(factoryClassName, cl, false); + return newInstance(factoryClassName, cl, false, useBSClsLoader); } // No provider found diff -r 7b89fed7212b -r ceae213d9812 src/javax/xml/stream/FactoryFinder.java --- a/src/javax/xml/stream/FactoryFinder.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/javax/xml/stream/FactoryFinder.java Tue Apr 17 11:17:59 2012 -0700 @@ -58,7 +58,7 @@ * Flag indicating if properties from java.home/lib/jaxp.properties * have been cached. */ - static boolean firstTime = true; + static volatile boolean firstTime = true; /** * Security support class use to check access control before diff -r 7b89fed7212b -r ceae213d9812 src/javax/xml/transform/FactoryFinder.java --- a/src/javax/xml/transform/FactoryFinder.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/javax/xml/transform/FactoryFinder.java Tue Apr 17 11:17:59 2012 -0700 @@ -25,15 +25,13 @@ package javax.xml.transform; +import java.io.BufferedReader; import java.io.File; -import java.io.FileInputStream; - -import java.util.Properties; -import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import java.net.URL; +import java.lang.reflect.Method; +import java.util.Properties; /** *

Implements pluggable Datatypes.

@@ -42,6 +40,7 @@ * sync. It is package private for secure class loading.

* * @author Santiago.PericasGeertsen@sun.com + * @author Huizhe.Wang@oracle.com */ class FactoryFinder { @@ -59,7 +58,7 @@ * Flag indicating if properties from java.home/lib/jaxp.properties * have been cached. */ - static boolean firstTime = true; + static volatile boolean firstTime = true; /** * Security support class use to check access control before @@ -95,18 +94,24 @@ * If the class loader supplied is null, first try using the * context class loader followed by the current (i.e. bootstrap) class * loader. + * + * Use bootstrap classLoader if cl = null and useBSClsLoader is true */ static private Class getProviderClass(String className, ClassLoader cl, - boolean doFallback) throws ClassNotFoundException + boolean doFallback, boolean useBSClsLoader) throws ClassNotFoundException { try { if (cl == null) { - cl = ss.getContextClassLoader(); - if (cl == null) { - throw new ClassNotFoundException(); - } - else { - return cl.loadClass(className); + if (useBSClsLoader) { + return Class.forName(className, true, FactoryFinder.class.getClassLoader()); + } else { + cl = ss.getContextClassLoader(); + if (cl == null) { + throw new ClassNotFoundException(); + } + else { + return cl.loadClass(className); + } } } else { @@ -131,8 +136,8 @@ * @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 cl ClassLoader used to load the factory class. If null + * current Thread's context classLoader is used to load the factory class. * * @param doFallback True if the current ClassLoader should be tried as * a fallback if the class is not found using cl @@ -140,9 +145,39 @@ static Object newInstance(String className, ClassLoader cl, boolean doFallback) throws ConfigurationError { + return newInstance(className, cl, doFallback, false, false); + } + + /** + * Create an instance of a class. Delegates to method + * getProviderClass() in order to load the class. + * + * @param className Name of the concrete class corresponding to the + * service provider + * + * @param cl ClassLoader used to load the factory class. If null + * current Thread's context classLoader is used to load the factory class. + * + * @param doFallback True if the current ClassLoader should be tried as + * a fallback if the class is not found using cl + * + * @param useBSClsLoader True if cl=null actually meant bootstrap classLoader. This parameter + * is needed since DocumentBuilderFactory/SAXParserFactory defined null as context classLoader. + * + * @param useServicesMechanism True use services mechanism + */ + static Object newInstance(String className, ClassLoader cl, boolean doFallback, boolean useBSClsLoader, boolean useServicesMechanism) + throws ConfigurationError + { try { - Class providerClass = getProviderClass(className, cl, doFallback); - Object instance = providerClass.newInstance(); + Class providerClass = getProviderClass(className, cl, doFallback, useBSClsLoader); + Object instance = null; + if (!useServicesMechanism) { + instance = newInstanceNoServiceLoader(providerClass); + } + if (instance == null) { + instance = providerClass.newInstance(); + } if (debug) { // Extra check to avoid computing cl strings dPrint("created new instance of " + providerClass + " using ClassLoader: " + cl); @@ -159,7 +194,29 @@ x); } } - + /** + * Try to construct using newTransformerFactoryNoServiceLoader + * method if available. + */ + private static Object newInstanceNoServiceLoader( + Class providerClass + ) { + // Retain maximum compatibility if no security manager. + if (System.getSecurityManager() == null) { + return null; + } + try { + Method creationMethod = + providerClass.getDeclaredMethod( + "newTransformerFactoryNoServiceLoader" + ); + return creationMethod.invoke(null, null); + } catch (NoSuchMethodException exc) { + return null; + } catch (Exception exc) { + return null; + } + } /** * Finds the implementation Class object in the specified order. Main * entry point. @@ -176,13 +233,12 @@ throws ConfigurationError { 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, null, true); + return newInstance(systemProp, null, true, false, true); } } catch (SecurityException se) { @@ -210,7 +266,7 @@ if (factoryClassName != null) { dPrint("found in $java.home/jaxp.properties, value=" + factoryClassName); - return newInstance(factoryClassName, null, true); + return newInstance(factoryClassName, null, true, false, true); } } catch (Exception ex) { @@ -228,7 +284,7 @@ } dPrint("loaded from fallback value: " + fallbackClassName); - return newInstance(fallbackClassName, null, true); + return newInstance(fallbackClassName, null, true, false, true); } /* @@ -244,6 +300,7 @@ // First try the Context ClassLoader ClassLoader cl = ss.getContextClassLoader(); + boolean useBSClsLoader = false; if (cl != null) { is = ss.getResourceAsStream(cl, serviceId); @@ -251,11 +308,13 @@ if (is == null) { cl = FactoryFinder.class.getClassLoader(); is = ss.getResourceAsStream(cl, serviceId); - } + useBSClsLoader = true; + } } else { // No Context ClassLoader, try the current ClassLoader cl = FactoryFinder.class.getClassLoader(); is = ss.getResourceAsStream(cl, serviceId); + useBSClsLoader = true; } if (is == null) { @@ -293,7 +352,7 @@ // 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. - return newInstance(factoryClassName, cl, false); + return newInstance(factoryClassName, cl, false, useBSClsLoader, true); } // No provider found diff -r 7b89fed7212b -r ceae213d9812 src/javax/xml/validation/SchemaFactoryFinder.java --- a/src/javax/xml/validation/SchemaFactoryFinder.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/javax/xml/validation/SchemaFactoryFinder.java Tue Apr 17 11:17:59 2012 -0700 @@ -43,6 +43,7 @@ * Implementation of {@link SchemaFactory#newInstance(String)}. * * @author Kohsuke Kawaguchi + * @version $Revision: 1.8 $, $Date: 2010-11-01 04:36:13 $ * @since 1.5 */ class SchemaFactoryFinder { @@ -61,7 +62,7 @@ /** *

First time requires initialization overhead.

*/ - private static boolean firstTime = true; + private static volatile boolean firstTime = true; static { // Use try/catch block to support applets @@ -166,7 +167,7 @@ String r = ss.getSystemProperty(propertyName); if(r!=null) { debugPrintln("The value is '"+r+"'"); - sf = createInstance(r); + sf = createInstance(r, true); if(sf!=null) return sf; } else debugPrintln("The property is undefined."); @@ -201,7 +202,7 @@ debugPrintln("found " + factoryClassName + " in $java.home/jaxp.properties"); if (factoryClassName != null) { - sf = createInstance(factoryClassName); + sf = createInstance(factoryClassName, true); if(sf != null){ return sf; } @@ -254,7 +255,7 @@ // platform default if(schemaLanguage.equals("http://www.w3.org/2001/XMLSchema")) { debugPrintln("attempting to use the platform default XML Schema validator"); - return createInstance("com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory"); + return createInstance("com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory", true); } debugPrintln("all things were tried, but none was found. bailing out."); @@ -294,6 +295,10 @@ * if it fails. Error messages will be printed by this method. */ SchemaFactory createInstance( String className ) { + return createInstance( className, false ); + } + + SchemaFactory createInstance( String className, boolean useServicesMechanism ) { SchemaFactory schemaFactory = null; debugPrintln("createInstance(" + className + ")"); @@ -308,7 +313,12 @@ // instantiate Class as a SchemaFactory try { - schemaFactory = (SchemaFactory) clazz.newInstance(); + if (!useServicesMechanism) { + schemaFactory = (SchemaFactory) newInstanceNoServiceLoader(clazz); + } + if (schemaFactory == null) { + schemaFactory = (SchemaFactory) clazz.newInstance(); + } } catch (ClassCastException classCastException) { debugPrintln("could not instantiate " + clazz.getName()); if (debug) { @@ -331,6 +341,29 @@ return schemaFactory; } + /** + * Try to construct using newTransformerFactoryNoServiceLoader + * method if available. + */ + private static Object newInstanceNoServiceLoader( + Class providerClass + ) { + // Retain maximum compatibility if no security manager. + if (System.getSecurityManager() == null) { + return null; + } + try { + Method creationMethod = + providerClass.getDeclaredMethod( + "newXMLSchemaFactoryNoServiceLoader" + ); + return creationMethod.invoke(null, null); + } catch (NoSuchMethodException exc) { + return null; + } catch (Exception exc) { + return null; + } + } /** Iterator that lazily computes one value and returns it. */ private static abstract class SingleIterator implements Iterator { diff -r 7b89fed7212b -r ceae213d9812 src/javax/xml/xpath/XPathFactoryFinder.java --- a/src/javax/xml/xpath/XPathFactoryFinder.java Thu Apr 12 08:38:26 2012 -0700 +++ b/src/javax/xml/xpath/XPathFactoryFinder.java Tue Apr 17 11:17:59 2012 -0700 @@ -44,6 +44,7 @@ * Implementation of {@link XPathFactory#newInstance(String)}. * * @author Kohsuke Kawaguchi + * @version $Revision: 1.7 $, $Date: 2010-11-01 04:36:14 $ * @since 1.5 */ class XPathFactoryFinder { @@ -68,7 +69,7 @@ /** *

First time requires initialization overhead.

*/ - private static boolean firstTime = true; + private volatile static boolean firstTime = true; /** *

Conditional debug printing.

@@ -163,7 +164,7 @@ String r = ss.getSystemProperty(propertyName); if(r!=null) { debugPrintln("The value is '"+r+"'"); - xpathFactory = createInstance(r); + xpathFactory = createInstance(r, true); if(xpathFactory != null) return xpathFactory; } else debugPrintln("The property is undefined."); @@ -198,7 +199,7 @@ debugPrintln("found " + factoryClassName + " in $java.home/jaxp.properties"); if (factoryClassName != null) { - xpathFactory = createInstance(factoryClassName); + xpathFactory = createInstance(factoryClassName, true); if(xpathFactory != null){ return xpathFactory; } @@ -231,7 +232,7 @@ // platform default if(uri.equals(XPathFactory.DEFAULT_OBJECT_MODEL_URI)) { debugPrintln("attempting to use the platform default W3C DOM XPath lib"); - return createInstance("com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl"); + return createInstance("com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl", true); } debugPrintln("all things were tried, but none was found. bailing out."); @@ -271,6 +272,9 @@ * if it fails. Error messages will be printed by this method. */ XPathFactory createInstance( String className ) { + return createInstance( className, false ); + } + XPathFactory createInstance( String className, boolean useServicesMechanism ) { XPathFactory xPathFactory = null; debugPrintln("createInstance(" + className + ")"); @@ -285,7 +289,12 @@ // instantiate Class as a XPathFactory try { + if (!useServicesMechanism) { + xPathFactory = (XPathFactory) newInstanceNoServiceLoader(clazz); + } + if (xPathFactory == null) { xPathFactory = (XPathFactory) clazz.newInstance(); + } } catch (ClassCastException classCastException) { debugPrintln("could not instantiate " + clazz.getName()); if (debug) { @@ -308,6 +317,29 @@ return xPathFactory; } + /** + * Try to construct using newXPathFactoryNoServiceLoader + * method if available. + */ + private static Object newInstanceNoServiceLoader( + Class providerClass + ) { + // Retain maximum compatibility if no security manager. + if (System.getSecurityManager() == null) { + return null; + } + try { + Method creationMethod = + providerClass.getDeclaredMethod( + "newXPathFactoryNoServiceLoader" + ); + return creationMethod.invoke(null, null); + } catch (NoSuchMethodException exc) { + return null; + } catch (Exception exc) { + return null; + } + } /** *

Look up a value in a property file.

@@ -432,7 +464,7 @@ String factoryClassName = props.getProperty(keyName); if(factoryClassName != null){ debugPrintln("found "+keyName+" = " + factoryClassName); - return createInstance(factoryClassName); + return createInstance(factoryClassName, true); } else { debugPrintln(keyName+" is not in the property file"); return null;