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;
|
||||
|
||||
// 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;
|
||||
|
||||
String charset;
|
||||
|
@ -131,6 +136,9 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IRep
|
|||
debug = "true".equalsIgnoreCase (props.getProperty ("debug"));
|
||||
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 {
|
||||
requestTimeout = Long.parseLong (props.getProperty ("requestTimeout", "60"))*1000l;
|
||||
} catch (Exception ignore) { }
|
||||
|
@ -333,7 +341,20 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IRep
|
|||
// 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);
|
||||
root.setDbMapping (rootMapping);
|
||||
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 the generic hopobject prototype.
|
||||
*/
|
||||
public Prototype getPrototype (INode n) {
|
||||
public Prototype getPrototype (IPathElement n) {
|
||||
String protoname = n.getPrototype ();
|
||||
if (protoname == null)
|
||||
return typemgr.getPrototype ("hopobject");
|
||||
|
@ -444,7 +465,7 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IRep
|
|||
if (pw != null && pw.equals (password)) {
|
||||
// give the user her piece of persistence
|
||||
u.setNode (unode);
|
||||
activeUsers.put (unode.getNameOrID (), u.user);
|
||||
activeUsers.put (unode.getName (), u.user);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -477,29 +498,69 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, IRep
|
|||
return pwfile.authenticate (uname, password);
|
||||
}
|
||||
|
||||
public String getNodePath (INode n, String tmpname) {
|
||||
INode root = getDataRoot ();
|
||||
/* public String getNodePath (INode n, String tmpname) {
|
||||
// FIXME: will fail for non-node roots
|
||||
INode root = (INode) getDataRoot ();
|
||||
INode users = getUserRoot ();
|
||||
String siteroot = props.getProperty ("rootPrototype");
|
||||
String href = n.getUrl (root, users, tmpname, siteroot);
|
||||
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 ();
|
||||
|
||||
// check base uri and optional root prototype from app.properties
|
||||
String base = props.getProperty ("baseURI");
|
||||
String siteroot = props.getProperty ("rootPrototype");
|
||||
String rootproto = props.getProperty ("rootPrototype");
|
||||
|
||||
if (base != null || baseURI == null)
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
public void setBaseURI (String uri) {
|
||||
if (uri == null)
|
||||
this.baseURI = "/";
|
||||
|
|
|
@ -130,7 +130,7 @@ public class ESAppNode extends ESNode {
|
|||
|
||||
|
||||
public String toString () {
|
||||
return ("AppNode "+node.getNameOrID ());
|
||||
return ("AppNode "+node.getElementName ());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -413,6 +413,10 @@ public class ESNode extends ObjectPrototype {
|
|||
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!
|
||||
|
|
|
@ -5,6 +5,7 @@ package helma.framework.core;
|
|||
|
||||
import helma.objectmodel.*;
|
||||
import helma.util.*;
|
||||
import helma.framework.IPathElement;
|
||||
import FESI.Interpreter.*;
|
||||
import FESI.Exceptions.*;
|
||||
import FESI.Extensions.*;
|
||||
|
@ -76,7 +77,7 @@ public class HopExtension {
|
|||
reval.esNodePrototype.putHiddenProperty ("editor", new NodeEditor ("editor", evaluator, fp));
|
||||
reval.esNodePrototype.putHiddenProperty ("chooser", new NodeChooser ("chooser", 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 ("setParent", new NodeSetParent ("setParent", evaluator, fp));
|
||||
reval.esNodePrototype.putHiddenProperty ("invalidate", new NodeInvalidate ("invalidate", evaluator, fp));
|
||||
|
@ -574,12 +575,12 @@ public class HopExtension {
|
|||
this.global = global;
|
||||
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)
|
||||
throw new EcmaScriptException ("renderSkin must be called with one Skin argument and an optional parameter argument");
|
||||
try {
|
||||
Skin skin = null;
|
||||
ESNode handlerNode = global ? null : (ESNode) thisObject;
|
||||
ESObject thisObject = global ? null : thisObj;
|
||||
ESObject paramObject = null;
|
||||
if (arguments.length > 1 && arguments[1] instanceof ESObject)
|
||||
paramObject = (ESObject) arguments[1];
|
||||
|
@ -592,11 +593,11 @@ public class HopExtension {
|
|||
}
|
||||
|
||||
if (skin == null)
|
||||
skin = reval.getSkin (handlerNode, arguments[0].toString ());
|
||||
skin = reval.getSkin (thisObject, arguments[0].toString ());
|
||||
if (asString)
|
||||
reval.res.pushStringBuffer ();
|
||||
if (skin != null)
|
||||
skin.render (reval, handlerNode, paramObject);
|
||||
skin.render (reval, thisObject, paramObject);
|
||||
else
|
||||
reval.res.write ("[Skin not found: "+arguments[0]+"]");
|
||||
if (asString)
|
||||
|
@ -916,7 +917,7 @@ public class HopExtension {
|
|||
}
|
||||
|
||||
|
||||
class NodePath extends BuiltinFunctionObject {
|
||||
/* class NodePath extends BuiltinFunctionObject {
|
||||
NodePath (String name, Evaluator evaluator, FunctionPrototype fp) {
|
||||
super (fp, evaluator, name, 1);
|
||||
}
|
||||
|
@ -925,7 +926,7 @@ public class HopExtension {
|
|||
String tmpname = arguments[0].toString ();
|
||||
return new ESString (app.getNodePath (n, tmpname));
|
||||
}
|
||||
}
|
||||
} */
|
||||
|
||||
class NodeSetParent extends BuiltinFunctionObject {
|
||||
NodeSetParent (String name, Evaluator evaluator, FunctionPrototype fp) {
|
||||
|
@ -943,33 +944,33 @@ public class HopExtension {
|
|||
super (fp, evaluator, name, 1);
|
||||
}
|
||||
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 basicHref =app.getNodeHref (n, tmpname);
|
||||
String basicHref =app.getNodeHref (elem, tmpname);
|
||||
String hrefSkin = app.props.getProperty ("hrefSkin");
|
||||
// FIXME: we should actually walk down the path from the object we called href() on
|
||||
// instead we move down the URL path.
|
||||
if (hrefSkin != null) {
|
||||
// we need to post-process the href with a skin for this application
|
||||
// first, look in the object href was called on.
|
||||
INode sn = n;
|
||||
IPathElement skinElem = elem;
|
||||
Skin skin = null;
|
||||
while (skin == null && sn != null) {
|
||||
Prototype proto = app.getPrototype (sn);
|
||||
while (skin == null && skinElem != null) {
|
||||
Prototype proto = app.getPrototype (skinElem);
|
||||
if (proto != null)
|
||||
skin = proto.getSkin (hrefSkin);
|
||||
if (skin == null)
|
||||
sn = sn.getParent ();
|
||||
skinElem = skinElem.getParentElement ();
|
||||
}
|
||||
|
||||
if (skin != null) {
|
||||
ESNode esn = reval.getNodeWrapper (sn);
|
||||
return renderSkin (skin, basicHref, esn);
|
||||
ESObject eso = reval.getElementWrapper (skinElem);
|
||||
return renderSkin (skin, basicHref, eso);
|
||||
}
|
||||
}
|
||||
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 ();
|
||||
ESObject param = new ObjectPrototype (null, reval.evaluator);
|
||||
param.putProperty ("path", new ESString (path), "path".hashCode ());
|
||||
|
@ -1040,7 +1041,7 @@ public class HopExtension {
|
|||
buffer.append ("<input type=radio name=\"");
|
||||
buffer.append (name);
|
||||
buffer.append ("\" value=\"");
|
||||
buffer.append (next.getNameOrID ()+"\"");
|
||||
buffer.append (next.getElementName ()+"\"");
|
||||
if (target == next)
|
||||
buffer.append (" checked");
|
||||
buffer.append (">");
|
||||
|
@ -1062,7 +1063,7 @@ public class HopExtension {
|
|||
buffer.append ("<input type=checkbox name=\"");
|
||||
buffer.append (name);
|
||||
buffer.append ("\" value=");
|
||||
buffer.append (next.getNameOrID ());
|
||||
buffer.append (next.getElementName ());
|
||||
if (target.contains (next) > -1)
|
||||
buffer.append (" checked");
|
||||
buffer.append (">");
|
||||
|
|
|
@ -77,7 +77,7 @@ public class RequestEvaluator implements Runnable {
|
|||
static final int XMLRPC = 2; // via XML-RPC
|
||||
static final int INTERNAL = 3; // generic function call, e.g. by scheduler
|
||||
|
||||
INode root, userroot, currentNode;
|
||||
// INode root, currentNode;
|
||||
INode[] skinmanagers;
|
||||
|
||||
/**
|
||||
|
@ -99,6 +99,7 @@ public class RequestEvaluator implements Runnable {
|
|||
private void initEvaluator () {
|
||||
try {
|
||||
evaluator = new Evaluator();
|
||||
evaluator.reval = this;
|
||||
global = evaluator.getGlobalObject();
|
||||
for (int i=0; i<extensions.length; i++)
|
||||
evaluator.addExtension (extensions[i]);
|
||||
|
@ -140,7 +141,7 @@ public class RequestEvaluator implements Runnable {
|
|||
try {
|
||||
do {
|
||||
|
||||
// app.logEvent ("got request "+reqtype);
|
||||
IPathElement root, currentElement;
|
||||
// reset skinManager
|
||||
skinmanagers = null;
|
||||
|
||||
|
@ -152,7 +153,7 @@ public class RequestEvaluator implements Runnable {
|
|||
while (!done) {
|
||||
|
||||
current = null;
|
||||
currentNode = null;
|
||||
currentElement = null;
|
||||
reqPath.setSize (0);
|
||||
// delete path objects-via-prototype
|
||||
for (Enumeration en=reqPath.getAllProperties(); en.hasMoreElements(); ) {
|
||||
|
@ -176,7 +177,7 @@ public class RequestEvaluator implements Runnable {
|
|||
|
||||
ESUser esu = (ESUser) getNodeWrapper (user);
|
||||
// esu.setUser (user);
|
||||
global.putHiddenProperty ("root", getNodeWrapper (root));
|
||||
global.putHiddenProperty ("root", getElementWrapper (root));
|
||||
global.putHiddenProperty("user", esu);
|
||||
global.putHiddenProperty ("req", new ESWrapper (req, evaluator));
|
||||
global.putHiddenProperty ("res", new ESWrapper (res, evaluator));
|
||||
|
@ -197,8 +198,8 @@ public class RequestEvaluator implements Runnable {
|
|||
|
||||
if (error != null) {
|
||||
// there was an error in the previous loop, call error handler
|
||||
currentNode = root;
|
||||
current = getNodeWrapper (root);
|
||||
currentElement = root;
|
||||
current = getElementWrapper (root);
|
||||
reqPath.putProperty (0, current);
|
||||
reqPath.putHiddenProperty ("root", current);
|
||||
Prototype p = app.getPrototype (root);
|
||||
|
@ -208,8 +209,8 @@ public class RequestEvaluator implements Runnable {
|
|||
throw new RuntimeException (error);
|
||||
|
||||
} else if (req.path == null || "".equals (req.path.trim ())) {
|
||||
currentNode = root;
|
||||
current = getNodeWrapper (root);
|
||||
currentElement = root;
|
||||
current = getElementWrapper (root);
|
||||
reqPath.putProperty (0, current);
|
||||
reqPath.putHiddenProperty ("root", current);
|
||||
Prototype p = app.getPrototype (root);
|
||||
|
@ -233,38 +234,38 @@ public class RequestEvaluator implements Runnable {
|
|||
for (int i=0; i<ntokens; i++)
|
||||
pathItems[i] = st.nextToken ();
|
||||
|
||||
currentNode = root;
|
||||
current = getNodeWrapper (root);
|
||||
currentElement = root;
|
||||
current = getElementWrapper (root);
|
||||
reqPath.putProperty (0, current);
|
||||
reqPath.putHiddenProperty ("root", current);
|
||||
|
||||
for (int i=0; i<ntokens; i++) {
|
||||
|
||||
if (currentNode == null)
|
||||
if (currentElement == null)
|
||||
throw new FrameworkException ("Object not found.");
|
||||
|
||||
// the first token in the path needs to be treated seprerately,
|
||||
// because "/user" is a shortcut to the current user session, while "/users"
|
||||
// is the mounting point for all users.
|
||||
if (i == 0 && "user".equalsIgnoreCase (pathItems[i])) {
|
||||
currentNode = user.getNode ();
|
||||
if (currentNode != null) {
|
||||
current = getNodeWrapper (currentNode);
|
||||
// currentElement = user.getNode ();
|
||||
if (currentElement != null) {
|
||||
current = getElementWrapper (currentElement);
|
||||
reqPath.putProperty (1, current);
|
||||
reqPath.putHiddenProperty ("user", current);
|
||||
}
|
||||
|
||||
} else if (i == 0 && "users".equalsIgnoreCase (pathItems[i])) {
|
||||
currentNode = app.getUserRoot ();
|
||||
isProperty = true;
|
||||
if (currentNode != null) {
|
||||
current = getNodeWrapper (currentNode);
|
||||
// currentElement = app.getUserRoot ();
|
||||
// isProperty = true;
|
||||
if (currentElement != null) {
|
||||
current = getElementWrapper (currentElement);
|
||||
reqPath.putProperty (1, current);
|
||||
}
|
||||
|
||||
} else {
|
||||
if (i == ntokens-1) {
|
||||
Prototype p = app.getPrototype (currentNode);
|
||||
Prototype p = app.getPrototype (currentElement);
|
||||
if (p != null)
|
||||
action = p.getActionOrTemplate (pathItems[i]);
|
||||
}
|
||||
|
@ -273,23 +274,25 @@ public class RequestEvaluator implements Runnable {
|
|||
|
||||
if (pathItems[i].length () == 0)
|
||||
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 {
|
||||
// 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)
|
||||
nextNode = currentNode.getNode (pathItems[i], false);
|
||||
currentNode = nextNode;
|
||||
nextNode = currentElement.getNode (pathItems[i], false);
|
||||
currentElement = nextNode;
|
||||
}
|
||||
isProperty = false;
|
||||
isProperty = false; */
|
||||
|
||||
// add object to request path if suitable
|
||||
if (currentNode != null) {
|
||||
if (currentElement != null) {
|
||||
// add to reqPath array
|
||||
current = getNodeWrapper (currentNode);
|
||||
current = getElementWrapper (currentElement);
|
||||
reqPath.putProperty (reqPath.size(), current);
|
||||
String pt = currentNode.getPrototype ();
|
||||
String pt = currentElement.getPrototype ();
|
||||
if (pt != null) {
|
||||
// if a prototype exists, add also by prototype name
|
||||
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.");
|
||||
else
|
||||
current = getNodeWrapper (currentNode);
|
||||
current = getElementWrapper (currentElement);
|
||||
|
||||
if (action == null) {
|
||||
Prototype p = app.getPrototype (currentNode);
|
||||
Prototype p = app.getPrototype (currentElement);
|
||||
if (p != null)
|
||||
action = p.getActionOrTemplate (null);
|
||||
}
|
||||
|
@ -328,7 +331,7 @@ public class RequestEvaluator implements Runnable {
|
|||
action = p.getActionOrTemplate (notFoundAction);
|
||||
if (action == null)
|
||||
throw new FrameworkException (notfound.getMessage ());
|
||||
current = getNodeWrapper (root);
|
||||
current = getElementWrapper (root);
|
||||
}
|
||||
|
||||
localrtx.timer.endEvent (requestPath+" init");
|
||||
|
@ -430,7 +433,7 @@ public class RequestEvaluator implements Runnable {
|
|||
|
||||
root = app.getDataRoot ();
|
||||
|
||||
global.putHiddenProperty ("root", getNodeWrapper (root));
|
||||
global.putHiddenProperty ("root", getElementWrapper (root));
|
||||
global.deleteProperty("user", "user".hashCode());
|
||||
global.deleteProperty ("req", "req".hashCode());
|
||||
global.putHiddenProperty ("res", ESLoader.normalizeValue(res, evaluator));
|
||||
|
@ -439,7 +442,7 @@ public class RequestEvaluator implements Runnable {
|
|||
|
||||
// convert arguments
|
||||
int l = args.size ();
|
||||
current = getNodeWrapper (root);
|
||||
current = getElementWrapper (root);
|
||||
if (method.indexOf (".") > -1) {
|
||||
StringTokenizer st = new StringTokenizer (method, ".");
|
||||
int cnt = st.countTokens ();
|
||||
|
@ -491,7 +494,7 @@ public class RequestEvaluator implements Runnable {
|
|||
|
||||
root = app.getDataRoot ();
|
||||
|
||||
global.putHiddenProperty ("root", getNodeWrapper (root));
|
||||
global.putHiddenProperty ("root", getElementWrapper (root));
|
||||
global.deleteProperty("user", "user".hashCode());
|
||||
global.deleteProperty ("req", "req".hashCode());
|
||||
global.putHiddenProperty ("res", ESLoader.normalizeValue(res, evaluator));
|
||||
|
@ -642,13 +645,13 @@ public class RequestEvaluator implements Runnable {
|
|||
return result;
|
||||
}
|
||||
|
||||
public synchronized ESValue invokeFunction (INode node, String functionName, ESValue[] args)
|
||||
public synchronized ESValue invokeFunction (IPathElement node, String functionName, ESValue[] args)
|
||||
throws Exception {
|
||||
ESObject obj = null;
|
||||
if (node == null)
|
||||
obj = global;
|
||||
else
|
||||
obj = getNodeWrapper (node);
|
||||
obj = getElementWrapper (node);
|
||||
return invokeFunction (obj, functionName, args);
|
||||
}
|
||||
|
||||
|
@ -741,8 +744,14 @@ public class RequestEvaluator implements Runnable {
|
|||
Prototype proto = null;
|
||||
if (thisObject == null)
|
||||
proto = app.typemgr.getPrototype ("global");
|
||||
else
|
||||
proto = app.getPrototype (((ESNode) thisObject).getNode ());
|
||||
else {
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -829,6 +838,21 @@ public class RequestEvaluator implements Runnable {
|
|||
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) {
|
||||
|
||||
if (n == null)
|
||||
|
|
|
@ -72,12 +72,24 @@ public class Skin {
|
|||
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)
|
||||
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++) {
|
||||
if (parts[i] instanceof Macro)
|
||||
((Macro) parts[i]).render (reval, thisNode, paramObject);
|
||||
((Macro) parts[i]).render (reval, thisObject, elem, paramObject);
|
||||
else
|
||||
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) {
|
||||
String h = handler == null ? "global" : handler;
|
||||
|
@ -223,32 +235,33 @@ public class Skin {
|
|||
if ("currentuser".equalsIgnoreCase (handler)) {
|
||||
// as a special convention, we use "currentuser" to access macros in the current user object
|
||||
handlerObject = reval.getNodeWrapper (reval.user.getNode ());
|
||||
} else if (thisNode != null) {
|
||||
} else if (elem != null) {
|
||||
// not a global macro - need to find handler object
|
||||
// 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
|
||||
INode n = thisNode.getNode();
|
||||
IPathElement n = elem;
|
||||
// walk down parent chain to find handler object
|
||||
while (n != null) {
|
||||
if (handler.equalsIgnoreCase (n.getPrototype())) {
|
||||
handlerObject = reval.getNodeWrapper (n);
|
||||
handlerObject = reval.getElementWrapper (n);
|
||||
break;
|
||||
}
|
||||
n = n.getParent ();
|
||||
n = n.getParentElement ();
|
||||
}
|
||||
} else {
|
||||
// we already have the right handler object
|
||||
handlerObject = thisNode;
|
||||
handlerObject = thisObject;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
int l = reval.reqPath.size();
|
||||
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);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ public class User implements Serializable {
|
|||
nhandle = null;
|
||||
uid = null;
|
||||
} else {
|
||||
uid = n.getNameOrID ();
|
||||
uid = n.getElementName ();
|
||||
nhandle = ((helma.objectmodel.db.Node) n).getHandle ();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue