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

sunlabs.brazil.python.PythonServerTemplate Maven / Gradle / Ivy

The newest version!
/*
 * PythonServerTemplate.java
 *
 * Brazil project web application toolkit,
 * export version: 2.3 
 * Copyright (c) 2000-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: suhler.
 * Portions created by suhler are Copyright (C) Sun Microsystems, Inc.
 * All Rights Reserved.
 * 
 * Contributor(s): drach, suhler.
 *
 * Version:  2.4
 * Created by suhler on 00/09/08
 * Last modified by suhler on 04/11/30 15:19:40
 *
 * Version Histories:
 *
 * 2.4 04/11/30-15:19:40 (suhler)
 *   fixed sccs version string
 *
 * 2.3 03/08/01-16:19:36 (suhler)
 *   fixes for javadoc
 *
 * 2.2 03/07/07-14:45:11 (suhler)
 *   Merged changes between child workspace "/home/suhler/brazil/naws" and
 *   parent workspace "/net/mack.eng/export/ws/brazil/naws".
 *
 * 1.11.1.1 03/07/07-14:05:01 (suhler)
 *   use addClosingTag() convenience method
 *
 * 2.1 02/10/01-16:38:53 (suhler)
 *   version change
 *
 * 1.11 02/07/18-14:06:26 (suhler)
 *   don't do \
 *   \XXX expansions with eval
 *
 * 1.10 01/07/16-16:50:52 (suhler)
 *   use new Template convenience methods
 *
 * 1.6.1.1 01/06/04-11:06:58 (suhler)
 *   jython -vs- jpython
 *
 * 1.9 01/05/24-17:07:55 (drach)
 *   Add closing tag  every time init() is called.
 *
 * 1.8 01/05/14-08:52:30 (drach)
 *   Use new debug method in super class Template.
 *
 * 1.7 01/05/14-08:33:31 (drach)
 *   Jython apparently doesn't have a classBasedException option.
 *
 * 1.6 01/04/06-08:51:29 (suhler)
 *   added "eval" attribute to perform ${...} substitutions before running script
 *
 * 1.5 00/12/11-13:31:45 (suhler)
 *   add class=props for automatic property extraction
 *
 * 1.4 00/10/06-16:04:19 (suhler)
 *   fixed initialization bug, add python tracebacks when log=5
 *
 * 1.3 00/09/13-14:48:41 (suhler)
 *   move to python package, add  tag
 *
 * 1.2 00/09/08-19:40:11 (suhler)
 *   capture stdout of pyton interp
 *
 * 1.2 00/09/08-18:11:17 (Codemgr)
 *   SunPro Code Manager data about conflicts, renames, etc...
 *   Name history : 2 1 python/PythonServerTemplate.java
 *   Name history : 1 0 tcl/PythonServerTemplate.java
 *
 * 1.1 00/09/08-18:11:16 (suhler)
 *   date and time created 00/09/08 18:11:16 by suhler
 *
 */

package sunlabs.brazil.python;

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.python.core.PyException;
import org.python.core.Options;
import org.python.util.PythonInterpreter;

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

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

* The reason that python 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 <python> and * </python> tags is replaced by all output written * to the Python standard output stream (if any). *

* All Python fragments within a given page are evaluated in the same Python * interpreter. The Python 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 Python script to evaluate when the interpreter is * created. This script 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 Python 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 off the form ${...} are substituted before processing the * script. * * @author Stephen Uhler * @version 2.4 */ public class PythonServerTemplate extends Template { private static final String SCRIPT = "script"; PythonInterpreter interp = null; ByteArrayOutputStream stdout; /* * Called at the beginning of each HTML document that this * PythonServerTemplate 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 interpreter was successfully initialized * false otherwise. About the only way that the * initialization could fail would be

    *
  1. there was an error sourcing the initialization script. *
* If false is returned, an error message is logged. */ public boolean init(RewriteContext hr) { Properties props = hr.request.props; if (interp == null) { stdout = new ByteArrayOutputStream(); try { Options.classBasedExceptions = false; } catch (NoSuchFieldError e) {}; if (hr.server.logLevel >= Server.LOG_DIAGNOSTIC) { Options.showJavaExceptions = true; } interp = new PythonInterpreter(); String script = props.getProperty(hr.prefix + SCRIPT); // System.err.println("Creating Python interp"); try { interp.set("prefix", hr.prefix); interp.set("server", hr.server); if (script != null) { String body = ResourceHandler.getResourceString(props, hr.prefix, script); // System.err.println("startup: " + body); interp.exec(body); } } catch (IOException e) { hr.request.log(Server.LOG_ERROR, "reading init script", script); return false; } catch (PyException e) { hr.request.log(Server.LOG_ERROR, "initializing Python", e.toString()); return false; } // System.out.println("Init done"); } hr.addClosingTag("python"); try { hr.request.log(Server.LOG_DIAGNOSTIC, hr.prefix, "Setting request"); interp.set("request", hr.request); } catch (PyException e) { hr.request.log(Server.LOG_WARNING, hr.prefix, "Setting up Python request: " + e.toString()); done(hr); return false; } return super.init(hr); } /** * Processes the <server> tag. Substitues the * result of evaluating the following Python 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 ("python".equals(hr.get("language")) == false) { return; } tag_python(hr); } /** * Processes the <python> tag. Substitues the * result of evaluating the following Python script into the resultant * HTML document. * * @param hr * The request and associated HTML document that will be * processed. */ public void tag_python(RewriteContext hr) { debug(hr); boolean eval = hr.isTrue("eval"); hr.accumulate(false); hr.nextToken(); interp.setOut(stdout); String script = hr.getBody(); if (eval) { script = Format.subst(hr.request.props, script, true); } hr.request.log(Server.LOG_DIAGNOSTIC, hr.prefix, script); try { interp.exec(script); } catch (PyException e) { hr.append("\n\n"); hr.request.log(Server.LOG_DIAGNOSTIC, hr.prefix, e.toString()); } interp.setOut(System.out); hr.nextToken(); hr.append(stdout.toString()); stdout.reset(); hr.accumulate(true); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy