first implementation of system lever skin support

This commit is contained in:
hns 2001-02-19 16:59:11 +00:00
parent 9922ea3fd8
commit bf0ecdd923
7 changed files with 187 additions and 17 deletions

View file

@ -52,7 +52,7 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, Runn
long requestTimeout = 60000; // 60 seconds for request timeout. long requestTimeout = 60000; // 60 seconds for request timeout.
ThreadGroup threadgroup; ThreadGroup threadgroup;
protected String templateExtension, scriptExtension, actionExtension; protected String templateExtension, scriptExtension, actionExtension, skinExtension;
// A transient node that is shared among all evaluators // A transient node that is shared among all evaluators
protected INode appnode; protected INode appnode;
@ -95,6 +95,7 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, Runn
templateExtension = props.getProperty ("templateExtension", ".hsp"); templateExtension = props.getProperty ("templateExtension", ".hsp");
scriptExtension = props.getProperty ("scriptExtension", ".js"); scriptExtension = props.getProperty ("scriptExtension", ".js");
actionExtension = props.getProperty ("actionExtension", ".hac"); actionExtension = props.getProperty ("actionExtension", ".hac");
skinExtension = ".skin";
sessions = new Hashtable (); sessions = new Hashtable ();
activeUsers = new Hashtable (); activeUsers = new Hashtable ();

View file

@ -602,18 +602,30 @@ public class HopExtension {
this.asString = asString; this.asString = asString;
} }
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException { public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
if (arguments.length != 1 || !(arguments[0] instanceof ESWrapper)) 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!"); throw new EcmaScriptException ("renderSkin must be called with one Skin argument and an optional parameter argument");
try { try {
Skin skin = (Skin) ((ESWrapper) arguments[0]).toJavaObject (); Skin skin = null;
ESNode handlerNode = global ? null : (ESNode) thisObject; ESNode handlerNode = global ? null : (ESNode) thisObject;
// first, see if the first argument already is a skin object. If not, it's the name of the skin to be called
if (arguments[0] instanceof ESWrapper) {
Object obj = ((ESWrapper) arguments[0]).toJavaObject ();
if (obj instanceof Skin)
skin = (Skin) obj;
}
if (skin == null)
skin = reval.getSkin (handlerNode, arguments[0].toString ());
if (asString) if (asString)
reval.res.pushStringBuffer (); reval.res.pushStringBuffer ();
skin.render (reval, handlerNode); try {
skin.render (reval, handlerNode);
} catch (NullPointerException npx) {
reval.res.write ("[Skin not found: "+arguments[0]+"]");
}
if (asString) if (asString)
return new ESString (reval.res.popStringBuffer ()); return new ESString (reval.res.popStringBuffer ());
} catch (ClassCastException x) { } catch (Exception x) {
throw new EcmaScriptException ("renderSkin must be called with one Skin argument!"); throw new EcmaScriptException ("renderSkin: "+x);
} }
return ESNull.theNull; return ESNull.theNull;
} }

View file

@ -24,7 +24,7 @@ public class Prototype {
String id; String id;
String name; String name;
Application app; Application app;
Hashtable templates, functions, actions; Hashtable templates, functions, actions, skins;
File codeDir; File codeDir;
long lastUpdate; long lastUpdate;
@ -86,6 +86,18 @@ public class Prototype {
return (Action) actions.get (afname); return (Action) actions.get (afname);
} }
public SkinFile getSkinFile (String sfname) {
return (SkinFile) skins.get (sfname);
}
public Skin getSkin (String sfname) {
SkinFile sf = (SkinFile) skins.get (sfname);
if (sf != null)
return sf.getSkin ();
else
return null;
}
public File getCodeDir () { public File getCodeDir () {
return codeDir; return codeDir;
} }

View file

@ -653,6 +653,17 @@ public class RequestEvaluator implements Runnable {
} }
} }
public Skin getSkin (ESObject thisObject, String skinname) {
INode n = null;
if (thisObject != null && thisObject instanceof ESNode)
n = ((ESNode) thisObject).getNode ();
Prototype proto = app.getPrototype (n);
if (proto != null)
return proto.getSkin (skinname);
else
return null;
}
/** /**
* Returns a node wrapper only if it already exists in the cache table. This is used * Returns a node wrapper only if it already exists in the cache table. This is used

View file

@ -55,12 +55,12 @@ public class Skin {
parts = partBuffer.toArray (); parts = partBuffer.toArray ();
} }
public void render (RequestEvaluator reval, ESNode handlerNode) { public void render (RequestEvaluator reval, ESNode thisNode) {
if (parts == null) if (parts == null)
return; return;
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, handlerNode); ((Macro) parts[i]).render (reval, thisNode);
else else
reval.res.write (parts[i]); reval.res.write (parts[i]);
} }
@ -165,7 +165,7 @@ public class Skin {
} }
public void render (RequestEvaluator reval, ESNode handlerNode) { public void render (RequestEvaluator reval, ESNode thisNode) {
if ("response".equalsIgnoreCase (handler)) { if ("response".equalsIgnoreCase (handler)) {
renderFromResponse (reval); renderFromResponse (reval);
@ -182,12 +182,13 @@ public class Skin {
arguments[0] = par; arguments[0] = par;
if (handler != null) { if (handler != null) {
// not a macro handled by global - need to find handler object // not a global macro - need to find handler object
if (handlerNode != null) { if (thisNode != null) {
// 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 (handlerNode.getPrototypeName ())) { if (!handler.equalsIgnoreCase ("this") && !handler.equalsIgnoreCase (thisNode.getPrototypeName ())) {
// the handler object is not what we want // the handler object is not what we want
INode n = handlerNode.getNode(); INode n = thisNode.getNode();
// 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.getNodeWrapper (n);
@ -197,12 +198,12 @@ public class Skin {
} }
} else { } else {
// we already have the right handler object // we already have the right handler object
handlerObject = handlerNode; handlerObject = thisNode;
} }
} }
if (handlerObject == null) { if (handlerObject == null) {
// eiter because handlerNode == null or the right object wasn't found in the targetNode path // eiter because thisNode == null or the right object wasn't found in the targetNode 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--) {

View file

@ -0,0 +1,106 @@
// SkinFile.java
// Copyright (c) Hannes Wallnöfer 2001
package helma.framework.core;
import java.util.*;
import java.io.*;
import helma.objectmodel.IServer;
/**
* This represents a File containing a Hop skin
*/
public class SkinFile {
String name;
Prototype prototype;
Application app;
File file;
Skin skin;
long lastmod;
public SkinFile (File file, String name, Prototype proto) {
this.prototype = proto;
this.app = proto.app;
this.name = name;
this.file = file;
this.skin = null;
}
public void update (File f) {
this.file = f;
long fmod = file.lastModified ();
// we only update this if we already have read the skin
if (skin == null || lastmod == fmod)
return;
read ();
}
private void read () {
try {
FileReader reader = new FileReader (file);
char c[] = new char[(int) file.length()];
reader.read (c);
reader.close();
skin = new Skin (new String (c));
} catch (IOException x) {
IServer.getLogger().log ("Error reading Skin "+file+": "+x);
}
lastmod = file.lastModified ();
}
public Skin getSkin () {
if (skin == null)
read ();
return skin;
}
}

View file

@ -157,6 +157,7 @@ public class TypeManager implements Runnable {
Hashtable ntemp = new Hashtable (); Hashtable ntemp = new Hashtable ();
Hashtable nfunc = new Hashtable (); Hashtable nfunc = new Hashtable ();
Hashtable nact = new Hashtable (); Hashtable nact = new Hashtable ();
Hashtable nskins = new Hashtable ();
for (int i=0; i<list.length; i++) { for (int i=0; i<list.length; i++) {
File tmpfile = new File (dir, list[i]); File tmpfile = new File (dir, list[i]);
@ -182,6 +183,7 @@ public class TypeManager implements Runnable {
} catch (Throwable x) { } catch (Throwable x) {
IServer.getLogger().log ("Error creating prototype: "+x); IServer.getLogger().log ("Error creating prototype: "+x);
} }
} else if (list[i].endsWith (app.actionExtension) && tmpfile.length () > 0) { } else if (list[i].endsWith (app.actionExtension) && tmpfile.length () > 0) {
try { try {
Action af = new Action (tmpfile, tmpname, proto); Action af = new Action (tmpfile, tmpname, proto);
@ -189,11 +191,19 @@ public class TypeManager implements Runnable {
} catch (Throwable x) { } catch (Throwable x) {
IServer.getLogger().log ("Error creating prototype: "+x); IServer.getLogger().log ("Error creating prototype: "+x);
} }
} else if (list[i].endsWith (app.skinExtension)) {
try {
SkinFile sf = new SkinFile (tmpfile, tmpname, proto);
nskins.put (tmpname, sf);
} catch (Throwable x) {
IServer.getLogger().log ("Error creating prototype: "+x);
}
} }
} }
proto.templates = ntemp; proto.templates = ntemp;
proto.functions = nfunc; proto.functions = nfunc;
proto.actions = nact; proto.actions = nact;
proto.skins = nskins;
// init prototype on evaluators that are already initialized. // init prototype on evaluators that are already initialized.
Iterator evals = getRegisteredRequestEvaluators (); Iterator evals = getRegisteredRequestEvaluators ();
@ -212,6 +222,7 @@ public class TypeManager implements Runnable {
Hashtable ntemp = new Hashtable (); Hashtable ntemp = new Hashtable ();
Hashtable nfunc = new Hashtable (); Hashtable nfunc = new Hashtable ();
Hashtable nact = new Hashtable (); Hashtable nact = new Hashtable ();
Hashtable nskins = new Hashtable ();
for (int i=0; i<list.length; i++) { for (int i=0; i<list.length; i++) {
File tmpfile = new File (dir, list[i]); File tmpfile = new File (dir, list[i]);
@ -266,6 +277,21 @@ public class TypeManager implements Runnable {
} }
nact.put (tmpname, af); nact.put (tmpname, af);
} else if (list[i].endsWith (app.skinExtension)) {
SkinFile sf = proto.getSkinFile (tmpname);
try {
if (sf == null) {
sf = new SkinFile (tmpfile, tmpname, proto);
idleSeconds = 0;
} else if (sf.lastmod != tmpfile.lastModified ()) {
sf.update (tmpfile);
idleSeconds = 0;
}
} catch (Throwable x) {
IServer.getLogger().log ("Error updating prototype: "+x);
}
nskins.put (tmpname, sf);
} else if ("type.properties".equalsIgnoreCase (list[i])) { } else if ("type.properties".equalsIgnoreCase (list[i])) {
try { try {
if (proto.dbmap.read ()) { if (proto.dbmap.read ()) {
@ -280,6 +306,7 @@ public class TypeManager implements Runnable {
proto.templates = ntemp; proto.templates = ntemp;
proto.functions = nfunc; proto.functions = nfunc;
proto.actions = nact; proto.actions = nact;
proto.skins = nskins;
} }