moved classes here from helma.framework.* packages.
This commit is contained in:
parent
dd3cbc45e9
commit
936a9de0e8
17 changed files with 5344 additions and 0 deletions
291
src/helma/scripting/Action.java
Normal file
291
src/helma/scripting/Action.java
Normal file
|
@ -0,0 +1,291 @@
|
||||||
|
// Action.java
|
||||||
|
// Copyright (c) Hannes Wallnöfer 1998-2000
|
||||||
|
|
||||||
|
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;
|
||||||
|
import FESI.Data.*;
|
||||||
|
import FESI.Parser.*;
|
||||||
|
import FESI.AST.ASTFormalParameterList;
|
||||||
|
import FESI.AST.ASTStatementList;
|
||||||
|
import FESI.AST.EcmaScriptTreeConstants;
|
||||||
|
import FESI.Interpreter.*;
|
||||||
|
import FESI.Exceptions.*;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An Action is a JavaScript function that is exposed as a URI. It is
|
||||||
|
* 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 {
|
||||||
|
|
||||||
|
String name;
|
||||||
|
String functionName;
|
||||||
|
Prototype prototype;
|
||||||
|
Application app;
|
||||||
|
File file;
|
||||||
|
long lastmod;
|
||||||
|
|
||||||
|
// this is the parsed function which can be easily applied to RequestEvaluator objects
|
||||||
|
TypeUpdater pfunc;
|
||||||
|
|
||||||
|
|
||||||
|
public Action (File file, String name, Prototype proto) {
|
||||||
|
this.prototype = proto;
|
||||||
|
this.app = proto.getApplication ();
|
||||||
|
this.name = name;
|
||||||
|
this.file = file;
|
||||||
|
if (file != null)
|
||||||
|
update ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void update (String content) throws Exception {
|
||||||
|
// app.logEvent ("Reading text template " + name);
|
||||||
|
|
||||||
|
functionName = name+"_action";
|
||||||
|
|
||||||
|
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 ()) {
|
||||||
|
try {
|
||||||
|
RequestEvaluator reval = (RequestEvaluator) evals.next ();
|
||||||
|
updateRequestEvaluator (reval);
|
||||||
|
} catch (Exception ignore) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void remove () {
|
||||||
|
prototype.actions.remove (name);
|
||||||
|
prototype.updatables.remove (file.getName());
|
||||||
|
|
||||||
|
Iterator evals = app.typemgr.getRegisteredRequestEvaluators ();
|
||||||
|
while (evals.hasNext ()) {
|
||||||
|
try {
|
||||||
|
RequestEvaluator reval = (RequestEvaluator) evals.next ();
|
||||||
|
ObjectPrototype op = reval.getPrototype (prototype.getName());
|
||||||
|
functionName = name+"_action";
|
||||||
|
ESValue esv = (ESValue) op.getProperty (functionName, functionName.hashCode());
|
||||||
|
if (esv instanceof ConstructedFunctionObject || esv instanceof ThrowException) {
|
||||||
|
op.deleteProperty (functionName, functionName.hashCode());
|
||||||
|
}
|
||||||
|
} catch (Exception ignore) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName () {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFunctionName () {
|
||||||
|
return functionName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString () {
|
||||||
|
return prototype.getName()+"/"+file.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void updateRequestEvaluator (RequestEvaluator reval) throws EcmaScriptException {
|
||||||
|
if (pfunc != null)
|
||||||
|
pfunc.updateRequestEvaluator (reval);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected TypeUpdater parseFunction (String funcname, String params, String body) throws EcmaScriptException {
|
||||||
|
|
||||||
|
// ESObject fp = app.eval.evaluator.getFunctionPrototype();
|
||||||
|
// ConstructedFunctionObject function = null;
|
||||||
|
ASTFormalParameterList fpl = null;
|
||||||
|
ASTStatementList sl = null;
|
||||||
|
FunctionEvaluationSource fes = null;
|
||||||
|
|
||||||
|
if (body == null || "".equals (body.trim()))
|
||||||
|
body = ";\r\n";
|
||||||
|
else
|
||||||
|
body = body + "\r\n";
|
||||||
|
if (params == null) params = "";
|
||||||
|
else params = params.trim ();
|
||||||
|
|
||||||
|
String fulltext = "function "+funcname+" (" + params + ") {\n" + body + "\n}";
|
||||||
|
|
||||||
|
EcmaScript parser;
|
||||||
|
StringReader is;
|
||||||
|
|
||||||
|
// Special case for empty parameters
|
||||||
|
if (params.length()==0) {
|
||||||
|
fpl = new ASTFormalParameterList(EcmaScriptTreeConstants.JJTFORMALPARAMETERLIST);
|
||||||
|
} else {
|
||||||
|
is = new java.io.StringReader(params);
|
||||||
|
parser = new EcmaScript(is);
|
||||||
|
try {
|
||||||
|
fpl = (ASTFormalParameterList) parser.FormalParameterList();
|
||||||
|
is.close();
|
||||||
|
} catch (ParseException x) {
|
||||||
|
throw new EcmaScriptParseException (x, new StringEvaluationSource(fulltext, null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// this is very very very strange: without the toString, lots of obscure exceptions
|
||||||
|
// deep inside the parser...
|
||||||
|
is = new java.io.StringReader(body.toString ());
|
||||||
|
try {
|
||||||
|
parser = new EcmaScript (is);
|
||||||
|
sl = (ASTStatementList) parser.StatementList();
|
||||||
|
is.close();
|
||||||
|
} catch (ParseException x) {
|
||||||
|
app.logEvent ("Error parsing file "+app.getName()+":"+prototype.getName()+"/"+file.getName()+": "+x);
|
||||||
|
throw new EcmaScriptParseException (x, new StringEvaluationSource(fulltext, null));
|
||||||
|
} catch (Exception x) {
|
||||||
|
app.logEvent ("Error parsing file "+app.getName()+":"+prototype.getName()+"/"+file.getName()+": "+x);
|
||||||
|
throw new RuntimeException (x.getMessage ());
|
||||||
|
}
|
||||||
|
|
||||||
|
fes = new FunctionEvaluationSource (new StringEvaluationSource(fulltext, null), funcname);
|
||||||
|
return new ParsedFunction (fpl, sl, fes, fulltext, funcname);
|
||||||
|
}
|
||||||
|
|
||||||
|
class ParsedFunction implements TypeUpdater {
|
||||||
|
|
||||||
|
ASTFormalParameterList fpl = null;
|
||||||
|
ASTStatementList sl = null;
|
||||||
|
FunctionEvaluationSource fes = null;
|
||||||
|
String fullFunctionText = null;
|
||||||
|
String functionName;
|
||||||
|
|
||||||
|
public ParsedFunction (ASTFormalParameterList fpl, ASTStatementList sl, FunctionEvaluationSource fes,
|
||||||
|
String fullFunctionText, String functionName) {
|
||||||
|
this.fpl = fpl;
|
||||||
|
this.sl = sl;
|
||||||
|
this.fes = fes;
|
||||||
|
this.fullFunctionText = fullFunctionText;
|
||||||
|
this.functionName = functionName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateRequestEvaluator (RequestEvaluator reval) throws EcmaScriptException {
|
||||||
|
|
||||||
|
ObjectPrototype op = reval.getPrototype (prototype.getName());
|
||||||
|
|
||||||
|
EcmaScriptVariableVisitor vdvisitor = reval.evaluator.getVarDeclarationVisitor();
|
||||||
|
Vector vnames = vdvisitor.processVariableDeclarations(sl, fes);
|
||||||
|
|
||||||
|
FunctionPrototype fp = ConstructedFunctionObject.makeNewConstructedFunction (
|
||||||
|
reval.evaluator, functionName, fes,
|
||||||
|
fullFunctionText, fpl.getArguments(), vnames, sl);
|
||||||
|
op.putHiddenProperty (functionName, fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class ErrorFeedback implements TypeUpdater {
|
||||||
|
|
||||||
|
String functionName, errorMessage;
|
||||||
|
|
||||||
|
public ErrorFeedback (String fname, String msg) {
|
||||||
|
functionName = fname;
|
||||||
|
errorMessage = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateRequestEvaluator (RequestEvaluator reval) throws EcmaScriptException {
|
||||||
|
|
||||||
|
ObjectPrototype op = reval.getPrototype (prototype.getName ());
|
||||||
|
|
||||||
|
FunctionPrototype fp = (FunctionPrototype) reval.evaluator.getFunctionPrototype ();
|
||||||
|
FunctionPrototype func = new ThrowException (functionName, reval.evaluator, fp, errorMessage);
|
||||||
|
op.putHiddenProperty (functionName, func);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ThrowException extends BuiltinFunctionObject {
|
||||||
|
String message;
|
||||||
|
ThrowException (String name, Evaluator evaluator, FunctionPrototype fp, String message) {
|
||||||
|
super (fp, evaluator, name, 1);
|
||||||
|
this.message = message == null ? "No error message available" : message;
|
||||||
|
}
|
||||||
|
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
|
||||||
|
throw new EcmaScriptException (message);
|
||||||
|
}
|
||||||
|
public ESObject doConstruct (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
|
||||||
|
throw new EcmaScriptException (message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TypeUpdater {
|
||||||
|
public void updateRequestEvaluator (RequestEvaluator reval) throws EcmaScriptException;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
272
src/helma/scripting/FunctionFile.java
Normal file
272
src/helma/scripting/FunctionFile.java
Normal file
|
@ -0,0 +1,272 @@
|
||||||
|
// FunctionFile.java
|
||||||
|
// Copyright (c) Hannes Wallnöfer 1998-2000
|
||||||
|
|
||||||
|
package helma.scripting;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.io.*;
|
||||||
|
import helma.framework.*;
|
||||||
|
import helma.framework.core.*;
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
public class FunctionFile implements Updatable {
|
||||||
|
|
||||||
|
String name;
|
||||||
|
Prototype prototype;
|
||||||
|
Application app;
|
||||||
|
File file;
|
||||||
|
String content;
|
||||||
|
long lastmod;
|
||||||
|
|
||||||
|
// a set of funcion names defined by this file. We keep this to be able to
|
||||||
|
// remove them once the file should get removed
|
||||||
|
HashSet declaredProps;
|
||||||
|
long declaredPropsTimestamp;
|
||||||
|
|
||||||
|
public FunctionFile (File file, String name, Prototype proto) {
|
||||||
|
this.prototype = proto;
|
||||||
|
this.app = proto.getApplication ();
|
||||||
|
this.name = name;
|
||||||
|
this.file = file;
|
||||||
|
update ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
* by immediately parsing the code.
|
||||||
|
*/
|
||||||
|
public FunctionFile (String body, String name, Prototype proto) {
|
||||||
|
this.prototype = proto;
|
||||||
|
this.app = proto.getApplication ();
|
||||||
|
this.name = name;
|
||||||
|
this.file = null;
|
||||||
|
this.content = body;
|
||||||
|
|
||||||
|
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) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 ();
|
||||||
|
|
||||||
|
} 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) {
|
||||||
|
try {
|
||||||
|
FileReader fr = new FileReader (file);
|
||||||
|
EvaluationSource es = new FileEvaluationSource (file.getPath (), null);
|
||||||
|
updateRequestEvaluator (reval, fr, es);
|
||||||
|
} catch (Exception ignore) {}
|
||||||
|
} else {
|
||||||
|
StringReader reader = new StringReader (content);
|
||||||
|
StringEvaluationSource es = new StringEvaluationSource (content, null);
|
||||||
|
updateRequestEvaluator (reval, reader, es);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void updateRequestEvaluator (RequestEvaluator reval, Reader reader, EvaluationSource source) {
|
||||||
|
|
||||||
|
HashMap priorProps = null;
|
||||||
|
HashSet newProps = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
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 (Exception e) {
|
||||||
|
// app.logEvent ("Error parsing function file "+app.getName()+":"+prototype.getName()+"/"+file.getName()+": "+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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void remove () {
|
||||||
|
prototype.functions.remove (name);
|
||||||
|
prototype.updatables.remove (file.getName());
|
||||||
|
|
||||||
|
// if we did not add anything to any evaluator, we're done
|
||||||
|
if (declaredProps == null || declaredProps.size() == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
removeProperties (declaredProps);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the properties in the HashMap iff they're still the same as declared by this file.
|
||||||
|
* This method is called by remove() with the latest props, and by update with the prior props
|
||||||
|
* after the file has been reevaluated.
|
||||||
|
*/
|
||||||
|
void removeProperties (HashSet props) {
|
||||||
|
// first loop through other function files in this prototype to make a set of properties
|
||||||
|
// owned by other files.
|
||||||
|
HashSet otherFiles = new HashSet ();
|
||||||
|
for (Iterator it=prototype.functions.values ().iterator (); it.hasNext (); ) {
|
||||||
|
FunctionFile other = (FunctionFile) it.next ();
|
||||||
|
if (other != this && other.declaredProps != null)
|
||||||
|
otherFiles.addAll (other.declaredProps);
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator evals = app.typemgr.getRegisteredRequestEvaluators ();
|
||||||
|
while (evals.hasNext ()) {
|
||||||
|
try {
|
||||||
|
RequestEvaluator reval = (RequestEvaluator) evals.next ();
|
||||||
|
ObjectPrototype op = reval.getPrototype (prototype.getName());
|
||||||
|
for (Iterator it = props.iterator (); it.hasNext (); ) {
|
||||||
|
String fname = (String) it.next ();
|
||||||
|
// check if this property has been declared by some other function file in the meantime
|
||||||
|
if (otherFiles.contains (fname))
|
||||||
|
continue;
|
||||||
|
op.deleteProperty (fname, fname.hashCode());
|
||||||
|
// System.err.println ("REMOVING PROP: "+fname);
|
||||||
|
}
|
||||||
|
} catch (Exception ignore) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString () {
|
||||||
|
if (file == null)
|
||||||
|
return "[Zipped script file]";
|
||||||
|
else
|
||||||
|
return prototype.getName()+"/"+file.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
60
src/helma/scripting/ScriptingEnvironment.java
Normal file
60
src/helma/scripting/ScriptingEnvironment.java
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
// ScriptingEnvironment.java
|
||||||
|
// Copyright (c) Hannes Wallnöfer 1998-2001
|
||||||
|
|
||||||
|
package helma.scripting;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the interface that must be implemented to make a scripting environment
|
||||||
|
* usable by the Helma application server.
|
||||||
|
*/
|
||||||
|
public interface ScriptingEnvironment {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the environment using the given properties
|
||||||
|
*/
|
||||||
|
public void init (Properties props) throws ScriptingException;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invoke a function on some object, using the given arguments and global vars.
|
||||||
|
*/
|
||||||
|
public Object invoke (Object thisObject, Object[] args, HashMap globals) throws ScriptingException;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
52
src/helma/scripting/ScriptingException.java
Normal file
52
src/helma/scripting/ScriptingException.java
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
// ScriptingException.java
|
||||||
|
// Copyright (c) Hannes Wallnöfer 1998-2001
|
||||||
|
|
||||||
|
package helma.scripting;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The base class for exceptions thrown by Helma scripting package
|
||||||
|
*/
|
||||||
|
public class ScriptingException extends Exception {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a ScriptingException given an error message
|
||||||
|
*/
|
||||||
|
public ScriptingException (String msg) {
|
||||||
|
super (msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
257
src/helma/scripting/Template.java
Normal file
257
src/helma/scripting/Template.java
Normal file
|
@ -0,0 +1,257 @@
|
||||||
|
// Template.java
|
||||||
|
// Copyright (c) Hannes Wallnöfer 1998-2000
|
||||||
|
|
||||||
|
package helma.scripting;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.Vector;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
import helma.framework.*;
|
||||||
|
import helma.framework.core.*;
|
||||||
|
import FESI.Data.*;
|
||||||
|
import FESI.Exceptions.*;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
* as EcmaScript and parts that are to be delivered to the client as-is.
|
||||||
|
* Internally, templates are regular functions.
|
||||||
|
* 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
|
||||||
|
* now is to have a .hac file with all the logic which in turn calls one or more
|
||||||
|
* template files to do the formatting.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class Template extends Action {
|
||||||
|
|
||||||
|
// this is the *_as_string function, which is in addition to the normal one
|
||||||
|
TypeUpdater psfunc;
|
||||||
|
|
||||||
|
|
||||||
|
public Template (File file, String name, Prototype proto) {
|
||||||
|
super (file, name, proto);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void update (String content) throws Exception {
|
||||||
|
// IServer.getLogger().log ("Reading text template " + name);
|
||||||
|
|
||||||
|
Vector partBuffer = new Vector ();
|
||||||
|
int l = content.length ();
|
||||||
|
char cnt[] = new char[l];
|
||||||
|
content.getChars (0, l, cnt, 0);
|
||||||
|
|
||||||
|
// if last charackter is whitespace, swallow it. this is necessary for some inner templates to look ok.
|
||||||
|
if (Character.isWhitespace (cnt[l-1]))
|
||||||
|
l -= 1;
|
||||||
|
|
||||||
|
int lastIdx = 0;
|
||||||
|
for (int i = 0; i < l-1; i++) {
|
||||||
|
if (cnt[i] == '<' && cnt[i+1] == '%') {
|
||||||
|
int j = i+2;
|
||||||
|
while (j < l-1 && (cnt[j] != '%' || cnt[j+1] != '>')) {
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
if (j > i+2) {
|
||||||
|
if (i - lastIdx > 0)
|
||||||
|
partBuffer.addElement (new Part (this, new String (cnt, lastIdx, i - lastIdx), true));
|
||||||
|
String script = new String (cnt, i+2, (j-i)-2);
|
||||||
|
partBuffer.addElement (new Part (this, script, false));
|
||||||
|
lastIdx = j+2;
|
||||||
|
}
|
||||||
|
i = j+1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (lastIdx < l)
|
||||||
|
partBuffer.addElement (new Part (this, new String (cnt, lastIdx, l - lastIdx), true));
|
||||||
|
|
||||||
|
StringBuffer templateBody = new StringBuffer ();
|
||||||
|
int nparts = partBuffer.size();
|
||||||
|
|
||||||
|
for (int k = 0; k < nparts; k++) {
|
||||||
|
Part nextPart = (Part) partBuffer.elementAt (k);
|
||||||
|
|
||||||
|
if (nextPart.isStatic || nextPart.content.trim ().startsWith ("=")) {
|
||||||
|
// check for <%= ... %> statements
|
||||||
|
if (!nextPart.isStatic) {
|
||||||
|
nextPart.content = nextPart.content.trim ().substring (1).trim ();
|
||||||
|
// cut trailing ";"
|
||||||
|
while (nextPart.content.endsWith (";"))
|
||||||
|
nextPart.content = nextPart.content.substring (0, nextPart.content.length()-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
StringTokenizer st = new StringTokenizer (nextPart.content, "\r\n", true);
|
||||||
|
String nextLine = st.hasMoreTokens () ? st.nextToken () : null;
|
||||||
|
|
||||||
|
// count newLines we "swallow", see explanation below
|
||||||
|
int newLineCount = 0;
|
||||||
|
|
||||||
|
templateBody.append ("res.write (");
|
||||||
|
if (nextPart.isStatic) {
|
||||||
|
templateBody.append ("\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
while (nextLine != null) {
|
||||||
|
|
||||||
|
if ("\n".equals (nextLine)) {
|
||||||
|
// append a CRLF
|
||||||
|
newLineCount++;
|
||||||
|
templateBody.append ("\\r\\n");
|
||||||
|
} else if (!"\r".equals (nextLine)){
|
||||||
|
StringReader lineReader = new StringReader (nextLine);
|
||||||
|
int c = lineReader.read ();
|
||||||
|
while (c > -1) {
|
||||||
|
if (nextPart.isStatic && ((char)c == '"' || (char)c == '\\')) {
|
||||||
|
templateBody.append ('\\');
|
||||||
|
}
|
||||||
|
templateBody.append ((char) c);
|
||||||
|
c = lineReader.read ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nextLine = st.hasMoreTokens () ? st.nextToken () : null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextPart.isStatic) {
|
||||||
|
templateBody.append ("\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
templateBody.append ("); ");
|
||||||
|
|
||||||
|
// append the number of lines we have "swallowed" into
|
||||||
|
// one write statement, so error messages will *approximately*
|
||||||
|
// give correct line numbers.
|
||||||
|
for (int i=0; i<newLineCount; i++) {
|
||||||
|
templateBody.append ("\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
templateBody.append (nextPart.content);
|
||||||
|
if (!nextPart.content.trim ().endsWith (";")) {
|
||||||
|
templateBody.append (";");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// templateBody.append ("\r\nreturn null;\r\n");
|
||||||
|
|
||||||
|
functionName = name;
|
||||||
|
String fname = name+"_as_string";
|
||||||
|
String body = templateBody.toString ();
|
||||||
|
|
||||||
|
try {
|
||||||
|
pfunc = parseFunction (name,
|
||||||
|
"arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10",
|
||||||
|
body+"\r\nreturn null;\r\n");
|
||||||
|
} catch (Throwable x) {
|
||||||
|
String message = x.getMessage ();
|
||||||
|
pfunc = new ErrorFeedback (name, message);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
psfunc = parseFunction (fname,
|
||||||
|
"arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10",
|
||||||
|
"res.pushStringBuffer(); "+body+"\r\nreturn res.popStringBuffer();\r\n");
|
||||||
|
} catch (Throwable x) {
|
||||||
|
String message = x.getMessage ();
|
||||||
|
psfunc = new ErrorFeedback (fname, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator evals = app.typemgr.getRegisteredRequestEvaluators ();
|
||||||
|
while (evals.hasNext ()) {
|
||||||
|
try {
|
||||||
|
RequestEvaluator reval = (RequestEvaluator) evals.next ();
|
||||||
|
updateRequestEvaluator (reval);
|
||||||
|
} catch (Exception ignore) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void remove () {
|
||||||
|
prototype.templates.remove (name);
|
||||||
|
prototype.updatables.remove (file.getName());
|
||||||
|
|
||||||
|
Iterator evals = app.typemgr.getRegisteredRequestEvaluators ();
|
||||||
|
while (evals.hasNext ()) {
|
||||||
|
try {
|
||||||
|
RequestEvaluator reval = (RequestEvaluator) evals.next ();
|
||||||
|
ObjectPrototype op = reval.getPrototype (prototype.getName());
|
||||||
|
functionName = name;
|
||||||
|
ESValue esv = (ESValue) op.getProperty (functionName, functionName.hashCode());
|
||||||
|
if (esv instanceof ConstructedFunctionObject || esv instanceof ThrowException) {
|
||||||
|
op.deleteProperty (functionName, functionName.hashCode());
|
||||||
|
}
|
||||||
|
String fname = name+"_as_string";
|
||||||
|
esv = (ESValue) op.getProperty (fname, fname.hashCode());
|
||||||
|
if (esv instanceof ConstructedFunctionObject || esv instanceof ThrowException) {
|
||||||
|
op.deleteProperty (fname, fname.hashCode());
|
||||||
|
}
|
||||||
|
} catch (Exception ignore) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public synchronized void updateRequestEvaluator (RequestEvaluator reval) throws EcmaScriptException {
|
||||||
|
if (pfunc != null)
|
||||||
|
pfunc.updateRequestEvaluator (reval);
|
||||||
|
if (psfunc != null)
|
||||||
|
psfunc.updateRequestEvaluator (reval);
|
||||||
|
}
|
||||||
|
|
||||||
|
class Part {
|
||||||
|
|
||||||
|
String content;
|
||||||
|
Template parent;
|
||||||
|
boolean isPart;
|
||||||
|
boolean isStatic;
|
||||||
|
|
||||||
|
|
||||||
|
public Part (Template parent, String content, boolean isStatic) {
|
||||||
|
isPart = false;
|
||||||
|
this.parent = parent;
|
||||||
|
this.content = content;
|
||||||
|
this.isStatic = isStatic;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName () {
|
||||||
|
return isStatic ? null : content;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String toString () {
|
||||||
|
return "Template.Part ["+content+","+isStatic+"]";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
138
src/helma/scripting/fesi/ESAppNode.java
Normal file
138
src/helma/scripting/fesi/ESAppNode.java
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
// ESAppNode.java
|
||||||
|
// Copyright (c) Hannes Wallnöfer 1998-2000
|
||||||
|
|
||||||
|
package helma.scripting.fesi;
|
||||||
|
|
||||||
|
import helma.framework.core.*;
|
||||||
|
import helma.objectmodel.*;
|
||||||
|
import FESI.Exceptions.*;
|
||||||
|
import FESI.Data.*;
|
||||||
|
import FESI.Interpreter.Evaluator;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ESApp represents the app node of an application, providing an app-wide transient shared
|
||||||
|
* space as well as access to some app related runtime information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class ESAppNode extends ESNode {
|
||||||
|
|
||||||
|
private Application app;
|
||||||
|
private DatePrototype createtime;
|
||||||
|
|
||||||
|
public ESAppNode (INode node, RequestEvaluator eval) throws EcmaScriptException {
|
||||||
|
super (eval.esNodePrototype, eval.evaluator, node, eval);
|
||||||
|
app = eval.app;
|
||||||
|
createtime = new DatePrototype (eval.evaluator, node.created());
|
||||||
|
/* FunctionPrototype fp = (FunctionPrototype) eval.evaluator.getFunctionPrototype();
|
||||||
|
putHiddenProperty("getThreads", new AppCountThreads ("getThreads", evaluator, fp));
|
||||||
|
putHiddenProperty("getMaxThreads", new AppCountMaxThreads ("getMaxThreads", evaluator, fp));
|
||||||
|
putHiddenProperty("getFreeThreads", new AppCountFreeEvaluators ("getFreeThreads", evaluator, fp));
|
||||||
|
putHiddenProperty("getActiveThreads", new AppCountActiveEvaluators ("getActiveThreads", evaluator, fp));
|
||||||
|
putHiddenProperty("getMaxActiveThreads", new AppCountMaxActiveEvaluators ("getMaxActiveThreads", evaluator, fp));
|
||||||
|
putHiddenProperty("setMaxThreads", new AppSetNumberOfEvaluators ("setMaxThreads", evaluator, fp)); */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overrides getProperty to return some app-specific properties
|
||||||
|
*/
|
||||||
|
public ESValue getProperty (String propname, int hash) throws EcmaScriptException {
|
||||||
|
/* if ("requestCount".equals (propname)) {
|
||||||
|
return new ESNumber (app.requestCount);
|
||||||
|
}
|
||||||
|
if ("xmlrpcCount".equals (propname)) {
|
||||||
|
return new ESNumber (app.xmlrpcCount);
|
||||||
|
}
|
||||||
|
if ("errorCount".equals (propname)) {
|
||||||
|
return new ESNumber (app.errorCount);
|
||||||
|
}
|
||||||
|
if ("upSince".equals (propname)) {
|
||||||
|
return createtime;
|
||||||
|
}
|
||||||
|
if ("skinfiles".equals (propname)) {
|
||||||
|
ESObject skinz = new ObjectPrototype (null, evaluator);
|
||||||
|
for (Iterator it = app.typemgr.prototypes.values().iterator(); it.hasNext(); ) {
|
||||||
|
Prototype p = (Prototype) it.next ();
|
||||||
|
ESObject proto = new ObjectPrototype (null, evaluator);
|
||||||
|
for (Iterator it2 = p.skins.values().iterator(); it2.hasNext(); ) {
|
||||||
|
SkinFile sf = (SkinFile) it2.next ();
|
||||||
|
String name = sf.getName ();
|
||||||
|
Skin skin = sf.getSkin ();
|
||||||
|
proto.putProperty (name, new ESString (skin.getSource ()), name.hashCode ());
|
||||||
|
}
|
||||||
|
skinz.putProperty (p.getName (), proto, p.getName ().hashCode ());
|
||||||
|
}
|
||||||
|
return skinz;
|
||||||
|
} */
|
||||||
|
if ("__app__".equals (propname)) {
|
||||||
|
return new ESWrapper (app, evaluator);
|
||||||
|
}
|
||||||
|
return super.getProperty (propname, hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* class AppCountEvaluators extends BuiltinFunctionObject {
|
||||||
|
AppCountEvaluators (String name, Evaluator evaluator, FunctionPrototype fp) {
|
||||||
|
super (fp, evaluator, name, 0);
|
||||||
|
}
|
||||||
|
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
|
||||||
|
return new ESNumber (app.allThreads.size()-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class AppCountFreeEvaluators extends BuiltinFunctionObject {
|
||||||
|
AppCountFreeEvaluators (String name, Evaluator evaluator, FunctionPrototype fp) {
|
||||||
|
super (fp, evaluator, name, 0);
|
||||||
|
}
|
||||||
|
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
|
||||||
|
return new ESNumber (app.freeThreads.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class AppCountActiveEvaluators extends BuiltinFunctionObject {
|
||||||
|
AppCountBusyEvaluators (String name, Evaluator evaluator, FunctionPrototype fp) {
|
||||||
|
super (fp, evaluator, name, 0);
|
||||||
|
}
|
||||||
|
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
|
||||||
|
return new ESNumber (app.allThreads.size() - app.freeThreads.size() -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class AppCountMaxActiveEvaluators extends BuiltinFunctionObject {
|
||||||
|
AppCountMaxActiveEvaluators (String name, Evaluator evaluator, FunctionPrototype fp) {
|
||||||
|
super (fp, evaluator, name, 0);
|
||||||
|
}
|
||||||
|
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
|
||||||
|
return new ESNumber (app.typemgr.countRegisteredRequestEvaluators () -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class AppCountThreads extends BuiltinFunctionObject {
|
||||||
|
AppCountThreads (String name, Evaluator evaluator, FunctionPrototype fp) {
|
||||||
|
super (fp, evaluator, name, 0);
|
||||||
|
}
|
||||||
|
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
|
||||||
|
return new ESNumber (app.threadgroup.activeCount() -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class AppSetNumberOfEvaluators extends BuiltinFunctionObject {
|
||||||
|
AppSetNumberOfEvaluators (String name, Evaluator evaluator, FunctionPrototype fp) {
|
||||||
|
super (fp, evaluator, name, 1);
|
||||||
|
}
|
||||||
|
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
|
||||||
|
RequestEvaluator ev = new RequestEvaluator (app);
|
||||||
|
if (arguments.length != 1)
|
||||||
|
return ESBoolean.makeBoolean (false);
|
||||||
|
return ESBoolean.makeBoolean (app.setNumberOfEvaluators (1 + arguments[0].toInt32()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
public String toString () {
|
||||||
|
return ("AppNode "+node.getElementName ());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
160
src/helma/scripting/fesi/ESGenericObject.java
Normal file
160
src/helma/scripting/fesi/ESGenericObject.java
Normal file
|
@ -0,0 +1,160 @@
|
||||||
|
// ESGenericObject.java
|
||||||
|
// Copyright (c) Hannes Wallnöfer 1998-2000
|
||||||
|
|
||||||
|
|
||||||
|
package helma.scripting.fesi;
|
||||||
|
|
||||||
|
import helma.framework.core.*;
|
||||||
|
import helma.framework.IPathElement;
|
||||||
|
import FESI.Interpreter.*;
|
||||||
|
import FESI.Exceptions.*;
|
||||||
|
import FESI.Data.*;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class ESGenericObject extends ObjectPrototype {
|
||||||
|
|
||||||
|
ESWrapper wrapper;
|
||||||
|
IPathElement pathObj;
|
||||||
|
|
||||||
|
public ESGenericObject (ESObject prototype, Evaluator evaluator, IPathElement obj) {
|
||||||
|
super (prototype, evaluator);
|
||||||
|
pathObj = obj;
|
||||||
|
wrapper = new ESWrapper (obj, evaluator);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getESClassName () {
|
||||||
|
return "GenericObject";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString () {
|
||||||
|
return pathObj.toString ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toDetailString () {
|
||||||
|
return wrapper.toDetailString ();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void putProperty(String propertyName, ESValue propertyValue, int hash) throws EcmaScriptException {
|
||||||
|
wrapper.putProperty (propertyName, propertyValue, hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasProperty(String propertyName, int hash) throws EcmaScriptException {
|
||||||
|
return super.hasProperty (propertyName, hash) || wrapper.hasProperty (propertyName, hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean deleteProperty(String propertyName, int hash) throws EcmaScriptException {
|
||||||
|
return wrapper.deleteProperty (propertyName, hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ESValue getProperty (int i) throws EcmaScriptException {
|
||||||
|
return wrapper.getProperty (i);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void putProperty(int index, ESValue propertyValue) throws EcmaScriptException {
|
||||||
|
wrapper.putProperty (index, propertyValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public ESValue getProperty(String propertyName, int hash) throws EcmaScriptException {
|
||||||
|
ESValue val = super.getProperty (propertyName, hash);
|
||||||
|
if (val == null || val == ESUndefined.theUndefined)
|
||||||
|
val = wrapper.getProperty (propertyName, hash);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ESValue doIndirectCall(Evaluator evaluator, ESObject thisObject, String functionName, ESValue[] arguments)
|
||||||
|
throws EcmaScriptException, NoSuchMethodException {
|
||||||
|
if (super.hasProperty (functionName, functionName.hashCode()))
|
||||||
|
return super.doIndirectCall (evaluator, thisObject, functionName, arguments);
|
||||||
|
return wrapper.doIndirectCall (evaluator, thisObject, functionName, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Enumeration getAllProperties () {
|
||||||
|
return wrapper.getProperties ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Enumeration getProperties () {
|
||||||
|
return wrapper.getProperties ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object toJavaObject () {
|
||||||
|
return pathObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An ESNode equals another object if it is an ESNode that wraps the same INode
|
||||||
|
* or the wrapped INode itself. FIXME: doesen't check dbmapping/type!
|
||||||
|
*/
|
||||||
|
public boolean equals (Object what) {
|
||||||
|
if (what == null)
|
||||||
|
return false;
|
||||||
|
if (what == this)
|
||||||
|
return true;
|
||||||
|
if (what instanceof ESGenericObject) {
|
||||||
|
ESGenericObject other = (ESGenericObject) what;
|
||||||
|
return (pathObj.equals (other.pathObj));
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
517
src/helma/scripting/fesi/ESNode.java
Normal file
517
src/helma/scripting/fesi/ESNode.java
Normal file
|
@ -0,0 +1,517 @@
|
||||||
|
// ESNode.java
|
||||||
|
// Copyright (c) Hannes Wallnöfer 1998-2000
|
||||||
|
|
||||||
|
|
||||||
|
package helma.scripting.fesi;
|
||||||
|
|
||||||
|
import helma.objectmodel.*;
|
||||||
|
import helma.objectmodel.db.*;
|
||||||
|
import helma.framework.core.*;
|
||||||
|
import helma.util.*;
|
||||||
|
import FESI.Interpreter.*;
|
||||||
|
import FESI.Exceptions.*;
|
||||||
|
import FESI.Data.*;
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An EcmaScript wrapper around a 'Node' object. This is the basic
|
||||||
|
* HOP object type that can be stored in the internal or external databases.
|
||||||
|
* All HOP types inherit from the Node object.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class ESNode extends ObjectPrototype {
|
||||||
|
|
||||||
|
INode node;
|
||||||
|
|
||||||
|
// the cache node - persistent nodes have a transient property as a commodity to
|
||||||
|
// store temporary stuff.
|
||||||
|
INode cache;
|
||||||
|
// the ecmascript wrapper for the cache.
|
||||||
|
ESObject cacheWrapper;
|
||||||
|
|
||||||
|
// The handle of the wrapped Node. Makes ESNodes comparable without accessing the wrapped node.
|
||||||
|
NodeHandle handle;
|
||||||
|
DbMapping dbmap;
|
||||||
|
Throwable lastError = null;
|
||||||
|
RequestEvaluator eval;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor used to create transient cache nodes
|
||||||
|
*/
|
||||||
|
public ESNode (INode node, RequestEvaluator eval) {
|
||||||
|
super (eval.esNodePrototype, eval.evaluator);
|
||||||
|
this.eval = eval;
|
||||||
|
this.node = node;
|
||||||
|
cache = null;
|
||||||
|
cacheWrapper = null;
|
||||||
|
|
||||||
|
// this is a transient node, set node handle to null
|
||||||
|
handle = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ESNode (ESObject prototype, Evaluator evaluator, Object obj, RequestEvaluator eval) {
|
||||||
|
super (prototype, evaluator);
|
||||||
|
// eval.app.logEvent ("in ESNode constructor: "+o.getClass ());
|
||||||
|
this.eval = eval;
|
||||||
|
if (obj == null)
|
||||||
|
node = new TransientNode (null);
|
||||||
|
else if (obj instanceof ESWrapper)
|
||||||
|
node = (INode) ((ESWrapper) obj).getJavaObject ();
|
||||||
|
else if (obj instanceof INode)
|
||||||
|
node = (INode) obj;
|
||||||
|
else
|
||||||
|
node = new TransientNode (obj.toString ());
|
||||||
|
// set node handle to wrapped node
|
||||||
|
if (node instanceof Node)
|
||||||
|
handle = ((Node) node).getHandle ();
|
||||||
|
else
|
||||||
|
handle = null;
|
||||||
|
|
||||||
|
// cache Node is initialized on demend when it is needed
|
||||||
|
cache = null;
|
||||||
|
cacheWrapper = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the node has been invalidated. If so, it has to be re-fetched
|
||||||
|
* from the db via the app's node manager.
|
||||||
|
*/
|
||||||
|
protected void checkNode () {
|
||||||
|
if (node.getState () == INode.INVALID) try {
|
||||||
|
node = handle.getNode (eval.app.getWrappedNodeManager ());
|
||||||
|
} catch (Exception nx) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
public INode getNode () {
|
||||||
|
checkNode ();
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* public void setNode (INode node) {
|
||||||
|
if (node != null) {
|
||||||
|
this.node = node;
|
||||||
|
// set node handle to wrapped node
|
||||||
|
if (node instanceof helma.objectmodel.db.Node)
|
||||||
|
handle = ((helma.objectmodel.db.Node) node).getHandle ();
|
||||||
|
else
|
||||||
|
handle = null;
|
||||||
|
eval.objectcache.put (node, this);
|
||||||
|
// reset cache Node - will be reinitialized when needed
|
||||||
|
cache = null;
|
||||||
|
cacheWrapper = null;
|
||||||
|
}
|
||||||
|
} */
|
||||||
|
|
||||||
|
public void setPrototype (String protoName) {
|
||||||
|
checkNode ();
|
||||||
|
node.setPrototype (protoName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPrototypeName () {
|
||||||
|
return node.getPrototype ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getESClassName () {
|
||||||
|
return "HopObject";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString () {
|
||||||
|
if (node == null)
|
||||||
|
return "<null>";
|
||||||
|
return node.toString ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toDetailString () {
|
||||||
|
return "ES:[Object: builtin " + this.getClass().getName() + ":" +
|
||||||
|
((node == null) ? "null" : node.toString()) + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setError (Throwable e) {
|
||||||
|
lastError = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean add (ESValue what[]) {
|
||||||
|
checkNode ();
|
||||||
|
for (int i=0; i<what.length; i++)
|
||||||
|
if (what[i] instanceof ESNode) {
|
||||||
|
ESNode esn = (ESNode) what[i];
|
||||||
|
INode added = node.addNode (esn.getNode ());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ESValue list () {
|
||||||
|
checkNode ();
|
||||||
|
int l = node.numberOfNodes ();
|
||||||
|
Enumeration e = node.getSubnodes ();
|
||||||
|
ESObject ap = evaluator.getArrayPrototype();
|
||||||
|
ArrayPrototype theArray = new ArrayPrototype(ap, evaluator);
|
||||||
|
if (e != null) {
|
||||||
|
theArray.setSize(l);
|
||||||
|
for (int i = 0; i<l; i++) {
|
||||||
|
theArray.setElementAt (eval.getNodeWrapper ((INode) e.nextElement ()), i);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
theArray.setSize (0);
|
||||||
|
}
|
||||||
|
return theArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean addAt (ESValue what[]) throws EcmaScriptException {
|
||||||
|
checkNode ();
|
||||||
|
if (what.length < 2)
|
||||||
|
throw new EcmaScriptException ("Wrong number of arguments");
|
||||||
|
if (! (what[1] instanceof ESNode))
|
||||||
|
throw new EcmaScriptException ("Can ony add Node objects as subnodes");
|
||||||
|
ESNode esn = (ESNode) what[1];
|
||||||
|
INode added = node.addNode (esn.getNode (), (int) what[0].toInt32 ());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove one or more subnodes.
|
||||||
|
*/
|
||||||
|
public boolean remove (ESValue args[]) {
|
||||||
|
checkNode ();
|
||||||
|
for (int i=0; i<args.length; i++) {
|
||||||
|
if (args[i] instanceof ESNode) {
|
||||||
|
ESNode esn = (ESNode) args[i];
|
||||||
|
node.removeNode (esn.getNode ());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if node is contained in subnodes
|
||||||
|
*/
|
||||||
|
public int contains (ESValue args[]) {
|
||||||
|
checkNode ();
|
||||||
|
if (args.length == 1 && args[0] instanceof ESNode) {
|
||||||
|
ESNode esn = (ESNode) args[0];
|
||||||
|
return node.contains (esn.getNode ());
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This used to be different from add(), it isn't anymore. It's left here for
|
||||||
|
* compatibility.
|
||||||
|
*/
|
||||||
|
public boolean link (ESValue args[]) {
|
||||||
|
checkNode ();
|
||||||
|
for (int i=0; i<args.length; i++) {
|
||||||
|
if (args[i] instanceof ESNode) {
|
||||||
|
ESNode esn = (ESNode) args[i];
|
||||||
|
node.addNode (esn.getNode ());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean setParent (ESValue[] pval) {
|
||||||
|
// do a couple of checks: both nodes need to be persistent in order for setParent to make sense.
|
||||||
|
if (!(node instanceof helma.objectmodel.db.Node))
|
||||||
|
return false;
|
||||||
|
if (pval == null || pval.length < 1 || pval.length > 2)
|
||||||
|
return false;
|
||||||
|
if (!(pval[0] instanceof ESNode))
|
||||||
|
return false;
|
||||||
|
ESNode esn = (ESNode) pval[0];
|
||||||
|
INode pn = esn.getNode ();
|
||||||
|
if (!(pn instanceof helma.objectmodel.db.Node))
|
||||||
|
return false;
|
||||||
|
// check if there is an additional string element - if so, it's the property name by which the node is
|
||||||
|
// accessed, otherwise it will be accessed as anonymous subnode via its id
|
||||||
|
String propname = null;
|
||||||
|
if (pval.length == 2 && pval[1] != null && !(pval[1] instanceof ESNull))
|
||||||
|
propname = pval[1].toString ();
|
||||||
|
helma.objectmodel.db.Node n = (helma.objectmodel.db.Node) node;
|
||||||
|
n.setParent ((helma.objectmodel.db.Node) pn, propname);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void putProperty(String propertyName, ESValue propertyValue, int hash) throws EcmaScriptException {
|
||||||
|
checkNode ();
|
||||||
|
// eval.app.logEvent ("put property called: "+propertyName+", "+propertyValue.getClass());
|
||||||
|
if (/* "lastmodified".equalsIgnoreCase (propertyName) || "created".equalsIgnoreCase (propertyName) || */
|
||||||
|
"cache".equalsIgnoreCase (propertyName))
|
||||||
|
throw new EcmaScriptException ("Can't modify read-only property \""+propertyName+"\".");
|
||||||
|
|
||||||
|
if ("subnodeRelation".equalsIgnoreCase (propertyName)) {
|
||||||
|
node.setSubnodeRelation (propertyValue instanceof ESNull ? null : propertyValue.toString ());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (propertyValue instanceof ESNull)
|
||||||
|
node.unset (propertyName);
|
||||||
|
else if (propertyValue instanceof ESString)
|
||||||
|
node.setString (propertyName, propertyValue.toString ());
|
||||||
|
else if (propertyValue instanceof ESBoolean)
|
||||||
|
node.setBoolean (propertyName, propertyValue.booleanValue ());
|
||||||
|
else if (propertyValue instanceof ESNumber)
|
||||||
|
node.setFloat (propertyName, propertyValue.doubleValue ());
|
||||||
|
else if (propertyValue instanceof DatePrototype)
|
||||||
|
node.setDate (propertyName, (Date) propertyValue.toJavaObject ());
|
||||||
|
else if (propertyValue instanceof ESNode) {
|
||||||
|
// long now = System.currentTimeMillis ();
|
||||||
|
ESNode esn = (ESNode) propertyValue;
|
||||||
|
node.setNode (propertyName, esn.getNode ());
|
||||||
|
// eval.app.logEvent ("*** spent "+(System.currentTimeMillis () - now)+" ms to set property "+propertyName);
|
||||||
|
} else {
|
||||||
|
// eval.app.logEvent ("got "+propertyValue.getClass ());
|
||||||
|
// A persistent node can't store anything other than the types above, so throw an exception
|
||||||
|
// throw new EcmaScriptException ("Can't set a JavaScript Object or Array as property of "+node);
|
||||||
|
node.setJavaObject (propertyName, propertyValue.toJavaObject ());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean deleteProperty(String propertyName, int hash) throws EcmaScriptException {
|
||||||
|
checkNode ();
|
||||||
|
// eval.app.logEvent ("delete property called: "+propertyName);
|
||||||
|
if (node.get (propertyName, false) != null) {
|
||||||
|
node.unset (propertyName);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return super.deleteProperty (propertyName, hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ESValue getProperty (int i) throws EcmaScriptException {
|
||||||
|
checkNode ();
|
||||||
|
INode n = node.getSubnodeAt (i);
|
||||||
|
if (n == null)
|
||||||
|
return ESNull.theNull;
|
||||||
|
return eval.getNodeWrapper (n);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void putProperty(int index, ESValue propertyValue) throws EcmaScriptException {
|
||||||
|
checkNode ();
|
||||||
|
if (propertyValue instanceof ESNode) {
|
||||||
|
ESNode n = (ESNode) propertyValue;
|
||||||
|
node.addNode (n.getNode (), index);
|
||||||
|
} else
|
||||||
|
throw new EcmaScriptException ("Can only add Nodes to Node arrays");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public ESValue getProperty(String propertyName, int hash) throws EcmaScriptException {
|
||||||
|
checkNode ();
|
||||||
|
// eval.app.logEvent ("get property called: "+propertyName);
|
||||||
|
ESValue retval = super.getProperty (propertyName, hash);
|
||||||
|
if (! (retval instanceof ESUndefined))
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
// persistent or persistent capable nodes have a cache property that's a transient node.
|
||||||
|
// it it hasn't requested before, initialize it now
|
||||||
|
if ("cache".equalsIgnoreCase (propertyName) && node instanceof Node) {
|
||||||
|
if (cacheWrapper == null) {
|
||||||
|
cache = node.getCacheNode ();
|
||||||
|
cacheWrapper = new ESNode (cache, eval);
|
||||||
|
}
|
||||||
|
return cacheWrapper;
|
||||||
|
}
|
||||||
|
if ("subnodeRelation".equalsIgnoreCase (propertyName)) {
|
||||||
|
String rel = node.getSubnodeRelation ();
|
||||||
|
return rel == null ? (ESValue) ESNull.theNull : new ESString (rel);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("_id".equals (propertyName))
|
||||||
|
return new ESString (node.getID ());
|
||||||
|
if ("_parent".equals (propertyName)) {
|
||||||
|
INode n = node.getParent ();
|
||||||
|
if (n != null)
|
||||||
|
return eval.getNodeWrapper (n);
|
||||||
|
else
|
||||||
|
return ESNull.theNull;
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is not very nice, but as a hack we return the id of a node as node.__id__
|
||||||
|
if (propertyName.startsWith ("__") && propertyName.endsWith ("__"))
|
||||||
|
return getInternalProperty (propertyName);
|
||||||
|
|
||||||
|
// this _may_ do a relational query if properties are mapped to a relational type.
|
||||||
|
IProperty p = node.get (propertyName, false);
|
||||||
|
if (p != null) {
|
||||||
|
if (p.getType () == IProperty.STRING) {
|
||||||
|
String str = p.getStringValue ();
|
||||||
|
if (str == null)
|
||||||
|
return ESNull.theNull;
|
||||||
|
else
|
||||||
|
return new ESString (str);
|
||||||
|
}
|
||||||
|
if (p.getType () == IProperty.BOOLEAN)
|
||||||
|
return ESBoolean.makeBoolean (p.getBooleanValue ());
|
||||||
|
if (p.getType () == IProperty.DATE)
|
||||||
|
return new DatePrototype (evaluator, p.getDateValue ());
|
||||||
|
if (p.getType () == IProperty.INTEGER)
|
||||||
|
return new ESNumber ((double) p.getIntegerValue ());
|
||||||
|
if (p.getType () == IProperty.FLOAT)
|
||||||
|
return new ESNumber (p.getFloatValue ());
|
||||||
|
if (p.getType () == IProperty.NODE) {
|
||||||
|
INode nd = p.getNodeValue ();
|
||||||
|
if (nd == null)
|
||||||
|
return ESNull.theNull;
|
||||||
|
else
|
||||||
|
return eval.getNodeWrapper (nd);
|
||||||
|
}
|
||||||
|
if (p.getType () == IProperty.JAVAOBJECT)
|
||||||
|
return ESLoader.normalizeObject (p.getJavaObjectValue (), evaluator);
|
||||||
|
}
|
||||||
|
|
||||||
|
// these are predefined
|
||||||
|
// if ("created".equalsIgnoreCase (propertyName))
|
||||||
|
// return new DatePrototype (evaluator, node.created ());
|
||||||
|
// if ("lastmodified".equalsIgnoreCase (propertyName))
|
||||||
|
// return new DatePrototype (evaluator, node.lastModified ());
|
||||||
|
|
||||||
|
// as last resort, try to get property as anonymous subnode
|
||||||
|
INode anon = node.getSubnode (propertyName);
|
||||||
|
if (anon != null)
|
||||||
|
return eval.getNodeWrapper (anon);
|
||||||
|
|
||||||
|
return ESNull.theNull;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ESValue getInternalProperty (String propertyName) throws EcmaScriptException {
|
||||||
|
if ("__id__".equalsIgnoreCase (propertyName)) {
|
||||||
|
return new ESString (node.getID ());
|
||||||
|
}
|
||||||
|
if ("__prototype__".equalsIgnoreCase (propertyName)) {
|
||||||
|
String p = node.getPrototype ();
|
||||||
|
if (p == null)
|
||||||
|
return ESNull.theNull;
|
||||||
|
else
|
||||||
|
return new ESString (node.getPrototype ());
|
||||||
|
}
|
||||||
|
// some more internal properties
|
||||||
|
if ("__parent__".equals (propertyName)) {
|
||||||
|
INode n = node.getParent ();
|
||||||
|
if (n == null)
|
||||||
|
return ESNull.theNull;
|
||||||
|
else
|
||||||
|
return eval.getNodeWrapper (n);
|
||||||
|
}
|
||||||
|
if ("__name__".equals (propertyName))
|
||||||
|
return new ESString (node.getName ());
|
||||||
|
if ("__fullname__".equals (propertyName))
|
||||||
|
return new ESString (node.getFullName ());
|
||||||
|
if ("__hash__".equals (propertyName))
|
||||||
|
return new ESString (""+node.hashCode ());
|
||||||
|
if ("__node__".equals (propertyName))
|
||||||
|
return new ESWrapper (node, evaluator);
|
||||||
|
if ("__created__".equalsIgnoreCase (propertyName))
|
||||||
|
return new DatePrototype (evaluator, node.created ());
|
||||||
|
if ("__lastmodified__".equalsIgnoreCase (propertyName))
|
||||||
|
return new DatePrototype (evaluator, node.lastModified ());
|
||||||
|
|
||||||
|
return ESNull.theNull;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Enumeration getAllProperties () {
|
||||||
|
return getProperties ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Enumeration getProperties () {
|
||||||
|
checkNode ();
|
||||||
|
return node.properties ();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String error() {
|
||||||
|
if (lastError == null) {
|
||||||
|
return "";
|
||||||
|
} else {
|
||||||
|
String exceptionName = lastError.getClass().getName();
|
||||||
|
int l = exceptionName.lastIndexOf(".");
|
||||||
|
if (l>0) exceptionName = exceptionName.substring(l+1);
|
||||||
|
return exceptionName +": " + lastError.getMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearError() {
|
||||||
|
lastError = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object toJavaObject () {
|
||||||
|
return getNode ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An ESNode equals another object if it is an ESNode that wraps the same INode
|
||||||
|
* or the wrapped INode itself. FIXME: doesen't check dbmapping/type!
|
||||||
|
*/
|
||||||
|
public boolean equals (Object what) {
|
||||||
|
if (what == null)
|
||||||
|
return false;
|
||||||
|
if (what == this)
|
||||||
|
return true;
|
||||||
|
if (what instanceof ESNode) {
|
||||||
|
ESNode other = (ESNode) what;
|
||||||
|
if (handle != null)
|
||||||
|
return handle.equals (other.handle);
|
||||||
|
else
|
||||||
|
return (node == other.node);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // class ESNode
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
129
src/helma/scripting/fesi/ESRequestData.java
Normal file
129
src/helma/scripting/fesi/ESRequestData.java
Normal file
|
@ -0,0 +1,129 @@
|
||||||
|
// ESRequestData.java
|
||||||
|
// Copyright (c) Hannes Wallnöfer 1998-2000
|
||||||
|
|
||||||
|
|
||||||
|
package helma.scripting.fesi;
|
||||||
|
|
||||||
|
import helma.framework.core.*;
|
||||||
|
import helma.objectmodel.INode;
|
||||||
|
import FESI.Data.*;
|
||||||
|
import FESI.Exceptions.*;
|
||||||
|
import FESI.Interpreter.Evaluator;
|
||||||
|
import java.util.Hashtable;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An EcmaScript object that makes stuff in a hashtable accessible as its properties
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class ESRequestData extends ESWrapper {
|
||||||
|
|
||||||
|
private Hashtable data;
|
||||||
|
private RequestEvaluator reval;
|
||||||
|
|
||||||
|
public ESRequestData (RequestEvaluator reval) {
|
||||||
|
super (new Object(), reval.evaluator);
|
||||||
|
this.reval = reval;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setData (Hashtable data) {
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overridden to make the object read-only
|
||||||
|
*/
|
||||||
|
public void putProperty(String propertyName, ESValue propertyValue, int hash) throws EcmaScriptException {
|
||||||
|
throw new EcmaScriptException ("Can't set property, object is read-only");
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean deleteProperty(String propertyName, int hash) throws EcmaScriptException {
|
||||||
|
throw new EcmaScriptException ("Can't delete property, object is read-only");
|
||||||
|
}
|
||||||
|
|
||||||
|
public ESValue getProperty(String propertyName, int hash) throws EcmaScriptException {
|
||||||
|
if (data == null)
|
||||||
|
return ESNull.theNull;
|
||||||
|
|
||||||
|
Object val = data.get (propertyName);
|
||||||
|
|
||||||
|
if (val == null)
|
||||||
|
return ESNull.theNull;
|
||||||
|
|
||||||
|
if (val instanceof String)
|
||||||
|
return new ESString ((String) val);
|
||||||
|
else if (val instanceof INode)
|
||||||
|
return reval.getNodeWrapper ((INode) val);
|
||||||
|
|
||||||
|
return ESLoader.normalizeValue(val, evaluator);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Enumeration getAllProperties () {
|
||||||
|
return getProperties ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Enumeration getProperties () {
|
||||||
|
if (data == null)
|
||||||
|
return new Hashtable().keys();
|
||||||
|
return data.keys();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
141
src/helma/scripting/fesi/ESUser.java
Normal file
141
src/helma/scripting/fesi/ESUser.java
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
// ESUser.java
|
||||||
|
// Copyright (c) Hannes Wallnöfer 1998-2000
|
||||||
|
|
||||||
|
package helma.scripting.fesi;
|
||||||
|
|
||||||
|
import helma.framework.core.*;
|
||||||
|
import helma.objectmodel.*;
|
||||||
|
import FESI.Interpreter.*;
|
||||||
|
import FESI.Exceptions.*;
|
||||||
|
import FESI.Data.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The ESUser is a special kind of Node object that represents a user of
|
||||||
|
* a HOP application. The actual user session data are kept in class User.
|
||||||
|
* If the user is logged in as a registered member, the wrapped node represents
|
||||||
|
* the user object in the database, while for anonymous surfers the node object
|
||||||
|
* is just a transient node. <p>
|
||||||
|
* This means that the wrapped node will be swapped when the user logs in or out.
|
||||||
|
* To save session state across logins and logouts, the
|
||||||
|
* cache property of the user object stays the same for the whole time the user
|
||||||
|
* spends on this site.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class ESUser extends ESNode {
|
||||||
|
|
||||||
|
/** if the user is online, this is his/her online session object */
|
||||||
|
public User user;
|
||||||
|
|
||||||
|
public ESUser (INode node, RequestEvaluator eval, User user) {
|
||||||
|
super (eval.esUserPrototype, eval.evaluator, node, eval);
|
||||||
|
this.user = user;
|
||||||
|
if (user != null) {
|
||||||
|
cache = user.getCache ();
|
||||||
|
cacheWrapper = new ESNode (cache, eval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overrides getProperty to return the uid (which is not a regular property)
|
||||||
|
*/
|
||||||
|
public ESValue getProperty (String propname, int hash) throws EcmaScriptException {
|
||||||
|
if ("uid".equals (propname)) {
|
||||||
|
if (user == null || user.getUID () == null)
|
||||||
|
return ESNull.theNull;
|
||||||
|
else
|
||||||
|
return new ESString (user.getUID ());
|
||||||
|
}
|
||||||
|
if ("sessionID".equals (propname)) {
|
||||||
|
if (user == null || user.getSessionID () == null)
|
||||||
|
return ESNull.theNull;
|
||||||
|
else
|
||||||
|
return new ESString (user.getSessionID ());
|
||||||
|
}
|
||||||
|
if ("cache".equals (propname))
|
||||||
|
return cacheWrapper;
|
||||||
|
return super.getProperty (propname, hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The node for a user object changes at login and logout, so we don't use our
|
||||||
|
* own node, but just reach through to the session user object instead.
|
||||||
|
*/
|
||||||
|
public void setNode (INode node) {
|
||||||
|
user.setNode (node);
|
||||||
|
if (node != null) {
|
||||||
|
this.node = node;
|
||||||
|
} else {
|
||||||
|
// user.getNode will never return null. If the node is set to null (=user logged out)
|
||||||
|
// it will user the original transient cache node again.
|
||||||
|
this.node = user.getNode ();
|
||||||
|
}
|
||||||
|
// set node handle to wrapped node
|
||||||
|
if (node instanceof helma.objectmodel.db.Node)
|
||||||
|
handle = ((helma.objectmodel.db.Node) node).getHandle ();
|
||||||
|
else
|
||||||
|
handle = null;
|
||||||
|
// we don't take over the transient cache from the node,
|
||||||
|
// because we always stick to the one from the user object.
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateNodeFromUser () {
|
||||||
|
node = user.getNode ();
|
||||||
|
// set node handle to wrapped node
|
||||||
|
if (node instanceof helma.objectmodel.db.Node)
|
||||||
|
handle = ((helma.objectmodel.db.Node) node).getHandle ();
|
||||||
|
else
|
||||||
|
handle = null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString () {
|
||||||
|
return ("UserObject "+node.getName ());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
1162
src/helma/scripting/fesi/HopExtension.java
Normal file
1162
src/helma/scripting/fesi/HopExtension.java
Normal file
File diff suppressed because it is too large
Load diff
86
src/helma/scripting/fesi/NodeConstructor.java
Normal file
86
src/helma/scripting/fesi/NodeConstructor.java
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
// NodeConstructor.java
|
||||||
|
// Copyright (c) Hannes Wallnöfer 2000
|
||||||
|
|
||||||
|
package helma.scripting.fesi;
|
||||||
|
|
||||||
|
import helma.objectmodel.db.Node;
|
||||||
|
import helma.framework.core.*;
|
||||||
|
import FESI.Data.*;
|
||||||
|
import FESI.Exceptions.*;
|
||||||
|
import FESI.Interpreter.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A constructor for user defined data types. This first constructs a node, sets its prototype
|
||||||
|
* and invokes the scripted constructor function on it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class NodeConstructor extends BuiltinFunctionObject {
|
||||||
|
|
||||||
|
RequestEvaluator reval;
|
||||||
|
String typename;
|
||||||
|
|
||||||
|
public NodeConstructor (String name, FunctionPrototype fp, RequestEvaluator reval) {
|
||||||
|
super(fp, reval.evaluator, name, 1);
|
||||||
|
typename = name;
|
||||||
|
this.reval = reval;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ESValue callFunction(ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
|
||||||
|
return doConstruct(thisObject, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ESObject doConstruct(ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
|
||||||
|
ESNode node = null;
|
||||||
|
if ("Node".equals (typename) || "hopobject".equalsIgnoreCase (typename)) {
|
||||||
|
if (arguments.length == 0) {
|
||||||
|
Node n = new Node ((String) null, (String) null, reval.app.getWrappedNodeManager ());
|
||||||
|
node = new ESNode (reval.esNodePrototype, this.evaluator, n, reval);
|
||||||
|
reval.objectcache.put (node.getNode (), node);
|
||||||
|
} else {
|
||||||
|
Node n = new Node (arguments[0].toString(), (String) null, reval.app.getWrappedNodeManager ());
|
||||||
|
node = new ESNode (reval.esNodePrototype, this.evaluator, n, reval);
|
||||||
|
reval.objectcache.put (node.getNode (), node);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 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
|
||||||
|
// is that we want to be able to use the specail features like subnode relations even for
|
||||||
|
// transient nodes.
|
||||||
|
ObjectPrototype op = reval.getPrototype (typename);
|
||||||
|
Node n = new Node (typename, typename, reval.app.getWrappedNodeManager ());
|
||||||
|
node = new ESNode (op, reval.evaluator, n, reval);
|
||||||
|
node.setPrototype (typename);
|
||||||
|
node.getNode ().setDbMapping (reval.app.getDbMapping (typename));
|
||||||
|
try {
|
||||||
|
// first try calling "constructor", if that doesn't work, try calling a function
|
||||||
|
// with the name of the type.
|
||||||
|
// HACK: There is an incompatibility problem here, because the property
|
||||||
|
// constructor is defined as the constructor of the object by EcmaScript.
|
||||||
|
if (op.getProperty("constructor", "constructor".hashCode()) instanceof ConstructedFunctionObject)
|
||||||
|
node.doIndirectCall (reval.evaluator, node, "constructor", arguments);
|
||||||
|
else
|
||||||
|
node.doIndirectCall (reval.evaluator, node, typename, arguments);
|
||||||
|
} catch (Exception ignore) {}
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ESValue getPropertyInScope(String propertyName, ScopeChain previousScope, int hash) throws EcmaScriptException {
|
||||||
|
return super.getPropertyInScope (propertyName, previousScope, hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ESValue getProperty(String propertyName, int hash) throws EcmaScriptException {
|
||||||
|
if ("prototype".equals (propertyName))
|
||||||
|
return reval.getPrototype (typename);
|
||||||
|
return super.getProperty(propertyName, hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getSpecialPropertyNames() {
|
||||||
|
String ns[] = {};
|
||||||
|
return ns;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // class NodeConstructor
|
||||||
|
|
||||||
|
|
||||||
|
|
1076
src/helma/scripting/fesi/extensions/Database.java
Normal file
1076
src/helma/scripting/fesi/extensions/Database.java
Normal file
File diff suppressed because it is too large
Load diff
196
src/helma/scripting/fesi/extensions/ESMail.java
Normal file
196
src/helma/scripting/fesi/extensions/ESMail.java
Normal file
|
@ -0,0 +1,196 @@
|
||||||
|
// ESMail.java
|
||||||
|
// Copyright (c) Hannes Wallnöfer 1998-2000
|
||||||
|
|
||||||
|
|
||||||
|
package helma.scripting.fesi.extensions;
|
||||||
|
|
||||||
|
import javax.mail.*;
|
||||||
|
import javax.mail.internet.*;
|
||||||
|
import javax.activation.*;
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.*;
|
||||||
|
import helma.main.Server;
|
||||||
|
import helma.framework.core.*;
|
||||||
|
import helma.util.*;
|
||||||
|
import FESI.Data.*;
|
||||||
|
import FESI.Interpreter.*;
|
||||||
|
import FESI.Exceptions.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A JavaScript wrapper around a JavaMail message class to send
|
||||||
|
* mail via SMTP from Helma
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class ESMail extends ESObject implements Serializable {
|
||||||
|
|
||||||
|
MailExtension mailx;
|
||||||
|
Properties mprops;
|
||||||
|
MimeMessage message;
|
||||||
|
Multipart multipart;
|
||||||
|
StringBuffer buffer;
|
||||||
|
|
||||||
|
int status;
|
||||||
|
public static final int OK=0;
|
||||||
|
public static final int SUBJECT=10;
|
||||||
|
public static final int TEXT=11;
|
||||||
|
public static final int MIMEPART=12;
|
||||||
|
public static final int TO=20;
|
||||||
|
public static final int CC=21;
|
||||||
|
public static final int BCC=22;
|
||||||
|
public static final int FROM=23;
|
||||||
|
public static final int REPLYTO=24;
|
||||||
|
public static final int SEND=30;
|
||||||
|
|
||||||
|
|
||||||
|
public ESMail (MailExtension mailx) {
|
||||||
|
|
||||||
|
super (mailx.esMailPrototype, mailx.evaluator);
|
||||||
|
this.status = OK;
|
||||||
|
this.mailx = mailx;
|
||||||
|
this.mprops = mailx.mprops;
|
||||||
|
|
||||||
|
// create some properties and get the default Session
|
||||||
|
try {
|
||||||
|
Properties props = new Properties();
|
||||||
|
props.put ("mail.smtp.host", mprops.getProperty ("smtp", "mail"));
|
||||||
|
|
||||||
|
Session session = Session.getDefaultInstance(props, null);
|
||||||
|
message = new MimeMessage (session);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
Server.getLogger().log ("caught in mail constructor: "+t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus (int status) {
|
||||||
|
// Only register the first error that occurrs
|
||||||
|
if (this.status == 0)
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getStatus () {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ESValue getProperty(String propertyName, int hash) throws EcmaScriptException {
|
||||||
|
if ("status".equalsIgnoreCase (propertyName))
|
||||||
|
return new ESNumber (status);
|
||||||
|
return super.getProperty (propertyName, hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public void setText (ESValue val) throws Exception {
|
||||||
|
if (buffer == null)
|
||||||
|
buffer = new StringBuffer ();
|
||||||
|
if (val != null)
|
||||||
|
buffer.append (val.toString ());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addPart (ESValue val[]) throws Exception {
|
||||||
|
if (val == null || val.length == 0) return;
|
||||||
|
if (multipart == null) {
|
||||||
|
multipart = new MimeMultipart ();
|
||||||
|
}
|
||||||
|
for (int i=0; i<val.length; i++) {
|
||||||
|
// FIXME: addPart is broken.
|
||||||
|
MimeBodyPart part = new MimeBodyPart ();
|
||||||
|
Object obj = val[i].toJavaObject ();
|
||||||
|
if (obj instanceof String) {
|
||||||
|
part.setContent (obj.toString (), "text/plain");
|
||||||
|
} else if (obj instanceof File) {
|
||||||
|
FileDataSource source = new FileDataSource ((File) obj);
|
||||||
|
part.setDataHandler (new DataHandler (source));
|
||||||
|
}
|
||||||
|
multipart.addBodyPart (part);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSubject (ESValue val) throws Exception {
|
||||||
|
if (val == null)
|
||||||
|
return;
|
||||||
|
message.setSubject (MimeUtility.encodeWord (val.toString (), "iso-8859-1", null));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReplyTo (ESValue add) throws Exception {
|
||||||
|
String addstring = add.toString ();
|
||||||
|
if (addstring.indexOf ("@") < 0)
|
||||||
|
throw new AddressException ();
|
||||||
|
Address replyTo[] = new Address[1];
|
||||||
|
replyTo[0] = new InternetAddress (addstring);
|
||||||
|
message.setReplyTo (replyTo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFrom (ESValue add[]) throws Exception {
|
||||||
|
String addstring = add[0].toString ();
|
||||||
|
if (addstring.indexOf ("@") < 0)
|
||||||
|
throw new AddressException ();
|
||||||
|
Address address = null;
|
||||||
|
if (add.length > 1)
|
||||||
|
address = new InternetAddress (addstring, MimeUtility.encodeWord (add[1].toString (), "iso-8859-1", null));
|
||||||
|
else
|
||||||
|
address = new InternetAddress (addstring);
|
||||||
|
message.setFrom (address);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addTo (ESValue add[]) throws Exception {
|
||||||
|
String addstring = add[0].toString ();
|
||||||
|
if (addstring.indexOf ("@") < 0)
|
||||||
|
throw new AddressException ();
|
||||||
|
Address address = null;
|
||||||
|
if (add.length > 1)
|
||||||
|
address = new InternetAddress (addstring, MimeUtility.encodeWord (add[1].toString (), "iso-8859-1", null));
|
||||||
|
else
|
||||||
|
address = new InternetAddress (addstring);
|
||||||
|
message.addRecipient (Message.RecipientType.TO, address);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addCC (ESValue add[]) throws Exception {
|
||||||
|
String addstring = add[0].toString ();
|
||||||
|
if (addstring.indexOf ("@") < 0)
|
||||||
|
throw new AddressException ();
|
||||||
|
Address address = null;
|
||||||
|
if (add.length > 1)
|
||||||
|
address = new InternetAddress (addstring, MimeUtility.encodeWord (add[1].toString (), "iso-8859-1", null));
|
||||||
|
else
|
||||||
|
address = new InternetAddress (addstring);
|
||||||
|
message.addRecipient (Message.RecipientType.CC, address);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addBCC (ESValue add[]) throws Exception {
|
||||||
|
String addstring = add[0].toString ();
|
||||||
|
if (addstring.indexOf ("@") < 0)
|
||||||
|
throw new AddressException ();
|
||||||
|
Address address = null;
|
||||||
|
if (add.length > 1)
|
||||||
|
address = new InternetAddress (addstring, MimeUtility.encodeWord (add[1].toString (), "iso-8859-1", null));
|
||||||
|
else
|
||||||
|
address = new InternetAddress (addstring);
|
||||||
|
message.addRecipient (Message.RecipientType.BCC, address);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void send () throws Exception {
|
||||||
|
if (buffer != null)
|
||||||
|
message.setText (buffer.toString ());
|
||||||
|
else if (multipart != null)
|
||||||
|
message.setContent (multipart);
|
||||||
|
else
|
||||||
|
message.setText ("");
|
||||||
|
Transport.send (message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
419
src/helma/scripting/fesi/extensions/FtpExtension.java
Normal file
419
src/helma/scripting/fesi/extensions/FtpExtension.java
Normal file
|
@ -0,0 +1,419 @@
|
||||||
|
// FtpExtension.java
|
||||||
|
// Copyright (c) Hannes Wallnöfer 1998-2000
|
||||||
|
|
||||||
|
package helma.scripting.fesi.extensions;
|
||||||
|
|
||||||
|
import helma.objectmodel.*;
|
||||||
|
import FESI.Parser.*;
|
||||||
|
import FESI.AST.*;
|
||||||
|
import FESI.Interpreter.*;
|
||||||
|
import FESI.Exceptions.*;
|
||||||
|
import FESI.Extensions.*;
|
||||||
|
import FESI.Data.*;
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
import com.oroinc.net.ftp.*;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A FTP-client object that allows to do some FTP from HOP applications.
|
||||||
|
* FTP support is far from complete but can easily be extended if more
|
||||||
|
* functionality is needed.
|
||||||
|
* This uses the NetComponent classes from savarese.org (ex oroinc.com).
|
||||||
|
*/
|
||||||
|
|
||||||
|
class ESFtpClient extends ESObject {
|
||||||
|
|
||||||
|
private FTPClient ftpclient;
|
||||||
|
private String server;
|
||||||
|
private Exception lastError = null;
|
||||||
|
private File localDir = null;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new FTP Client
|
||||||
|
*
|
||||||
|
* @param prototype The prototype object for the FTP object
|
||||||
|
* @param evaluator The current evaluator
|
||||||
|
*/
|
||||||
|
ESFtpClient(ESObject prototype, Evaluator evaluator, ESValue srvstr) {
|
||||||
|
super(prototype, evaluator);
|
||||||
|
this.server = srvstr.toString ();
|
||||||
|
}
|
||||||
|
|
||||||
|
ESFtpClient(ESObject prototype, Evaluator evaluator) {
|
||||||
|
super(prototype, evaluator);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getESClassName() {
|
||||||
|
return "FtpClient";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return "[FtpClient]";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toDetailString() {
|
||||||
|
return "ES:[Object: builtin " + this.getClass().getName() + ":" +
|
||||||
|
this.toString() + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
ESValue getLastError() throws EcmaScriptException {
|
||||||
|
if (lastError == null) {
|
||||||
|
return ESNull.theNull;
|
||||||
|
} else {
|
||||||
|
return ESLoader.normalizeValue(lastError, evaluator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Login to the FTP server
|
||||||
|
*
|
||||||
|
* @param arguments The argument list
|
||||||
|
* @return true if successful, false otherwise
|
||||||
|
*/
|
||||||
|
ESValue login(ESValue arguments[]) throws EcmaScriptException {
|
||||||
|
if (server == null)
|
||||||
|
return ESBoolean.makeBoolean(false);
|
||||||
|
try {
|
||||||
|
ftpclient = new FTPClient ();
|
||||||
|
ftpclient.connect (server);
|
||||||
|
ftpclient.login (arguments[0].toString(), arguments[1].toString());
|
||||||
|
return ESBoolean.makeBoolean (true);
|
||||||
|
} catch (Exception x) {
|
||||||
|
return ESBoolean.makeBoolean (false);
|
||||||
|
} catch (NoClassDefFoundError x) {
|
||||||
|
return ESBoolean.makeBoolean (false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ESValue cd (ESValue arguments[]) throws EcmaScriptException {
|
||||||
|
if (ftpclient == null)
|
||||||
|
return ESBoolean.makeBoolean(false);
|
||||||
|
try {
|
||||||
|
ftpclient.changeWorkingDirectory (arguments[0].toString ());
|
||||||
|
return ESBoolean.makeBoolean(true);
|
||||||
|
} catch (Exception wrong) {}
|
||||||
|
return ESBoolean.makeBoolean(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ESValue mkdir (ESValue arguments[]) throws EcmaScriptException {
|
||||||
|
if (ftpclient == null)
|
||||||
|
return ESBoolean.makeBoolean(false);
|
||||||
|
try {
|
||||||
|
return ESBoolean.makeBoolean(ftpclient.makeDirectory (arguments[0].toString ()));
|
||||||
|
} catch (Exception wrong) {}
|
||||||
|
return ESBoolean.makeBoolean(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
ESValue lcd (ESValue arguments[]) throws EcmaScriptException {
|
||||||
|
try {
|
||||||
|
localDir = new File (arguments[0].toString());
|
||||||
|
if (!localDir.exists())
|
||||||
|
localDir.mkdirs();
|
||||||
|
return ESBoolean.makeBoolean(true);
|
||||||
|
} catch (Exception wrong) {}
|
||||||
|
return ESBoolean.makeBoolean(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
ESValue putFile(ESValue arguments[]) throws EcmaScriptException {
|
||||||
|
if (ftpclient == null)
|
||||||
|
return ESBoolean.makeBoolean(false);
|
||||||
|
try {
|
||||||
|
String fn = arguments[0].toString();
|
||||||
|
File f = localDir == null ? new File (fn) : new File (localDir, fn);
|
||||||
|
InputStream fin = new BufferedInputStream (new FileInputStream (f));
|
||||||
|
ftpclient.storeFile (arguments[1].toString (), fin);
|
||||||
|
fin.close ();
|
||||||
|
return ESBoolean.makeBoolean(true);
|
||||||
|
} catch (Exception wrong) {}
|
||||||
|
return ESBoolean.makeBoolean(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
ESValue putString(ESValue arguments[]) throws EcmaScriptException {
|
||||||
|
if (ftpclient == null)
|
||||||
|
return ESBoolean.makeBoolean(false);
|
||||||
|
try {
|
||||||
|
byte[] bytes = null;
|
||||||
|
// check if this already is a byte array
|
||||||
|
if (arguments[0] instanceof ESArrayWrapper) {
|
||||||
|
Object o = ((ESArrayWrapper) arguments[0]).toJavaObject ();
|
||||||
|
if (o instanceof byte[])
|
||||||
|
bytes = (byte[]) o;
|
||||||
|
}
|
||||||
|
if (bytes == null)
|
||||||
|
bytes = arguments[0].toString().getBytes();
|
||||||
|
ByteArrayInputStream bin = new ByteArrayInputStream (bytes);
|
||||||
|
ftpclient.storeFile (arguments[1].toString (), bin);
|
||||||
|
return ESBoolean.makeBoolean(true);
|
||||||
|
} catch (Exception wrong) {}
|
||||||
|
return ESBoolean.makeBoolean(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ESValue getFile(ESValue arguments[]) throws EcmaScriptException {
|
||||||
|
if (ftpclient == null )
|
||||||
|
return ESBoolean.makeBoolean(false);
|
||||||
|
try {
|
||||||
|
String fn = arguments[0].toString();
|
||||||
|
File f = localDir == null ? new File (fn) : new File (localDir, fn);
|
||||||
|
OutputStream out = new BufferedOutputStream (new FileOutputStream(f));
|
||||||
|
ftpclient.retrieveFile (arguments[0].toString (), out);
|
||||||
|
out.close ();
|
||||||
|
return ESBoolean.makeBoolean(true);
|
||||||
|
} catch (Exception wrong) {}
|
||||||
|
return ESBoolean.makeBoolean(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
ESValue getString(ESValue arguments[]) throws EcmaScriptException {
|
||||||
|
if (ftpclient == null )
|
||||||
|
return ESNull.theNull;
|
||||||
|
try {
|
||||||
|
ByteArrayOutputStream bout = new ByteArrayOutputStream ();
|
||||||
|
ftpclient.retrieveFile (arguments[0].toString (), bout);
|
||||||
|
return new ESString (bout.toString ());
|
||||||
|
} catch (Exception wrong) {}
|
||||||
|
return ESNull.theNull;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disconnect from FTP server
|
||||||
|
*
|
||||||
|
* @param arguments The argument list
|
||||||
|
* @return true if successful, false otherwise
|
||||||
|
*/
|
||||||
|
ESValue logout (ESValue arguments[]) throws EcmaScriptException {
|
||||||
|
if (ftpclient != null) {
|
||||||
|
try {
|
||||||
|
ftpclient.logout ();
|
||||||
|
} catch (IOException ignore) {}
|
||||||
|
try {
|
||||||
|
ftpclient.disconnect ();
|
||||||
|
} catch (IOException ignore) {}
|
||||||
|
}
|
||||||
|
return ESBoolean.makeBoolean (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
ESValue binary (ESValue arguments[]) throws EcmaScriptException {
|
||||||
|
if (ftpclient != null) {
|
||||||
|
try {
|
||||||
|
ftpclient.setFileType (FTP.BINARY_FILE_TYPE);
|
||||||
|
return ESBoolean.makeBoolean (true);
|
||||||
|
} catch (IOException ignore) {}
|
||||||
|
}
|
||||||
|
return ESBoolean.makeBoolean (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
ESValue ascii (ESValue arguments[]) throws EcmaScriptException {
|
||||||
|
if (ftpclient != null) {
|
||||||
|
try {
|
||||||
|
ftpclient.setFileType (FTP.ASCII_FILE_TYPE);
|
||||||
|
return ESBoolean.makeBoolean (true);
|
||||||
|
} catch (IOException ignore) {}
|
||||||
|
}
|
||||||
|
return ESBoolean.makeBoolean (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class FtpExtension extends Extension {
|
||||||
|
|
||||||
|
private transient Evaluator evaluator = null;
|
||||||
|
private ESObject esFtpPrototype = null;
|
||||||
|
|
||||||
|
public FtpExtension () {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
class GlobalObjectFtpClient extends BuiltinFunctionObject {
|
||||||
|
GlobalObjectFtpClient(String name, Evaluator evaluator, FunctionPrototype fp) {
|
||||||
|
super(fp, evaluator, name, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ESValue callFunction(ESObject thisObject, ESValue[] arguments)
|
||||||
|
throws EcmaScriptException {
|
||||||
|
return doConstruct(thisObject, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ESObject doConstruct(ESObject thisObject, ESValue[] arguments)
|
||||||
|
throws EcmaScriptException {
|
||||||
|
ESFtpClient ftp = null;
|
||||||
|
if (arguments.length != 1)
|
||||||
|
throw new EcmaScriptException("FtpClient requires 1 argument");
|
||||||
|
ftp = new ESFtpClient (esFtpPrototype,
|
||||||
|
this.evaluator,
|
||||||
|
arguments[0]);
|
||||||
|
return ftp;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class FtpClientLogin extends BuiltinFunctionObject {
|
||||||
|
FtpClientLogin(String name, Evaluator evaluator, FunctionPrototype fp) {
|
||||||
|
super(fp, evaluator, name, 1);
|
||||||
|
}
|
||||||
|
public ESValue callFunction(ESObject thisObject,
|
||||||
|
ESValue[] arguments)
|
||||||
|
throws EcmaScriptException {
|
||||||
|
ESFtpClient ftp = (ESFtpClient) thisObject;
|
||||||
|
return ftp.login (arguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FtpClientCD extends BuiltinFunctionObject {
|
||||||
|
FtpClientCD(String name, Evaluator evaluator, FunctionPrototype fp) {
|
||||||
|
super(fp, evaluator, name, 1);
|
||||||
|
}
|
||||||
|
public ESValue callFunction(ESObject thisObject,
|
||||||
|
ESValue[] arguments)
|
||||||
|
throws EcmaScriptException {
|
||||||
|
ESFtpClient ftp = (ESFtpClient) thisObject;
|
||||||
|
return ftp.cd (arguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FtpClientMKDIR extends BuiltinFunctionObject {
|
||||||
|
FtpClientMKDIR(String name, Evaluator evaluator, FunctionPrototype fp) {
|
||||||
|
super(fp, evaluator, name, 1);
|
||||||
|
}
|
||||||
|
public ESValue callFunction(ESObject thisObject,
|
||||||
|
ESValue[] arguments)
|
||||||
|
throws EcmaScriptException {
|
||||||
|
ESFtpClient ftp = (ESFtpClient) thisObject;
|
||||||
|
return ftp.mkdir (arguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FtpClientLCD extends BuiltinFunctionObject {
|
||||||
|
FtpClientLCD(String name, Evaluator evaluator, FunctionPrototype fp) {
|
||||||
|
super(fp, evaluator, name, 1);
|
||||||
|
}
|
||||||
|
public ESValue callFunction(ESObject thisObject,
|
||||||
|
ESValue[] arguments)
|
||||||
|
throws EcmaScriptException {
|
||||||
|
ESFtpClient ftp = (ESFtpClient) thisObject;
|
||||||
|
return ftp.lcd (arguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FtpClientPutFile extends BuiltinFunctionObject {
|
||||||
|
FtpClientPutFile (String name, Evaluator evaluator, FunctionPrototype fp) {
|
||||||
|
super(fp, evaluator, name, 1);
|
||||||
|
}
|
||||||
|
public ESValue callFunction(ESObject thisObject,
|
||||||
|
ESValue[] arguments)
|
||||||
|
throws EcmaScriptException {
|
||||||
|
ESFtpClient ftp = (ESFtpClient) thisObject;
|
||||||
|
return ftp.putFile (arguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FtpClientPutString extends BuiltinFunctionObject {
|
||||||
|
FtpClientPutString (String name, Evaluator evaluator, FunctionPrototype fp) {
|
||||||
|
super(fp, evaluator, name, 1);
|
||||||
|
}
|
||||||
|
public ESValue callFunction(ESObject thisObject,
|
||||||
|
ESValue[] arguments)
|
||||||
|
throws EcmaScriptException {
|
||||||
|
ESFtpClient ftp = (ESFtpClient) thisObject;
|
||||||
|
return ftp.putString (arguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FtpClientGetFile extends BuiltinFunctionObject {
|
||||||
|
FtpClientGetFile (String name, Evaluator evaluator, FunctionPrototype fp) {
|
||||||
|
super(fp, evaluator, name, 1);
|
||||||
|
}
|
||||||
|
public ESValue callFunction(ESObject thisObject,
|
||||||
|
ESValue[] arguments)
|
||||||
|
throws EcmaScriptException {
|
||||||
|
ESFtpClient ftp = (ESFtpClient) thisObject;
|
||||||
|
return ftp.getFile (arguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FtpClientGetString extends BuiltinFunctionObject {
|
||||||
|
FtpClientGetString (String name, Evaluator evaluator, FunctionPrototype fp) {
|
||||||
|
super(fp, evaluator, name, 1);
|
||||||
|
}
|
||||||
|
public ESValue callFunction(ESObject thisObject,
|
||||||
|
ESValue[] arguments)
|
||||||
|
throws EcmaScriptException {
|
||||||
|
ESFtpClient ftp = (ESFtpClient) thisObject;
|
||||||
|
return ftp.getString (arguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FtpClientLogout extends BuiltinFunctionObject {
|
||||||
|
FtpClientLogout(String name, Evaluator evaluator, FunctionPrototype fp) {
|
||||||
|
super(fp, evaluator, name, 1);
|
||||||
|
}
|
||||||
|
public ESValue callFunction(ESObject thisObject,
|
||||||
|
ESValue[] arguments)
|
||||||
|
throws EcmaScriptException {
|
||||||
|
ESFtpClient ftp = (ESFtpClient) thisObject;
|
||||||
|
return ftp.logout (arguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FtpClientBinary extends BuiltinFunctionObject {
|
||||||
|
FtpClientBinary(String name, Evaluator evaluator, FunctionPrototype fp) {
|
||||||
|
super(fp, evaluator, name, 1);
|
||||||
|
}
|
||||||
|
public ESValue callFunction(ESObject thisObject,
|
||||||
|
ESValue[] arguments)
|
||||||
|
throws EcmaScriptException {
|
||||||
|
ESFtpClient ftp = (ESFtpClient) thisObject;
|
||||||
|
return ftp.binary (arguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FtpClientAscii extends BuiltinFunctionObject {
|
||||||
|
FtpClientAscii(String name, Evaluator evaluator, FunctionPrototype fp) {
|
||||||
|
super(fp, evaluator, name, 1);
|
||||||
|
}
|
||||||
|
public ESValue callFunction(ESObject thisObject,
|
||||||
|
ESValue[] arguments)
|
||||||
|
throws EcmaScriptException {
|
||||||
|
ESFtpClient ftp = (ESFtpClient) thisObject;
|
||||||
|
return ftp.ascii (arguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void initializeExtension(Evaluator evaluator) throws EcmaScriptException {
|
||||||
|
|
||||||
|
this.evaluator = evaluator;
|
||||||
|
GlobalObject go = evaluator.getGlobalObject();
|
||||||
|
ObjectPrototype op = (ObjectPrototype) evaluator.getObjectPrototype();
|
||||||
|
FunctionPrototype fp = (FunctionPrototype) evaluator.getFunctionPrototype();
|
||||||
|
|
||||||
|
esFtpPrototype = new ESFtpClient (op, evaluator);
|
||||||
|
|
||||||
|
ESObject globalFtpObject = new GlobalObjectFtpClient("FtpClient", evaluator, fp);
|
||||||
|
globalFtpObject.putHiddenProperty("prototype",esFtpPrototype);
|
||||||
|
globalFtpObject.putHiddenProperty("length",new ESNumber(1));
|
||||||
|
|
||||||
|
|
||||||
|
esFtpPrototype.putHiddenProperty("login", new FtpClientLogin("login", evaluator, fp));
|
||||||
|
esFtpPrototype.putHiddenProperty("cd", new FtpClientCD("cd", evaluator, fp));
|
||||||
|
esFtpPrototype.putHiddenProperty("mkdir", new FtpClientMKDIR("mkdir", evaluator, fp));
|
||||||
|
esFtpPrototype.putHiddenProperty("lcd", new FtpClientLCD("lcd", evaluator, fp));
|
||||||
|
esFtpPrototype.putHiddenProperty("putFile", new FtpClientPutFile("putFile", evaluator, fp));
|
||||||
|
esFtpPrototype.putHiddenProperty("putString", new FtpClientPutString("putString", evaluator, fp));
|
||||||
|
esFtpPrototype.putHiddenProperty("getFile", new FtpClientGetFile("getFile", evaluator, fp));
|
||||||
|
esFtpPrototype.putHiddenProperty("getString", new FtpClientGetString("getString", evaluator, fp));
|
||||||
|
esFtpPrototype.putHiddenProperty("logout", new FtpClientLogout("logout", evaluator, fp));
|
||||||
|
esFtpPrototype.putHiddenProperty("binary", new FtpClientBinary("binary", evaluator, fp));
|
||||||
|
esFtpPrototype.putHiddenProperty("ascii", new FtpClientAscii("ascii", evaluator, fp));
|
||||||
|
|
||||||
|
go.putHiddenProperty("FtpClient", globalFtpObject);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
133
src/helma/scripting/fesi/extensions/ImageExtension.java
Normal file
133
src/helma/scripting/fesi/extensions/ImageExtension.java
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
// ImageExtension.java
|
||||||
|
// Copyright (c) Hannes Wallnöfer 1998-2000
|
||||||
|
|
||||||
|
package helma.scripting.fesi.extensions;
|
||||||
|
|
||||||
|
import helma.objectmodel.*;
|
||||||
|
import helma.util.*;
|
||||||
|
import helma.image.*;
|
||||||
|
|
||||||
|
import FESI.Interpreter.*;
|
||||||
|
import FESI.Exceptions.*;
|
||||||
|
import FESI.Extensions.*;
|
||||||
|
import FESI.Data.*;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.awt.image.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.rmi.Naming;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extension to do Image manipulation from HOP.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class ImageExtension extends Extension {
|
||||||
|
|
||||||
|
protected Evaluator evaluator = null;
|
||||||
|
|
||||||
|
static boolean remote = false;
|
||||||
|
|
||||||
|
|
||||||
|
public ImageExtension () {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class GlobalObjectImage extends BuiltinFunctionObject {
|
||||||
|
|
||||||
|
ImageExtension imagex;
|
||||||
|
ImageGenerator imggen;
|
||||||
|
|
||||||
|
GlobalObjectImage (String name, Evaluator evaluator, FunctionPrototype fp, ImageExtension imagex) {
|
||||||
|
super(fp, evaluator, name, 1);
|
||||||
|
this.imagex = imagex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ESValue callFunction(ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
|
||||||
|
return doConstruct(thisObject, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ESObject doConstruct(ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
|
||||||
|
Object img = null;
|
||||||
|
IRemoteGenerator rgen = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (imggen == null && !remote) {
|
||||||
|
try {
|
||||||
|
imggen = new ImageGenerator ();
|
||||||
|
} catch (UnsatisfiedLinkError noawt) {
|
||||||
|
remote = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remote)
|
||||||
|
rgen = (IRemoteGenerator) Naming.lookup ("//localhost:3033/server");
|
||||||
|
|
||||||
|
if (arguments.length == 1) {
|
||||||
|
if (arguments[0] instanceof ESArrayWrapper) {
|
||||||
|
Object obj = ((ESArrayWrapper) arguments[0]).toJavaObject ();
|
||||||
|
if (obj instanceof byte[]) {
|
||||||
|
img = remote ?
|
||||||
|
(Object) rgen.createImage ((byte[]) obj) :
|
||||||
|
(Object) imggen.createImage ((byte[]) obj);
|
||||||
|
}
|
||||||
|
} else if (arguments[0] instanceof ESString) {
|
||||||
|
String imgurl = arguments[0].toString ();
|
||||||
|
img = remote ?
|
||||||
|
(Object) rgen.createPaintableImage (imgurl) :
|
||||||
|
(Object) imggen.createPaintableImage (imgurl);
|
||||||
|
}
|
||||||
|
} else if (arguments.length == 2) {
|
||||||
|
if (arguments[0] instanceof ESWrapper && arguments[1] instanceof ESWrapper) {
|
||||||
|
// create a new image from an existing one and an image filter
|
||||||
|
Object image = arguments[0].toJavaObject ();
|
||||||
|
Object filter = arguments[1].toJavaObject ();
|
||||||
|
img = imggen.createPaintableImage ((ImageWrapper) image, (ImageFilter) filter);
|
||||||
|
} else if (arguments[0].isNumberValue () && arguments[1].isNumberValue ()) {
|
||||||
|
img = remote ?
|
||||||
|
(Object) rgen.createPaintableImage (arguments[0].toInt32(), arguments[1].toInt32()) :
|
||||||
|
(Object) imggen.createPaintableImage (arguments[0].toInt32(), arguments[1].toInt32());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception error) {
|
||||||
|
System.err.println ("Error creating Image: "+error);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (img == null)
|
||||||
|
throw new EcmaScriptException ("Error creating image: Bad parameters or setup problem.");
|
||||||
|
|
||||||
|
return new ESWrapper (img, this.evaluator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called by the evaluator after the extension is loaded.
|
||||||
|
*/
|
||||||
|
public void initializeExtension(Evaluator evaluator) throws EcmaScriptException {
|
||||||
|
|
||||||
|
this.evaluator = evaluator;
|
||||||
|
GlobalObject go = evaluator.getGlobalObject();
|
||||||
|
FunctionPrototype fp = (FunctionPrototype) evaluator.getFunctionPrototype();
|
||||||
|
|
||||||
|
ESObject image = new GlobalObjectImage ("Image", evaluator, fp, this); // the Image constructor
|
||||||
|
|
||||||
|
go.putHiddenProperty("Image", image); // register the constructor for a Image object.
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
255
src/helma/scripting/fesi/extensions/MailExtension.java
Normal file
255
src/helma/scripting/fesi/extensions/MailExtension.java
Normal file
|
@ -0,0 +1,255 @@
|
||||||
|
// MailExtension.java
|
||||||
|
// Copyright (c) Hannes Wallnöfer 1998-2000
|
||||||
|
|
||||||
|
package helma.scripting.fesi.extensions;
|
||||||
|
|
||||||
|
import helma.main.Server;
|
||||||
|
import helma.util.*;
|
||||||
|
|
||||||
|
import FESI.Interpreter.*;
|
||||||
|
import FESI.Exceptions.*;
|
||||||
|
import FESI.Extensions.*;
|
||||||
|
import FESI.Data.*;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extension to create and send mail messages via SMTP from HOP applications
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class MailExtension extends Extension {
|
||||||
|
|
||||||
|
|
||||||
|
protected Evaluator evaluator = null;
|
||||||
|
protected ObjectPrototype esMailPrototype = null;
|
||||||
|
protected Properties mprops;
|
||||||
|
|
||||||
|
|
||||||
|
public MailExtension () {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProperties (Properties props) {
|
||||||
|
this.mprops = props;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called by the evaluator after the extension is loaded.
|
||||||
|
*/
|
||||||
|
public void initializeExtension(Evaluator evaluator) throws EcmaScriptException {
|
||||||
|
|
||||||
|
this.evaluator = evaluator;
|
||||||
|
GlobalObject go = evaluator.getGlobalObject();
|
||||||
|
FunctionPrototype fp = (FunctionPrototype) evaluator.getFunctionPrototype();
|
||||||
|
|
||||||
|
ESObject op = evaluator.getObjectPrototype();
|
||||||
|
esMailPrototype = new ObjectPrototype(op, evaluator); // the Node prototype
|
||||||
|
|
||||||
|
ESObject mail = new GlobalObjectMail ("Mail", evaluator, fp, this); // the Mail constructor
|
||||||
|
|
||||||
|
go.putHiddenProperty("Mail", mail); // register the constructor for a Mail object.
|
||||||
|
|
||||||
|
|
||||||
|
// methods for sending mail from JS...
|
||||||
|
ESObject p = new MailSetText ("setText", evaluator, fp);
|
||||||
|
esMailPrototype.putHiddenProperty("setText", p);
|
||||||
|
esMailPrototype.putHiddenProperty("addText", p);
|
||||||
|
|
||||||
|
esMailPrototype.putHiddenProperty("addPart", new MailAddPart ("addPart", evaluator, fp));
|
||||||
|
esMailPrototype.putHiddenProperty("setSubject", new MailSetSubject ("setSubject", evaluator, fp));
|
||||||
|
esMailPrototype.putHiddenProperty("setReplyTo", new MailSetReplyTo ("setReplyTo", evaluator, fp));
|
||||||
|
esMailPrototype.putHiddenProperty("setFrom", new MailSetFrom ("setFrom", evaluator, fp));
|
||||||
|
|
||||||
|
p = new MailAddTo ("addTo", evaluator, fp);
|
||||||
|
esMailPrototype.putHiddenProperty("addTo", p);
|
||||||
|
esMailPrototype.putHiddenProperty("setTo", p);
|
||||||
|
|
||||||
|
p = new MailAddCC ("addCC", evaluator, fp);
|
||||||
|
esMailPrototype.putHiddenProperty("addCC", p);
|
||||||
|
esMailPrototype.putHiddenProperty("setCC", p);
|
||||||
|
|
||||||
|
p = new MailAddBCC ("addBCC", evaluator, fp);
|
||||||
|
esMailPrototype.putHiddenProperty("addBCC", p);
|
||||||
|
esMailPrototype.putHiddenProperty("setBCC", p);
|
||||||
|
|
||||||
|
esMailPrototype.putHiddenProperty("send", new MailSend ("send", evaluator, fp));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class GlobalObjectMail extends BuiltinFunctionObject {
|
||||||
|
|
||||||
|
MailExtension mailx;
|
||||||
|
|
||||||
|
GlobalObjectMail (String name, Evaluator evaluator, FunctionPrototype fp, MailExtension mailx) {
|
||||||
|
super(fp, evaluator, name, 1);
|
||||||
|
this.mailx = mailx;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ESValue callFunction(ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
|
||||||
|
return doConstruct(thisObject, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ESObject doConstruct(ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
|
||||||
|
ESMail mail = null;
|
||||||
|
|
||||||
|
if (arguments.length == 0) {
|
||||||
|
mail = new ESMail (mailx);
|
||||||
|
} else {
|
||||||
|
mail = new ESMail (mailx);
|
||||||
|
// should/could do something with extra arguments...
|
||||||
|
}
|
||||||
|
return mail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class MailSetText extends BuiltinFunctionObject {
|
||||||
|
MailSetText (String name, Evaluator evaluator, FunctionPrototype fp) {
|
||||||
|
super (fp, evaluator, name, 1);
|
||||||
|
}
|
||||||
|
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
|
||||||
|
ESMail mail = (ESMail) thisObject;
|
||||||
|
if (arguments.length == 1) try {
|
||||||
|
mail.setText (arguments[0]);
|
||||||
|
} catch (Exception x) {
|
||||||
|
mail.setStatus (ESMail.TEXT);
|
||||||
|
return ESBoolean.makeBoolean(false);
|
||||||
|
}
|
||||||
|
return ESBoolean.makeBoolean(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MailAddPart extends BuiltinFunctionObject {
|
||||||
|
MailAddPart (String name, Evaluator evaluator, FunctionPrototype fp) {
|
||||||
|
super (fp, evaluator, name, 1);
|
||||||
|
}
|
||||||
|
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
|
||||||
|
ESMail mail = (ESMail) thisObject;
|
||||||
|
try {
|
||||||
|
mail.addPart (arguments);
|
||||||
|
} catch (Exception x) {
|
||||||
|
mail.setStatus (ESMail.MIMEPART);
|
||||||
|
return ESBoolean.makeBoolean(false);
|
||||||
|
}
|
||||||
|
return ESBoolean.makeBoolean(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MailSetSubject extends BuiltinFunctionObject {
|
||||||
|
MailSetSubject (String name, Evaluator evaluator, FunctionPrototype fp) {
|
||||||
|
super (fp, evaluator, name, 1);
|
||||||
|
}
|
||||||
|
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
|
||||||
|
ESMail mail = (ESMail) thisObject;
|
||||||
|
if (arguments.length == 1) try {
|
||||||
|
mail.setSubject (arguments[0]);
|
||||||
|
} catch (Exception x) {
|
||||||
|
mail.setStatus (ESMail.SUBJECT);
|
||||||
|
return ESBoolean.makeBoolean(false);
|
||||||
|
}
|
||||||
|
return ESBoolean.makeBoolean(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MailSetReplyTo extends BuiltinFunctionObject {
|
||||||
|
MailSetReplyTo (String name, Evaluator evaluator, FunctionPrototype fp) {
|
||||||
|
super (fp, evaluator, name, 1);
|
||||||
|
}
|
||||||
|
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
|
||||||
|
ESMail mail = (ESMail) thisObject;
|
||||||
|
if (arguments.length == 1) try {
|
||||||
|
mail.setReplyTo (arguments[0]);
|
||||||
|
} catch (Exception x) {
|
||||||
|
mail.setStatus (ESMail.REPLYTO);
|
||||||
|
return ESBoolean.makeBoolean(false);
|
||||||
|
}
|
||||||
|
return ESBoolean.makeBoolean(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MailSetFrom extends BuiltinFunctionObject {
|
||||||
|
MailSetFrom (String name, Evaluator evaluator, FunctionPrototype fp) {
|
||||||
|
super (fp, evaluator, name, 1);
|
||||||
|
}
|
||||||
|
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
|
||||||
|
ESMail mail = (ESMail) thisObject;
|
||||||
|
try {
|
||||||
|
mail.setFrom (arguments);
|
||||||
|
} catch (Exception x) {
|
||||||
|
mail.setStatus (ESMail.FROM);
|
||||||
|
return ESBoolean.makeBoolean(false);
|
||||||
|
}
|
||||||
|
return ESBoolean.makeBoolean(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MailAddTo extends BuiltinFunctionObject {
|
||||||
|
MailAddTo (String name, Evaluator evaluator, FunctionPrototype fp) {
|
||||||
|
super (fp, evaluator, name, 1);
|
||||||
|
}
|
||||||
|
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
|
||||||
|
ESMail mail = (ESMail) thisObject;
|
||||||
|
try {
|
||||||
|
mail.addTo (arguments);
|
||||||
|
} catch (Exception x) {
|
||||||
|
mail.setStatus (ESMail.TO);
|
||||||
|
return ESBoolean.makeBoolean(false);
|
||||||
|
}
|
||||||
|
return ESBoolean.makeBoolean(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MailAddCC extends BuiltinFunctionObject {
|
||||||
|
MailAddCC (String name, Evaluator evaluator, FunctionPrototype fp) {
|
||||||
|
super (fp, evaluator, name, 1);
|
||||||
|
}
|
||||||
|
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
|
||||||
|
ESMail mail = (ESMail) thisObject;
|
||||||
|
try {
|
||||||
|
mail.addCC (arguments);
|
||||||
|
} catch (Exception x) {
|
||||||
|
mail.setStatus (ESMail.CC);
|
||||||
|
return ESBoolean.makeBoolean(false);
|
||||||
|
}
|
||||||
|
return ESBoolean.makeBoolean(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MailAddBCC extends BuiltinFunctionObject {
|
||||||
|
MailAddBCC (String name, Evaluator evaluator, FunctionPrototype fp) {
|
||||||
|
super (fp, evaluator, name, 1);
|
||||||
|
}
|
||||||
|
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
|
||||||
|
ESMail mail = (ESMail) thisObject;
|
||||||
|
try {
|
||||||
|
mail.addBCC (arguments);
|
||||||
|
} catch (Exception x) {
|
||||||
|
mail.setStatus (ESMail.BCC);
|
||||||
|
return ESBoolean.makeBoolean(false);
|
||||||
|
}
|
||||||
|
return ESBoolean.makeBoolean(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MailSend extends BuiltinFunctionObject {
|
||||||
|
MailSend (String name, Evaluator evaluator, FunctionPrototype fp) {
|
||||||
|
super (fp, evaluator, name, 1);
|
||||||
|
}
|
||||||
|
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
|
||||||
|
ESMail mail = (ESMail) thisObject;
|
||||||
|
try {
|
||||||
|
mail.send ();
|
||||||
|
} catch (Exception x) {
|
||||||
|
Server.getLogger().log ("Error sending mail: "+x);
|
||||||
|
mail.setStatus (ESMail.SEND);
|
||||||
|
return ESBoolean.makeBoolean(false);
|
||||||
|
}
|
||||||
|
return ESBoolean.makeBoolean(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue