X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fxwt%2FTemplate.java;h=363886c5ebe95f816f938988dcd48f74573da917;hb=a81a151e639664cb340cf3726f9e8b9c77d125fb;hp=11bb1fc72093ee4760d9d712a12449a14b2ec7c9;hpb=517e8e64135ecf6dc5a8d9d8e0a32cce978a3aef;p=org.ibex.core.git diff --git a/src/org/xwt/Template.java b/src/org/xwt/Template.java index 11bb1fc..363886c 100644 --- a/src/org/xwt/Template.java +++ b/src/org/xwt/Template.java @@ -10,12 +10,7 @@ import org.xwt.util.*; /** * Encapsulates a template node (the <template/> element of a - * .xwt file, or any child element thereof). Each instance of - * Template has a nodeName -- this is the resource name of - * the file that the template node occurs in, concatenated with the - * path from the root element to this node, each step of which is in - * the form .n for some integer n. Static nodes use the string "._" - * as a path. + * .xwt file, or any child element thereof). * * Note that the Template instance corresponding to the * <template/> node carries all the header information -- hence @@ -26,27 +21,23 @@ import org.xwt.util.*; * See the XWT reference for information on the order in which * templates are applied, attributes are put, and scripts are run. */ + +// FIXME imports public class Template { // Instance Members /////////////////////////////////////////////////////// - /** this instance's nodeName */ - String nodeName; + /** the id of this box */ + String id = null; /** the id of the redirect target; only meaningful on a root node */ String redirect = null; /** templates that should be preapplied (in the order of application); only meaningful on a root node */ - private String[] preapply; - - /** 'linked' form of preapply -- the String references have been resolved into instance references */ - private Template[] _preapply = null; + private Template[] preapply; /** templates that should be postapplied (in the order of application); only meaningful on a root node */ - private String[] postapply; - - /** 'linked' form of postapply -- the String references have been resolved into instance references */ - private Template[] _postapply = null; + private Template[] postapply; /** keys to be "put" to instances of this template; elements correspond to those of vals */ private String[] keys; @@ -54,23 +45,14 @@ public class Template { /** values to be "put" to instances of this template; elements correspond to those of keys */ private Object[] vals; - /** array of strings representing the importlist for this template */ - private String[] importlist; - /** child template objects */ private Template[] children; - /** an array of the names of properties to be preserved when retheming; only meaningful on a root node */ - private String[] preserve = null; - - /** the id attribute on this node */ - private String id = ""; - /** see numUnits(); -1 means that this value has not yet been computed */ private int numunits = -1; - /** true iff the resolution of this template's preapply/postapply sets changed as a result of the most recent call to retheme() */ - private boolean changed = false; + /** the scope in which the static block is executed */ + private JS.Scope staticScope = null; /** the script on the static node of this template, null if it has already been executed */ private JS.CompiledFunction staticscript = null; @@ -78,6 +60,12 @@ public class Template { /** the script on this node */ private JS.CompiledFunction script = null; + /** the filename this node came from; used only for debugging */ + private String fileName = "unknown"; + + + // Only used during parsing ///////////////////////////////////////////////////////////////// + /** during XML parsing, this holds the list of currently-parsed children; null otherwise */ private Vec childvect = new Vec(); @@ -93,44 +81,27 @@ public class Template { /** the line number that this element starts on */ private int startLine = -1; - // Static data/methods /////////////////////////////////////////////////////////////////// - - /** a template cache so that only one Template object is created for each xwt */ - private static Hashtable cache = new Hashtable(1000); - - /** The default importlist; in future revisions this will contain "xwt.*" */ - public static final String[] defaultImportList = new String[] { }; - /** returns the appropriate template, resolving and theming as needed */ - public static Template getTemplate(String name, String[] importlist) { - String resolved = Resources.resolve(name + ".xwt", importlist); - Template t = resolved == null ? null : (Template)cache.get(resolved.substring(0, resolved.length() - 4)); - if (t != null) return t; - if (resolved == null) return null; - - // note that Templates in xwar's are instantiated as read in via loadStream() -- - // the following code only runs when XWT is reading templates from a filesystem. - ByteArrayInputStream bais = new ByteArrayInputStream(Resources.getResource(resolved)); - return buildTemplate(bais, resolved.substring(0, resolved.length() - 4)); - } + // Static data/methods /////////////////////////////////////////////////////////////////// - public static Template buildTemplate(InputStream is, String nodeName) { - return buildTemplate(is, nodeName, new TemplateHelper()); - } + private Template(String fileName) { this.fileName = fileName; } - public static Template buildTemplate(InputStream is, String nodeName, TemplateHelper t) { + public static Template getTemplate(Res r) { try { - return new Template(is, nodeName, t); + if (r.t != null) return r.t; + r.t = new Template(r.getDescriptiveName()); + new TemplateHelper().parseit(r.getInputStream(), r.t); + return r.t; } catch (XML.SchemaException e) { - if (Log.on) Log.log(Template.class, "error parsing template " + nodeName); + if (Log.on) Log.log(Template.class, "error parsing template " + r.t.fileName); if (Log.on) Log.log(Template.class, e.getMessage()); return null; } catch (XML.XMLException e) { - if (Log.on) Log.log(Template.class, "error parsing template at " + nodeName + ":" + e.getLine() + "," + e.getCol()); + if (Log.on) Log.log(Template.class, "error parsing template at " + r.t.fileName + ":" + e.getLine() + "," + e.getCol()); if (Log.on) Log.log(Template.class, e.getMessage()); return null; } catch (IOException e) { - if (Log.on) Log.log(Template.class, "IOException while parsing template " + nodeName + " -- this should never happen"); + if (Log.on) Log.log(Template.class, "IOException while parsing template " + r.t.fileName + " -- this should never happen"); if (Log.on) Log.log(Template.class, e); return null; } @@ -139,183 +110,75 @@ public class Template { // Methods to apply templates //////////////////////////////////////////////////////// - private Template(String nodeName) { - this.nodeName = nodeName; - cache.put(nodeName, this); - } - private Template(InputStream is, String nodeName, TemplateHelper th) throws XML.XMLException, IOException { - this(nodeName); - th.parseit(is, this); - } - - /** calculates, caches, and returns an integer approximation of how long it will take to apply this template, including pre/post and children */ + /** calculates, caches, and returns an integer approximation of how long it will take to apply this template, + * including pre/post and children */ int numUnits() { - link(); if (numunits != -1) return numunits; numunits = 1; - for(int i=0; _preapply != null && i<_preapply.length; i++) if (_preapply[i] != null) numunits += _preapply[i].numUnits(); - for(int i=0; _postapply != null && i<_postapply.length; i++) if (_postapply[i] != null) numunits += _postapply[i].numUnits(); + for(int i=0; preapply != null && ichange as needed */ - void link() { link(false); } - - /** same as link(), except that with a true value, it will force a re-link */ - private void link(boolean force) { - - if (staticscript != null) try { - JS.Scope s = Static.createStatic(nodeName, false); - if (staticscript != null) { - JS.CompiledFunction temp = staticscript; - staticscript = null; - - // we layer a transparent scope over the Static so that we can catch requests for the xwt object - // yet not screw up paths that include a package called xwt (ie xwt.static.org.xwt.foo) - JS.Scope varScope = new JS.Scope(s) { - public boolean isTransparent() { return true; } - public Object get(Object key) { - if ("xwt".equals(key)) return XWT.singleton; else return super.get(key); - } }; - - temp.call(new JS.Array(), varScope); - } - } catch (JS.Exn e) { - if (Log.on) Log.log(this, "WARNING: uncaught ecmascript exception: " + e.getMessage()); - } - - if (!(force || (preapply != null && _preapply == null) || (postapply != null && _postapply == null))) return; - - if (preapply != null) { - if (_preapply == null) _preapply = new Template[preapply.length]; - for(int i=0; i<_preapply.length; i++) { - Template t = getTemplate(preapply[i], importlist); - if (t != _preapply[i]) changed = true; - _preapply[i] = t; - } - } - if (postapply != null) { - if (_postapply == null) _postapply = new Template[postapply.length]; - for(int i=0; i<_postapply.length; i++) { - Template t = getTemplate(postapply[i], importlist); - if (t != _postapply[i]) changed = true; - _postapply[i] = t; - } - } - - for(int i=0; children != null && i node must have exactly one attribute, which must be called 'name'"); String importpackage = c.vals[0].toString(); if (importpackage.endsWith(".*")) importpackage = importpackage.substring(0, importpackage.length() - 2); - importlist.addElement(importpackage); return; } else if (c.localName.equals("redirect")) { @@ -426,24 +282,11 @@ public class Template { staticNodeHasBeenEncountered = true; return; - } else if (c.localName.equals("preserve")) { - if (c.len != 1 || !c.keys[0].equals("attributes")) - throw new XML.SchemaException(" node must have exactly one attribute, which must be called 'attributes'"); - if (t.preserve != null) - throw new XML.SchemaException(" header element may not appear more than once"); - - StringTokenizer tok = new StringTokenizer(c.vals[0].toString(), ",", false); - t.preserve = new String[tok.countTokens()]; - for(int i=0; i 0) preapply.copyInto(t.preapply = new String[preapply.size()]); - if (postapply.size() > 0) postapply.copyInto(t.postapply = new String[postapply.size()]); - importlist.setSize(0); preapply.setSize(0); postapply.setSize(0); + if (preapply.size() > 0) preapply.copyInto(t.preapply = new Template[preapply.size()]); + if (postapply.size() > 0) postapply.copyInto(t.postapply = new Template[postapply.size()]); templateNodeHasBeenEncountered = true; } else { @@ -456,11 +299,10 @@ public class Template { // push the last node we were in onto the stack nodeStack.addElement(t); - // instantiate a new node, and set its nodeName/importlist/preapply - Template t2 = new Template(t.nodeName + "." + t.childvect.size()); - t2.importlist = t.importlist; + // instantiate a new node, and set its fileName/importlist/preapply + Template t2 = new Template(t.fileName); t2.startLine = getLine(); - if (!c.localName.equals("box")) t2.preapply = new String[] { c.localName }; + if (!c.localName.equals("box")) t2.preapply = new Template[] { /*c.localName FIXME */ }; // make the new node the current node t = t2; @@ -468,6 +310,8 @@ public class Template { } // TODO: Sort contents straight from one array to another + // FIXME: height must come after image + // FIXME: use Vec here t.keys = new String[c.len]; t.vals = new Object[c.len]; System.arraycopy(c.keys, 0, t.keys, 0, c.len); @@ -569,10 +413,7 @@ public class Template { private JS.CompiledFunction genscript(boolean isstatic) { JS.CompiledFunction thisscript = null; try { - thisscript = JS.parse(t.nodeName + (isstatic ? "._" : ""), t.content_start, new StringReader(t.content.toString())); - } catch (JS.Exn ee) { - if (Log.on) Log.log(this, " ERROR: " + ee.getMessage()); - thisscript = null; + thisscript = JS.parse(t.fileName + (isstatic ? "._" : ""), t.content_start, new StringReader(t.content.toString())); } catch (IOException ioe) { if (Log.on) Log.log(this, " ERROR: " + ioe.getMessage()); thisscript = null; @@ -587,7 +428,7 @@ public class Template { public void characters(char[] ch, int start, int length) throws XML.SchemaException { // invoke the no-tab crusade for (int i=0; length >i; i++) if (ch[start+i] == '\t') throw new XML.SchemaException( - t.nodeName+ ":" + getLine() + "," + getCol() + ": tabs are not allowed in XWT files"); + t.fileName+ ":" + getLine() + "," + getCol() + ": tabs are not allowed in XWT files"); if ("static".equals(nameOfHeaderNodeBeingProcessed) || templateNodeHasBeenEncountered) { if (t.content == null) {