001: /**
002: * InstantJ
003: *
004: * Copyright (C) 2002 Nils Meier
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or (at your option) any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: */package instantj.j2ee;
017:
018: import instantj.compile.CompilationFailedException;
019: import instantj.expression.EvaluationFailedException;
020: import instantj.expression.Expression;
021: import instantj.reflect.IllegalPropertyException;
022:
023: import java.io.IOException;
024: import java.io.PrintWriter;
025: import java.net.URLEncoder;
026: import java.util.Date;
027: import java.util.HashMap;
028: import java.util.Iterator;
029: import java.util.Map;
030:
031: import javax.servlet.ServletException;
032: import javax.servlet.http.HttpServlet;
033: import javax.servlet.http.HttpServletRequest;
034: import javax.servlet.http.HttpServletResponse;
035:
036: /**
037: * A <b>simple</b> Servlet that allows expressions to be executed.
038: * Warning: Any user accessing this Servlet can perform functions
039: * on your server that you might not appreciate. This is a proof
040: * of concept only!
041: */
042: public class ExpressionServlet extends HttpServlet {
043:
044: private static final String TYPES[] = { String.class.getName(),
045: Boolean.class.getName(), Integer.class.getName(),
046: Date.class.getName(), Boolean.TYPE.getName(),
047: Integer.TYPE.getName(), };
048:
049: /** some predefined sample expressions */
050: public final static String[][] SAMPLES = new String[][] {
051: { "\"Hello World\"" },
052: { "\"It is \" + new java.util.Date() + \" ... too late!\"" },
053: { "\"PI equals \" + Math.PI " },
054: { "2 * Math.PI * radius", "radius", "int", "16" },
055: {
056: "birthday ? \"Turning \" +(new Date().getYear()-date.getYear())+ \" today? \" + hurray + \" times Hurray!!!\" : \"*sigh*\"",
057: "birthday", "boolean", "true", "date",
058: "java.util.Date", "1970/05/25", "hurray",
059: "java.lang.Integer", "3" } };
060:
061: /**
062: * @see HttpServlet#doGet(HttpServletRequest, HttpServletResponse)
063: */
064: protected void doGet(HttpServletRequest req, HttpServletResponse res)
065: throws ServletException, IOException {
066:
067: res.setContentType("text/html");
068: PrintWriter out = new PrintWriter(res.getOutputStream());
069:
070: // The header and stuff
071: generateHeader(out);
072:
073: // The body
074: generateBody(out, req);
075:
076: // The footer and stuff
077: generateFooter(out);
078:
079: // Done
080: out.flush();
081: out.close();
082: }
083:
084: /**
085: * Generates the Header
086: */
087: private void generateHeader(PrintWriter out) {
088: out.println("<html><body>");
089: out.println("<h1>InstantJ - Expression Servlet</h1>");
090: }
091:
092: /**
093: * Generates the Footer
094: */
095: private void generateFooter(PrintWriter out) {
096: out
097: .println("<p align=right><a href=\"http://instantj.sourceforge.net\">InstantJ @ Sourceforge</a></p>");
098: out.println("</body></html>");
099: }
100:
101: /**
102: * Helper that returns a value
103: */
104: private String getValue(HttpServletRequest req, String name) {
105: String result = req.getParameter(name);
106: if (result == null)
107: result = "";
108: return result;
109: }
110:
111: /**
112: * Helper that checks for given value
113: */
114: private boolean isValue(HttpServletRequest req, String name) {
115: return getValue(req, name).length() > 0;
116: }
117:
118: /**
119: * Helper that checks for given value
120: */
121: private boolean isValue(HttpServletRequest req, String name,
122: int value) {
123: try {
124: return Integer.parseInt(getValue(req, name)) == value;
125: } catch (NumberFormatException nfe) {
126: return false;
127: }
128: }
129:
130: /**
131: * Generates a URL
132: */
133: private void outURL(PrintWriter out, String name, Map parameters) {
134: out.print("<a href=\"?");
135:
136: Iterator it = parameters.keySet().iterator();
137: while (it.hasNext()) {
138: Object key = it.next();
139: out.print(key);
140: out.print("=");
141: // this is how it would look for 1.4
142: // try {
143: // out.print(URLEncoder.encode(parameters.get(key).toString(),"UTF-8"));
144: // } catch (UnsupportedEncodingException e) { }
145: out
146: .print(URLEncoder.encode(parameters.get(key)
147: .toString()));
148: if (it.hasNext())
149: out.print('&');
150: }
151: out.print("\">");
152: out.print(name);
153: out.println("</a>");
154:
155: }
156:
157: /**
158: * Helper that translates given String into valid HTML FORM text
159: */
160: private String formalize(String s) {
161:
162: StringBuffer result = new StringBuffer(s.length() * 2);
163: for (int i = 0; i < s.length(); i++) {
164: char c = s.charAt(i);
165: switch (c) {
166: case '\"':
167: result.append(""");
168: break;
169: default:
170: result.append(c);
171: }
172: }
173: return result.toString();
174: }
175:
176: /**
177: * Generates a textbox
178: */
179: private void outTextBox(PrintWriter out, String prefix,
180: String name, String value) {
181: out.print(prefix);
182: out.print("<input type=\"text\" name=\"");
183: out.print(name);
184: out.print("\" value=\"");
185: out.print(formalize(value));
186: out.println("\"></input>");
187: }
188:
189: /**
190: * Generates a button
191: */
192: private void outButton(PrintWriter out, String text) {
193: out.print(" <input type=\"submit\" value=\"");
194: out.print(text);
195: out.println("\"></input>");
196: }
197:
198: /**
199: * Generates a combobox
200: */
201: private void outDropBox(PrintWriter out, String prefix,
202: String name, String[] values, String selection) {
203:
204: out.print(prefix);
205: out.print("<select name=\"");
206: out.print(name);
207: out.print("\"> ");
208: for (int t = 0; t < values.length; t++) {
209: boolean selected = values[t].equals(selection);
210: out.print(" <option value=\"");
211: out.print(formalize(values[t]));
212: out.print("\" ");
213: if (selected)
214: out.print("SELECTED");
215: out.print(">");
216: out.print(values[t]);
217: out.print("</option>");
218: }
219: out.println(" </select>,");
220: }
221:
222: /**
223: * Generates the Body
224: */
225: private void generateBody(PrintWriter out, HttpServletRequest req) {
226:
227: // The preselection section
228: out.println("<blockquote>");
229: out.println("Good expressions are:<br>");
230: for (int i = 0; i < SAMPLES.length; i++) {
231: Map parms = new HashMap();
232: String body = SAMPLES[i][0];
233: parms.put("body", body);
234: for (int p = 0; p < SAMPLES[i].length / 3; p++) {
235: parms.put("parm." + p + ".name",
236: SAMPLES[i][1 + p * 3 + 0]);
237: parms.put("parm." + p + ".type",
238: SAMPLES[i][1 + p * 3 + 1]);
239: parms.put("parm." + p + ".value",
240: SAMPLES[i][1 + p * 3 + 2]);
241: }
242: if (body.length() > 72)
243: body = body.substring(0, 72) + "...";
244: outURL(out, body, parms);
245: out.println("<br>");
246: }
247: out.println("</blockquote>");
248:
249: // The enter expression section
250: out.println("<form>");
251:
252: out.println("<blockquote>");
253: out.println("Please enter a Java expression here:<br>");
254: outTextBox(out, " body=", "body", getValue(req, "body"));
255: outButton(out, "Evaluate");
256: out.println("</blockquote>");
257:
258: // The enter parameters section
259: out.println("<blockquote>");
260: out
261: .println("and enter (optional) parameters here (no quotes):<br>");
262:
263: for (int i = 0; i < 3; i++) {
264: String p_name = "parm." + i + ".name", p_type = "parm." + i
265: + ".type", p_value = "parm." + i + ".value";
266:
267: outTextBox(out, "name=", p_name, getValue(req, p_name));
268: outDropBox(out, "type=", p_type, TYPES, getValue(req,
269: p_type));
270: outTextBox(out, "value=", p_value, getValue(req, p_value));
271:
272: out.println("<br>");
273: }
274: out.println("</blockquote>");
275:
276: out.println("</form>");
277:
278: // The result from last expression
279: if (isValue(req, "body")) {
280: out.println("<blockquote>");
281: out.println("Evaluation resulted in:<br>");
282: evaluate(out, req);
283: out.println("</blockquote>");
284: }
285:
286: // Done
287: }
288:
289: /**
290: * Evaluates an expression
291: */
292: private void evaluate(PrintWriter out, HttpServletRequest req) {
293:
294: try {
295: String body = getValue(req, "body");
296:
297: Map parms = new HashMap();
298: Map values = new HashMap();
299: for (int i = 0;; i++) {
300: String name = getValue(req, "parm." + i + ".name");
301: if (name.length() == 0)
302: break;
303: String type = getValue(req, "parm." + i + ".type");
304: String value = getValue(req, "parm." + i + ".value");
305: parms.put(name, type);
306: values.put(name, value);
307: }
308:
309: Object result = new Expression(body, parms).getInstance(
310: values).evaluate();
311:
312: out.println("<b>" + result + "</b>");
313:
314: } catch (IllegalPropertyException e) {
315: out.println("<b>Setting parameters failed because of "
316: + e.getMessage() + "</b>");
317: out.println("<font size=\"1\"><pre>");
318: e.printStackTrace(out);
319: out.println("</pre></font>");
320: } catch (EvaluationFailedException e) {
321: out.println("<b>Evaluation failed because of "
322: + e.getMessage() + "</b>");
323: out.println("<font size=\"1\"><pre>");
324: e.printStackTrace(out);
325: out.println("</pre></font>");
326: } catch (CompilationFailedException e) {
327: out.println("<b>Compilation failed because of "
328: + e.getMessage() + "</b>");
329: out.println("<font color=\"red\"><pre>");
330: e.printErrors(out);
331: out.println("</pre></font>");
332: out.println("<font size=\"1\"><pre>");
333: e.printStackTrace(out);
334: out.println("</pre></font>");
335: }
336: }
337:
338: }
|