merged changes from refactor_scripting_05_02 branch
This commit is contained in:
		
							parent
							
								
									5a015fbbc5
								
							
						
					
					
						commit
						1bd0fe6c05
					
				
					 22 changed files with 1419 additions and 1438 deletions
				
			
		| 
						 | 
					@ -3,14 +3,13 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package helma.framework;
 | 
					package helma.framework;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import FESI.Exceptions.EcmaScriptException;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** 
 | 
					/**
 | 
				
			||||||
 * RedirectException is thrown internally when a response is redirected to a
 | 
					 * RedirectException is thrown internally when a response is redirected to a
 | 
				
			||||||
 * new URL.
 | 
					 * new URL.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 
 | 
					
 | 
				
			||||||
public class RedirectException extends EcmaScriptException {
 | 
					public class RedirectException extends RuntimeException {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    String url;
 | 
					    String url;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,11 +17,11 @@ public class RedirectException extends EcmaScriptException {
 | 
				
			||||||
	super ("Redirection Request to "+url);
 | 
						super ("Redirection Request to "+url);
 | 
				
			||||||
	this.url = url;
 | 
						this.url = url;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    public String getMessage () {
 | 
					    public String getMessage () {
 | 
				
			||||||
	return url;
 | 
						return url;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    public void printStackTrace(java.io.PrintStream s) {
 | 
					    public void printStackTrace(java.io.PrintStream s) {
 | 
				
			||||||
	// do nothing
 | 
						// do nothing
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,8 +35,7 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IPat
 | 
				
			||||||
    protected NodeManager nmgr;
 | 
					    protected NodeManager nmgr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // the class name of the scripting environment implementation
 | 
					    // the class name of the scripting environment implementation
 | 
				
			||||||
    static final String scriptEnvironmentName = "helma.scripting.fesi.Environment";
 | 
					    ScriptingEnvironment scriptingEngine;
 | 
				
			||||||
    ScriptingEnvironment scriptEnv;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // the root of the website, if a custom root object is defined.
 | 
					    // the root of the website, if a custom root object is defined.
 | 
				
			||||||
    // otherwise this is managed by the NodeManager and not cached here.
 | 
					    // otherwise this is managed by the NodeManager and not cached here.
 | 
				
			||||||
| 
						 | 
					@ -49,6 +48,11 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IPat
 | 
				
			||||||
    */
 | 
					    */
 | 
				
			||||||
    public TypeManager typemgr;
 | 
					    public TypeManager typemgr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The skin manager for this application
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    protected SkinManager skinmgr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
    *  Each application has one internal request evaluator for calling
 | 
					    *  Each application has one internal request evaluator for calling
 | 
				
			||||||
    * the scheduler and other internal functions.
 | 
					    * the scheduler and other internal functions.
 | 
				
			||||||
| 
						 | 
					@ -227,7 +231,9 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IPat
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Get the application ready to run, initializing the evaluators and type manager.
 | 
					     * Get the application ready to run, initializing the evaluators and type manager.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public void init () throws DbException {
 | 
					    public void init () throws DbException, ScriptingException {
 | 
				
			||||||
 | 
						scriptingEngine = new helma.scripting.fesi.FesiScriptingEnvironment ();
 | 
				
			||||||
 | 
						scriptingEngine.init (this, props);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	eval = new RequestEvaluator (this);
 | 
						eval = new RequestEvaluator (this);
 | 
				
			||||||
	logEvent ("Starting evaluators for "+name);
 | 
						logEvent ("Starting evaluators for "+name);
 | 
				
			||||||
| 
						 | 
					@ -249,6 +255,8 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IPat
 | 
				
			||||||
	typemgr.createPrototypes ();
 | 
						typemgr.createPrototypes ();
 | 
				
			||||||
	// logEvent ("Started type manager for "+name);
 | 
						// logEvent ("Started type manager for "+name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						skinmgr = new SkinManager (this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rootMapping = getDbMapping ("root");
 | 
						rootMapping = getDbMapping ("root");
 | 
				
			||||||
	userMapping = getDbMapping ("user");
 | 
						userMapping = getDbMapping ("user");
 | 
				
			||||||
	SystemProperties p = new SystemProperties ();
 | 
						SystemProperties p = new SystemProperties ();
 | 
				
			||||||
| 
						 | 
					@ -366,7 +374,7 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IPat
 | 
				
			||||||
	            try {
 | 
						            try {
 | 
				
			||||||
	                RequestEvaluator re = (RequestEvaluator) freeThreads.pop ();
 | 
						                RequestEvaluator re = (RequestEvaluator) freeThreads.pop ();
 | 
				
			||||||
	                allThreads.removeElement (re);
 | 
						                allThreads.removeElement (re);
 | 
				
			||||||
	                typemgr.unregisterRequestEvaluator (re);
 | 
						                // typemgr.unregisterRequestEvaluator (re);
 | 
				
			||||||
	                re.stopThread ();
 | 
						                re.stopThread ();
 | 
				
			||||||
	            } catch (EmptyStackException empty) {
 | 
						            } catch (EmptyStackException empty) {
 | 
				
			||||||
	                return false;
 | 
						                return false;
 | 
				
			||||||
| 
						 | 
					@ -520,6 +528,13 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IPat
 | 
				
			||||||
	return nmgr.safe;
 | 
						return nmgr.safe;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     *  Return a transient node that is shared by all evaluators of this application ("app node")
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public INode getAppNode () {
 | 
				
			||||||
 | 
						return appnode;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Returns a Node representing a registered user of this application by his or her user name.
 | 
					     * Returns a Node representing a registered user of this application by his or her user name.
 | 
				
			||||||
| 
						 | 
					@ -552,9 +567,16 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IPat
 | 
				
			||||||
     * Return a collection containing all prototypes defined for this application
 | 
					     * Return a collection containing all prototypes defined for this application
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public Collection getPrototypes () {
 | 
					    public Collection getPrototypes () {
 | 
				
			||||||
    return typemgr.prototypes.values ();
 | 
						return typemgr.prototypes.values ();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     *  Retrurn a skin for a given object. The skin is found by determining the prototype
 | 
				
			||||||
 | 
					     *  to use for the object, then looking up the skin for the prototype.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public Skin getSkin (Object object, String skinname, Object[] skinpath) {
 | 
				
			||||||
 | 
						return skinmgr.getSkin (object, skinname, skinpath); // not yet implemented
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Return the user currently associated with a given Hop session ID. This may be
 | 
					     * Return the user currently associated with a given Hop session ID. This may be
 | 
				
			||||||
| 
						 | 
					@ -815,6 +837,8 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IPat
 | 
				
			||||||
     * within the Helma scripting and rendering framework.
 | 
					     * within the Helma scripting and rendering framework.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public String getPrototypeName (Object obj) {
 | 
					    public String getPrototypeName (Object obj) {
 | 
				
			||||||
 | 
						if (obj == null)
 | 
				
			||||||
 | 
						    return "global";
 | 
				
			||||||
	// check if e implements the IPathElement interface
 | 
						// check if e implements the IPathElement interface
 | 
				
			||||||
	if (obj instanceof IPathElement)
 | 
						if (obj instanceof IPathElement)
 | 
				
			||||||
	    // e implements the getPrototype() method
 | 
						    // e implements the getPrototype() method
 | 
				
			||||||
| 
						 | 
					@ -902,6 +926,14 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IPat
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     *  Get scripting environment for this application
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public ScriptingEnvironment getScriptingEnvironment () {
 | 
				
			||||||
 | 
						return scriptingEngine;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * The run method performs periodic tasks like executing the scheduler method and
 | 
					     * The run method performs periodic tasks like executing the scheduler method and
 | 
				
			||||||
     * kicking out expired user sessions.
 | 
					     * kicking out expired user sessions.
 | 
				
			||||||
| 
						 | 
					@ -917,7 +949,9 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IPat
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	try {
 | 
						try {
 | 
				
			||||||
	    eval.invokeFunction ((INode) null, "onStart", new Object[0]);
 | 
						    eval.invokeFunction ((INode) null, "onStart", new Object[0]);
 | 
				
			||||||
	} catch (Exception ignore) {}
 | 
						} catch (Exception ignore) {
 | 
				
			||||||
 | 
						    System.err.println ("Error in "+name+"/onStart(): "+ignore);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	while (Thread.currentThread () == worker) {
 | 
						while (Thread.currentThread () == worker) {
 | 
				
			||||||
	    // get session timeout
 | 
						    // get session timeout
 | 
				
			||||||
| 
						 | 
					@ -1022,7 +1056,7 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IPat
 | 
				
			||||||
     * Check whether a prototype is for scripting a java class, i.e. if there's an entry
 | 
					     * Check whether a prototype is for scripting a java class, i.e. if there's an entry
 | 
				
			||||||
     * for it in the class.properties file.
 | 
					     * for it in the class.properties file.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    protected boolean isJavaPrototype (String typename) {
 | 
					    public boolean isJavaPrototype (String typename) {
 | 
				
			||||||
	for (Enumeration en = classMapping.elements(); en.hasMoreElements(); ) {
 | 
						for (Enumeration en = classMapping.elements(); en.hasMoreElements(); ) {
 | 
				
			||||||
	    String value = (String) en.nextElement ();
 | 
						    String value = (String) en.nextElement ();
 | 
				
			||||||
	    if (typename.equals (value))
 | 
						    if (typename.equals (value))
 | 
				
			||||||
| 
						 | 
					@ -1129,7 +1163,9 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IPat
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public int countMaxActiveEvaluators () {
 | 
					    public int countMaxActiveEvaluators () {
 | 
				
			||||||
	return typemgr.countRegisteredRequestEvaluators () -1;
 | 
						// return typemgr.countRegisteredRequestEvaluators () -1;
 | 
				
			||||||
 | 
						// not available due to framework refactoring
 | 
				
			||||||
 | 
						return -1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
| 
						 | 
					@ -1194,7 +1230,7 @@ class XmlRpcInvoker implements XmlRpcHandler {
 | 
				
			||||||
	RequestEvaluator ev = null;
 | 
						RequestEvaluator ev = null;
 | 
				
			||||||
	try {
 | 
						try {
 | 
				
			||||||
	    ev = app.getEvaluator ();
 | 
						    ev = app.getEvaluator ();
 | 
				
			||||||
	    retval = ev.invokeXmlRpc (method, argvec);
 | 
						    retval = ev.invokeXmlRpc (method, argvec.toArray());
 | 
				
			||||||
	}  finally {
 | 
						}  finally {
 | 
				
			||||||
	    app.releaseEvaluator (ev);
 | 
						    app.releaseEvaluator (ev);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,11 +8,8 @@ import java.util.Iterator;
 | 
				
			||||||
import java.io.*;
 | 
					import java.io.*;
 | 
				
			||||||
import helma.framework.*;
 | 
					import helma.framework.*;
 | 
				
			||||||
import helma.scripting.*;
 | 
					import helma.scripting.*;
 | 
				
			||||||
import helma.scripting.fesi.*;
 | 
					 | 
				
			||||||
import helma.objectmodel.*;
 | 
					import helma.objectmodel.*;
 | 
				
			||||||
import helma.util.Updatable;
 | 
					import helma.util.Updatable;
 | 
				
			||||||
import FESI.Data.*;
 | 
					 | 
				
			||||||
import FESI.Exceptions.EcmaScriptException;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					@ -66,12 +63,12 @@ public class Prototype {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// if parent has changed, update ES-prototypes in request evaluators
 | 
						// if parent has changed, update ES-prototypes in request evaluators
 | 
				
			||||||
	if (parent != old) {
 | 
						if (parent != old) {
 | 
				
			||||||
	    Iterator evals = app.typemgr.getRegisteredRequestEvaluators ();
 | 
						    /* Iterator evals = app.typemgr.getRegisteredRequestEvaluators ();
 | 
				
			||||||
	    while (evals.hasNext ()) {
 | 
						    while (evals.hasNext ()) {
 | 
				
			||||||
	        try {
 | 
						        try {
 | 
				
			||||||
	            RequestEvaluator reval = (RequestEvaluator) evals.next ();
 | 
						            RequestEvaluator reval = (RequestEvaluator) evals.next ();
 | 
				
			||||||
	            ObjectPrototype op = reval.getPrototype (getName());
 | 
						            ObjectPrototype op = reval.getPrototype (getName());
 | 
				
			||||||
	            // use hopobject (node) as prototype even if prototype is null - 
 | 
						            // use hopobject (node) as prototype even if prototype is null -
 | 
				
			||||||
	            // this is the case if no hopobject directory exists
 | 
						            // this is the case if no hopobject directory exists
 | 
				
			||||||
	            ObjectPrototype opp = parent == null ?
 | 
						            ObjectPrototype opp = parent == null ?
 | 
				
			||||||
	            	reval.esNodePrototype : reval.getPrototype (parent.getName ());
 | 
						            	reval.esNodePrototype : reval.getPrototype (parent.getName ());
 | 
				
			||||||
| 
						 | 
					@ -81,7 +78,7 @@ public class Prototype {
 | 
				
			||||||
	            op.setPrototype (opp);
 | 
						            op.setPrototype (opp);
 | 
				
			||||||
	        } catch (Exception ignore) {
 | 
						        } catch (Exception ignore) {
 | 
				
			||||||
	        }
 | 
						        }
 | 
				
			||||||
	    }
 | 
						    } */
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -97,8 +94,8 @@ public class Prototype {
 | 
				
			||||||
	return (FunctionFile) functions.get (ffname);
 | 
						return (FunctionFile) functions.get (ffname);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public Action getAction (String afname) {
 | 
					    public ActionFile getActionFile (String afname) {
 | 
				
			||||||
	return (Action) actions.get (afname);
 | 
						return (ActionFile) actions.get (afname);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public SkinFile getSkinFile (String sfname) {
 | 
					    public SkinFile getSkinFile (String sfname) {
 | 
				
			||||||
| 
						 | 
					@ -128,76 +125,11 @@ public class Prototype {
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return upd;
 | 
						return upd;
 | 
				
			||||||
	
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public void initRequestEvaluator (RequestEvaluator reval) {
 | 
					 | 
				
			||||||
	// see if we already registered with this evaluator
 | 
					 | 
				
			||||||
	if (reval.getPrototype (name) != null)
 | 
					 | 
				
			||||||
	    return;
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	ObjectPrototype op = null;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// get the prototype's prototype if possible and necessary
 | 
					 | 
				
			||||||
	ObjectPrototype opp = null;
 | 
					 | 
				
			||||||
	if (parent != null) {
 | 
					 | 
				
			||||||
	    // see if parent prototype is already registered. if not, register it
 | 
					 | 
				
			||||||
	    opp = reval.getPrototype (parent.getName ());
 | 
					 | 
				
			||||||
	    if (opp == null) {
 | 
					 | 
				
			||||||
	        parent.initRequestEvaluator (reval);
 | 
					 | 
				
			||||||
	        opp = reval.getPrototype (parent.getName ());
 | 
					 | 
				
			||||||
	    }
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (!"global".equalsIgnoreCase (name) && !"hopobject".equalsIgnoreCase (name) && opp == null) {
 | 
					 | 
				
			||||||
	    if (isJavaPrototype)
 | 
					 | 
				
			||||||
	        opp = reval.esObjectPrototype;
 | 
					 | 
				
			||||||
	    else
 | 
					 | 
				
			||||||
	        opp = reval.esNodePrototype;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if ("user".equalsIgnoreCase (name)) {
 | 
					 | 
				
			||||||
	    op = reval.esUserPrototype;
 | 
					 | 
				
			||||||
	    op.setPrototype (opp);
 | 
					 | 
				
			||||||
	} else if ("global".equalsIgnoreCase (name))
 | 
					 | 
				
			||||||
	    op = reval.global;
 | 
					 | 
				
			||||||
	else if ("hopobject".equalsIgnoreCase (name))
 | 
					 | 
				
			||||||
	    op = reval.esNodePrototype;
 | 
					 | 
				
			||||||
	else {
 | 
					 | 
				
			||||||
	    op = new ObjectPrototype (opp, reval.evaluator);
 | 
					 | 
				
			||||||
	    try {
 | 
					 | 
				
			||||||
	        op.putProperty ("prototypename", new ESString (name), "prototypename".hashCode ());
 | 
					 | 
				
			||||||
	    } catch (EcmaScriptException ignore) {}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	reval.putPrototype (name, op);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Register a constructor for all types except global.
 | 
					 | 
				
			||||||
	// This will first create a node and then call the actual (scripted) constructor on it.
 | 
					 | 
				
			||||||
	if (!"global".equalsIgnoreCase (name)) {
 | 
					 | 
				
			||||||
	    try {
 | 
					 | 
				
			||||||
	        FunctionPrototype fp = (FunctionPrototype) reval.evaluator.getFunctionPrototype();
 | 
					 | 
				
			||||||
	        reval.global.putHiddenProperty (name, new NodeConstructor (name, fp, reval));
 | 
					 | 
				
			||||||
	    } catch (EcmaScriptException ignore) {}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	for (Iterator it = functions.values().iterator(); it.hasNext(); ) {
 | 
					 | 
				
			||||||
	    FunctionFile ff = (FunctionFile) it.next ();
 | 
					 | 
				
			||||||
	    ff.updateRequestEvaluator (reval);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	for (Iterator it = templates.values().iterator(); it.hasNext(); ) {
 | 
					 | 
				
			||||||
	    Template tmp = (Template) it.next ();
 | 
					 | 
				
			||||||
	    try {
 | 
					 | 
				
			||||||
	        tmp.updateRequestEvaluator (reval);
 | 
					 | 
				
			||||||
	    } catch (EcmaScriptException ignore) {}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	for (Iterator it = actions.values().iterator(); it.hasNext(); ) {
 | 
					 | 
				
			||||||
	    Action act = (Action) it.next ();
 | 
					 | 
				
			||||||
	    try {
 | 
					 | 
				
			||||||
	        act.updateRequestEvaluator (reval);
 | 
					 | 
				
			||||||
	    } catch (EcmaScriptException ignore) {}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public String toString () {
 | 
					    public String toString () {
 | 
				
			||||||
	return "[Prototype "+ app.getName()+"/"+name+"]";
 | 
						return "[Prototype "+ app.getName()+"/"+name+"]";
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
					@ -278,9 +278,9 @@ public class Skin {
 | 
				
			||||||
	            if (handlerObject == null) {
 | 
						            if (handlerObject == null) {
 | 
				
			||||||
	                // eiter because thisObject == null or the right object wasn't found in the object's parent path
 | 
						                // eiter because thisObject == null or the right object wasn't found in the object's parent path
 | 
				
			||||||
	                // go check request path for an object with matching prototype
 | 
						                // go check request path for an object with matching prototype
 | 
				
			||||||
	                int l = reval.reqPath.size();
 | 
						                int l = reval.requestPath.size();
 | 
				
			||||||
	                for (int i=l-1; i>=0; i--) {
 | 
						                for (int i=l-1; i>=0; i--) {
 | 
				
			||||||
	                    Object pathelem = reval.reqPath.getProperty (i).toJavaObject ();
 | 
						                    Object pathelem = reval.requestPath.get (i);
 | 
				
			||||||
	                    if (handler.equalsIgnoreCase (app.getPrototypeName (pathelem))) {
 | 
						                    if (handler.equalsIgnoreCase (app.getPrototypeName (pathelem))) {
 | 
				
			||||||
	                         handlerObject = pathelem;
 | 
						                         handlerObject = pathelem;
 | 
				
			||||||
	                         break;
 | 
						                         break;
 | 
				
			||||||
| 
						 | 
					@ -302,12 +302,12 @@ public class Skin {
 | 
				
			||||||
	            // if so, the macro evaluates to the function. Otherwise,
 | 
						            // if so, the macro evaluates to the function. Otherwise,
 | 
				
			||||||
	            // a property/field with the name is used, if defined.
 | 
						            // a property/field with the name is used, if defined.
 | 
				
			||||||
	            Object v = null;
 | 
						            Object v = null;
 | 
				
			||||||
	            if (reval.hasFunction (handlerObject, name+"_macro")) {
 | 
						            if (app.scriptingEngine.hasFunction (handlerObject, name+"_macro", reval)) {
 | 
				
			||||||
	                // System.err.println ("Getting macro from function");
 | 
						                // System.err.println ("Getting macro from function");
 | 
				
			||||||
	                v = reval.invokeDirectFunction (handlerObject, name+"_macro", arguments);
 | 
						                v = app.scriptingEngine.invoke (handlerObject, name+"_macro", arguments, null, reval);
 | 
				
			||||||
	            } else {
 | 
						            } else {
 | 
				
			||||||
	                // System.err.println ("Getting macro from property");
 | 
						                // System.err.println ("Getting macro from property");
 | 
				
			||||||
	                v = reval.getProperty (handlerObject, name);
 | 
						                v = app.scriptingEngine.get (handlerObject, name, reval);
 | 
				
			||||||
	            }
 | 
						            }
 | 
				
			||||||
	            if (v != null)
 | 
						            if (v != null)
 | 
				
			||||||
	                writeToResponse (v.toString (), reval.res);
 | 
						                writeToResponse (v.toString (), reval.res);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										134
									
								
								src/helma/framework/core/SkinManager.java
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								src/helma/framework/core/SkinManager.java
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,134 @@
 | 
				
			||||||
 | 
					// SkinManager.java
 | 
				
			||||||
 | 
					// Copyright (c) Hannes Wallnöfer 2002
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					package helma.framework.core;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.HashMap;
 | 
				
			||||||
 | 
					import java.util.Iterator;
 | 
				
			||||||
 | 
					import helma.objectmodel.INode;
 | 
				
			||||||
 | 
					import java.io.*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Manages skins for a Helma application
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class SkinManager {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Application app;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public SkinManager (Application app) {
 | 
				
			||||||
 | 
						this.app = app;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public Skin getSkin (Object object, String skinname, Object[] skinpath) {
 | 
				
			||||||
 | 
						Prototype proto = app.getPrototype (object);
 | 
				
			||||||
 | 
						return getSkin (proto, skinname, "skin", skinpath);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public Skin getSkin (Prototype proto, String skinname, String extension, Object[] skinpath) {
 | 
				
			||||||
 | 
						if (proto == null)
 | 
				
			||||||
 | 
						    return null;
 | 
				
			||||||
 | 
						Skin skin = null;
 | 
				
			||||||
 | 
						// First check if the skin has been already used within the execution of this request
 | 
				
			||||||
 | 
						/* SkinKey key = new SkinKey (proto.getName(), skinname, extension);
 | 
				
			||||||
 | 
						Skin skin = (Skin) skincache.get (key);
 | 
				
			||||||
 | 
						if (skin != null) {
 | 
				
			||||||
 | 
						    return skin;
 | 
				
			||||||
 | 
						} */
 | 
				
			||||||
 | 
						// check for skinsets set via res.skinpath property
 | 
				
			||||||
 | 
						do {
 | 
				
			||||||
 | 
						    if (skinpath != null) {
 | 
				
			||||||
 | 
						        for (int i=0; i<skinpath.length; i++) {
 | 
				
			||||||
 | 
						            skin = getSkinInternal (skinpath[i], proto.getName (), skinname, extension);
 | 
				
			||||||
 | 
						            if (skin != null) {
 | 
				
			||||||
 | 
						                // skincache.put (key, skin);
 | 
				
			||||||
 | 
						                return skin;
 | 
				
			||||||
 | 
						            }
 | 
				
			||||||
 | 
						        }
 | 
				
			||||||
 | 
						    }
 | 
				
			||||||
 | 
						    // skin for this prototype wasn't found in the skinsets.
 | 
				
			||||||
 | 
						    // the next step is to look if it is defined as skin file in the application directory
 | 
				
			||||||
 | 
						    skin = proto.getSkin (skinname);
 | 
				
			||||||
 | 
						    if (skin != null) {
 | 
				
			||||||
 | 
						        // skincache.put (key, skin);
 | 
				
			||||||
 | 
						        return skin;
 | 
				
			||||||
 | 
						    }
 | 
				
			||||||
 | 
						    // still not found. See if there is a parent prototype which might define the skin.
 | 
				
			||||||
 | 
						    proto = proto.getParentPrototype ();
 | 
				
			||||||
 | 
						} while (proto != null);
 | 
				
			||||||
 | 
						// looked every where, nothing to be found
 | 
				
			||||||
 | 
						return null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected Skin getSkinInternal (Object skinset, String prototype, String skinname, String extension) {
 | 
				
			||||||
 | 
						if (prototype == null || skinset == null)
 | 
				
			||||||
 | 
						    return null;
 | 
				
			||||||
 | 
						// check if the skinset object is a HopObject (db based skin)
 | 
				
			||||||
 | 
						// or a String (file based skin)
 | 
				
			||||||
 | 
						if (skinset instanceof INode) {
 | 
				
			||||||
 | 
						    INode n = ((INode) skinset).getNode (prototype, false);
 | 
				
			||||||
 | 
						    if (n != null) {
 | 
				
			||||||
 | 
						        n = n.getNode (skinname, false);
 | 
				
			||||||
 | 
						        if (n != null) {
 | 
				
			||||||
 | 
						            String skin = n.getString (extension, false);
 | 
				
			||||||
 | 
						            if (skin != null) {
 | 
				
			||||||
 | 
						                Skin s = (Skin) app.skincache.get (skin);
 | 
				
			||||||
 | 
						                if (s == null) {
 | 
				
			||||||
 | 
						                    s = new Skin (skin, app);
 | 
				
			||||||
 | 
						                    app.skincache.put (skin, s);
 | 
				
			||||||
 | 
						                }
 | 
				
			||||||
 | 
						                return s;
 | 
				
			||||||
 | 
						            }
 | 
				
			||||||
 | 
						        }
 | 
				
			||||||
 | 
						    }
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
						    // Skinset is interpreted as directory name from which to
 | 
				
			||||||
 | 
						    // retrieve the skin
 | 
				
			||||||
 | 
						    File f = new File (skinset.toString (), prototype);
 | 
				
			||||||
 | 
						    f = new File (f, skinname+"."+extension);
 | 
				
			||||||
 | 
						    if (f.exists() && f.canRead()) {
 | 
				
			||||||
 | 
						        SkinFile sf = new SkinFile (f, skinname, app);
 | 
				
			||||||
 | 
						        Skin s = sf.getSkin ();
 | 
				
			||||||
 | 
						        return s;
 | 
				
			||||||
 | 
						    }
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// Inheritance is taken care of in the above getSkin method.
 | 
				
			||||||
 | 
						// the sequence is prototype.skin-from-db, prototype.skin-from-file, parent.from-db, parent.from-file etc.
 | 
				
			||||||
 | 
						return null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     *  Utility class to use for caching skins in a Hashtable.
 | 
				
			||||||
 | 
					     *  The key consists out of two strings: prototype name and skin name.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    final class SkinKey {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						final String first, second, third;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public SkinKey (String first, String second, String third) {
 | 
				
			||||||
 | 
						    this.first = first;
 | 
				
			||||||
 | 
						    this.second = second;
 | 
				
			||||||
 | 
						    this.third = third;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public boolean equals (Object other) {
 | 
				
			||||||
 | 
						    try {
 | 
				
			||||||
 | 
						        SkinKey key = (SkinKey) other;
 | 
				
			||||||
 | 
						        return first.equals (key.first) && second.equals (key.second) && third.equals (key.third);
 | 
				
			||||||
 | 
						    } catch (Exception x) {
 | 
				
			||||||
 | 
						        return false;
 | 
				
			||||||
 | 
						    }
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public int hashCode () {
 | 
				
			||||||
 | 
						    return first.hashCode () + second.hashCode () + third.hashCode ();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -225,7 +225,7 @@ public class TypeManager {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                } else if (list[i].endsWith (app.actionExtension) && tmpfile.length () > 0) {
 | 
					                } else if (list[i].endsWith (app.actionExtension) && tmpfile.length () > 0) {
 | 
				
			||||||
                    try {
 | 
					                    try {
 | 
				
			||||||
                        Action af = new Action (tmpfile, tmpname, proto);
 | 
					                        ActionFile af = new ActionFile (tmpfile, tmpname, proto);
 | 
				
			||||||
                        updatables.put (list[i], af);
 | 
					                        updatables.put (list[i], af);
 | 
				
			||||||
                        nact.put (tmpname, af);
 | 
					                        nact.put (tmpname, af);
 | 
				
			||||||
                    } catch (Throwable x) {
 | 
					                    } catch (Throwable x) {
 | 
				
			||||||
| 
						 | 
					@ -257,11 +257,12 @@ public class TypeManager {
 | 
				
			||||||
        proto.updatables = updatables;
 | 
					        proto.updatables = updatables;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // init prototype on evaluators that are already initialized.
 | 
					        // init prototype on evaluators that are already initialized.
 | 
				
			||||||
        Iterator evals = getRegisteredRequestEvaluators ();
 | 
					        /* Iterator evals = getRegisteredRequestEvaluators ();
 | 
				
			||||||
        while (evals.hasNext ()) {
 | 
					        while (evals.hasNext ()) {
 | 
				
			||||||
            RequestEvaluator reval = (RequestEvaluator) evals.next ();
 | 
					            RequestEvaluator reval = (RequestEvaluator) evals.next ();
 | 
				
			||||||
            proto.initRequestEvaluator (reval);
 | 
					            proto.initRequestEvaluator (reval);
 | 
				
			||||||
        }
 | 
					        }*/
 | 
				
			||||||
 | 
					        app.scriptingEngine.updatePrototype (proto);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -303,9 +304,9 @@ public class TypeManager {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!needsUpdate)
 | 
					        if (!needsUpdate)
 | 
				
			||||||
	return;
 | 
						return;
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
        proto.lastUpdate = System.currentTimeMillis ();
 | 
					        proto.lastUpdate = System.currentTimeMillis ();
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
        // let the thread know we had to do something.
 | 
					        // let the thread know we had to do something.
 | 
				
			||||||
        idleSeconds = 0;
 | 
					        idleSeconds = 0;
 | 
				
			||||||
        // app.logEvent ("TypeManager: Updating prototypes for "+app.getName()+": "+updatables);
 | 
					        // app.logEvent ("TypeManager: Updating prototypes for "+app.getName()+": "+updatables);
 | 
				
			||||||
| 
						 | 
					@ -347,7 +348,7 @@ public class TypeManager {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            }  else if (list[i].endsWith (app.actionExtension)) {
 | 
					            }  else if (list[i].endsWith (app.actionExtension)) {
 | 
				
			||||||
                try {
 | 
					                try {
 | 
				
			||||||
                    Action af = new Action (tmpfile, tmpname, proto);
 | 
					                    ActionFile af = new ActionFile (tmpfile, tmpname, proto);
 | 
				
			||||||
                    proto.updatables.put (list[i], af);
 | 
					                    proto.updatables.put (list[i], af);
 | 
				
			||||||
                    proto.actions.put (tmpname, af);
 | 
					                    proto.actions.put (tmpname, af);
 | 
				
			||||||
                } catch (Throwable x) {
 | 
					                } catch (Throwable x) {
 | 
				
			||||||
| 
						 | 
					@ -362,29 +363,29 @@ public class TypeManager {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // next go through existing updatables
 | 
					        // next go through existing updatables
 | 
				
			||||||
        if (updatables == null)
 | 
					        if (updatables != null) {
 | 
				
			||||||
            return;
 | 
					            for (Iterator i = updatables.iterator(); i.hasNext(); ) {
 | 
				
			||||||
        for (Iterator i = updatables.iterator(); i.hasNext(); ) {
 | 
					                Updatable upd = (Updatable) i.next();
 | 
				
			||||||
            Updatable upd = (Updatable) i.next();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (upd.needsUpdate ()) {
 | 
					                if (upd.needsUpdate ()) {
 | 
				
			||||||
                if (upd instanceof DbMapping)
 | 
					                    if (upd instanceof DbMapping)
 | 
				
			||||||
                    rewire = true;
 | 
					                        rewire = true;
 | 
				
			||||||
                try {
 | 
					                    try {
 | 
				
			||||||
                    upd.update ();
 | 
					                        upd.update ();
 | 
				
			||||||
                } catch (Exception x) {
 | 
					                    } catch (Exception x) {
 | 
				
			||||||
                     if (upd instanceof DbMapping)
 | 
					                         if (upd instanceof DbMapping)
 | 
				
			||||||
	            app.logEvent ("Error updating db mapping for type "+name+": "+x);
 | 
					                            app.logEvent ("Error updating db mapping for type "+name+": "+x);
 | 
				
			||||||
                     else
 | 
					                         else
 | 
				
			||||||
	            app.logEvent ("Error updating "+upd+" of prototye type "+name+": "+x);
 | 
					                            app.logEvent ("Error updating "+upd+" of prototye type "+name+": "+x);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        app.scriptingEngine.updatePrototype (proto);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*public void initRequestEvaluator (RequestEvaluator reval) {
 | 
				
			||||||
    public void initRequestEvaluator (RequestEvaluator reval) {
 | 
					 | 
				
			||||||
        if (!registeredEvaluators.contains (reval))
 | 
					        if (!registeredEvaluators.contains (reval))
 | 
				
			||||||
            registeredEvaluators.add (reval);
 | 
					            registeredEvaluators.add (reval);
 | 
				
			||||||
        for (Iterator it = prototypes.values().iterator(); it.hasNext(); ) {
 | 
					        for (Iterator it = prototypes.values().iterator(); it.hasNext(); ) {
 | 
				
			||||||
| 
						 | 
					@ -404,7 +405,7 @@ public class TypeManager {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public int countRegisteredRequestEvaluators () {
 | 
					    public int countRegisteredRequestEvaluators () {
 | 
				
			||||||
        return registeredEvaluators.size ();
 | 
					        return registeredEvaluators.size ();
 | 
				
			||||||
    }
 | 
					    } */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -72,16 +72,14 @@ public class ZippedAppFile implements Updatable {
 | 
				
			||||||
	                    String name = fname.substring (0, fname.lastIndexOf ("."));
 | 
						                    String name = fname.substring (0, fname.lastIndexOf ("."));
 | 
				
			||||||
	                    String content = getZipEntryContent (zip, entry);
 | 
						                    String content = getZipEntryContent (zip, entry);
 | 
				
			||||||
	                    // System.err.println ("["+content+"]");
 | 
						                    // System.err.println ("["+content+"]");
 | 
				
			||||||
	                    Action act = new Action (null, name, proto);
 | 
						                    ActionFile act = new ActionFile (content, name, proto);
 | 
				
			||||||
	                    act.update (content);
 | 
					 | 
				
			||||||
	                    proto.actions.put (name, act);
 | 
						                    proto.actions.put (name, act);
 | 
				
			||||||
	                }
 | 
						                }
 | 
				
			||||||
	                else if (fname.endsWith (".hsp")) {
 | 
						                else if (fname.endsWith (".hsp")) {
 | 
				
			||||||
	                    String name = fname.substring (0, fname.lastIndexOf ("."));
 | 
						                    String name = fname.substring (0, fname.lastIndexOf ("."));
 | 
				
			||||||
	                    String content = getZipEntryContent (zip, entry);
 | 
						                    String content = getZipEntryContent (zip, entry);
 | 
				
			||||||
	                    // System.err.println ("["+content+"]");
 | 
						                    // System.err.println ("["+content+"]");
 | 
				
			||||||
	                    Template tmp = new Template (null, name, proto);
 | 
						                    Template tmp = new Template (content, name, proto);
 | 
				
			||||||
	                    tmp.update (content);
 | 
					 | 
				
			||||||
	                    proto.templates.put (name, tmp);
 | 
						                    proto.templates.put (name, tmp);
 | 
				
			||||||
	                }
 | 
						                }
 | 
				
			||||||
	                else if (fname.endsWith (".skin")) {
 | 
						                else if (fname.endsWith (".skin")) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										128
									
								
								src/helma/scripting/ActionFile.java
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								src/helma/scripting/ActionFile.java
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,128 @@
 | 
				
			||||||
 | 
					// ActionFile.java
 | 
				
			||||||
 | 
					// Copyright (c) Helma.org 1998-2002
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package helma.scripting;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.Vector;
 | 
				
			||||||
 | 
					import java.util.Iterator;
 | 
				
			||||||
 | 
					import java.io.*;
 | 
				
			||||||
 | 
					import helma.framework.*;
 | 
				
			||||||
 | 
					import helma.framework.core.*;
 | 
				
			||||||
 | 
					import helma.util.Updatable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 *  An ActionFile is a file containing function code that is exposed as a URI
 | 
				
			||||||
 | 
					 *  of objects of this class/type. It is
 | 
				
			||||||
 | 
					 *  usually represented by a file with extension .hac (hop action file)
 | 
				
			||||||
 | 
					 *  that contains the raw body of the function.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class ActionFile implements Updatable {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    String name;
 | 
				
			||||||
 | 
					    String functionName;
 | 
				
			||||||
 | 
					    Prototype prototype;
 | 
				
			||||||
 | 
					    Application app;
 | 
				
			||||||
 | 
					    File file;
 | 
				
			||||||
 | 
					    String content;
 | 
				
			||||||
 | 
					    long lastmod;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public ActionFile (File file, String name, Prototype proto) {
 | 
				
			||||||
 | 
						this.prototype = proto;
 | 
				
			||||||
 | 
						this.app = proto.getApplication ();
 | 
				
			||||||
 | 
						this.name = name;
 | 
				
			||||||
 | 
						functionName = getName()+"_action";
 | 
				
			||||||
 | 
						this.file = file;
 | 
				
			||||||
 | 
						this.content = null;
 | 
				
			||||||
 | 
						if (file != null)
 | 
				
			||||||
 | 
						    update ();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public ActionFile (String content, String name, Prototype proto) {
 | 
				
			||||||
 | 
						this.prototype = proto;
 | 
				
			||||||
 | 
						this.app = proto.getApplication ();
 | 
				
			||||||
 | 
						this.name = name;
 | 
				
			||||||
 | 
						functionName = getName()+"_action";
 | 
				
			||||||
 | 
						this.file = null;
 | 
				
			||||||
 | 
						this.content = content;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Abstract method that must be implemented by subclasses to update evaluators with
 | 
				
			||||||
 | 
					     * new content of action file.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    // protected abstract void update (String content) throws Exception;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Abstract method that must be implemented by subclasses to remove
 | 
				
			||||||
 | 
					     * action from evaluators.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    // protected abstract void remove ();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Tell the type manager whether we need an update. this is the case when
 | 
				
			||||||
 | 
					     * the file has been modified or deleted.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public boolean needsUpdate () {
 | 
				
			||||||
 | 
						return lastmod != file.lastModified ();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public void update () {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!file.exists ()) {
 | 
				
			||||||
 | 
						    // remove functions declared by this from all object prototypes
 | 
				
			||||||
 | 
						    remove ();
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
						    try {
 | 
				
			||||||
 | 
						        FileReader reader = new FileReader (file);
 | 
				
			||||||
 | 
						        char cbuf[] = new char[(int) file.length ()];
 | 
				
			||||||
 | 
						        reader.read (cbuf);
 | 
				
			||||||
 | 
						        reader.close ();
 | 
				
			||||||
 | 
						        content = new String (cbuf);
 | 
				
			||||||
 | 
						        // update (content);
 | 
				
			||||||
 | 
						    } catch (Exception filex) {
 | 
				
			||||||
 | 
						        app.logEvent ("*** Error reading action file "+file+": "+filex);
 | 
				
			||||||
 | 
						    }
 | 
				
			||||||
 | 
						    lastmod = file.lastModified ();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected void remove () {
 | 
				
			||||||
 | 
						prototype.actions.remove (name);
 | 
				
			||||||
 | 
						if (file != null)
 | 
				
			||||||
 | 
						    prototype.updatables.remove (file.getName());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public String getName () {
 | 
				
			||||||
 | 
						return name;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public String getContent () {
 | 
				
			||||||
 | 
						return content;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public String getFunctionName () {
 | 
				
			||||||
 | 
						return functionName;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public Prototype getPrototype () {
 | 
				
			||||||
 | 
						return prototype;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public Application getApplication () {
 | 
				
			||||||
 | 
						return app;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public String toString () {
 | 
				
			||||||
 | 
						return "ActionFile["+prototype.getName()+"/"+functionName+"]";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,13 +11,10 @@ import java.io.*;
 | 
				
			||||||
import helma.framework.*;
 | 
					import helma.framework.*;
 | 
				
			||||||
import helma.framework.core.*;
 | 
					import helma.framework.core.*;
 | 
				
			||||||
import helma.util.Updatable;
 | 
					import helma.util.Updatable;
 | 
				
			||||||
import FESI.Data.*;
 | 
					 | 
				
			||||||
import FESI.Exceptions.EcmaScriptException;
 | 
					 | 
				
			||||||
import FESI.Interpreter.*;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * This represents a File containing JavaScript functions for a given Object. 
 | 
					 * This represents a File containing script functions for a given class/prototype.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -44,8 +41,8 @@ public class FunctionFile implements Updatable {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Create a function file without a file, passing the code directly. This is used for
 | 
					     *  Create a function file without a file, passing the code directly. This is used for
 | 
				
			||||||
     * files contained in zipped applications. The whole update mechanism is bypassed
 | 
					     *  files contained in zipped applications. The whole update mechanism is bypassed
 | 
				
			||||||
     *  by immediately parsing the code.
 | 
					     *  by immediately parsing the code.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public FunctionFile (String body, String name, Prototype proto) {
 | 
					    public FunctionFile (String body, String name, Prototype proto) {
 | 
				
			||||||
| 
						 | 
					@ -54,20 +51,7 @@ public class FunctionFile implements Updatable {
 | 
				
			||||||
	this.name = name;
 | 
						this.name = name;
 | 
				
			||||||
	this.file = null;
 | 
						this.file = null;
 | 
				
			||||||
	this.content = body;
 | 
						this.content = body;
 | 
				
			||||||
 | 
						update ();
 | 
				
			||||||
	Iterator evals = app.typemgr.getRegisteredRequestEvaluators ();
 | 
					 | 
				
			||||||
	while (evals.hasNext ()) {
 | 
					 | 
				
			||||||
	    try {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	        StringEvaluationSource es = new StringEvaluationSource (body, null);
 | 
					 | 
				
			||||||
	        StringReader reader = new StringReader (body);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	        RequestEvaluator reval = (RequestEvaluator) evals.next ();
 | 
					 | 
				
			||||||
	        updateRequestEvaluator (reval, reader, es);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	    } catch (Exception ignore) {}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
| 
						 | 
					@ -75,108 +59,41 @@ public class FunctionFile implements Updatable {
 | 
				
			||||||
     * the file has been modified or deleted.
 | 
					     * the file has been modified or deleted.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public boolean needsUpdate () {
 | 
					    public boolean needsUpdate () {
 | 
				
			||||||
	return lastmod != file.lastModified ();
 | 
						return file != null && lastmod != file.lastModified ();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public void update () {
 | 
					    public void update () {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!file.exists ()) {
 | 
					 | 
				
			||||||
	    remove ();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	    lastmod = file.lastModified ();
 | 
					 | 
				
			||||||
	    // app.typemgr.readFunctionFile (file, prototype.getName ());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	    Iterator evals = app.typemgr.getRegisteredRequestEvaluators ();
 | 
					 | 
				
			||||||
	    while (evals.hasNext ()) {
 | 
					 | 
				
			||||||
	        try {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	            RequestEvaluator reval = (RequestEvaluator) evals.next ();
 | 
					 | 
				
			||||||
	            FileReader fr = new FileReader(file);
 | 
					 | 
				
			||||||
	            EvaluationSource es = new FileEvaluationSource(file.getPath(), null);
 | 
					 | 
				
			||||||
	            updateRequestEvaluator (reval, fr, es);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	        } catch (Throwable ignore) {}
 | 
					 | 
				
			||||||
	    }
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public  synchronized void updateRequestEvaluator (RequestEvaluator reval) {
 | 
					 | 
				
			||||||
	if (file != null) {
 | 
						if (file != null) {
 | 
				
			||||||
	    try {
 | 
						    if (!file.exists ()) {
 | 
				
			||||||
	        FileReader fr = new FileReader (file);
 | 
						        remove ();
 | 
				
			||||||
	        EvaluationSource es = new FileEvaluationSource (file.getPath (), null);
 | 
						    } else {
 | 
				
			||||||
	        updateRequestEvaluator (reval, fr, es);
 | 
						        lastmod = file.lastModified ();
 | 
				
			||||||
	    } catch (IOException iox) {
 | 
						        // app.typemgr.readFunctionFile (file, prototype.getName ());
 | 
				
			||||||
	        app.logEvent ("Error updating function file: "+iox);
 | 
						        // app.getScriptingEnvironment().evaluateFile (prototype, file);
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
	    StringReader reader = new StringReader (content);
 | 
						    // app.getScriptingEnvironment().evaluateString (prototype, content);
 | 
				
			||||||
	    StringEvaluationSource es = new StringEvaluationSource (content, null);
 | 
					 | 
				
			||||||
	    updateRequestEvaluator (reval, reader, es);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public  synchronized void updateRequestEvaluator (RequestEvaluator reval, Reader reader, EvaluationSource source) {
 | 
					    /* public void evaluate (ScriptingEnvironment env) {
 | 
				
			||||||
 | 
						if (file != null)
 | 
				
			||||||
 | 
						    env.evaluateFile (prototype, file);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						    env.evaluateString (prototype, content);
 | 
				
			||||||
 | 
					    }*/
 | 
				
			||||||
 | 
					    public boolean hasFile () {
 | 
				
			||||||
 | 
						return file != null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        HashMap priorProps = null;
 | 
					    public File getFile () {
 | 
				
			||||||
        HashSet newProps = null;
 | 
						return file;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        try {
 | 
					    public String getContent () {
 | 
				
			||||||
 | 
						return content;
 | 
				
			||||||
            ObjectPrototype op = reval.getPrototype (prototype.getName());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // extract all properties from prototype _before_ evaluation, so we can compare afterwards
 | 
					 | 
				
			||||||
            // but only do this is declaredProps is not up to date yet
 | 
					 | 
				
			||||||
            if (declaredPropsTimestamp != lastmod) {
 | 
					 | 
				
			||||||
                priorProps = new HashMap ();
 | 
					 | 
				
			||||||
                // remember properties before evaluation, so we can tell what's new afterwards
 | 
					 | 
				
			||||||
                try {
 | 
					 | 
				
			||||||
                    for (Enumeration en=op.getAllProperties(); en.hasMoreElements(); ) {
 | 
					 | 
				
			||||||
                        String prop = (String) en.nextElement ();
 | 
					 | 
				
			||||||
                        priorProps.put (prop, op.getProperty (prop, prop.hashCode()));
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                } catch (Exception ignore) {}
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // do the update, evaluating the file
 | 
					 | 
				
			||||||
            reval.evaluator.evaluate(reader, op, source, false);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // check what's new
 | 
					 | 
				
			||||||
            if (declaredPropsTimestamp != lastmod) try {
 | 
					 | 
				
			||||||
                newProps = new HashSet ();
 | 
					 | 
				
			||||||
                for (Enumeration en=op.getAllProperties(); en.hasMoreElements(); ) {
 | 
					 | 
				
			||||||
                    String prop = (String) en.nextElement ();
 | 
					 | 
				
			||||||
                    if (priorProps.get (prop) == null || op.getProperty (prop, prop.hashCode()) != priorProps.get (prop))
 | 
					 | 
				
			||||||
                        newProps.add (prop);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            } catch (Exception ignore) {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        } catch (Throwable e) {
 | 
					 | 
				
			||||||
            app.logEvent ("Error parsing function file "+source+": "+e);
 | 
					 | 
				
			||||||
        } finally {
 | 
					 | 
				
			||||||
            if (reader != null) {
 | 
					 | 
				
			||||||
                try {
 | 
					 | 
				
			||||||
                    reader.close();
 | 
					 | 
				
			||||||
                } catch (IOException ignore) {}
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // now remove the props that were not refreshed, and set declared props to new collection
 | 
					 | 
				
			||||||
            if (declaredPropsTimestamp != lastmod) {
 | 
					 | 
				
			||||||
                declaredPropsTimestamp = lastmod;
 | 
					 | 
				
			||||||
                if (declaredProps != null) {
 | 
					 | 
				
			||||||
                    declaredProps.removeAll (newProps);
 | 
					 | 
				
			||||||
                    removeProperties (declaredProps);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                declaredProps = newProps;
 | 
					 | 
				
			||||||
                // System.err.println ("DECLAREDPROPS = "+declaredProps);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -185,10 +102,10 @@ public class FunctionFile implements Updatable {
 | 
				
			||||||
	prototype.updatables.remove (file.getName());
 | 
						prototype.updatables.remove (file.getName());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// if we did not add anything to any evaluator, we're done
 | 
						// if we did not add anything to any evaluator, we're done
 | 
				
			||||||
	if (declaredProps == null || declaredProps.size() == 0)
 | 
						/* if (declaredProps == null || declaredProps.size() == 0)
 | 
				
			||||||
	    return;
 | 
						    return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	removeProperties (declaredProps);
 | 
						removeProperties (declaredProps); */
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
| 
						 | 
					@ -199,7 +116,7 @@ public class FunctionFile implements Updatable {
 | 
				
			||||||
    void removeProperties (HashSet props) {
 | 
					    void removeProperties (HashSet props) {
 | 
				
			||||||
	// first loop through other function files in this prototype to make a set of properties
 | 
						// first loop through other function files in this prototype to make a set of properties
 | 
				
			||||||
	// owned by other files.
 | 
						// owned by other files.
 | 
				
			||||||
	HashSet otherFiles = new HashSet ();
 | 
					/*	HashSet otherFiles = new HashSet ();
 | 
				
			||||||
	for (Iterator it=prototype.functions.values ().iterator (); it.hasNext (); ) {
 | 
						for (Iterator it=prototype.functions.values ().iterator (); it.hasNext (); ) {
 | 
				
			||||||
	    FunctionFile other = (FunctionFile) it.next ();
 | 
						    FunctionFile other = (FunctionFile) it.next ();
 | 
				
			||||||
	    if (other != this && other.declaredProps != null)
 | 
						    if (other != this && other.declaredProps != null)
 | 
				
			||||||
| 
						 | 
					@ -220,7 +137,7 @@ public class FunctionFile implements Updatable {
 | 
				
			||||||
	            // System.err.println ("REMOVING PROP: "+fname);
 | 
						            // System.err.println ("REMOVING PROP: "+fname);
 | 
				
			||||||
	        }
 | 
						        }
 | 
				
			||||||
	    } catch (Exception ignore) {}
 | 
						    } catch (Exception ignore) {}
 | 
				
			||||||
	}
 | 
						} */
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public String toString () {
 | 
					    public String toString () {
 | 
				
			||||||
| 
						 | 
					@ -234,40 +151,3 @@ public class FunctionFile implements Updatable {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,11 +1,13 @@
 | 
				
			||||||
// ScriptingEnvironment.java
 | 
					// ScriptingEnvironment.java
 | 
				
			||||||
// Copyright (c) Hannes Wallnöfer 1998-2001
 | 
					// Copyright (c) Hannes Wallnöfer 1998-2001
 | 
				
			||||||
 
 | 
					
 | 
				
			||||||
package helma.scripting;
 | 
					package helma.scripting;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import helma.framework.core.Application;
 | 
				
			||||||
 | 
					import helma.framework.core.Prototype;
 | 
				
			||||||
 | 
					import helma.framework.core.RequestEvaluator;
 | 
				
			||||||
import java.util.*;
 | 
					import java.util.*;
 | 
				
			||||||
 | 
					import java.io.File;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * This is the interface that must be implemented to make a scripting environment
 | 
					 * This is the interface that must be implemented to make a scripting environment
 | 
				
			||||||
| 
						 | 
					@ -16,14 +18,30 @@ public interface ScriptingEnvironment {
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Initialize the environment using the given properties
 | 
					     * Initialize the environment using the given properties
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public void init (Properties props) throws ScriptingException;
 | 
					    public void init (Application app, Properties props) throws ScriptingException;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * A prototype has been updated and must be re-evaluated.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public void updatePrototype (Prototype prototype);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Invoke a function on some object, using the given arguments and global vars.
 | 
					     * Invoke a function on some object, using the given arguments and global vars.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public Object invoke (Object thisObject, Object[] args, HashMap globals) throws ScriptingException;
 | 
					    public Object invoke (Object thisObject, String functionName, Object[] args,
 | 
				
			||||||
 | 
							HashMap globals, RequestEvaluator reval)
 | 
				
			||||||
 | 
							throws ScriptingException;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     *  Get a property on an object
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public Object get (Object thisObject, String key, RequestEvaluator reval);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     *  Return true if a function by that name is defined for that object.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public boolean hasFunction (Object thisObject, String functionName, RequestEvaluator reval)
 | 
				
			||||||
 | 
							throws ScriptingException;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -51,9 +69,6 @@ public interface ScriptingEnvironment {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,14 +9,14 @@ import java.util.Iterator;
 | 
				
			||||||
import java.util.StringTokenizer;
 | 
					import java.util.StringTokenizer;
 | 
				
			||||||
import helma.framework.*;
 | 
					import helma.framework.*;
 | 
				
			||||||
import helma.framework.core.*;
 | 
					import helma.framework.core.*;
 | 
				
			||||||
import FESI.Data.*;
 | 
					// import FESI.Data.*;
 | 
				
			||||||
import FESI.Exceptions.*;
 | 
					// import FESI.Exceptions.*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * This represents a Helma template, i.e. a file with the extension .hsp
 | 
					 * This represents a Helma template, i.e. a file with the extension .hsp
 | 
				
			||||||
 * (Helma server page) that contains both parts that are to be evaluated
 | 
					 * (Helma server page) that contains both parts that are to be evaluated
 | 
				
			||||||
 * as EcmaScript and parts that are to be delivered to the client as-is. 
 | 
					 * as EcmaScript and parts that are to be delivered to the client as-is.
 | 
				
			||||||
 * Internally, templates are regular functions. 
 | 
					 * Internally, templates are regular functions. 
 | 
				
			||||||
 * Helma templates are callable via URL, but this is just a leftover from the
 | 
					 * Helma templates are callable via URL, but this is just a leftover from the
 | 
				
			||||||
 * days when there were no .hac (action) files. The recommended way
 | 
					 * days when there were no .hac (action) files. The recommended way
 | 
				
			||||||
| 
						 | 
					@ -24,18 +24,24 @@ import FESI.Exceptions.*;
 | 
				
			||||||
 * template files to do the formatting.
 | 
					 * template files to do the formatting.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class Template extends Action {
 | 
					public class Template extends ActionFile {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // this is the *_as_string function, which is in addition to the normal one
 | 
					    // this is the *_as_string function, which is in addition to the normal one
 | 
				
			||||||
    TypeUpdater psfunc;
 | 
					    // TypeUpdater psfunc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public Template (File file, String name, Prototype proto) {
 | 
					    public Template (File file, String name, Prototype proto) {
 | 
				
			||||||
	super (file, name, proto);
 | 
						super (file, name, proto);
 | 
				
			||||||
 | 
						functionName = name;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public Template (String content, String name, Prototype proto) {
 | 
				
			||||||
 | 
						super (content, name, proto);
 | 
				
			||||||
 | 
						functionName = name;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public void update (String content) throws Exception {
 | 
					    public String getContent () {
 | 
				
			||||||
	// IServer.getLogger().log ("Reading text template " + name);
 | 
						// IServer.getLogger().log ("Reading text template " + name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Vector partBuffer = new Vector ();
 | 
						Vector partBuffer = new Vector ();
 | 
				
			||||||
| 
						 | 
					@ -99,7 +105,7 @@ public class Template extends Action {
 | 
				
			||||||
	                // append a CRLF
 | 
						                // append a CRLF
 | 
				
			||||||
	                newLineCount++;
 | 
						                newLineCount++;
 | 
				
			||||||
	                templateBody.append ("\\r\\n");
 | 
						                templateBody.append ("\\r\\n");
 | 
				
			||||||
	            } else if (!"\r".equals (nextLine)){
 | 
						            } else if (!"\r".equals (nextLine)) try {
 | 
				
			||||||
	                StringReader lineReader = new StringReader (nextLine);
 | 
						                StringReader lineReader = new StringReader (nextLine);
 | 
				
			||||||
	                int c = lineReader.read ();
 | 
						                int c = lineReader.read ();
 | 
				
			||||||
	                while (c > -1) {
 | 
						                while (c > -1) {
 | 
				
			||||||
| 
						 | 
					@ -109,7 +115,7 @@ public class Template extends Action {
 | 
				
			||||||
	                    templateBody.append ((char) c);
 | 
						                    templateBody.append ((char) c);
 | 
				
			||||||
	                    c = lineReader.read ();
 | 
						                    c = lineReader.read ();
 | 
				
			||||||
	                }
 | 
						                }
 | 
				
			||||||
	            }
 | 
						            } catch (IOException srx) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	            nextLine = st.hasMoreTokens () ? st.nextToken () : null;
 | 
						            nextLine = st.hasMoreTokens () ? st.nextToken () : null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -124,7 +130,7 @@ public class Template extends Action {
 | 
				
			||||||
	        // append the number of lines we have "swallowed" into
 | 
						        // append the number of lines we have "swallowed" into
 | 
				
			||||||
	        // one write statement, so error messages will *approximately*
 | 
						        // one write statement, so error messages will *approximately*
 | 
				
			||||||
	        // give correct line numbers.
 | 
						        // give correct line numbers.
 | 
				
			||||||
	        for (int i=0; i<newLineCount; i++) {							
 | 
						        for (int i=0; i<newLineCount; i++) {
 | 
				
			||||||
	                templateBody.append ("\r\n");
 | 
						                templateBody.append ("\r\n");
 | 
				
			||||||
	        }
 | 
						        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -137,7 +143,9 @@ public class Template extends Action {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// templateBody.append ("\r\nreturn null;\r\n");
 | 
						// templateBody.append ("\r\nreturn null;\r\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
             functionName = name;
 | 
						return templateBody.toString ();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
	String fname = name+"_as_string";
 | 
						String fname = name+"_as_string";
 | 
				
			||||||
	String body = templateBody.toString ();
 | 
						String body = templateBody.toString ();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -164,14 +172,15 @@ public class Template extends Action {
 | 
				
			||||||
	        RequestEvaluator reval = (RequestEvaluator) evals.next ();
 | 
						        RequestEvaluator reval = (RequestEvaluator) evals.next ();
 | 
				
			||||||
	        updateRequestEvaluator (reval);
 | 
						        updateRequestEvaluator (reval);
 | 
				
			||||||
	    } catch (Exception ignore) {}
 | 
						    } catch (Exception ignore) {}
 | 
				
			||||||
	}
 | 
						} */
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void remove () {
 | 
					    protected void remove () {
 | 
				
			||||||
	prototype.templates.remove (name);
 | 
						prototype.templates.remove (name);
 | 
				
			||||||
	prototype.updatables.remove (file.getName());
 | 
						if (file != null)
 | 
				
			||||||
 | 
						    prototype.updatables.remove (file.getName());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Iterator evals = app.typemgr.getRegisteredRequestEvaluators ();
 | 
						/* Iterator evals = app.typemgr.getRegisteredRequestEvaluators ();
 | 
				
			||||||
	while (evals.hasNext ()) {
 | 
						while (evals.hasNext ()) {
 | 
				
			||||||
	    try {
 | 
						    try {
 | 
				
			||||||
	        RequestEvaluator reval = (RequestEvaluator) evals.next ();
 | 
						        RequestEvaluator reval = (RequestEvaluator) evals.next ();
 | 
				
			||||||
| 
						 | 
					@ -187,16 +196,16 @@ public class Template extends Action {
 | 
				
			||||||
	            op.deleteProperty (fname, fname.hashCode());
 | 
						            op.deleteProperty (fname, fname.hashCode());
 | 
				
			||||||
	        }
 | 
						        }
 | 
				
			||||||
	    } catch (Exception ignore) {}
 | 
						    } catch (Exception ignore) {}
 | 
				
			||||||
	}
 | 
						} */
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public synchronized void updateRequestEvaluator (RequestEvaluator reval) throws EcmaScriptException {
 | 
					    /* public synchronized void updateRequestEvaluator (RequestEvaluator reval) throws EcmaScriptException {
 | 
				
			||||||
        if (pfunc != null)
 | 
					        if (pfunc != null)
 | 
				
			||||||
            pfunc.updateRequestEvaluator (reval);
 | 
					            pfunc.updateRequestEvaluator (reval);
 | 
				
			||||||
        if (psfunc != null)
 | 
					        if (psfunc != null)
 | 
				
			||||||
            psfunc.updateRequestEvaluator (reval);
 | 
					            psfunc.updateRequestEvaluator (reval);
 | 
				
			||||||
    }
 | 
					    } */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class Part {
 | 
					    class Part {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -224,34 +233,9 @@ public class Template extends Action {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,11 +20,11 @@ public class ESAppNode extends ESNode {
 | 
				
			||||||
    private Application app;
 | 
					    private Application app;
 | 
				
			||||||
    private DatePrototype createtime;
 | 
					    private DatePrototype createtime;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public ESAppNode (INode node, RequestEvaluator eval) throws EcmaScriptException {
 | 
					    public ESAppNode (INode node, FesiEvaluator eval) throws EcmaScriptException {
 | 
				
			||||||
	super (eval.esNodePrototype, eval.evaluator, node, eval);
 | 
						super (eval.getPrototype("hopobject"), eval.getEvaluator(), node, eval);
 | 
				
			||||||
	app = eval.app;
 | 
						app = eval.getApplication();
 | 
				
			||||||
	createtime = new DatePrototype (eval.evaluator, node.created());
 | 
						createtime = new DatePrototype (evaluator, node.created());
 | 
				
			||||||
	FunctionPrototype fp = (FunctionPrototype) eval.evaluator.getFunctionPrototype();
 | 
						FunctionPrototype fp = (FunctionPrototype) evaluator.getFunctionPrototype();
 | 
				
			||||||
	putHiddenProperty("getThreads", new AppCountThreads ("getThreads", evaluator, fp));
 | 
						putHiddenProperty("getThreads", new AppCountThreads ("getThreads", evaluator, fp));
 | 
				
			||||||
	putHiddenProperty("getMaxThreads", new AppCountEvaluators ("getMaxThreads", evaluator, fp));
 | 
						putHiddenProperty("getMaxThreads", new AppCountEvaluators ("getMaxThreads", evaluator, fp));
 | 
				
			||||||
	putHiddenProperty("getFreeThreads", new AppCountFreeEvaluators ("getFreeThreads", evaluator, fp));
 | 
						putHiddenProperty("getFreeThreads", new AppCountFreeEvaluators ("getFreeThreads", evaluator, fp));
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -107,54 +107,3 @@ public class ESGenericObject extends ObjectPrototype {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,16 +20,16 @@ import java.util.*;
 | 
				
			||||||
public class ESMapWrapper extends ESWrapper {
 | 
					public class ESMapWrapper extends ESWrapper {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private Map data;
 | 
					    private Map data;
 | 
				
			||||||
    private RequestEvaluator reval;
 | 
					    private FesiEvaluator fesi;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public ESMapWrapper (RequestEvaluator reval) {
 | 
					    public ESMapWrapper (FesiEvaluator fesi) {
 | 
				
			||||||
	super (new Object(), reval.evaluator);
 | 
						super (new Object(), fesi.getEvaluator ());
 | 
				
			||||||
	this.reval = reval;
 | 
						this.fesi = fesi;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public ESMapWrapper (RequestEvaluator reval, Map data) {
 | 
					    public ESMapWrapper (FesiEvaluator fesi, Map data) {
 | 
				
			||||||
	super (new Object(), reval.evaluator);
 | 
						super (new Object(), fesi.getEvaluator ());
 | 
				
			||||||
	this.reval = reval;
 | 
						this.fesi = fesi;
 | 
				
			||||||
	this.data = data;
 | 
						this.data = data;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -63,7 +63,7 @@ public class ESMapWrapper extends ESWrapper {
 | 
				
			||||||
	if (val instanceof  String)
 | 
						if (val instanceof  String)
 | 
				
			||||||
	    return new ESString ((String) val);
 | 
						    return new ESString ((String) val);
 | 
				
			||||||
	else if (val instanceof INode)
 | 
						else if (val instanceof INode)
 | 
				
			||||||
	    return reval.getNodeWrapper ((INode) val);
 | 
						    return fesi.getNodeWrapper ((INode) val);
 | 
				
			||||||
	else if (val instanceof ESValue)
 | 
						else if (val instanceof ESValue)
 | 
				
			||||||
	    return (ESValue) val;
 | 
						    return (ESValue) val;
 | 
				
			||||||
	return ESLoader.normalizeValue(val, evaluator);
 | 
						return ESLoader.normalizeValue(val, evaluator);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,23 +35,23 @@ public class ESNode extends ObjectPrototype {
 | 
				
			||||||
    NodeHandle handle;
 | 
					    NodeHandle handle;
 | 
				
			||||||
    DbMapping dbmap;
 | 
					    DbMapping dbmap;
 | 
				
			||||||
    Throwable lastError = null;
 | 
					    Throwable lastError = null;
 | 
				
			||||||
    RequestEvaluator eval;
 | 
					    FesiEvaluator eval;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Constructor used to create transient cache nodes
 | 
					     * Constructor used to create transient cache nodes
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public ESNode (INode node, RequestEvaluator eval) {
 | 
					    public ESNode (INode node, FesiEvaluator eval) {
 | 
				
			||||||
	super (eval.esNodePrototype, eval.evaluator);
 | 
						super (eval.getPrototype("hopobject"), eval.getEvaluator());
 | 
				
			||||||
	this.eval = eval;
 | 
						this.eval = eval;
 | 
				
			||||||
	this.node = node;
 | 
						this.node = node;
 | 
				
			||||||
	cache = null;
 | 
						cache = null;
 | 
				
			||||||
	cacheWrapper = null;
 | 
						cacheWrapper = null;
 | 
				
			||||||
	
 | 
					
 | 
				
			||||||
	// this is a transient node, set node handle to null
 | 
						// this is a transient node, set node handle to null
 | 
				
			||||||
	handle = null;
 | 
						handle = null;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    public ESNode (ESObject prototype, Evaluator evaluator, Object obj, RequestEvaluator eval) {
 | 
					    public ESNode (ESObject prototype, Evaluator evaluator, Object obj, FesiEvaluator eval) {
 | 
				
			||||||
	super (prototype, evaluator);
 | 
						super (prototype, evaluator);
 | 
				
			||||||
	// eval.app.logEvent ("in ESNode constructor: "+o.getClass ());
 | 
						// eval.app.logEvent ("in ESNode constructor: "+o.getClass ());
 | 
				
			||||||
	this.eval = eval;
 | 
						this.eval = eval;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,8 +27,8 @@ public class ESUser extends ESNode {
 | 
				
			||||||
    /** if the user is online, this is his/her online session object */
 | 
					    /** if the user is online, this is his/her online session object */
 | 
				
			||||||
    public User user;
 | 
					    public User user;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public ESUser (INode node, RequestEvaluator eval, User user) {
 | 
					    public ESUser (INode node, FesiEvaluator eval, User user) {
 | 
				
			||||||
	super (eval.esUserPrototype, eval.evaluator, node, eval);
 | 
						super (eval.getPrototype("user"), eval.getEvaluator(), node, eval);
 | 
				
			||||||
	this.user = user;
 | 
						this.user = user;
 | 
				
			||||||
	if (user != null) {
 | 
						if (user != null) {
 | 
				
			||||||
	    cache = user.getCache ();
 | 
						    cache = user.getCache ();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,8 +1,9 @@
 | 
				
			||||||
// Action.java
 | 
					// ActionFile.java
 | 
				
			||||||
// Copyright (c) Hannes Wallnöfer 1998-2000
 | 
					// Copyright (c) Hannes Wallnöfer 1998-2000
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
package helma.scripting;
 | 
					package helma.scripting.fesi;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import helma.scripting.*;
 | 
				
			||||||
import java.util.Vector;
 | 
					import java.util.Vector;
 | 
				
			||||||
import java.util.Iterator;
 | 
					import java.util.Iterator;
 | 
				
			||||||
import java.io.*;
 | 
					import java.io.*;
 | 
				
			||||||
| 
						 | 
					@ -20,90 +21,46 @@ import FESI.Exceptions.*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * An Action is a JavaScript function that is exposed as a URI. It is 
 | 
					 *  An class that updates fesi interpreters with actionfiles and templates.
 | 
				
			||||||
 * usually represented by a file with extension .hac (hop action file)
 | 
					 | 
				
			||||||
 * that contains the pure JavaScript body of the function. 
 | 
					 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class Action implements Updatable {
 | 
					public class FesiActionAdapter {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    String name;
 | 
					 | 
				
			||||||
    String functionName;
 | 
					 | 
				
			||||||
    Prototype prototype;
 | 
					    Prototype prototype;
 | 
				
			||||||
    Application app;
 | 
					    Application app;
 | 
				
			||||||
    File file;
 | 
					    String sourceName;
 | 
				
			||||||
    long lastmod;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // this is the parsed function which can be easily applied to RequestEvaluator objects
 | 
					    // this is the parsed function which can be easily applied to RequestEvaluator objects
 | 
				
			||||||
    TypeUpdater pfunc;
 | 
					    TypeUpdater pfunc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public FesiActionAdapter (ActionFile action) {
 | 
				
			||||||
    public Action (File file, String name, Prototype proto) {
 | 
						prototype = action.getPrototype ();
 | 
				
			||||||
	this.prototype = proto;
 | 
						app = action.getApplication ();
 | 
				
			||||||
	this.app = proto.getApplication ();
 | 
						String content = action.getContent ();
 | 
				
			||||||
	this.name = name;
 | 
						String functionName = action.getFunctionName ();
 | 
				
			||||||
	this.file = file;
 | 
						sourceName = action.toString ();
 | 
				
			||||||
	if (file != null)
 | 
						try {
 | 
				
			||||||
	    update ();
 | 
						    pfunc = parseFunction (functionName, "arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10", content);
 | 
				
			||||||
    }
 | 
						} catch (Throwable x) {
 | 
				
			||||||
 | 
						    String message = x.getMessage ();
 | 
				
			||||||
    /**
 | 
						    pfunc =  new ErrorFeedback (functionName, message);
 | 
				
			||||||
     * Tell the type manager whether we need an update. this is the case when
 | 
					 | 
				
			||||||
     * the file has been modified or deleted.
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public boolean needsUpdate () {
 | 
					 | 
				
			||||||
	return lastmod != file.lastModified ();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public void update () {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!file.exists ()) {
 | 
					 | 
				
			||||||
	    // remove functions declared by this from all object prototypes
 | 
					 | 
				
			||||||
	    remove ();
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
	    try {
 | 
					 | 
				
			||||||
	        FileReader reader = new FileReader (file);
 | 
					 | 
				
			||||||
	        char cbuf[] = new char[(int) file.length ()];
 | 
					 | 
				
			||||||
	        reader.read (cbuf);
 | 
					 | 
				
			||||||
	        reader.close ();
 | 
					 | 
				
			||||||
	        String content = new String (cbuf);
 | 
					 | 
				
			||||||
	        update (content);
 | 
					 | 
				
			||||||
	    } catch (Exception filex) {
 | 
					 | 
				
			||||||
	        app.logEvent ("*** Error reading action file "+file+": "+filex);
 | 
					 | 
				
			||||||
	    }
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	    lastmod = file.lastModified ();
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* protected void update (FesiEvaluator fesi) throws Exception {
 | 
				
			||||||
    public void update (String content) throws Exception {
 | 
					 | 
				
			||||||
	// app.logEvent ("Reading text template " + name);
 | 
						// app.logEvent ("Reading text template " + name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	functionName = name+"_action";
 | 
						FesiScriptingEnvironment scriptEnv = (FesiScriptingEnvironment) app.getScriptingEnvironment ();
 | 
				
			||||||
 | 
						Iterator evals = scriptEnv.getEvaluators().iterator();
 | 
				
			||||||
             try {
 | 
					 | 
				
			||||||
	    pfunc = parseFunction (functionName, "arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10", content);
 | 
					 | 
				
			||||||
             } catch (Throwable x) {
 | 
					 | 
				
			||||||
                 String message = x.getMessage ();
 | 
					 | 
				
			||||||
                 pfunc =  new ErrorFeedback (functionName, message);
 | 
					 | 
				
			||||||
             }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Iterator evals = app.typemgr.getRegisteredRequestEvaluators ();
 | 
					 | 
				
			||||||
	while (evals.hasNext ()) {
 | 
						while (evals.hasNext ()) {
 | 
				
			||||||
	    try {
 | 
						    try {
 | 
				
			||||||
	        RequestEvaluator reval = (RequestEvaluator) evals.next ();
 | 
						        FesiEvaluator fesi = (FesiEvaluator) evals.next ();
 | 
				
			||||||
	        updateRequestEvaluator (reval);
 | 
						        updateEvaluator (fesi);
 | 
				
			||||||
	    } catch (Exception ignore) {}
 | 
						    } catch (Exception ignore) {}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
    }
 | 
					    } */
 | 
				
			||||||
 | 
					 | 
				
			||||||
    void remove () {
 | 
					 | 
				
			||||||
	prototype.actions.remove (name);
 | 
					 | 
				
			||||||
	prototype.updatables.remove (file.getName());
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   /* protected void remove () {
 | 
				
			||||||
	Iterator evals = app.typemgr.getRegisteredRequestEvaluators ();
 | 
						Iterator evals = app.typemgr.getRegisteredRequestEvaluators ();
 | 
				
			||||||
	while (evals.hasNext ()) {
 | 
						while (evals.hasNext ()) {
 | 
				
			||||||
	    try {
 | 
						    try {
 | 
				
			||||||
| 
						 | 
					@ -116,23 +73,12 @@ public class Action implements Updatable {
 | 
				
			||||||
	        }
 | 
						        }
 | 
				
			||||||
	    } catch (Exception ignore) {}
 | 
						    } catch (Exception ignore) {}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
    }
 | 
					    } */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public String getName () {
 | 
					 | 
				
			||||||
	return name;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public String getFunctionName () {
 | 
					    public synchronized void updateEvaluator (FesiEvaluator fesi) throws EcmaScriptException {
 | 
				
			||||||
	return functionName;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public String toString () {
 | 
					 | 
				
			||||||
	return prototype.getName()+"/"+file.getName();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public synchronized void updateRequestEvaluator (RequestEvaluator reval) throws EcmaScriptException {
 | 
					 | 
				
			||||||
        if (pfunc != null)
 | 
					        if (pfunc != null)
 | 
				
			||||||
            pfunc.updateRequestEvaluator (reval);
 | 
					            pfunc.updateEvaluator (fesi);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected TypeUpdater parseFunction (String funcname, String params, String body) throws EcmaScriptException {
 | 
					    protected TypeUpdater parseFunction (String funcname, String params, String body) throws EcmaScriptException {
 | 
				
			||||||
| 
						 | 
					@ -176,10 +122,10 @@ public class Action implements Updatable {
 | 
				
			||||||
            sl = (ASTStatementList) parser.StatementList();
 | 
					            sl = (ASTStatementList) parser.StatementList();
 | 
				
			||||||
            is.close();
 | 
					            is.close();
 | 
				
			||||||
        } catch (ParseException x) {
 | 
					        } catch (ParseException x) {
 | 
				
			||||||
            app.logEvent ("Error parsing file "+app.getName()+":"+prototype.getName()+"/"+file.getName()+": "+x);
 | 
					            app.logEvent ("Error parsing file "+app.getName()+":"+sourceName+": "+x);
 | 
				
			||||||
            throw new EcmaScriptParseException (x, new StringEvaluationSource(fulltext, null));
 | 
					            throw new EcmaScriptParseException (x, new StringEvaluationSource(fulltext, null));
 | 
				
			||||||
        } catch (Exception x) {
 | 
					        } catch (Exception x) {
 | 
				
			||||||
            app.logEvent ("Error parsing file "+app.getName()+":"+prototype.getName()+"/"+file.getName()+": "+x);
 | 
					            app.logEvent ("Error parsing file "+app.getName()+":"+sourceName+": "+x);
 | 
				
			||||||
            throw new RuntimeException (x.getMessage ());
 | 
					            throw new RuntimeException (x.getMessage ());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -204,15 +150,15 @@ public class Action implements Updatable {
 | 
				
			||||||
	this.functionName = functionName;
 | 
						this.functionName = functionName;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public void updateRequestEvaluator (RequestEvaluator reval) throws EcmaScriptException {
 | 
					        public void updateEvaluator (FesiEvaluator fesi) throws EcmaScriptException {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ObjectPrototype op = reval.getPrototype (prototype.getName());
 | 
						ObjectPrototype op = fesi.getPrototype (prototype.getName());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	EcmaScriptVariableVisitor vdvisitor = reval.evaluator.getVarDeclarationVisitor();
 | 
						EcmaScriptVariableVisitor vdvisitor = fesi.evaluator.getVarDeclarationVisitor();
 | 
				
			||||||
	Vector vnames = vdvisitor.processVariableDeclarations(sl, fes);
 | 
						Vector vnames = vdvisitor.processVariableDeclarations(sl, fes);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	FunctionPrototype fp = ConstructedFunctionObject.makeNewConstructedFunction (
 | 
						FunctionPrototype fp = ConstructedFunctionObject.makeNewConstructedFunction (
 | 
				
			||||||
		reval.evaluator, functionName, fes,
 | 
							fesi.evaluator, functionName, fes,
 | 
				
			||||||
		fullFunctionText, fpl.getArguments(), vnames, sl);
 | 
							fullFunctionText, fpl.getArguments(), vnames, sl);
 | 
				
			||||||
	op.putHiddenProperty (functionName, fp);
 | 
						op.putHiddenProperty (functionName, fp);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -228,12 +174,12 @@ public class Action implements Updatable {
 | 
				
			||||||
            errorMessage = msg;
 | 
					            errorMessage = msg;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public void updateRequestEvaluator (RequestEvaluator reval) throws EcmaScriptException {
 | 
					        public void updateEvaluator (FesiEvaluator fesi) throws EcmaScriptException {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            ObjectPrototype op = reval.getPrototype (prototype.getName ());
 | 
					            ObjectPrototype op = fesi.getPrototype (prototype.getName ());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            FunctionPrototype fp = (FunctionPrototype) reval.evaluator.getFunctionPrototype ();
 | 
					            FunctionPrototype fp = (FunctionPrototype) fesi.evaluator.getFunctionPrototype ();
 | 
				
			||||||
            FunctionPrototype func = new ThrowException (functionName, reval.evaluator, fp, errorMessage);
 | 
					            FunctionPrototype func = new ThrowException (functionName, fesi.evaluator, fp, errorMessage);
 | 
				
			||||||
            op.putHiddenProperty (functionName, func);
 | 
					            op.putHiddenProperty (functionName, func);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -254,38 +200,8 @@ public class Action implements Updatable {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    interface TypeUpdater {
 | 
					    interface TypeUpdater {
 | 
				
			||||||
        public void updateRequestEvaluator (RequestEvaluator reval) throws EcmaScriptException;
 | 
					        public void updateEvaluator (FesiEvaluator fesi) throws EcmaScriptException;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
							
								
								
									
										584
									
								
								src/helma/scripting/fesi/FesiEvaluator.java
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										584
									
								
								src/helma/scripting/fesi/FesiEvaluator.java
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,584 @@
 | 
				
			||||||
 | 
					// FesiScriptingEnvironment.java
 | 
				
			||||||
 | 
					// Copyright (c) Hannes Wallnöfer 2002
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package helma.scripting.fesi;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import helma.scripting.*;
 | 
				
			||||||
 | 
					import helma.scripting.fesi.extensions.*;
 | 
				
			||||||
 | 
					import helma.framework.*;
 | 
				
			||||||
 | 
					import helma.framework.core.*;
 | 
				
			||||||
 | 
					import helma.objectmodel.*;
 | 
				
			||||||
 | 
					import helma.objectmodel.db.DbMapping;
 | 
				
			||||||
 | 
					import helma.objectmodel.db.Relation;
 | 
				
			||||||
 | 
					import helma.util.Updatable;
 | 
				
			||||||
 | 
					import java.util.*;
 | 
				
			||||||
 | 
					import java.io.*;
 | 
				
			||||||
 | 
					import FESI.Data.*;
 | 
				
			||||||
 | 
					import FESI.Interpreter.*;
 | 
				
			||||||
 | 
					import FESI.Exceptions.*;
 | 
				
			||||||
 | 
					import Acme.LruHashtable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * This is the implementation of ScriptingEnvironment for the FESI EcmaScript interpreter.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class FesiEvaluator {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // the application we're running in
 | 
				
			||||||
 | 
					    public Application app;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // The FESI evaluator
 | 
				
			||||||
 | 
					    Evaluator evaluator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // the global object
 | 
				
			||||||
 | 
					    GlobalObject global;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // caching table for JavaScript object wrappers
 | 
				
			||||||
 | 
					    LruHashtable wrappercache;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // table containing JavaScript prototypes
 | 
				
			||||||
 | 
					    Hashtable prototypes;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // the request evaluator instance owning this fesi evaluator
 | 
				
			||||||
 | 
					    RequestEvaluator reval;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // extensions loaded by this evaluator
 | 
				
			||||||
 | 
					    static String[] extensions = new String[] {
 | 
				
			||||||
 | 
						"FESI.Extensions.BasicIO",
 | 
				
			||||||
 | 
						"FESI.Extensions.FileIO",
 | 
				
			||||||
 | 
						"helma.xmlrpc.fesi.FesiRpcExtension",
 | 
				
			||||||
 | 
						"helma.scripting.fesi.extensions.ImageExtension",
 | 
				
			||||||
 | 
						"helma.scripting.fesi.extensions.FtpExtension",
 | 
				
			||||||
 | 
						"FESI.Extensions.JavaAccess",
 | 
				
			||||||
 | 
						"FESI.Extensions.OptionalRegExp"};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public FesiEvaluator (Application app, RequestEvaluator reval) {
 | 
				
			||||||
 | 
						this.app = app;
 | 
				
			||||||
 | 
						this.reval = reval;
 | 
				
			||||||
 | 
						wrappercache = new LruHashtable (100, .80f);
 | 
				
			||||||
 | 
						prototypes = new Hashtable ();
 | 
				
			||||||
 | 
						try {
 | 
				
			||||||
 | 
						    evaluator = new Evaluator();
 | 
				
			||||||
 | 
						    evaluator.reval = this;
 | 
				
			||||||
 | 
						    global = evaluator.getGlobalObject();
 | 
				
			||||||
 | 
						    for (int i=0; i<extensions.length; i++)
 | 
				
			||||||
 | 
						        evaluator.addExtension (extensions[i]);
 | 
				
			||||||
 | 
						    HopExtension hopx = new HopExtension (app);
 | 
				
			||||||
 | 
						    hopx.initializeExtension (this);
 | 
				
			||||||
 | 
						    MailExtension mailx = (MailExtension) evaluator.addExtension ("helma.scripting.fesi.extensions.MailExtension");
 | 
				
			||||||
 | 
						    mailx.setProperties (app.getProperties ());
 | 
				
			||||||
 | 
						    Database dbx = (Database) evaluator.addExtension ("helma.scripting.fesi.extensions.Database");
 | 
				
			||||||
 | 
						    dbx.setApplication (app);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						    // fake a cache member like the one found in ESNodes
 | 
				
			||||||
 | 
						    global.putHiddenProperty ("cache", new ESNode (new TransientNode ("cache"), this));
 | 
				
			||||||
 | 
						    global.putHiddenProperty ("undefined", ESUndefined.theUndefined);
 | 
				
			||||||
 | 
						    ESAppNode appnode = new ESAppNode (app.getAppNode (), this);
 | 
				
			||||||
 | 
						    global.putHiddenProperty ("app", appnode);
 | 
				
			||||||
 | 
						    initialize();
 | 
				
			||||||
 | 
						} catch (Exception e) {
 | 
				
			||||||
 | 
						    System.err.println("Cannot initialize interpreter");
 | 
				
			||||||
 | 
						    System.err.println("Error: " + e);
 | 
				
			||||||
 | 
						    e.printStackTrace ();
 | 
				
			||||||
 | 
						    throw new RuntimeException (e.getMessage ());
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private void initialize () {
 | 
				
			||||||
 | 
						Collection prototypes = app.getPrototypes();
 | 
				
			||||||
 | 
						for (Iterator i=prototypes.iterator(); i.hasNext(); ) {
 | 
				
			||||||
 | 
						    Prototype proto = (Prototype) i.next ();
 | 
				
			||||||
 | 
						    evaluatePrototype (proto);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void evaluatePrototype (Prototype prototype) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ObjectPrototype op = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// get the prototype's prototype if possible and necessary
 | 
				
			||||||
 | 
						ObjectPrototype opp = null;
 | 
				
			||||||
 | 
						Prototype parent = prototype.getParentPrototype ();
 | 
				
			||||||
 | 
						if (parent != null) {
 | 
				
			||||||
 | 
						    // see if parent prototype is already registered. if not, register it
 | 
				
			||||||
 | 
						    opp = getPrototype (parent.getName ());
 | 
				
			||||||
 | 
						    if (opp == null) {
 | 
				
			||||||
 | 
						        evaluatePrototype (parent);
 | 
				
			||||||
 | 
						        opp = getPrototype (parent.getName ());
 | 
				
			||||||
 | 
						    }
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						String name = prototype.getName ();
 | 
				
			||||||
 | 
						if (!"global".equalsIgnoreCase (name) && !"hopobject".equalsIgnoreCase (name) && opp == null) {
 | 
				
			||||||
 | 
						    if (app.isJavaPrototype (name))
 | 
				
			||||||
 | 
						        opp = getPrototype ("__javaobject__");
 | 
				
			||||||
 | 
						    else
 | 
				
			||||||
 | 
						        opp = getPrototype ("hopobject");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// if prototype doesn't exist (i.e. is a standard prototype built by HopExtension), create it.
 | 
				
			||||||
 | 
						op = getPrototype (name);
 | 
				
			||||||
 | 
						if (op == null) {
 | 
				
			||||||
 | 
						    op = new ObjectPrototype (opp, evaluator);
 | 
				
			||||||
 | 
						    try {
 | 
				
			||||||
 | 
						        op.putProperty ("prototypename", new ESString (name), "prototypename".hashCode ());
 | 
				
			||||||
 | 
						    } catch (EcmaScriptException ignore) {}
 | 
				
			||||||
 | 
						    putPrototype (name, op);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
						    // set parent prototype just in case it has been changed
 | 
				
			||||||
 | 
						    op.setPrototype (opp);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						resetPrototype (op);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Register a constructor for all types except global.
 | 
				
			||||||
 | 
						// This will first create a node and then call the actual (scripted) constructor on it.
 | 
				
			||||||
 | 
						if (!"global".equalsIgnoreCase (name)) {
 | 
				
			||||||
 | 
						    try {
 | 
				
			||||||
 | 
						        FunctionPrototype fp = (FunctionPrototype) evaluator.getFunctionPrototype();
 | 
				
			||||||
 | 
						        evaluator.getGlobalObject().putHiddenProperty (name, new NodeConstructor (name, fp, this));
 | 
				
			||||||
 | 
						    } catch (EcmaScriptException ignore) {}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for (Iterator it = prototype.functions.values().iterator(); it.hasNext(); ) {
 | 
				
			||||||
 | 
						    FunctionFile ff = (FunctionFile) it.next ();
 | 
				
			||||||
 | 
						    if (ff.hasFile ())
 | 
				
			||||||
 | 
						        evaluateFile (prototype, ff.getFile ());
 | 
				
			||||||
 | 
						    else
 | 
				
			||||||
 | 
						        evaluateString (prototype, ff.getContent ());
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						/* for (Iterator it = prototype.templates.values().iterator(); it.hasNext(); ) {
 | 
				
			||||||
 | 
						    Template tmp = (Template) it.next ();
 | 
				
			||||||
 | 
						    try {
 | 
				
			||||||
 | 
						        tmp.updateRequestEvaluator (reval);
 | 
				
			||||||
 | 
						    } catch (EcmaScriptException ignore) {}
 | 
				
			||||||
 | 
						} */
 | 
				
			||||||
 | 
						for (Iterator it = prototype.actions.values().iterator(); it.hasNext(); ) {
 | 
				
			||||||
 | 
						    ActionFile act = (ActionFile) it.next ();
 | 
				
			||||||
 | 
						    try {
 | 
				
			||||||
 | 
						        FesiActionAdapter adp = new FesiActionAdapter (act);
 | 
				
			||||||
 | 
						        adp.updateEvaluator (this);
 | 
				
			||||||
 | 
						    } catch (EcmaScriptException ignore) {}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     *  Return an object prototype to its initial state, removing all application specific
 | 
				
			||||||
 | 
					     *  functions.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    void resetPrototype (ObjectPrototype op) {
 | 
				
			||||||
 | 
						for (Enumeration en = op.getAllProperties(); en.hasMoreElements(); ) {
 | 
				
			||||||
 | 
						    String prop = en.nextElement ().toString ();
 | 
				
			||||||
 | 
						    try {
 | 
				
			||||||
 | 
						        ESValue esv = op.getProperty (prop, prop.hashCode ());
 | 
				
			||||||
 | 
						        // System.err.println (protoname+"."+obj+"   ->   "+esv.getClass());
 | 
				
			||||||
 | 
						        if (esv instanceof ConstructedFunctionObject || esv instanceof FesiActionAdapter.ThrowException)
 | 
				
			||||||
 | 
						            op.deleteProperty (prop, prop.hashCode());
 | 
				
			||||||
 | 
						    } catch (Exception x) {}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Invoke a function on some object, using the given arguments and global vars.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public Object invoke (Object thisObject, String functionName, Object[] args, HashMap globals) throws ScriptingException {
 | 
				
			||||||
 | 
						ESObject eso = null;
 | 
				
			||||||
 | 
						if (thisObject == null)
 | 
				
			||||||
 | 
						    eso = global;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						    eso = getElementWrapper (thisObject);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						GlobalObject global = evaluator.getGlobalObject ();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// if we are provided with global variables to set for this invocation,
 | 
				
			||||||
 | 
						// remember the global variables before invocation to be able to reset them afterwards.
 | 
				
			||||||
 | 
						Set globalVariables = null;
 | 
				
			||||||
 | 
						try {
 | 
				
			||||||
 | 
						    ESValue[] esv = args == null ? new ESValue[0] : new ESValue[args.length];
 | 
				
			||||||
 | 
						    for (int i=0; i<esv.length; i++) {
 | 
				
			||||||
 | 
						        // for java.util.Map objects, we use the special "tight" wrapper
 | 
				
			||||||
 | 
						        // that makes the Map look like a native object
 | 
				
			||||||
 | 
						        if (args[i] instanceof Map)
 | 
				
			||||||
 | 
						            esv[i] = new ESMapWrapper (this, (Map) args[i]);
 | 
				
			||||||
 | 
						        else
 | 
				
			||||||
 | 
						            esv[i] = ESLoader.normalizeValue (args[i], evaluator);
 | 
				
			||||||
 | 
						    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						    if (globals != null) {
 | 
				
			||||||
 | 
						        // remember all global variables before invocation
 | 
				
			||||||
 | 
						        Set tmpGlobal = new HashSet ();
 | 
				
			||||||
 | 
						        for (Enumeration en = global.getAllProperties(); en.hasMoreElements(); ) {
 | 
				
			||||||
 | 
						            tmpGlobal.add (en.nextElement ().toString ());
 | 
				
			||||||
 | 
						        }
 | 
				
			||||||
 | 
						        globalVariables = tmpGlobal;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						        // loop through global vars and set them
 | 
				
			||||||
 | 
						        for (Iterator i=globals.keySet().iterator(); i.hasNext(); ) {
 | 
				
			||||||
 | 
						            String k = (String) i.next();
 | 
				
			||||||
 | 
						            Object v = globals.get (k);
 | 
				
			||||||
 | 
						            ESValue sv = null;
 | 
				
			||||||
 | 
						            // we do a lot of extra work to make access to global variables
 | 
				
			||||||
 | 
						            // comfortable to EcmaScript coders, i.e. we use a lot of custom wrappers
 | 
				
			||||||
 | 
						            // that expose properties and functions in a special way instead of just going
 | 
				
			||||||
 | 
						            // with the standard java object wrappers.
 | 
				
			||||||
 | 
						            if (v instanceof RequestTrans)
 | 
				
			||||||
 | 
						                ((RequestTrans) v).data = new ESMapWrapper (this, ((RequestTrans) v).getRequestData ());
 | 
				
			||||||
 | 
						            else if (v instanceof ResponseTrans)
 | 
				
			||||||
 | 
						                ((ResponseTrans) v).data = new ESMapWrapper (this, ((ResponseTrans) v).getResponseData ());
 | 
				
			||||||
 | 
						            if (v instanceof Map)
 | 
				
			||||||
 | 
						                sv = new ESMapWrapper (this, (Map) v);
 | 
				
			||||||
 | 
						            else if ("path".equals (k)) {
 | 
				
			||||||
 | 
						                ArrayPrototype parr = new ArrayPrototype (evaluator.getArrayPrototype(), evaluator);
 | 
				
			||||||
 | 
						                List path = (List) v;
 | 
				
			||||||
 | 
						                for (int j=0; j<path.size(); j++) {
 | 
				
			||||||
 | 
						                    Object pathElem = path.get (j);
 | 
				
			||||||
 | 
						                    ESValue wrappedElement = getElementWrapper (pathElem);
 | 
				
			||||||
 | 
						                    parr.putProperty (j, wrappedElement);
 | 
				
			||||||
 | 
						                    parr.putHiddenProperty (app.getPrototypeName(pathElem), wrappedElement);
 | 
				
			||||||
 | 
						                }
 | 
				
			||||||
 | 
						                sv = parr;
 | 
				
			||||||
 | 
						            } else if ("user".equals (k)) {
 | 
				
			||||||
 | 
						                sv = getNodeWrapper ((User) v);
 | 
				
			||||||
 | 
						            } else if ("app".equals (k)) {
 | 
				
			||||||
 | 
						                sv = new ESAppNode ((INode) v, this);
 | 
				
			||||||
 | 
						            }
 | 
				
			||||||
 | 
						            else
 | 
				
			||||||
 | 
						                sv = ESLoader.normalizeValue (v, evaluator);
 | 
				
			||||||
 | 
						            global.putHiddenProperty (k, sv);
 | 
				
			||||||
 | 
						        }
 | 
				
			||||||
 | 
						    }
 | 
				
			||||||
 | 
						    evaluator.thread = Thread.currentThread ();
 | 
				
			||||||
 | 
						    ESValue retval =  eso.doIndirectCall (evaluator, eso, functionName, esv);
 | 
				
			||||||
 | 
						    return retval == null ? null : retval.toJavaObject ();
 | 
				
			||||||
 | 
						} catch (Exception x) {
 | 
				
			||||||
 | 
						    // check if this is a redirect exception, which has been converted by fesi
 | 
				
			||||||
 | 
						    // into an EcmaScript exception, which is why we can't explicitly catch it
 | 
				
			||||||
 | 
						    if (reval.res.getRedirect() != null)
 | 
				
			||||||
 | 
						        throw new RedirectException (reval.res.getRedirect ());
 | 
				
			||||||
 | 
						    // create and throw a ScriptingException with the right message
 | 
				
			||||||
 | 
						    String msg = x.getMessage ();
 | 
				
			||||||
 | 
						    if (msg == null || msg.length() < 10)
 | 
				
			||||||
 | 
						        msg = x.toString ();
 | 
				
			||||||
 | 
						    // System.err.println ("INVOKE-ERROR: "+msg);
 | 
				
			||||||
 | 
						    // x.printStackTrace ();
 | 
				
			||||||
 | 
						    throw new ScriptingException (msg);
 | 
				
			||||||
 | 
						} finally {
 | 
				
			||||||
 | 
						    // remove global variables that have been added during invocation.
 | 
				
			||||||
 | 
						    // this are typically undeclared variables, and we don't want them to
 | 
				
			||||||
 | 
						    // endure from one request to the next since this leads to buggy code that
 | 
				
			||||||
 | 
						    // relies on requests being served by the same evaluator, which is typically the
 | 
				
			||||||
 | 
						    // case under development conditions but not in deployment.
 | 
				
			||||||
 | 
						    if (globalVariables != null) {
 | 
				
			||||||
 | 
						        for (Enumeration en = global.getAllProperties(); en.hasMoreElements(); ) {
 | 
				
			||||||
 | 
						            String g = en.nextElement ().toString ();
 | 
				
			||||||
 | 
						            if (!globalVariables.contains (g)) try {
 | 
				
			||||||
 | 
						                global.deleteProperty (g, g.hashCode());
 | 
				
			||||||
 | 
						            } catch (Exception x) {
 | 
				
			||||||
 | 
						                System.err.println ("Error resetting global property: "+g);
 | 
				
			||||||
 | 
						            }
 | 
				
			||||||
 | 
						        }
 | 
				
			||||||
 | 
						    }
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Check if an object has a function property (public method if it
 | 
				
			||||||
 | 
					     * is a java object) with that name.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public boolean hasFunction (Object obj, String fname) {
 | 
				
			||||||
 | 
						ESObject eso = null;
 | 
				
			||||||
 | 
						if (obj == null)
 | 
				
			||||||
 | 
						    eso = evaluator.getGlobalObject ();
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						    eso = getElementWrapper (obj);
 | 
				
			||||||
 | 
						try {
 | 
				
			||||||
 | 
						    ESValue func = eso.getProperty (fname, fname.hashCode());
 | 
				
			||||||
 | 
						    if (func != null && func instanceof FunctionPrototype)
 | 
				
			||||||
 | 
						        return true;
 | 
				
			||||||
 | 
						} catch (EcmaScriptException esx) {
 | 
				
			||||||
 | 
						    // System.err.println ("Error in hasFunction: "+esx);
 | 
				
			||||||
 | 
						    return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Check if an object has a defined property (public field if it
 | 
				
			||||||
 | 
					     * is a java object) with that name.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public Object getProperty (Object obj, String propname) {
 | 
				
			||||||
 | 
						if (obj == null || propname == null)
 | 
				
			||||||
 | 
						    return null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						String prototypeName = app.getPrototypeName (obj);
 | 
				
			||||||
 | 
						if ("user".equalsIgnoreCase (prototypeName) &&
 | 
				
			||||||
 | 
							"password".equalsIgnoreCase (propname))
 | 
				
			||||||
 | 
						    return "[macro access to password property not allowed]";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// if this is a HopObject, check if the property is defined
 | 
				
			||||||
 | 
						// in the type.properties db-mapping.
 | 
				
			||||||
 | 
						if (obj instanceof INode) {
 | 
				
			||||||
 | 
						    DbMapping dbm = app.getDbMapping (prototypeName);
 | 
				
			||||||
 | 
						    if (dbm != null) {
 | 
				
			||||||
 | 
						        Relation rel = dbm.propertyToRelation (propname);
 | 
				
			||||||
 | 
						        if (rel == null || !rel.isPrimitive ())
 | 
				
			||||||
 | 
						            return "[property \""+propname+"\" is not defined for "+prototypeName+"]";
 | 
				
			||||||
 | 
						    }
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ESObject eso = getElementWrapper (obj);
 | 
				
			||||||
 | 
						try {
 | 
				
			||||||
 | 
						    ESValue prop = eso.getProperty (propname, propname.hashCode());
 | 
				
			||||||
 | 
						    if (prop != null && !(prop instanceof ESNull) &&
 | 
				
			||||||
 | 
						                    !(prop instanceof ESUndefined))
 | 
				
			||||||
 | 
						        return prop.toJavaObject ();
 | 
				
			||||||
 | 
						} catch (EcmaScriptException esx) {
 | 
				
			||||||
 | 
						    // System.err.println ("Error in getProperty: "+esx);
 | 
				
			||||||
 | 
						    return null;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     *  Return the FESI Evaluator object wrapped by this object.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public Evaluator getEvaluator () {
 | 
				
			||||||
 | 
						return evaluator;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Return the application we're running in
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public Application getApplication () {
 | 
				
			||||||
 | 
						return app;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     *  Get the object prototype for a prototype name
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public ObjectPrototype getPrototype (String protoName) {
 | 
				
			||||||
 | 
					        if (protoName == null)
 | 
				
			||||||
 | 
					            return null;
 | 
				
			||||||
 | 
					        return (ObjectPrototype) prototypes.get (protoName);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Register an object prototype for a certain prototype name.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public void putPrototype (String protoName, ObjectPrototype op) {
 | 
				
			||||||
 | 
					        if (protoName != null && op != null)
 | 
				
			||||||
 | 
					            prototypes.put (protoName, op);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     *  Get a Script wrapper for an object. In contrast to getElementWrapper, this is called for
 | 
				
			||||||
 | 
					     * any Java object, not just the ones in the request path which we know are scripted.
 | 
				
			||||||
 | 
					     * So what we do is check if the object belongs to a scripted class. If so, we call getElementWrapper()
 | 
				
			||||||
 | 
					     * with the object, otherwise we return a generic unscripted object wrapper.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public ESValue getObjectWrapper (Object e) {
 | 
				
			||||||
 | 
						if (app.getPrototypeName (e) != null)
 | 
				
			||||||
 | 
						    return getElementWrapper (e);
 | 
				
			||||||
 | 
						/* else if (e instanceof INode)
 | 
				
			||||||
 | 
						    return new ESNode ((INode) e, this); */
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						    return new ESWrapper (e, evaluator);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     *  Get a Script wrapper for any given object. If the object implements the IPathElement
 | 
				
			||||||
 | 
					     *  interface, the getPrototype method will be used to retrieve the name of the prototype
 | 
				
			||||||
 | 
					     * to use. Otherwise, a Java-Class-to-Script-Prototype mapping is consulted.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public ESObject getElementWrapper (Object e) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// check if e is an instance of a helma objectmodel node.
 | 
				
			||||||
 | 
						if (e instanceof INode)
 | 
				
			||||||
 | 
						    return getNodeWrapper ((INode) e);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Gotta find out the prototype name to use for this object...
 | 
				
			||||||
 | 
						String prototypeName = app.getPrototypeName (e);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ObjectPrototype op = getPrototype (prototypeName);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (op == null)
 | 
				
			||||||
 | 
						    op = getPrototype ("hopobject");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return new ESGenericObject (op, evaluator, e);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     *  Get a script wrapper for an implemntation of helma.objectmodel.INode
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public ESNode getNodeWrapper (INode n) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (n == null)
 | 
				
			||||||
 | 
					            return null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ESNode esn = (ESNode) wrappercache.get (n);
 | 
				
			||||||
 | 
					        if (esn == null || esn.getNode() != n) {
 | 
				
			||||||
 | 
					            String protoname = n.getPrototype ();
 | 
				
			||||||
 | 
					            ObjectPrototype op = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // set the DbMapping of the node according to its prototype.
 | 
				
			||||||
 | 
					            // this *should* be done on the objectmodel level, but isn't currently
 | 
				
			||||||
 | 
					            // for embedded nodes since there's not enough type info at the objectmodel level
 | 
				
			||||||
 | 
					            // for those nodes.
 | 
				
			||||||
 | 
					            if (protoname != null && protoname.length() > 0 && n.getDbMapping () == null) {
 | 
				
			||||||
 | 
					                n.setDbMapping (app.getDbMapping (protoname));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            op = getPrototype (protoname);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // no prototype found for this node?
 | 
				
			||||||
 | 
					            if (op == null)
 | 
				
			||||||
 | 
					                op = getPrototype("hopobject");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            DbMapping dbm = n.getDbMapping ();
 | 
				
			||||||
 | 
					            if (dbm != null && dbm.isInstanceOf ("user"))
 | 
				
			||||||
 | 
					                esn = new ESUser (n, this, null);
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					                esn = new ESNode (op, evaluator, n, this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            wrappercache.put (n, esn);
 | 
				
			||||||
 | 
					            // app.logEvent ("Wrapper for "+n+" created");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return esn;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     *  Register a new Node wrapper with the wrapper cache. This is used by the
 | 
				
			||||||
 | 
					     * Node constructor.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public void putNodeWrapper (INode n, ESNode esn) {
 | 
				
			||||||
 | 
						wrappercache.put (n, esn);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     *  Get a scripting wrapper object for a user object. Active user objects are represented by
 | 
				
			||||||
 | 
					     *  the special ESUser wrapper class.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public ESNode getNodeWrapper (User u) {
 | 
				
			||||||
 | 
					        if (u == null)
 | 
				
			||||||
 | 
					            return null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ESUser esn = (ESUser) wrappercache.get (u);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (esn == null) {
 | 
				
			||||||
 | 
					            esn = new ESUser (u.getNode(), this, u);
 | 
				
			||||||
 | 
					            wrappercache.put (u, esn);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            // the user node may have changed (login/logout) while the ESUser was
 | 
				
			||||||
 | 
					            // lingering in the cache.
 | 
				
			||||||
 | 
					            esn.updateNodeFromUser ();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return esn;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     *  Return the RequestEvaluator owning and driving this FESI evaluator.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public RequestEvaluator getRequestEvaluator () {
 | 
				
			||||||
 | 
						return reval;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     *  Return the Response object of the current evaluation context. Proxy method to RequestEvaluator.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public ResponseTrans getResponse () {
 | 
				
			||||||
 | 
						return reval.res;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     *  Return the Request object of the current evaluation context. Proxy method to RequestEvaluator.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public RequestTrans getRequest () {
 | 
				
			||||||
 | 
						return reval.req;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public  synchronized void evaluateFile (Prototype prototype, File file) {
 | 
				
			||||||
 | 
						try {
 | 
				
			||||||
 | 
						    FileReader fr = new FileReader (file);
 | 
				
			||||||
 | 
						    EvaluationSource es = new FileEvaluationSource (file.getPath (), null);
 | 
				
			||||||
 | 
						    updateEvaluator (prototype, fr, es);
 | 
				
			||||||
 | 
						} catch (IOException iox) {
 | 
				
			||||||
 | 
						    app.logEvent ("Error updating function file: "+iox);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public synchronized void evaluateString (Prototype prototype, String code) {
 | 
				
			||||||
 | 
						StringReader reader = new StringReader (code);
 | 
				
			||||||
 | 
						StringEvaluationSource es = new StringEvaluationSource (code, null);
 | 
				
			||||||
 | 
						updateEvaluator (prototype, reader, es);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public  synchronized void updateEvaluator (Prototype prototype, Reader reader, EvaluationSource source) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // HashMap priorProps = null;
 | 
				
			||||||
 | 
					        // HashSet newProps = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            ObjectPrototype op = getPrototype (prototype.getName());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // extract all properties from prototype _before_ evaluation, so we can compare afterwards
 | 
				
			||||||
 | 
					            // but only do this is declaredProps is not up to date yet
 | 
				
			||||||
 | 
					            /*if (declaredPropsTimestamp != lastmod) {
 | 
				
			||||||
 | 
					                priorProps = new HashMap ();
 | 
				
			||||||
 | 
					                // remember properties before evaluation, so we can tell what's new afterwards
 | 
				
			||||||
 | 
					                try {
 | 
				
			||||||
 | 
					                    for (Enumeration en=op.getAllProperties(); en.hasMoreElements(); ) {
 | 
				
			||||||
 | 
					                        String prop = (String) en.nextElement ();
 | 
				
			||||||
 | 
					                        priorProps.put (prop, op.getProperty (prop, prop.hashCode()));
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                } catch (Exception ignore) {}
 | 
				
			||||||
 | 
					            } */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // do the update, evaluating the file
 | 
				
			||||||
 | 
					            evaluator.evaluate(reader, op, source, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // check what's new
 | 
				
			||||||
 | 
					            /* if (declaredPropsTimestamp != lastmod) try {
 | 
				
			||||||
 | 
					                newProps = new HashSet ();
 | 
				
			||||||
 | 
					                for (Enumeration en=op.getAllProperties(); en.hasMoreElements(); ) {
 | 
				
			||||||
 | 
					                    String prop = (String) en.nextElement ();
 | 
				
			||||||
 | 
					                    if (priorProps.get (prop) == null || op.getProperty (prop, prop.hashCode()) != priorProps.get (prop))
 | 
				
			||||||
 | 
					                        newProps.add (prop);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            } catch (Exception ignore) {} */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        } catch (Throwable e) {
 | 
				
			||||||
 | 
					            app.logEvent ("Error parsing function file "+source+": "+e);
 | 
				
			||||||
 | 
					        } finally {
 | 
				
			||||||
 | 
					            if (reader != null) {
 | 
				
			||||||
 | 
					                try {
 | 
				
			||||||
 | 
					                    reader.close();
 | 
				
			||||||
 | 
					                } catch (IOException ignore) {}
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // now remove the props that were not refreshed, and set declared props to new collection
 | 
				
			||||||
 | 
					            /* if (declaredPropsTimestamp != lastmod) {
 | 
				
			||||||
 | 
					                declaredPropsTimestamp = lastmod;
 | 
				
			||||||
 | 
					                if (declaredProps != null) {
 | 
				
			||||||
 | 
					                    declaredProps.removeAll (newProps);
 | 
				
			||||||
 | 
					                    removeProperties (declaredProps);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                declaredProps = newProps;
 | 
				
			||||||
 | 
					                // System.err.println ("DECLAREDPROPS = "+declaredProps);
 | 
				
			||||||
 | 
					            } */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										85
									
								
								src/helma/scripting/fesi/FesiScriptingEnvironment.java
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								src/helma/scripting/fesi/FesiScriptingEnvironment.java
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,85 @@
 | 
				
			||||||
 | 
					// FesiScriptingEnvironment.java
 | 
				
			||||||
 | 
					// Copyright (c) Hannes Wallnöfer 2002
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package helma.scripting.fesi;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import helma.scripting.*;
 | 
				
			||||||
 | 
					import helma.framework.core.*;
 | 
				
			||||||
 | 
					import java.util.*;
 | 
				
			||||||
 | 
					import java.io.File;
 | 
				
			||||||
 | 
					import FESI.Data.*;
 | 
				
			||||||
 | 
					import FESI.Interpreter.*;
 | 
				
			||||||
 | 
					import FESI.Exceptions.*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * This is the implementation of ScriptingEnvironment for the FESI EcmaScript interpreter.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					public class FesiScriptingEnvironment implements ScriptingEnvironment {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Application app;
 | 
				
			||||||
 | 
					    Properties props;
 | 
				
			||||||
 | 
					    HashMap evaluators;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Initialize the environment using the given properties
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public void init (Application app, Properties props) throws ScriptingException {
 | 
				
			||||||
 | 
						this.app = app;
 | 
				
			||||||
 | 
						this.props = props;
 | 
				
			||||||
 | 
						evaluators = new HashMap ();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * A prototype has been updated and must be re-evaluated.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public void updatePrototype (Prototype prototype) {
 | 
				
			||||||
 | 
						for (Iterator i = evaluators.values().iterator(); i.hasNext(); ) {
 | 
				
			||||||
 | 
						    FesiEvaluator fesi = (FesiEvaluator) i.next();
 | 
				
			||||||
 | 
						    fesi.evaluatePrototype (prototype);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Invoke a function on some object, using the given arguments and global vars.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public Object invoke (Object thisObject, String functionName, Object[] args,
 | 
				
			||||||
 | 
								HashMap globals, RequestEvaluator reval)
 | 
				
			||||||
 | 
								throws ScriptingException {
 | 
				
			||||||
 | 
						// check if there is already a FesiEvaluator for this RequestEvaluator.
 | 
				
			||||||
 | 
						// if not, create one.
 | 
				
			||||||
 | 
						FesiEvaluator fesi = getEvaluator (reval);
 | 
				
			||||||
 | 
						return fesi.invoke (thisObject, functionName, args, globals);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     *  Get a property on an object
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public Object get (Object thisObject, String key, RequestEvaluator reval) {
 | 
				
			||||||
 | 
						FesiEvaluator fesi = getEvaluator (reval);
 | 
				
			||||||
 | 
						return fesi.getProperty (thisObject, key);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     *  Return true if a function by that name is defined for that object.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public boolean hasFunction (Object thisObject, String functionName, RequestEvaluator reval)
 | 
				
			||||||
 | 
								throws ScriptingException {
 | 
				
			||||||
 | 
						FesiEvaluator fesi = getEvaluator (reval);
 | 
				
			||||||
 | 
						return fesi.hasFunction (thisObject, functionName);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Collection getEvaluators () {
 | 
				
			||||||
 | 
						return evaluators.values();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    FesiEvaluator getEvaluator (RequestEvaluator reval) {
 | 
				
			||||||
 | 
						FesiEvaluator fesi = (FesiEvaluator) evaluators.get (reval);
 | 
				
			||||||
 | 
						if (fesi == null) {
 | 
				
			||||||
 | 
						    fesi = new FesiEvaluator (app, reval);
 | 
				
			||||||
 | 
						    evaluators.put (reval, fesi);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return fesi;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -17,29 +17,28 @@ import java.util.*;
 | 
				
			||||||
import java.text.*;
 | 
					import java.text.*;
 | 
				
			||||||
import org.xml.sax.InputSource;
 | 
					import org.xml.sax.InputSource;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** 
 | 
					/**
 | 
				
			||||||
 * This is the basic Extension for FESI interpreters used in HOP. It sets up 
 | 
					 * This is the basic Extension for FESI interpreters used in Helma. It sets up
 | 
				
			||||||
 * varios constructors, global functions and properties etc. 
 | 
					 * varios constructors, global functions and properties on the HopObject prototype
 | 
				
			||||||
 | 
					 * (Node objects), the user prototype, the global prototype  etc.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 
 | 
					
 | 
				
			||||||
public class HopExtension {
 | 
					public class HopExtension {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected Application app;
 | 
					    protected Application app;
 | 
				
			||||||
    protected RequestEvaluator reval;
 | 
					    protected FesiEvaluator fesi;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public HopExtension () {
 | 
					    public HopExtension (Application app) {
 | 
				
			||||||
        super();
 | 
					        this.app = app;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Called by the evaluator after the extension is loaded.
 | 
					     * Called by the evaluator after the extension is loaded.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public void initializeExtension (RequestEvaluator reval) throws EcmaScriptException {
 | 
					    public void initializeExtension (FesiEvaluator fesi) throws EcmaScriptException {
 | 
				
			||||||
 | 
					        this.fesi = fesi;
 | 
				
			||||||
        this.reval = reval;
 | 
					        Evaluator evaluator = fesi.getEvaluator ();
 | 
				
			||||||
        this.app = reval.app;
 | 
					 | 
				
			||||||
        Evaluator evaluator = reval.evaluator;
 | 
					 | 
				
			||||||
        GlobalObject go = evaluator.getGlobalObject();
 | 
					        GlobalObject go = evaluator.getGlobalObject();
 | 
				
			||||||
        FunctionPrototype fp = (FunctionPrototype) evaluator.getFunctionPrototype();
 | 
					        FunctionPrototype fp = (FunctionPrototype) evaluator.getFunctionPrototype();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -56,42 +55,42 @@ public class HopExtension {
 | 
				
			||||||
        ESObject dp = evaluator.getDatePrototype ();
 | 
					        ESObject dp = evaluator.getDatePrototype ();
 | 
				
			||||||
        dp.putHiddenProperty ("format", new DatePrototypeFormat ("format", evaluator, fp));
 | 
					        dp.putHiddenProperty ("format", new DatePrototypeFormat ("format", evaluator, fp));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		sp.putHiddenProperty ("trim",   new StringTrim ("trim", evaluator, fp));
 | 
					        sp.putHiddenProperty ("trim",   new StringTrim ("trim", evaluator, fp));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // generic (Java wrapper) object prototype
 | 
					        // generic (Java wrapper) object prototype
 | 
				
			||||||
        reval.esObjectPrototype = new ObjectPrototype (op, evaluator);
 | 
					        ObjectPrototype esObjectPrototype = new ObjectPrototype (op, evaluator);
 | 
				
			||||||
        // the Node prototype
 | 
					        // the Node prototype
 | 
				
			||||||
        reval.esNodePrototype = new ObjectPrototype(op, evaluator);
 | 
					        ObjectPrototype esNodePrototype = new ObjectPrototype(op, evaluator);
 | 
				
			||||||
        // the User prototype
 | 
					        // the User prototype
 | 
				
			||||||
        reval.esUserPrototype = new ObjectPrototype (reval.esNodePrototype, evaluator);
 | 
					        ObjectPrototype esUserPrototype = new ObjectPrototype (esNodePrototype, evaluator);
 | 
				
			||||||
        // the Node constructor
 | 
					        // the Node constructor
 | 
				
			||||||
        ESObject node = new NodeConstructor ("Node", fp, reval);
 | 
					        ESObject node = new NodeConstructor ("Node", fp, fesi);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // register the default methods of Node objects in the Node prototype
 | 
					        // register the default methods of Node objects in the Node prototype
 | 
				
			||||||
        reval.esNodePrototype.putHiddenProperty ("add", new NodeAdd ("add", evaluator, fp));
 | 
					        esNodePrototype.putHiddenProperty ("add", new NodeAdd ("add", evaluator, fp));
 | 
				
			||||||
        reval.esNodePrototype.putHiddenProperty ("addAt", new NodeAddAt ("addAt", evaluator, fp));
 | 
					        esNodePrototype.putHiddenProperty ("addAt", new NodeAddAt ("addAt", evaluator, fp));
 | 
				
			||||||
        reval.esNodePrototype.putHiddenProperty ("remove", new NodeRemove ("remove", evaluator, fp));
 | 
					        esNodePrototype.putHiddenProperty ("remove", new NodeRemove ("remove", evaluator, fp));
 | 
				
			||||||
        reval.esNodePrototype.putHiddenProperty ("link", new NodeLink ("link", evaluator, fp));
 | 
					        esNodePrototype.putHiddenProperty ("link", new NodeLink ("link", evaluator, fp));
 | 
				
			||||||
        reval.esNodePrototype.putHiddenProperty ("list", new NodeList ("list", evaluator, fp));
 | 
					        esNodePrototype.putHiddenProperty ("list", new NodeList ("list", evaluator, fp));
 | 
				
			||||||
        reval.esNodePrototype.putHiddenProperty ("set", new NodeSet ("set", evaluator, fp));
 | 
					        esNodePrototype.putHiddenProperty ("set", new NodeSet ("set", evaluator, fp));
 | 
				
			||||||
        reval.esNodePrototype.putHiddenProperty ("get", new NodeGet ("get", evaluator, fp));
 | 
					        esNodePrototype.putHiddenProperty ("get", new NodeGet ("get", evaluator, fp));
 | 
				
			||||||
        reval.esNodePrototype.putHiddenProperty ("count", new NodeCount ("count", evaluator, fp));
 | 
					        esNodePrototype.putHiddenProperty ("count", new NodeCount ("count", evaluator, fp));
 | 
				
			||||||
        reval.esNodePrototype.putHiddenProperty ("contains", new NodeContains ("contains", evaluator, fp));
 | 
					        esNodePrototype.putHiddenProperty ("contains", new NodeContains ("contains", evaluator, fp));
 | 
				
			||||||
        reval.esNodePrototype.putHiddenProperty ("size", new NodeCount ("size", evaluator, fp));
 | 
					        esNodePrototype.putHiddenProperty ("size", new NodeCount ("size", evaluator, fp));
 | 
				
			||||||
        reval.esNodePrototype.putHiddenProperty ("editor", new NodeEditor ("editor", evaluator, fp));
 | 
					        esNodePrototype.putHiddenProperty ("editor", new NodeEditor ("editor", evaluator, fp));
 | 
				
			||||||
        reval.esNodePrototype.putHiddenProperty ("path", new NodeHref ("path", evaluator, fp));
 | 
					        esNodePrototype.putHiddenProperty ("path", new NodeHref ("path", evaluator, fp));
 | 
				
			||||||
        reval.esNodePrototype.putHiddenProperty ("href", new NodeHref ("href", evaluator, fp));
 | 
					        esNodePrototype.putHiddenProperty ("href", new NodeHref ("href", evaluator, fp));
 | 
				
			||||||
        reval.esNodePrototype.putHiddenProperty ("setParent", new NodeSetParent ("setParent", evaluator, fp));
 | 
					        esNodePrototype.putHiddenProperty ("setParent", new NodeSetParent ("setParent", evaluator, fp));
 | 
				
			||||||
        reval.esNodePrototype.putHiddenProperty ("invalidate", new NodeInvalidate ("invalidate", evaluator, fp));
 | 
					        esNodePrototype.putHiddenProperty ("invalidate", new NodeInvalidate ("invalidate", evaluator, fp));
 | 
				
			||||||
        reval.esNodePrototype.putHiddenProperty ("renderSkin", new RenderSkin ("renderSkin", evaluator, fp, false, false));
 | 
					        esNodePrototype.putHiddenProperty ("renderSkin", new RenderSkin ("renderSkin", evaluator, fp, false, false));
 | 
				
			||||||
        reval.esNodePrototype.putHiddenProperty ("renderSkinAsString", new RenderSkin ("renderSkinAsString", evaluator, fp, false, true));
 | 
					        esNodePrototype.putHiddenProperty ("renderSkinAsString", new RenderSkin ("renderSkinAsString", evaluator, fp, false, true));
 | 
				
			||||||
        reval.esNodePrototype.putHiddenProperty ("clearCache", new NodeClearCache ("clearCache", evaluator, fp));
 | 
					        esNodePrototype.putHiddenProperty ("clearCache", new NodeClearCache ("clearCache", evaluator, fp));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // default methods for generic Java wrapper object prototype.
 | 
					        // default methods for generic Java wrapper object prototype.
 | 
				
			||||||
        // This is a small subset of the methods in esNodePrototype.
 | 
					        // This is a small subset of the methods in esNodePrototype.
 | 
				
			||||||
        reval.esObjectPrototype.putHiddenProperty ("href", new NodeHref ("href", evaluator, fp));
 | 
					        esObjectPrototype.putHiddenProperty ("href", new NodeHref ("href", evaluator, fp));
 | 
				
			||||||
        reval.esObjectPrototype.putHiddenProperty("renderSkin", new RenderSkin ("renderSkin", evaluator, fp, false, false));
 | 
					        esObjectPrototype.putHiddenProperty("renderSkin", new RenderSkin ("renderSkin", evaluator, fp, false, false));
 | 
				
			||||||
        reval.esObjectPrototype.putHiddenProperty("renderSkinAsString", new RenderSkin ("renderSkinAsString", evaluator, fp, false, true));
 | 
					        esObjectPrototype.putHiddenProperty("renderSkinAsString", new RenderSkin ("renderSkinAsString", evaluator, fp, false, true));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // methods that give access to properties and global user lists
 | 
					        // methods that give access to properties and global user lists
 | 
				
			||||||
        go.putHiddenProperty("Node", node); // register the constructor for a plain Node object.
 | 
					        go.putHiddenProperty("Node", node); // register the constructor for a plain Node object.
 | 
				
			||||||
| 
						 | 
					@ -122,14 +121,19 @@ public class HopExtension {
 | 
				
			||||||
        go.deleteProperty("exit", "exit".hashCode());
 | 
					        go.deleteProperty("exit", "exit".hashCode());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // and some methods for session management from JS...
 | 
					        // and some methods for session management from JS...
 | 
				
			||||||
        reval.esUserPrototype.putHiddenProperty("logon", new UserLogin ("logon", evaluator, fp));
 | 
					        esUserPrototype.putHiddenProperty("logon", new UserLogin ("logon", evaluator, fp));
 | 
				
			||||||
        reval.esUserPrototype.putHiddenProperty("login", new UserLogin ("login", evaluator, fp));
 | 
					        esUserPrototype.putHiddenProperty("login", new UserLogin ("login", evaluator, fp));
 | 
				
			||||||
        reval.esUserPrototype.putHiddenProperty("register", new UserRegister ("register", evaluator, fp));
 | 
					        esUserPrototype.putHiddenProperty("register", new UserRegister ("register", evaluator, fp));
 | 
				
			||||||
        reval.esUserPrototype.putHiddenProperty("logout", new UserLogout ("logout", evaluator, fp));
 | 
					        esUserPrototype.putHiddenProperty("logout", new UserLogout ("logout", evaluator, fp));
 | 
				
			||||||
        reval.esUserPrototype.putHiddenProperty("onSince", new UserOnSince ("onSince", evaluator, fp));
 | 
					        esUserPrototype.putHiddenProperty("onSince", new UserOnSince ("onSince", evaluator, fp));
 | 
				
			||||||
        reval.esUserPrototype.putHiddenProperty("lastActive", new UserLastActive ("lastActive", evaluator, fp));
 | 
					        esUserPrototype.putHiddenProperty("lastActive", new UserLastActive ("lastActive", evaluator, fp));
 | 
				
			||||||
        reval.esUserPrototype.putHiddenProperty("touch", new UserTouch ("touch", evaluator, fp));
 | 
					        esUserPrototype.putHiddenProperty("touch", new UserTouch ("touch", evaluator, fp));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // register object prototypes with FesiEvaluator
 | 
				
			||||||
 | 
					        fesi.putPrototype ("global", go);
 | 
				
			||||||
 | 
					        fesi.putPrototype ("hopobject", esNodePrototype);
 | 
				
			||||||
 | 
					        fesi.putPrototype ("__javaobject__", esObjectPrototype);
 | 
				
			||||||
 | 
					        fesi.putPrototype ("user", esUserPrototype);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class NodeAdd extends BuiltinFunctionObject {
 | 
					    class NodeAdd extends BuiltinFunctionObject {
 | 
				
			||||||
| 
						 | 
					@ -437,7 +441,7 @@ public class HopExtension {
 | 
				
			||||||
            if (unode == null)
 | 
					            if (unode == null)
 | 
				
			||||||
                return ESNull.theNull;
 | 
					                return ESNull.theNull;
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
                return  reval.getNodeWrapper (unode);
 | 
					                return  fesi.getNodeWrapper (unode);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -552,12 +556,13 @@ public class HopExtension {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        public ESValue callFunction (ESObject thisObj, ESValue[] arguments) throws EcmaScriptException {
 | 
					        public ESValue callFunction (ESObject thisObj, ESValue[] arguments) throws EcmaScriptException {
 | 
				
			||||||
            if (arguments.length < 1 || arguments.length > 2 || arguments[0] ==null || arguments[0] == ESNull.theNull)
 | 
					            if (arguments.length < 1 || arguments.length > 2 || arguments[0] ==null || arguments[0] == ESNull.theNull)
 | 
				
			||||||
                throw new EcmaScriptException ("renderSkin must be called with one Skin argument and an optional parameter argument");
 | 
					                throw new EcmaScriptException ("renderSkin requires one argument containing the skin name and an optional parameter object argument");
 | 
				
			||||||
            try {
 | 
					            try {
 | 
				
			||||||
                Skin skin = null;
 | 
					                Skin skin = null;
 | 
				
			||||||
                ESObject thisObject = global ? null : thisObj;
 | 
					                ESObject thisObject = global ? null : thisObj;
 | 
				
			||||||
                HashMap params = null;
 | 
					                HashMap params = null;
 | 
				
			||||||
                if (arguments.length > 1 && arguments[1] instanceof ESObject) {
 | 
					                if (arguments.length > 1 && arguments[1] instanceof ESObject) {
 | 
				
			||||||
 | 
					                // create an parameter object to pass to the skin
 | 
				
			||||||
                    ESObject paramObject = (ESObject) arguments[1];
 | 
					                    ESObject paramObject = (ESObject) arguments[1];
 | 
				
			||||||
                    params = new HashMap ();
 | 
					                    params = new HashMap ();
 | 
				
			||||||
                    for (Enumeration en=paramObject.getProperties(); en.hasMoreElements(); ) {
 | 
					                    for (Enumeration en=paramObject.getProperties(); en.hasMoreElements(); ) {
 | 
				
			||||||
| 
						 | 
					@ -573,17 +578,29 @@ public class HopExtension {
 | 
				
			||||||
                        skin = (Skin) obj;
 | 
					                        skin = (Skin) obj;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // if res.skinpath is set, transform it into an array of java objects
 | 
				
			||||||
 | 
					                // (strings for directory names and INodes for internal, db-stored skinsets)
 | 
				
			||||||
 | 
					                ResponseTrans res = fesi.getResponse();
 | 
				
			||||||
 | 
					                Object[] skinpath = new Object[0];
 | 
				
			||||||
 | 
					                if (res.skinpath != null && res.skinpath instanceof ArrayPrototype) {
 | 
				
			||||||
 | 
					                    ArrayPrototype array = (ArrayPrototype) res.skinpath;
 | 
				
			||||||
 | 
					                    skinpath = new Object[array.size()];
 | 
				
			||||||
 | 
					                    for (int i=0; i<skinpath.length; i++)
 | 
				
			||||||
 | 
					                       skinpath[i] = array.getProperty(i).toJavaObject ();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // ready... retrieve the skin and render it.
 | 
				
			||||||
 | 
					                Object javaObject = thisObject == null ? null : thisObject.toJavaObject ();
 | 
				
			||||||
                if (skin == null)
 | 
					                if (skin == null)
 | 
				
			||||||
                    skin = reval.getSkin (thisObject, arguments[0].toString ());
 | 
					                    skin = app.getSkin (javaObject, arguments[0].toString (), skinpath);
 | 
				
			||||||
                if (asString)
 | 
					                if (asString)
 | 
				
			||||||
                    reval.res.pushStringBuffer ();
 | 
					                    res.pushStringBuffer ();
 | 
				
			||||||
                Object javaObj = thisObject == null ? null : thisObject.toJavaObject ();
 | 
					 | 
				
			||||||
                if (skin != null)
 | 
					                if (skin != null)
 | 
				
			||||||
                    skin.render (reval, javaObj, params);
 | 
					                    skin.render (fesi.getRequestEvaluator(), javaObject, params);
 | 
				
			||||||
                else
 | 
					                else
 | 
				
			||||||
                    reval.res.write ("[Skin not found: "+arguments[0]+"]");
 | 
					                    res.write ("[Skin not found: "+arguments[0]+"]");
 | 
				
			||||||
                if (asString)
 | 
					                if (asString)
 | 
				
			||||||
                    return  new ESString (reval.res.popStringBuffer ());
 | 
					                    return  new ESString (res.popStringBuffer ());
 | 
				
			||||||
            } catch (RedirectException redir) {
 | 
					            } catch (RedirectException redir) {
 | 
				
			||||||
                // let redirect pass through
 | 
					                // let redirect pass through
 | 
				
			||||||
                throw redir;
 | 
					                throw redir;
 | 
				
			||||||
| 
						 | 
					@ -602,14 +619,14 @@ public class HopExtension {
 | 
				
			||||||
            super (fp, evaluator, name, 1);
 | 
					            super (fp, evaluator, name, 1);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
 | 
					        public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
 | 
				
			||||||
        	INode user = null;
 | 
					            INode user = null;
 | 
				
			||||||
	if (arguments.length > 0) {
 | 
					            if (arguments.length > 0) {
 | 
				
			||||||
	    String uname = arguments[0].toString ().trim ();
 | 
					                String uname = arguments[0].toString ().trim ();
 | 
				
			||||||
	    user = app.getUserNode (uname);
 | 
					                user = app.getUserNode (uname);
 | 
				
			||||||
	}
 | 
					            }
 | 
				
			||||||
        	if (user == null)
 | 
					            if (user == null)
 | 
				
			||||||
        	    return ESNull.theNull;
 | 
					                return ESNull.theNull;
 | 
				
			||||||
        	return reval.getNodeWrapper (user);
 | 
					            return fesi.getNodeWrapper (user);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -618,15 +635,15 @@ public class HopExtension {
 | 
				
			||||||
            super (fp, evaluator, name, 1);
 | 
					            super (fp, evaluator, name, 1);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
 | 
					        public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
 | 
				
			||||||
        	User user = null;
 | 
					            User user = null;
 | 
				
			||||||
	if (arguments.length > 0) {
 | 
					            if (arguments.length > 0) {
 | 
				
			||||||
	    String sid = arguments[0].toString ().trim ();
 | 
					                String sid = arguments[0].toString ().trim ();
 | 
				
			||||||
	    user = app.getUser (sid);
 | 
					                user = app.getUser (sid);
 | 
				
			||||||
	}
 | 
					            }
 | 
				
			||||||
        	if (user == null || user.getUID() == null)
 | 
					            if (user == null || user.getUID() == null)
 | 
				
			||||||
        	    return ESNull.theNull;
 | 
					                return ESNull.theNull;
 | 
				
			||||||
	user.touch ();
 | 
					            user.touch ();
 | 
				
			||||||
        	return reval.getNodeWrapper (user.getNode ());
 | 
					            return fesi.getNodeWrapper (user.getNode ());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -663,7 +680,7 @@ public class HopExtension {
 | 
				
			||||||
               User u = (User) e.nextElement ();
 | 
					               User u = (User) e.nextElement ();
 | 
				
			||||||
               // Note: we previously sorted out duplicate users - now we simply enumerate all active sessions.
 | 
					               // Note: we previously sorted out duplicate users - now we simply enumerate all active sessions.
 | 
				
			||||||
               // if (u.uid == null || !visited.containsKey (u.uid)) {
 | 
					               // if (u.uid == null || !visited.containsKey (u.uid)) {
 | 
				
			||||||
               theArray.setElementAt (reval.getNodeWrapper (u), i++);
 | 
					               theArray.setElementAt (fesi.getNodeWrapper (u), i++);
 | 
				
			||||||
               // if (u.uid != null) visited.put (u.uid, u);
 | 
					               // if (u.uid != null) visited.put (u.uid, u);
 | 
				
			||||||
               // }
 | 
					               // }
 | 
				
			||||||
           }
 | 
					           }
 | 
				
			||||||
| 
						 | 
					@ -901,18 +918,6 @@ public class HopExtension {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* class NodePath extends BuiltinFunctionObject {
 | 
					 | 
				
			||||||
        NodePath (String name, Evaluator evaluator, FunctionPrototype fp) {
 | 
					 | 
				
			||||||
            super (fp, evaluator, name, 1);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
 | 
					 | 
				
			||||||
            INode n = ((ESNode) thisObject).getNode ();
 | 
					 | 
				
			||||||
            String tmpname = arguments[0].toString ();
 | 
					 | 
				
			||||||
            return new ESString (app.getNodePath (n, tmpname));
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    } */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    class NodeSetParent extends BuiltinFunctionObject {
 | 
					    class NodeSetParent extends BuiltinFunctionObject {
 | 
				
			||||||
        NodeSetParent (String name, Evaluator evaluator, FunctionPrototype fp) {
 | 
					        NodeSetParent (String name, Evaluator evaluator, FunctionPrototype fp) {
 | 
				
			||||||
            super (fp, evaluator, name, 2);
 | 
					            super (fp, evaluator, name, 2);
 | 
				
			||||||
| 
						 | 
					@ -964,11 +969,11 @@ public class HopExtension {
 | 
				
			||||||
            return new ESString (basicHref);
 | 
					            return new ESString (basicHref);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        private ESString renderSkin (Skin skin, String path, Object skinElem) throws EcmaScriptException {
 | 
					        private ESString renderSkin (Skin skin, String path, Object skinElem) throws EcmaScriptException {
 | 
				
			||||||
            reval.res.pushStringBuffer ();
 | 
					            fesi.getResponse().pushStringBuffer ();
 | 
				
			||||||
            HashMap param = new HashMap ();
 | 
					            HashMap param = new HashMap ();
 | 
				
			||||||
            param.put ("path", path);
 | 
					            param.put ("path", path);
 | 
				
			||||||
            skin.render (reval, skinElem, param);
 | 
					            skin.render (fesi.getRequestEvaluator(), skinElem, param);
 | 
				
			||||||
            return new ESString (reval.res.popStringBuffer ().trim ());
 | 
					            return new ESString (fesi.getResponse().popStringBuffer ().trim ());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -985,7 +990,7 @@ public class HopExtension {
 | 
				
			||||||
        double d = from <= to ? 1.0 : -1.0;
 | 
					        double d = from <= to ? 1.0 : -1.0;
 | 
				
			||||||
        for (double i=from; i*d<=to*d; i+=step) {
 | 
					        for (double i=from; i*d<=to*d; i+=step) {
 | 
				
			||||||
            if (Math.abs (i%1) < l) {
 | 
					            if (Math.abs (i%1) < l) {
 | 
				
			||||||
            	   int j = (int) i; 
 | 
					                int j = (int) i;
 | 
				
			||||||
                b.append ("<option value=\""+j);
 | 
					                b.append ("<option value=\""+j);
 | 
				
			||||||
                if (i == value) b.append ("\" selected=\"true");
 | 
					                if (i == value) b.append ("\" selected=\"true");
 | 
				
			||||||
                b.append ("\">"+j);
 | 
					                b.append ("\">"+j);
 | 
				
			||||||
| 
						 | 
					@ -998,165 +1003,7 @@ public class HopExtension {
 | 
				
			||||||
        b.append ("</select>");
 | 
					        b.append ("</select>");
 | 
				
			||||||
        return b.toString ();
 | 
					        return b.toString ();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
					 | 
				
			||||||
    private String getNodeChooserDD (String name, INode collection, INode target, String teaser) {
 | 
					 | 
				
			||||||
        StringBuffer buffer = new StringBuffer ("<select name=\"");
 | 
					 | 
				
			||||||
        buffer.append (name);
 | 
					 | 
				
			||||||
        buffer.append ("\">");
 | 
					 | 
				
			||||||
        if (collection.contains (target) == -1) {
 | 
					 | 
				
			||||||
            buffer.append ("<option value=>");
 | 
					 | 
				
			||||||
            buffer.append (HtmlEncoder.encodeAll (teaser));
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (collection != null) {
 | 
					 | 
				
			||||||
        	int l = collection.numberOfNodes ();
 | 
					 | 
				
			||||||
        	for (int i=0; i<l; i++) {
 | 
					 | 
				
			||||||
        	    INode next = collection.getSubnodeAt (i);
 | 
					 | 
				
			||||||
        	    buffer.append ("<option value=\"");
 | 
					 | 
				
			||||||
        	    buffer.append (next.getID ());
 | 
					 | 
				
			||||||
        	    if (target == next)
 | 
					 | 
				
			||||||
        	        buffer.append ("\" selected=\"true");
 | 
					 | 
				
			||||||
        	    buffer.append ("\">");
 | 
					 | 
				
			||||||
        	    String cname = next.getString ("name", false);
 | 
					 | 
				
			||||||
        	    if (cname == null) cname = next.getName ();
 | 
					 | 
				
			||||||
        	    buffer.append (HtmlEncoder.encodeAll (cname));
 | 
					 | 
				
			||||||
        	}
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        buffer.append ("</select>");
 | 
					 | 
				
			||||||
        return buffer.toString ();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    private String getNodeChooserRB (String name, INode collection, INode target) {
 | 
					 | 
				
			||||||
        StringBuffer buffer = new StringBuffer ();
 | 
					 | 
				
			||||||
        if (collection != null) {
 | 
					 | 
				
			||||||
        	int l = collection.numberOfNodes ();
 | 
					 | 
				
			||||||
        	for (int i=0; i<l; i++) {
 | 
					 | 
				
			||||||
        	    INode next = collection.getSubnodeAt (i);
 | 
					 | 
				
			||||||
        	    buffer.append ("<input type=radio name=\"");
 | 
					 | 
				
			||||||
        	    buffer.append (name);
 | 
					 | 
				
			||||||
        	    buffer.append ("\" value=\"");
 | 
					 | 
				
			||||||
        	    buffer.append (next.getElementName ()+"\"");
 | 
					 | 
				
			||||||
        	    if (target == next)
 | 
					 | 
				
			||||||
        	        buffer.append (" checked");
 | 
					 | 
				
			||||||
        	    buffer.append (">");
 | 
					 | 
				
			||||||
                 String cname = next.getString ("name", false);
 | 
					 | 
				
			||||||
        	    if (cname == null) cname = next.getName ();
 | 
					 | 
				
			||||||
        	    buffer.append (HtmlEncoder.encodeAll (cname));
 | 
					 | 
				
			||||||
        	    buffer.append ("<br>");
 | 
					 | 
				
			||||||
        	}
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return buffer.toString ();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private String getNodeChooserCB (String name, INode collection, INode target) {
 | 
					
 | 
				
			||||||
        StringBuffer buffer = new StringBuffer ();
 | 
					 | 
				
			||||||
         if (collection != null) {
 | 
					 | 
				
			||||||
        	int l = collection.numberOfNodes ();
 | 
					 | 
				
			||||||
        	for (int i=0; i<l; i++) {
 | 
					 | 
				
			||||||
        	    INode next = collection.getSubnodeAt (i);
 | 
					 | 
				
			||||||
        	    buffer.append ("<input type=checkbox name=\"");
 | 
					 | 
				
			||||||
        	    buffer.append (name);
 | 
					 | 
				
			||||||
        	    buffer.append ("\" value=");
 | 
					 | 
				
			||||||
        	    buffer.append (next.getElementName ());
 | 
					 | 
				
			||||||
        	    if (target.contains (next) > -1)
 | 
					 | 
				
			||||||
        	        buffer.append (" checked");
 | 
					 | 
				
			||||||
        	    buffer.append (">");
 | 
					 | 
				
			||||||
        	    buffer.append (HtmlEncoder.encodeAll (next.getName ()));
 | 
					 | 
				
			||||||
        	    buffer.append ("<br>");
 | 
					 | 
				
			||||||
        	}
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return buffer.toString ();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
 }
 | 
					 }
 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,14 +15,14 @@ import FESI.Interpreter.*;
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class NodeConstructor extends BuiltinFunctionObject {
 | 
					public class NodeConstructor extends BuiltinFunctionObject {
 | 
				
			||||||
    	
 | 
					
 | 
				
			||||||
        RequestEvaluator reval;
 | 
					        FesiEvaluator fesi;
 | 
				
			||||||
        String typename;
 | 
					        String typename;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public NodeConstructor (String name, FunctionPrototype fp, RequestEvaluator reval) {
 | 
					        public NodeConstructor (String name, FunctionPrototype fp, FesiEvaluator fesi) {
 | 
				
			||||||
            super(fp, reval.evaluator, name, 1);
 | 
					            super(fp, fesi.getEvaluator (), name, 1);
 | 
				
			||||||
            typename = name;
 | 
					            typename = name;
 | 
				
			||||||
            this.reval = reval;
 | 
					            this.fesi = fesi;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public ESValue callFunction(ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
 | 
					        public ESValue callFunction(ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
 | 
				
			||||||
| 
						 | 
					@ -31,35 +31,33 @@ public class NodeConstructor extends BuiltinFunctionObject {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public ESObject doConstruct(ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
 | 
					        public ESObject doConstruct(ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
 | 
				
			||||||
           ESNode node = null;
 | 
					           ESNode node = null;
 | 
				
			||||||
 | 
					           Application app = fesi.getApplication ();
 | 
				
			||||||
           if ("Node".equals (typename) || "hopobject".equalsIgnoreCase (typename)) {
 | 
					           if ("Node".equals (typename) || "hopobject".equalsIgnoreCase (typename)) {
 | 
				
			||||||
               if (arguments.length == 0) {
 | 
					               String nodeName = null;
 | 
				
			||||||
                   Node n = new Node ((String) null, (String) null, reval.app.getWrappedNodeManager ());
 | 
					               if (arguments.length > 0 && arguments[0] != null)
 | 
				
			||||||
                   node = new ESNode (reval.esNodePrototype, this.evaluator, n, reval);
 | 
					                   nodeName = arguments[0].toString();
 | 
				
			||||||
                   reval.objectcache.put (node.getNode (), node);
 | 
					               Node n = new Node (nodeName, (String) null, app.getWrappedNodeManager ());
 | 
				
			||||||
               } else {
 | 
					               node = new ESNode (fesi.getPrototype ("hopobject"), this.evaluator, n, fesi);
 | 
				
			||||||
                   Node n = new Node (arguments[0].toString(), (String) null, reval.app.getWrappedNodeManager ());
 | 
					               fesi.putNodeWrapper (node.getNode (), node);
 | 
				
			||||||
                   node = new ESNode (reval.esNodePrototype, this.evaluator, n, reval);
 | 
					 | 
				
			||||||
                   reval.objectcache.put (node.getNode (), node);
 | 
					 | 
				
			||||||
               }
 | 
					 | 
				
			||||||
           } else {
 | 
					           } else {
 | 
				
			||||||
               // Typed nodes are instantiated as helma.objectmodel.db.Node from the beginning
 | 
					               // Typed nodes are instantiated as helma.objectmodel.db.Node from the beginning
 | 
				
			||||||
               // even if we don't know yet if they are going to be stored in a database. The reason
 | 
					               // even if we don't know yet if they are going to be stored in a database. The reason
 | 
				
			||||||
               // is that we want to be able to use the specail features like subnode relations even for
 | 
					               // is that we want to be able to use the specail features like subnode relations even for
 | 
				
			||||||
               // transient nodes.
 | 
					               // transient nodes.
 | 
				
			||||||
               ObjectPrototype op = reval.getPrototype (typename);
 | 
					               ObjectPrototype op = fesi.getPrototype (typename);
 | 
				
			||||||
               Node n = new Node (typename, typename, reval.app.getWrappedNodeManager ());
 | 
					               Node n = new Node (typename, typename, app.getWrappedNodeManager ());
 | 
				
			||||||
               node = new ESNode (op, reval.evaluator, n, reval);
 | 
					               node = new ESNode (op, fesi.getEvaluator (), n, fesi);
 | 
				
			||||||
               node.setPrototype (typename);
 | 
					               node.setPrototype (typename);
 | 
				
			||||||
               node.getNode ().setDbMapping (reval.app.getDbMapping (typename));
 | 
					               node.getNode ().setDbMapping (app.getDbMapping (typename));
 | 
				
			||||||
               try {
 | 
					               try {
 | 
				
			||||||
                   // first try calling "constructor", if that doesn't work, try calling a function
 | 
					                   // first try calling "constructor", if that doesn't work, try calling a function
 | 
				
			||||||
                   // with the name of the type.
 | 
					                   // with the name of the type.
 | 
				
			||||||
                   // HACK: There is an incompatibility problem here, because the property
 | 
					                   // HACK: There is an incompatibility problem here, because the property
 | 
				
			||||||
                   // constructor is defined as the constructor of the object by EcmaScript.
 | 
					                   // constructor is defined as the constructor of the object by EcmaScript.
 | 
				
			||||||
                   if (op.getProperty("constructor", "constructor".hashCode()) instanceof ConstructedFunctionObject)
 | 
					                   if (op.getProperty ("constructor", "constructor".hashCode()) instanceof ConstructedFunctionObject)
 | 
				
			||||||
                       node.doIndirectCall (reval.evaluator, node, "constructor", arguments);
 | 
					                       node.doIndirectCall (fesi.getEvaluator(), node, "constructor", arguments);
 | 
				
			||||||
                   else
 | 
					                   else
 | 
				
			||||||
                       node.doIndirectCall (reval.evaluator, node, typename, arguments);
 | 
					                       node.doIndirectCall (fesi.getEvaluator(), node, typename, arguments);
 | 
				
			||||||
               } catch (Exception ignore) {}
 | 
					               } catch (Exception ignore) {}
 | 
				
			||||||
           }
 | 
					           }
 | 
				
			||||||
           return node;
 | 
					           return node;
 | 
				
			||||||
| 
						 | 
					@ -70,9 +68,9 @@ public class NodeConstructor extends BuiltinFunctionObject {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public ESValue getProperty(String propertyName, int hash) throws EcmaScriptException {
 | 
					        public ESValue getProperty(String propertyName, int hash) throws EcmaScriptException {
 | 
				
			||||||
	if ("prototype".equals (propertyName))
 | 
					            if ("prototype".equals (propertyName))
 | 
				
			||||||
	    return reval.getPrototype (typename);
 | 
					                return fesi.getPrototype (typename);
 | 
				
			||||||
             return super.getProperty(propertyName, hash);
 | 
					            return super.getProperty(propertyName, hash);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public String[] getSpecialPropertyNames() {
 | 
					        public String[] getSpecialPropertyNames() {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue