Revision: 4498 http://vexi.svn.sourceforge.net/vexi/?rev=4498&view=rev Author: mkpg2 Date: 2013-03-21 06:16:32 +0000 (Thu, 21 Mar 2013) Log Message: ----------- Implement. lang:subtemplate. Assigns a vexi template to a property on the parent instance (as opposed to adding an instance of the template as a child property).
Modified Paths: -------------- trunk/org.vexi-core.main/src/main/java/org/vexi/core/VML.java trunk/org.vexi-core.main/src/main/java/org/vexi/core/VMLBuilder.java trunk/org.vexi-core.main/src/test/java/test/core/template/TestTemplate.java Added Paths: ----------- trunk/org.vexi-core.main/src/test/java/test/core/template/lang_apply.t trunk/org.vexi-core.main/src/test/java/test/core/template/lang_subtemplate.t Removed Paths: ------------- trunk/org.vexi-core.main/src/test/java/test/core/template/ui_apply.t Modified: trunk/org.vexi-core.main/src/main/java/org/vexi/core/VML.java =================================================================== --- trunk/org.vexi-core.main/src/main/java/org/vexi/core/VML.java 2013-03-21 06:10:41 UTC (rev 4497) +++ trunk/org.vexi-core.main/src/main/java/org/vexi/core/VML.java 2013-03-21 06:16:32 UTC (rev 4498) @@ -14,6 +14,24 @@ public class VML implements Constants { + static public class SubBlessing extends JS.Obj { + final JS property; + final Template template; + SubBlessing(String property, Template template){ + this.property = JSU.S(property); + this.template = template; + } + @Override public JS new_(JS[] args) throws JSExn { + return apply(null,args); + } + @Override public JS apply(JS this_, JS[] args) throws JSExn { + return template.apply(this_,args); + } + @Override public String coerceToString() { + return "SubString$"+Integer.toHexString(hashCode()); + } + } + static class Static extends CodeBlock implements Backtraceable { final JS vexi; final JS constructor; @@ -22,6 +40,7 @@ Template template; public Static(JS vexi, JS constructor, String sourceName) { + super(null); this.vexi = vexi; this.constructor = constructor; this.sourceName = sourceName; @@ -91,8 +110,9 @@ JS[] vals; ///< values to be "put" to instances of this template; elements correspond to those of keys Object script = null; ///< the script on this node - List children = new ArrayList(); ///< during XML parsing, this holds the list of currently-parsed children; null otherwise - Object preapply = null; ///< Pre-applied template (~linked list) in root node only (unless js:apply) + List children = null; ///< during XML parsing, this holds the list of currently-parsed children; null otherwise + List subtemplates = null; ///< sub templates to be assigned to properties, not applied on creation + Object preapply = null; ///< Pre-applied template (~linked list) in root node only (unless lang:apply) Object principal = null; ///< Template to be applied JS.Constructor type = null; @@ -111,11 +131,21 @@ // Static data/methods /////////////////////////////////////////////////////////////////// // FOOTNOTE:1 Template(CodeBlock parent, Template preapply, int startLine) { - this.parent = parent; + super(parent); this.preapply = preapply; this.startLine = startLine; } + void addChild(Template template) { + if(children==null) children = new ArrayList(); + children.add(template); + } + + void addSubTemplate(String property, Template template) { + if(subtemplates==null) subtemplates = new ArrayList(); + subtemplates.add(new SubBlessing(property, template)); + } + // Methods to apply templates //////////////////////////////////////////////////////// @@ -192,6 +222,11 @@ JS ind = Main.SCHEDULER.getAndTriggerTraps(this_,SC_numchildren); Main.SCHEDULER.putAndTriggerTraps(this_, ind, kidHolder[0]); } + + for (int i=0; subtemplates!=null && i<subtemplates.size(); i++) { + SubBlessing subTemplate = (SubBlessing)subtemplates.get(i); + Main.SCHEDULER.putAndTriggerTraps(this_, subTemplate.property, subTemplate); + } if (keys!=null) { int l = keys.length; @@ -352,8 +387,20 @@ } } + static class SubTemplate extends CodeBlock{ + final boolean apply; + Template template; + + public SubTemplate(CodeBlock parent, boolean apply) { + super(parent); + this.apply = apply; + } + } - static class CodeBlock { + static abstract class CodeBlock { + final CodeBlock parent; /// Only used for sharing namepspace prefix information. + /// (i.e. templates are otherwise independent of each other). + // Only used during parsing ///////////////////////////////////////////////////////////////// StringBuffer content = null; ///< during XML parsing, this holds partially-read character data; null otherwise int content_start = 0; ///< line number of the first line of <tt>content</tt> @@ -361,13 +408,11 @@ Prefixes uriPrefixes; /// Uri prefixes->Blessings - CodeBlock parent = null; /// Only used for sharing namepspace prefix information. - /// (i.e. templates are independent of each other). - Template apply; // HACK related to ui:apply + CodeBlock(CodeBlock parent) { + this.parent = parent; + } - CodeBlock() { } - /** * Contains list of xml namespace prefixes. The <vexi/> and * each template node has its xml namespace converted into JS objects @@ -391,12 +436,14 @@ for (int i=0; i < prefixes.pfxSize(); i++) { String key = prefixes.getPrefixKey(i); String val = prefixes.getPrefixVal(i); - if (val.equals("vexi://ui")) { - continue; + if (val.startsWith("vexi://")){ + if(val.equals(equals("vexi://ui")) || + val.equals(equals("vexi://lang")) || + val.equals(equals("vexi://meta"))) { + continue; + } + } - if (val.equals("vexi://meta")) { - continue; - } if (val.length() > 0 && val.charAt(0)=='.') { val = val.substring(1); } Modified: trunk/org.vexi-core.main/src/main/java/org/vexi/core/VMLBuilder.java =================================================================== --- trunk/org.vexi-core.main/src/main/java/org/vexi/core/VMLBuilder.java 2013-03-21 06:10:41 UTC (rev 4497) +++ trunk/org.vexi-core.main/src/main/java/org/vexi/core/VMLBuilder.java 2013-03-21 06:16:32 UTC (rev 4498) @@ -18,9 +18,10 @@ import org.ibex.js.parse.Function; import org.ibex.util.Basket; import org.ibex.util.Tree; +import org.ibex.util.Tree.Element; import org.ibex.util.Vec; import org.ibex.util.XML; -import org.ibex.util.Tree.Element; +import org.vexi.core.VML.SubTemplate; import org.vexi.core.VML.CodeBlock; import org.vexi.core.VML.CodeBlock.Prefixes; import org.vexi.core.VML.Static.Template; @@ -143,7 +144,7 @@ public class VMLBuilder { - // FIXME having only one vexi object probably not correct in the GUT scheme of things + // FIXME having only one vexi object probably not correct in the GUT scheme of things static private Vexi vexi; static VMLBuilder instance; @@ -180,6 +181,7 @@ private static final int STATE_IN_APPLY_NODE = 2; private static final int STATE_IN_TEMPLATE_NODE = 3; private static final int STATE_IN_META_NODE = 4; + private static final int STATE_IN_SUB_TEMPLATE_NODE = 5; private static final JS[] callempty = new JS[0]; private static String LOG_TYPE = "[Template Warning]"; @@ -280,11 +282,15 @@ return r; } protected Exn e(String e){ - return new Exn(e, 0, getLine(), getCol()); + return new Exn(e, 0, getLine(), getCol()); } protected JSU.Wrapper e(JSExn e){ - return new JSU.Wrapper(e, this); + return new JSU.Wrapper(e, this); } + + @Override public void error(Exn e) throws Exn, IOException { + throw e; + } /** @param cur - current element */ public void startElement(Tree.Element cur) throws XML.Exn { @@ -320,24 +326,32 @@ uri = ""; } boolean specialUri = uri.startsWith("vexi://"); - boolean uiUri = specialUri && uri.equals("vexi://ui"); + boolean langUri = specialUri && uri.equals("vexi://lang"); switch (state) { case STATE_IN_ROOT_NODE: case STATE_IN_APPLY_NODE: - CodeBlock parent = state==STATE_IN_APPLY_NODE?cb.parent:null; + case STATE_IN_SUB_TEMPLATE_NODE: + CodeBlock parent = state!=STATE_IN_ROOT_NODE?cb.parent:null; Template preapply = t; cb = t = static_.new Template(parent, preapply, getLine()); state = STATE_IN_TEMPLATE_NODE; break; case STATE_IN_TEMPLATE_NODE: - if (uiUri && "apply".equals(cur.getLocalName())) { - cb = new CodeBlock(); - cb.parent = t; - t = null; - state = STATE_IN_APPLY_NODE; - cb.uriPrefixes = prefixes; - return; + if (langUri){ + if("apply".equals(cur.getLocalName())) { + cb = new SubTemplate(t, true); + t = null; + state = STATE_IN_APPLY_NODE; + cb.uriPrefixes = prefixes; + return; + }else if("subtemplate".equals(cur.getLocalName())){ + cb = new SubTemplate(t, false); + t = null; + state = STATE_IN_SUB_TEMPLATE_NODE; + cb.uriPrefixes = prefixes; + return; + } } cb = t = static_.new Template(t, null, getLine()); break; @@ -382,7 +396,7 @@ int keysSize = keys.size(); if (keysSize == 0) { - // no keys - nothing more to do + // no keys - nothing more to do return; } @@ -445,9 +459,10 @@ return; case STATE_IN_ROOT_NODE: return; + case STATE_IN_SUB_TEMPLATE_NODE: case STATE_IN_APPLY_NODE: if (cb.content!=null && cb.content.toString().trim().length()>0) { - throw e("apply element cannot have code/text"); + throw e(c.getLocalName()+" element cannot have code/text"); } } CodeBlock oldCb = cb; @@ -457,34 +472,49 @@ insertNewLines(cb.content, getLine() - oldCb.startLine); } // UGLY ... + + if (cb instanceof Template) { - Template oldT = state==STATE_IN_APPLY_NODE ? oldCb.apply : (Template)oldCb; - t = (Template)cb; - t.children.add(oldT); - state = STATE_IN_TEMPLATE_NODE; + t = (Template)cb; + if(oldCb instanceof SubTemplate){ + SubTemplate oldSt = (SubTemplate)oldCb; + if(oldSt.apply){ + assert(state==STATE_IN_APPLY_NODE); + t.addChild(oldSt.template); + }else{ + assert(state==STATE_IN_SUB_TEMPLATE_NODE); + int propI = c.getAttributes().getIndex(null, "property"); + String prop = c.getAttributes().getVal(propI); + if(prop==null) throw e("Sub Template node expects property"); + t.addSubTemplate(prop, oldSt.template); + } + }else{ + t.addChild((Template)oldCb); + } + state = STATE_IN_TEMPLATE_NODE; } else { if (nodeStack.size() == 0) { state = STATE_IN_ROOT_NODE; } else { - cb.apply = t; - state = STATE_IN_APPLY_NODE; + SubTemplate st = (SubTemplate)cb; + st.template = t; + state = st.apply?STATE_IN_APPLY_NODE:STATE_IN_SUB_TEMPLATE_NODE; } } } public void characters(char[] ch, int start, int length) throws XML.Exn { switch(state) { - case STATE_IN_APPLY_NODE: - case STATE_IN_ROOT_NODE: - case STATE_IN_TEMPLATE_NODE: + case STATE_INITIAL: + case STATE_IN_META_NODE: + return; + default: if (cb.content == null) { cb.content_start = getLine(); cb.content = new StringBuffer(); } cb.content.append(ch, start, length); return; - default: - return; } } Modified: trunk/org.vexi-core.main/src/test/java/test/core/template/TestTemplate.java =================================================================== --- trunk/org.vexi-core.main/src/test/java/test/core/template/TestTemplate.java 2013-03-21 06:10:41 UTC (rev 4497) +++ trunk/org.vexi-core.main/src/test/java/test/core/template/TestTemplate.java 2013-03-21 06:16:32 UTC (rev 4498) @@ -16,7 +16,8 @@ public static void main(String[] args) throws Throwable { CoreTestSuite cts = new CoreTestSuite(TestTemplate.class); - TestCase t = cts.createTestCase(cts.getResourceDirs(), "subComponents.t"); +// TestCase t = cts.createTestCase(cts.getResourceDirs(), "lang_apply.t"); + TestCase t = cts.createTestCase(cts.getResourceDirs(), "lang_subtemplate.t"); t.runBare(); } } Copied: trunk/org.vexi-core.main/src/test/java/test/core/template/lang_apply.t (from rev 4471, trunk/org.vexi-core.main/src/test/java/test/core/template/ui_apply.t) =================================================================== --- trunk/org.vexi-core.main/src/test/java/test/core/template/lang_apply.t (rev 0) +++ trunk/org.vexi-core.main/src/test/java/test/core/template/lang_apply.t 2013-03-21 06:16:32 UTC (rev 4498) @@ -0,0 +1,20 @@ +<vexi xmlns:ui="vexi://ui" xmlns:lang="vexi://lang"> + + + <ui:box> + <lang:apply> + <ui:box a="1"/> + <ui:box b="2"/> + <ui:box c="3"> + thisbox.d ++= function(){ + return a + b + c; + }; + </ui:box> + </lang:apply> + .util..assertEquals(1,thisbox[0].a); + .util..assertEquals(2,thisbox[0].b); + .util..assertEquals(3,thisbox[0].c); + .util..assertEquals(6,thisbox[0].d); + </ui:box> + +</vexi> Added: trunk/org.vexi-core.main/src/test/java/test/core/template/lang_subtemplate.t =================================================================== --- trunk/org.vexi-core.main/src/test/java/test/core/template/lang_subtemplate.t (rev 0) +++ trunk/org.vexi-core.main/src/test/java/test/core/template/lang_subtemplate.t 2013-03-21 06:16:32 UTC (rev 4498) @@ -0,0 +1,18 @@ +<vexi xmlns:ui="vexi://ui" xmlns:lang="vexi://lang"> + <ui:Box> + <lang:subtemplate property="sub"> + <ui:Box> + thisbox.text = arguments[0]; + </ui:Box> + </lang:subtemplate> + + .util..assertEquals(0,thisbox.numchildren); + + thisbox.add(new sub("A")); + thisbox.add(new sub("B")); + + .util..assertEquals("A",thisbox[0].text); + .util..assertEquals("B",thisbox[1].text); + </ui:Box> + +</vexi> Deleted: trunk/org.vexi-core.main/src/test/java/test/core/template/ui_apply.t =================================================================== --- trunk/org.vexi-core.main/src/test/java/test/core/template/ui_apply.t 2013-03-21 06:10:41 UTC (rev 4497) +++ trunk/org.vexi-core.main/src/test/java/test/core/template/ui_apply.t 2013-03-21 06:16:32 UTC (rev 4498) @@ -1,20 +0,0 @@ -<vexi xmlns:ui="vexi://ui" xmlns=""> - - - <ui:box> - <ui:apply> - <ui:box a="1"/> - <ui:box b="2"/> - <ui:box c="3"> - thisbox.d ++= function(){ - return a + b + c; - }; - </ui:box> - </ui:apply> - .util..assertEquals(1,thisbox[0].a); - .util..assertEquals(2,thisbox[0].b); - .util..assertEquals(3,thisbox[0].c); - .util..assertEquals(6,thisbox[0].d); - </ui:box> - -</vexi> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------------ Everyone hates slow websites. So do we. Make your web apps faster with AppDynamics Download AppDynamics Lite for free today: http://p.sf.net/sfu/appdyn_d2d_mar _______________________________________________ Vexi-svn mailing list Vexi-svn@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/vexi-svn