001: package fr.aliacom.commands;
002:
003: import fr.aliacom.form.common.FormContext;
004: import fr.aliacom.form.common.IForm;
005: import fr.aliacom.form.common.ToolkitManager;
006: import fr.aliacom.util.InterpreterPool;
007: import fr.aliacom.util.JythonInterpreter;
008:
009: /**
010: * Instances of PythonCommand execute execute python script
011: * with jython.
012: *
013: * @author tom
014: *
015: * (c) 2001, 2003 Thomas Cataldo
016: */
017: class PythonCommand extends ASyncCommand {
018:
019: private String script;
020: private IForm form;
021: private FormContext ctx;
022:
023: /**
024: * Create a python command that will execute a python script.
025: * The script is loaded from the script repository provided by the
026: * running {@link fr.aliacom.form.common.IApplication}.
027: *
028: * When this script is executed, all the {@link fr.aliacom.form.common.FormVariable}
029: * defined in the given context will apear as real python variables.
030: * A special variable named <code>FORM</code> is automagically added the python
031: * variables before execution. It will referenced the {@link IForm} instance passed
032: * to this constructor.
033: *
034: * A variable named <code>LOG</code> is also added. This is a reference to
035: * a log4j logger.
036: *
037: * You should notice that (f.getFormContext() == ctx) might be false. Thanks to this,
038: * sub-parts of the UI (tabs,...) can be created dynamically from XML without poluting
039: * the FormContext of the main window. Consider 2 tabs in the main window
040: * with a textfield in each tab, created from the same XML file. The XML contains
041: * something like <code><textField id="myText"/></code>. When a PythonCommand
042: * linked to a button in the tab is executed, you clearly want it to refer to the
043: * correct TextField.
044: *
045: *
046: * @param form the form referenced by the <code>FORM</code> variable in the script.
047: * @param script the script to execute, loaded by an
048: * {@link fr.aliacom.form.storage.IScriptRepository}.
049: * @param ctx the variables defined when the script is executed
050: */
051: public PythonCommand(IForm form, String script, FormContext ctx) {
052: this .script = script;
053: this .form = form;
054: this .ctx = ctx;
055: }
056:
057: public void doIt() {
058: log.debug("Running command (" + script + ")");
059: try {
060: JythonInterpreter interp = InterpreterPool.getInstance()
061: .getInterpreter();
062: interp.executeByName(script, (ctx == null ? form
063: .getFormContext() : ctx));
064: interp.release();
065: } catch (Exception ie) {
066: log.fatal("Error occured while running " + script, ie);
067: /* sync execution would deadlock the event queue
068: * as python command are already executed in that
069: * queue.
070: */
071: ToolkitManager.getToolkit().asyncExec(new ErrorHandler(ie));
072: }
073: }
074:
075: private final class ErrorHandler implements Runnable {
076: private Throwable t;
077:
078: public ErrorHandler(Throwable t) {
079: this .t = t;
080: }
081:
082: public void run() {
083: ToolkitManager.getToolkit().handleError(
084: ToolkitManager.getToolkit().getMainWindow(), t);
085: }
086: }
087:
088: /**
089: * Method getForm.
090: * @return IForm
091: */
092: public IForm getForm() {
093: return form;
094: }
095:
096: public FormContext getContext() {
097: return ctx;
098: }
099:
100: /**
101: * @param form
102: */
103: public void setForm(IForm form) {
104: this.form = form;
105: }
106:
107: }
|