Search in sources :

Example 1 with TemplateCollectionModel

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

the class RhinoScriptableModel method values.

public TemplateCollectionModel values() throws TemplateModelException {
    Object[] ids = scriptable.getIds();
    Object[] values = new Object[ids.length];
    for (int i = 0; i < values.length; i++) {
        Object id = ids[i];
        if (id instanceof Number) {
            values[i] = ScriptableObject.getProperty(scriptable, ((Number) id).intValue());
        } else {
            values[i] = ScriptableObject.getProperty(scriptable, String.valueOf(id));
        }
    }
    return (TemplateCollectionModel) wrapper.wrap(values);
}
Also used : NativeJavaObject(org.mozilla.javascript.NativeJavaObject) ScriptableObject(org.mozilla.javascript.ScriptableObject) TemplateCollectionModel(freemarker.template.TemplateCollectionModel)

Example 2 with TemplateCollectionModel

use of freemarker.template.TemplateCollectionModel in project be5 by DevelopmentOnTheEdge.

the class FtlToYaml method ftlToHash.

public static LinkedHashMap<String, Object> ftlToHash(TemplateHashModelEx model) throws TemplateModelException {
    LinkedHashMap<String, Object> result = new LinkedHashMap<>();
    TemplateCollectionModel keys = model.keys();
    TemplateModelIterator iterator = keys.iterator();
    while (iterator.hasNext()) {
        TemplateModel next = iterator.next();
        if (!(next instanceof TemplateScalarModel)) {
            throw new TemplateModelException("Invalid key: " + next);
        }
        String key = ((TemplateScalarModel) next).getAsString();
        TemplateModel value = model.get(key);
        try {
            result.put(key, ftlToObject(value));
        } catch (TemplateModelException e) {
            throw new TemplateModelException(key + ": " + e.getMessage(), e);
        }
    }
    return result;
}
Also used : TemplateModelException(freemarker.template.TemplateModelException) TemplateModelIterator(freemarker.template.TemplateModelIterator) TemplateScalarModel(freemarker.template.TemplateScalarModel) TemplateModel(freemarker.template.TemplateModel) TemplateCollectionModel(freemarker.template.TemplateCollectionModel) LinkedHashMap(java.util.LinkedHashMap)

Example 3 with TemplateCollectionModel

use of freemarker.template.TemplateCollectionModel 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)

Example 4 with TemplateCollectionModel

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

the class RmiDebugModelImpl method getCollection.

public DebugModel[] getCollection() throws TemplateModelException, RemoteException {
    List list = new ArrayList();
    TemplateModelIterator i = ((TemplateCollectionModel) model).iterator();
    while (i.hasNext()) {
        list.add(getDebugModel(i.next()));
    }
    return (DebugModel[]) list.toArray(new DebugModel[list.size()]);
}
Also used : DebugModel(freemarker.debug.DebugModel) TemplateModelIterator(freemarker.template.TemplateModelIterator) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) TemplateCollectionModel(freemarker.template.TemplateCollectionModel)

Aggregations

TemplateCollectionModel (freemarker.template.TemplateCollectionModel)4 TemplateModelIterator (freemarker.template.TemplateModelIterator)2 TemplateScalarModel (freemarker.template.TemplateScalarModel)2 DebugModel (freemarker.debug.DebugModel)1 WrapperTemplateModel (freemarker.ext.util.WrapperTemplateModel)1 AdapterTemplateModel (freemarker.template.AdapterTemplateModel)1 TemplateBooleanModel (freemarker.template.TemplateBooleanModel)1 TemplateDateModel (freemarker.template.TemplateDateModel)1 TemplateHashModel (freemarker.template.TemplateHashModel)1 TemplateModel (freemarker.template.TemplateModel)1 TemplateModelException (freemarker.template.TemplateModelException)1 TemplateNumberModel (freemarker.template.TemplateNumberModel)1 TemplateSequenceModel (freemarker.template.TemplateSequenceModel)1 AccessibleObject (java.lang.reflect.AccessibleObject)1 ArrayList (java.util.ArrayList)1 Collection (java.util.Collection)1 Date (java.util.Date)1 LinkedHashMap (java.util.LinkedHashMap)1 List (java.util.List)1 NativeJavaObject (org.mozilla.javascript.NativeJavaObject)1