Search in sources :

Example 1 with freemarker.core._DelayedFTLTypeDescription

use of freemarker.core._DelayedFTLTypeDescription in project freemarker by apache.

the class BeanModel method get.

/**
 * Uses Beans introspection to locate a property or method with name
 * matching the key name. If a method or property is found, it's wrapped
 * into {@link freemarker.template.TemplateMethodModelEx} (for a method or
 * indexed property), or evaluated on-the-fly and the return value wrapped
 * into appropriate model (for a non-indexed property) Models for various
 * properties and methods are cached on a per-class basis, so the costly
 * introspection is performed only once per property or method of a class.
 * (Side-note: this also implies that any class whose method has been called
 * will be strongly referred to by the framework and will not become
 * unloadable until this class has been unloaded first. Normally this is not
 * an issue, but can be in a rare scenario where you create many classes on-
 * the-fly. Also, as the cache grows with new classes and methods introduced
 * to the framework, it may appear as if it were leaking memory. The
 * framework does, however detect class reloads (if you happen to be in an
 * environment that does this kind of things--servlet containers do it when
 * they reload a web application) and flushes the cache. If no method or
 * property matching the key is found, the framework will try to invoke
 * methods with signature
 * <tt>non-void-return-type get(java.lang.String)</tt>,
 * then <tt>non-void-return-type get(java.lang.Object)</tt>, or
 * alternatively (if the wrapped object is a resource bundle)
 * <tt>Object getObject(java.lang.String)</tt>.
 * @throws TemplateModelException if there was no property nor method nor
 * a generic <tt>get</tt> method to invoke.
 */
public TemplateModel get(String key) throws TemplateModelException {
    Class<?> clazz = object.getClass();
    Map<Object, Object> classInfo = wrapper.getClassIntrospector().get(clazz);
    TemplateModel retval = null;
    try {
        if (wrapper.isMethodsShadowItems()) {
            Object fd = classInfo.get(key);
            if (fd != null) {
                retval = invokeThroughDescriptor(fd, classInfo);
            } else {
                retval = invokeGenericGet(classInfo, clazz, key);
            }
        } else {
            TemplateModel model = invokeGenericGet(classInfo, clazz, key);
            final TemplateModel nullModel = wrapper.wrap(null);
            if (model != nullModel && model != UNKNOWN) {
                return model;
            }
            Object fd = classInfo.get(key);
            if (fd != null) {
                retval = invokeThroughDescriptor(fd, classInfo);
                if (retval == UNKNOWN && model == nullModel) {
                    // This is the (somewhat subtle) case where the generic get() returns null
                    // and we have no bean info, so we respect the fact that
                    // the generic get() returns null and return null. (JR)
                    retval = nullModel;
                }
            }
        }
        if (retval == UNKNOWN) {
            if (wrapper.isStrict()) {
                throw new InvalidPropertyException("No such bean property: " + key);
            } else if (LOG.isDebugEnabled()) {
                logNoSuchKey(key, classInfo);
            }
            retval = wrapper.wrap(null);
        }
        return retval;
    } catch (TemplateModelException e) {
        throw e;
    } catch (Exception e) {
        throw new _TemplateModelException(e, "An error has occurred when reading existing sub-variable ", new _DelayedJQuote(key), "; see cause exception! The type of the containing value was: ", new _DelayedFTLTypeDescription(this));
    }
}
Also used : TemplateModelException(freemarker.template.TemplateModelException) freemarker.core._TemplateModelException(freemarker.core._TemplateModelException) freemarker.core._TemplateModelException(freemarker.core._TemplateModelException) freemarker.core._DelayedJQuote(freemarker.core._DelayedJQuote) freemarker.core._DelayedFTLTypeDescription(freemarker.core._DelayedFTLTypeDescription) AdapterTemplateModel(freemarker.template.AdapterTemplateModel) WrapperTemplateModel(freemarker.ext.util.WrapperTemplateModel) TemplateModel(freemarker.template.TemplateModel) TemplateModelException(freemarker.template.TemplateModelException) freemarker.core._TemplateModelException(freemarker.core._TemplateModelException) InvocationTargetException(java.lang.reflect.InvocationTargetException)

Example 2 with freemarker.core._DelayedFTLTypeDescription

use of freemarker.core._DelayedFTLTypeDescription in project freemarker by apache.

the class BeansWrapper method unwrapSequenceToArray.

/**
 * @param tryOnly
 *            If {@code true}, if the conversion of an item to the component type isn't possible, the method returns
 *            {@link ObjectWrapperAndUnwrapper#CANT_UNWRAP_TO_TARGET_CLASS} instead of throwing a
 *            {@link TemplateModelException}.
 */
Object unwrapSequenceToArray(TemplateSequenceModel seq, Class<?> arrayClass, boolean tryOnly, Map<Object, Object> recursionStops) throws TemplateModelException {
    if (recursionStops != null) {
        Object retval = recursionStops.get(seq);
        if (retval != null) {
            return retval;
        }
    } else {
        recursionStops = new IdentityHashMap<Object, Object>();
    }
    Class<?> componentType = arrayClass.getComponentType();
    final int size = seq.size();
    Object array = Array.newInstance(componentType, size);
    recursionStops.put(seq, array);
    try {
        for (int i = 0; i < size; i++) {
            final TemplateModel seqItem = seq.get(i);
            Object val = tryUnwrapTo(seqItem, componentType, 0, recursionStops);
            if (val == ObjectWrapperAndUnwrapper.CANT_UNWRAP_TO_TARGET_CLASS) {
                if (tryOnly) {
                    return ObjectWrapperAndUnwrapper.CANT_UNWRAP_TO_TARGET_CLASS;
                } else {
                    throw new _TemplateModelException("Failed to convert ", new _DelayedFTLTypeDescription(seq), " object to ", new _DelayedShortClassName(array.getClass()), ": Problematic sequence item at index ", Integer.valueOf(i), " with value type: ", new _DelayedFTLTypeDescription(seqItem));
                }
            }
            Array.set(array, i, val);
        }
    } finally {
        recursionStops.remove(seq);
    }
    return array;
}
Also used : freemarker.core._TemplateModelException(freemarker.core._TemplateModelException) freemarker.core._DelayedShortClassName(freemarker.core._DelayedShortClassName) AccessibleObject(java.lang.reflect.AccessibleObject) freemarker.core._DelayedFTLTypeDescription(freemarker.core._DelayedFTLTypeDescription) WrapperTemplateModel(freemarker.ext.util.WrapperTemplateModel) AdapterTemplateModel(freemarker.template.AdapterTemplateModel) TemplateModel(freemarker.template.TemplateModel)

Example 3 with freemarker.core._DelayedFTLTypeDescription

use of freemarker.core._DelayedFTLTypeDescription in project freemarker by apache.

the class IncludePage method execute.

public void execute(final Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body) throws TemplateException, IOException {
    // Determine the path
    final TemplateModel path = (TemplateModel) params.get("path");
    if (path == null) {
        throw new _MiscTemplateException(env, "Missing required parameter \"path\"");
    }
    if (!(path instanceof TemplateScalarModel)) {
        throw new _MiscTemplateException(env, "Expected a scalar model. \"path\" is instead ", new _DelayedFTLTypeDescription(path));
    }
    final String strPath = ((TemplateScalarModel) path).getAsString();
    if (strPath == null) {
        throw new _MiscTemplateException(env, "String value of \"path\" parameter is null");
    }
    // See whether we need to use a custom response (if we're inside a TTM
    // or TDM or macro nested body, we'll need to as then the current
    // FM environment writer is not identical to HTTP servlet response
    // writer.
    final Writer envOut = env.getOut();
    final HttpServletResponse wrappedResponse;
    if (envOut == response.getWriter()) {
        // Don't bother wrapping if environment's writer is same as
        // response writer
        wrappedResponse = response;
    } else {
        final PrintWriter printWriter = (envOut instanceof PrintWriter) ? (PrintWriter) envOut : new PrintWriter(envOut);
        // Otherwise, create a response wrapper that will pass the
        // env writer, potentially first wrapping it in a print
        // writer when it ain't one already.
        wrappedResponse = new HttpServletResponseWrapper(response) {

            @Override
            public PrintWriter getWriter() {
                return printWriter;
            }
        };
    }
    // Determine inherit_params value
    final boolean inheritParams;
    final TemplateModel inheritParamsModel = (TemplateModel) params.get("inherit_params");
    if (inheritParamsModel == null) {
        // defaults to true when not specified
        inheritParams = true;
    } else {
        if (!(inheritParamsModel instanceof TemplateBooleanModel)) {
            throw new _MiscTemplateException(env, "\"inherit_params\" should be a boolean but it's a(n) ", inheritParamsModel.getClass().getName(), " instead");
        }
        inheritParams = ((TemplateBooleanModel) inheritParamsModel).getAsBoolean();
    }
    // Get explicit params, if any
    final TemplateModel paramsModel = (TemplateModel) params.get("params");
    // Determine whether we need to wrap the request
    final HttpServletRequest wrappedRequest;
    if (paramsModel == null && inheritParams) {
        // Inherit original request params & no params explicitly
        // specified, so use the original request
        wrappedRequest = request;
    } else {
        // In any other case, use a custom request wrapper
        final Map paramsMap;
        if (paramsModel != null) {
            // Convert params to a Map
            final Object unwrapped = DeepUnwrap.unwrap(paramsModel);
            if (!(unwrapped instanceof Map)) {
                throw new _MiscTemplateException(env, "Expected \"params\" to unwrap into a java.util.Map. It unwrapped into ", unwrapped.getClass().getName(), " instead.");
            }
            paramsMap = (Map) unwrapped;
        } else {
            paramsMap = Collections.EMPTY_MAP;
        }
        wrappedRequest = new CustomParamsRequest(request, paramsMap, inheritParams);
    }
    // Finally, do the include
    try {
        request.getRequestDispatcher(strPath).include(wrappedRequest, wrappedResponse);
    } catch (ServletException e) {
        throw new _MiscTemplateException(e, env);
    }
}
Also used : freemarker.core._MiscTemplateException(freemarker.core._MiscTemplateException) HttpServletResponseWrapper(javax.servlet.http.HttpServletResponseWrapper) HttpServletResponse(javax.servlet.http.HttpServletResponse) freemarker.core._DelayedFTLTypeDescription(freemarker.core._DelayedFTLTypeDescription) TemplateModel(freemarker.template.TemplateModel) HttpServletRequest(javax.servlet.http.HttpServletRequest) ServletException(javax.servlet.ServletException) TemplateScalarModel(freemarker.template.TemplateScalarModel) HashMap(java.util.HashMap) Map(java.util.Map) PrintWriter(java.io.PrintWriter) Writer(java.io.Writer) TemplateBooleanModel(freemarker.template.TemplateBooleanModel) PrintWriter(java.io.PrintWriter)

Aggregations

freemarker.core._DelayedFTLTypeDescription (freemarker.core._DelayedFTLTypeDescription)3 TemplateModel (freemarker.template.TemplateModel)3 freemarker.core._TemplateModelException (freemarker.core._TemplateModelException)2 WrapperTemplateModel (freemarker.ext.util.WrapperTemplateModel)2 AdapterTemplateModel (freemarker.template.AdapterTemplateModel)2 freemarker.core._DelayedJQuote (freemarker.core._DelayedJQuote)1 freemarker.core._DelayedShortClassName (freemarker.core._DelayedShortClassName)1 freemarker.core._MiscTemplateException (freemarker.core._MiscTemplateException)1 TemplateBooleanModel (freemarker.template.TemplateBooleanModel)1 TemplateModelException (freemarker.template.TemplateModelException)1 TemplateScalarModel (freemarker.template.TemplateScalarModel)1 PrintWriter (java.io.PrintWriter)1 Writer (java.io.Writer)1 AccessibleObject (java.lang.reflect.AccessibleObject)1 InvocationTargetException (java.lang.reflect.InvocationTargetException)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1 ServletException (javax.servlet.ServletException)1 HttpServletRequest (javax.servlet.http.HttpServletRequest)1 HttpServletResponse (javax.servlet.http.HttpServletResponse)1