diff --git a/src-impl/org/seasar/mayaa/impl/builder/TemplateBuilderImpl.java b/src-impl/org/seasar/mayaa/impl/builder/TemplateBuilderImpl.java index bc377c281..6167b8571 100644 --- a/src-impl/org/seasar/mayaa/impl/builder/TemplateBuilderImpl.java +++ b/src-impl/org/seasar/mayaa/impl/builder/TemplateBuilderImpl.java @@ -479,6 +479,7 @@ protected void optimizeProcessors(SequenceIDGenerator idGenerator, } } + // expandsとして展開された同階層のLiteralCharactersProcessorが連続している場合は結合する List packs = new ArrayList<>(); for (int i = 0; i < expands.size(); i++) { ProcessorTreeWalker node = (ProcessorTreeWalker) expands.get(i); diff --git a/src-impl/org/seasar/mayaa/impl/engine/processor/CDATAProcessor.java b/src-impl/org/seasar/mayaa/impl/engine/processor/CDATAProcessor.java index 78048b7f7..a05cba6c5 100644 --- a/src-impl/org/seasar/mayaa/impl/engine/processor/CDATAProcessor.java +++ b/src-impl/org/seasar/mayaa/impl/engine/processor/CDATAProcessor.java @@ -23,6 +23,7 @@ import org.seasar.mayaa.impl.CONST_IMPL; import org.seasar.mayaa.impl.builder.BuilderUtil; import org.seasar.mayaa.impl.cycle.CycleUtil; +import org.seasar.mayaa.impl.cycle.DefaultCycleLocalInstantiator; /** * @author Masataka Kurihara (Gluegent, Inc.) @@ -34,15 +35,44 @@ public class CDATAProcessor extends TemplateProcessorSupport private static final String CDATAIN = ""; + /** + * CDATAは入れ子で出力できないため、CDATAProcessorの呼び出しネストレベルをカウントするGlobalVariableを使用する。 + * 閉じタグのバランスが取れていないとCDATAが閉じないため注意する。 + * テンプレートに元々記載されている は検知できない(そもそもXMLパーサにより評価されないため期待通り)。 + */ + private static final String CDATA_IN_PROCESS_KEY = CDATAProcessor.class.getName() + "#nestLevel"; + static { + CycleUtil.registVariableFactory(CDATA_IN_PROCESS_KEY, + new DefaultCycleLocalInstantiator() { + @Override + public Object create(Object[] params) { + return Integer.valueOf(0); + } + } + ); + } + public ProcessStatus doStartProcess(Page topLevelPage) { - ServiceCycle cycle = CycleUtil.getServiceCycle(); - cycle.getResponse().write(CDATAIN); + // 入れ子のレベルを確認する。 + Integer nestLevel = (Integer) CycleUtil.getGlobalVariable(CDATA_IN_PROCESS_KEY, null); + if (nestLevel.intValue() == 0) { + ServiceCycle cycle = CycleUtil.getServiceCycle(); + cycle.getResponse().write(CDATAIN); + } + CycleUtil.setGlobalVariable(CDATA_IN_PROCESS_KEY, Integer.valueOf(nestLevel.intValue() + 1)); return ProcessStatus.EVAL_BODY_INCLUDE; } public ProcessStatus doEndProcess() { - ServiceCycle cycle = CycleUtil.getServiceCycle(); - cycle.getResponse().write(CDATAOUT); + // 入れ子のレベルを確認する。 + Integer nestLevel = (Integer) CycleUtil.getGlobalVariable(CDATA_IN_PROCESS_KEY, null); + CycleUtil.setGlobalVariable(CDATA_IN_PROCESS_KEY, Integer.valueOf(nestLevel.intValue() - 1)); + + if (nestLevel.intValue() <= 1 /* 1:最後のネストレベル */) { + ServiceCycle cycle = CycleUtil.getServiceCycle(); + cycle.getResponse().write(CDATAOUT); + CycleUtil.clearGlobalVariable(CDATA_IN_PROCESS_KEY); + } return ProcessStatus.EVAL_PAGE; } diff --git a/src/test/java/org/seasar/mayaa/functional/EngineTestBase.java b/src/test/java/org/seasar/mayaa/functional/EngineTestBase.java index 57bbd1409..6ed039b3b 100644 --- a/src/test/java/org/seasar/mayaa/functional/EngineTestBase.java +++ b/src/test/java/org/seasar/mayaa/functional/EngineTestBase.java @@ -22,6 +22,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; import java.net.URL; import java.util.Iterator; @@ -159,7 +160,14 @@ protected MockHttpServletResponse exec(final MockHttpServletRequest request, fin engine.doService(pageScopeAttribute, true); // verify(servletContext).getRealPath(path); - + if ("true".equals(engine.getParameter(EngineImpl.DUMP_ENABLED))) { + try { + final String content = response.getContentAsString(); + System.out.println(content); + } + catch (UnsupportedEncodingException e) { + } + } return response; } diff --git a/src/test/java/org/seasar/mayaa/functional/ProcessorTest.java b/src/test/java/org/seasar/mayaa/functional/ProcessorTest.java index 99a3fceb0..fe6892cc6 100644 --- a/src/test/java/org/seasar/mayaa/functional/ProcessorTest.java +++ b/src/test/java/org/seasar/mayaa/functional/ProcessorTest.java @@ -70,4 +70,11 @@ public class ProcessorTest extends EngineTestBase { } } + + @Test + public void プロセッサcdataで子要素をCDATAで囲む() throws IOException { + enableDump(); + execAndVerify(BASE_PATH + "cdata/target.html", BASE_PATH + "cdata/expected.html", null); + } + } diff --git a/src/test/resources/it-case/html-transform/processors/cdata/expected.html b/src/test/resources/it-case/html-transform/processors/cdata/expected.html new file mode 100644 index 000000000..ff7b72c0d --- /dev/null +++ b/src/test/resources/it-case/html-transform/processors/cdata/expected.html @@ -0,0 +1,24 @@ + + +
+ +
+
+ 子要素のテキスト1

+ TEXT + ]]> +
+
+ 子要素のテキスト1

+ +

子要素のテキスト2

+ TEXT + + ]]> +
+ + diff --git a/src/test/resources/it-case/html-transform/processors/cdata/target.html b/src/test/resources/it-case/html-transform/processors/cdata/target.html new file mode 100644 index 000000000..67ccca0c5 --- /dev/null +++ b/src/test/resources/it-case/html-transform/processors/cdata/target.html @@ -0,0 +1,24 @@ + + +
+
+ var val_int = 0; +
+
+
+
+

子要素のテキスト1

+

子要素のテキスト2

+
+
+
+
+

子要素のテキスト1

+
+

子要素のテキスト2

+

子要素のテキスト2

+
+
+
+ + diff --git a/src/test/resources/it-case/html-transform/processors/cdata/target.mayaa b/src/test/resources/it-case/html-transform/processors/cdata/target.mayaa new file mode 100644 index 000000000..5428b20a1 --- /dev/null +++ b/src/test/resources/it-case/html-transform/processors/cdata/target.mayaa @@ -0,0 +1,8 @@ + + + + + + + +