diff --git a/src/helma/framework/core/RequestEvaluator.java b/src/helma/framework/core/RequestEvaluator.java index cf9b31cc..f93621f1 100644 --- a/src/helma/framework/core/RequestEvaluator.java +++ b/src/helma/framework/core/RequestEvaluator.java @@ -83,7 +83,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[] skinmanagers; + Object[] skinsets; /** * Build a RenderContext from a RequestTrans. Checks if the path is the user home node ("user") @@ -154,8 +154,8 @@ public class RequestEvaluator implements Runnable { // object refs to ressolve request path Object root, currentElement; - // reset skinManager - skinmanagers = null; + // reset skinsets array and skin cache + skinsets = null; skincache.clear (); switch (reqtype) { @@ -209,7 +209,6 @@ public class RequestEvaluator implements Runnable { req.data = reqData; resData.setData (res.getResponseData()); res.data = resData; - res.skinpath = app.getProperty ("skinpath"); try { @@ -345,8 +344,14 @@ public class RequestEvaluator implements Runnable { try { localrtx.timer.beginEvent (requestPath+" execute"); + int actionDot = action.lastIndexOf ("."); + boolean isAction = actionDot == -1; // set the req.action property, cutting off the _action suffix - req.action = action.substring (0, action.length()-7); + if (isAction) + req.action = action.substring (0, action.length()-7); + else + req.action = action; + // try calling onRequest() function on object before // calling the actual action try { @@ -357,7 +362,16 @@ public class RequestEvaluator implements Runnable { // function is not defined or caused an exception, ignore } // do the actual action invocation - current.doIndirectCall (evaluator, current, action, new ESValue[0]); + if (isAction) + current.doIndirectCall (evaluator, current, action, new ESValue[0]); + else { + Skin skin = getSkinInternal (app.appDir, app.getPrototype(currentElement).getName(), action.substring (0, actionDot), action.substring (actionDot+1)); + if (skin != null) + skin.render (this, current.toJavaObject (), null); + else + throw new RuntimeException ("Skin "+action+" not found in "+req.path); + } + // check if the script set the name of a skin to render in res.skin if (res.skin != null) { @@ -820,103 +834,107 @@ public class RequestEvaluator implements Runnable { Object elem = thisObject.toJavaObject (); proto = app.getPrototype (elem); } - return getSkin (proto, skinname); + return getSkin (proto, skinname, "skin"); } - - public Skin getSkin (Prototype proto, String skinname) { + + public Skin getSkin (Prototype proto, String skinname, String extension) { if (proto == null) return null; // First check if the skin has been already used within the execution of this request - SkinKey key = new SkinKey (proto.getName(), skinname); + SkinKey key = new SkinKey (proto.getName(), skinname, extension); Skin skin = (Skin) skincache.get (key); if (skin != null) { return skin; } - // check for skin path - if (res.skinpath != null) { - File f = new File (res.skinpath, proto.getName()); - f = new File (f, skinname+".skin"); - if (f.exists ()) { - SkinFile sf = new SkinFile (f, skinname, proto); - skin = sf.getSkin (); - if (skin != null) - return skin; - } - } - // check for Helma-internal skinmanager nodes - if (skinmanagers == null) - getSkinManagers (); + // check for skinsets set via res.skinpath property + if (skinsets == null) + getSkinSets (); do { - for (int i=0; i=0; i--) try { - ESNode esn = (ESNode) reqPath.getProperty (i); - INode n = esn.getNode (); - DbMapping dbm = n.getDbMapping (); - if (dbm == null) - continue; - String[] skinmgr = dbm.getSkinManagers(); - if (skinmgr == null) - continue; - for (int j=0; j -1) { + int dot = action.lastIndexOf ("."); + String extension = action.substring (dot+1); + String contentType = app.skinExtensions.getProperty (extension); + if (contentType != null) { + res.contentType = contentType; + return action; + } else + return null; + } else { + String act = action == null ? "main_action" : action+"_action"; + try { + ESObject proto = obj.getPrototype (); + if (proto != null) { + ESValue esv = proto.getProperty (act, act.hashCode()); + if (esv != null && esv instanceof FunctionPrototype) + return act; + } + } catch (EcmaScriptException notfound) {} + } return null; } @@ -1127,24 +1161,25 @@ public class RequestEvaluator implements Runnable { */ final class SkinKey { - final String first, second; + final String first, second, third; - public SkinKey (String first, String second) { + public SkinKey (String first, String second, String third) { this.first = first; this.second = second; + this.third = third; } public boolean equals (Object other) { try { SkinKey key = (SkinKey) other; - return first.equals (key.first) && second.equals (key.second); + return first.equals (key.first) && second.equals (key.second) && third.equals (key.third); } catch (Exception x) { return false; } } - + public int hashCode () { - return first.hashCode () + second.hashCode (); + return first.hashCode () + second.hashCode () + third.hashCode (); } } }