📄 scriptaction.java
字号:
/*
* $Id: ScriptAction.java 471754 2006-11-06 14:55:09Z husted $
*
* 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.struts.scripting;
// util imports:
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.StringTokenizer;
// io imports:
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
// logging imports:
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
// struts imports:
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessages;
// misc imports:
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.bsf.BSFException;
import org.apache.bsf.BSFManager;
import org.apache.bsf.util.IOUtils;
/**
* This Action uses scripts to perform its action. The scripting framework is
* Apache's Bean Scripting Framework which allows the scripts to be written
* many of the popular scripting languages including JavaScript, Perl, Python,
* and even VBA. <br />
* <br />
* To determine what script will be executed, the "parameter" attribute of the
* action mapping should contain the name of the script relative to the web
* application root directory (i.e. http://server/app). <br />
* <br />
* Before the script completes, the next ActionForward needs to be specified.
* This can be done one of two ways:
* <ol>
* <li> Set <code>struts.forwardName</code> to the name of the forward</li>
*
* <li> Set <code>struts.forward</code> to the actual ActionForward object
* </li>
* </ol>
* A number of pre-defined variables are available to the script:
* <ul>
* <li> <code>request</code> - The HTTP request</li>
* <li> <code>response</code> - The HTTP response</li>
* <li> <code>session</code> - The session</li>
* <li> <code>application</code> - The servlet context</li>
* <li> <code>struts</code> - A grouping of all Struts-related objects</li>
*
* <li> <code>log</code> - A logging instance</li>
* </ul>
* You can add your own variables by creating a BSFManagerFilter and
* configuring it in struts-scripting.properties:
* <ul>
* <li> <code>struts-scripting.filters.FILTER_NAME.class=FILTER_CLASS</code>
* - The class implementing BSFManagerFilter where FILTER_NAME is the name
* you are calling the filter.</li>
* <li> <code>
* struts-scripting.filters.FILTER_NAME.PROPERTY_NAME=PROPERTY_VALUE
* </code> - A property to be used by the filter.</li>
* </ul>
* <br />
* <br />
* To use other scripting engines other than BeanShell, create a file called
* <code>struts-scripting.properties</code> and add two properties for each
* engine:
* <ul>
* <li> <code>struts-scripting.engine.ENGINE_NAME.class</code> - The class of
* the BSF engine where ENGINE_NAME is the name you are calling the engine.
* </li>
* <li> <code>struts-scripting.engine.ENGINE_NAME.extensions</code> - A
* comma-delimited list of file extensions that will be used to identify the
* engine to use to execute the script.</li>
* </ul>
* This code was originally based off code from JPublish, but has since been
* almost completely rewritten.
*/
public class ScriptAction extends Action {
/** The logging instance. */
protected static final Log LOG = LogFactory.getLog(ScriptAction.class);
/** The default path to the properties file. */
protected static final String PROPS_PATH = "/struts-scripting.properties";
/** The base property for alternate BSF engines. */
protected static final String ENGINE_BASE = "struts-scripting.engine.";
/** The base property for classes that put new variables in the context. */
protected static final String FILTERS_BASE = "struts-scripting.filters.";
/** A list of initialized filters. */
private static BSFManagerFilter[] filters = null;
/** Holds the "compiled" scripts and their information. */
private Map scripts = new Hashtable();
static {
Properties props = new Properties();
try {
InputStream in =
ScriptAction.class.getClassLoader()
.getResourceAsStream(PROPS_PATH);
if (in == null) {
in =
ScriptAction.class.getClassLoader().getResourceAsStream(
"/struts-bsf.properties");
if (in != null) {
LOG.warn("The struts-bsf.properties file has been "
+ "deprecated. Please use "
+ "struts-scripting.properties instead.");
} else {
LOG.warn("struts-scripting.properties not found, using "
+ "default engine mappings.");
}
}
if (in != null) {
props.load(in);
}
} catch (Exception ex) {
LOG.warn("Unable to load struts-scripting.properties, using "
+ " default engine mappings.");
}
int pos = ENGINE_BASE.length();
for (Enumeration e = props.propertyNames(); e.hasMoreElements();) {
String name = (String) e.nextElement();
if (name.startsWith(ENGINE_BASE) && name.endsWith(".class")) {
String type = name.substring(pos, name.indexOf('.', pos));
String cls = props.getProperty(name);
String ext = props.getProperty(ENGINE_BASE + type
+ ".extensions", "");
String[] exts = split(ext, ",");
if (LOG.isInfoEnabled()) {
LOG.info("Loading BSF engine name:" + type + " class:"
+ cls + " ext:" + ext);
}
BSFManager.registerScriptingEngine(type, cls, exts);
}
}
filters = loadFilters(props);
}
/**
* Executes the script.
*
*@param mapping The action mapping
*@param form The action form
*@param request The request object
*@param response The response object
*@return The action forward
*@exception Exception If something goes wrong
*/
public ActionForward execute(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception {
BSFManager bsfManager = new BSFManager();
String scriptName = null;
try {
scriptName = parseScriptName(mapping.getParameter(), bsfManager);
} catch (Exception ex) {
LOG.error("Unable to parse " + mapping.getParameter(), ex);
throw new Exception("Unable to parse " + mapping.getParameter());
}
if (scriptName == null) {
LOG.error("No script specified in the parameter attribute");
throw new Exception("No script specified");
}
if (LOG.isDebugEnabled()) {
LOG.debug("Executing script: " + scriptName);
}
HttpSession session = request.getSession();
ServletContext application = getServlet().getServletContext();
Script script = loadScript(scriptName, application);
bsfManager.declareBean("request", request,
HttpServletRequest.class);
bsfManager.declareBean("response", response,
HttpServletResponse.class);
if (session == null) {
LOG.debug("HTTP session is null");
} else {
bsfManager.declareBean("session", session, HttpSession.class);
}
bsfManager.declareBean("application", application,
ServletContext.class);
bsfManager.declareBean("log", LOG, Log.class);
StrutsInfo struts = new StrutsInfo(this, mapping, form,
getResources(request));
bsfManager.declareBean("struts", struts, StrutsInfo.class);
for (int x = 0; x < filters.length; x++) {
filters[x].apply(bsfManager);
}
bsfManager.exec(script.lang, script.file.getCanonicalPath(), 0, 0,
script.string);
ActionForward af = struts.getForward();
return af;
}
/**
* Parses the script name and puts any url parameters in the context.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -