Search in sources :

Example 61 with TemplateModelException

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

the class NodeListModel method exec.

/**
 * Applies an XPath expression to the node list and returns the resulting node list.
 * In order for this method to work, your application must have access
 * <a href="http://www.jaxen.org">Jaxen</a> library classes. The
 * implementation does cache the parsed format of XPath expressions in a weak hash
 * map, keyed by the string representation of the XPath expression. As the string
 * object passed as the argument is usually kept in the parsed FreeMarker template,
 * this ensures that each XPath expression is parsed only once during the lifetime
 * of the FreeMarker template that contains it.
 * @param arguments the list of arguments. Must contain exactly one string that is
 * the XPath expression you wish to apply. The XPath expression can use any namespace
 * prefixes that were defined using the {@link #registerNamespace(String, String)}
 * method or the <code>nodelist._registerNamespace(prefix, uri)</code> expression in the
 * template.
 * @return a NodeListModel representing the nodes that are the result of application
 * of the XPath to the current node list.
 */
public Object exec(List arguments) throws TemplateModelException {
    if (arguments == null || arguments.size() != 1)
        throw new TemplateModelException("Exactly one argument required for execute() on NodeTemplate");
    String xpathString = (String) arguments.get(0);
    JDOMXPathEx xpath = null;
    try {
        synchronized (XPATH_CACHE) {
            xpath = (JDOMXPathEx) XPATH_CACHE.get(xpathString);
            if (xpath == null) {
                xpath = new JDOMXPathEx(xpathString);
                XPATH_CACHE.put(xpathString, xpath);
            }
        }
        return createNodeListModel(xpath.selectNodes(nodes, namespaces), namespaces);
    } catch (Exception e) {
        throw new TemplateModelException("Could not evaulate XPath expression " + xpathString, e);
    }
}
Also used : TemplateModelException(freemarker.template.TemplateModelException) JaxenException(org.jaxen.JaxenException) TemplateModelException(freemarker.template.TemplateModelException) IOException(java.io.IOException)

Example 62 with TemplateModelException

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

the class NodeListModel method get.

/**
 * Provides node list traversal as well as special functions: filtering by name,
 * filtering by node type, shallow-copying, and duplicate removal.
 * While not as powerful as the full XPath support built into the
 * {@link #exec(List)} method, it does not require the external Jaxen
 * library to be present at run time. Below are listed the recognized keys.
 * In key descriptions, "applicable to this-and-that node type" means that if
 * a key is applied to a node list that contains a node of non-applicable type
 * a TemplateMethodModel will be thrown. However, you can use <tt>_ftype</tt>
 * key to explicitly filter out undesired node types prior to applying the
 * restricted-applicability key. Also "current nodes" means nodes contained in this
 * set.
 * <ul>
 *    <li><tt>*</tt> or <tt>_children</tt>: all direct element children of current nodes (non-recursive). Applicable
 *  to element and document nodes.</li>
 *    <li><tt>@*</tt> or <tt>_attributes</tt>: all attributes of current nodes. Applicable to elements only.</li>
 *    <li><tt>_content</tt> the complete content of current nodes (non-recursive).
 *  Applicable to elements and documents.</li>
 *    <li><tt>_text</tt>: the text of current nodes, one string per node (non-recursive).
 *  Applicable to elements, attributes, comments, processing instructions (returns its data)
 *  and CDATA sections. The reserved XML characters ('&lt;' and '&amp;') are escaped.</li>
 *    <li><tt>_plaintext</tt>: same as <tt>_text</tt>, but does not escape any characters,
 *  and instead of returning a NodeList returns a SimpleScalar.</li>
 *    <li><tt>_name</tt>: the names of current nodes, one string per node (non-recursive).
 *  Applicable to elements and attributes (returns their local name),
 *  entities, processing instructions (returns its target), doctypes
 * (returns its public ID)</li>
 *    <li><tt>_qname</tt>: the qualified names of current nodes in <tt>[namespacePrefix:]localName</tt>
 * form, one string per node (non-recursive). Applicable to elements and attributes</li>
 *    <li><tt>_cname</tt>: the canonical names of current nodes (namespace URI + local name),
 * one string per node (non-recursive). Applicable to elements and attributes</li>
 *    <li><tt>_nsprefix</tt>: namespace prefixes of current nodes,
 * one string per node (non-recursive). Applicable to elements and attributes</li>
 *    <li><tt>_nsuri</tt>: namespace URIs of current nodes,
 * one string per node (non-recursive). Applicable to elements and attributes</li>
 *    <li><tt>_parent</tt>: parent elements of current nodes. Applicable to element, attribute, comment,
 *  entity, processing instruction.</li>
 *    <li><tt>_ancestor</tt>: all ancestors up to root element (recursive) of current nodes. Applicable
 *  to same node types as <tt>_parent</tt>.</li>
 *    <li><tt>_ancestorOrSelf</tt>: all ancestors of current nodes plus current nodes. Applicable
 *  to same node types as <tt>_parent</tt>.</li>
 *    <li><tt>_descendant</tt>: all recursive descendant element children of current nodes. Applicable to
 *  document and element nodes.
 *    <li><tt>_descendantOrSelf</tt>: all recursive descendant element children of current nodes
 *  plus current nodes. Applicable to document and element nodes.
 *    <li><tt>_document</tt>: all documents the current nodes belong to.
 *  Applicable to all nodes except text.
 *    <li><tt>_doctype</tt>: doctypes of the current nodes.
 *  Applicable to document nodes only.
 *    <li><tt>_fname</tt>: is a filter-by-name template method model. When called,
 *  it will yield a node list that contains only those current nodes whose name
 *  matches one of names passed as argument. Attribute names should NOT be prefixed with the
 *  at sign (@). Applicable on all node types, however has no effect on unnamed nodes.</li>
 *    <li><tt>_ftype</tt>: is a filter-by-type template method model. When called,
 *  it will yield a node list that contains only those current nodes whose type matches one
 *  of types passed as argument. You should pass a single string to this method
 *  containing the characters of all types to keep. Valid characters are:
 *  e (Element), a (Attribute), n (Entity), d (Document), t (DocType),
 *  c (Comment), p (ProcessingInstruction), x (text). If the string anywhere contains
 *  the exclamation mark (!), the filter's effect is inverted.</li>
 *    <li><tt>_type</tt>: Returns a one-character String SimpleScalar containing
 *    the typecode of the first node in the node list. Valid characters are:
 *  e (Element), a (Attribute), n (Entity), d (Document), t (DocType),
 *  c (Comment), p (ProcessingInstruction), x (text). If the type of the node
 *  is unknown, returns '?'. If the node list is empty, returns an empty string scalar.</li>
 *    <li><tt>_unique</tt>: a copy of the current nodes that keeps only the
 *  first occurrence of every node, eliminating duplicates. Duplicates can
 *  occur in the node list by applying uptree-traversals <tt>_parent</tt>,
 *  <tt>_ancestor</tt>, <tt>_ancestorOrSelf</tt>, and <tt>_document</tt>.
 *  I.e. <tt>foo._children._parent</tt> will return a node list that has
 *  duplicates of nodes in foo - each node will have the number of occurrences
 *  equal to the number of its children. In these cases, use
 *  <tt>foo._children._parent._unique</tt> to eliminate duplicates. Applicable
 *  to all node types.</li>
 *    <li><tt>_copy</tt>: a copy of the current node list. It is a shallow copy that
 *  shares the underlying node list with this node list, however it has a
 *  separate namespace registry, so it can be used to guarantee that subsequent
 *  changes to the set of registered namespaces does not affect the node lists
 *  that were used to create this node list. Applicable to all node types.</li>
 *    <li><tt>_registerNamespace(prefix, uri)</tt>: register a XML namespace
 *  with the specified prefix and URI for the current node list and all node
 *  lists that are derived from the current node list. After registering,
 *  you can use the <tt>nodelist["prefix:localname"]</tt> or
 *  <tt>nodelist["@prefix:localname"]</tt> syntaxes to reach elements and
 *  attributes whose names are namespace-scoped. Note that the namespace
 *  prefix need not match the actual prefix used by the XML document itself
 *  since namespaces are compared solely by their URI. You can also register
 *  namespaces from Java code using the
 *  {@link #registerNamespace(String, String)} method.
 * </li>
 *    <li><tt>@attributeName</tt>: named attributes of current nodes. Applicable to
 *  elements, doctypes and processing instructions. On doctypes it supports
 *  attributes <tt>publicId</tt>, <tt>systemId</tt> and <tt>elementName</tt>. On processing
 *  instructions, it supports attributes <tt>target</tt> and <tt>data</tt>, as
 *  well as any other attribute name specified in data as <tt>name="value"</tt> pair.
 *  The attribute nodes for doctype and processing instruction are synthetic, and
 *  as such have no parent. Note, however that <tt>@*</tt> does NOT operate on
 *  doctypes or processing instructions.</li>
 *    <li>any other key: element children of current nodes with name matching the key.
 *  This allows for convenience child traversal in <tt>book.chapter.title</tt> style syntax.
 *  Note that <tt>nodeset.childname</tt> is technically equivalent to
 *  <tt>nodeset._children._fname("childname")</tt>, but is both shorter to write
 *  and evaluates faster. Applicable to document and element nodes.</li>
 * </ul>
 * The order of nodes in the resulting set is the order of evaluation of the key
 * on each node in this set from left to right. Evaluation of the key on a single
 * node always yields the results in "natural" order (that of the document preorder
 * traversal), even for uptree traversals. As a consequence, if this node list's nodes
 * are listed in natural order, applying any of the keys will produce a node list that
 * is also naturally ordered. As a special case, all node lists that are directly or
 * indirectly generated from a single Document or Element node through repeated
 * invocations of this method will be naturally ordered.
 * @param key a key that identifies a required set of nodes
 * @return a new NodeListModel that represents the requested set of nodes.
 */
public TemplateModel get(String key) throws TemplateModelException {
    if (isEmpty())
        return EMPTY;
    if (key == null || key.length() == 0)
        throw new TemplateModelException("Invalid key [" + key + "]");
    NodeOperator op = null;
    NamedNodeOperator nop = null;
    String name = null;
    switch(key.charAt(0)) {
        case '@':
            {
                if (key.length() != 2 || key.charAt(1) != '*') {
                    // Generic attribute key
                    nop = NAMED_ATTRIBUTE_OP;
                    name = key.substring(1);
                } else
                    // It is @*
                    op = ALL_ATTRIBUTES_OP;
                break;
            }
        case '*':
            {
                if (key.length() == 1)
                    op = ALL_CHILDREN_OP;
                else
                    // Explicitly disallow any other identifier starting with asterisk
                    throw new TemplateModelException("Invalid key [" + key + "]");
                break;
            }
        case 'x':
        case '_':
            {
                op = (NodeOperator) OPERATIONS.get(key);
                if (op == null) {
                    // Some special operation?
                    Integer specop = (Integer) SPECIAL_OPERATIONS.get(key);
                    if (specop != null) {
                        switch(specop.intValue()) {
                            case SPECIAL_OPERATION_COPY:
                                {
                                    synchronized (namespaces) {
                                        return new NodeListModel(nodes, (Map) ((HashMap) namespaces).clone());
                                    }
                                }
                            case SPECIAL_OPERATION_UNIQUE:
                                return new NodeListModel(removeDuplicates(nodes), namespaces);
                            case SPECIAL_OPERATION_FILTER_NAME:
                                return new NameFilter();
                            case SPECIAL_OPERATION_FILTER_TYPE:
                                return new TypeFilter();
                            case SPECIAL_OPERATION_QUERY_TYPE:
                                return getType();
                            case SPECIAL_OPERATION_REGISTER_NAMESPACE:
                                return new RegisterNamespace();
                            case SPECIAL_OPERATION_PLAINTEXT:
                                return getPlainText();
                        }
                    }
                }
                break;
            }
    }
    if (op == null && nop == null) {
        nop = NAMED_CHILDREN_OP;
        name = key;
    }
    List list = null;
    if (op != null)
        list = evaluateElementOperation(op, nodes);
    else {
        String localName = name;
        Namespace namespace = Namespace.NO_NAMESPACE;
        int colon = name.indexOf(':');
        if (colon != -1) {
            localName = name.substring(colon + 1);
            String nsPrefix = name.substring(0, colon);
            synchronized (namespaces) {
                namespace = (Namespace) namespaces.get(nsPrefix);
            }
            if (namespace == null) {
                if (nsPrefix.equals("xml"))
                    namespace = Namespace.XML_NAMESPACE;
                else
                    throw new TemplateModelException("Unregistered namespace prefix '" + nsPrefix + "'");
            }
        }
        list = evaluateNamedElementOperation(nop, localName, namespace, nodes);
    }
    return createNodeListModel(list, namespaces);
}
Also used : TemplateModelException(freemarker.template.TemplateModelException) HashMap(java.util.HashMap) WeakHashMap(java.util.WeakHashMap) Namespace(org.jdom.Namespace) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) List(java.util.List)

Example 63 with TemplateModelException

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

the class FreemarkerServlet method createTaglibFactory.

/**
 * Called to create the {@link TaglibFactory} once per servlet context.
 * The default implementation configures it based on the servlet-init parameters and various other environmental
 * settings, so if you override this method, you should call super, then adjust the result.
 *
 * @since 2.3.22
 */
protected TaglibFactory createTaglibFactory(ObjectWrapper objectWrapper, ServletContext servletContext) throws TemplateModelException {
    TaglibFactory taglibFactory = new TaglibFactory(servletContext);
    taglibFactory.setObjectWrapper(objectWrapper);
    {
        List /*<MetaInfTldSource>*/
        mergedMetaInfTldSources = new ArrayList();
        if (metaInfTldSources != null) {
            mergedMetaInfTldSources.addAll(metaInfTldSources);
        }
        String sysPropVal = SecurityUtilities.getSystemProperty(SYSTEM_PROPERTY_META_INF_TLD_SOURCES, null);
        if (sysPropVal != null) {
            try {
                List metaInfTldSourcesSysProp = parseAsMetaInfTldLocations(sysPropVal);
                if (metaInfTldSourcesSysProp != null) {
                    mergedMetaInfTldSources.addAll(metaInfTldSourcesSysProp);
                }
            } catch (ParseException e) {
                throw new TemplateModelException("Failed to parse system property \"" + SYSTEM_PROPERTY_META_INF_TLD_SOURCES + "\"", e);
            }
        }
        List /*<Pattern>*/
        jettyTaglibJarPatterns = null;
        try {
            final String attrVal = (String) servletContext.getAttribute(ATTR_JETTY_CP_TAGLIB_JAR_PATTERNS);
            jettyTaglibJarPatterns = attrVal != null ? InitParamParser.parseCommaSeparatedPatterns(attrVal) : null;
        } catch (Exception e) {
            LOG.error("Failed to parse application context attribute \"" + ATTR_JETTY_CP_TAGLIB_JAR_PATTERNS + "\" - it will be ignored", e);
        }
        if (jettyTaglibJarPatterns != null) {
            for (Iterator /*<Pattern>*/
            it = jettyTaglibJarPatterns.iterator(); it.hasNext(); ) {
                Pattern pattern = (Pattern) it.next();
                mergedMetaInfTldSources.add(new ClasspathMetaInfTldSource(pattern));
            }
        }
        taglibFactory.setMetaInfTldSources(mergedMetaInfTldSources);
    }
    {
        List /*<String>*/
        mergedClassPathTlds = new ArrayList();
        if (classpathTlds != null) {
            mergedClassPathTlds.addAll(classpathTlds);
        }
        String sysPropVal = SecurityUtilities.getSystemProperty(SYSTEM_PROPERTY_CLASSPATH_TLDS, null);
        if (sysPropVal != null) {
            try {
                List /*<String>*/
                classpathTldsSysProp = InitParamParser.parseCommaSeparatedList(sysPropVal);
                if (classpathTldsSysProp != null) {
                    mergedClassPathTlds.addAll(classpathTldsSysProp);
                }
            } catch (ParseException e) {
                throw new TemplateModelException("Failed to parse system property \"" + SYSTEM_PROPERTY_CLASSPATH_TLDS + "\"", e);
            }
        }
        taglibFactory.setClasspathTlds(mergedClassPathTlds);
    }
    return taglibFactory;
}
Also used : TemplateModelException(freemarker.template.TemplateModelException) Pattern(java.util.regex.Pattern) ArrayList(java.util.ArrayList) Iterator(java.util.Iterator) TaglibFactory(freemarker.ext.jsp.TaglibFactory) ArrayList(java.util.ArrayList) List(java.util.List) ParseException(java.text.ParseException) ServletException(javax.servlet.ServletException) TemplateModelException(freemarker.template.TemplateModelException) TemplateException(freemarker.template.TemplateException) TemplateNotFoundException(freemarker.template.TemplateNotFoundException) ParseException(java.text.ParseException) IOException(java.io.IOException) ClasspathMetaInfTldSource(freemarker.ext.jsp.TaglibFactory.ClasspathMetaInfTldSource)

Example 64 with TemplateModelException

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

the class NodeListModel method getUniqueText.

private String getUniqueText(NodeListModel model, String property) throws TemplateModelException {
    String s1 = null;
    Set s = null;
    for (Iterator it = model.nodes.iterator(); it.hasNext(); ) {
        String s2 = (String) it.next();
        if (s2 != null) {
            // No text yet, make this text the current text
            if (s1 == null) {
                s1 = s2;
            } else // accumulating them for an error message
            if (!s1.equals(s2)) {
                if (s == null) {
                    s = new HashSet();
                    s.add(s1);
                }
                s.add(s2);
            }
        }
    }
    // If the set for the error messages is empty, return the retval
    if (s == null) {
        return s1;
    }
    // Else throw an exception signaling ambiguity
    throw new TemplateModelException("Value for node " + property + " is ambiguos: " + s);
}
Also used : TemplateModelException(freemarker.template.TemplateModelException) Set(java.util.Set) HashSet(java.util.HashSet) Iterator(java.util.Iterator) HashSet(java.util.HashSet)

Example 65 with TemplateModelException

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

the class JspTagModelBase method setupTag.

void setupTag(Object tag, Map args, ObjectWrapper wrapper) throws TemplateModelException, InvocationTargetException, IllegalAccessException {
    if (args != null && !args.isEmpty()) {
        ObjectWrapperAndUnwrapper unwrapper = wrapper instanceof ObjectWrapperAndUnwrapper ? (ObjectWrapperAndUnwrapper) wrapper : // [2.4] Throw exception in this case
        BeansWrapper.getDefaultInstance();
        final Object[] argArray = new Object[1];
        for (Iterator iter = args.entrySet().iterator(); iter.hasNext(); ) {
            final Map.Entry entry = (Map.Entry) iter.next();
            final Object arg = unwrapper.unwrap((TemplateModel) entry.getValue());
            argArray[0] = arg;
            final Object paramName = entry.getKey();
            Method setterMethod = (Method) propertySetters.get(paramName);
            if (setterMethod == null) {
                if (dynaSetter == null) {
                    throw new TemplateModelException("Unknown property " + StringUtil.jQuote(paramName.toString()) + " on instance of " + tagClass.getName());
                } else {
                    dynaSetter.invoke(tag, null, paramName, argArray[0]);
                }
            } else {
                if (arg instanceof BigDecimal) {
                    argArray[0] = BeansWrapper.coerceBigDecimal((BigDecimal) arg, setterMethod.getParameterTypes()[0]);
                }
                try {
                    setterMethod.invoke(tag, argArray);
                } catch (Exception e) {
                    final Class setterType = setterMethod.getParameterTypes()[0];
                    final _ErrorDescriptionBuilder desc = new _ErrorDescriptionBuilder("Failed to set JSP tag parameter ", new _DelayedJQuote(paramName), " (declared type: ", new _DelayedShortClassName(setterType) + ", actual value's type: ", (argArray[0] != null ? (Object) new _DelayedShortClassName(argArray[0].getClass()) : "Null"), "). See cause exception for the more specific cause...");
                    if (e instanceof IllegalArgumentException && !(setterType.isAssignableFrom(String.class)) && argArray[0] != null && argArray[0] instanceof String) {
                        desc.tip("This problem is often caused by unnecessary parameter quotation. Paramters " + "aren't quoted in FTL, similarly as they aren't quoted in most languages. " + "For example, these parameter assignments are wrong: ", "<@my.tag p1=\"true\" p2=\"10\" p3=\"${someVariable}\" p4=\"${x+1}\" />", ". The correct form is: ", "<@my.tag p1=true p2=10 p3=someVariable p4=x+1 />", ". Only string literals are quoted (regardless of where they occur): ", "<@my.box style=\"info\" message=\"Hello ${name}!\" width=200 />", ".");
                    }
                    throw new _TemplateModelException(e, null, desc);
                }
            }
        }
    }
}
Also used : freemarker.core._TemplateModelException(freemarker.core._TemplateModelException) TemplateModelException(freemarker.template.TemplateModelException) ObjectWrapperAndUnwrapper(freemarker.template.ObjectWrapperAndUnwrapper) freemarker.core._DelayedJQuote(freemarker.core._DelayedJQuote) Method(java.lang.reflect.Method) BigDecimal(java.math.BigDecimal) TemplateExceptionWrapperJspException(freemarker.ext.jsp.SimpleTagDirectiveModel.TemplateExceptionWrapperJspException) freemarker.core._TemplateModelException(freemarker.core._TemplateModelException) TemplateModelException(freemarker.template.TemplateModelException) TemplateException(freemarker.template.TemplateException) IntrospectionException(java.beans.IntrospectionException) InvocationTargetException(java.lang.reflect.InvocationTargetException) freemarker.core._TemplateModelException(freemarker.core._TemplateModelException) Iterator(java.util.Iterator) freemarker.core._DelayedShortClassName(freemarker.core._DelayedShortClassName) freemarker.core._ErrorDescriptionBuilder(freemarker.core._ErrorDescriptionBuilder) HashMap(java.util.HashMap) Map(java.util.Map)

Aggregations

TemplateModelException (freemarker.template.TemplateModelException)87 TemplateModel (freemarker.template.TemplateModel)24 IOException (java.io.IOException)21 TemplateScalarModel (freemarker.template.TemplateScalarModel)18 SimpleScalar (freemarker.template.SimpleScalar)17 BeanModel (freemarker.ext.beans.BeanModel)14 Environment (freemarker.core.Environment)13 Writer (java.io.Writer)13 ArrayList (java.util.ArrayList)13 HttpServletRequest (javax.servlet.http.HttpServletRequest)12 Map (java.util.Map)10 List (java.util.List)9 SimpleNumber (freemarker.template.SimpleNumber)7 TemplateHashModel (freemarker.template.TemplateHashModel)7 Iterator (java.util.Iterator)6 freemarker.core._TemplateModelException (freemarker.core._TemplateModelException)5 TemplateHashModelEx (freemarker.template.TemplateHashModelEx)5 TemplateMethodModelEx (freemarker.template.TemplateMethodModelEx)5 TemplateModelIterator (freemarker.template.TemplateModelIterator)5 UMAException (com.ibm.uma.UMAException)4