diff --git a/template/org.tinygroup.templateengine/src/main/java/org/tinygroup/template/interpret/TemplateInterpretEngine.java b/template/org.tinygroup.templateengine/src/main/java/org/tinygroup/template/interpret/TemplateInterpretEngine.java index 0e99b7d1753215b1f999a72352f38f91166d4165..df5c49b3a290c51410c4261e7e1fc51a5b510387 100644 --- a/template/org.tinygroup.templateengine/src/main/java/org/tinygroup/template/interpret/TemplateInterpretEngine.java +++ b/template/org.tinygroup.templateengine/src/main/java/org/tinygroup/template/interpret/TemplateInterpretEngine.java @@ -56,6 +56,7 @@ public class TemplateInterpretEngine implements TemplateEngine { } static { + interpreter.addContextProcessor(new StopProcessor()); interpreter.addContextProcessor(new ValueProcessor()); interpreter.addContextProcessor(new ForProcessor()); interpreter.addContextProcessor(new SetProcessor()); diff --git a/template/org.tinygroup.templateengine/src/main/java/org/tinygroup/template/interpret/TinyAnltrParseConstants.java b/template/org.tinygroup.templateengine/src/main/java/org/tinygroup/template/interpret/TinyAnltrParseConstants.java new file mode 100644 index 0000000000000000000000000000000000000000..d94a6da002ec07896a8b62e066533f0eeecfee67 --- /dev/null +++ b/template/org.tinygroup.templateengine/src/main/java/org/tinygroup/template/interpret/TinyAnltrParseConstants.java @@ -0,0 +1,10 @@ +package org.tinygroup.template.interpret; + +/** + * + * @author Young 2015年7月22日 + * + */ +public class TinyAnltrParseConstants { + public static final String _STOP_EXIT = "STOP"; +} diff --git a/template/org.tinygroup.templateengine/src/main/java/org/tinygroup/template/interpret/context/MapProcessor.java b/template/org.tinygroup.templateengine/src/main/java/org/tinygroup/template/interpret/context/MapProcessor.java index f8b0649c872b079cc24e0c81464e0085f778ee26..d24d3d456d8158ca38a5ec4d4a3f8c9ce1d4530e 100644 --- a/template/org.tinygroup.templateengine/src/main/java/org/tinygroup/template/interpret/context/MapProcessor.java +++ b/template/org.tinygroup.templateengine/src/main/java/org/tinygroup/template/interpret/context/MapProcessor.java @@ -1,16 +1,15 @@ package org.tinygroup.template.interpret.context; +import java.io.Writer; +import java.util.List; + import org.tinygroup.template.TemplateContext; import org.tinygroup.template.interpret.ContextProcessor; import org.tinygroup.template.interpret.TemplateFromContext; import org.tinygroup.template.interpret.TemplateInterpretEngine; import org.tinygroup.template.interpret.TemplateInterpreter; import org.tinygroup.template.parser.grammer.TinyTemplateParser; - -import java.io.Writer; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import org.tinygroup.template.rumtime.TemplateMap; /** * Created by luog on 15/7/17. @@ -18,27 +17,36 @@ import java.util.Map; public class MapProcessor implements ContextProcessor { - public Class getType() { - return TinyTemplateParser.Expr_hash_mapContext.class; - } - - public boolean processChildren() { - return false; - } - - public Object process(TemplateInterpreter interpreter, TemplateFromContext templateFromContext, TinyTemplateParser.Expr_hash_mapContext parseTree, TemplateContext context, Writer writer, TemplateInterpretEngine engine) throws Exception { - List expressions = parseTree.hash_map_entry_list().expression(); - List expressionContexts = expressions; - Map map = new HashMap(); - if (expressions != null) { - for (int i = 0; i < expressions.size(); i += 2) { - String key = interpreter.interpretTree(engine, templateFromContext, expressions.get(i), context, writer).toString(); - String value = interpreter.interpretTree(engine, templateFromContext, expressions.get(i + 1), context, writer).toString(); - map.put(key, value); - } - } - return map; + public Class getType() { + return TinyTemplateParser.Expr_hash_mapContext.class; + } + + public boolean processChildren() { + return false; + } + + @SuppressWarnings("unchecked") + public Object process(TemplateInterpreter interpreter, TemplateFromContext templateFromContext, + TinyTemplateParser.Expr_hash_mapContext parseTree, TemplateContext context, Writer writer, + TemplateInterpretEngine engine) throws Exception { + List expressions = + parseTree.hash_map_entry_list().expression(); + TemplateMap tmap = new TemplateMap(); + if (expressions != null) { + for (int i = 0; i < expressions.size(); i += 2) { + String key = interpreter + .interpretTree(engine, templateFromContext, expressions.get(i), context, writer) + .toString(); + String value = interpreter + .interpretTree(engine, templateFromContext, expressions.get(i + 1), context, writer) + .toString(); + tmap.put(key, value); + tmap.getBlockingDeque().add(key); + tmap.getBlockingDeque().add(value); + } } + return tmap; + } } diff --git a/template/org.tinygroup.templateengine/src/main/java/org/tinygroup/template/interpret/context/StopProcessor.java b/template/org.tinygroup.templateengine/src/main/java/org/tinygroup/template/interpret/context/StopProcessor.java index f4d74eaff04d7bb9583a7ec464b4a1cd32f31b4b..02e81fdd3c9459b24ff73ff5621ebfee1e69a42b 100644 --- a/template/org.tinygroup.templateengine/src/main/java/org/tinygroup/template/interpret/context/StopProcessor.java +++ b/template/org.tinygroup.templateengine/src/main/java/org/tinygroup/template/interpret/context/StopProcessor.java @@ -12,23 +12,26 @@ import java.io.Writer; */ public class StopProcessor implements ContextProcessor { - public Class getType() { - return TinyTemplateParser.Stop_directiveContext.class; - } + public Class getType() { + return TinyTemplateParser.Stop_directiveContext.class; + } - public boolean processChildren() { - return false; - } + public boolean processChildren() { + return false; + } - public Object process(TemplateInterpreter interpreter, TemplateFromContext template, TinyTemplateParser.Stop_directiveContext parseTree, TemplateContext context, Writer writer, TemplateInterpretEngine engine) throws Exception { - boolean stop = true; - if (parseTree.expression() != null) { - stop = U.b(interpreter.interpretTree(engine, template, parseTree.expression(), context, writer)); - } - if (stop) { - throw new StopException(); - } - return null; + public Object process(TemplateInterpreter interpreter, TemplateFromContext template, + TinyTemplateParser.Stop_directiveContext parseTree, TemplateContext context, Writer writer, + TemplateInterpretEngine engine) throws Exception { + boolean stop = true; + if (parseTree.expression() != null) { + stop = + U.b(interpreter.interpretTree(engine, template, parseTree.expression(), context, writer)); + } + if (stop) { + context.put(TinyAnltrParseConstants._STOP_EXIT, true); } + return null; + } } diff --git a/template/org.tinygroup.templateengine/src/main/java/org/tinygroup/template/interpret/context/ValueProcessor.java b/template/org.tinygroup.templateengine/src/main/java/org/tinygroup/template/interpret/context/ValueProcessor.java index a65530a430e70c2e2350f974abafaac9867154b1..6f38d8652f1d13f519b4a840956016a3efff9bab 100644 --- a/template/org.tinygroup.templateengine/src/main/java/org/tinygroup/template/interpret/context/ValueProcessor.java +++ b/template/org.tinygroup.templateengine/src/main/java/org/tinygroup/template/interpret/context/ValueProcessor.java @@ -1,39 +1,54 @@ package org.tinygroup.template.interpret.context; +import java.io.Writer; + import org.tinygroup.template.TemplateContext; import org.tinygroup.template.interpret.ContextProcessor; import org.tinygroup.template.interpret.TemplateFromContext; import org.tinygroup.template.interpret.TemplateInterpretEngine; import org.tinygroup.template.interpret.TemplateInterpreter; import org.tinygroup.template.parser.grammer.TinyTemplateParser; +import org.tinygroup.template.rumtime.TemplateMap; import org.tinygroup.template.rumtime.U; -import java.io.Writer; - /** * Created by luog on 15/7/17. */ public class ValueProcessor implements ContextProcessor { - public Class getType() { - return TinyTemplateParser.ValueContext.class; - } - - public boolean processChildren() { - return false; - } - - public Object process(TemplateInterpreter interpreter, TemplateFromContext templateFromContext, TinyTemplateParser.ValueContext parseTree, TemplateContext context, Writer writer, TemplateInterpretEngine engine) throws Exception { - Object value = interpreter.interpretTree(engine, templateFromContext, parseTree.getChild(1), context, writer); - if (parseTree.getChild(0).getText().equals("${")) { - TemplateInterpreter.write(writer, value); - } else if (parseTree.getChild(0).getText().equals("$!{")) { - TemplateInterpreter.write(writer, U.escapeHtml(value)); - } else if (parseTree.getChild(0).getText().equals("$${")) { - TemplateInterpreter.write(writer, U.getI18n(null, context, value.toString())); - } - return null; + public Class getType() { + return TinyTemplateParser.ValueContext.class; + } + + public boolean processChildren() { + return false; + } + + public Object process(TemplateInterpreter interpreter, TemplateFromContext templateFromContext, + TinyTemplateParser.ValueContext parseTree, TemplateContext context, Writer writer, + TemplateInterpretEngine engine) throws Exception { + Object value = interpreter.interpretTree(engine, templateFromContext, parseTree.getChild(1), + context, writer); + TemplateMap tmap = (TemplateMap) context.getItemMap().get("map"); + if (tmap != null && tmap.size() > 0) { + Object key = tmap.getBlockingDeque().pop(); + if (value.equals("key")) { + TemplateInterpreter.write(writer, key); + } else { + Object k_value = tmap.getBlockingDeque().pop(); + TemplateInterpreter.write(writer, k_value); + } + } else { + if (parseTree.getChild(0).getText().equals("${")) { + TemplateInterpreter.write(writer, value); + } else if (parseTree.getChild(0).getText().equals("$!{")) { + TemplateInterpreter.write(writer, U.escapeHtml(value)); + } else if (parseTree.getChild(0).getText().equals("$${")) { + TemplateInterpreter.write(writer, U.getI18n(null, context, value.toString())); + } } + return null; + } } diff --git a/template/org.tinygroup.templateengine/src/main/java/org/tinygroup/template/interpret/terminal/TextPlainNodeProcessor.java b/template/org.tinygroup.templateengine/src/main/java/org/tinygroup/template/interpret/terminal/TextPlainNodeProcessor.java index dcec4501cd06fe716030542b35c8c48b633f7b17..d8372125f5c19641ac19e9753d54859363c2cd3e 100644 --- a/template/org.tinygroup.templateengine/src/main/java/org/tinygroup/template/interpret/terminal/TextPlainNodeProcessor.java +++ b/template/org.tinygroup.templateengine/src/main/java/org/tinygroup/template/interpret/terminal/TextPlainNodeProcessor.java @@ -1,30 +1,36 @@ package org.tinygroup.template.interpret.terminal; +import java.io.IOException; +import java.io.Writer; + import org.antlr.v4.runtime.tree.TerminalNode; import org.tinygroup.template.TemplateContext; -import org.tinygroup.template.interpret.TerminalNodeProcessor; import org.tinygroup.template.interpret.TemplateInterpreter; +import org.tinygroup.template.interpret.TerminalNodeProcessor; +import org.tinygroup.template.interpret.TinyAnltrParseConstants; import org.tinygroup.template.parser.grammer.TinyTemplateParser; -import java.io.IOException; -import java.io.Writer; - /** * Created by luog on 15/7/17. */ public class TextPlainNodeProcessor implements TerminalNodeProcessor { - public int getType() { - return TinyTemplateParser.TEXT_PLAIN; - } + public int getType() { + return TinyTemplateParser.TEXT_PLAIN; + } - public boolean processChildren() { - return false; - } + public boolean processChildren() { + return false; + } - public Object process(TerminalNode terminalNode, TemplateContext context, Writer writer) throws IOException { - TemplateInterpreter.write(writer, terminalNode.getText()); - return null; + public Object process(TerminalNode terminalNode, TemplateContext context, Writer writer) + throws IOException { + if (context.get(TinyAnltrParseConstants._STOP_EXIT) != null) { + return null; + } else { + TemplateInterpreter.write(writer, terminalNode.getText()); } + return null; + } } diff --git a/template/org.tinygroup.templateengine/src/main/java/org/tinygroup/template/rumtime/TemplateMap.java b/template/org.tinygroup.templateengine/src/main/java/org/tinygroup/template/rumtime/TemplateMap.java index 9ba0b5adafbd3741976e636d6bb60055bdf74629..26480e3d47bc91fafadd80e6db9d6f128a147507 100644 --- a/template/org.tinygroup.templateengine/src/main/java/org/tinygroup/template/rumtime/TemplateMap.java +++ b/template/org.tinygroup.templateengine/src/main/java/org/tinygroup/template/rumtime/TemplateMap.java @@ -1,32 +1,38 @@ /** - * Copyright (c) 1997-2013, www.tinygroup.org (tinygroup@126.com). + * Copyright (c) 1997-2013, www.tinygroup.org (tinygroup@126.com). * - * Licensed under the GPL, Version 3.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the GPL, Version 3.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at * - * http://www.gnu.org/licenses/gpl.html + * http://www.gnu.org/licenses/gpl.html * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. */ package org.tinygroup.template.rumtime; import java.util.HashMap; +import java.util.concurrent.BlockingDeque; +import java.util.concurrent.LinkedBlockingDeque; /** * Created by luoguo on 2014/6/8. */ public class TemplateMap extends HashMap { - public TemplateMap() { + public TemplateMap() { - } + } - public TemplateMap putItem(Object key, Object value) { - put(key, value); - return this; - } + private BlockingDeque queue = new LinkedBlockingDeque(); + + public TemplateMap putItem(Object key, Object value) { + put(key, value); + return this; + } + + public BlockingDeque getBlockingDeque() { + return queue; + } } diff --git a/template/org.tinygroup.templateengine/src/test/java/org/tinygroup/template/anltr/parser/TinyTemplateAnltrParse.java b/template/org.tinygroup.templateengine/src/test/java/org/tinygroup/template/anltr/parser/TinyTemplateAnltrParse.java new file mode 100644 index 0000000000000000000000000000000000000000..06da122dc2e39b537f775c5453721a3a6199c66a --- /dev/null +++ b/template/org.tinygroup.templateengine/src/test/java/org/tinygroup/template/anltr/parser/TinyTemplateAnltrParse.java @@ -0,0 +1,64 @@ +package org.tinygroup.template.anltr.parser; + +import java.io.OutputStreamWriter; +import java.io.Writer; + +import org.tinygroup.template.TemplateContext; +import org.tinygroup.template.TemplateEngine; +import org.tinygroup.template.impl.TemplateContextDefault; +import org.tinygroup.template.interpret.TemplateInterpretEngine; +import org.tinygroup.template.loader.FileObjectResourceLoader; + +import junit.framework.TestCase; + +/** + * + * @author Young + * + */ +@SuppressWarnings("static-access") +public class TinyTemplateAnltrParse extends TestCase { + public void test_render_set() throws Exception { + TemplateInterpretEngine engine = new TemplateInterpretEngine(); + TemplateContext context = new TemplateContextDefault(); + Writer writer = new OutputStreamWriter(System.out); + engine.interpreter.interpret(null, null, "#set(abc=123) ${abc} #eol ##123", "abc", context, + writer); + } + + public void test_render_for_break() throws Exception { + TemplateInterpretEngine engine = new TemplateInterpretEngine(); + TemplateContext context = new TemplateContextDefault(); + Writer writer = new OutputStreamWriter(System.out); + engine.interpreter.interpret(null, null, "#for(i: [1,2,3,4,5]) ${i} #break(i>3) #end", + "abc", context, writer); + + FileObjectResourceLoader tinySample = + new FileObjectResourceLoader("vm", "layout", null, "src/test/resources"); + engine.addResourceLoader(tinySample); + engine.renderTemplate("/template/tiny/for-break.vm"); + } + + + public void test_render_for_map() throws Exception { + TemplateInterpretEngine engine = new TemplateInterpretEngine(); + TemplateContext context = new TemplateContextDefault(); + Writer writer = new OutputStreamWriter(System.out); + engine.interpreter.interpret(null, null, + "#set ( map = {123: 1, 456: 2}) #for (x : map) ${x.value} #end", "abc", context, writer); + } + + public void test_render_for_continue() throws Exception { + TemplateEngine engine = new TemplateInterpretEngine(); + FileObjectResourceLoader tinySample = + new FileObjectResourceLoader("vm", "layout", null, "src/test/resources"); + engine.addResourceLoader(tinySample); + engine.renderTemplate("/template/tiny/for-continue.vm"); + } + public void test_render_stop() throws Exception { + TemplateInterpretEngine engine = new TemplateInterpretEngine(); + TemplateContext context = new TemplateContextDefault(); + Writer writer = new OutputStreamWriter(System.out); + engine.interpreter.interpret(null, null, "1234567890 #stop 111", "abc", context, writer); + } +}