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/07/31 20:12:51 UTC
svn commit: r799681 [17/24] - in /struts/sandbox/trunk/struts2-jsp-plugin:
./ src/main/java/org/apache/struts/ src/main/java/org/apache/struts2/
src/main/java/org/apache/struts2/compiler/
src/main/java/org/apache/struts2/jasper/ src/main/java/org/apach...
Added: struts/sandbox/trunk/struts2-jsp-plugin/src/main/java/org/apache/struts2/jasper/runtime/HttpJspBase.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-jsp-plugin/src/main/java/org/apache/struts2/jasper/runtime/HttpJspBase.java?rev=799681&view=auto
==============================================================================
--- struts/sandbox/trunk/struts2-jsp-plugin/src/main/java/org/apache/struts2/jasper/runtime/HttpJspBase.java (added)
+++ struts/sandbox/trunk/struts2-jsp-plugin/src/main/java/org/apache/struts2/jasper/runtime/HttpJspBase.java Fri Jul 31 18:12:48 2009
@@ -0,0 +1,116 @@
+/*
+ * 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.runtime;
+
+import java.io.IOException;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.jsp.HttpJspPage;
+import javax.servlet.jsp.JspFactory;
+
+import org.apache.struts2.jasper.compiler.Localizer;
+
+/**
+ * This is the super class of all JSP-generated servlets.
+ *
+ * @author Anil K. Vijendran
+ */
+public abstract class HttpJspBase
+ extends HttpServlet
+ implements HttpJspPage
+
+
+{
+
+ static {
+ if( JspFactory.getDefaultFactory() == null ) {
+ JspFactoryImpl factory = new JspFactoryImpl();
+ if( System.getSecurityManager() != null ) {
+ String basePackage = "org.apache.struts2.jasper.";
+ try {
+ factory.getClass().getClassLoader().loadClass( basePackage +
+ "runtime.JspFactoryImpl$PrivilegedGetPageContext");
+ factory.getClass().getClassLoader().loadClass( basePackage +
+ "runtime.JspFactoryImpl$PrivilegedReleasePageContext");
+ factory.getClass().getClassLoader().loadClass( basePackage +
+ "runtime.JspRuntimeLibrary");
+ factory.getClass().getClassLoader().loadClass( basePackage +
+ "runtime.JspRuntimeLibrary$PrivilegedIntrospectHelper");
+ factory.getClass().getClassLoader().loadClass( basePackage +
+ "runtime.ServletResponseWrapperInclude");
+ factory.getClass().getClassLoader().loadClass( basePackage +
+ "servlet.JspServletWrapper");
+ } catch (ClassNotFoundException ex) {
+ org.apache.commons.logging.LogFactory.getLog( HttpJspBase.class )
+ .error("Jasper JspRuntimeContext preload of class failed: " +
+ ex.getMessage(), ex);
+ }
+ }
+ JspFactory.setDefaultFactory(factory);
+ }
+ }
+
+ protected HttpJspBase() {
+ }
+
+ public final void init(ServletConfig config)
+ throws ServletException
+ {
+ super.init(config);
+ jspInit();
+ _jspInit();
+ }
+
+ public String getServletInfo() {
+ return Localizer.getMessage("jsp.engine.info");
+ }
+
+ public final void destroy() {
+ jspDestroy();
+ _jspDestroy();
+ }
+
+ /**
+ * Entry point into service.
+ */
+ public final void service(HttpServletRequest request, HttpServletResponse response)
+ throws ServletException, IOException
+ {
+ _jspService(request, response);
+ }
+
+ public void jspInit() {
+ }
+
+ public void _jspInit() {
+ }
+
+ public void jspDestroy() {
+ }
+
+ protected void _jspDestroy() {
+ }
+
+ public abstract void _jspService(HttpServletRequest request,
+ HttpServletResponse response)
+ throws ServletException, IOException;
+}
Added: struts/sandbox/trunk/struts2-jsp-plugin/src/main/java/org/apache/struts2/jasper/runtime/JspContextWrapper.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-jsp-plugin/src/main/java/org/apache/struts2/jasper/runtime/JspContextWrapper.java?rev=799681&view=auto
==============================================================================
--- struts/sandbox/trunk/struts2-jsp-plugin/src/main/java/org/apache/struts2/jasper/runtime/JspContextWrapper.java (added)
+++ struts/sandbox/trunk/struts2-jsp-plugin/src/main/java/org/apache/struts2/jasper/runtime/JspContextWrapper.java Fri Jul 31 18:12:48 2009
@@ -0,0 +1,455 @@
+/*
+ * 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.runtime;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.servlet.Servlet;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpSession;
+import javax.servlet.jsp.JspContext;
+import javax.servlet.jsp.JspWriter;
+import javax.servlet.jsp.PageContext;
+import javax.servlet.jsp.el.ELException;
+import javax.servlet.jsp.el.ExpressionEvaluator;
+import javax.servlet.jsp.el.VariableResolver;
+import javax.servlet.jsp.tagext.BodyContent;
+import javax.servlet.jsp.tagext.VariableInfo;
+
+import org.apache.commons.el.VariableResolverImpl;
+import org.apache.struts2.jasper.compiler.Localizer;
+
+/**
+ * Implementation of a JSP Context Wrapper.
+ *
+ * The JSP Context Wrapper is a JspContext created and maintained by a tag
+ * handler implementation. It wraps the Invoking JSP Context, that is, the
+ * JspContext instance passed to the tag handler by the invoking page via
+ * setJspContext().
+ *
+ * @author Kin-man Chung
+ * @author Jan Luehe
+ */
+public class JspContextWrapper
+ extends PageContext implements VariableResolver {
+
+ // Invoking JSP context
+ private PageContext invokingJspCtxt;
+
+ private transient Hashtable pageAttributes;
+
+ // ArrayList of NESTED scripting variables
+ private ArrayList nestedVars;
+
+ // ArrayList of AT_BEGIN scripting variables
+ private ArrayList atBeginVars;
+
+ // ArrayList of AT_END scripting variables
+ private ArrayList atEndVars;
+
+ private Map aliases;
+
+ private Hashtable originalNestedVars;
+
+ /**
+ * The variable resolver, for evaluating EL expressions.
+ */
+ private VariableResolverImpl variableResolver
+ = new VariableResolverImpl(this);
+
+ public JspContextWrapper(JspContext jspContext, ArrayList nestedVars,
+ ArrayList atBeginVars, ArrayList atEndVars,
+ Map aliases) {
+ this.invokingJspCtxt = (PageContext) jspContext;
+ this.nestedVars = nestedVars;
+ this.atBeginVars = atBeginVars;
+ this.atEndVars = atEndVars;
+ this.pageAttributes = new Hashtable(16);
+ this.aliases = aliases;
+
+ if (nestedVars != null) {
+ this.originalNestedVars = new Hashtable(nestedVars.size());
+ }
+ syncBeginTagFile();
+ }
+
+ public void initialize(Servlet servlet, ServletRequest request,
+ ServletResponse response, String errorPageURL,
+ boolean needsSession, int bufferSize,
+ boolean autoFlush)
+ throws IOException, IllegalStateException, IllegalArgumentException
+ {
+ }
+
+ public Object getAttribute(String name) {
+
+ if (name == null) {
+ throw new NullPointerException(
+ Localizer.getMessage("jsp.error.attribute.null_name"));
+ }
+
+ return pageAttributes.get(name);
+ }
+
+ public Object getAttribute(String name, int scope) {
+
+ if (name == null) {
+ throw new NullPointerException(
+ Localizer.getMessage("jsp.error.attribute.null_name"));
+ }
+
+ if (scope == PAGE_SCOPE) {
+ return pageAttributes.get(name);
+ }
+
+ return invokingJspCtxt.getAttribute(name, scope);
+ }
+
+ public void setAttribute(String name, Object value) {
+
+ if (name == null) {
+ throw new NullPointerException(
+ Localizer.getMessage("jsp.error.attribute.null_name"));
+ }
+
+ if (value != null) {
+ pageAttributes.put(name, value);
+ } else {
+ removeAttribute(name, PAGE_SCOPE);
+ }
+ }
+
+ public void setAttribute(String name, Object value, int scope) {
+
+ if (name == null) {
+ throw new NullPointerException(
+ Localizer.getMessage("jsp.error.attribute.null_name"));
+ }
+
+ if (scope == PAGE_SCOPE) {
+ if (value != null) {
+ pageAttributes.put(name, value);
+ } else {
+ removeAttribute(name, PAGE_SCOPE);
+ }
+ } else {
+ invokingJspCtxt.setAttribute(name, value, scope);
+ }
+ }
+
+ public Object findAttribute(String name) {
+
+ if (name == null) {
+ throw new NullPointerException(
+ Localizer.getMessage("jsp.error.attribute.null_name"));
+ }
+
+ Object o = pageAttributes.get(name);
+ if (o == null) {
+ o = invokingJspCtxt.getAttribute(name, REQUEST_SCOPE);
+ if (o == null) {
+ if (getSession() != null) {
+ o = invokingJspCtxt.getAttribute(name, SESSION_SCOPE);
+ }
+ if (o == null) {
+ o = invokingJspCtxt.getAttribute(name, APPLICATION_SCOPE);
+ }
+ }
+ }
+
+ return o;
+ }
+
+ public void removeAttribute(String name) {
+
+ if (name == null) {
+ throw new NullPointerException(
+ Localizer.getMessage("jsp.error.attribute.null_name"));
+ }
+
+ pageAttributes.remove(name);
+ invokingJspCtxt.removeAttribute(name, REQUEST_SCOPE);
+ if (getSession() != null) {
+ invokingJspCtxt.removeAttribute(name, SESSION_SCOPE);
+ }
+ invokingJspCtxt.removeAttribute(name, APPLICATION_SCOPE);
+ }
+
+ public void removeAttribute(String name, int scope) {
+
+ if (name == null) {
+ throw new NullPointerException(
+ Localizer.getMessage("jsp.error.attribute.null_name"));
+ }
+
+ if (scope == PAGE_SCOPE){
+ pageAttributes.remove(name);
+ } else {
+ invokingJspCtxt.removeAttribute(name, scope);
+ }
+ }
+
+ public int getAttributesScope(String name) {
+
+ if (name == null) {
+ throw new NullPointerException(
+ Localizer.getMessage("jsp.error.attribute.null_name"));
+ }
+
+ if (pageAttributes.get(name) != null) {
+ return PAGE_SCOPE;
+ } else {
+ return invokingJspCtxt.getAttributesScope(name);
+ }
+ }
+
+ public Enumeration getAttributeNamesInScope(int scope) {
+ if (scope == PAGE_SCOPE) {
+ return pageAttributes.keys();
+ }
+
+ return invokingJspCtxt.getAttributeNamesInScope(scope);
+ }
+
+ public void release() {
+ invokingJspCtxt.release();
+ }
+
+ public JspWriter getOut() {
+ return invokingJspCtxt.getOut();
+ }
+
+ public HttpSession getSession() {
+ return invokingJspCtxt.getSession();
+ }
+
+ public Object getPage() {
+ return invokingJspCtxt.getPage();
+ }
+
+ public ServletRequest getRequest() {
+ return invokingJspCtxt.getRequest();
+ }
+
+ public ServletResponse getResponse() {
+ return invokingJspCtxt.getResponse();
+ }
+
+ public Exception getException() {
+ return invokingJspCtxt.getException();
+ }
+
+ public ServletConfig getServletConfig() {
+ return invokingJspCtxt.getServletConfig();
+ }
+
+ public ServletContext getServletContext() {
+ return invokingJspCtxt.getServletContext();
+ }
+
+ public void forward(String relativeUrlPath)
+ throws ServletException, IOException
+ {
+ invokingJspCtxt.forward(relativeUrlPath);
+ }
+
+ public void include(String relativeUrlPath)
+ throws ServletException, IOException
+ {
+ invokingJspCtxt.include(relativeUrlPath);
+ }
+
+ public void include(String relativeUrlPath, boolean flush)
+ throws ServletException, IOException {
+ include(relativeUrlPath, false); // XXX
+ }
+
+ public VariableResolver getVariableResolver() {
+ return this;
+ }
+
+ public BodyContent pushBody() {
+ return invokingJspCtxt.pushBody();
+ }
+
+ public JspWriter pushBody(Writer writer) {
+ return invokingJspCtxt.pushBody(writer);
+ }
+
+ public JspWriter popBody() {
+ return invokingJspCtxt.popBody();
+ }
+
+ public ExpressionEvaluator getExpressionEvaluator() {
+ return invokingJspCtxt.getExpressionEvaluator();
+ }
+
+ public void handlePageException(Exception ex)
+ throws IOException, ServletException
+ {
+ // Should never be called since handleException() called with a
+ // Throwable in the generated servlet.
+ handlePageException((Throwable) ex);
+ }
+
+ public void handlePageException(Throwable t)
+ throws IOException, ServletException
+ {
+ invokingJspCtxt.handlePageException(t);
+ }
+
+ /**
+ * VariableResolver interface
+ */
+ public Object resolveVariable( String pName ) throws ELException
+ {
+ return variableResolver.resolveVariable(pName);
+ }
+
+ /**
+ * Synchronize variables at begin of tag file
+ */
+ public void syncBeginTagFile() {
+ saveNestedVariables();
+ }
+
+ /**
+ * Synchronize variables before fragment invokation
+ */
+ public void syncBeforeInvoke() {
+ copyTagToPageScope(VariableInfo.NESTED);
+ copyTagToPageScope(VariableInfo.AT_BEGIN);
+ }
+
+ /**
+ * Synchronize variables at end of tag file
+ */
+ public void syncEndTagFile() {
+ copyTagToPageScope(VariableInfo.AT_BEGIN);
+ copyTagToPageScope(VariableInfo.AT_END);
+ restoreNestedVariables();
+ }
+
+ /**
+ * Copies the variables of the given scope from the virtual page scope of
+ * this JSP context wrapper to the page scope of the invoking JSP context.
+ *
+ * @param scope variable scope (one of NESTED, AT_BEGIN, or AT_END)
+ */
+ private void copyTagToPageScope(int scope) {
+ Iterator iter = null;
+
+ switch (scope) {
+ case VariableInfo.NESTED:
+ if (nestedVars != null) {
+ iter = nestedVars.iterator();
+ }
+ break;
+ case VariableInfo.AT_BEGIN:
+ if (atBeginVars != null) {
+ iter = atBeginVars.iterator();
+ }
+ break;
+ case VariableInfo.AT_END:
+ if (atEndVars != null) {
+ iter = atEndVars.iterator();
+ }
+ break;
+ }
+
+ while ((iter != null) && iter.hasNext()) {
+ String varName = (String) iter.next();
+ Object obj = getAttribute(varName);
+ varName = findAlias(varName);
+ if (obj != null) {
+ invokingJspCtxt.setAttribute(varName, obj);
+ } else {
+ invokingJspCtxt.removeAttribute(varName, PAGE_SCOPE);
+ }
+ }
+ }
+
+ /**
+ * Saves the values of any NESTED variables that are present in
+ * the invoking JSP context, so they can later be restored.
+ */
+ private void saveNestedVariables() {
+ if (nestedVars != null) {
+ Iterator iter = nestedVars.iterator();
+ while (iter.hasNext()) {
+ String varName = (String) iter.next();
+ varName = findAlias(varName);
+ Object obj = invokingJspCtxt.getAttribute(varName);
+ if (obj != null) {
+ originalNestedVars.put(varName, obj);
+ }
+ }
+ }
+ }
+
+ /**
+ * Restores the values of any NESTED variables in the invoking JSP
+ * context.
+ */
+ private void restoreNestedVariables() {
+ if (nestedVars != null) {
+ Iterator iter = nestedVars.iterator();
+ while (iter.hasNext()) {
+ String varName = (String) iter.next();
+ varName = findAlias(varName);
+ Object obj = originalNestedVars.get(varName);
+ if (obj != null) {
+ invokingJspCtxt.setAttribute(varName, obj);
+ } else {
+ invokingJspCtxt.removeAttribute(varName, PAGE_SCOPE);
+ }
+ }
+ }
+ }
+
+ /**
+ * Checks to see if the given variable name is used as an alias, and if so,
+ * returns the variable name for which it is used as an alias.
+ *
+ * @param varName The variable name to check
+ * @return The variable name for which varName is used as an alias, or
+ * varName if it is not being used as an alias
+ */
+ private String findAlias(String varName) {
+
+ if (aliases == null)
+ return varName;
+
+ String alias = (String) aliases.get(varName);
+ if (alias == null) {
+ return varName;
+ }
+ return alias;
+ }
+}
+
Added: struts/sandbox/trunk/struts2-jsp-plugin/src/main/java/org/apache/struts2/jasper/runtime/JspFactoryImpl.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-jsp-plugin/src/main/java/org/apache/struts2/jasper/runtime/JspFactoryImpl.java?rev=799681&view=auto
==============================================================================
--- struts/sandbox/trunk/struts2-jsp-plugin/src/main/java/org/apache/struts2/jasper/runtime/JspFactoryImpl.java (added)
+++ struts/sandbox/trunk/struts2-jsp-plugin/src/main/java/org/apache/struts2/jasper/runtime/JspFactoryImpl.java Fri Jul 31 18:12:48 2009
@@ -0,0 +1,178 @@
+/*
+ * 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.runtime;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import javax.servlet.Servlet;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.jsp.JspFactory;
+import javax.servlet.jsp.JspEngineInfo;
+import javax.servlet.jsp.PageContext;
+
+import org.apache.struts2.jasper.util.SimplePool;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Implementation of JspFactory.
+ *
+ * @author Anil K. Vijendran
+ */
+public class JspFactoryImpl extends JspFactory {
+
+ // Logger
+ private Log log = LogFactory.getLog(JspFactoryImpl.class);
+
+ private static final String SPEC_VERSION = "2.0";
+ private static final boolean USE_POOL =
+ Boolean.valueOf(System.getProperty("org.apache.struts2.jasper.runtime.JspFactoryImpl.USE_POOL", "true")).booleanValue();
+
+ private SimplePool pool = new SimplePool(100);
+
+ public PageContext getPageContext(Servlet servlet,
+ ServletRequest request,
+ ServletResponse response,
+ String errorPageURL,
+ boolean needsSession,
+ int bufferSize,
+ boolean autoflush) {
+ if( System.getSecurityManager() != null ) {
+ PrivilegedGetPageContext dp = new PrivilegedGetPageContext(
+ (JspFactoryImpl)this, servlet, request, response, errorPageURL,
+ needsSession, bufferSize, autoflush);
+ return (PageContext)AccessController.doPrivileged(dp);
+ } else {
+ return internalGetPageContext(servlet, request, response,
+ errorPageURL, needsSession,
+ bufferSize, autoflush);
+ }
+ }
+
+ public void releasePageContext(PageContext pc) {
+ if( pc == null )
+ return;
+ if( System.getSecurityManager() != null ) {
+ PrivilegedReleasePageContext dp = new PrivilegedReleasePageContext(
+ (JspFactoryImpl)this,pc);
+ AccessController.doPrivileged(dp);
+ } else {
+ internalReleasePageContext(pc);
+ }
+ }
+
+ public JspEngineInfo getEngineInfo() {
+ return new JspEngineInfo() {
+ public String getSpecificationVersion() {
+ return SPEC_VERSION;
+ }
+ };
+ }
+
+ private PageContext internalGetPageContext(Servlet servlet,
+ ServletRequest request,
+ ServletResponse response,
+ String errorPageURL,
+ boolean needsSession,
+ int bufferSize,
+ boolean autoflush) {
+ try {
+ PageContext pc;
+ if( USE_POOL ) {
+ pc = (PageContext) pool.get();
+ if( pc == null ) {
+ pc= new PageContextImpl(this);
+ }
+ } else {
+ pc = new PageContextImpl(this);
+ }
+ pc.initialize(servlet, request, response, errorPageURL,
+ needsSession, bufferSize, autoflush);
+ return pc;
+ } catch (Throwable ex) {
+ /* FIXME: need to do something reasonable here!! */
+ log.fatal("Exception initializing page context", ex);
+ return null;
+ }
+ }
+
+ private void internalReleasePageContext(PageContext pc) {
+ pc.release();
+ if (USE_POOL && (pc instanceof PageContextImpl)) {
+ pool.put( pc );
+ }
+ }
+
+ private class PrivilegedGetPageContext implements PrivilegedAction {
+
+ private JspFactoryImpl factory;
+ private Servlet servlet;
+ private ServletRequest request;
+ private ServletResponse response;
+ private String errorPageURL;
+ private boolean needsSession;
+ private int bufferSize;
+ private boolean autoflush;
+
+ PrivilegedGetPageContext(JspFactoryImpl factory,
+ Servlet servlet,
+ ServletRequest request,
+ ServletResponse response,
+ String errorPageURL,
+ boolean needsSession,
+ int bufferSize,
+ boolean autoflush) {
+ this.factory = factory;
+ this.servlet = servlet;
+ this.request = request;
+ this.response = response;
+ this.errorPageURL = errorPageURL;
+ this.needsSession = needsSession;
+ this.bufferSize = bufferSize;
+ this.autoflush = autoflush;
+ }
+
+ public Object run() {
+ return factory.internalGetPageContext(servlet,
+ request,
+ response,
+ errorPageURL,
+ needsSession,
+ bufferSize,
+ autoflush);
+ }
+ }
+
+ private class PrivilegedReleasePageContext implements PrivilegedAction {
+
+ private JspFactoryImpl factory;
+ private PageContext pageContext;
+
+ PrivilegedReleasePageContext(JspFactoryImpl factory,
+ PageContext pageContext) {
+ this.factory = factory;
+ this.pageContext = pageContext;
+ }
+
+ public Object run() {
+ factory.internalReleasePageContext(pageContext);
+ return null;
+ }
+ }
+}
Added: struts/sandbox/trunk/struts2-jsp-plugin/src/main/java/org/apache/struts2/jasper/runtime/JspFragmentHelper.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-jsp-plugin/src/main/java/org/apache/struts2/jasper/runtime/JspFragmentHelper.java?rev=799681&view=auto
==============================================================================
--- struts/sandbox/trunk/struts2-jsp-plugin/src/main/java/org/apache/struts2/jasper/runtime/JspFragmentHelper.java (added)
+++ struts/sandbox/trunk/struts2-jsp-plugin/src/main/java/org/apache/struts2/jasper/runtime/JspFragmentHelper.java Fri Jul 31 18:12:48 2009
@@ -0,0 +1,65 @@
+/*
+ * 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.runtime;
+
+import javax.servlet.jsp.JspContext;
+import javax.servlet.jsp.PageContext;
+import javax.servlet.jsp.tagext.JspFragment;
+import javax.servlet.jsp.tagext.JspTag;
+
+/**
+ * Helper class from which all Jsp Fragment helper classes extend.
+ * This class allows for the emulation of numerous fragments within
+ * a single class, which in turn reduces the load on the class loader
+ * since there are potentially many JspFragments in a single page.
+ * <p>
+ * The class also provides various utility methods for JspFragment
+ * implementations.
+ *
+ * @author Mark Roth
+ */
+public abstract class JspFragmentHelper
+ extends JspFragment
+{
+
+ protected int discriminator;
+ protected JspContext jspContext;
+ protected PageContext _jspx_page_context;
+ protected JspTag parentTag;
+
+ public JspFragmentHelper( int discriminator, JspContext jspContext,
+ JspTag parentTag )
+ {
+ this.discriminator = discriminator;
+ this.jspContext = jspContext;
+ this._jspx_page_context = null;
+ if( jspContext instanceof PageContext ) {
+ _jspx_page_context = (PageContext)jspContext;
+ }
+ this.parentTag = parentTag;
+ }
+
+ public JspContext getJspContext() {
+ return this.jspContext;
+ }
+
+ public JspTag getParentTag() {
+ return this.parentTag;
+ }
+
+}
Added: struts/sandbox/trunk/struts2-jsp-plugin/src/main/java/org/apache/struts2/jasper/runtime/JspRuntimeLibrary.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-jsp-plugin/src/main/java/org/apache/struts2/jasper/runtime/JspRuntimeLibrary.java?rev=799681&view=auto
==============================================================================
--- struts/sandbox/trunk/struts2-jsp-plugin/src/main/java/org/apache/struts2/jasper/runtime/JspRuntimeLibrary.java (added)
+++ struts/sandbox/trunk/struts2-jsp-plugin/src/main/java/org/apache/struts2/jasper/runtime/JspRuntimeLibrary.java Fri Jul 31 18:12:48 2009
@@ -0,0 +1,1044 @@
+/*
+ * 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.runtime;
+
+import java.beans.PropertyEditor;
+import java.beans.PropertyEditorManager;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.Enumeration;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.jsp.JspWriter;
+import javax.servlet.jsp.PageContext;
+import javax.servlet.jsp.tagext.BodyContent;
+
+import org.apache.struts2.jasper.JasperException;
+import org.apache.struts2.jasper.compiler.Localizer;
+
+/**
+ * Bunch of util methods that are used by code generated for useBean,
+ * getProperty and setProperty.
+ *
+ * The __begin, __end stuff is there so that the JSP engine can
+ * actually parse this file and inline them if people don't want
+ * runtime dependencies on this class. However, I'm not sure if that
+ * works so well right now. It got forgotten at some point. -akv
+ *
+ * @author Mandar Raje
+ * @author Shawn Bayern
+ */
+public class JspRuntimeLibrary {
+
+ private static final String SERVLET_EXCEPTION
+ = "javax.servlet.error.exception";
+ private static final String JSP_EXCEPTION
+ = "javax.servlet.jsp.jspException";
+
+ protected static class PrivilegedIntrospectHelper
+ implements PrivilegedExceptionAction {
+
+ private Object bean;
+ private String prop;
+ private String value;
+ private ServletRequest request;
+ private String param;
+ private boolean ignoreMethodNF;
+
+ PrivilegedIntrospectHelper(Object bean, String prop,
+ String value, ServletRequest request,
+ String param, boolean ignoreMethodNF)
+ {
+ this.bean = bean;
+ this.prop = prop;
+ this.value = value;
+ this.request = request;
+ this.param = param;
+ this.ignoreMethodNF = ignoreMethodNF;
+ }
+
+ public Object run() throws JasperException {
+ internalIntrospecthelper(
+ bean,prop,value,request,param,ignoreMethodNF);
+ return null;
+ }
+ }
+
+ /**
+ * Returns the value of the javax.servlet.error.exception request
+ * attribute value, if present, otherwise the value of the
+ * javax.servlet.jsp.jspException request attribute value.
+ *
+ * This method is called at the beginning of the generated servlet code
+ * for a JSP error page, when the "exception" implicit scripting language
+ * variable is initialized.
+ */
+ public static Throwable getThrowable(ServletRequest request) {
+ Throwable error = (Throwable) request.getAttribute(SERVLET_EXCEPTION);
+ if (error == null) {
+ error = (Throwable) request.getAttribute(JSP_EXCEPTION);
+ if (error != null) {
+ /*
+ * The only place that sets JSP_EXCEPTION is
+ * PageContextImpl.handlePageException(). It really should set
+ * SERVLET_EXCEPTION, but that would interfere with the
+ * ErrorReportValve. Therefore, if JSP_EXCEPTION is set, we
+ * need to set SERVLET_EXCEPTION.
+ */
+ request.setAttribute(SERVLET_EXCEPTION, error);
+ }
+ }
+
+ return error;
+ }
+
+ public static boolean coerceToBoolean(String s) {
+ if (s == null || s.length() == 0)
+ return false;
+ else
+ return Boolean.valueOf(s).booleanValue();
+ }
+
+ public static byte coerceToByte(String s) {
+ if (s == null || s.length() == 0)
+ return (byte) 0;
+ else
+ return Byte.valueOf(s).byteValue();
+ }
+
+ public static char coerceToChar(String s) {
+ if (s == null || s.length() == 0) {
+ return (char) 0;
+ } else {
+ // this trick avoids escaping issues
+ return (char)(int) s.charAt(0);
+ }
+ }
+
+ public static double coerceToDouble(String s) {
+ if (s == null || s.length() == 0)
+ return (double) 0;
+ else
+ return Double.valueOf(s).doubleValue();
+ }
+
+ public static float coerceToFloat(String s) {
+ if (s == null || s.length() == 0)
+ return (float) 0;
+ else
+ return Float.valueOf(s).floatValue();
+ }
+
+ public static int coerceToInt(String s) {
+ if (s == null || s.length() == 0)
+ return 0;
+ else
+ return Integer.valueOf(s).intValue();
+ }
+
+ public static short coerceToShort(String s) {
+ if (s == null || s.length() == 0)
+ return (short) 0;
+ else
+ return Short.valueOf(s).shortValue();
+ }
+
+ public static long coerceToLong(String s) {
+ if (s == null || s.length() == 0)
+ return (long) 0;
+ else
+ return Long.valueOf(s).longValue();
+ }
+
+ public static Object coerce(String s, Class target) {
+
+ boolean isNullOrEmpty = (s == null || s.length() == 0);
+
+ if (target == Boolean.class) {
+ if (isNullOrEmpty) {
+ s = "false";
+ }
+ return new Boolean(s);
+ } else if (target == Byte.class) {
+ if (isNullOrEmpty)
+ return new Byte((byte) 0);
+ else
+ return new Byte(s);
+ } else if (target == Character.class) {
+ if (isNullOrEmpty)
+ return new Character((char) 0);
+ else
+ return new Character(s.charAt(0));
+ } else if (target == Double.class) {
+ if (isNullOrEmpty)
+ return new Double(0);
+ else
+ return new Double(s);
+ } else if (target == Float.class) {
+ if (isNullOrEmpty)
+ return new Float(0);
+ else
+ return new Float(s);
+ } else if (target == Integer.class) {
+ if (isNullOrEmpty)
+ return new Integer(0);
+ else
+ return new Integer(s);
+ } else if (target == Short.class) {
+ if (isNullOrEmpty)
+ return new Short((short) 0);
+ else
+ return new Short(s);
+ } else if (target == Long.class) {
+ if (isNullOrEmpty)
+ return new Long(0);
+ else
+ return new Long(s);
+ } else {
+ return null;
+ }
+ }
+
+ // __begin convertMethod
+ public static Object convert(String propertyName, String s, Class t,
+ Class propertyEditorClass)
+ throws JasperException
+ {
+ try {
+ if (s == null) {
+ if (t.equals(Boolean.class) || t.equals(Boolean.TYPE))
+ s = "false";
+ else
+ return null;
+ }
+ if (propertyEditorClass != null) {
+ return getValueFromBeanInfoPropertyEditor(
+ t, propertyName, s, propertyEditorClass);
+ } else if ( t.equals(Boolean.class) || t.equals(Boolean.TYPE) ) {
+ if (s.equalsIgnoreCase("on") || s.equalsIgnoreCase("true"))
+ s = "true";
+ else
+ s = "false";
+ return new Boolean(s);
+ } else if ( t.equals(Byte.class) || t.equals(Byte.TYPE) ) {
+ return new Byte(s);
+ } else if (t.equals(Character.class) || t.equals(Character.TYPE)) {
+ return s.length() > 0 ? new Character(s.charAt(0)) : null;
+ } else if ( t.equals(Short.class) || t.equals(Short.TYPE) ) {
+ return new Short(s);
+ } else if ( t.equals(Integer.class) || t.equals(Integer.TYPE) ) {
+ return new Integer(s);
+ } else if ( t.equals(Float.class) || t.equals(Float.TYPE) ) {
+ return new Float(s);
+ } else if ( t.equals(Long.class) || t.equals(Long.TYPE) ) {
+ return new Long(s);
+ } else if ( t.equals(Double.class) || t.equals(Double.TYPE) ) {
+ return new Double(s);
+ } else if ( t.equals(String.class) ) {
+ return s;
+ } else if ( t.equals(java.io.File.class) ) {
+ return new java.io.File(s);
+ } else if (t.getName().equals("java.lang.Object")) {
+ return new Object[] {s};
+ } else {
+ return getValueFromPropertyEditorManager(
+ t, propertyName, s);
+ }
+ } catch (Exception ex) {
+ throw new JasperException(ex);
+ }
+ }
+ // __end convertMethod
+
+ // __begin introspectMethod
+ public static void introspect(Object bean, ServletRequest request)
+ throws JasperException
+ {
+ Enumeration e = request.getParameterNames();
+ while ( e.hasMoreElements() ) {
+ String name = (String) e.nextElement();
+ String value = request.getParameter(name);
+ introspecthelper(bean, name, value, request, name, true);
+ }
+ }
+ // __end introspectMethod
+
+ // __begin introspecthelperMethod
+ public static void introspecthelper(Object bean, String prop,
+ String value, ServletRequest request,
+ String param, boolean ignoreMethodNF)
+ throws JasperException
+ {
+ if( System.getSecurityManager() != null ) {
+ try {
+ PrivilegedIntrospectHelper dp =
+ new PrivilegedIntrospectHelper(
+ bean,prop,value,request,param,ignoreMethodNF);
+ AccessController.doPrivileged(dp);
+ } catch( PrivilegedActionException pe) {
+ Exception e = pe.getException();
+ throw (JasperException)e;
+ }
+ } else {
+ internalIntrospecthelper(
+ bean,prop,value,request,param,ignoreMethodNF);
+ }
+ }
+
+ private static void internalIntrospecthelper(Object bean, String prop,
+ String value, ServletRequest request,
+ String param, boolean ignoreMethodNF)
+ throws JasperException
+ {
+ Method method = null;
+ Class type = null;
+ Class propertyEditorClass = null;
+ try {
+ java.beans.BeanInfo info
+ = java.beans.Introspector.getBeanInfo(bean.getClass());
+ if ( info != null ) {
+ java.beans.PropertyDescriptor pd[]
+ = info.getPropertyDescriptors();
+ for (int i = 0 ; i < pd.length ; i++) {
+ if ( pd[i].getName().equals(prop) ) {
+ method = pd[i].getWriteMethod();
+ type = pd[i].getPropertyType();
+ propertyEditorClass = pd[i].getPropertyEditorClass();
+ break;
+ }
+ }
+ }
+ if ( method != null ) {
+ if (type.isArray()) {
+ if (request == null) {
+ throw new JasperException(
+ Localizer.getMessage("jsp.error.beans.setproperty.noindexset"));
+ }
+ Class t = type.getComponentType();
+ String[] values = request.getParameterValues(param);
+ //XXX Please check.
+ if(values == null) return;
+ if(t.equals(String.class)) {
+ method.invoke(bean, new Object[] { values });
+ } else {
+ createTypedArray (prop, bean, method, values, t,
+ propertyEditorClass);
+ }
+ } else {
+ if(value == null || (param != null && value.equals(""))) return;
+ Object oval = convert(prop, value, type, propertyEditorClass);
+ if ( oval != null )
+ method.invoke(bean, new Object[] { oval });
+ }
+ }
+ } catch (Exception ex) {
+ throw new JasperException(ex);
+ }
+ if (!ignoreMethodNF && (method == null)) {
+ if (type == null) {
+ throw new JasperException(
+ Localizer.getMessage("jsp.error.beans.noproperty",
+ prop,
+ bean.getClass().getName()));
+ } else {
+ throw new JasperException(
+ Localizer.getMessage("jsp.error.beans.nomethod.setproperty",
+ prop,
+ type.getName(),
+ bean.getClass().getName()));
+ }
+ }
+ }
+ // __end introspecthelperMethod
+
+ //-------------------------------------------------------------------
+ // functions to convert builtin Java data types to string.
+ //-------------------------------------------------------------------
+ // __begin toStringMethod
+ public static String toString(Object o) {
+ return String.valueOf(o);
+ }
+
+ public static String toString(byte b) {
+ return new Byte(b).toString();
+ }
+
+ public static String toString(boolean b) {
+ return new Boolean(b).toString();
+ }
+
+ public static String toString(short s) {
+ return new Short(s).toString();
+ }
+
+ public static String toString(int i) {
+ return new Integer(i).toString();
+ }
+
+ public static String toString(float f) {
+ return new Float(f).toString();
+ }
+
+ public static String toString(long l) {
+ return new Long(l).toString();
+ }
+
+ public static String toString(double d) {
+ return new Double(d).toString();
+ }
+
+ public static String toString(char c) {
+ return new Character(c).toString();
+ }
+ // __end toStringMethod
+
+
+ /**
+ * Create a typed array.
+ * This is a special case where params are passed through
+ * the request and the property is indexed.
+ */
+ public static void createTypedArray(String propertyName,
+ Object bean,
+ Method method,
+ String[] values,
+ Class t,
+ Class propertyEditorClass)
+ throws JasperException {
+
+ try {
+ if (propertyEditorClass != null) {
+ Object[] tmpval = new Integer[values.length];
+ for (int i=0; i<values.length; i++) {
+ tmpval[i] = getValueFromBeanInfoPropertyEditor(
+ t, propertyName, values[i], propertyEditorClass);
+ }
+ method.invoke (bean, new Object[] {tmpval});
+ } else if (t.equals(Integer.class)) {
+ Integer []tmpval = new Integer[values.length];
+ for (int i = 0 ; i < values.length; i++)
+ tmpval[i] = new Integer (values[i]);
+ method.invoke (bean, new Object[] {tmpval});
+ } else if (t.equals(Byte.class)) {
+ Byte[] tmpval = new Byte[values.length];
+ for (int i = 0 ; i < values.length; i++)
+ tmpval[i] = new Byte (values[i]);
+ method.invoke (bean, new Object[] {tmpval});
+ } else if (t.equals(Boolean.class)) {
+ Boolean[] tmpval = new Boolean[values.length];
+ for (int i = 0 ; i < values.length; i++)
+ tmpval[i] = new Boolean (values[i]);
+ method.invoke (bean, new Object[] {tmpval});
+ } else if (t.equals(Short.class)) {
+ Short[] tmpval = new Short[values.length];
+ for (int i = 0 ; i < values.length; i++)
+ tmpval[i] = new Short (values[i]);
+ method.invoke (bean, new Object[] {tmpval});
+ } else if (t.equals(Long.class)) {
+ Long[] tmpval = new Long[values.length];
+ for (int i = 0 ; i < values.length; i++)
+ tmpval[i] = new Long (values[i]);
+ method.invoke (bean, new Object[] {tmpval});
+ } else if (t.equals(Double.class)) {
+ Double[] tmpval = new Double[values.length];
+ for (int i = 0 ; i < values.length; i++)
+ tmpval[i] = new Double (values[i]);
+ method.invoke (bean, new Object[] {tmpval});
+ } else if (t.equals(Float.class)) {
+ Float[] tmpval = new Float[values.length];
+ for (int i = 0 ; i < values.length; i++)
+ tmpval[i] = new Float (values[i]);
+ method.invoke (bean, new Object[] {tmpval});
+ } else if (t.equals(Character.class)) {
+ Character[] tmpval = new Character[values.length];
+ for (int i = 0 ; i < values.length; i++)
+ tmpval[i] = new Character(values[i].charAt(0));
+ method.invoke (bean, new Object[] {tmpval});
+ } else if (t.equals(int.class)) {
+ int []tmpval = new int[values.length];
+ for (int i = 0 ; i < values.length; i++)
+ tmpval[i] = Integer.parseInt (values[i]);
+ method.invoke (bean, new Object[] {tmpval});
+ } else if (t.equals(byte.class)) {
+ byte[] tmpval = new byte[values.length];
+ for (int i = 0 ; i < values.length; i++)
+ tmpval[i] = Byte.parseByte (values[i]);
+ method.invoke (bean, new Object[] {tmpval});
+ } else if (t.equals(boolean.class)) {
+ boolean[] tmpval = new boolean[values.length];
+ for (int i = 0 ; i < values.length; i++)
+ tmpval[i] = (Boolean.valueOf(values[i])).booleanValue();
+ method.invoke (bean, new Object[] {tmpval});
+ } else if (t.equals(short.class)) {
+ short[] tmpval = new short[values.length];
+ for (int i = 0 ; i < values.length; i++)
+ tmpval[i] = Short.parseShort (values[i]);
+ method.invoke (bean, new Object[] {tmpval});
+ } else if (t.equals(long.class)) {
+ long[] tmpval = new long[values.length];
+ for (int i = 0 ; i < values.length; i++)
+ tmpval[i] = Long.parseLong (values[i]);
+ method.invoke (bean, new Object[] {tmpval});
+ } else if (t.equals(double.class)) {
+ double[] tmpval = new double[values.length];
+ for (int i = 0 ; i < values.length; i++)
+ tmpval[i] = Double.valueOf(values[i]).doubleValue();
+ method.invoke (bean, new Object[] {tmpval});
+ } else if (t.equals(float.class)) {
+ float[] tmpval = new float[values.length];
+ for (int i = 0 ; i < values.length; i++)
+ tmpval[i] = Float.valueOf(values[i]).floatValue();
+ method.invoke (bean, new Object[] {tmpval});
+ } else if (t.equals(char.class)) {
+ char[] tmpval = new char[values.length];
+ for (int i = 0 ; i < values.length; i++)
+ tmpval[i] = values[i].charAt(0);
+ method.invoke (bean, new Object[] {tmpval});
+ } else {
+ Object[] tmpval = new Integer[values.length];
+ for (int i=0; i<values.length; i++) {
+ tmpval[i] =
+ getValueFromPropertyEditorManager(
+ t, propertyName, values[i]);
+ }
+ method.invoke (bean, new Object[] {tmpval});
+ }
+ } catch (Exception ex) {
+ throw new JasperException ("error in invoking method", ex);
+ }
+ }
+
+ /**
+ * Escape special shell characters.
+ * @param unescString The string to shell-escape
+ * @return The escaped shell string.
+ */
+
+ public static String escapeQueryString(String unescString) {
+ if ( unescString == null )
+ return null;
+
+ String escString = "";
+ String shellSpChars = "&;`'\"|*?~<>^()[]{}$\\\n";
+
+ for(int index=0; index<unescString.length(); index++) {
+ char nextChar = unescString.charAt(index);
+
+ if( shellSpChars.indexOf(nextChar) != -1 )
+ escString += "\\";
+
+ escString += nextChar;
+ }
+ return escString;
+ }
+
+ /**
+ * Decode an URL formatted string.
+ * @param encoded The string to decode.
+ * @return The decoded string.
+ */
+
+ public static String decode(String encoded) {
+ // speedily leave if we're not needed
+ if (encoded == null) return null;
+ if (encoded.indexOf('%') == -1 && encoded.indexOf('+') == -1)
+ return encoded;
+
+ //allocate the buffer - use byte[] to avoid calls to new.
+ byte holdbuffer[] = new byte[encoded.length()];
+
+ int bufcount = 0;
+
+ for (int count = 0; count < encoded.length(); count++) {
+ char cur = encoded.charAt(count);
+ if (cur == '%') {
+ holdbuffer[bufcount++] =
+ (byte)Integer.parseInt(encoded.substring(count+1,count+3),16);
+ if (count + 2 >= encoded.length())
+ count = encoded.length();
+ else
+ count += 2;
+ } else if (cur == '+') {
+ holdbuffer[bufcount++] = (byte) ' ';
+ } else {
+ holdbuffer[bufcount++] = (byte) cur;
+ }
+ }
+ // REVISIT -- remedy for Deprecated warning.
+ //return new String(holdbuffer,0,0,bufcount);
+ return new String(holdbuffer,0,bufcount);
+ }
+
+ // __begin lookupReadMethodMethod
+ public static Object handleGetProperty(Object o, String prop)
+ throws JasperException {
+ if (o == null) {
+ throw new JasperException(
+ Localizer.getMessage("jsp.error.beans.nullbean"));
+ }
+ Object value = null;
+ try {
+ Method method = getReadMethod(o.getClass(), prop);
+ value = method.invoke(o, null);
+ } catch (Exception ex) {
+ throw new JasperException (ex);
+ }
+ return value;
+ }
+ // __end lookupReadMethodMethod
+
+ // handles <jsp:setProperty> with EL expression for 'value' attribute
+/** Use proprietaryEvaluate
+ public static void handleSetPropertyExpression(Object bean,
+ String prop, String expression, PageContext pageContext,
+ VariableResolver variableResolver, FunctionMapper functionMapper )
+ throws JasperException
+ {
+ try {
+ Method method = getWriteMethod(bean.getClass(), prop);
+ method.invoke(bean, new Object[] {
+ pageContext.getExpressionEvaluator().evaluate(
+ expression,
+ method.getParameterTypes()[0],
+ variableResolver,
+ functionMapper,
+ null )
+ });
+ } catch (Exception ex) {
+ throw new JasperException(ex);
+ }
+ }
+**/
+ public static void handleSetPropertyExpression(Object bean,
+ String prop, String expression, PageContext pageContext,
+ ProtectedFunctionMapper functionMapper )
+ throws JasperException
+ {
+ try {
+ Method method = getWriteMethod(bean.getClass(), prop);
+ method.invoke(bean, new Object[] {
+ PageContextImpl.proprietaryEvaluate(
+ expression,
+ method.getParameterTypes()[0],
+ pageContext,
+ functionMapper,
+ false )
+ });
+ } catch (Exception ex) {
+ throw new JasperException(ex);
+ }
+ }
+
+ public static void handleSetProperty(Object bean, String prop,
+ Object value)
+ throws JasperException
+ {
+ try {
+ Method method = getWriteMethod(bean.getClass(), prop);
+ method.invoke(bean, new Object[] { value });
+ } catch (Exception ex) {
+ throw new JasperException(ex);
+ }
+ }
+
+ public static void handleSetProperty(Object bean, String prop,
+ int value)
+ throws JasperException
+ {
+ try {
+ Method method = getWriteMethod(bean.getClass(), prop);
+ method.invoke(bean, new Object[] { new Integer(value) });
+ } catch (Exception ex) {
+ throw new JasperException(ex);
+ }
+ }
+
+ public static void handleSetProperty(Object bean, String prop,
+ short value)
+ throws JasperException
+ {
+ try {
+ Method method = getWriteMethod(bean.getClass(), prop);
+ method.invoke(bean, new Object[] { new Short(value) });
+ } catch (Exception ex) {
+ throw new JasperException(ex);
+ }
+ }
+
+ public static void handleSetProperty(Object bean, String prop,
+ long value)
+ throws JasperException
+ {
+ try {
+ Method method = getWriteMethod(bean.getClass(), prop);
+ method.invoke(bean, new Object[] { new Long(value) });
+ } catch (Exception ex) {
+ throw new JasperException(ex);
+ }
+ }
+
+ public static void handleSetProperty(Object bean, String prop,
+ double value)
+ throws JasperException
+ {
+ try {
+ Method method = getWriteMethod(bean.getClass(), prop);
+ method.invoke(bean, new Object[] { new Double(value) });
+ } catch (Exception ex) {
+ throw new JasperException(ex);
+ }
+ }
+
+ public static void handleSetProperty(Object bean, String prop,
+ float value)
+ throws JasperException
+ {
+ try {
+ Method method = getWriteMethod(bean.getClass(), prop);
+ method.invoke(bean, new Object[] { new Float(value) });
+ } catch (Exception ex) {
+ throw new JasperException(ex);
+ }
+ }
+
+ public static void handleSetProperty(Object bean, String prop,
+ char value)
+ throws JasperException
+ {
+ try {
+ Method method = getWriteMethod(bean.getClass(), prop);
+ method.invoke(bean, new Object[] { new Character(value) });
+ } catch (Exception ex) {
+ throw new JasperException(ex);
+ }
+ }
+
+ public static void handleSetProperty(Object bean, String prop,
+ byte value)
+ throws JasperException
+ {
+ try {
+ Method method = getWriteMethod(bean.getClass(), prop);
+ method.invoke(bean, new Object[] { new Byte(value) });
+ } catch (Exception ex) {
+ throw new JasperException(ex);
+ }
+ }
+
+ public static void handleSetProperty(Object bean, String prop,
+ boolean value)
+ throws JasperException
+ {
+ try {
+ Method method = getWriteMethod(bean.getClass(), prop);
+ method.invoke(bean, new Object[] { new Boolean(value) });
+ } catch (Exception ex) {
+ throw new JasperException(ex);
+ }
+ }
+
+ public static Method getWriteMethod(Class beanClass, String prop)
+ throws JasperException {
+ Method method = null;
+ Class type = null;
+ try {
+ java.beans.BeanInfo info
+ = java.beans.Introspector.getBeanInfo(beanClass);
+ if ( info != null ) {
+ java.beans.PropertyDescriptor pd[]
+ = info.getPropertyDescriptors();
+ for (int i = 0 ; i < pd.length ; i++) {
+ if ( pd[i].getName().equals(prop) ) {
+ method = pd[i].getWriteMethod();
+ type = pd[i].getPropertyType();
+ break;
+ }
+ }
+ } else {
+ // just in case introspection silently fails.
+ throw new JasperException(
+ Localizer.getMessage("jsp.error.beans.nobeaninfo",
+ beanClass.getName()));
+ }
+ } catch (Exception ex) {
+ throw new JasperException (ex);
+ }
+ if (method == null) {
+ if (type == null) {
+ throw new JasperException(
+ Localizer.getMessage("jsp.error.beans.noproperty",
+ prop,
+ beanClass.getName()));
+ } else {
+ throw new JasperException(
+ Localizer.getMessage("jsp.error.beans.nomethod.setproperty",
+ prop,
+ type.getName(),
+ beanClass.getName()));
+ }
+ }
+ return method;
+ }
+
+ public static Method getReadMethod(Class beanClass, String prop)
+ throws JasperException {
+
+ Method method = null;
+ Class type = null;
+ try {
+ java.beans.BeanInfo info
+ = java.beans.Introspector.getBeanInfo(beanClass);
+ if ( info != null ) {
+ java.beans.PropertyDescriptor pd[]
+ = info.getPropertyDescriptors();
+ for (int i = 0 ; i < pd.length ; i++) {
+ if ( pd[i].getName().equals(prop) ) {
+ method = pd[i].getReadMethod();
+ type = pd[i].getPropertyType();
+ break;
+ }
+ }
+ } else {
+ // just in case introspection silently fails.
+ throw new JasperException(
+ Localizer.getMessage("jsp.error.beans.nobeaninfo",
+ beanClass.getName()));
+ }
+ } catch (Exception ex) {
+ throw new JasperException (ex);
+ }
+ if (method == null) {
+ if (type == null) {
+ throw new JasperException(
+ Localizer.getMessage("jsp.error.beans.noproperty", prop,
+ beanClass.getName()));
+ } else {
+ throw new JasperException(
+ Localizer.getMessage("jsp.error.beans.nomethod", prop,
+ beanClass.getName()));
+ }
+ }
+
+ return method;
+ }
+
+ //*********************************************************************
+ // PropertyEditor Support
+
+ public static Object getValueFromBeanInfoPropertyEditor(
+ Class attrClass, String attrName, String attrValue,
+ Class propertyEditorClass)
+ throws JasperException
+ {
+ try {
+ PropertyEditor pe = (PropertyEditor)propertyEditorClass.newInstance();
+ pe.setAsText(attrValue);
+ return pe.getValue();
+ } catch (Exception ex) {
+ throw new JasperException(
+ Localizer.getMessage("jsp.error.beans.property.conversion",
+ attrValue, attrClass.getName(), attrName,
+ ex.getMessage()));
+ }
+ }
+
+ public static Object getValueFromPropertyEditorManager(
+ Class attrClass, String attrName, String attrValue)
+ throws JasperException
+ {
+ try {
+ PropertyEditor propEditor =
+ PropertyEditorManager.findEditor(attrClass);
+ if (propEditor != null) {
+ propEditor.setAsText(attrValue);
+ return propEditor.getValue();
+ } else {
+ throw new IllegalArgumentException(
+ Localizer.getMessage("jsp.error.beans.propertyeditor.notregistered"));
+ }
+ } catch (IllegalArgumentException ex) {
+ throw new JasperException(
+ Localizer.getMessage("jsp.error.beans.property.conversion",
+ attrValue, attrClass.getName(), attrName,
+ ex.getMessage()));
+ }
+ }
+
+
+ // ************************************************************************
+ // General Purpose Runtime Methods
+ // ************************************************************************
+
+
+ /**
+ * Convert a possibly relative resource path into a context-relative
+ * resource path that starts with a '/'.
+ *
+ * @param request The servlet request we are processing
+ * @param relativePath The possibly relative resource path
+ */
+ public static String getContextRelativePath(ServletRequest request,
+ String relativePath) {
+
+ if (relativePath.startsWith("/"))
+ return (relativePath);
+ if (!(request instanceof HttpServletRequest))
+ return (relativePath);
+ HttpServletRequest hrequest = (HttpServletRequest) request;
+ String uri = (String)
+ request.getAttribute("javax.servlet.include.servlet_path");
+ if (uri != null) {
+ String pathInfo = (String)
+ request.getAttribute("javax.servlet.include.path_info");
+ if (pathInfo == null) {
+ if (uri.lastIndexOf('/') >= 0)
+ uri = uri.substring(0, uri.lastIndexOf('/'));
+ }
+ }
+ else {
+ uri = hrequest.getServletPath();
+ if (uri.lastIndexOf('/') >= 0)
+ uri = uri.substring(0, uri.lastIndexOf('/'));
+ }
+ return uri + '/' + relativePath;
+
+ }
+
+
+ /**
+ * Perform a RequestDispatcher.include() operation, with optional flushing
+ * of the response beforehand.
+ *
+ * @param request The servlet request we are processing
+ * @param response The servlet response we are processing
+ * @param relativePath The relative path of the resource to be included
+ * @param out The Writer to whom we are currently writing
+ * @param flush Should we flush before the include is processed?
+ *
+ * @exception IOException if thrown by the included servlet
+ * @exception ServletException if thrown by the included servlet
+ */
+ public static void include(ServletRequest request,
+ ServletResponse response,
+ String relativePath,
+ JspWriter out,
+ boolean flush)
+ throws IOException, ServletException {
+
+ if (flush && !(out instanceof BodyContent))
+ out.flush();
+
+ // FIXME - It is tempting to use request.getRequestDispatcher() to
+ // resolve a relative path directly, but Catalina currently does not
+ // take into account whether the caller is inside a RequestDispatcher
+ // include or not. Whether Catalina *should* take that into account
+ // is a spec issue currently under review. In the mean time,
+ // replicate Jasper's previous behavior
+
+ String resourcePath = getContextRelativePath(request, relativePath);
+ RequestDispatcher rd = request.getRequestDispatcher(resourcePath);
+
+ rd.include(request,
+ new ServletResponseWrapperInclude(response, out));
+
+ }
+
+ /**
+ * URL encodes a string, based on the supplied character encoding.
+ * This performs the same function as java.next.URLEncode.encode
+ * in J2SDK1.4, and should be removed if the only platform supported
+ * is 1.4 or higher.
+ * @param s The String to be URL encoded.
+ * @param enc The character encoding
+ * @return The URL encoded String
+ */
+ public static String URLEncode(String s, String enc) {
+
+ if (s == null) {
+ return "null";
+ }
+
+ if (enc == null) {
+ enc = "ISO-8859-1"; // The default request encoding
+ }
+
+ StringBuffer out = new StringBuffer(s.length());
+ ByteArrayOutputStream buf = new ByteArrayOutputStream();
+ OutputStreamWriter writer = null;
+ try {
+ writer = new OutputStreamWriter(buf, enc);
+ } catch (java.io.UnsupportedEncodingException ex) {
+ // Use the default encoding?
+ writer = new OutputStreamWriter(buf);
+ }
+
+ for (int i = 0; i < s.length(); i++) {
+ int c = s.charAt(i);
+ if (c == ' ') {
+ out.append('+');
+ } else if (isSafeChar(c)) {
+ out.append((char)c);
+ } else {
+ // convert to external encoding before hex conversion
+ try {
+ writer.write(c);
+ writer.flush();
+ } catch(IOException e) {
+ buf.reset();
+ continue;
+ }
+ byte[] ba = buf.toByteArray();
+ for (int j = 0; j < ba.length; j++) {
+ out.append('%');
+ // Converting each byte in the buffer
+ out.append(Character.forDigit((ba[j]>>4) & 0xf, 16));
+ out.append(Character.forDigit(ba[j] & 0xf, 16));
+ }
+ buf.reset();
+ }
+ }
+ return out.toString();
+ }
+
+ private static boolean isSafeChar(int c) {
+ if (c >= 'a' && c <= 'z') {
+ return true;
+ }
+ if (c >= 'A' && c <= 'Z') {
+ return true;
+ }
+ if (c >= '0' && c <= '9') {
+ return true;
+ }
+ if (c == '-' || c == '_' || c == '.' || c == '!' ||
+ c == '~' || c == '*' || c == '\'' || c == '(' || c == ')') {
+ return true;
+ }
+ return false;
+ }
+
+}
Added: struts/sandbox/trunk/struts2-jsp-plugin/src/main/java/org/apache/struts2/jasper/runtime/JspSourceDependent.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-jsp-plugin/src/main/java/org/apache/struts2/jasper/runtime/JspSourceDependent.java?rev=799681&view=auto
==============================================================================
--- struts/sandbox/trunk/struts2-jsp-plugin/src/main/java/org/apache/struts2/jasper/runtime/JspSourceDependent.java (added)
+++ struts/sandbox/trunk/struts2-jsp-plugin/src/main/java/org/apache/struts2/jasper/runtime/JspSourceDependent.java Fri Jul 31 18:12:48 2009
@@ -0,0 +1,39 @@
+/*
+ * 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.runtime;
+
+/**
+ * Interface for tracking the source files dependencies, for the purpose
+ * of compiling out of date pages. This is used for
+ * 1) files that are included by page directives
+ * 2) files that are included by include-prelude and include-coda in jsp:config
+ * 3) files that are tag files and referenced
+ * 4) TLDs referenced
+ */
+
+public interface JspSourceDependent {
+
+ /**
+ * Returns a list of files names that the current page has a source
+ * dependency on.
+ */
+ // FIXME: Type used is Object due to very weird behavior
+ // with Eclipse JDT 3.1 in Java 5 mode
+ public Object getDependants();
+
+}