Search in sources :

Example 1 with TemplateDirectiveModel

use of freemarker.template.TemplateDirectiveModel 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;
}
Also used : TemplateModelException(freemarker.template.TemplateModelException) TemplateModel(freemarker.template.TemplateModel) MalformedTemplateNameException(freemarker.template.MalformedTemplateNameException) Template(freemarker.template.Template) TemplateMethodModelEx(freemarker.template.TemplateMethodModelEx) List(java.util.List) KeyValuePairIterator(freemarker.template.TemplateHashModelEx2.KeyValuePairIterator) KeyValuePair(freemarker.template.TemplateHashModelEx2.KeyValuePair) TemplateException(freemarker.template.TemplateException) IOException(java.io.IOException) TemplateDirectiveBody(freemarker.template.TemplateDirectiveBody) TemplateHashModelEx(freemarker.template.TemplateHashModelEx) SimpleHash(freemarker.template.SimpleHash) TemplateScalarModel(freemarker.template.TemplateScalarModel) Map(java.util.Map) TemplateDirectiveModel(freemarker.template.TemplateDirectiveModel)

Example 2 with TemplateDirectiveModel

use of freemarker.template.TemplateDirectiveModel in project freemarker by apache.

the class NumberFormatTest method testStringBIDoesSnapshot.

/**
 * ?string formats lazily (at least in 2.3.x), so it must make a snapshot of the format inputs when it's called.
 */
@Test
public void testStringBIDoesSnapshot() throws Exception {
    // TemplateNumberModel-s shouldn't change, but we have to keep BC when that still happens.
    final MutableTemplateNumberModel nm = new MutableTemplateNumberModel();
    nm.setNumber(123);
    addToDataModel("n", nm);
    addToDataModel("incN", new TemplateDirectiveModel() {

        public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body) throws TemplateException, IOException {
            nm.setNumber(nm.getAsNumber().intValue() + 1);
        }
    });
    assertOutput("<#assign s1 = n?string>" + "<#setting numberFormat='@loc'>" + "<#assign s2 = n?string>" + "<#setting numberFormat='@hex'>" + "<#assign s3 = n?string>" + "${s1} ${s2} ${s3}", "123 123_en_US 7b");
    assertOutput("<#assign s1 = n?string>" + "<@incN />" + "<#assign s2 = n?string>" + "${s1} ${s2}", "123 124");
}
Also used : TemplateException(freemarker.template.TemplateException) TemplateModel(freemarker.template.TemplateModel) IOException(java.io.IOException) ImmutableMap(com.google.common.collect.ImmutableMap) Map(java.util.Map) TemplateDirectiveModel(freemarker.template.TemplateDirectiveModel) TemplateDirectiveBody(freemarker.template.TemplateDirectiveBody) Test(org.junit.Test) TemplateTest(freemarker.test.TemplateTest)

Example 3 with TemplateDirectiveModel

use of freemarker.template.TemplateDirectiveModel in project freemarker by apache.

the class UnifiedCall method accept.

@Override
TemplateElement[] accept(Environment env) throws TemplateException, IOException {
    TemplateModel tm = nameExp.eval(env);
    // shortcut here.
    if (tm == Macro.DO_NOTHING_MACRO)
        return null;
    if (tm instanceof Macro) {
        Macro macro = (Macro) tm;
        if (macro.isFunction() && !legacySyntax) {
            throw new _MiscTemplateException(env, "Routine ", new _DelayedJQuote(macro.getName()), " is a function, not a directive. " + "Functions can only be called from expressions, like in ${f()}, ${x + f()} or ", "<@someDirective someParam=f() />", ".");
        }
        env.invoke(macro, namedArgs, positionalArgs, bodyParameterNames, this);
    } else {
        boolean isDirectiveModel = tm instanceof TemplateDirectiveModel;
        if (isDirectiveModel || tm instanceof TemplateTransformModel) {
            Map args;
            if (namedArgs != null && !namedArgs.isEmpty()) {
                args = new HashMap();
                for (Iterator it = namedArgs.entrySet().iterator(); it.hasNext(); ) {
                    Map.Entry entry = (Map.Entry) it.next();
                    String key = (String) entry.getKey();
                    Expression valueExp = (Expression) entry.getValue();
                    TemplateModel value = valueExp.eval(env);
                    args.put(key, value);
                }
            } else {
                args = EmptyMap.instance;
            }
            if (isDirectiveModel) {
                env.visit(getChildBuffer(), (TemplateDirectiveModel) tm, args, bodyParameterNames);
            } else {
                env.visitAndTransform(getChildBuffer(), (TemplateTransformModel) tm, args);
            }
        } else if (tm == null) {
            throw InvalidReferenceException.getInstance(nameExp, env);
        } else {
            throw new NonUserDefinedDirectiveLikeException(nameExp, tm, env);
        }
    }
    return null;
}
Also used : HashMap(java.util.HashMap) TemplateModel(freemarker.template.TemplateModel) Iterator(java.util.Iterator) TemplateTransformModel(freemarker.template.TemplateTransformModel) HashMap(java.util.HashMap) EmptyMap(freemarker.template.EmptyMap) Map(java.util.Map) TemplateDirectiveModel(freemarker.template.TemplateDirectiveModel)

Aggregations

TemplateDirectiveModel (freemarker.template.TemplateDirectiveModel)3 TemplateModel (freemarker.template.TemplateModel)3 Map (java.util.Map)3 TemplateDirectiveBody (freemarker.template.TemplateDirectiveBody)2 TemplateException (freemarker.template.TemplateException)2 IOException (java.io.IOException)2 ImmutableMap (com.google.common.collect.ImmutableMap)1 EmptyMap (freemarker.template.EmptyMap)1 MalformedTemplateNameException (freemarker.template.MalformedTemplateNameException)1 SimpleHash (freemarker.template.SimpleHash)1 Template (freemarker.template.Template)1 TemplateHashModelEx (freemarker.template.TemplateHashModelEx)1 KeyValuePair (freemarker.template.TemplateHashModelEx2.KeyValuePair)1 KeyValuePairIterator (freemarker.template.TemplateHashModelEx2.KeyValuePairIterator)1 TemplateMethodModelEx (freemarker.template.TemplateMethodModelEx)1 TemplateModelException (freemarker.template.TemplateModelException)1 TemplateScalarModel (freemarker.template.TemplateScalarModel)1 TemplateTransformModel (freemarker.template.TemplateTransformModel)1 TemplateTest (freemarker.test.TemplateTest)1 HashMap (java.util.HashMap)1