LinkedList<Node> nodes = new LinkedList<Node>();
Node nextNode = null;
while (true) {
if (!iter.hasNext()) throw new TemplateBuildFailedException("format error"); // TODO
// message
Fragment nextFrag = iter.next();
nextNode = this.toNode(template, text, nextFrag, iter, replaces, charset); // 再帰
if (nextNode instanceof StartTagNode) break; // 再帰終了
nodes.addFirst(nextNode);
}
StartTagNode start = (StartTagNode) nextNode;
Node compositeNode = CompositeNode.newNode(start, end, nodes.toArray(new Node[nodes.size()]));
if (compositeNode instanceof BlockNode) {
BlockNode block = (BlockNode) compositeNode;
String id = block.startTagNode.attrValue;
if (replaces == null) {
// 置換対象がない場合は積み上げる
this.blocks.put(id, block);
} else if (replaces.containsKey(id)) {
// 置換対象があれば置換する
return new BlockNode(start, end, replaces.get(id).nodes);
} else {
// そのまま使うのでなにもしない
}
}
return compositeNode;
case TAG_EMPTY_ELEMENTS:
if (PrkElement.REPLACE.name.equals(fragment.prkKey)) {
tagText = getTagText(str);
start = new StartTagNode(tagText, fragment.prkKey, fragment.prkValue, fragment.prkAttributes(),
fragment.pathAttributes(), fragment.attributes());
end = new EndTagNode(str);
return new ReplaceNode(start, end, new Node[] {});
} else if (PrkElement.INCLUDE.name.equals(fragment.prkKey)) {
// prk: include
// TODO 相対パスの解決
try {
XhtmlTemplate includeTemplate = new XhtmlTemplate(fragment.prkValue);
File includeFile = loader.toFile(fragment.prkValue, template.templateName);
XhtmlStruct includeStruct = parse(includeFile, charset);
buildTemplate(includeTemplate, includeStruct, null, charset);
// IncludeNode node = new IncludeNode(includeTemplate);
// template.stack(node);
template.components.addAll(includeTemplate.components);
for (String name : includeTemplate.functions.keySet()) {
template.functions.put(name, includeTemplate.functions.get(name));
}
// text.delete(fragment.offset, text.length());
return new IncludeNode(includeTemplate);
} catch (Exception e) {
throw new ParseException(e);
}
} else if (PrkElement.VAL.name.equals(fragment.prkKey)) {
return new ValNode(fragment.prkValue, fragment.attributes().get("value"));
} else {
String tagName = getTagText(str);
return new EmptyElementTagNode(tagName, fragment.prkKey, fragment.prkValue, fragment.prkAttributes(),
fragment.pathAttributes(), fragment.attributes());
}
case DEF_START:
throw new AssertionError();
case DEF_CDATA:
throw new AssertionError();
case DEF_END:
// ENDは無視
if (!iter.hasNext()) throw new TemplateBuildFailedException("format error"); // TODO
// message
Fragment cdataFrag = iter.next();
if (cdataFrag.type != Fragment.Type.DEF_CDATA) throw new TemplateBuildFailedException("format error"); // TODO
// message
StringBuilder script = new StringBuilder(text.substring(cdataFrag.offset));
script.delete(0, script.indexOf("<![CDATA[") + "<![CDATA[".length());
script.setLength(script.lastIndexOf("]]>"));
text.delete(cdataFrag.offset, text.length());
if (!iter.hasNext()) throw new TemplateBuildFailedException("format error"); // TODO
// message
Fragment startFrag = iter.next();
if (startFrag.type != Fragment.Type.DEF_START) throw new TemplateBuildFailedException("format error"); // TODO
// message
text.delete(startFrag.offset, text.length());
Fragment.Attribute[] flgAttrs = startFrag.attributeArray();
assert flgAttrs.length == 3 : startFrag;
assert flgAttrs[0].key.equals("language") : startFrag;
assert flgAttrs[1].key.equals("type") : startFrag;
assert flgAttrs[1].value.equals("function") : startFrag;
assert flgAttrs[2].key.equals("name") : startFrag;