com.github.mustachejava.codes.ValueCode Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of compiler Show documentation
Show all versions of compiler Show documentation
Implementation of mustache.js for Java
package com.github.mustachejava.codes;
import com.github.mustachejava.DefaultMustacheFactory;
import com.github.mustachejava.FragmentKey;
import com.github.mustachejava.MustacheException;
import com.github.mustachejava.TemplateContext;
import com.github.mustachejava.util.LatchedWriter;
import com.github.mustachejava.util.Node;
import com.google.common.base.Function;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static com.github.mustachejava.MustacheParser.DEFAULT_EM;
import static com.github.mustachejava.MustacheParser.DEFAULT_SM;
import static com.github.mustachejava.util.NodeValue.value;
/**
* Output a value
*/
public class ValueCode extends DefaultCode {
private final boolean encoded;
private final ExecutorService les;
@Override
public void identity(Writer writer) {
try {
if (name != null) {
writer.write(tc.startChars());
if (!encoded) {
writer.write("{");
}
writer.write(type);
writer.write(name);
if (!encoded) {
writer.write("}");
}
writer.write(tc.endChars());
}
appendText(writer);
} catch (IOException e) {
throw new MustacheException(e);
}
}
public ValueCode(TemplateContext tc, DefaultMustacheFactory df, String variable, boolean encoded) {
super(tc, df, null, variable, "");
this.encoded = encoded;
les = df.getExecutorService();
}
@Override
public Writer execute(Writer writer, final Object[] scopes) {
try {
final Object object = get(scopes);
if (object != null) {
if (object instanceof Function) {
handleFunction(writer, (Function) object, scopes);
} else if (object instanceof Callable) {
return handleCallable(writer, (Callable) object, scopes);
} else {
execute(writer, oh.stringify(object));
}
}
return super.execute(writer, scopes);
} catch (Exception e) {
throw new MustacheException("Failed to get value for " + name, e, tc);
}
}
protected Writer handleCallable(Writer writer, final Callable callable, final Object[] scopes) throws Exception {
if (les == null) {
Object call = callable.call();
execute(writer, call == null ? null : oh.stringify(call));
return super.execute(writer, scopes);
} else {
// Flush the current writer
try {
writer.flush();
} catch (IOException e) {
throw new MustacheException("Failed to flush writer", e);
}
final LatchedWriter latchedWriter = new LatchedWriter(writer);
final Writer finalWriter = writer;
les.execute(new Runnable() {
@Override
public void run() {
try {
Object call = callable.call();
execute(finalWriter, call == null ? null : oh.stringify(call));
latchedWriter.done();
} catch (Throwable e) {
latchedWriter.failed(e);
}
}
});
return super.execute(latchedWriter, scopes);
}
}
@SuppressWarnings("unchecked")
protected void handleFunction(Writer writer, Function function, Object[] scopes) throws IOException {
String value;
Object newtemplate = function.apply(null);
if (newtemplate == null) {
value = "";
} else {
String templateText = newtemplate.toString();
StringWriter sw = new StringWriter();
TemplateContext newTC = new TemplateContext(DEFAULT_SM, DEFAULT_EM, tc.file(), tc.line(), tc.startOfLine());
df.getFragment(new FragmentKey(newTC, templateText)).execute(sw, scopes).close();
value = sw.toString();
}
execute(writer, value);
}
protected void execute(Writer writer, String value) throws IOException {
// Treat null values as the empty string
if (value != null) {
if (encoded) {
df.encode(value, writer);
} else {
writer.write(value);
}
}
}
private Pattern compiledAppended;
@Override
public Node invert(Node node, String text, AtomicInteger position) {
if (compiledAppended == null) {
if (appended == null) {
compiledAppended = Pattern.compile("$");
} else {
compiledAppended = Pattern.compile(appended);
}
}
int start = position.get();
Matcher matcher = compiledAppended.matcher(text);
if (matcher.find(position.get())) {
String value = text.substring(start, matcher.start());
position.set(matcher.start() + matcher.group(0).length());
node.put(name, value(value));
return node;
} else {
return null;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy