Worked on skin support

This commit is contained in:
hns 2001-01-10 19:31:05 +00:00
parent 30f539b396
commit b0d134b811
5 changed files with 149 additions and 52 deletions

View file

@ -37,14 +37,12 @@ public class ResponseTrans implements Serializable {
// the buffers used to build the single body parts -
// transient, response must be constructed before this is serialized
public transient String title;
public transient String body;
public transient String message;
public transient String title, head, body, message;
public ResponseTrans () {
super ();
title = body = message = "";
title = head = body = message = "";
}
public void reset () {

View file

@ -12,16 +12,16 @@ import helma.objectmodel.INode;
/**
* An EcmaScript object to access the form data sent with a HTTP request
* An EcmaScript object that makes stuff in a hashtable accessible as its properties
*/
public class ESRequestData extends ESWrapper {
public class ESRequestData extends ESObject {
private Hashtable data;
private RequestEvaluator reval;
public ESRequestData (ESObject prototype, Evaluator evaluator, RequestEvaluator reval) {
super (prototype, evaluator);
public ESRequestData (RequestEvaluator reval) {
super (null, reval.evaluator);
this.reval = reval;
}
@ -33,11 +33,11 @@ public class ESRequestData extends ESWrapper {
* 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, req.data is read-only");
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, req.data is read-only");
throw new EcmaScriptException ("Can't delete property, object is read-only");
}
public ESValue getProperty(String propertyName, int hash) throws EcmaScriptException {

View file

@ -77,6 +77,8 @@ public class HopExtension {
reval.esNodePrototype.putHiddenProperty ("href", new NodeHref ("href", evaluator, fp));
reval.esNodePrototype.putHiddenProperty ("setParent", new NodeSetParent ("setParent", evaluator, fp));
reval.esNodePrototype.putHiddenProperty ("invalidate", new NodeInvalidate ("invalidate", evaluator, fp));
reval.esNodePrototype.putHiddenProperty("renderSkin", new RenderSkin ("renderSkin", evaluator, fp, reval, false, false));
reval.esNodePrototype.putHiddenProperty("renderSkin_as_string", new RenderSkin ("renderSkin_as_string", evaluator, fp, reval, false, true));
// methods that give access to properties and global user lists
go.putHiddenProperty("Node", node); // register the constructor for a plain Node object.
@ -97,7 +99,10 @@ public class HopExtension {
go.putHiddenProperty("getXmlDocument", new GlobalGetXmlDocument ("getXmlDocument", evaluator, fp));
go.putHiddenProperty("getHtmlDocument", new GlobalGetHtmlDocument ("getHtmlDocument", evaluator, fp));
go.putHiddenProperty("jdomize", new GlobalJDOM ("jdomize", evaluator, fp));
go.putHiddenProperty("getSkin", new GlobalGetSkin ("getSkin", evaluator, fp, reval));
go.putHiddenProperty("getSkin", new GlobalGetSkin ("getSkin", evaluator, fp));
go.putHiddenProperty("createSkin", new GlobalCreateSkin ("createSkin", evaluator, fp));
go.putHiddenProperty("renderSkin", new RenderSkin ("renderSkin", evaluator, fp, reval, true, false));
go.putHiddenProperty("renderSkin_as_string", new RenderSkin ("renderSkin_as_string", evaluator, fp, reval, true, true));
go.deleteProperty("exit", "exit".hashCode());
// and some methods for session management from JS...
@ -548,19 +553,66 @@ public class HopExtension {
}
}
/**
* Get a parsed Skin from the central skin repository
*/
class GlobalGetSkin extends BuiltinFunctionObject {
RequestEvaluator reval;
GlobalGetSkin (String name, Evaluator evaluator, FunctionPrototype fp, RequestEvaluator reval) {
GlobalGetSkin (String name, Evaluator evaluator, FunctionPrototype fp) {
super (fp, evaluator, name, 1);
}
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
throw new EcmaScriptException ("getSkin() is not implemented yet, use createSkin() instead");
}
}
/**
* Get a parsed Skin from an app-managed skin text
*/
class GlobalCreateSkin extends BuiltinFunctionObject {
GlobalCreateSkin (String name, Evaluator evaluator, FunctionPrototype fp) {
super (fp, evaluator, name, 1);
this.reval = reval;
}
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
if (arguments.length != 1 || ESNull.theNull.equals (arguments[0]))
throw new EcmaScriptException ("getSkin must be called with one String argument!");
return new ESWrapper (new Skin (arguments[0].toString(), reval), evaluator);
return new ESWrapper (new Skin (arguments[0].toString()), evaluator);
}
}
/**
* Render a skin
*/
class RenderSkin extends BuiltinFunctionObject {
RequestEvaluator reval;
boolean global;
boolean asString;
RenderSkin (String name, Evaluator evaluator, FunctionPrototype fp,
RequestEvaluator reval, boolean global, boolean asString) {
super (fp, evaluator, name, 1);
this.reval = reval;
this.global = global;
this.asString = asString;
}
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
if (arguments.length != 1 || !(arguments[0] instanceof ESWrapper))
throw new EcmaScriptException ("renderSkin must be called with one Skin argument!");
try {
Skin skin = (Skin) ((ESWrapper) arguments[0]).toJavaObject ();
ESNode handlerNode = global ? null : (ESNode) thisObject;
if (asString)
reval.res.pushStringBuffer ();
skin.render (reval, handlerNode);
if (asString)
return new ESString (reval.res.popStringBuffer ());
} catch (ClassCastException x) {
throw new EcmaScriptException ("renderSkin must be called with one Skin argument!");
}
return ESNull.theNull;
}
}
class GlobalGetUser extends BuiltinFunctionObject {
RequestEvaluator reval;
GlobalGetUser (String name, Evaluator evaluator, FunctionPrototype fp, RequestEvaluator reval) {

View file

@ -108,7 +108,7 @@ public class RequestEvaluator implements Runnable {
appnode = new ESAppNode (app.appnode, this);
global.putHiddenProperty ("app", appnode);
reqPath = new ArrayPrototype (evaluator.getArrayPrototype(), evaluator);
reqData = new ESRequestData (evaluator.getObjectPrototype(), evaluator, this);
reqData = new ESRequestData (this);
} catch (Exception e) {
System.err.println("Cannot initialize interpreter");

View file

@ -8,6 +8,8 @@ import java.io.*;
import helma.framework.*;
import FESI.Data.*;
import FESI.Exceptions.*;
import helma.objectmodel.INode;
import helma.objectmodel.IServer;
/**
@ -18,10 +20,8 @@ import FESI.Exceptions.*;
public class Skin {
Object[] parts;
RequestEvaluator reval;
public Skin (String content, RequestEvaluator reval) {
this.reval = reval;
public Skin (String content) {
parse (content);
}
@ -55,13 +55,15 @@ public class Skin {
parts = partBuffer.toArray ();
}
public String toString () {
public void render (RequestEvaluator reval, ESNode handlerNode) {
if (parts == null)
return "";
StringBuffer b = new StringBuffer ();
for (int i=0; i<parts.length; i++)
b.append (parts[i]);
return b.toString ();
return;
for (int i=0; i<parts.length; i++) {
if (parts[i] instanceof Macro)
((Macro) parts[i]).render (reval, handlerNode);
else
reval.res.write (parts[i]);
}
}
static final int HANDLER = 0;
@ -73,11 +75,11 @@ public class Skin {
String handler;
String name;
ESObject parameters;
Hashtable parameters;
public Macro (String str) {
parameters = new ObjectPrototype (null, reval.evaluator);
parameters = new Hashtable ();
int l = str.length ();
char cnt[] = new char[l];
@ -108,9 +110,7 @@ public class Skin {
case '\'':
if (!escape && state == PARAMVALUE) {
if (quotechar == cnt[i]) {
try {
parameters.putHiddenProperty (lastParamName, new ESString (b.toString()));
} catch (EcmaScriptException badluck) {}
parameters.put (lastParamName, b.toString());
b.setLength (0);
state = PARAMNAME;
quotechar = '\u0000';
@ -133,9 +133,7 @@ public class Skin {
b.setLength (0);
state = PARAMNAME;
} else if (state == PARAMVALUE && quotechar == '\u0000') {
try {
parameters.putHiddenProperty (lastParamName, new ESString (b.toString()));
} catch (EcmaScriptException badluck) {}
parameters.put (lastParamName, b.toString());
b.setLength (0);
state = PARAMNAME;
} else if (state == PARAMVALUE)
@ -156,43 +154,92 @@ public class Skin {
escape = false;
}
}
if (lastParamName != null && b.length() > 0) try {
parameters.putHiddenProperty (lastParamName, new ESString (b.toString()));
} catch (EcmaScriptException noluck) {}
if (lastParamName != null && b.length() > 0)
parameters.put (lastParamName, b.toString());
}
public String toString () {
public void render (RequestEvaluator reval, ESNode handlerNode) {
if ("response".equalsIgnoreCase (handler)) {
renderFromResponse (reval);
return;
}
try {
ESValue[] arguments = new ESValue[2];
arguments[0] = new ESString (name);
arguments[1] = parameters;
ESNode handlerNode = null;
ESObject handlerObject = null;
ESValue[] arguments = new ESValue[1];
ESRequestData par = new ESRequestData (reval);
par.setData (parameters);
arguments[0] = par;
if (handler != null) {
int l = reval.reqPath.size();
for (int i=l-1; i>=0; i--) {
if (handler.equalsIgnoreCase (((ESNode) reval.reqPath.getProperty(i)).getPrototypeName())) {
handlerNode = (ESNode) reval.reqPath.getProperty(i);
break;
// not a macro handled by global - check handler object
if (handlerNode != null) {
// was called with this object - check it or its parents for matching prototype
if (!handler.equalsIgnoreCase (handlerNode.getPrototypeName ())) {
// the handler object is not what we want
INode n = handlerNode.getNode();
while (n != null) {
if (handler.equalsIgnoreCase (n.getPrototype())) {
handlerObject = reval.getNodeWrapper (n);
break;
}
n = n.getParent ();
}
} else {
// we already have the right handler object
handlerObject = handlerNode;
}
}
} else {
handlerNode = (ESNode) reval.reqPath.getProperty(0);
if (handlerObject == null) {
// eiter because handlerNode == null or the right object wasn't found in the targetNode path
// go check request path for an object with matching prototype
int l = reval.reqPath.size();
for (int i=l-1; i>=0; i--) {
if (handler.equalsIgnoreCase (((ESNode) reval.reqPath.getProperty(i)).getPrototypeName())) {
handlerObject = (ESNode) reval.reqPath.getProperty(i);
break;
}
}
}
} else {
// this is a global macro with no handler specified
handlerObject = reval.global;
}
if (handlerNode != null) {
return handlerNode.doIndirectCall (reval.evaluator, handlerNode, "handleMacro", arguments).toString();
if (handlerObject != null) {
handlerObject.doIndirectCall (reval.evaluator, handlerObject, name+"_macro", arguments);
} else {
return "[HopMacro unhandled: "+handler+"."+name+"]";
String msg = "[HopMacro unhandled: "+handler+"."+name+"]";
reval.res.write (" "+msg+" ");
IServer.getLogger().log (msg);
}
} catch (Exception x) {
return "[HopMacro error: "+x.getMessage()+"]";
String msg = "[HopMacro error: "+x+"]";
reval.res.write (" "+msg+" ");
IServer.getLogger().log (msg);
}
}
private void renderFromResponse (RequestEvaluator reval) {
if ("title".equals (name))
reval.res.write (reval.res.title);
else if ("head".equals (name))
reval.res.write (reval.res.head);
else if ("body".equals (name))
reval.res.write (reval.res.body);
else if ("message".equals (name))
reval.res.write (reval.res.message);
}
public String toString () {
return "[HopMacro: "+handler+","+name+"]";
}
}