use of freemarker.template.TemplateMethodModelEx in project freemarker by apache.
the class GetOptionalTemplateMethod method exec.
public Object exec(List args) throws TemplateModelException {
final int argCnt = args.size();
if (argCnt < 1 || argCnt > 2) {
throw _MessageUtil.newArgCntError(methodName, argCnt, 1, 2);
}
final Environment env = Environment.getCurrentEnvironment();
if (env == null) {
throw new IllegalStateException("No freemarer.core.Environment is associated to the current thread.");
}
final String absTemplateName;
{
TemplateModel arg = (TemplateModel) args.get(0);
if (!(arg instanceof TemplateScalarModel)) {
throw _MessageUtil.newMethodArgMustBeStringException(methodName, 0, arg);
}
String templateName = EvalUtil.modelToString((TemplateScalarModel) arg, null, env);
try {
absTemplateName = env.toFullTemplateName(env.getCurrentTemplate().getName(), templateName);
} catch (MalformedTemplateNameException e) {
throw new _TemplateModelException(e, "Failed to convert template path to full path; see cause exception.");
}
}
final TemplateHashModelEx options;
if (argCnt > 1) {
TemplateModel arg = (TemplateModel) args.get(1);
if (!(arg instanceof TemplateHashModelEx)) {
throw _MessageUtil.newMethodArgMustBeExtendedHashException(methodName, 1, arg);
}
options = (TemplateHashModelEx) arg;
} else {
options = null;
}
String encoding = null;
boolean parse = true;
if (options != null) {
final KeyValuePairIterator kvpi = TemplateModelUtils.getKeyValuePairIterator(options);
while (kvpi.hasNext()) {
final KeyValuePair kvp = kvpi.next();
final String optName;
{
TemplateModel optNameTM = kvp.getKey();
if (!(optNameTM instanceof TemplateScalarModel)) {
throw _MessageUtil.newMethodArgInvalidValueException(methodName, 1, "All keys in the options hash must be strings, but found ", new _DelayedAOrAn(new _DelayedFTLTypeDescription(optNameTM)));
}
optName = ((TemplateScalarModel) optNameTM).getAsString();
}
final TemplateModel optValue = kvp.getValue();
if (OPTION_ENCODING.equals(optName)) {
encoding = getStringOption(OPTION_ENCODING, optValue);
} else if (OPTION_PARSE.equals(optName)) {
parse = getBooleanOption(OPTION_PARSE, optValue);
} else {
throw _MessageUtil.newMethodArgInvalidValueException(methodName, 1, "Unsupported option ", new _DelayedJQuote(optName), "; valid names are: ", new _DelayedJQuote(OPTION_ENCODING), ", ", new _DelayedJQuote(OPTION_PARSE), ".");
}
}
}
final Template template;
try {
template = env.getTemplateForInclusion(absTemplateName, encoding, parse, true);
} catch (IOException e) {
throw new _TemplateModelException(e, "I/O error when trying to load optional template ", new _DelayedJQuote(absTemplateName), "; see cause exception");
}
SimpleHash result = new SimpleHash(env.getObjectWrapper());
result.put(RESULT_EXISTS, template != null);
// conveniently provided like in <@optTemp.include!myDefaultMacro />.
if (template != null) {
result.put(RESULT_INCLUDE, new TemplateDirectiveModel() {
public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body) throws TemplateException, IOException {
if (!params.isEmpty()) {
throw new TemplateException("This directive supports no parameters.", env);
}
if (loopVars.length != 0) {
throw new TemplateException("This directive supports no loop variables.", env);
}
if (body != null) {
throw new TemplateException("This directive supports no nested content.", env);
}
env.include(template);
}
});
result.put(RESULT_IMPORT, new TemplateMethodModelEx() {
public Object exec(List args) throws TemplateModelException {
if (!args.isEmpty()) {
throw new TemplateModelException("This method supports no parameters.");
}
try {
return env.importLib(template, null);
} catch (IOException e) {
throw new _TemplateModelException(e, "Failed to import loaded template; see cause exception");
} catch (TemplateException e) {
throw new _TemplateModelException(e, "Failed to import loaded template; see cause exception");
}
}
});
}
return result;
}
use of freemarker.template.TemplateMethodModelEx in project freemarker by apache.
the class MethodCall method _eval.
@Override
TemplateModel _eval(Environment env) throws TemplateException {
TemplateModel targetModel = target.eval(env);
if (targetModel instanceof TemplateMethodModel) {
TemplateMethodModel targetMethod = (TemplateMethodModel) targetModel;
List argumentStrings = targetMethod instanceof TemplateMethodModelEx ? arguments.getModelList(env) : arguments.getValueList(env);
Object result = targetMethod.exec(argumentStrings);
return env.getObjectWrapper().wrap(result);
} else if (targetModel instanceof Macro) {
Macro func = (Macro) targetModel;
env.setLastReturnValue(null);
if (!func.isFunction()) {
throw new _MiscTemplateException(env, "A macro cannot be called in an expression. (Functions can be.)");
}
Writer prevOut = env.getOut();
try {
env.setOut(NullWriter.INSTANCE);
env.invoke(func, null, arguments.items, null, this);
} catch (IOException e) {
// Should not occur
throw new TemplateException("Unexpected exception during function execution", e, env);
} finally {
env.setOut(prevOut);
}
return env.getLastReturnValue();
} else {
throw new NonMethodException(target, targetModel, env);
}
}
use of freemarker.template.TemplateMethodModelEx in project freemarker by apache.
the class Java8BeansWrapperBridgeMethodsTest method test.
private void test(Class<?> pClass) throws TemplateModelException {
BeansWrapper ow = new BeansWrapperBuilder(Configuration.VERSION_2_3_26).build();
TemplateHashModel wrapped;
try {
wrapped = (TemplateHashModel) ow.wrap(pClass.newInstance());
} catch (Exception e) {
throw new IllegalStateException(e);
}
TemplateMethodModelEx m1 = (TemplateMethodModelEx) wrapped.get("m1");
assertEquals(BridgeMethodsBean.M1_RETURN_VALUE, "" + m1.exec(Collections.emptyList()));
TemplateMethodModelEx m2 = (TemplateMethodModelEx) wrapped.get("m2");
assertNull(m2.exec(Collections.emptyList()));
}
use of freemarker.template.TemplateMethodModelEx in project freemarker by apache.
the class Java8BeansWrapperTest method testDefaultMethodRecognized.
@Test
public void testDefaultMethodRecognized() throws TemplateModelException {
BeansWrapperBuilder owb = new BeansWrapperBuilder(Configuration.VERSION_2_3_0);
owb.setTreatDefaultMethodsAsBeanMembers(true);
BeansWrapper ow = owb.build();
TemplateHashModel wrappedBean = (TemplateHashModel) ow.wrap(new Java8DefaultMethodsBean());
{
TemplateScalarModel prop = (TemplateScalarModel) wrappedBean.get(Java8DefaultMethodsBean.NORMAL_PROP);
assertNotNull(prop);
assertEquals(Java8DefaultMethodsBean.NORMAL_PROP_VALUE, prop.getAsString());
}
{
// This is overridden in the subclass, so it's visible even without default method support:
TemplateScalarModel prop = (TemplateScalarModel) wrappedBean.get(Java8DefaultMethodsBean.DEFAULT_METHOD_PROP_2);
assertNotNull(prop);
assertEquals(Java8DefaultMethodsBean.PROP_2_OVERRIDE_VALUE, prop.getAsString());
}
{
TemplateScalarModel prop = (TemplateScalarModel) wrappedBean.get(Java8DefaultMethodsBeanBase.DEFAULT_METHOD_PROP);
assertNotNull(prop);
assertEquals(Java8DefaultMethodsBeanBase.DEFAULT_METHOD_PROP_VALUE, prop.getAsString());
}
{
TemplateSequenceModel prop = (TemplateSequenceModel) wrappedBean.get(Java8DefaultMethodsBeanBase.DEFAULT_METHOD_INDEXED_PROP);
assertNotNull(prop);
assertEquals(Java8DefaultMethodsBeanBase.DEFAULT_METHOD_INDEXED_PROP_VALUE, ((TemplateScalarModel) prop.get(0)).getAsString());
}
{
// We see default method indexed read method, but it's invalidated by normal getter in the subclass
TemplateNumberModel prop = (TemplateNumberModel) wrappedBean.get(Java8DefaultMethodsBean.DEFAULT_METHOD_NOT_AN_INDEXED_PROP);
assertNotNull(prop);
assertEquals(Java8DefaultMethodsBean.NOT_AN_INDEXED_PROP_VALUE, prop.getAsNumber());
}
{
// The default method read method invalidates the indexed read method in the subclass
TemplateScalarModel prop = (TemplateScalarModel) wrappedBean.get(Java8DefaultMethodsBean.DEFAULT_METHOD_NOT_AN_INDEXED_PROP_2);
assertNotNull(prop);
assertEquals(Java8DefaultMethodsBean.DEFAULT_METHOD_NOT_AN_INDEXED_PROP_2_VALUE, prop.getAsString());
}
{
// The default method read method invalidates the indexed read method in the subclass
TemplateSequenceModel prop = (TemplateSequenceModel) wrappedBean.get(Java8DefaultMethodsBean.DEFAULT_METHOD_NOT_AN_INDEXED_PROP_3);
assertNotNull(prop);
assertEquals(Java8DefaultMethodsBean.DEFAULT_METHOD_NOT_AN_INDEXED_PROP_3_VALUE_0, ((TemplateScalarModel) prop.get(0)).getAsString());
}
{
// We see the default method indexed reader, which overrides the plain array reader in the subclass.
TemplateSequenceModel prop = (TemplateSequenceModel) wrappedBean.get(Java8DefaultMethodsBean.DEFAULT_METHOD_INDEXED_PROP_2);
assertNotNull(prop);
assertEquals(Java8DefaultMethodsBean.DEFAULT_METHOD_INDEXED_PROP_2_VALUE_0, ((TemplateScalarModel) prop.get(0)).getAsString());
}
{
// We do see the default method non-indexed reader, but the subclass has a matching indexed reader, so that
// takes over.
TemplateSequenceModel prop = (TemplateSequenceModel) wrappedBean.get(Java8DefaultMethodsBean.DEFAULT_METHOD_INDEXED_PROP_3);
assertNotNull(prop);
assertEquals(Java8DefaultMethodsBean.INDEXED_PROP_3_VALUE, ((TemplateScalarModel) prop.get(0)).getAsString());
}
{
// Only present in the subclass.
TemplateSequenceModel prop = (TemplateSequenceModel) wrappedBean.get(Java8DefaultMethodsBean.INDEXED_PROP_4);
assertNotNull(prop);
assertEquals(Java8DefaultMethodsBean.INDEXED_PROP_4_VALUE, ((TemplateScalarModel) prop.get(0)).getAsString());
}
{
TemplateMethodModelEx action = (TemplateMethodModelEx) wrappedBean.get(Java8DefaultMethodsBean.NORMAL_ACTION);
assertNotNull(action);
assertEquals(Java8DefaultMethodsBean.NORMAL_ACTION_RETURN_VALUE, ((TemplateScalarModel) action.exec(Collections.emptyList())).getAsString());
}
{
TemplateMethodModelEx action = (TemplateMethodModelEx) wrappedBean.get(Java8DefaultMethodsBean.NORMAL_ACTION);
assertNotNull(action);
assertEquals(Java8DefaultMethodsBean.NORMAL_ACTION_RETURN_VALUE, ((TemplateScalarModel) action.exec(Collections.emptyList())).getAsString());
}
{
TemplateMethodModelEx action = (TemplateMethodModelEx) wrappedBean.get(Java8DefaultMethodsBean.DEFAULT_METHOD_ACTION);
assertNotNull(action);
assertEquals(Java8DefaultMethodsBean.DEFAULT_METHOD_ACTION_RETURN_VALUE, ((TemplateScalarModel) action.exec(Collections.emptyList())).getAsString());
}
{
TemplateMethodModelEx action = (TemplateMethodModelEx) wrappedBean.get(Java8DefaultMethodsBean.OVERRIDDEN_DEFAULT_METHOD_ACTION);
assertNotNull(action);
assertEquals(Java8DefaultMethodsBean.OVERRIDDEN_DEFAULT_METHOD_ACTION_RETURN_VALUE, ((TemplateScalarModel) action.exec(Collections.emptyList())).getAsString());
}
}
use of freemarker.template.TemplateMethodModelEx in project freemarker by apache.
the class Java8BeansWrapperTest method testDefaultMethodNotRecognized.
@Test
public void testDefaultMethodNotRecognized() throws TemplateModelException {
BeansWrapperBuilder owb = new BeansWrapperBuilder(Configuration.VERSION_2_3_0);
// owb.setTreatDefaultMethodsAsBeanMembers(false);
BeansWrapper ow = owb.build();
TemplateHashModel wrappedBean = (TemplateHashModel) ow.wrap(new Java8DefaultMethodsBean());
{
TemplateScalarModel prop = (TemplateScalarModel) wrappedBean.get(Java8DefaultMethodsBean.NORMAL_PROP);
assertNotNull(prop);
assertEquals(Java8DefaultMethodsBean.NORMAL_PROP_VALUE, prop.getAsString());
}
{
// This is overridden in the subclass, so it's visible even without default method support:
TemplateScalarModel prop = (TemplateScalarModel) wrappedBean.get(Java8DefaultMethodsBean.DEFAULT_METHOD_PROP_2);
assertNotNull(prop);
assertEquals(Java8DefaultMethodsBean.PROP_2_OVERRIDE_VALUE, prop.getAsString());
}
assertNull(wrappedBean.get(Java8DefaultMethodsBeanBase.DEFAULT_METHOD_PROP));
assertNull(wrappedBean.get(Java8DefaultMethodsBeanBase.DEFAULT_METHOD_INDEXED_PROP));
{
// We don't see the default method indexed reader, but see the plain reader method in the subclass.
TemplateNumberModel prop = (TemplateNumberModel) wrappedBean.get(Java8DefaultMethodsBean.DEFAULT_METHOD_NOT_AN_INDEXED_PROP);
assertNotNull(prop);
assertEquals(Java8DefaultMethodsBean.NOT_AN_INDEXED_PROP_VALUE, prop.getAsNumber());
}
{
// We don't see the default method non-indexed reader that would spoil the indexed reader in the subclass.
TemplateSequenceModel prop = (TemplateSequenceModel) wrappedBean.get(Java8DefaultMethodsBean.DEFAULT_METHOD_NOT_AN_INDEXED_PROP_2);
assertNotNull(prop);
assertEquals(Java8DefaultMethodsBean.NOT_AN_INDEXED_PROP_2_VALUE, ((TemplateScalarModel) prop.get(0)).getAsString());
}
{
// We don't see the default method non-indexed reader that would spoil the indexed reader in the subclass.
TemplateSequenceModel prop = (TemplateSequenceModel) wrappedBean.get(Java8DefaultMethodsBean.DEFAULT_METHOD_NOT_AN_INDEXED_PROP_3);
assertNotNull(prop);
assertEquals(Java8DefaultMethodsBean.NOT_AN_INDEXED_PROP_3_VALUE, ((TemplateNumberModel) prop.get(0)).getAsNumber());
}
{
// We don't see the default method indexed reader, but see the plain array reader in the subclass.
TemplateSequenceModel prop = (TemplateSequenceModel) wrappedBean.get(Java8DefaultMethodsBean.DEFAULT_METHOD_INDEXED_PROP_2);
assertNotNull(prop);
assertEquals(Java8DefaultMethodsBean.ARRAY_PROP_2_VALUE_0, ((TemplateScalarModel) prop.get(0)).getAsString());
}
{
// Only present in the subclass.
TemplateSequenceModel prop = (TemplateSequenceModel) wrappedBean.get(Java8DefaultMethodsBean.INDEXED_PROP_4);
assertNotNull(prop);
assertEquals(Java8DefaultMethodsBean.INDEXED_PROP_4_VALUE, ((TemplateScalarModel) prop.get(0)).getAsString());
}
{
// We don't see the default method non-indexed reader
TemplateSequenceModel prop = (TemplateSequenceModel) wrappedBean.get(Java8DefaultMethodsBean.DEFAULT_METHOD_INDEXED_PROP_3);
assertNotNull(prop);
assertEquals(Java8DefaultMethodsBean.INDEXED_PROP_3_VALUE, ((TemplateScalarModel) prop.get(0)).getAsString());
}
{
TemplateMethodModelEx action = (TemplateMethodModelEx) wrappedBean.get(Java8DefaultMethodsBean.NORMAL_ACTION);
assertNotNull(action);
assertEquals(Java8DefaultMethodsBean.NORMAL_ACTION_RETURN_VALUE, ((TemplateScalarModel) action.exec(Collections.emptyList())).getAsString());
}
assertNull(wrappedBean.get(Java8DefaultMethodsBeanBase.DEFAULT_METHOD_ACTION));
{
TemplateMethodModelEx action = (TemplateMethodModelEx) wrappedBean.get(Java8DefaultMethodsBean.OVERRIDDEN_DEFAULT_METHOD_ACTION);
assertNotNull(action);
assertEquals(Java8DefaultMethodsBean.OVERRIDDEN_DEFAULT_METHOD_ACTION_RETURN_VALUE, ((TemplateScalarModel) action.exec(Collections.emptyList())).getAsString());
}
}
Aggregations