Author: markt Date: Wed Dec 30 22:20:30 2009 New Revision: 894720 URL: http://svn.apache.org/viewvc?rev=894720&view=rev Log: Implement ExpressionFactory.newInstance() and ensure that Jasper does not refer to org.apache.el directly JSP 2.1 TCK passes with these changes applied
Modified: tomcat/trunk/java/javax/el/ExpressionFactory.java tomcat/trunk/java/org/apache/jasper/compiler/JspUtil.java tomcat/trunk/java/org/apache/jasper/compiler/PageInfo.java tomcat/trunk/java/org/apache/jasper/compiler/Validator.java tomcat/trunk/java/org/apache/jasper/runtime/JspApplicationContextImpl.java Modified: tomcat/trunk/java/javax/el/ExpressionFactory.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/javax/el/ExpressionFactory.java?rev=894720&r1=894719&r2=894720&view=diff ============================================================================== --- tomcat/trunk/java/javax/el/ExpressionFactory.java (original) +++ tomcat/trunk/java/javax/el/ExpressionFactory.java Wed Dec 30 22:20:30 2009 @@ -17,6 +17,16 @@ package javax.el; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; import java.util.Properties; /** @@ -25,6 +35,15 @@ */ public abstract class ExpressionFactory { + private static final String SERVICE_RESOURCE_NAME = + "META-INF/services/javax.el.ExpressionFactory"; + + private static final String SEP = System.getProperty("file.separator"); + private static final String PROPERTY_FILE = + System.getProperty("java.home") + "jre" + SEP + "lib" + SEP + + "el.properties"; + private static final String PROPERTY_NAME = "javax.el.ExpressionFactory"; + public abstract Object coerceToType(Object obj, Class<?> expectedType) throws ELException; @@ -39,13 +58,172 @@ String expression, Class<?> expectedReturnType, Class<?>[] expectedParamTypes) throws ELException, NullPointerException; - + + /** + * Create a new {...@link ExpressionFactory}. The class to use is determined by + * the following search order: + * <ol> + * <li>services API (META-INF/services/javax.el.ExpressionFactory)</li> + * <li>$JRE_HOME/lib/el.properties - key javax.el.ExpressionFactory</li> + * <li>javax.el.ExpressionFactory</li> + * <li>Platform default implementation - + * org.apache.el.ExpressionFactoryImpl</li> + * </ol> + * @return + */ public static ExpressionFactory newInstance() { return newInstance(null); } + /** + * Create a new {...@link ExpressionFactory} passing in the provided + * {...@link Properties}. Search order is the same as {...@link #newInstance()}. + * + * @param properties + * @return + */ public static ExpressionFactory newInstance(Properties properties) { - // TODO + String className = null; + ExpressionFactory result = null; + + ClassLoader tccl = Thread.currentThread().getContextClassLoader(); + + // First services API + className = getClassNameServices(tccl); + if (className == null) { + // Second el.properties file + className = getClassNameJreDir(); + } + if (className == null) { + // Third system property + className = getClassNameSysProp(); + } + if (className == null) { + // Fourth - default + className = "org.apache.el.ExpressionFactoryImpl"; + } + + try { + Class<?> clazz = null; + if (tccl == null) { + clazz = Class.forName(className); + } else { + clazz = tccl.loadClass(className); + } + Constructor<?> constructor = null; + // Do we need to look for a constructor that will take properties? + if (properties != null) { + try { + constructor = clazz.getConstructor(Properties.class); + } catch (SecurityException se) { + throw new ELException(se); + } catch (NoSuchMethodException nsme) { + // This can be ignored + // This is OK for this constructor not to exist + } + } + if (constructor == null) { + result = (ExpressionFactory) clazz.newInstance(); + } else { + result = + (ExpressionFactory) constructor.newInstance(properties); + } + + } catch (ClassNotFoundException e) { + throw new ELException( + "Unable to find ExpressionFactory of type: " + className, + e); + } catch (InstantiationException e) { + throw new ELException( + "Unable to create ExpressionFactory of type: " + className, + e); + } catch (IllegalAccessException e) { + throw new ELException( + "Unable to create ExpressionFactory of type: " + className, + e); + } catch (IllegalArgumentException e) { + throw new ELException( + "Unable to create ExpressionFactory of type: " + className, + e); + } catch (InvocationTargetException e) { + throw new ELException( + "Unable to create ExpressionFactory of type: " + className, + e); + } + + return result; + } + + private static String getClassNameServices(ClassLoader tccl) { + InputStream is = null; + + if (tccl == null) { + is = ClassLoader.getSystemResourceAsStream(SERVICE_RESOURCE_NAME); + } else { + is = tccl.getResourceAsStream(SERVICE_RESOURCE_NAME); + } + + if (is != null) { + String line = null; + try { + BufferedReader br = + new BufferedReader(new InputStreamReader(is, "UTF-8")); + line = br.readLine(); + if (line != null && line.trim().length() > 0) { + return line.trim(); + } + } catch (UnsupportedEncodingException e) { + // Should never happen with UTF-8 + // If it does - ignore & return null + } catch (IOException e) { + throw new ELException("Failed to read " + SERVICE_RESOURCE_NAME, + e); + } finally { + try { + is.close(); + } catch (IOException ioe) { + // Ignore + } + } + } + + return null; + } + + private static String getClassNameJreDir() { + File file = new File(PROPERTY_FILE); + if (file.canRead()) { + InputStream is = null; + try { + is = new FileInputStream(file); + Properties props = new Properties(); + props.load(is); + String value = props.getProperty(PROPERTY_NAME); + if (value != null && value.trim().length() > 0) { + return value.trim(); + } + } catch (FileNotFoundException e) { + // Should not happen - ignore it if it does + } catch (IOException e) { + throw new ELException("Failed to read " + PROPERTY_FILE, e); + } finally { + if (is != null) { + try { + is.close(); + } catch (IOException e) { + // Ignore + } + } + } + } + return null; + } + + private static final String getClassNameSysProp() { + String value = System.getProperty(PROPERTY_NAME); + if (value != null && value.trim().length() > 0) { + return value.trim(); + } return null; } } Modified: tomcat/trunk/java/org/apache/jasper/compiler/JspUtil.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/jasper/compiler/JspUtil.java?rev=894720&r1=894719&r2=894720&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/jasper/compiler/JspUtil.java (original) +++ tomcat/trunk/java/org/apache/jasper/compiler/JspUtil.java Wed Dec 30 22:20:30 2009 @@ -49,9 +49,6 @@ private static final String OPEN_EXPR = "<%="; private static final String CLOSE_EXPR = "%>"; - // private static ExpressionEvaluatorImpl expressionEvaluator - // = new ExpressionEvaluatorImpl(); - private static final String javaKeywords[] = { "abstract", "assert", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "continue", "default", "do", "double", "else", "enum", Modified: tomcat/trunk/java/org/apache/jasper/compiler/PageInfo.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/jasper/compiler/PageInfo.java?rev=894720&r1=894719&r2=894720&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/jasper/compiler/PageInfo.java (original) +++ tomcat/trunk/java/org/apache/jasper/compiler/PageInfo.java Wed Dec 30 22:20:30 2009 @@ -24,7 +24,6 @@ import java.util.Set; import java.util.Vector; -import org.apache.el.ExpressionFactoryImpl; import org.apache.jasper.Constants; import org.apache.jasper.JasperException; @@ -76,7 +75,8 @@ // JSP 2.1 private String deferredSyntaxAllowedAsLiteralValue; private boolean deferredSyntaxAllowedAsLiteral = false; - private ExpressionFactory expressionFactory = new ExpressionFactoryImpl(); + private ExpressionFactory expressionFactory = + ExpressionFactory.newInstance(); private String trimDirectiveWhitespacesValue; private boolean trimDirectiveWhitespaces = false; Modified: tomcat/trunk/java/org/apache/jasper/compiler/Validator.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/jasper/compiler/Validator.java?rev=894720&r1=894719&r2=894720&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/jasper/compiler/Validator.java (original) +++ tomcat/trunk/java/org/apache/jasper/compiler/Validator.java Wed Dec 30 22:20:30 2009 @@ -35,7 +35,6 @@ import javax.servlet.jsp.tagext.TagLibraryInfo; import javax.servlet.jsp.tagext.ValidationMessage; -import org.apache.el.lang.ELSupport; import org.apache.jasper.JasperException; import org.apache.jasper.el.ELContextImpl; import org.xml.sax.Attributes; @@ -502,6 +501,9 @@ new JspUtil.ValidAttribute("doctype-public"), new JspUtil.ValidAttribute("doctype-system") }; + private static final ExpressionFactory EXPRESSION_FACTORY = + ExpressionFactory.newInstance(); + /* * Constructor */ @@ -1160,7 +1162,7 @@ } // Check casting try { - ELSupport.checkType(attrs.getValue(i), expectedClass); + EXPRESSION_FACTORY.coerceToType(attrs.getValue(i), expectedClass); } catch (Exception e) { err.jspError (n, "jsp.error.coerce_to_type", Modified: tomcat/trunk/java/org/apache/jasper/runtime/JspApplicationContextImpl.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/jasper/runtime/JspApplicationContextImpl.java?rev=894720&r1=894719&r2=894720&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/jasper/runtime/JspApplicationContextImpl.java (original) +++ tomcat/trunk/java/org/apache/jasper/runtime/JspApplicationContextImpl.java Wed Dec 30 22:20:30 2009 @@ -38,7 +38,6 @@ import javax.servlet.jsp.el.ImplicitObjectELResolver; import javax.servlet.jsp.el.ScopedAttributeELResolver; -import org.apache.el.ExpressionFactoryImpl; import org.apache.jasper.Constants; import org.apache.jasper.el.ELContextImpl; @@ -51,7 +50,8 @@ private final static String KEY = JspApplicationContextImpl.class.getName(); - private final static ExpressionFactory expressionFactory = new ExpressionFactoryImpl(); + private final static ExpressionFactory expressionFactory = + ExpressionFactory.newInstance(); private final List<ELContextListener> contextListeners = new ArrayList<ELContextListener>(); --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org