All Downloads are FREE. Search and download functionalities are using the official Maven repository.

sunlabs.brazil.javascript.JavaScriptTemplate Maven / Gradle / Ivy

The newest version!
/*
 * JavaScriptTemplate.java
 *
 * Brazil project web application toolkit,
 * export version: 2.3 
 * Copyright (c) 2002-2004 Sun Microsystems, Inc.
 *
 * Sun Public License Notice
 *
 * The contents of this file are subject to the Sun Public License Version 
 * 1.0 (the "License"). You may not use this file except in compliance with 
 * the License. A copy of the License is included as the file "license.terms",
 * and also available at http://www.sun.com/
 * 
 * The Original Code is from:
 *    Brazil project web application toolkit release 2.3.
 * The Initial Developer of the Original Code is: drach.
 * Portions created by drach are Copyright (C) Sun Microsystems, Inc.
 * All Rights Reserved.
 * 
 * Contributor(s): drach, suhler.
 *
 * Version:  2.4
 * Created by drach on 02/07/19
 * Last modified by suhler on 04/11/30 15:19:39
 *
 * Version Histories:
 *
 * 2.4 04/11/30-15:19:39 (suhler)
 *   fixed sccs version string
 *
 * 2.3 03/08/01-16:21:57 (suhler)
 *   javadoc fixes
 *
 * 2.2 03/07/07-14:44:34 (suhler)
 *   Merged changes between child workspace "/home/suhler/brazil/naws" and
 *   parent workspace "/net/mack.eng/export/ws/brazil/naws".
 *
 * 1.2.1.1 03/07/07-14:04:54 (suhler)
 *   use addClosingTag() convenience method
 *
 * 2.1 02/10/01-16:34:49 (suhler)
 *   version change
 *
 * 1.2 02/07/19-17:01:29 (drach)
 *   Fixed up the comments.
 *
 * 1.2 02/07/19-16:12:01 (Codemgr)
 *   SunPro Code Manager data about conflicts, renames, etc...
 *   Name history : 1 0 javascript/JavaScriptTemplate.java
 *
 * 1.1 02/07/19-16:12:00 (drach)
 *   date and time created 02/07/19 16:12:00 by drach
 *
 */

package sunlabs.brazil.javascript;

import sunlabs.brazil.server.Request;
import sunlabs.brazil.server.Server;
import sunlabs.brazil.handler.ResourceHandler;
import sunlabs.brazil.template.RewriteContext;
import sunlabs.brazil.template.Template;
import sunlabs.brazil.util.Format;

import org.mozilla.javascript.Context;
import org.mozilla.javascript.JavaScriptException;
import org.mozilla.javascript.Scriptable;

import java.io.IOException;
import java.util.Properties;

/**
 * The JavaScriptTemplate looks for each
 * <server language="javascript"> (or
 *  <javascript>)
 * tag in an HTML page and treats the following data up to the next
 * </server> (or  </javascript>)
 * tag as a JavaScript script to evaluate.
 * 

* The reason that JavaScript scripts are included in an HTML page is usually * to generate dynamic, server-side content. After running this template, * everything between and including the <server> and * </server> (or <javascript> and * </javascript> tags is replaced by all output written * to the JavaScript standard output stream (if any). *

* All JavaScript fragments within a given page are evaluated in the same JavaScript * interpreter. The JavaScript interpreter actually lives for the entire duration * of this Template object, so the user can implement * persistence across requests. *

* The following configuration parameters are used to initialize this * template.

*
script *
The name of the JavaScript script to evaluate when the interpreter is * created. This script is only evaluated when the interp is created, * not on every request. The variables prefix and * server are set before this file is evaluated, and * are references to the parameters passed to a handler * init method. *
root *
The document root, if the script is a relative file name. * If the "root" property under the template prefix is not found, the * global "root" property is used. If the global "root" property is * not found, the current directory is used. *
debug *
If this configuration parameter is present, this class * replaces the <server> and * </server> tags with comments, so the user * can keep track of where the dynamically generated content is coming * from by examining the comments in the resultant HTML document. * By default, the <server> and * </server> are completely eliminated from the * HTML document rather than changed into comments. *
*

* Before evaluating each HTML document, this class sets variables * in the JavaScript interpreter, which can be used to interact back with Java to * do things like set the response headers:

*
request *
Exposes the {@link sunlabs.brazil.server.Request} Java object. * It is set anew at each request. *
prefix *
Exposes the handler prefix String. *
server *
Exposes the handler {@link sunlabs.brazil.server.Server} object. *
* If the attribute eval is present as an attribute, all * constructs of the form ${...} are substituted before processing the * script. *

* Here's a simple example of a JavaScript template: *


 * <html>
 * <head>
 * <title>JavaScript Example</title>
 * </head>
 * <body>
 * <javascript>
 * var s = "request=" + request;
 * s += "<br>request.serverUrl is " + request.serverUrl();
 * s += "<br>server hostName is " + server.hostName;
 * s += "<br>prefix is " + prefix;
 * s += "<br> <table>";
 * 
 * // This is an example of using Java in JavaScript with LiveConnect
 * var e = request.props.propertyNames();
 * while (e.hasMoreElements()) {
 *   var prop = e.nextElement();
 *   s += "<tr><td>" + prop + "</td>";
 *   s += "<td>" + request.props.getProperty(prop) + "</td></tr>";
 * }
 * 
 * s += "</table>";
 * 
 * // The last value computed or expressed is returned
 * s;
 * 
 * </javascript>
 * </body>
 * </html>
 * 
* * @author Steve Drach * @version 2.4 */ public class JavaScriptTemplate extends Template { private static final String SCRIPT = "script"; Context cx = null; Scriptable scope = null; Thread current = null; /** * Called at the beginning of each HTML document that this * JavaScriptTemplate is asked to process. *

* The first time this method is called, the initialization script is * sourced into the interpreter, based on the configuration properties * in the Request * * @param hr * The request and associated HTML document that will be * processed. * * @return true. */ public boolean init(RewriteContext hr) { hr.addClosingTag("javascript"); return super.init(hr); } private boolean setup(RewriteContext hr) { Properties props = hr.request.props; scope = cx.initStandardObjects(null); String script = props.getProperty(hr.prefix + SCRIPT); try { scope.put("prefix", scope, hr.prefix); scope.put("server", scope, Context.toObject(hr.server, scope)); if (script != null) { String body = ResourceHandler.getResourceString(props, hr.prefix, script); System.err.println("startup: " + body); cx.evaluateString(scope, body, script, 1, null); } } catch (IOException e) { hr.request.log(Server.LOG_ERROR, "reading init script", script); Context.exit(); return false; } catch (JavaScriptException e) { hr.request.log(Server.LOG_ERROR, "initializing JavaScript", e.toString()); Context.exit(); return false; } return true; } /** * Processes the <server> tag. Substitutes the * result of evaluating the following JavaScript script into the resultant * HTML document. *

* Note: Currently, there is no mechanism for other language interpreters * to share the same server tag. * * @param hr * The request and associated HTML document that will be * processed. */ public void tag_server(RewriteContext hr) { if ("javascript".equals(hr.get("language")) == false) { return; } tag_javascript(hr); } /** * Processes the <javascript> tag. Substitutes the * result of evaluating the following JavaScript script into the resultant * HTML document. * * @param hr * The request and associated HTML document that will be * processed. */ public void tag_javascript(RewriteContext hr) { Thread thread; debug(hr); boolean eval = hr.isTrue("eval"); hr.accumulate(false); hr.nextToken(); String script = hr.getBody(); if (eval) { script = Format.subst(hr.request.props, script); } hr.request.log(Server.LOG_DIAGNOSTIC, hr.prefix, "Setting request"); if ((thread = Thread.currentThread()) != current) { if (cx != null) { Context.exit(); } cx = Context.enter(); current = thread; } if (scope == null) { if (!setup(hr)) { hr.accumulate(true); return; } } scope.put("request", scope, Context.toObject(hr.request, scope)); hr.request.log(Server.LOG_DIAGNOSTIC, hr.prefix, script); Object result = null; try { result = cx.evaluateString(scope, script, "template", 1, null); } catch (JavaScriptException e) { hr.append("\n\n"); hr.request.log(Server.LOG_DIAGNOSTIC, hr.prefix, e.toString()); } hr.nextToken(); if (result != cx.getUndefinedValue()) { hr.append(cx.toString(result)); } hr.accumulate(true); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy