bsh.servlet.BshServlet Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of bsh Show documentation
Show all versions of bsh Show documentation
BeanShell is a small, free, embeddable Java source interpreter with object scripting language features,
written in Java. BeanShell dynamically executes standard Java syntax and extends it with common scripting
conveniences such as loose types, commands, and method closures like those in Perl and JavaScript.
The newest version!
package bsh.servlet;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import bsh.*;
/**
This file is part of BeanShell - www.beanshell.org
@author Pat Niemeyer
*/
public class BshServlet extends HttpServlet
{
static String bshVersion;
static String exampleScript = "print(\"hello!\");";
static String getBshVersion()
{
if ( bshVersion != null )
return bshVersion;
/*
We have included a getVersion() command to detect the version
of bsh. If bsh is packaged in the WAR file it could access it
directly as a bsh command. But if bsh is in the app server's
classpath it won't see it here, so we will source it directly.
This command works around the lack of a coherent version number
in the early versions.
*/
Interpreter bsh = new Interpreter();
try {
bsh.eval( new InputStreamReader( BshServlet.class.getResource(
"getVersion.bsh").openStream() ) );
bshVersion = (String)bsh.eval( "getVersion()" );
} catch ( Exception e ) {
bshVersion = "BeanShell: unknown version";
}
return bshVersion;
}
public void doGet(
HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
String script = request.getParameter("bsh.script");
String client = request.getParameter("bsh.client");
String output = request.getParameter("bsh.servlet.output");
String captureOutErr =
request.getParameter("bsh.servlet.captureOutErr");
boolean capture = false;
if ( captureOutErr != null && captureOutErr.equalsIgnoreCase("true") )
capture = true;
Object scriptResult = null;
Exception scriptError = null;
StringBuffer scriptOutput = new StringBuffer();
if ( script != null ) {
try {
scriptResult = evalScript(
script, scriptOutput, capture, request, response );
} catch ( Exception e ) {
scriptError = e;
}
}
response.setHeader( "Bsh-Return", String.valueOf(scriptResult) );
if ( (output != null && output.equalsIgnoreCase("raw"))
|| ( client != null && client.equals("Remote") ) )
sendRaw(
request, response, scriptError, scriptResult, scriptOutput );
else
sendHTML( request, response, script, scriptError,
scriptResult, scriptOutput, capture );
}
void sendHTML(
HttpServletRequest request, HttpServletResponse response,
String script, Exception scriptError, Object scriptResult,
StringBuffer scriptOutput, boolean capture )
throws IOException
{
// Format the output using a simple templating utility
SimpleTemplate st = new SimpleTemplate(
BshServlet.class.getResource("page.template") );
st.replace( "version", getBshVersion() );
//String requestURI = HttpUtils.getRequestURL( request ).toString()
// I was told this should work
String requestURI = request.getRequestURI();
st.replace( "servletURL", requestURI );
if ( script != null )
st.replace( "script", script );
else
st.replace( "script", exampleScript );
if ( capture )
st.replace( "captureOutErr", "CHECKED" );
else
st.replace( "captureOutErr", "" );
if ( script != null )
st.replace( "scriptResult",
formatScriptResultHTML(
script, scriptResult, scriptError, scriptOutput ) );
response.setContentType("text/html");
PrintWriter out = response.getWriter();
st.write(out);
out.flush();
}
void sendRaw(
HttpServletRequest request, HttpServletResponse response,
Exception scriptError, Object scriptResult, StringBuffer scriptOutput )
throws IOException
{
response.setContentType("text/plain");
PrintWriter out = response.getWriter();
if ( scriptError != null )
out.println( "Script Error:\n"+scriptError );
else
out.println( scriptOutput.toString() );
out.flush();
}
/**
*/
String formatScriptResultHTML(
String script, Object result, Exception error,
StringBuffer scriptOutput )
throws IOException
{
SimpleTemplate tmplt;
if ( error != null )
{
tmplt = new SimpleTemplate(
getClass().getResource("error.template") );
String errString;
if ( error instanceof bsh.EvalError )
{
int lineNo = ((EvalError)error).getErrorLineNumber();
String msg = error.getMessage();
int contextLines = 4;
errString = escape(msg);
if ( lineNo > -1 )
errString += "
"
+ showScriptContextHTML( script, lineNo, contextLines );
} else
errString = escape( error.toString() );
tmplt.replace("error", errString );
} else {
tmplt = new SimpleTemplate(
getClass().getResource("result.template") );
tmplt.replace( "value", escape(String.valueOf(result)) );
tmplt.replace( "output", escape(scriptOutput.toString()) );
}
return tmplt.toString();
}
/*
Show context number lines of string before and after target line.
Add HTML formatting to bold the target line.
*/
String showScriptContextHTML( String s, int lineNo, int context )
{
StringBuffer sb = new StringBuffer();
BufferedReader br = new BufferedReader( new StringReader(s) );
int beginLine = Math.max( 1, lineNo-context );
int endLine = lineNo + context;
for( int i=1; i<=lineNo+context+1; i++ )
{
if ( i < beginLine )
{
try {
br.readLine();
} catch ( IOException e ) {
throw new RuntimeException( e.toString() );
}
continue;
}
if ( i > endLine )
break;
String line;
try {
line = br.readLine();
} catch ( IOException e ) {
throw new RuntimeException( e.toString() );
}
if ( line == null )
break;
if ( i == lineNo )
sb.append( ""+i+": "+line +"
" );
else
sb.append( i+": " +line +"
" );
}
return sb.toString();
}
public void doPost(
HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
doGet( request, response );
}
Object evalScript(
String script, StringBuffer scriptOutput, boolean captureOutErr,
HttpServletRequest request, HttpServletResponse response )
throws EvalError
{
// Create a PrintStream to capture output
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream pout = new PrintStream( baos );
// Create an interpreter instance with a null inputstream,
// the capture out/err stream, non-interactive
Interpreter bsh = new Interpreter( null, pout, pout, false );
// set up interpreter
bsh.set( "bsh.httpServletRequest", request );
bsh.set( "bsh.httpServletResponse", response );
// Eval the text, gathering the return value or any error.
Object result = null;
String error = null;
PrintStream sout = System.out;
PrintStream serr = System.err;
if ( captureOutErr ) {
System.setOut( pout );
System.setErr( pout );
}
try {
// Eval the user text
result = bsh.eval( script );
} finally {
if ( captureOutErr ) {
System.setOut( sout );
System.setErr( serr );
}
}
pout.flush();
scriptOutput.append( baos.toString() );
return result;
}
/**
* Convert special characters to entities for XML output
*/
public static String escape(String value)
{
String search = "&<>";
String[] replace = {"&", "<", ">"};
StringBuffer buf = new StringBuffer();
for (int i = 0; i < value.length(); i++)
{
char c = value.charAt(i);
int pos = search.indexOf(c);
if (pos < 0)
buf.append(c);
else
buf.append(replace[pos]);
}
return buf.toString();
}
}