use of freemarker.template.TemplateModel in project freemarker by apache.
the class Interpret method calculateResult.
/**
* Constructs a template on-the-fly and returns it embedded in a
* {@link TemplateTransformModel}.
*
* <p>The built-in has two arguments:
* the arguments passed to the method. It can receive at
* least one and at most two arguments, both must evaluate to a scalar.
* The first scalar is interpreted as a template source code and a template
* is built from it. The second (optional) is used to give the generated
* template a name.
*
* @return a {@link TemplateTransformModel} that when executed inside
* a <tt><transform></tt> block will process the generated template
* just as if it had been <tt><transform></tt>-ed at that point.
*/
@Override
protected TemplateModel calculateResult(Environment env) throws TemplateException {
TemplateModel model = target.eval(env);
Expression sourceExpr = null;
String id = "anonymous_interpreted";
if (model instanceof TemplateSequenceModel) {
sourceExpr = ((Expression) new DynamicKeyName(target, new NumberLiteral(Integer.valueOf(0))).copyLocationFrom(target));
if (((TemplateSequenceModel) model).size() > 1) {
id = ((Expression) new DynamicKeyName(target, new NumberLiteral(Integer.valueOf(1))).copyLocationFrom(target)).evalAndCoerceToPlainText(env);
}
} else if (model instanceof TemplateScalarModel) {
sourceExpr = target;
} else {
throw new UnexpectedTypeException(target, model, "sequence or string", new Class[] { TemplateSequenceModel.class, TemplateScalarModel.class }, env);
}
String templateSource = sourceExpr.evalAndCoerceToPlainText(env);
Template parentTemplate = env.getConfiguration().getIncompatibleImprovements().intValue() >= _TemplateAPI.VERSION_INT_2_3_26 ? env.getCurrentTemplate() : env.getTemplate();
final Template interpretedTemplate;
try {
ParserConfiguration pCfg = parentTemplate.getParserConfiguration();
// pCfg.outputFormat is exceptional: it's inherited from the lexical context
if (pCfg.getOutputFormat() != outputFormat) {
pCfg = new _ParserConfigurationWithInheritedFormat(pCfg, outputFormat, Integer.valueOf(autoEscapingPolicy));
}
interpretedTemplate = new Template((parentTemplate.getName() != null ? parentTemplate.getName() : "nameless_template") + "->" + id, null, new StringReader(templateSource), parentTemplate.getConfiguration(), pCfg, null);
} catch (IOException e) {
throw new _MiscTemplateException(this, e, env, new Object[] { "Template parsing with \"?", key, "\" has failed with this error:\n\n", _MessageUtil.EMBEDDED_MESSAGE_BEGIN, new _DelayedGetMessage(e), _MessageUtil.EMBEDDED_MESSAGE_END, "\n\nThe failed expression:" });
}
interpretedTemplate.setLocale(env.getLocale());
return new TemplateProcessorModel(interpretedTemplate);
}
use of freemarker.template.TemplateModel in project freemarker by apache.
the class Assignment method accept.
@Override
TemplateElement[] accept(Environment env) throws TemplateException {
final Environment.Namespace namespace;
if (namespaceExp == null) {
switch(scope) {
case LOCAL:
namespace = null;
break;
case GLOBAL:
namespace = env.getGlobalNamespace();
break;
case NAMESPACE:
namespace = env.getCurrentNamespace();
break;
default:
throw new BugException("Unexpected scope type: " + scope);
}
} else {
TemplateModel namespaceTM = namespaceExp.eval(env);
try {
namespace = (Environment.Namespace) namespaceTM;
} catch (ClassCastException e) {
throw new NonNamespaceException(namespaceExp, namespaceTM, env);
}
if (namespace == null) {
throw InvalidReferenceException.getInstance(namespaceExp, env);
}
}
TemplateModel value;
if (operatorType == OPERATOR_TYPE_EQUALS) {
value = valueExp.eval(env);
if (value == null) {
if (env.isClassicCompatible()) {
value = TemplateScalarModel.EMPTY_STRING;
} else {
throw InvalidReferenceException.getInstance(valueExp, env);
}
}
} else {
TemplateModel lhoValue;
if (namespace == null) {
lhoValue = env.getLocalVariable(variableName);
} else {
lhoValue = namespace.get(variableName);
}
if (operatorType == OPERATOR_TYPE_PLUS_EQUALS) {
// Add or concat operation
if (lhoValue == null) {
if (env.isClassicCompatible()) {
lhoValue = TemplateScalarModel.EMPTY_STRING;
} else {
throw InvalidReferenceException.getInstance(scope, variableName, getOperatorTypeAsString(), env);
}
}
value = valueExp.eval(env);
if (value == null) {
if (env.isClassicCompatible()) {
value = TemplateScalarModel.EMPTY_STRING;
} else {
throw InvalidReferenceException.getInstance(valueExp, env);
}
}
value = AddConcatExpression._eval(env, namespaceExp, null, lhoValue, valueExp, value);
} else {
// Numerical operation
Number lhoNumber;
if (lhoValue instanceof TemplateNumberModel) {
lhoNumber = EvalUtil.modelToNumber((TemplateNumberModel) lhoValue, null);
} else if (lhoValue == null) {
throw InvalidReferenceException.getInstance(scope, variableName, getOperatorTypeAsString(), env);
} else {
throw new NonNumericalException(variableName, lhoValue, null, env);
}
if (operatorType == OPERATOR_TYPE_PLUS_PLUS) {
value = AddConcatExpression._evalOnNumbers(env, getParentElement(), lhoNumber, ONE);
} else if (operatorType == OPERATOR_TYPE_MINUS_MINUS) {
value = ArithmeticExpression._eval(env, getParentElement(), lhoNumber, ArithmeticExpression.TYPE_SUBSTRACTION, ONE);
} else {
// operatorType == ArithmeticExpression.TYPE_...
Number rhoNumber = valueExp.evalToNumber(env);
value = ArithmeticExpression._eval(env, this, lhoNumber, operatorType, rhoNumber);
}
}
}
if (namespace == null) {
env.setLocalVariable(variableName, value);
} else {
namespace.put(variableName, value);
}
return null;
}
use of freemarker.template.TemplateModel in project freemarker by apache.
the class BlockAssignment method accept.
@Override
TemplateElement[] accept(Environment env) throws TemplateException, IOException {
TemplateElement[] children = getChildBuffer();
TemplateModel value;
if (children != null) {
StringWriter out = new StringWriter();
env.visit(children, out);
value = capturedStringToModel(out.toString());
} else {
value = capturedStringToModel("");
}
if (namespaceExp != null) {
((Environment.Namespace) namespaceExp.eval(env)).put(varName, value);
} else if (scope == Assignment.NAMESPACE) {
env.setVariable(varName, value);
} else if (scope == Assignment.GLOBAL) {
env.setGlobalVariable(varName, value);
} else if (scope == Assignment.LOCAL) {
env.setLocalVariable(varName, value);
} else {
throw new BugException("Unhandled scope");
}
return null;
}
use of freemarker.template.TemplateModel in project freemarker by apache.
the class BuiltInForLegacyEscaping method _eval.
@Override
TemplateModel _eval(Environment env) throws TemplateException {
TemplateModel tm = target.eval(env);
Object moOrStr = EvalUtil.coerceModelToStringOrMarkup(tm, target, null, env);
if (moOrStr instanceof String) {
return calculateResult((String) moOrStr, env);
} else {
TemplateMarkupOutputModel<?> mo = (TemplateMarkupOutputModel<?>) moOrStr;
if (mo.getOutputFormat().isLegacyBuiltInBypassed(key)) {
return mo;
}
throw new NonStringException(target, tm, env);
}
}
use of freemarker.template.TemplateModel in project freemarker by apache.
the class SequenceBuiltInTest method testWithCollection.
@Test
public void testWithCollection() throws TemplateException, IOException {
ObjectWrapperWithAPISupport ow = (ObjectWrapperWithAPISupport) getConfiguration().getObjectWrapper();
TemplateModel xs = DefaultIterableAdapter.adapt(ImmutableSet.of("a", "b"), ow);
assertThat(xs, not(instanceOf(TemplateCollectionModelEx.class)));
assertThat(xs, not(instanceOf(TemplateSequenceModel.class)));
addToDataModel("xs", xs);
try {
assertOutput("${xs[1]}", "b");
fail();
} catch (TemplateException e) {
// Contains tip to use ?sequence
assertThat(e.getMessage(), containsString("?sequence"));
}
assertOutput("${xs?sequence[1]}", "b");
try {
assertOutput("${xs?size}", "2");
fail();
} catch (TemplateException e) {
// Contains tip to use ?sequence
assertThat(e.getMessage(), containsString("?sequence"));
}
assertOutput("${xs?sequence?size}", "2");
}
Aggregations