You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by mu...@apache.org on 2009/09/28 03:55:35 UTC
svn commit: r819444 [6/27] - in /struts/struts2/trunk/plugins/embeddedjsp:
./ src/main/java/org/apache/struts2/el/
src/main/java/org/apache/struts2/el/lang/
src/main/java/org/apache/struts2/el/parser/
src/main/java/org/apache/struts2/el/util/ src/main/...
Added: struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/el/util/ConcurrentCache.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/el/util/ConcurrentCache.java?rev=819444&view=auto
==============================================================================
--- struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/el/util/ConcurrentCache.java (added)
+++ struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/el/util/ConcurrentCache.java Mon Sep 28 01:55:26 2009
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts2.el.util;
+
+import java.util.Map;
+import java.util.WeakHashMap;
+import java.util.concurrent.ConcurrentHashMap;
+
+public final class ConcurrentCache<K,V> {
+
+ private final int size;
+
+ private final Map<K,V> eden;
+
+ private final Map<K,V> longterm;
+
+ public ConcurrentCache(int size) {
+ this.size = size;
+ this.eden = new ConcurrentHashMap<K,V>(size);
+ this.longterm = new WeakHashMap<K,V>(size);
+ }
+
+ public V get(K k) {
+ V v = this.eden.get(k);
+ if (v == null) {
+ v = this.longterm.get(k);
+ if (v != null) {
+ this.eden.put(k, v);
+ }
+ }
+ return v;
+ }
+
+ public void put(K k, V v) {
+ if (this.eden.size() >= size) {
+ this.longterm.putAll(this.eden);
+ this.eden.clear();
+ }
+ this.eden.put(k, v);
+ }
+}
Added: struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/el/util/MessageFactory.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/el/util/MessageFactory.java?rev=819444&view=auto
==============================================================================
--- struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/el/util/MessageFactory.java (added)
+++ struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/el/util/MessageFactory.java Mon Sep 28 01:55:26 2009
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts2.el.util;
+
+import java.text.MessageFormat;
+import java.util.ResourceBundle;
+
+/**
+ * @author Jacob Hookom [jacob@hookom.net]
+ * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: rjung $
+ */
+public final class MessageFactory {
+
+ protected final static ResourceBundle bundle = ResourceBundle
+ .getBundle("org.apache.el.Messages");
+ /**
+ *
+ */
+ public MessageFactory() {
+ super();
+ }
+
+ public static String get(final String key) {
+ return bundle.getString(key);
+ }
+
+ public static String get(final String key, final Object obj0) {
+ return getArray(key, new Object[] { obj0 });
+ }
+
+ public static String get(final String key, final Object obj0,
+ final Object obj1) {
+ return getArray(key, new Object[] { obj0, obj1 });
+ }
+
+ public static String get(final String key, final Object obj0,
+ final Object obj1, final Object obj2) {
+ return getArray(key, new Object[] { obj0, obj1, obj2 });
+ }
+
+ public static String get(final String key, final Object obj0,
+ final Object obj1, final Object obj2, final Object obj3) {
+ return getArray(key, new Object[] { obj0, obj1, obj2, obj3 });
+ }
+
+ public static String get(final String key, final Object obj0,
+ final Object obj1, final Object obj2, final Object obj3,
+ final Object obj4) {
+ return getArray(key, new Object[] { obj0, obj1, obj2, obj3, obj4 });
+ }
+
+ public static String getArray(final String key, final Object[] objA) {
+ return MessageFormat.format(bundle.getString(key), objA);
+ }
+
+}
Added: struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/el/util/ReflectionUtil.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/el/util/ReflectionUtil.java?rev=819444&view=auto
==============================================================================
--- struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/el/util/ReflectionUtil.java (added)
+++ struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/el/util/ReflectionUtil.java Mon Sep 28 01:55:26 2009
@@ -0,0 +1,184 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts2.el.util;
+
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Array;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+
+import javax.el.ELException;
+import javax.el.MethodNotFoundException;
+import javax.el.PropertyNotFoundException;
+
+import org.apache.struts2.el.lang.ELSupport;
+
+
+/**
+ * Utilities for Managing Serialization and Reflection
+ *
+ * @author Jacob Hookom [jacob@hookom.net]
+ * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: markt $
+ */
+public class ReflectionUtil {
+
+ protected static final String[] EMPTY_STRING = new String[0];
+
+ protected static final String[] PRIMITIVE_NAMES = new String[] { "boolean",
+ "byte", "char", "double", "float", "int", "long", "short", "void" };
+
+ protected static final Class[] PRIMITIVES = new Class[] { boolean.class,
+ byte.class, char.class, double.class, float.class, int.class,
+ long.class, short.class, Void.TYPE };
+
+ /**
+ *
+ */
+ private ReflectionUtil() {
+ super();
+ }
+
+ public static Class forName(String name) throws ClassNotFoundException {
+ if (null == name || "".equals(name)) {
+ return null;
+ }
+ Class c = forNamePrimitive(name);
+ if (c == null) {
+ if (name.endsWith("[]")) {
+ String nc = name.substring(0, name.length() - 2);
+ c = Class.forName(nc, true, Thread.currentThread().getContextClassLoader());
+ c = Array.newInstance(c, 0).getClass();
+ } else {
+ c = Class.forName(name, true, Thread.currentThread().getContextClassLoader());
+ }
+ }
+ return c;
+ }
+
+ protected static Class forNamePrimitive(String name) {
+ if (name.length() <= 8) {
+ int p = Arrays.binarySearch(PRIMITIVE_NAMES, name);
+ if (p >= 0) {
+ return PRIMITIVES[p];
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Converts an array of Class names to Class types
+ * @param s
+ * @return
+ * @throws ClassNotFoundException
+ */
+ public static Class[] toTypeArray(String[] s) throws ClassNotFoundException {
+ if (s == null)
+ return null;
+ Class[] c = new Class[s.length];
+ for (int i = 0; i < s.length; i++) {
+ c[i] = forName(s[i]);
+ }
+ return c;
+ }
+
+ /**
+ * Converts an array of Class types to Class names
+ * @param c
+ * @return
+ */
+ public static String[] toTypeNameArray(Class[] c) {
+ if (c == null)
+ return null;
+ String[] s = new String[c.length];
+ for (int i = 0; i < c.length; i++) {
+ s[i] = c[i].getName();
+ }
+ return s;
+ }
+
+ /**
+ * Returns a method based on the criteria
+ * @param base the object that owns the method
+ * @param property the name of the method
+ * @param paramTypes the parameter types to use
+ * @return the method specified
+ * @throws MethodNotFoundException
+ */
+ public static Method getMethod(Object base, Object property,
+ Class[] paramTypes) throws MethodNotFoundException {
+ if (base == null || property == null) {
+ throw new MethodNotFoundException(MessageFactory.get(
+ "error.method.notfound", base, property,
+ paramString(paramTypes)));
+ }
+
+ String methodName = (property instanceof String) ? (String) property
+ : property.toString();
+
+ Method method = null;
+ try {
+ method = base.getClass().getMethod(methodName, paramTypes);
+ } catch (NoSuchMethodException nsme) {
+ throw new MethodNotFoundException(MessageFactory.get(
+ "error.method.notfound", base, property,
+ paramString(paramTypes)));
+ }
+ return method;
+ }
+
+ protected static final String paramString(Class[] types) {
+ if (types != null) {
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < types.length; i++) {
+ sb.append(types[i].getName()).append(", ");
+ }
+ if (sb.length() > 2) {
+ sb.setLength(sb.length() - 2);
+ }
+ return sb.toString();
+ }
+ return null;
+ }
+
+ /**
+ * @param base
+ * @param property
+ * @return
+ * @throws ELException
+ * @throws PropertyNotFoundException
+ */
+ public static PropertyDescriptor getPropertyDescriptor(Object base,
+ Object property) throws ELException, PropertyNotFoundException {
+ String name = ELSupport.coerceToString(property);
+ PropertyDescriptor p = null;
+ try {
+ PropertyDescriptor[] desc = Introspector.getBeanInfo(
+ base.getClass()).getPropertyDescriptors();
+ for (int i = 0; i < desc.length; i++) {
+ if (desc[i].getName().equals(name)) {
+ return desc[i];
+ }
+ }
+ } catch (IntrospectionException ie) {
+ throw new ELException(ie);
+ }
+ throw new PropertyNotFoundException(MessageFactory.get(
+ "error.property.notfound", base, name));
+ }
+}
Added: struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/Constants.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/Constants.java?rev=819444&view=auto
==============================================================================
--- struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/Constants.java (added)
+++ struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/Constants.java Mon Sep 28 01:55:26 2009
@@ -0,0 +1,208 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.struts2.jasper;
+
+
+/**
+ * Some constants and other global data that are used by the compiler and the runtime.
+ *
+ * @author Anil K. Vijendran
+ * @author Harish Prabandham
+ * @author Shawn Bayern
+ * @author Mark Roth
+ */
+public class Constants {
+
+ /**
+ * The base class of the generated servlets.
+ */
+ public static final String JSP_SERVLET_BASE =
+ System.getProperty("org.apache.struts2.jasper.Constants.JSP_SERVLET_BASE", "org.apache.struts2.jasper.runtime.HttpJspBase");
+
+ /**
+ * _jspService is the name of the method that is called by
+ * HttpJspBase.service(). This is where most of the code generated
+ * from JSPs go.
+ */
+ public static final String SERVICE_METHOD_NAME =
+ System.getProperty("org.apache.struts2.jasper.Constants.SERVICE_METHOD_NAME", "_jspService");
+
+ /**
+ * Default servlet content type.
+ */
+ public static final String SERVLET_CONTENT_TYPE = "text/html";
+
+ /**
+ * These classes/packages are automatically imported by the
+ * generated code.
+ */
+ public static final String[] STANDARD_IMPORTS = {
+ "javax.servlet.*",
+ "javax.servlet.http.*",
+ "javax.servlet.jsp.*"
+ };
+
+ /**
+ * ServletContext attribute for classpath. This is tomcat specific.
+ * Other servlet engines may choose to support this attribute if they
+ * want to have this JSP engine running on them.
+ */
+ public static final String SERVLET_CLASSPATH =
+ System.getProperty("org.apache.struts2.jasper.Constants.SERVLET_CLASSPATH", "org.apache.catalina.jsp_classpath");
+
+ /**
+ * Request attribute for <code><jsp-file></code> element of a
+ * servlet definition. If present on a request, this overrides the
+ * value returned by <code>request.getServletPath()</code> to select
+ * the JSP page to be executed.
+ */
+ public static final String JSP_FILE =
+ System.getProperty("org.apache.struts2.jasper.Constants.JSP_FILE", "org.apache.catalina.jsp_file");
+
+
+ /**
+ * Default size of the JSP buffer.
+ */
+ public static final int DEFAULT_BUFFER_SIZE = 8 * 1024;
+
+ /**
+ * Default size for the tag buffers.
+ */
+ public static final int DEFAULT_TAG_BUFFER_SIZE = 512;
+
+ /**
+ * Default tag handler pool size.
+ */
+ public static final int MAX_POOL_SIZE = 5;
+
+ /**
+ * The query parameter that causes the JSP engine to just
+ * pregenerated the servlet but not invoke it.
+ */
+ public static final String PRECOMPILE =
+ System.getProperty("org.apache.struts2.jasper.Constants.PRECOMPILE", "jsp_precompile");
+
+ /**
+ * The default package name for compiled jsp pages.
+ */
+ public static final String JSP_PACKAGE_NAME =
+ System.getProperty("org.apache.struts2.jasper.Constants.JSP_PACKAGE_NAME", "org.apache.jsp");
+
+ /**
+ * The default package name for tag handlers generated from tag files
+ */
+ public static final String TAG_FILE_PACKAGE_NAME =
+ System.getProperty("org.apache.struts2.jasper.Constants.TAG_FILE_PACKAGE_NAME", "org.apache.jsp.tag");
+
+ /**
+ * Servlet context and request attributes that the JSP engine
+ * uses.
+ */
+ public static final String INC_SERVLET_PATH = "javax.servlet.include.servlet_path";
+ public static final String TMP_DIR = "javax.servlet.context.tempdir";
+
+ // Must be kept in sync with org/apache/catalina/Globals.java
+ public static final String ALT_DD_ATTR =
+ System.getProperty("org.apache.struts2.jasper.Constants.ALT_DD_ATTR", "org.apache.catalina.deploy.alt_dd");
+
+ /**
+ * Public Id and the Resource path (of the cached copy)
+ * of the DTDs for tag library descriptors.
+ */
+ public static final String TAGLIB_DTD_PUBLIC_ID_11 =
+ "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN";
+ public static final String TAGLIB_DTD_RESOURCE_PATH_11 =
+ "/javax/servlet/jsp/resources/web-jsptaglibrary_1_1.dtd";
+ public static final String TAGLIB_DTD_PUBLIC_ID_12 =
+ "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN";
+ public static final String TAGLIB_DTD_RESOURCE_PATH_12 =
+ "/javax/servlet/jsp/resources/web-jsptaglibrary_1_2.dtd";
+
+ /**
+ * Public Id and the Resource path (of the cached copy)
+ * of the DTDs for web application deployment descriptors
+ */
+ public static final String WEBAPP_DTD_PUBLIC_ID_22 =
+ "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN";
+ public static final String WEBAPP_DTD_RESOURCE_PATH_22 =
+ "/javax/servlet/resources/web-app_2_2.dtd";
+ public static final String WEBAPP_DTD_PUBLIC_ID_23 =
+ "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN";
+ public static final String WEBAPP_DTD_RESOURCE_PATH_23 =
+ "/javax/servlet/resources/web-app_2_3.dtd";
+
+ /**
+ * List of the Public IDs that we cache, and their
+ * associated location. This is used by
+ * an EntityResolver to return the location of the
+ * cached copy of a DTD.
+ */
+ public static final String[] CACHED_DTD_PUBLIC_IDS = {
+ TAGLIB_DTD_PUBLIC_ID_11,
+ TAGLIB_DTD_PUBLIC_ID_12,
+ WEBAPP_DTD_PUBLIC_ID_22,
+ WEBAPP_DTD_PUBLIC_ID_23,
+ };
+ public static final String[] CACHED_DTD_RESOURCE_PATHS = {
+ TAGLIB_DTD_RESOURCE_PATH_11,
+ TAGLIB_DTD_RESOURCE_PATH_12,
+ WEBAPP_DTD_RESOURCE_PATH_22,
+ WEBAPP_DTD_RESOURCE_PATH_23,
+ };
+
+ /**
+ * Default URLs to download the pluging for Netscape and IE.
+ */
+ public static final String NS_PLUGIN_URL =
+ "http://java.sun.com/products/plugin/";
+
+ public static final String IE_PLUGIN_URL =
+ "http://java.sun.com/products/plugin/1.2.2/jinstall-1_2_2-win.cab#Version=1,2,2,0";
+
+ /**
+ * Prefix to use for generated temporary variable names
+ */
+ public static final String TEMP_VARIABLE_NAME_PREFIX =
+ System.getProperty("org.apache.struts2.jasper.Constants.TEMP_VARIABLE_NAME_PREFIX", "_jspx_temp");
+
+ /**
+ * A replacement char for "\$".
+ * XXX This is a hack to avoid changing EL interpreter to recognize "\$"
+ * @deprecated
+ */
+ public static final char ESC = '\u001b';
+ /**
+ * @deprecated
+ */
+ public static final String ESCStr = "'\\u001b'";
+
+ /**
+ * Has security been turned on?
+ */
+ public static final boolean IS_SECURITY_ENABLED =
+ (System.getSecurityManager() != null);
+
+ /**
+ * The name of the path parameter used to pass the session identifier
+ * back and forth with the client.
+ */
+ public static final String SESSION_PARAMETER_NAME =
+ System.getProperty("org.apache.catalina.SESSION_PARAMETER_NAME",
+ "jsessionid");
+
+}
Added: struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/CustomCompiler.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/CustomCompiler.java?rev=819444&view=auto
==============================================================================
--- struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/CustomCompiler.java (added)
+++ struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/CustomCompiler.java Mon Sep 28 01:55:26 2009
@@ -0,0 +1,37 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts2.jasper;
+
+import java.io.FileNotFoundException;
+
+public class CustomCompiler extends org.apache.struts2.jasper.compiler.Compiler {
+
+ public boolean isOutDated() {
+ return true;
+ }
+
+ public boolean isOutDated(boolean checkClass) {
+ return true;
+ }
+
+ protected void generateClass(String[] smap) throws FileNotFoundException, JasperException, Exception {
+ }
+}
Added: struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/EmbeddedServletOptions.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/EmbeddedServletOptions.java?rev=819444&view=auto
==============================================================================
--- struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/EmbeddedServletOptions.java (added)
+++ struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/EmbeddedServletOptions.java Mon Sep 28 01:55:26 2009
@@ -0,0 +1,673 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.struts2.jasper;
+
+import java.io.File;
+import java.util.*;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+
+import org.apache.struts2.jasper.compiler.TldLocationsCache;
+import org.apache.struts2.jasper.compiler.JspConfig;
+import org.apache.struts2.jasper.compiler.TagPluginManager;
+import org.apache.struts2.jasper.compiler.Localizer;
+import org.apache.struts2.jasper.xmlparser.ParserUtils;
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+
+/**
+ * A class to hold all init parameters specific to the JSP engine.
+ *
+ * @author Anil K. Vijendran
+ * @author Hans Bergsten
+ * @author Pierre Delisle
+ */
+public final class EmbeddedServletOptions implements Options {
+
+ // Logger
+ private Log log = LogFactory.getLog(EmbeddedServletOptions.class);
+
+ private Properties settings = new Properties();
+
+ /**
+ * Is Jasper being used in development mode?
+ */
+ private boolean development = true;
+
+ /**
+ * Should Ant fork its java compiles of JSP pages.
+ */
+ public boolean fork = true;
+
+ /**
+ * Do you want to keep the generated Java files around?
+ */
+ private boolean keepGenerated = true;
+
+ /**
+ * Should white spaces between directives or actions be trimmed?
+ */
+ private boolean trimSpaces = false;
+
+ /**
+ * Determines whether tag handler pooling is enabled.
+ */
+ private boolean isPoolingEnabled = true;
+
+ /**
+ * Do you want support for "mapped" files? This will generate
+ * servlet that has a print statement per line of the JSP file.
+ * This seems like a really nice feature to have for debugging.
+ */
+ private boolean mappedFile = true;
+
+ /**
+ * Do we want to include debugging information in the class file?
+ */
+ private boolean classDebugInfo = true;
+
+ /**
+ * Background compile thread check interval in seconds.
+ */
+ private int checkInterval = 0;
+
+ /**
+ * Is the generation of SMAP info for JSR45 debuggin suppressed?
+ */
+ private boolean isSmapSuppressed = false;
+
+ /**
+ * Should SMAP info for JSR45 debugging be dumped to a file?
+ */
+ private boolean isSmapDumped = false;
+
+ /**
+ * Are Text strings to be generated as char arrays?
+ */
+ private boolean genStringAsCharArray = false;
+
+ private boolean errorOnUseBeanInvalidClassAttribute = true;
+
+ /**
+ * I want to see my generated servlets. Which directory are they
+ * in?
+ */
+ private File scratchDir;
+
+ /**
+ * Need to have this as is for versions 4 and 5 of IE. Can be set from
+ * the initParams so if it changes in the future all that is needed is
+ * to have a jsp initParam of type ieClassId="<value>"
+ */
+ private String ieClassId = "clsid:8AD9C840-044E-11D1-B3E9-00805F499D93";
+
+ /**
+ * What classpath should I use while compiling generated servlets?
+ */
+ private String classpath = null;
+
+ /**
+ * Compiler to use.
+ */
+ private String compiler = null;
+
+ /**
+ * Compiler target VM.
+ */
+ private String compilerTargetVM = "1.5";
+
+ /**
+ * The compiler source VM.
+ */
+ private String compilerSourceVM = "1.5";
+
+ /**
+ * The compiler class name.
+ */
+ private String compilerClassName = null;
+
+ /**
+ * Cache for the TLD locations
+ */
+ private TldLocationsCache tldLocationsCache = null;
+
+ /**
+ * Jsp config information
+ */
+ private JspConfig jspConfig = null;
+
+ /**
+ * TagPluginManager
+ */
+ private TagPluginManager tagPluginManager = null;
+
+ /**
+ * Java platform encoding to generate the JSP
+ * page servlet.
+ */
+ private String javaEncoding = "UTF8";
+
+ /**
+ * Modification test interval.
+ */
+ private int modificationTestInterval = 4;
+
+ /**
+ * Is generation of X-Powered-By response header enabled/disabled?
+ */
+ private boolean xpoweredBy;
+
+ /**
+ * Should we include a source fragment in exception messages, which could be displayed
+ * to the developer ?
+ */
+ private boolean displaySourceFragment = true;
+
+
+ public String getProperty(String name ) {
+ return settings.getProperty( name );
+ }
+
+ public void setProperty(String name, String value ) {
+ if (name != null && value != null){
+ settings.setProperty( name, value );
+ }
+ }
+
+ /**
+ * Are we keeping generated code around?
+ */
+ public boolean getKeepGenerated() {
+ return keepGenerated;
+ }
+
+ /**
+ * Should white spaces between directives or actions be trimmed?
+ */
+ public boolean getTrimSpaces() {
+ return trimSpaces;
+ }
+
+ public boolean isPoolingEnabled() {
+ return isPoolingEnabled;
+ }
+
+ /**
+ * Are we supporting HTML mapped servlets?
+ */
+ public boolean getMappedFile() {
+ return mappedFile;
+ }
+
+ /**
+ * Should errors be sent to client or thrown into stderr?
+ * @deprecated
+ */
+ @Deprecated
+ public boolean getSendErrorToClient() {
+ return true;
+ }
+
+ /**
+ * Should class files be compiled with debug information?
+ */
+ public boolean getClassDebugInfo() {
+ return classDebugInfo;
+ }
+
+ /**
+ * Background JSP compile thread check intervall
+ */
+ public int getCheckInterval() {
+ return checkInterval;
+ }
+
+ /**
+ * Modification test interval.
+ */
+ public int getModificationTestInterval() {
+ return modificationTestInterval;
+ }
+
+ /**
+ * Is Jasper being used in development mode?
+ */
+ public boolean getDevelopment() {
+ return development;
+ }
+
+ /**
+ * Is the generation of SMAP info for JSR45 debuggin suppressed?
+ */
+ public boolean isSmapSuppressed() {
+ return isSmapSuppressed;
+ }
+
+ /**
+ * Should SMAP info for JSR45 debugging be dumped to a file?
+ */
+ public boolean isSmapDumped() {
+ return isSmapDumped;
+ }
+
+ /**
+ * Are Text strings to be generated as char arrays?
+ */
+ public boolean genStringAsCharArray() {
+ return this.genStringAsCharArray;
+ }
+
+ /**
+ * Class ID for use in the plugin tag when the browser is IE.
+ */
+ public String getIeClassId() {
+ return ieClassId;
+ }
+
+ /**
+ * What is my scratch dir?
+ */
+ public File getScratchDir() {
+ return scratchDir;
+ }
+
+ /**
+ * What classpath should I use while compiling the servlets
+ * generated from JSP files?
+ */
+ public String getClassPath() {
+ return classpath;
+ }
+
+ /**
+ * Is generation of X-Powered-By response header enabled/disabled?
+ */
+ public boolean isXpoweredBy() {
+ return xpoweredBy;
+ }
+
+ /**
+ * Compiler to use.
+ */
+ public String getCompiler() {
+ return compiler;
+ }
+
+ /**
+ * @see Options#getCompilerTargetVM
+ */
+ public String getCompilerTargetVM() {
+ return compilerTargetVM;
+ }
+
+ /**
+ * @see Options#getCompilerSourceVM
+ */
+ public String getCompilerSourceVM() {
+ return compilerSourceVM;
+ }
+
+ /**
+ * Java compiler class to use.
+ */
+ public String getCompilerClassName() {
+ return compilerClassName;
+ }
+
+ public boolean getErrorOnUseBeanInvalidClassAttribute() {
+ return errorOnUseBeanInvalidClassAttribute;
+ }
+
+ public void setErrorOnUseBeanInvalidClassAttribute(boolean b) {
+ errorOnUseBeanInvalidClassAttribute = b;
+ }
+
+ public TldLocationsCache getTldLocationsCache() {
+ return tldLocationsCache;
+ }
+
+ public void setTldLocationsCache( TldLocationsCache tldC ) {
+ tldLocationsCache = tldC;
+ }
+
+ public String getJavaEncoding() {
+ return javaEncoding;
+ }
+
+ public boolean getFork() {
+ return fork;
+ }
+
+ public JspConfig getJspConfig() {
+ return jspConfig;
+ }
+
+ public TagPluginManager getTagPluginManager() {
+ return tagPluginManager;
+ }
+
+ public boolean isCaching() {
+ return false;
+ }
+
+ public Map getCache() {
+ return null;
+ }
+
+ /**
+ * Should we include a source fragment in exception messages, which could be displayed
+ * to the developer ?
+ */
+ public boolean getDisplaySourceFragment() {
+ return displaySourceFragment;
+ }
+
+ /**
+ * Create an EmbeddedServletOptions object using data available from
+ * ServletConfig and ServletContext.
+ */
+ public EmbeddedServletOptions(ServletConfig config,
+ ServletContext context) {
+
+ // JVM version numbers
+ try {
+ if (Float.parseFloat(System.getProperty("java.specification.version")) > 1.4) {
+ compilerSourceVM = compilerTargetVM = "1.5";
+ } else {
+ compilerSourceVM = compilerTargetVM = "1.4";
+ }
+ } catch (NumberFormatException e) {
+ // Ignore
+ }
+
+ Enumeration enumeration=config.getInitParameterNames();
+ while( enumeration.hasMoreElements() ) {
+ String k=(String)enumeration.nextElement();
+ String v=config.getInitParameter( k );
+ setProperty( k, v);
+ }
+
+ // quick hack
+ String validating=config.getInitParameter( "validating");
+ if( "false".equals( validating )) ParserUtils.validating=false;
+
+ String keepgen = config.getInitParameter("keepgenerated");
+ if (keepgen != null) {
+ if (keepgen.equalsIgnoreCase("true")) {
+ this.keepGenerated = true;
+ } else if (keepgen.equalsIgnoreCase("false")) {
+ this.keepGenerated = false;
+ } else {
+ if (log.isWarnEnabled()) {
+ log.warn(Localizer.getMessage("jsp.warning.keepgen"));
+ }
+ }
+ }
+
+
+ String trimsp = config.getInitParameter("trimSpaces");
+ if (trimsp != null) {
+ if (trimsp.equalsIgnoreCase("true")) {
+ trimSpaces = true;
+ } else if (trimsp.equalsIgnoreCase("false")) {
+ trimSpaces = false;
+ } else {
+ if (log.isWarnEnabled()) {
+ log.warn(Localizer.getMessage("jsp.warning.trimspaces"));
+ }
+ }
+ }
+
+ this.isPoolingEnabled = true;
+ String poolingEnabledParam
+ = config.getInitParameter("enablePooling");
+ if (poolingEnabledParam != null
+ && !poolingEnabledParam.equalsIgnoreCase("true")) {
+ if (poolingEnabledParam.equalsIgnoreCase("false")) {
+ this.isPoolingEnabled = false;
+ } else {
+ if (log.isWarnEnabled()) {
+ log.warn(Localizer.getMessage("jsp.warning.enablePooling"));
+ }
+ }
+ }
+
+ String mapFile = config.getInitParameter("mappedfile");
+ if (mapFile != null) {
+ if (mapFile.equalsIgnoreCase("true")) {
+ this.mappedFile = true;
+ } else if (mapFile.equalsIgnoreCase("false")) {
+ this.mappedFile = false;
+ } else {
+ if (log.isWarnEnabled()) {
+ log.warn(Localizer.getMessage("jsp.warning.mappedFile"));
+ }
+ }
+ }
+
+ String debugInfo = config.getInitParameter("classdebuginfo");
+ if (debugInfo != null) {
+ if (debugInfo.equalsIgnoreCase("true")) {
+ this.classDebugInfo = true;
+ } else if (debugInfo.equalsIgnoreCase("false")) {
+ this.classDebugInfo = false;
+ } else {
+ if (log.isWarnEnabled()) {
+ log.warn(Localizer.getMessage("jsp.warning.classDebugInfo"));
+ }
+ }
+ }
+
+ String checkInterval = config.getInitParameter("checkInterval");
+ if (checkInterval != null) {
+ try {
+ this.checkInterval = Integer.parseInt(checkInterval);
+ } catch(NumberFormatException ex) {
+ if (log.isWarnEnabled()) {
+ log.warn(Localizer.getMessage("jsp.warning.checkInterval"));
+ }
+ }
+ }
+
+ String modificationTestInterval = config.getInitParameter("modificationTestInterval");
+ if (modificationTestInterval != null) {
+ try {
+ this.modificationTestInterval = Integer.parseInt(modificationTestInterval);
+ } catch(NumberFormatException ex) {
+ if (log.isWarnEnabled()) {
+ log.warn(Localizer.getMessage("jsp.warning.modificationTestInterval"));
+ }
+ }
+ }
+
+ String development = config.getInitParameter("development");
+ if (development != null) {
+ if (development.equalsIgnoreCase("true")) {
+ this.development = true;
+ } else if (development.equalsIgnoreCase("false")) {
+ this.development = false;
+ } else {
+ if (log.isWarnEnabled()) {
+ log.warn(Localizer.getMessage("jsp.warning.development"));
+ }
+ }
+ }
+
+ String suppressSmap = config.getInitParameter("suppressSmap");
+ if (suppressSmap != null) {
+ if (suppressSmap.equalsIgnoreCase("true")) {
+ isSmapSuppressed = true;
+ } else if (suppressSmap.equalsIgnoreCase("false")) {
+ isSmapSuppressed = false;
+ } else {
+ if (log.isWarnEnabled()) {
+ log.warn(Localizer.getMessage("jsp.warning.suppressSmap"));
+ }
+ }
+ }
+
+ String dumpSmap = config.getInitParameter("dumpSmap");
+ if (dumpSmap != null) {
+ if (dumpSmap.equalsIgnoreCase("true")) {
+ isSmapDumped = true;
+ } else if (dumpSmap.equalsIgnoreCase("false")) {
+ isSmapDumped = false;
+ } else {
+ if (log.isWarnEnabled()) {
+ log.warn(Localizer.getMessage("jsp.warning.dumpSmap"));
+ }
+ }
+ }
+
+ String genCharArray = config.getInitParameter("genStrAsCharArray");
+ if (genCharArray != null) {
+ if (genCharArray.equalsIgnoreCase("true")) {
+ genStringAsCharArray = true;
+ } else if (genCharArray.equalsIgnoreCase("false")) {
+ genStringAsCharArray = false;
+ } else {
+ if (log.isWarnEnabled()) {
+ log.warn(Localizer.getMessage("jsp.warning.genchararray"));
+ }
+ }
+ }
+
+ String errBeanClass =
+ config.getInitParameter("errorOnUseBeanInvalidClassAttribute");
+ if (errBeanClass != null) {
+ if (errBeanClass.equalsIgnoreCase("true")) {
+ errorOnUseBeanInvalidClassAttribute = true;
+ } else if (errBeanClass.equalsIgnoreCase("false")) {
+ errorOnUseBeanInvalidClassAttribute = false;
+ } else {
+ if (log.isWarnEnabled()) {
+ log.warn(Localizer.getMessage("jsp.warning.errBean"));
+ }
+ }
+ }
+
+ String ieClassId = config.getInitParameter("ieClassId");
+ if (ieClassId != null)
+ this.ieClassId = ieClassId;
+
+ String classpath = config.getInitParameter("classpath");
+ if (classpath != null)
+ this.classpath = classpath;
+
+ /*
+ * scratchdir
+ */
+ String dir = config.getInitParameter("scratchdir");
+ if (dir != null) {
+ scratchDir = new File(dir);
+ } else {
+ // First try the Servlet 2.2 javax.servlet.context.tempdir property
+ scratchDir = (File) context.getAttribute(Constants.TMP_DIR);
+ if (scratchDir == null) {
+ // Not running in a Servlet 2.2 container.
+ // Try to get the JDK 1.2 java.io.tmpdir property
+ dir = System.getProperty("java.io.tmpdir");
+ if (dir != null)
+ scratchDir = new File(dir);
+ }
+ }
+ if (this.scratchDir == null) {
+ log.fatal(Localizer.getMessage("jsp.error.no.scratch.dir"));
+ return;
+ }
+
+ if (!(scratchDir.exists() && scratchDir.canRead() &&
+ scratchDir.canWrite() && scratchDir.isDirectory()))
+ log.fatal(Localizer.getMessage("jsp.error.bad.scratch.dir",
+ scratchDir.getAbsolutePath()));
+
+ this.compiler = config.getInitParameter("compiler");
+
+ String compilerTargetVM = config.getInitParameter("compilerTargetVM");
+ if(compilerTargetVM != null) {
+ this.compilerTargetVM = compilerTargetVM;
+ }
+
+ String compilerSourceVM = config.getInitParameter("compilerSourceVM");
+ if(compilerSourceVM != null) {
+ this.compilerSourceVM = compilerSourceVM;
+ }
+
+ String javaEncoding = config.getInitParameter("javaEncoding");
+ if (javaEncoding != null) {
+ this.javaEncoding = javaEncoding;
+ }
+
+ String compilerClassName = config.getInitParameter("compilerClassName");
+ if (compilerClassName != null) {
+ this.compilerClassName = compilerClassName;
+ }
+
+ String fork = config.getInitParameter("fork");
+ if (fork != null) {
+ if (fork.equalsIgnoreCase("true")) {
+ this.fork = true;
+ } else if (fork.equalsIgnoreCase("false")) {
+ this.fork = false;
+ } else {
+ if (log.isWarnEnabled()) {
+ log.warn(Localizer.getMessage("jsp.warning.fork"));
+ }
+ }
+ }
+
+ String xpoweredBy = config.getInitParameter("xpoweredBy");
+ if (xpoweredBy != null) {
+ if (xpoweredBy.equalsIgnoreCase("true")) {
+ this.xpoweredBy = true;
+ } else if (xpoweredBy.equalsIgnoreCase("false")) {
+ this.xpoweredBy = false;
+ } else {
+ if (log.isWarnEnabled()) {
+ log.warn(Localizer.getMessage("jsp.warning.xpoweredBy"));
+ }
+ }
+ }
+
+ String displaySourceFragment = config.getInitParameter("displaySourceFragment");
+ if (displaySourceFragment != null) {
+ if (displaySourceFragment.equalsIgnoreCase("true")) {
+ this.displaySourceFragment = true;
+ } else if (displaySourceFragment.equalsIgnoreCase("false")) {
+ this.displaySourceFragment = false;
+ } else {
+ if (log.isWarnEnabled()) {
+ log.warn(Localizer.getMessage("jsp.warning.displaySourceFragment"));
+ }
+ }
+ }
+
+ // Setup the global Tag Libraries location cache for this
+ // web-application.
+ tldLocationsCache = new TldLocationsCache(context);
+
+ // Setup the jsp config info for this web app.
+ jspConfig = new JspConfig(context);
+
+ // Create a Tag plugin instance
+ tagPluginManager = new TagPluginManager(context);
+ }
+
+}
+
Added: struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/JasperException.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/JasperException.java?rev=819444&view=auto
==============================================================================
--- struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/JasperException.java (added)
+++ struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/JasperException.java Mon Sep 28 01:55:26 2009
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.struts2.jasper;
+
+/**
+ * Base class for all exceptions generated by the JSP engine. Makes it
+ * convienient to catch just this at the top-level.
+ *
+ * @author Anil K. Vijendran
+ */
+public class JasperException extends javax.servlet.ServletException {
+
+ public JasperException(String reason) {
+ super(reason);
+ }
+
+ /**
+ * Creates a JasperException with the embedded exception and the reason for
+ * throwing a JasperException
+ */
+ public JasperException (String reason, Throwable exception) {
+ super(reason, exception);
+ }
+
+ /**
+ * Creates a JasperException with the embedded exception
+ */
+ public JasperException (Throwable exception) {
+ super(exception);
+ }
+}
Added: struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/JspC.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/JspC.java?rev=819444&view=auto
==============================================================================
--- struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/JspC.java (added)
+++ struts/struts2/trunk/plugins/embeddedjsp/src/main/java/org/apache/struts2/jasper/JspC.java Mon Sep 28 01:55:26 2009
@@ -0,0 +1,1237 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.struts2.jasper;
+
+import java.io.BufferedReader;
+import java.io.CharArrayWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.Writer;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.*;
+
+import org.apache.struts2.jasper.compiler.Compiler;
+import org.apache.struts2.jasper.compiler.JspConfig;
+import org.apache.struts2.jasper.compiler.JspRuntimeContext;
+import org.apache.struts2.jasper.compiler.Localizer;
+import org.apache.struts2.jasper.compiler.TagPluginManager;
+import org.apache.struts2.jasper.compiler.TldLocationsCache;
+import org.apache.struts2.jasper.servlet.JspCServletContext;
+import org.apache.struts2.jasper.xmlparser.ParserUtils;
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+import com.opensymphony.xwork2.util.finder.ClassLoaderInterface;
+
+/**
+ * Shell for the jspc compiler. Handles all options associated with the
+ * command line and creates compilation contexts which it then compiles
+ * according to the specified options.
+ *
+ * This version can process files from a _single_ webapp at once, i.e.
+ * a single docbase can be specified.
+ *
+ * It can be used as an Ant task using:
+ * <pre>
+ * <taskdef classname="org.apache.struts2.jasper.JspC" name="jasper2" >
+ * <classpath>
+ * <pathelement location="${java.home}/../lib/tools.jar"/>
+ * <fileset dir="${ENV.CATALINA_HOME}/server/lib">
+ * <include name="*.jar"/>
+ * </fileset>
+ * <fileset dir="${ENV.CATALINA_HOME}/common/lib">
+ * <include name="*.jar"/>
+ * </fileset>
+ * <path refid="myjars"/>
+ * </classpath>
+ * </taskdef>
+ *
+ * <jasper2 verbose="0"
+ * package="my.package"
+ * uriroot="${webapps.dir}/${webapp.name}"
+ * webXmlFragment="${build.dir}/generated_web.xml"
+ * outputDir="${webapp.dir}/${webapp.name}/WEB-INF/src/my/package" />
+ * </pre>
+ *
+ * @author Danno Ferrin
+ * @author Pierre Delisle
+ * @author Costin Manolache
+ * @author Yoav Shapira
+ */
+public class JspC implements Options {
+
+ public static final String DEFAULT_IE_CLASS_ID =
+ "clsid:8AD9C840-044E-11D1-B3E9-00805F499D93";
+
+ // Logger
+ protected static Log log = LogFactory.getLog(JspC.class);
+
+ protected static final String SWITCH_VERBOSE = "-v";
+ protected static final String SWITCH_HELP = "-help";
+ protected static final String SWITCH_OUTPUT_DIR = "-d";
+ protected static final String SWITCH_PACKAGE_NAME = "-p";
+ protected static final String SWITCH_CACHE = "-cache";
+ protected static final String SWITCH_CLASS_NAME = "-c";
+ protected static final String SWITCH_FULL_STOP = "--";
+ protected static final String SWITCH_COMPILE = "-compile";
+ protected static final String SWITCH_SOURCE = "-source";
+ protected static final String SWITCH_TARGET = "-target";
+ protected static final String SWITCH_URI_BASE = "-uribase";
+ protected static final String SWITCH_URI_ROOT = "-uriroot";
+ protected static final String SWITCH_FILE_WEBAPP = "-webapp";
+ protected static final String SWITCH_WEBAPP_INC = "-webinc";
+ protected static final String SWITCH_WEBAPP_XML = "-webxml";
+ protected static final String SWITCH_MAPPED = "-mapped";
+ protected static final String SWITCH_XPOWERED_BY = "-xpoweredBy";
+ protected static final String SWITCH_TRIM_SPACES = "-trimSpaces";
+ protected static final String SWITCH_CLASSPATH = "-classpath";
+ protected static final String SWITCH_DIE = "-die";
+ protected static final String SWITCH_POOLING = "-poolingEnabled";
+ protected static final String SWITCH_ENCODING = "-javaEncoding";
+ protected static final String SWITCH_SMAP = "-smap";
+ protected static final String SWITCH_DUMP_SMAP = "-dumpsmap";
+
+ protected static final String SHOW_SUCCESS ="-s";
+ protected static final String LIST_ERRORS = "-l";
+ protected static final int INC_WEBXML = 10;
+ protected static final int ALL_WEBXML = 20;
+ protected static final int DEFAULT_DIE_LEVEL = 1;
+ protected static final int NO_DIE_LEVEL = 0;
+
+ protected static final String[] insertBefore =
+ { "</web-app>", "<servlet-mapping>", "<session-config>",
+ "<mime-mapping>", "<welcome-file-list>", "<error-page>", "<taglib>",
+ "<resource-env-ref>", "<resource-ref>", "<security-constraint>",
+ "<login-config>", "<security-role>", "<env-entry>", "<ejb-ref>",
+ "<ejb-local-ref>" };
+
+ protected static int die;
+ protected String classPath = null;
+ protected URLClassLoader loader = null;
+ protected boolean trimSpaces = false;
+ protected boolean genStringAsCharArray = false;
+ protected boolean xpoweredBy;
+ protected boolean mappedFile = false;
+ protected boolean poolingEnabled = true;
+ protected File scratchDir;
+ protected String ieClassId = DEFAULT_IE_CLASS_ID;
+ protected String targetPackage;
+ protected String targetClassName;
+ protected String uriBase;
+ protected String uriRoot;
+ protected int dieLevel;
+ protected boolean helpNeeded = false;
+ protected boolean compile = false;
+ protected boolean smapSuppressed = true;
+ protected boolean smapDumped = false;
+ protected boolean caching = true;
+ protected Map cache = new HashMap();
+
+ protected String compiler = null;
+
+ protected String compilerTargetVM = "1.4";
+ protected String compilerSourceVM = "1.4";
+
+ protected boolean classDebugInfo = true;
+
+ /**
+ * Throw an exception if there's a compilation error, or swallow it.
+ * Default is true to preserve old behavior.
+ */
+ protected boolean failOnError = true;
+
+ /**
+ * The file extensions to be handled as JSP files.
+ * Default list is .jsp and .jspx.
+ */
+ protected List extensions;
+
+ /**
+ * The pages.
+ */
+ protected List pages = new Vector();
+
+ /**
+ * Needs better documentation, this data member does.
+ * True by default.
+ */
+ protected boolean errorOnUseBeanInvalidClassAttribute = true;
+
+ /**
+ * The java file encoding. Default
+ * is UTF-8. Added per bugzilla 19622.
+ */
+ protected String javaEncoding = "UTF-8";
+
+ // Generation of web.xml fragments
+ protected String webxmlFile;
+ protected int webxmlLevel;
+ protected boolean addWebXmlMappings = false;
+
+ protected Writer mapout;
+ protected CharArrayWriter servletout;
+ protected CharArrayWriter mappingout;
+
+ /**
+ * The servlet context.
+ */
+ protected JspCServletContext context;
+
+ /**
+ * The runtime context.
+ * Maintain a dummy JspRuntimeContext for compiling tag files.
+ */
+ protected JspRuntimeContext rctxt;
+
+ /**
+ * Cache for the TLD locations
+ */
+ protected TldLocationsCache tldLocationsCache = null;
+
+ protected JspConfig jspConfig = null;
+ protected TagPluginManager tagPluginManager = null;
+
+ protected boolean verbose = false;
+ protected boolean listErrors = false;
+ protected boolean showSuccess = false;
+ protected int argPos;
+ protected boolean fullstop = false;
+ protected String args[];
+
+ private String sourceCode;
+ private ClassLoaderInterface classLoaderInterface;
+
+
+ public static void main(String arg[]) {
+ if (arg.length == 0) {
+ System.out.println(Localizer.getMessage("jspc.usage"));
+ } else {
+ try {
+ JspC jspc = new JspC();
+ jspc.setArgs(arg);
+ if (jspc.helpNeeded) {
+ System.out.println(Localizer.getMessage("jspc.usage"));
+ } else {
+ jspc.execute();
+ }
+ } catch (JasperException je) {
+ System.err.println(je);
+ if (die != NO_DIE_LEVEL) {
+ System.exit(die);
+ }
+ }
+ }
+ }
+
+ public void setArgs(String[] arg) throws JasperException {
+ args = arg;
+ String tok;
+
+ dieLevel = NO_DIE_LEVEL;
+ die = dieLevel;
+
+ while ((tok = nextArg()) != null) {
+ if (tok.equals(SWITCH_VERBOSE)) {
+ verbose = true;
+ showSuccess = true;
+ listErrors = true;
+ } else if (tok.equals(SWITCH_PACKAGE_NAME)) {
+ targetPackage = nextArg();
+ } else if (tok.equals(SWITCH_COMPILE)) {
+ compile=true;
+ } else if (tok.equals(SWITCH_CLASS_NAME)) {
+ targetClassName = nextArg();
+ } else if (tok.equals(SWITCH_URI_BASE)) {
+ uriBase=nextArg();
+ } else if ( tok.equals( SHOW_SUCCESS ) ) {
+ showSuccess = true;
+ } else if ( tok.equals( LIST_ERRORS ) ) {
+ listErrors = true;
+ } else if (tok.equals(SWITCH_WEBAPP_INC)) {
+ webxmlFile = nextArg();
+ if (webxmlFile != null) {
+ webxmlLevel = INC_WEBXML;
+ }
+ } else if (tok.equals(SWITCH_WEBAPP_XML)) {
+ webxmlFile = nextArg();
+ if (webxmlFile != null) {
+ webxmlLevel = ALL_WEBXML;
+ }
+ } else if (tok.equals(SWITCH_MAPPED)) {
+ mappedFile = true;
+ } else if (tok.equals(SWITCH_XPOWERED_BY)) {
+ xpoweredBy = true;
+ } else if (tok.equals(SWITCH_TRIM_SPACES)) {
+ setTrimSpaces(true);
+ } else if (tok.equals(SWITCH_CACHE)) {
+ tok = nextArg();
+ if ("false".equals(tok)) {
+ caching = false;
+ } else {
+ caching = true;
+ }
+ } else if (tok.equals(SWITCH_CLASSPATH)) {
+ setClassPath(nextArg());
+ } else if (tok.startsWith(SWITCH_DIE)) {
+ try {
+ dieLevel = Integer.parseInt(
+ tok.substring(SWITCH_DIE.length()));
+ } catch (NumberFormatException nfe) {
+ dieLevel = DEFAULT_DIE_LEVEL;
+ }
+ die = dieLevel;
+ } else if (tok.equals(SWITCH_HELP)) {
+ helpNeeded = true;
+ } else if (tok.equals(SWITCH_POOLING)) {
+ tok = nextArg();
+ if ("false".equals(tok)) {
+ poolingEnabled = false;
+ } else {
+ poolingEnabled = true;
+ }
+ } else if (tok.equals(SWITCH_ENCODING)) {
+ setJavaEncoding(nextArg());
+ } else if (tok.equals(SWITCH_SOURCE)) {
+ setCompilerSourceVM(nextArg());
+ } else if (tok.equals(SWITCH_TARGET)) {
+ setCompilerTargetVM(nextArg());
+ } else if (tok.equals(SWITCH_SMAP)) {
+ smapSuppressed = false;
+ } else if (tok.equals(SWITCH_DUMP_SMAP)) {
+ smapDumped = true;
+ } else {
+ if (tok.startsWith("-")) {
+ throw new JasperException("Unrecognized option: " + tok +
+ ". Use -help for help.");
+ }
+ if (!fullstop) {
+ argPos--;
+ }
+ // Start treating the rest as JSP Pages
+ break;
+ }
+ }
+
+ // Add all extra arguments to the list of files
+ while( true ) {
+ String file = nextFile();
+ if( file==null ) {
+ break;
+ }
+ pages.add( file );
+ }
+ }
+
+ public String getSourceCode() {
+ return sourceCode;
+ }
+
+ public void setClassLoaderInterface(ClassLoaderInterface classLoaderInterface) {
+ this.classLoaderInterface = classLoaderInterface;
+ }
+
+ public Set<String> getTldAbsolutePaths() {
+ return tldLocationsCache.getAbsolutePathsOfLocations();
+ }
+
+
+
+ public boolean getKeepGenerated() {
+ // isn't this why we are running jspc?
+ return true;
+ }
+
+ public boolean getTrimSpaces() {
+ return trimSpaces;
+ }
+
+ public void setTrimSpaces(boolean ts) {
+ this.trimSpaces = ts;
+ }
+
+ public boolean isPoolingEnabled() {
+ return poolingEnabled;
+ }
+
+ public void setPoolingEnabled(boolean poolingEnabled) {
+ this.poolingEnabled = poolingEnabled;
+ }
+
+ public boolean isXpoweredBy() {
+ return xpoweredBy;
+ }
+
+ public void setXpoweredBy(boolean xpoweredBy) {
+ this.xpoweredBy = xpoweredBy;
+ }
+
+ public boolean getDisplaySourceFragment() {
+ return true;
+ }
+
+ public boolean getErrorOnUseBeanInvalidClassAttribute() {
+ return errorOnUseBeanInvalidClassAttribute;
+ }
+
+ public void setErrorOnUseBeanInvalidClassAttribute(boolean b) {
+ errorOnUseBeanInvalidClassAttribute = b;
+ }
+
+ public int getTagPoolSize() {
+ return Constants.MAX_POOL_SIZE;
+ }
+
+ /**
+ * Are we supporting HTML mapped servlets?
+ */
+ public boolean getMappedFile() {
+ return mappedFile;
+ }
+
+ // Off-line compiler, no need for security manager
+ public Object getProtectionDomain() {
+ return null;
+ }
+
+ /**
+ * @deprecated
+ */
+ @Deprecated
+ public boolean getSendErrorToClient() {
+ return true;
+ }
+
+ public void setClassDebugInfo( boolean b ) {
+ classDebugInfo=b;
+ }
+
+ public boolean getClassDebugInfo() {
+ // compile with debug info
+ return classDebugInfo;
+ }
+
+ /**
+ * @see Options#isCaching()
+ */
+ public boolean isCaching() {
+ return caching;
+ }
+
+ /**
+ * @see Options#isCaching()
+ */
+ public void setCaching(boolean caching) {
+ this.caching = caching;
+ }
+
+ /**
+ * @see Options#getCache()
+ */
+ public Map getCache() {
+ return cache;
+ }
+
+ /**
+ * Background compilation check intervals in seconds
+ */
+ public int getCheckInterval() {
+ return 0;
+ }
+
+ /**
+ * Modification test interval.
+ */
+ public int getModificationTestInterval() {
+ return 0;
+ }
+
+ /**
+ * Is Jasper being used in development mode?
+ */
+ public boolean getDevelopment() {
+ return false;
+ }
+
+ /**
+ * Is the generation of SMAP info for JSR45 debuggin suppressed?
+ */
+ public boolean isSmapSuppressed() {
+ return smapSuppressed;
+ }
+
+ /**
+ * Set smapSuppressed flag.
+ */
+ public void setSmapSuppressed(boolean smapSuppressed) {
+ this.smapSuppressed = smapSuppressed;
+ }
+
+
+ /**
+ * Should SMAP info for JSR45 debugging be dumped to a file?
+ */
+ public boolean isSmapDumped() {
+ return smapDumped;
+ }
+
+ /**
+ * Set smapSuppressed flag.
+ */
+ public void setSmapDumped(boolean smapDumped) {
+ this.smapDumped = smapDumped;
+ }
+
+
+ /**
+ * Determines whether text strings are to be generated as char arrays,
+ * which improves performance in some cases.
+ *
+ * @param genStringAsCharArray true if text strings are to be generated as
+ * char arrays, false otherwise
+ */
+ public void setGenStringAsCharArray(boolean genStringAsCharArray) {
+ this.genStringAsCharArray = genStringAsCharArray;
+ }
+
+ /**
+ * Indicates whether text strings are to be generated as char arrays.
+ *
+ * @return true if text strings are to be generated as char arrays, false
+ * otherwise
+ */
+ public boolean genStringAsCharArray() {
+ return genStringAsCharArray;
+ }
+
+ /**
+ * Sets the class-id value to be sent to Internet Explorer when using
+ * <jsp:plugin> tags.
+ *
+ * @param ieClassId Class-id value
+ */
+ public void setIeClassId(String ieClassId) {
+ this.ieClassId = ieClassId;
+ }
+
+ /**
+ * Gets the class-id value that is sent to Internet Explorer when using
+ * <jsp:plugin> tags.
+ *
+ * @return Class-id value
+ */
+ public String getIeClassId() {
+ return ieClassId;
+ }
+
+ public File getScratchDir() {
+ return scratchDir;
+ }
+
+ public Class getJspCompilerPlugin() {
+ // we don't compile, so this is meanlingless
+ return null;
+ }
+
+ public String getJspCompilerPath() {
+ // we don't compile, so this is meanlingless
+ return null;
+ }
+
+ /**
+ * Compiler to use.
+ */
+ public String getCompiler() {
+ return compiler;
+ }
+
+ public void setCompiler(String c) {
+ compiler=c;
+ }
+
+ /**
+ * Compiler class name to use.
+ */
+ public String getCompilerClassName() {
+ return null;
+ }
+
+ /**
+ * @see Options#getCompilerTargetVM
+ */
+ public String getCompilerTargetVM() {
+ return compilerTargetVM;
+ }
+
+ public void setCompilerTargetVM(String vm) {
+ compilerTargetVM = vm;
+ }
+
+ /**
+ * @see Options#getCompilerSourceVM()
+ */
+ public String getCompilerSourceVM() {
+ return compilerSourceVM;
+ }
+
+ /**
+ * @see Options#getCompilerSourceVM()
+ */
+ public void setCompilerSourceVM(String vm) {
+ compilerSourceVM = vm;
+ }
+
+ public TldLocationsCache getTldLocationsCache() {
+ return tldLocationsCache;
+ }
+
+ /**
+ * Returns the encoding to use for
+ * java files. The default is UTF-8.
+ *
+ * @return String The encoding
+ */
+ public String getJavaEncoding() {
+ return javaEncoding;
+ }
+
+ /**
+ * Sets the encoding to use for
+ * java files.
+ *
+ * @param encodingName The name, e.g. "UTF-8"
+ */
+ public void setJavaEncoding(String encodingName) {
+ javaEncoding = encodingName;
+ }
+
+ public boolean getFork() {
+ return false;
+ }
+
+ public String getClassPath() {
+ if( classPath != null )
+ return classPath;
+ return System.getProperty("java.class.path");
+ }
+
+ public void setClassPath(String s) {
+ classPath=s;
+ }
+
+ /**
+ * Returns the list of file extensions
+ * that are treated as JSP files.
+ *
+ * @return The list of extensions
+ */
+ public List getExtensions() {
+ return extensions;
+ }
+
+ /**
+ * Adds the given file extension to the
+ * list of extensions handled as JSP files.
+ *
+ * @param extension The extension to add, e.g. "myjsp"
+ */
+ protected void addExtension(final String extension) {
+ if(extension != null) {
+ if(extensions == null) {
+ extensions = new Vector();
+ }
+
+ extensions.add(extension);
+ }
+ }
+
+
+ /**
+ * Parses comma-separated list of JSP files to be processed. If the argument
+ * is null, nothing is done.
+ *
+ * <p>Each file is interpreted relative to uriroot, unless it is absolute,
+ * in which case it must start with uriroot.</p>
+ *
+ * @param jspFiles Comma-separated list of JSP files to be processed
+ */
+ public void setJspFiles(final String jspFiles) {
+ if(jspFiles == null) {
+ return;
+ }
+
+ StringTokenizer tok = new StringTokenizer(jspFiles, ",");
+ while (tok.hasMoreTokens()) {
+ pages.add(tok.nextToken());
+ }
+ }
+
+ /**
+ * Sets the compile flag.
+ *
+ * @param b Flag value
+ */
+ public void setCompile( final boolean b ) {
+ compile = b;
+ }
+
+ /**
+ * Sets the verbosity level. The actual number doesn't
+ * matter: if it's greater than zero, the verbose flag will
+ * be true.
+ *
+ * @param level Positive means verbose
+ */
+ public void setVerbose( final int level ) {
+ if (level > 0) {
+ verbose = true;
+ showSuccess = true;
+ listErrors = true;
+ }
+ }
+
+ public void setValidateXml( boolean b ) {
+ ParserUtils.validating=b;
+ }
+
+ public void setListErrors( boolean b ) {
+ listErrors = b;
+ }
+
+ public void setPackage( String p ) {
+ targetPackage=p;
+ }
+
+ /**
+ * Class name of the generated file ( without package ).
+ * Can only be used if a single file is converted.
+ * XXX Do we need this feature ?
+ */
+ public void setClassName( String p ) {
+ targetClassName=p;
+ }
+
+ public void setAddWebXmlMappings(boolean b) {
+ addWebXmlMappings = b;
+ }
+
+ /**
+ * Set the option that throws an exception in case of a compilation error.
+ */
+ public void setFailOnError(final boolean b) {
+ failOnError = b;
+ }
+
+ public boolean getFailOnError() {
+ return failOnError;
+ }
+
+ /**
+ * Obtain JSP configuration informantion specified in web.xml.
+ */
+ public JspConfig getJspConfig() {
+ return jspConfig;
+ }
+
+ public TagPluginManager getTagPluginManager() {
+ return tagPluginManager;
+ }
+
+ public void generateWebMapping( String file, JspCompilationContext clctxt )
+ throws IOException
+ {
+ if (log.isDebugEnabled()) {
+ log.debug("Generating web mapping for file " + file
+ + " using compilation context " + clctxt);
+ }
+
+ String className = clctxt.getServletClassName();
+ String packageName = clctxt.getServletPackageName();
+
+ String thisServletName;
+ if ("".equals(packageName)) {
+ thisServletName = className;
+ } else {
+ thisServletName = packageName + '.' + className;
+ }
+
+ if (servletout != null) {
+ servletout.write("\n <servlet>\n <servlet-name>");
+ servletout.write(thisServletName);
+ servletout.write("</servlet-name>\n <servlet-class>");
+ servletout.write(thisServletName);
+ servletout.write("</servlet-class>\n </servlet>\n");
+ }
+ if (mappingout != null) {
+ mappingout.write("\n <servlet-mapping>\n <servlet-name>");
+ mappingout.write(thisServletName);
+ mappingout.write("</servlet-name>\n <url-pattern>");
+ mappingout.write(file.replace('\\', '/'));
+ mappingout.write("</url-pattern>\n </servlet-mapping>\n");
+
+ }
+ }
+
+ /**
+ * Include the generated web.xml inside the webapp's web.xml.
+ */
+ protected void mergeIntoWebXml() throws IOException {
+
+ File webappBase = new File(uriRoot);
+ File webXml = new File(webappBase, "WEB-INF/web.xml");
+ File webXml2 = new File(webappBase, "WEB-INF/web2.xml");
+ String insertStartMarker =
+ Localizer.getMessage("jspc.webinc.insertStart");
+ String insertEndMarker =
+ Localizer.getMessage("jspc.webinc.insertEnd");
+
+ BufferedReader reader = new BufferedReader(new FileReader(webXml));
+ BufferedReader fragmentReader =
+ new BufferedReader(new FileReader(webxmlFile));
+ PrintWriter writer = new PrintWriter(new FileWriter(webXml2));
+
+ // Insert the <servlet> and <servlet-mapping> declarations
+ int pos = -1;
+ String line = null;
+ while (true) {
+ line = reader.readLine();
+ if (line == null) {
+ break;
+ }
+ // Skip anything previously generated by JSPC
+ if (line.indexOf(insertStartMarker) >= 0) {
+ while (true) {
+ line = reader.readLine();
+ if (line == null) {
+ return;
+ }
+ if (line.indexOf(insertEndMarker) >= 0) {
+ line = reader.readLine();
+ line = reader.readLine();
+ if (line == null) {
+ return;
+ }
+ break;
+ }
+ }
+ }
+ for (int i = 0; i < insertBefore.length; i++) {
+ pos = line.indexOf(insertBefore[i]);
+ if (pos >= 0)
+ break;
+ }
+ if (pos >= 0) {
+ writer.print(line.substring(0, pos));
+ break;
+ } else {
+ writer.println(line);
+ }
+ }
+
+ writer.println(insertStartMarker);
+ while (true) {
+ String line2 = fragmentReader.readLine();
+ if (line2 == null) {
+ writer.println();
+ break;
+ }
+ writer.println(line2);
+ }
+ writer.println(insertEndMarker);
+ writer.println();
+
+ for (int i = 0; i < pos; i++) {
+ writer.print(" ");
+ }
+ writer.println(line.substring(pos));
+
+ while (true) {
+ line = reader.readLine();
+ if (line == null) {
+ break;
+ }
+ writer.println(line);
+ }
+ writer.close();
+
+ reader.close();
+ fragmentReader.close();
+
+ FileInputStream fis = new FileInputStream(webXml2);
+ FileOutputStream fos = new FileOutputStream(webXml);
+
+ byte buf[] = new byte[512];
+ while (true) {
+ int n = fis.read(buf);
+ if (n < 0) {
+ break;
+ }
+ fos.write(buf, 0, n);
+ }
+
+ fis.close();
+ fos.close();
+
+ webXml2.delete();
+ (new File(webxmlFile)).delete();
+
+ }
+
+ private void processFile(String file)
+ throws JasperException {
+ if (log.isDebugEnabled()) {
+ log.debug("Processing file: " + file);
+ }
+
+ ClassLoader originalClassLoader = null;
+
+ try {
+ // set up a scratch/output dir if none is provided
+ if (scratchDir == null) {
+ String temp = System.getProperty("java.io.tmpdir");
+ if (temp == null) {
+ temp = "";
+ }
+ scratchDir = new File(new File(temp).getAbsolutePath());
+ }
+
+ String jspUri = file.replace('\\', '/');
+ JspCompilationContext clctxt = new JspCompilationContext
+ (jspUri, false, this, context, null, rctxt, classLoaderInterface);
+
+ /* Override the defaults */
+ if ((targetClassName != null) && (targetClassName.length() > 0)) {
+ clctxt.setServletClassName(targetClassName);
+ targetClassName = null;
+ }
+ if (targetPackage != null) {
+ clctxt.setServletPackageName(targetPackage);
+ }
+
+ originalClassLoader = Thread.currentThread().getContextClassLoader();
+ if (loader == null) {
+ initClassLoader(clctxt);
+ }
+ Thread.currentThread().setContextClassLoader(loader);
+
+ clctxt.setClassLoader(loader);
+ clctxt.setClassPath(classPath);
+
+ Compiler clc = clctxt.createCompiler();
+
+ // If compile is set, generate both .java and .class, if
+ // .jsp file is newer than .class file;
+ // Otherwise only generate .java, if .jsp file is newer than
+ // the .java file
+ if (clc.isOutDated(compile)) {
+ if (log.isDebugEnabled()) {
+ log.debug(jspUri + " is out dated, compiling...");
+ }
+
+ clc.compile(compile, true);
+ }
+
+ // Generate mapping
+ generateWebMapping(file, clctxt);
+ if (showSuccess) {
+ log.info("Built File: " + file);
+ }
+
+ this.sourceCode = clctxt.getSourceCode();
+
+ } catch (JasperException je) {
+ Throwable rootCause = je;
+ while (rootCause instanceof JasperException
+ && ((JasperException) rootCause).getRootCause() != null) {
+ rootCause = ((JasperException) rootCause).getRootCause();
+ }
+ if (rootCause != je) {
+ log.error(Localizer.getMessage("jspc.error.generalException",
+ file),
+ rootCause);
+ }
+
+ // Bugzilla 35114.
+ if (getFailOnError()) {
+ throw je;
+ } else {
+ log.error(je.getMessage(), je);
+ ;
+ }
+
+ } catch (Exception e) {
+ if ((e instanceof FileNotFoundException) && log.isWarnEnabled()) {
+ log.warn(Localizer.getMessage("jspc.error.fileDoesNotExist",
+ e.getMessage()));
+ }
+ throw new JasperException(e);
+ } finally {
+ if (originalClassLoader != null) {
+ Thread.currentThread().setContextClassLoader(originalClassLoader);
+ }
+ }
+ }
+
+
+ /**
+ * Locate all jsp files in the webapp. Used if no explicit
+ * jsps are specified.
+ */
+ public void scanFiles( File base ) throws JasperException {
+ Stack<String> dirs = new Stack<String>();
+ dirs.push(base.toString());
+
+ // Make sure default extensions are always included
+ if ((getExtensions() == null) || (getExtensions().size() < 2)) {
+ addExtension("jsp");
+ addExtension("jspx");
+ }
+
+ while (!dirs.isEmpty()) {
+ String s = dirs.pop();
+ File f = new File(s);
+ if (f.exists() && f.isDirectory()) {
+ String[] files = f.list();
+ String ext;
+ for (int i = 0; (files != null) && i < files.length; i++) {
+ File f2 = new File(s, files[i]);
+ if (f2.isDirectory()) {
+ dirs.push(f2.getPath());
+ } else {
+ String path = f2.getPath();
+ String uri = path.substring(uriRoot.length());
+ ext = files[i].substring(files[i].lastIndexOf('.') +1);
+ if (getExtensions().contains(ext) ||
+ jspConfig.isJspPage(uri)) {
+ pages.add(path);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Executes the compilation.
+ *
+ * @throws JasperException If an error occurs
+ */
+ public void execute() throws JasperException {
+ if (log.isDebugEnabled()) {
+ log.debug("execute() starting for " + pages.size() + " pages.");
+ }
+
+ try {
+ if (context == null) {
+ initServletContext();
+ }
+
+ initWebXml();
+
+ Iterator iter = pages.iterator();
+ while (iter.hasNext()) {
+ String nextjsp = iter.next().toString();
+
+ processFile(nextjsp);
+ }
+
+ completeWebXml();
+ } catch (JasperException je) {
+ Throwable rootCause = je;
+ while (rootCause instanceof JasperException
+ && ((JasperException) rootCause).getRootCause() != null) {
+ rootCause = ((JasperException) rootCause).getRootCause();
+ }
+ if (rootCause != je) {
+ rootCause.printStackTrace();
+ }
+ throw je;
+ }
+ }
+ // ==================== protected utility methods ====================
+
+ protected String nextArg() {
+ if ((argPos >= args.length)
+ || (fullstop = SWITCH_FULL_STOP.equals(args[argPos]))) {
+ return null;
+ } else {
+ return args[argPos++];
+ }
+ }
+
+ protected String nextFile() {
+ if (fullstop) argPos++;
+ if (argPos >= args.length) {
+ return null;
+ } else {
+ return args[argPos++];
+ }
+ }
+
+ protected void initWebXml() {
+ try {
+ if (webxmlLevel >= INC_WEBXML) {
+ File fmapings = new File(webxmlFile);
+ mapout = new FileWriter(fmapings);
+ servletout = new CharArrayWriter();
+ mappingout = new CharArrayWriter();
+ } else {
+ mapout = null;
+ servletout = null;
+ mappingout = null;
+ }
+ if (webxmlLevel >= ALL_WEBXML) {
+ mapout.write(Localizer.getMessage("jspc.webxml.header"));
+ mapout.flush();
+ } else if ((webxmlLevel>= INC_WEBXML) && !addWebXmlMappings) {
+ mapout.write(Localizer.getMessage("jspc.webinc.header"));
+ mapout.flush();
+ }
+ } catch (IOException ioe) {
+ mapout = null;
+ servletout = null;
+ mappingout = null;
+ }
+ }
+
+ protected void completeWebXml() {
+ if (mapout != null) {
+ try {
+ servletout.writeTo(mapout);
+ mappingout.writeTo(mapout);
+ if (webxmlLevel >= ALL_WEBXML) {
+ mapout.write(Localizer.getMessage("jspc.webxml.footer"));
+ } else if ((webxmlLevel >= INC_WEBXML) && !addWebXmlMappings) {
+ mapout.write(Localizer.getMessage("jspc.webinc.footer"));
+ }
+ mapout.close();
+ } catch (IOException ioe) {
+ // noting to do if it fails since we are done with it
+ }
+ }
+ }
+
+ protected void initServletContext() {
+
+ context = new JspCServletContext
+ (new PrintWriter(System.out),
+ classLoaderInterface);
+ tldLocationsCache = new TldLocationsCache(context, true);
+
+ rctxt = new JspRuntimeContext(context, this);
+ jspConfig = new JspConfig(context);
+ tagPluginManager = new TagPluginManager(context);
+ }
+
+ /**
+ * Initializes the classloader as/if needed for the given
+ * compilation context.
+ *
+ * @param clctxt The compilation context
+ * @throws IOException If an error occurs
+ */
+ private void initClassLoader(JspCompilationContext clctxt)
+ throws IOException {
+
+ classPath = getClassPath();
+
+ ClassLoader jspcLoader = getClass().getClassLoader();
+ // Turn the classPath into URLs
+ ArrayList urls = new ArrayList();
+ StringTokenizer tokenizer = new StringTokenizer(classPath,
+ File.pathSeparator);
+ while (tokenizer.hasMoreTokens()) {
+ String path = tokenizer.nextToken();
+ try {
+ File libFile = new File(path);
+ urls.add(libFile.toURL());
+ } catch (IOException ioe) {
+ // Failing a toCanonicalPath on a file that
+ // exists() should be a JVM regression test,
+ // therefore we have permission to freak uot
+ throw new RuntimeException(ioe.toString());
+ }
+ }
+
+ //TODO: add .tld files to the URLCLassLoader
+
+ URL urlsA[] = new URL[urls.size()];
+ urls.toArray(urlsA);
+ loader = new URLClassLoader(urlsA, this.getClass().getClassLoader());
+
+ }
+
+ /**
+ * Find the WEB-INF dir by looking up in the directory tree.
+ * This is used if no explicit docbase is set, but only files.
+ * XXX Maybe we should require the docbase.
+ */
+ protected void locateUriRoot( File f ) {
+ String tUriBase = uriBase;
+ if (tUriBase == null) {
+ tUriBase = "/";
+ }
+ try {
+ if (f.exists()) {
+ f = new File(f.getAbsolutePath());
+ while (f != null) {
+ File g = new File(f, "WEB-INF");
+ if (g.exists() && g.isDirectory()) {
+ uriRoot = f.getCanonicalPath();
+ uriBase = tUriBase;
+ if (log.isInfoEnabled()) {
+ log.info(Localizer.getMessage(
+ "jspc.implicit.uriRoot",
+ uriRoot));
+ }
+ break;
+ }
+ if (f.exists() && f.isDirectory()) {
+ tUriBase = "/" + f.getName() + "/" + tUriBase;
+ }
+
+ String fParent = f.getParent();
+ if (fParent == null) {
+ break;
+ } else {
+ f = new File(fParent);
+ }
+
+ // If there is no acceptible candidate, uriRoot will
+ // remain null to indicate to the CompilerContext to
+ // use the current working/user dir.
+ }
+
+ if (uriRoot != null) {
+ File froot = new File(uriRoot);
+ uriRoot = froot.getCanonicalPath();
+ }
+ }
+ } catch (IOException ioe) {
+ // since this is an optional default and a null value
+ // for uriRoot has a non-error meaning, we can just
+ // pass straight through
+ }
+ }
+}