Worked on skin support
This commit is contained in:
parent
30f539b396
commit
b0d134b811
5 changed files with 149 additions and 52 deletions
|
@ -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 () {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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+"]";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue