Search in sources :

Example 26 with TemplateScalarModel

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

the class ErrorMessagesTest method markupOutputParameter.

@Test
public void markupOutputParameter() throws Exception {
    TemplateHTMLOutputModel html = HTMLOutputFormat.INSTANCE.fromMarkup("<p>a");
    for (Version ici : new Version[] { Configuration.VERSION_2_3_0, Configuration.VERSION_2_3_24 }) {
        BeansWrapper bw = new BeansWrapperBuilder(ici).build();
        TemplateHashModel thm = (TemplateHashModel) bw.wrap(new TestBean());
        {
            TemplateMethodModelEx m = (TemplateMethodModelEx) thm.get("m1");
            try {
                m.exec(Collections.singletonList(html));
                fail();
            } catch (TemplateModelException e) {
                assertThat(e.getMessage(), allOf(containsString("String"), containsString("convert"), containsString("markup_output"), containsString("Tip:"), containsString("?markup_string")));
            }
        }
        {
            TemplateMethodModelEx m = (TemplateMethodModelEx) thm.get("m2");
            try {
                m.exec(Collections.singletonList(html));
                fail();
            } catch (TemplateModelException e) {
                assertThat(e.getMessage(), allOf(containsString("Date"), containsString("convert"), containsString("markup_output"), not(containsString("?markup_string"))));
            }
        }
        for (String methodName : new String[] { "mOverloaded", "mOverloaded3" }) {
            TemplateMethodModelEx m = (TemplateMethodModelEx) thm.get(methodName);
            try {
                m.exec(Collections.singletonList(html));
                fail();
            } catch (TemplateModelException e) {
                assertThat(e.getMessage(), allOf(containsString("No compatible overloaded"), containsString("String"), containsString("markup_output"), containsString("Tip:"), containsString("?markup_string")));
            }
        }
        {
            TemplateMethodModelEx m = (TemplateMethodModelEx) thm.get("mOverloaded2");
            try {
                m.exec(Collections.singletonList(html));
                fail();
            } catch (TemplateModelException e) {
                assertThat(e.getMessage(), allOf(containsString("No compatible overloaded"), containsString("Integer"), containsString("markup_output"), not(containsString("?markup_string"))));
            }
        }
        {
            TemplateMethodModelEx m = (TemplateMethodModelEx) thm.get("mOverloaded4");
            Object r = m.exec(Collections.singletonList(html));
            if (r instanceof TemplateScalarModel) {
                r = ((TemplateScalarModel) r).getAsString();
            }
            assertEquals("<p>a", r);
        }
    }
}
Also used : TemplateModelException(freemarker.template.TemplateModelException) TemplateHashModel(freemarker.template.TemplateHashModel) Version(freemarker.template.Version) TemplateMethodModelEx(freemarker.template.TemplateMethodModelEx) TemplateScalarModel(freemarker.template.TemplateScalarModel) TemplateHTMLOutputModel(freemarker.core.TemplateHTMLOutputModel) Test(org.junit.Test)

Example 27 with TemplateScalarModel

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

the class VisitNode method accept.

@Override
TemplateElement[] accept(Environment env) throws IOException, TemplateException {
    TemplateModel node = targetNode.eval(env);
    if (!(node instanceof TemplateNodeModel)) {
        throw new NonNodeException(targetNode, node, env);
    }
    TemplateModel nss = namespaces == null ? null : namespaces.eval(env);
    if (namespaces instanceof StringLiteral) {
        nss = env.importLib(((TemplateScalarModel) nss).getAsString(), null);
    } else if (namespaces instanceof ListLiteral) {
        nss = ((ListLiteral) namespaces).evaluateStringsToNamespaces(env);
    }
    if (nss != null) {
        if (nss instanceof Environment.Namespace) {
            SimpleSequence ss = new SimpleSequence(1);
            ss.add(nss);
            nss = ss;
        } else if (!(nss instanceof TemplateSequenceModel)) {
            if (namespaces != null) {
                throw new NonSequenceException(namespaces, nss, env);
            } else {
                // Should not occur
                throw new _MiscTemplateException(env, "Expecting a sequence of namespaces after \"using\"");
            }
        }
    }
    env.invokeNodeHandlerFor((TemplateNodeModel) node, (TemplateSequenceModel) nss);
    return null;
}
Also used : TemplateSequenceModel(freemarker.template.TemplateSequenceModel) TemplateNodeModel(freemarker.template.TemplateNodeModel) TemplateScalarModel(freemarker.template.TemplateScalarModel) TemplateModel(freemarker.template.TemplateModel) SimpleSequence(freemarker.template.SimpleSequence)

Example 28 with TemplateScalarModel

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

the class RecurseNode method accept.

@Override
TemplateElement[] accept(Environment env) throws IOException, TemplateException {
    TemplateModel node = targetNode == null ? null : targetNode.eval(env);
    if (node != null && !(node instanceof TemplateNodeModel)) {
        throw new NonNodeException(targetNode, node, "node", env);
    }
    TemplateModel nss = namespaces == null ? null : namespaces.eval(env);
    if (namespaces instanceof StringLiteral) {
        nss = env.importLib(((TemplateScalarModel) nss).getAsString(), null);
    } else if (namespaces instanceof ListLiteral) {
        nss = ((ListLiteral) namespaces).evaluateStringsToNamespaces(env);
    }
    if (nss != null) {
        if (nss instanceof TemplateHashModel) {
            SimpleSequence ss = new SimpleSequence(1);
            ss.add(nss);
            nss = ss;
        } else if (!(nss instanceof TemplateSequenceModel)) {
            if (namespaces != null) {
                throw new NonSequenceException(namespaces, nss, env);
            } else {
                // Should not occur
                throw new _MiscTemplateException(env, "Expecting a sequence of namespaces after \"using\"");
            }
        }
    }
    env.recurse((TemplateNodeModel) node, (TemplateSequenceModel) nss);
    return null;
}
Also used : TemplateSequenceModel(freemarker.template.TemplateSequenceModel) TemplateHashModel(freemarker.template.TemplateHashModel) TemplateNodeModel(freemarker.template.TemplateNodeModel) TemplateScalarModel(freemarker.template.TemplateScalarModel) TemplateModel(freemarker.template.TemplateModel) SimpleSequence(freemarker.template.SimpleSequence)

Example 29 with TemplateScalarModel

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

the class BeanModel method values.

public TemplateCollectionModel values() throws TemplateModelException {
    List<Object> values = new ArrayList<Object>(size());
    TemplateModelIterator it = keys().iterator();
    while (it.hasNext()) {
        String key = ((TemplateScalarModel) it.next()).getAsString();
        values.add(get(key));
    }
    return new CollectionAndSequence(new SimpleSequence(values, wrapper));
}
Also used : TemplateModelIterator(freemarker.template.TemplateModelIterator) CollectionAndSequence(freemarker.core.CollectionAndSequence) ArrayList(java.util.ArrayList) TemplateScalarModel(freemarker.template.TemplateScalarModel) SimpleSequence(freemarker.template.SimpleSequence)

Example 30 with TemplateScalarModel

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

the class BeansWrapper method tryUnwrapTo.

/**
 * See {@link #tryUnwrapTo(TemplateModel, Class, int)}.
 */
private Object tryUnwrapTo(final TemplateModel model, Class<?> targetClass, final int typeFlags, final Map<Object, Object> recursionStops) throws TemplateModelException {
    if (model == null || model == nullModel) {
        return null;
    }
    final boolean is2321Bugfixed = is2321Bugfixed();
    if (is2321Bugfixed && targetClass.isPrimitive()) {
        targetClass = ClassUtil.primitiveClassToBoxingClass(targetClass);
    }
    // passed as an argument to TemplateMethodModelEx etc.
    if (model instanceof AdapterTemplateModel) {
        Object wrapped = ((AdapterTemplateModel) model).getAdaptedObject(targetClass);
        if (targetClass == Object.class || targetClass.isInstance(wrapped)) {
            return wrapped;
        }
        // Attempt numeric conversion:
        if (targetClass != Object.class && (wrapped instanceof Number && ClassUtil.isNumerical(targetClass))) {
            Number number = forceUnwrappedNumberToType((Number) wrapped, targetClass, is2321Bugfixed);
            if (number != null)
                return number;
        }
    }
    if (model instanceof WrapperTemplateModel) {
        Object wrapped = ((WrapperTemplateModel) model).getWrappedObject();
        if (targetClass == Object.class || targetClass.isInstance(wrapped)) {
            return wrapped;
        }
        // Attempt numeric conversion:
        if (targetClass != Object.class && (wrapped instanceof Number && ClassUtil.isNumerical(targetClass))) {
            Number number = forceUnwrappedNumberToType((Number) wrapped, targetClass, is2321Bugfixed);
            if (number != null) {
                return number;
            }
        }
    }
    // know what is expected as the return type.
    if (targetClass != Object.class) {
        // [2.4][IcI]: Should also check for CharSequence at the end
        if (String.class == targetClass) {
            if (model instanceof TemplateScalarModel) {
                return ((TemplateScalarModel) model).getAsString();
            }
            // String is final, so no other conversion will work
            return ObjectWrapperAndUnwrapper.CANT_UNWRAP_TO_TARGET_CLASS;
        }
        // Primitive numeric types & Number.class and its subclasses
        if (ClassUtil.isNumerical(targetClass)) {
            if (model instanceof TemplateNumberModel) {
                Number number = forceUnwrappedNumberToType(((TemplateNumberModel) model).getAsNumber(), targetClass, is2321Bugfixed);
                if (number != null) {
                    return number;
                }
            }
        }
        if (boolean.class == targetClass || Boolean.class == targetClass) {
            if (model instanceof TemplateBooleanModel) {
                return Boolean.valueOf(((TemplateBooleanModel) model).getAsBoolean());
            }
            // Boolean is final, no other conversion will work
            return ObjectWrapperAndUnwrapper.CANT_UNWRAP_TO_TARGET_CLASS;
        }
        if (Map.class == targetClass) {
            if (model instanceof TemplateHashModel) {
                return new HashAdapter((TemplateHashModel) model, this);
            }
        }
        if (List.class == targetClass) {
            if (model instanceof TemplateSequenceModel) {
                return new SequenceAdapter((TemplateSequenceModel) model, this);
            }
        }
        if (Set.class == targetClass) {
            if (model instanceof TemplateCollectionModel) {
                return new SetAdapter((TemplateCollectionModel) model, this);
            }
        }
        if (Collection.class == targetClass || Iterable.class == targetClass) {
            if (model instanceof TemplateCollectionModel) {
                return new CollectionAdapter((TemplateCollectionModel) model, this);
            }
            if (model instanceof TemplateSequenceModel) {
                return new SequenceAdapter((TemplateSequenceModel) model, this);
            }
        }
        // TemplateSequenceModels can be converted to arrays
        if (targetClass.isArray()) {
            if (model instanceof TemplateSequenceModel) {
                return unwrapSequenceToArray((TemplateSequenceModel) model, targetClass, true, recursionStops);
            }
            // array classes are final, no other conversion will work
            return ObjectWrapperAndUnwrapper.CANT_UNWRAP_TO_TARGET_CLASS;
        }
        // Allow one-char strings to be coerced to characters
        if (char.class == targetClass || targetClass == Character.class) {
            if (model instanceof TemplateScalarModel) {
                String s = ((TemplateScalarModel) model).getAsString();
                if (s.length() == 1) {
                    return Character.valueOf(s.charAt(0));
                }
            }
            // Character is final, no other conversion will work
            return ObjectWrapperAndUnwrapper.CANT_UNWRAP_TO_TARGET_CLASS;
        }
        if (Date.class.isAssignableFrom(targetClass) && model instanceof TemplateDateModel) {
            Date date = ((TemplateDateModel) model).getAsDate();
            if (targetClass.isInstance(date)) {
                return date;
            }
        }
    }
    // End: if (targetClass != Object.class)
    // Since the targetClass was of no help initially, now we use
    // a quite arbitrary order in which we walk through the TemplateModel subinterfaces, and unwrapp them to
    // their "natural" Java correspondent. We still try exclude unwrappings that won't fit the target parameter
    // type(s). This is mostly important because of multi-typed FTL values that could be unwrapped on multiple ways.
    // Iteration's Type Flags. Should be always 0 for non-overloaded and when !is2321Bugfixed.
    int itf = typeFlags;
    // returned, once more with itf == 0. Otherwise we execute this once with itf == 0.
    do {
        if ((itf == 0 || (itf & TypeFlags.ACCEPTS_NUMBER) != 0) && model instanceof TemplateNumberModel) {
            Number number = ((TemplateNumberModel) model).getAsNumber();
            if (itf != 0 || targetClass.isInstance(number)) {
                return number;
            }
        }
        if ((itf == 0 || (itf & TypeFlags.ACCEPTS_DATE) != 0) && model instanceof TemplateDateModel) {
            Date date = ((TemplateDateModel) model).getAsDate();
            if (itf != 0 || targetClass.isInstance(date)) {
                return date;
            }
        }
        if ((itf == 0 || (itf & (TypeFlags.ACCEPTS_STRING | TypeFlags.CHARACTER)) != 0) && model instanceof TemplateScalarModel && (itf != 0 || targetClass.isAssignableFrom(String.class))) {
            String strVal = ((TemplateScalarModel) model).getAsString();
            if (itf == 0 || (itf & TypeFlags.CHARACTER) == 0) {
                return strVal;
            } else {
                // TypeFlags.CHAR == 1
                if (strVal.length() == 1) {
                    if ((itf & TypeFlags.ACCEPTS_STRING) != 0) {
                        return new CharacterOrString(strVal);
                    } else {
                        return Character.valueOf(strVal.charAt(0));
                    }
                } else if ((itf & TypeFlags.ACCEPTS_STRING) != 0) {
                    return strVal;
                }
            // It had to be unwrapped to Character, but the string length wasn't 1 => Fall through
            }
        }
        // Should be earlier than TemplateScalarModel, but we keep it here until FM 2.4 or such
        if ((itf == 0 || (itf & TypeFlags.ACCEPTS_BOOLEAN) != 0) && model instanceof TemplateBooleanModel && (itf != 0 || targetClass.isAssignableFrom(Boolean.class))) {
            return Boolean.valueOf(((TemplateBooleanModel) model).getAsBoolean());
        }
        if ((itf == 0 || (itf & TypeFlags.ACCEPTS_MAP) != 0) && model instanceof TemplateHashModel && (itf != 0 || targetClass.isAssignableFrom(HashAdapter.class))) {
            return new HashAdapter((TemplateHashModel) model, this);
        }
        if ((itf == 0 || (itf & TypeFlags.ACCEPTS_LIST) != 0) && model instanceof TemplateSequenceModel && (itf != 0 || targetClass.isAssignableFrom(SequenceAdapter.class))) {
            return new SequenceAdapter((TemplateSequenceModel) model, this);
        }
        if ((itf == 0 || (itf & TypeFlags.ACCEPTS_SET) != 0) && model instanceof TemplateCollectionModel && (itf != 0 || targetClass.isAssignableFrom(SetAdapter.class))) {
            return new SetAdapter((TemplateCollectionModel) model, this);
        }
        // enough to check if the TypeFlags.ACCEPTS_ARRAY bit is 1:
        if ((itf & TypeFlags.ACCEPTS_ARRAY) != 0 && model instanceof TemplateSequenceModel) {
            return new SequenceAdapter((TemplateSequenceModel) model, this);
        }
        if (itf == 0) {
            break;
        }
        // start 2nd iteration
        itf = 0;
    } while (true);
    // Note that this will be always true for Object.class targetClass.
    if (targetClass.isInstance(model)) {
        return model;
    }
    return ObjectWrapperAndUnwrapper.CANT_UNWRAP_TO_TARGET_CLASS;
}
Also used : TemplateSequenceModel(freemarker.template.TemplateSequenceModel) TemplateNumberModel(freemarker.template.TemplateNumberModel) TemplateDateModel(freemarker.template.TemplateDateModel) AdapterTemplateModel(freemarker.template.AdapterTemplateModel) Date(java.util.Date) TemplateHashModel(freemarker.template.TemplateHashModel) Collection(java.util.Collection) AccessibleObject(java.lang.reflect.AccessibleObject) TemplateScalarModel(freemarker.template.TemplateScalarModel) WrapperTemplateModel(freemarker.ext.util.WrapperTemplateModel) TemplateCollectionModel(freemarker.template.TemplateCollectionModel) TemplateBooleanModel(freemarker.template.TemplateBooleanModel)

Aggregations

TemplateScalarModel (freemarker.template.TemplateScalarModel)41 TemplateModel (freemarker.template.TemplateModel)18 TemplateModelException (freemarker.template.TemplateModelException)18 TemplateHashModel (freemarker.template.TemplateHashModel)9 TemplateSequenceModel (freemarker.template.TemplateSequenceModel)9 IOException (java.io.IOException)9 TemplateNumberModel (freemarker.template.TemplateNumberModel)8 Environment (freemarker.core.Environment)7 BeanModel (freemarker.ext.beans.BeanModel)7 TemplateMethodModelEx (freemarker.template.TemplateMethodModelEx)7 SimpleScalar (freemarker.template.SimpleScalar)6 Test (org.junit.Test)6 SimpleSequence (freemarker.template.SimpleSequence)5 Template (freemarker.template.Template)5 TemplateNodeModel (freemarker.template.TemplateNodeModel)5 Writer (java.io.Writer)5 Map (java.util.Map)5 HttpServletRequest (javax.servlet.http.HttpServletRequest)5 TemplateBooleanModel (freemarker.template.TemplateBooleanModel)4 TemplateException (freemarker.template.TemplateException)3