The basic operations now use the IPathElement interface instead
of INode: Path resolution in RequestEvaluator, skin rendering, and href() function. Application will check the rootObject property in the app.properties file and try to create a custom root object, if set.
This commit is contained in:
parent
1b0c4329e5
commit
a2dcc29cec
7 changed files with 186 additions and 83 deletions
|
@ -75,6 +75,11 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IRep
|
||||||
|
|
||||||
private DbMapping rootMapping, userRootMapping, userMapping;
|
private DbMapping rootMapping, userRootMapping, userMapping;
|
||||||
|
|
||||||
|
// the root of the website, if a custom root object is defined.
|
||||||
|
// otherwise this is managed by the NodeManager and not cached here.
|
||||||
|
IPathElement rootObject = null;
|
||||||
|
String rootObjectClass;
|
||||||
|
|
||||||
boolean checkSubnodes;
|
boolean checkSubnodes;
|
||||||
|
|
||||||
String charset;
|
String charset;
|
||||||
|
@ -131,6 +136,9 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IRep
|
||||||
debug = "true".equalsIgnoreCase (props.getProperty ("debug"));
|
debug = "true".equalsIgnoreCase (props.getProperty ("debug"));
|
||||||
checkSubnodes = !"false".equalsIgnoreCase (props.getProperty ("subnodeChecking"));
|
checkSubnodes = !"false".equalsIgnoreCase (props.getProperty ("subnodeChecking"));
|
||||||
|
|
||||||
|
// get class name of root object if defined. Otherwise native Helma objectmodel will be used.
|
||||||
|
rootObjectClass = props.getProperty ("rootObject");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
requestTimeout = Long.parseLong (props.getProperty ("requestTimeout", "60"))*1000l;
|
requestTimeout = Long.parseLong (props.getProperty ("requestTimeout", "60"))*1000l;
|
||||||
} catch (Exception ignore) { }
|
} catch (Exception ignore) { }
|
||||||
|
@ -333,7 +341,20 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IRep
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
public INode getDataRoot () {
|
public IPathElement getDataRoot () {
|
||||||
|
if (rootObjectClass != null) {
|
||||||
|
// create custom root element.
|
||||||
|
// NOTE: This is but a very rough first sketch of an implementation
|
||||||
|
// and needs much more care.
|
||||||
|
if (rootObject == null) try {
|
||||||
|
Class c = Class.forName (rootObjectClass);
|
||||||
|
rootObject = (IPathElement) c.newInstance ();
|
||||||
|
} catch (Throwable x) {
|
||||||
|
System.err.println ("ERROR CREATING ROOT OBJECT: "+x);
|
||||||
|
}
|
||||||
|
return rootObject;
|
||||||
|
}
|
||||||
|
// no custom root object is defined - use standard helma objectmodel
|
||||||
INode root = nmgr.safe.getNode ("0", rootMapping);
|
INode root = nmgr.safe.getNode ("0", rootMapping);
|
||||||
root.setDbMapping (rootMapping);
|
root.setDbMapping (rootMapping);
|
||||||
return root;
|
return root;
|
||||||
|
@ -365,7 +386,7 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IRep
|
||||||
* Return a prototype for a given node. If the node doesn't specify a prototype,
|
* Return a prototype for a given node. If the node doesn't specify a prototype,
|
||||||
* return the generic hopobject prototype.
|
* return the generic hopobject prototype.
|
||||||
*/
|
*/
|
||||||
public Prototype getPrototype (INode n) {
|
public Prototype getPrototype (IPathElement n) {
|
||||||
String protoname = n.getPrototype ();
|
String protoname = n.getPrototype ();
|
||||||
if (protoname == null)
|
if (protoname == null)
|
||||||
return typemgr.getPrototype ("hopobject");
|
return typemgr.getPrototype ("hopobject");
|
||||||
|
@ -444,7 +465,7 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IRep
|
||||||
if (pw != null && pw.equals (password)) {
|
if (pw != null && pw.equals (password)) {
|
||||||
// give the user her piece of persistence
|
// give the user her piece of persistence
|
||||||
u.setNode (unode);
|
u.setNode (unode);
|
||||||
activeUsers.put (unode.getNameOrID (), u.user);
|
activeUsers.put (unode.getName (), u.user);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -477,29 +498,69 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IRep
|
||||||
return pwfile.authenticate (uname, password);
|
return pwfile.authenticate (uname, password);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getNodePath (INode n, String tmpname) {
|
/* public String getNodePath (INode n, String tmpname) {
|
||||||
INode root = getDataRoot ();
|
// FIXME: will fail for non-node roots
|
||||||
|
INode root = (INode) getDataRoot ();
|
||||||
INode users = getUserRoot ();
|
INode users = getUserRoot ();
|
||||||
String siteroot = props.getProperty ("rootPrototype");
|
String siteroot = props.getProperty ("rootPrototype");
|
||||||
String href = n.getUrl (root, users, tmpname, siteroot);
|
String href = n.getUrl (root, users, tmpname, siteroot);
|
||||||
return href;
|
return href;
|
||||||
}
|
} */
|
||||||
|
|
||||||
public String getNodeHref (INode n, String tmpname) {
|
/**
|
||||||
INode root = getDataRoot ();
|
* Return a path to be used in a URL pointing to the given element and action
|
||||||
|
*/
|
||||||
|
public String getNodeHref (IPathElement elem, String actionName) {
|
||||||
|
// FIXME: will fail for non-node roots
|
||||||
|
IPathElement root = getDataRoot ();
|
||||||
INode users = getUserRoot ();
|
INode users = getUserRoot ();
|
||||||
|
|
||||||
// check base uri and optional root prototype from app.properties
|
// check base uri and optional root prototype from app.properties
|
||||||
String base = props.getProperty ("baseURI");
|
String base = props.getProperty ("baseURI");
|
||||||
String siteroot = props.getProperty ("rootPrototype");
|
String rootproto = props.getProperty ("rootPrototype");
|
||||||
|
|
||||||
if (base != null || baseURI == null)
|
if (base != null || baseURI == null)
|
||||||
setBaseURI (base);
|
setBaseURI (base);
|
||||||
String href = n.getUrl (root, users, tmpname, siteroot);
|
|
||||||
|
// String href = n.getUrl (root, users, tmpname, siteroot);
|
||||||
|
|
||||||
|
String divider = "/";
|
||||||
|
StringBuffer b = new StringBuffer ();
|
||||||
|
IPathElement p = elem;
|
||||||
|
int loopWatch = 0;
|
||||||
|
|
||||||
|
while (p != null && p.getParentElement () != null && p != root) {
|
||||||
|
|
||||||
|
if (rootproto != null && rootproto.equals (p.getPrototype ()))
|
||||||
|
break;
|
||||||
|
|
||||||
|
b.insert (0, divider);
|
||||||
|
|
||||||
|
// users always have a canonical URL like /users/username
|
||||||
|
if ("user".equals (p.getPrototype ())) {
|
||||||
|
b.insert (0, UrlEncoder.encode (p.getElementName ()));
|
||||||
|
p = users;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
b.insert (0, UrlEncoder.encode (p.getElementName ()));
|
||||||
|
|
||||||
|
p = p.getParentElement ();
|
||||||
|
|
||||||
|
if (loopWatch++ > 20)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p == users) {
|
||||||
|
b.insert (0, divider);
|
||||||
|
b.insert (0, "users");
|
||||||
|
}
|
||||||
|
String href = b.toString()+UrlEncoder.encode (actionName);
|
||||||
|
|
||||||
return baseURI + href;
|
return baseURI + href;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setBaseURI (String uri) {
|
public void setBaseURI (String uri) {
|
||||||
if (uri == null)
|
if (uri == null)
|
||||||
this.baseURI = "/";
|
this.baseURI = "/";
|
||||||
|
|
|
@ -130,7 +130,7 @@ public class ESAppNode extends ESNode {
|
||||||
|
|
||||||
|
|
||||||
public String toString () {
|
public String toString () {
|
||||||
return ("AppNode "+node.getNameOrID ());
|
return ("AppNode "+node.getElementName ());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -413,6 +413,10 @@ public class ESNode extends ObjectPrototype {
|
||||||
lastError = null;
|
lastError = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Object toJavaObject () {
|
||||||
|
return getNode ();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An ESNode equals another object if it is an ESNode that wraps the same INode
|
* 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!
|
* or the wrapped INode itself. FIXME: doesen't check dbmapping/type!
|
||||||
|
|
|
@ -5,6 +5,7 @@ package helma.framework.core;
|
||||||
|
|
||||||
import helma.objectmodel.*;
|
import helma.objectmodel.*;
|
||||||
import helma.util.*;
|
import helma.util.*;
|
||||||
|
import helma.framework.IPathElement;
|
||||||
import FESI.Interpreter.*;
|
import FESI.Interpreter.*;
|
||||||
import FESI.Exceptions.*;
|
import FESI.Exceptions.*;
|
||||||
import FESI.Extensions.*;
|
import FESI.Extensions.*;
|
||||||
|
@ -76,7 +77,7 @@ public class HopExtension {
|
||||||
reval.esNodePrototype.putHiddenProperty ("editor", new NodeEditor ("editor", evaluator, fp));
|
reval.esNodePrototype.putHiddenProperty ("editor", new NodeEditor ("editor", evaluator, fp));
|
||||||
reval.esNodePrototype.putHiddenProperty ("chooser", new NodeChooser ("chooser", evaluator, fp));
|
reval.esNodePrototype.putHiddenProperty ("chooser", new NodeChooser ("chooser", evaluator, fp));
|
||||||
reval.esNodePrototype.putHiddenProperty ("multiChooser", new MultiNodeChooser ("multiChooser", evaluator, fp));
|
reval.esNodePrototype.putHiddenProperty ("multiChooser", new MultiNodeChooser ("multiChooser", evaluator, fp));
|
||||||
reval.esNodePrototype.putHiddenProperty ("path", new NodePath ("path", evaluator, fp));
|
reval.esNodePrototype.putHiddenProperty ("path", new NodeHref ("path", evaluator, fp));
|
||||||
reval.esNodePrototype.putHiddenProperty ("href", new NodeHref ("href", evaluator, fp));
|
reval.esNodePrototype.putHiddenProperty ("href", new NodeHref ("href", evaluator, fp));
|
||||||
reval.esNodePrototype.putHiddenProperty ("setParent", new NodeSetParent ("setParent", evaluator, fp));
|
reval.esNodePrototype.putHiddenProperty ("setParent", new NodeSetParent ("setParent", evaluator, fp));
|
||||||
reval.esNodePrototype.putHiddenProperty ("invalidate", new NodeInvalidate ("invalidate", evaluator, fp));
|
reval.esNodePrototype.putHiddenProperty ("invalidate", new NodeInvalidate ("invalidate", evaluator, fp));
|
||||||
|
@ -574,12 +575,12 @@ public class HopExtension {
|
||||||
this.global = global;
|
this.global = global;
|
||||||
this.asString = asString;
|
this.asString = asString;
|
||||||
}
|
}
|
||||||
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
|
public ESValue callFunction (ESObject thisObj, ESValue[] arguments) throws EcmaScriptException {
|
||||||
if (arguments.length < 1 || arguments.length > 2 || arguments[0] ==null || arguments[0] == ESNull.theNull)
|
if (arguments.length < 1 || arguments.length > 2 || arguments[0] ==null || arguments[0] == ESNull.theNull)
|
||||||
throw new EcmaScriptException ("renderSkin must be called with one Skin argument and an optional parameter argument");
|
throw new EcmaScriptException ("renderSkin must be called with one Skin argument and an optional parameter argument");
|
||||||
try {
|
try {
|
||||||
Skin skin = null;
|
Skin skin = null;
|
||||||
ESNode handlerNode = global ? null : (ESNode) thisObject;
|
ESObject thisObject = global ? null : thisObj;
|
||||||
ESObject paramObject = null;
|
ESObject paramObject = null;
|
||||||
if (arguments.length > 1 && arguments[1] instanceof ESObject)
|
if (arguments.length > 1 && arguments[1] instanceof ESObject)
|
||||||
paramObject = (ESObject) arguments[1];
|
paramObject = (ESObject) arguments[1];
|
||||||
|
@ -592,11 +593,11 @@ public class HopExtension {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (skin == null)
|
if (skin == null)
|
||||||
skin = reval.getSkin (handlerNode, arguments[0].toString ());
|
skin = reval.getSkin (thisObject, arguments[0].toString ());
|
||||||
if (asString)
|
if (asString)
|
||||||
reval.res.pushStringBuffer ();
|
reval.res.pushStringBuffer ();
|
||||||
if (skin != null)
|
if (skin != null)
|
||||||
skin.render (reval, handlerNode, paramObject);
|
skin.render (reval, thisObject, paramObject);
|
||||||
else
|
else
|
||||||
reval.res.write ("[Skin not found: "+arguments[0]+"]");
|
reval.res.write ("[Skin not found: "+arguments[0]+"]");
|
||||||
if (asString)
|
if (asString)
|
||||||
|
@ -916,7 +917,7 @@ public class HopExtension {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class NodePath extends BuiltinFunctionObject {
|
/* class NodePath extends BuiltinFunctionObject {
|
||||||
NodePath (String name, Evaluator evaluator, FunctionPrototype fp) {
|
NodePath (String name, Evaluator evaluator, FunctionPrototype fp) {
|
||||||
super (fp, evaluator, name, 1);
|
super (fp, evaluator, name, 1);
|
||||||
}
|
}
|
||||||
|
@ -925,7 +926,7 @@ public class HopExtension {
|
||||||
String tmpname = arguments[0].toString ();
|
String tmpname = arguments[0].toString ();
|
||||||
return new ESString (app.getNodePath (n, tmpname));
|
return new ESString (app.getNodePath (n, tmpname));
|
||||||
}
|
}
|
||||||
}
|
} */
|
||||||
|
|
||||||
class NodeSetParent extends BuiltinFunctionObject {
|
class NodeSetParent extends BuiltinFunctionObject {
|
||||||
NodeSetParent (String name, Evaluator evaluator, FunctionPrototype fp) {
|
NodeSetParent (String name, Evaluator evaluator, FunctionPrototype fp) {
|
||||||
|
@ -943,33 +944,33 @@ public class HopExtension {
|
||||||
super (fp, evaluator, name, 1);
|
super (fp, evaluator, name, 1);
|
||||||
}
|
}
|
||||||
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
|
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
|
||||||
INode n = ((ESNode) thisObject).getNode ();
|
IPathElement elem = (IPathElement) thisObject.toJavaObject ();
|
||||||
String tmpname = arguments.length == 0 ? "" : arguments[0].toString ();
|
String tmpname = arguments.length == 0 ? "" : arguments[0].toString ();
|
||||||
String basicHref =app.getNodeHref (n, tmpname);
|
String basicHref =app.getNodeHref (elem, tmpname);
|
||||||
String hrefSkin = app.props.getProperty ("hrefSkin");
|
String hrefSkin = app.props.getProperty ("hrefSkin");
|
||||||
// FIXME: we should actually walk down the path from the object we called href() on
|
// FIXME: we should actually walk down the path from the object we called href() on
|
||||||
// instead we move down the URL path.
|
// instead we move down the URL path.
|
||||||
if (hrefSkin != null) {
|
if (hrefSkin != null) {
|
||||||
// we need to post-process the href with a skin for this application
|
// we need to post-process the href with a skin for this application
|
||||||
// first, look in the object href was called on.
|
// first, look in the object href was called on.
|
||||||
INode sn = n;
|
IPathElement skinElem = elem;
|
||||||
Skin skin = null;
|
Skin skin = null;
|
||||||
while (skin == null && sn != null) {
|
while (skin == null && skinElem != null) {
|
||||||
Prototype proto = app.getPrototype (sn);
|
Prototype proto = app.getPrototype (skinElem);
|
||||||
if (proto != null)
|
if (proto != null)
|
||||||
skin = proto.getSkin (hrefSkin);
|
skin = proto.getSkin (hrefSkin);
|
||||||
if (skin == null)
|
if (skin == null)
|
||||||
sn = sn.getParent ();
|
skinElem = skinElem.getParentElement ();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (skin != null) {
|
if (skin != null) {
|
||||||
ESNode esn = reval.getNodeWrapper (sn);
|
ESObject eso = reval.getElementWrapper (skinElem);
|
||||||
return renderSkin (skin, basicHref, esn);
|
return renderSkin (skin, basicHref, eso);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new ESString (basicHref);
|
return new ESString (basicHref);
|
||||||
}
|
}
|
||||||
private ESString renderSkin (Skin skin, String path, ESNode obj) throws EcmaScriptException {
|
private ESString renderSkin (Skin skin, String path, ESObject obj) throws EcmaScriptException {
|
||||||
reval.res.pushStringBuffer ();
|
reval.res.pushStringBuffer ();
|
||||||
ESObject param = new ObjectPrototype (null, reval.evaluator);
|
ESObject param = new ObjectPrototype (null, reval.evaluator);
|
||||||
param.putProperty ("path", new ESString (path), "path".hashCode ());
|
param.putProperty ("path", new ESString (path), "path".hashCode ());
|
||||||
|
@ -1040,7 +1041,7 @@ public class HopExtension {
|
||||||
buffer.append ("<input type=radio name=\"");
|
buffer.append ("<input type=radio name=\"");
|
||||||
buffer.append (name);
|
buffer.append (name);
|
||||||
buffer.append ("\" value=\"");
|
buffer.append ("\" value=\"");
|
||||||
buffer.append (next.getNameOrID ()+"\"");
|
buffer.append (next.getElementName ()+"\"");
|
||||||
if (target == next)
|
if (target == next)
|
||||||
buffer.append (" checked");
|
buffer.append (" checked");
|
||||||
buffer.append (">");
|
buffer.append (">");
|
||||||
|
@ -1062,7 +1063,7 @@ public class HopExtension {
|
||||||
buffer.append ("<input type=checkbox name=\"");
|
buffer.append ("<input type=checkbox name=\"");
|
||||||
buffer.append (name);
|
buffer.append (name);
|
||||||
buffer.append ("\" value=");
|
buffer.append ("\" value=");
|
||||||
buffer.append (next.getNameOrID ());
|
buffer.append (next.getElementName ());
|
||||||
if (target.contains (next) > -1)
|
if (target.contains (next) > -1)
|
||||||
buffer.append (" checked");
|
buffer.append (" checked");
|
||||||
buffer.append (">");
|
buffer.append (">");
|
||||||
|
|
|
@ -77,7 +77,7 @@ public class RequestEvaluator implements Runnable {
|
||||||
static final int XMLRPC = 2; // via XML-RPC
|
static final int XMLRPC = 2; // via XML-RPC
|
||||||
static final int INTERNAL = 3; // generic function call, e.g. by scheduler
|
static final int INTERNAL = 3; // generic function call, e.g. by scheduler
|
||||||
|
|
||||||
INode root, userroot, currentNode;
|
// INode root, currentNode;
|
||||||
INode[] skinmanagers;
|
INode[] skinmanagers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -99,6 +99,7 @@ public class RequestEvaluator implements Runnable {
|
||||||
private void initEvaluator () {
|
private void initEvaluator () {
|
||||||
try {
|
try {
|
||||||
evaluator = new Evaluator();
|
evaluator = new Evaluator();
|
||||||
|
evaluator.reval = this;
|
||||||
global = evaluator.getGlobalObject();
|
global = evaluator.getGlobalObject();
|
||||||
for (int i=0; i<extensions.length; i++)
|
for (int i=0; i<extensions.length; i++)
|
||||||
evaluator.addExtension (extensions[i]);
|
evaluator.addExtension (extensions[i]);
|
||||||
|
@ -140,7 +141,7 @@ public class RequestEvaluator implements Runnable {
|
||||||
try {
|
try {
|
||||||
do {
|
do {
|
||||||
|
|
||||||
// app.logEvent ("got request "+reqtype);
|
IPathElement root, currentElement;
|
||||||
// reset skinManager
|
// reset skinManager
|
||||||
skinmanagers = null;
|
skinmanagers = null;
|
||||||
|
|
||||||
|
@ -152,7 +153,7 @@ public class RequestEvaluator implements Runnable {
|
||||||
while (!done) {
|
while (!done) {
|
||||||
|
|
||||||
current = null;
|
current = null;
|
||||||
currentNode = null;
|
currentElement = null;
|
||||||
reqPath.setSize (0);
|
reqPath.setSize (0);
|
||||||
// delete path objects-via-prototype
|
// delete path objects-via-prototype
|
||||||
for (Enumeration en=reqPath.getAllProperties(); en.hasMoreElements(); ) {
|
for (Enumeration en=reqPath.getAllProperties(); en.hasMoreElements(); ) {
|
||||||
|
@ -176,7 +177,7 @@ public class RequestEvaluator implements Runnable {
|
||||||
|
|
||||||
ESUser esu = (ESUser) getNodeWrapper (user);
|
ESUser esu = (ESUser) getNodeWrapper (user);
|
||||||
// esu.setUser (user);
|
// esu.setUser (user);
|
||||||
global.putHiddenProperty ("root", getNodeWrapper (root));
|
global.putHiddenProperty ("root", getElementWrapper (root));
|
||||||
global.putHiddenProperty("user", esu);
|
global.putHiddenProperty("user", esu);
|
||||||
global.putHiddenProperty ("req", new ESWrapper (req, evaluator));
|
global.putHiddenProperty ("req", new ESWrapper (req, evaluator));
|
||||||
global.putHiddenProperty ("res", new ESWrapper (res, evaluator));
|
global.putHiddenProperty ("res", new ESWrapper (res, evaluator));
|
||||||
|
@ -197,8 +198,8 @@ public class RequestEvaluator implements Runnable {
|
||||||
|
|
||||||
if (error != null) {
|
if (error != null) {
|
||||||
// there was an error in the previous loop, call error handler
|
// there was an error in the previous loop, call error handler
|
||||||
currentNode = root;
|
currentElement = root;
|
||||||
current = getNodeWrapper (root);
|
current = getElementWrapper (root);
|
||||||
reqPath.putProperty (0, current);
|
reqPath.putProperty (0, current);
|
||||||
reqPath.putHiddenProperty ("root", current);
|
reqPath.putHiddenProperty ("root", current);
|
||||||
Prototype p = app.getPrototype (root);
|
Prototype p = app.getPrototype (root);
|
||||||
|
@ -208,8 +209,8 @@ public class RequestEvaluator implements Runnable {
|
||||||
throw new RuntimeException (error);
|
throw new RuntimeException (error);
|
||||||
|
|
||||||
} else if (req.path == null || "".equals (req.path.trim ())) {
|
} else if (req.path == null || "".equals (req.path.trim ())) {
|
||||||
currentNode = root;
|
currentElement = root;
|
||||||
current = getNodeWrapper (root);
|
current = getElementWrapper (root);
|
||||||
reqPath.putProperty (0, current);
|
reqPath.putProperty (0, current);
|
||||||
reqPath.putHiddenProperty ("root", current);
|
reqPath.putHiddenProperty ("root", current);
|
||||||
Prototype p = app.getPrototype (root);
|
Prototype p = app.getPrototype (root);
|
||||||
|
@ -233,38 +234,38 @@ public class RequestEvaluator implements Runnable {
|
||||||
for (int i=0; i<ntokens; i++)
|
for (int i=0; i<ntokens; i++)
|
||||||
pathItems[i] = st.nextToken ();
|
pathItems[i] = st.nextToken ();
|
||||||
|
|
||||||
currentNode = root;
|
currentElement = root;
|
||||||
current = getNodeWrapper (root);
|
current = getElementWrapper (root);
|
||||||
reqPath.putProperty (0, current);
|
reqPath.putProperty (0, current);
|
||||||
reqPath.putHiddenProperty ("root", current);
|
reqPath.putHiddenProperty ("root", current);
|
||||||
|
|
||||||
for (int i=0; i<ntokens; i++) {
|
for (int i=0; i<ntokens; i++) {
|
||||||
|
|
||||||
if (currentNode == null)
|
if (currentElement == null)
|
||||||
throw new FrameworkException ("Object not found.");
|
throw new FrameworkException ("Object not found.");
|
||||||
|
|
||||||
// the first token in the path needs to be treated seprerately,
|
// the first token in the path needs to be treated seprerately,
|
||||||
// because "/user" is a shortcut to the current user session, while "/users"
|
// because "/user" is a shortcut to the current user session, while "/users"
|
||||||
// is the mounting point for all users.
|
// is the mounting point for all users.
|
||||||
if (i == 0 && "user".equalsIgnoreCase (pathItems[i])) {
|
if (i == 0 && "user".equalsIgnoreCase (pathItems[i])) {
|
||||||
currentNode = user.getNode ();
|
// currentElement = user.getNode ();
|
||||||
if (currentNode != null) {
|
if (currentElement != null) {
|
||||||
current = getNodeWrapper (currentNode);
|
current = getElementWrapper (currentElement);
|
||||||
reqPath.putProperty (1, current);
|
reqPath.putProperty (1, current);
|
||||||
reqPath.putHiddenProperty ("user", current);
|
reqPath.putHiddenProperty ("user", current);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (i == 0 && "users".equalsIgnoreCase (pathItems[i])) {
|
} else if (i == 0 && "users".equalsIgnoreCase (pathItems[i])) {
|
||||||
currentNode = app.getUserRoot ();
|
// currentElement = app.getUserRoot ();
|
||||||
isProperty = true;
|
// isProperty = true;
|
||||||
if (currentNode != null) {
|
if (currentElement != null) {
|
||||||
current = getNodeWrapper (currentNode);
|
current = getElementWrapper (currentElement);
|
||||||
reqPath.putProperty (1, current);
|
reqPath.putProperty (1, current);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (i == ntokens-1) {
|
if (i == ntokens-1) {
|
||||||
Prototype p = app.getPrototype (currentNode);
|
Prototype p = app.getPrototype (currentElement);
|
||||||
if (p != null)
|
if (p != null)
|
||||||
action = p.getActionOrTemplate (pathItems[i]);
|
action = p.getActionOrTemplate (pathItems[i]);
|
||||||
}
|
}
|
||||||
|
@ -273,23 +274,25 @@ public class RequestEvaluator implements Runnable {
|
||||||
|
|
||||||
if (pathItems[i].length () == 0)
|
if (pathItems[i].length () == 0)
|
||||||
continue;
|
continue;
|
||||||
if (isProperty) // get next element as property
|
|
||||||
currentNode = currentNode.getNode (pathItems[i], false);
|
currentElement = currentElement.getChildElement (pathItems[i]);
|
||||||
|
/* if (isProperty) // get next element as property
|
||||||
|
currentElement = currentElement.getNode (pathItems[i], false);
|
||||||
else {
|
else {
|
||||||
// try to get next element as subnode first, then fall back to property
|
// try to get next element as subnode first, then fall back to property
|
||||||
INode nextNode = currentNode.getSubnode (pathItems[i]);
|
INode nextNode = currentElement.getSubnode (pathItems[i]);
|
||||||
if (nextNode == null)
|
if (nextNode == null)
|
||||||
nextNode = currentNode.getNode (pathItems[i], false);
|
nextNode = currentElement.getNode (pathItems[i], false);
|
||||||
currentNode = nextNode;
|
currentElement = nextNode;
|
||||||
}
|
}
|
||||||
isProperty = false;
|
isProperty = false; */
|
||||||
|
|
||||||
// add object to request path if suitable
|
// add object to request path if suitable
|
||||||
if (currentNode != null) {
|
if (currentElement != null) {
|
||||||
// add to reqPath array
|
// add to reqPath array
|
||||||
current = getNodeWrapper (currentNode);
|
current = getElementWrapper (currentElement);
|
||||||
reqPath.putProperty (reqPath.size(), current);
|
reqPath.putProperty (reqPath.size(), current);
|
||||||
String pt = currentNode.getPrototype ();
|
String pt = currentElement.getPrototype ();
|
||||||
if (pt != null) {
|
if (pt != null) {
|
||||||
// if a prototype exists, add also by prototype name
|
// if a prototype exists, add also by prototype name
|
||||||
reqPath.putHiddenProperty (pt, current);
|
reqPath.putHiddenProperty (pt, current);
|
||||||
|
@ -300,13 +303,13 @@ public class RequestEvaluator implements Runnable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentNode == null)
|
if (currentElement == null)
|
||||||
throw new FrameworkException ("Object not found.");
|
throw new FrameworkException ("Object not found.");
|
||||||
else
|
else
|
||||||
current = getNodeWrapper (currentNode);
|
current = getElementWrapper (currentElement);
|
||||||
|
|
||||||
if (action == null) {
|
if (action == null) {
|
||||||
Prototype p = app.getPrototype (currentNode);
|
Prototype p = app.getPrototype (currentElement);
|
||||||
if (p != null)
|
if (p != null)
|
||||||
action = p.getActionOrTemplate (null);
|
action = p.getActionOrTemplate (null);
|
||||||
}
|
}
|
||||||
|
@ -328,7 +331,7 @@ public class RequestEvaluator implements Runnable {
|
||||||
action = p.getActionOrTemplate (notFoundAction);
|
action = p.getActionOrTemplate (notFoundAction);
|
||||||
if (action == null)
|
if (action == null)
|
||||||
throw new FrameworkException (notfound.getMessage ());
|
throw new FrameworkException (notfound.getMessage ());
|
||||||
current = getNodeWrapper (root);
|
current = getElementWrapper (root);
|
||||||
}
|
}
|
||||||
|
|
||||||
localrtx.timer.endEvent (requestPath+" init");
|
localrtx.timer.endEvent (requestPath+" init");
|
||||||
|
@ -430,7 +433,7 @@ public class RequestEvaluator implements Runnable {
|
||||||
|
|
||||||
root = app.getDataRoot ();
|
root = app.getDataRoot ();
|
||||||
|
|
||||||
global.putHiddenProperty ("root", getNodeWrapper (root));
|
global.putHiddenProperty ("root", getElementWrapper (root));
|
||||||
global.deleteProperty("user", "user".hashCode());
|
global.deleteProperty("user", "user".hashCode());
|
||||||
global.deleteProperty ("req", "req".hashCode());
|
global.deleteProperty ("req", "req".hashCode());
|
||||||
global.putHiddenProperty ("res", ESLoader.normalizeValue(res, evaluator));
|
global.putHiddenProperty ("res", ESLoader.normalizeValue(res, evaluator));
|
||||||
|
@ -439,7 +442,7 @@ public class RequestEvaluator implements Runnable {
|
||||||
|
|
||||||
// convert arguments
|
// convert arguments
|
||||||
int l = args.size ();
|
int l = args.size ();
|
||||||
current = getNodeWrapper (root);
|
current = getElementWrapper (root);
|
||||||
if (method.indexOf (".") > -1) {
|
if (method.indexOf (".") > -1) {
|
||||||
StringTokenizer st = new StringTokenizer (method, ".");
|
StringTokenizer st = new StringTokenizer (method, ".");
|
||||||
int cnt = st.countTokens ();
|
int cnt = st.countTokens ();
|
||||||
|
@ -491,7 +494,7 @@ public class RequestEvaluator implements Runnable {
|
||||||
|
|
||||||
root = app.getDataRoot ();
|
root = app.getDataRoot ();
|
||||||
|
|
||||||
global.putHiddenProperty ("root", getNodeWrapper (root));
|
global.putHiddenProperty ("root", getElementWrapper (root));
|
||||||
global.deleteProperty("user", "user".hashCode());
|
global.deleteProperty("user", "user".hashCode());
|
||||||
global.deleteProperty ("req", "req".hashCode());
|
global.deleteProperty ("req", "req".hashCode());
|
||||||
global.putHiddenProperty ("res", ESLoader.normalizeValue(res, evaluator));
|
global.putHiddenProperty ("res", ESLoader.normalizeValue(res, evaluator));
|
||||||
|
@ -642,13 +645,13 @@ public class RequestEvaluator implements Runnable {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized ESValue invokeFunction (INode node, String functionName, ESValue[] args)
|
public synchronized ESValue invokeFunction (IPathElement node, String functionName, ESValue[] args)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
ESObject obj = null;
|
ESObject obj = null;
|
||||||
if (node == null)
|
if (node == null)
|
||||||
obj = global;
|
obj = global;
|
||||||
else
|
else
|
||||||
obj = getNodeWrapper (node);
|
obj = getElementWrapper (node);
|
||||||
return invokeFunction (obj, functionName, args);
|
return invokeFunction (obj, functionName, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -741,8 +744,14 @@ public class RequestEvaluator implements Runnable {
|
||||||
Prototype proto = null;
|
Prototype proto = null;
|
||||||
if (thisObject == null)
|
if (thisObject == null)
|
||||||
proto = app.typemgr.getPrototype ("global");
|
proto = app.typemgr.getPrototype ("global");
|
||||||
else
|
else {
|
||||||
proto = app.getPrototype (((ESNode) thisObject).getNode ());
|
try {
|
||||||
|
IPathElement elem = (IPathElement) thisObject.toJavaObject ();
|
||||||
|
proto = app.getPrototype (elem);
|
||||||
|
} catch (ClassCastException wrongClass) {
|
||||||
|
throw new RuntimeException ("Can't render a skin on something that is not a path element: "+wrongClass);
|
||||||
|
}
|
||||||
|
}
|
||||||
return getSkin (proto, skinname);
|
return getSkin (proto, skinname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -829,6 +838,21 @@ public class RequestEvaluator implements Runnable {
|
||||||
return (ESNode) objectcache.get (n);
|
return (ESNode) objectcache.get (n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public ESObject getElementWrapper (IPathElement e) {
|
||||||
|
if (e instanceof INode)
|
||||||
|
return getNodeWrapper ((INode) e);
|
||||||
|
|
||||||
|
String protoname = e.getPrototype ();
|
||||||
|
|
||||||
|
ObjectPrototype op = (ObjectPrototype) prototypes.get (protoname);
|
||||||
|
|
||||||
|
return new ESGenericObject (op, evaluator, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a script wrapper for an implemntation of helma.objectmodel.INode
|
||||||
|
*/
|
||||||
public ESNode getNodeWrapper (INode n) {
|
public ESNode getNodeWrapper (INode n) {
|
||||||
|
|
||||||
if (n == null)
|
if (n == null)
|
||||||
|
|
|
@ -72,12 +72,24 @@ public class Skin {
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void render (RequestEvaluator reval, ESNode thisNode, ESObject paramObject) throws RedirectException {
|
public void render (RequestEvaluator reval, ESObject thisObject, ESObject paramObject) throws RedirectException {
|
||||||
|
|
||||||
if (parts == null)
|
if (parts == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
IPathElement elem = null;
|
||||||
|
|
||||||
|
if (thisObject != null) {
|
||||||
|
try {
|
||||||
|
elem = (IPathElement) thisObject.toJavaObject ();
|
||||||
|
} catch (ClassCastException wrongClass) {
|
||||||
|
throw new RuntimeException ("Can't render a skin on something that is not a path element: "+wrongClass);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (int i=0; i<parts.length; i++) {
|
for (int i=0; i<parts.length; i++) {
|
||||||
if (parts[i] instanceof Macro)
|
if (parts[i] instanceof Macro)
|
||||||
((Macro) parts[i]).render (reval, thisNode, paramObject);
|
((Macro) parts[i]).render (reval, thisObject, elem, paramObject);
|
||||||
else
|
else
|
||||||
reval.res.write (parts[i]);
|
reval.res.write (parts[i]);
|
||||||
}
|
}
|
||||||
|
@ -193,7 +205,7 @@ public class Skin {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void render (RequestEvaluator reval, ESNode thisNode, ESObject paramObject) throws RedirectException {
|
public void render (RequestEvaluator reval, ESObject thisObject, IPathElement elem, ESObject paramObject) throws RedirectException {
|
||||||
|
|
||||||
if (notallowed) {
|
if (notallowed) {
|
||||||
String h = handler == null ? "global" : handler;
|
String h = handler == null ? "global" : handler;
|
||||||
|
@ -223,32 +235,33 @@ public class Skin {
|
||||||
if ("currentuser".equalsIgnoreCase (handler)) {
|
if ("currentuser".equalsIgnoreCase (handler)) {
|
||||||
// as a special convention, we use "currentuser" to access macros in the current user object
|
// as a special convention, we use "currentuser" to access macros in the current user object
|
||||||
handlerObject = reval.getNodeWrapper (reval.user.getNode ());
|
handlerObject = reval.getNodeWrapper (reval.user.getNode ());
|
||||||
} else if (thisNode != null) {
|
} else if (elem != null) {
|
||||||
// not a global macro - need to find handler object
|
// not a global macro - need to find handler object
|
||||||
// was called with this object - check it or its parents for matching prototype
|
// was called with this object - check it or its parents for matching prototype
|
||||||
if (!handler.equalsIgnoreCase ("this") && !handler.equalsIgnoreCase (thisNode.getPrototypeName ())) {
|
if (!handler.equalsIgnoreCase ("this") && !handler.equalsIgnoreCase (elem.getPrototype ())) {
|
||||||
// the handler object is not what we want
|
// the handler object is not what we want
|
||||||
INode n = thisNode.getNode();
|
IPathElement n = elem;
|
||||||
// walk down parent chain to find handler object
|
// walk down parent chain to find handler object
|
||||||
while (n != null) {
|
while (n != null) {
|
||||||
if (handler.equalsIgnoreCase (n.getPrototype())) {
|
if (handler.equalsIgnoreCase (n.getPrototype())) {
|
||||||
handlerObject = reval.getNodeWrapper (n);
|
handlerObject = reval.getElementWrapper (n);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
n = n.getParent ();
|
n = n.getParentElement ();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// we already have the right handler object
|
// we already have the right handler object
|
||||||
handlerObject = thisNode;
|
handlerObject = thisObject;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handlerObject == null) {
|
if (handlerObject == null) {
|
||||||
// eiter because thisNode == null or the right object wasn't found in the targetNode path
|
// eiter because thisObject == null or the right object wasn't found in the object's parent path
|
||||||
// go check request path for an object with matching prototype
|
// go check request path for an object with matching prototype
|
||||||
int l = reval.reqPath.size();
|
int l = reval.reqPath.size();
|
||||||
for (int i=l-1; i>=0; i--) {
|
for (int i=l-1; i>=0; i--) {
|
||||||
if (handler.equalsIgnoreCase (((ESNode) reval.reqPath.getProperty(i)).getPrototypeName())) {
|
IPathElement pathelem = (IPathElement) reval.reqPath.getProperty (i).toJavaObject ();
|
||||||
|
if (handler.equalsIgnoreCase (pathelem.getPrototype ())) {
|
||||||
handlerObject = (ESNode) reval.reqPath.getProperty(i);
|
handlerObject = (ESNode) reval.reqPath.getProperty(i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ public class User implements Serializable {
|
||||||
nhandle = null;
|
nhandle = null;
|
||||||
uid = null;
|
uid = null;
|
||||||
} else {
|
} else {
|
||||||
uid = n.getNameOrID ();
|
uid = n.getElementName ();
|
||||||
nhandle = ((helma.objectmodel.db.Node) n).getHandle ();
|
nhandle = ((helma.objectmodel.db.Node) n).getHandle ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue