io.honeybadger.com.github.mustachejava.codes.ExtendCode Maven / Gradle / Ivy
package com.github.mustachejava.codes;
import com.github.mustachejava.Code;
import com.github.mustachejava.DefaultMustacheFactory;
import com.github.mustachejava.Mustache;
import com.github.mustachejava.MustacheException;
import com.github.mustachejava.TemplateContext;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* Extending a template through in-place replacement of the overridden codes.
*
* User: sam
* Date: 11/27/11
* Time: 10:39 AM
*/
public class ExtendCode extends PartialCode {
private final DefaultMustacheFactory mf;
public ExtendCode(TemplateContext tc, DefaultMustacheFactory mf, Mustache codes, String name) throws MustacheException {
super(tc, mf, codes, "<", name);
this.mf = mf;
}
private Code[] replaceCodes(Code[] supercodes, Map replaceMap, Set seen) {
Code[] newcodes = supercodes.clone();
for (int i = 0; i < supercodes.length; i++) {
Code code = supercodes[i];
if (seen.add(code)) {
if (code instanceof ExtendNameCode) {
ExtendNameCode enc = (ExtendNameCode) code;
ExtendNameCode extendReplaceCode = replaceMap.get(enc.getName());
if (extendReplaceCode != null) {
ExtendNameCode newcode = (ExtendNameCode) (newcodes[i] = (Code) extendReplaceCode.clone());
// We need to set the appended text of the new code to that of the old code
newcode.appended = enc.appended;
} else {
enc.setCodes(replaceCodes(enc.getCodes(), replaceMap, seen));
}
} else {
Code[] codes = code.getCodes();
if (codes != null) {
code.setCodes(replaceCodes(codes, replaceMap, seen));
}
}
seen.remove(code);
}
}
return newcodes;
}
@SuppressWarnings("StatementWithEmptyBody")
@Override
public synchronized void init() {
filterText();
Map replaceMap = new HashMap<>();
for (Code code : mustache.getCodes()) {
if (code instanceof ExtendNameCode) {
// put name codes in the map
ExtendNameCode erc = (ExtendNameCode) code;
replaceMap.put(erc.getName(), erc);
erc.init();
} else if ((code instanceof WriteCode) || (code instanceof CommentCode)) {
// ignore text and comments
} else {
// fail on everything else
throw new IllegalArgumentException(
"Illegal code in extend section: " + code.getClass().getName());
}
}
Mustache original = mf.compilePartial(partialName());
partial = (Mustache) original.clone();
Code[] supercodes = partial.getCodes();
// recursively replace named sections with replacements
Set seen = new HashSet<>();
seen.add(partial);
partial.setCodes(replaceCodes(supercodes, replaceMap, seen));
}
}