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 @@
+
+
+
+
+ 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 @@
+
+
+
+
+
+
子要素のテキスト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 @@
+
+
+
+
+
+
+
+