freemarker-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ddek...@apache.org
Subject [4/5] incubator-freemarker git commit: Removed legacy extensions: rhyno, jython, xml (not to be confused with dom), jdom, ant. Also removed JSP 2.0 support (2.1 is the minimum for now, but maybe it will be 2.2 later).
Date Fri, 20 Jan 2017 16:50:50 GMT
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1588a7f5/src/main/java/freemarker/ext/jdom/NodeListModel.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/jdom/NodeListModel.java b/src/main/java/freemarker/ext/jdom/NodeListModel.java
deleted file mode 100644
index 077a7e0..0000000
--- a/src/main/java/freemarker/ext/jdom/NodeListModel.java
+++ /dev/null
@@ -1,1200 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- * 
- *   http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package freemarker.ext.jdom;
-
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.WeakHashMap;
-
-import org.jaxen.Context;
-import org.jaxen.JaxenException;
-import org.jaxen.NamespaceContext;
-import org.jaxen.jdom.JDOMXPath;
-import org.jdom.Attribute;
-import org.jdom.CDATA;
-import org.jdom.Comment;
-import org.jdom.DocType;
-import org.jdom.Document;
-import org.jdom.Element;
-import org.jdom.EntityRef;
-import org.jdom.Namespace;
-import org.jdom.ProcessingInstruction;
-import org.jdom.Text;
-import org.jdom.output.XMLOutputter;
-
-import freemarker.template.SimpleHash;
-import freemarker.template.SimpleScalar;
-import freemarker.template.Template;
-import freemarker.template.TemplateCollectionModel;
-import freemarker.template.TemplateHashModel;
-import freemarker.template.TemplateMethodModel;
-import freemarker.template.TemplateModel;
-import freemarker.template.TemplateModelException;
-import freemarker.template.TemplateModelIterator;
-import freemarker.template.TemplateScalarModel;
-import freemarker.template.TemplateSequenceModel;
-
-/**
- * Provides a template for wrapping JDOM objects. It is capable of storing not only
- * a single JDOM node, but a list of JDOM nodes at once (hence the name).
- * Each node is an instance of any of the core JDOM node classes (except namespaces,
- * which are not supported at the moment), or String for representing text.
- * See individual method documentation for exact details on how the class works. In
- * short:
- * <ul>
- * <li>{@link #getAsString()} will render all contained nodes as XML fragment,
- * <li>{@link #exec(List)} provides full XPath functionality implemented on top of
- * the <a href="http://www.jaxen.org">Jaxen</a> library,</li>
- * <li>{@link #get(String)} provides node traversal, copying and filtering - somewhat
- * less expressive than XPath, however it does not require the external library and
- * it evaluates somewhat faster</li>
- * <li>being a {@link TemplateCollectionModel} allows to iterate the contained node list, and</li>
- * <li>being a {@link TemplateSequenceModel} allows to access the contained nodes by index and query the node count.</li>
- * </ul>
- * 
- * <p><b>Note:</b> There is a JDOM independent re-implementation of this class:
- *   {@link freemarker.ext.xml.NodeListModel freemarker.ext.xml.NodeListModel}
- * 
- * @deprecated Use {@link freemarker.ext.dom.NodeModel} instead.
- */
-@Deprecated
-public class NodeListModel
-implements
-    TemplateHashModel,
-    TemplateMethodModel,
-    TemplateCollectionModel,
-    TemplateSequenceModel,
-    TemplateScalarModel {
-    private static final AttributeXMLOutputter OUTPUT = new AttributeXMLOutputter();
-    // A convenience singleton for representing a node list without nodes.
-    private static final NodeListModel EMPTY = new NodeListModel(null, false);
-
-    // Cache of already parsed XPath expressions
-    private static final Map XPATH_CACHE = new WeakHashMap();
-
-    private static final NamedNodeOperator NAMED_CHILDREN_OP = new NamedChildrenOp();
-    private static final NamedNodeOperator NAMED_ATTRIBUTE_OP = new NamedAttributeOp();
-    private static final NodeOperator ALL_ATTRIBUTES_OP = new AllAttributesOp();
-    private static final NodeOperator ALL_CHILDREN_OP = new AllChildrenOp();
-    private static final Map OPERATIONS = createOperations();
-    private static final Map SPECIAL_OPERATIONS = createSpecialOperations();
-    private static final int SPECIAL_OPERATION_COPY = 0;
-    private static final int SPECIAL_OPERATION_UNIQUE = 1;
-    private static final int SPECIAL_OPERATION_FILTER_NAME = 2;
-    private static final int SPECIAL_OPERATION_FILTER_TYPE = 3;
-    private static final int SPECIAL_OPERATION_QUERY_TYPE = 4;
-    private static final int SPECIAL_OPERATION_REGISTER_NAMESPACE = 5;
-    private static final int SPECIAL_OPERATION_PLAINTEXT = 6;
-
-    // The contained nodes
-    private final List nodes;
-    private final Map namespaces;
-
-    /**
-     * Creates a node list that holds a single {@link Document} node.
-     */
-    public NodeListModel(Document document) {
-        nodes = document == null ? Collections.EMPTY_LIST : Collections.singletonList(document);
-        namespaces = new HashMap();
-    }
-
-    /**
-     * Creates a node list that holds a single {@link Element} node.
-     */
-    public NodeListModel(Element element) {
-        nodes = element == null ? Collections.EMPTY_LIST : Collections.singletonList(element);
-        namespaces = new HashMap();
-    }
-
-    private NodeListModel(Object object, Map namespaces) {
-        nodes = object == null ? Collections.EMPTY_LIST : Collections.singletonList(object);
-        this.namespaces = namespaces;
-    }
-
-    /**
-     * Creates a node list that holds a list of nodes.
-     * @param nodes the list of nodes this template should hold. The created template
-     * will copy the passed nodes list, so changes to the passed list will not affect
-     * the model.
-     */
-    public NodeListModel(List nodes) {
-        this(nodes, true);
-    }
-
-    /**
-     * Creates a node list that holds a list of nodes.
-     * @param nodes the list of nodes this template should hold.
-     * @param copy if true, the created template will copy the passed nodes list,
-     * so changes to the passed list will not affect the model. If false, the model
-     * will reference the passed list and will sense changes in it, although no
-     * operations on the list will be synchronized.
-     */
-    public NodeListModel(List nodes, boolean copy) {
-        this.nodes = copy && nodes != null ? new ArrayList(nodes) : (nodes == null ? Collections.EMPTY_LIST : nodes);
-        namespaces = new HashMap();
-    }
-
-    private NodeListModel(List nodes, Map namespaces) {
-        this.nodes = nodes == null ? Collections.EMPTY_LIST : nodes;
-        this.namespaces = namespaces;
-    }
-
-    private static final NodeListModel createNodeListModel(List list, Map namespaces) {
-        if (list == null || list.isEmpty()) {
-            if (namespaces.isEmpty()) {
-                return EMPTY;
-            } else {
-                return new NodeListModel(Collections.EMPTY_LIST, namespaces);
-            }
-        }
-        if (list.size() == 1) return new NodeListModel(list.get(0), namespaces);
-        return new NodeListModel(list, namespaces);
-    }
-
-    /**
-     * Returns true if this model contains no nodes.
-     */
-    public boolean isEmpty() {
-        return nodes.isEmpty();
-    }
-
-    /**
-     * This method returns the string resulting from concatenation
-     * of string representations of its nodes. Each node is rendered using its XML
-     * serialization format, while text (String) is rendered as itself. This greatly
-     * simplifies creating XML-transformation templates, as to output a node contained
-     * in variable x as XML fragment, you simply write ${x} in the template.
-     */
-    public String getAsString()
-    throws TemplateModelException {
-        if (isEmpty())
-            return "";
-
-        java.io.StringWriter sw = new java.io.StringWriter(nodes.size() * 128);
-        try {
-            for (Iterator i = nodes.iterator(); i.hasNext(); ) {
-                Object node = i.next();
-                if (node instanceof Element)
-                    OUTPUT.output((Element) node, sw);
-                else if (node instanceof Attribute)
-                    OUTPUT.output((Attribute) node, sw);
-                else if (node instanceof String)
-                    sw.write(OUTPUT.escapeElementEntities(node.toString()));
-                else if (node instanceof Text)
-                    OUTPUT.output((Text) node, sw);
-                else if (node instanceof Document)
-                    OUTPUT.output((Document) node, sw);
-                else if (node instanceof ProcessingInstruction)
-                    OUTPUT.output((ProcessingInstruction) node, sw);
-                else if (node instanceof Comment)
-                    OUTPUT.output((Comment) node, sw);
-                else if (node instanceof CDATA)
-                    OUTPUT.output((CDATA) node, sw);
-                else if (node instanceof DocType)
-                    OUTPUT.output((DocType) node, sw);
-                else if (node instanceof EntityRef)
-                    OUTPUT.output((EntityRef) node, sw);
-                else
-                    throw new TemplateModelException(node.getClass().getName() + " is not a core JDOM class");
-            }
-        } catch (IOException e) {
-            throw new TemplateModelException(e.getMessage());
-        }
-        return sw.toString();
-    }
-
-
-    /**
-     * 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);
-    }
-
-    private TemplateModel getType() {
-        if (nodes.size() == 0)
-            return new SimpleScalar("");
-        Object firstNode = nodes.get(0);
-        char code;
-        if (firstNode instanceof Element)
-            code = 'e';
-        else if (firstNode instanceof Text || firstNode instanceof String)
-            code = 'x';
-        else if (firstNode instanceof Attribute)
-            code = 'a';
-        else if (firstNode instanceof EntityRef)
-            code = 'n';
-        else if (firstNode instanceof Document)
-            code = 'd';
-        else if (firstNode instanceof DocType)
-            code = 't';
-        else if (firstNode instanceof Comment)
-            code = 'c';
-        else if (firstNode instanceof ProcessingInstruction)
-            code = 'p';
-        else
-            code = '?';
-        return new SimpleScalar(new String(new char[] { code}));
-    }
-
-    private SimpleScalar getPlainText()
-    throws TemplateModelException {
-        List list = evaluateElementOperation((TextOp) OPERATIONS.get("_text"), nodes);
-        StringBuilder buf = new StringBuilder();
-        for (Iterator it = list.iterator(); it.hasNext(); ) {
-            buf.append(it.next());
-        }
-        return new SimpleScalar(buf.toString());
-    }
-
-    public TemplateModelIterator iterator() {
-        return new TemplateModelIterator()
-        {
-            private final Iterator it = nodes.iterator();
-
-            public TemplateModel next() {
-                return it.hasNext() ? new NodeListModel(it.next(), namespaces) : null;
-            }
-
-            public boolean hasNext() {
-                return it.hasNext();
-            }
-        };
-    }
-
-    /**
-     * Retrieves the i-th element of the node list.
-     */
-    public TemplateModel get(int i)
-    throws TemplateModelException {
-        try {
-            return new NodeListModel(nodes.get(i), namespaces);
-        } catch (IndexOutOfBoundsException e) {
-            throw new TemplateModelException("Index out of bounds: " + e.getMessage());
-        }
-    }
-    
-    public int size() {
-        return nodes.size();
-    }
-
-    /**
-     * 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);
-        }
-    }
-
-    /**
-     * Registers an XML namespace with this node list. Once registered, you can
-     * refer to the registered namespace using its prefix in the
-     * {@link #get(String)} method from this node list and all other
-     * node lists that are derived from this node list. Use the
-     * <tt>nodelist["prefix:localname"]</tt> or the
-     * <tt>nodelist["@prefix:localname"]</tt> syntax 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 during template evaluation using the
-     * <tt>nodelist._registerNamespace(prefix, uri)</tt> syntax in the template.
-     * This mechanism is completely independent from the namespace declarations
-     * in the XML document itself; its purpose is to give you an easy way
-     * to refer to namespace-scoped elements in {@link #get(String)} and
-     * in XPath expressions passed to {@link #exec(List)}. Note also that
-     * the namespace prefix registry is shared among all node lists that
-     * are created from a single node list - modifying the registry in one
-     * affects all others as well. If you want to obtain a namespace 
-     * "detached" copy of the node list, use the <code>_copy</code> key on
-     * it (or call <code>nodeList.get("_copy")</code> directly from your
-     * Java code. The returned node list has all the namespaces that the
-     * original node list has, but they can be manipulated independently
-     * thereon.
-     */
-    public void registerNamespace(String prefix, String uri) {
-        synchronized (namespaces) {
-            namespaces.put(prefix, Namespace.getNamespace(prefix, uri));
-        }
-    }
-
-    private interface NodeOperator {
-        List operate(Object node)
-        throws TemplateModelException;
-    }
-
-    private interface NamedNodeOperator {
-        List operate(Object node, String localName, Namespace namespace)
-        throws TemplateModelException;
-    }
-
-    private static final class AllChildrenOp implements NodeOperator {
-        public List operate(Object node) {
-            if (node instanceof Element)
-                return((Element) node).getChildren();
-            else if (node instanceof Document) {
-                Element root = ((Document) node).getRootElement();
-                return root == null ? Collections.EMPTY_LIST : Collections.singletonList(root);
-            } 
- // With 2.1 semantics it  makes more sense to just return a null and let the core 
- // throw an InvalidReferenceException and the template writer can use ?exists etcetera. (JR)
-            return null;
-/*            
-            else
-                throw new TemplateModelException("_allChildren can not be applied on " + node.getClass());
-*/                
-        }
-    }
-
-    private static final class NamedChildrenOp implements NamedNodeOperator {
-        public List operate(Object node, String localName, Namespace namespace) {
-            if (node instanceof Element) {
-                return((Element) node).getChildren(localName, namespace);
-            } else if (node instanceof Document) {
-                Element root = ((Document) node).getRootElement();
-                if (root != null &&
-                    root.getName().equals(localName) &&
-                    root.getNamespaceURI().equals(namespace.getURI())) {
-                    return Collections.singletonList(root);
-                } else
-                    return Collections.EMPTY_LIST;
-            } 
- // With 2.1 semantics it  makes more sense to just return a null and let the core 
- // throw an InvalidReferenceException and the template writer can use ?exists etcetera. (JR)
-            return null;
- /*           
-            else
-                throw new TemplateModelException("_namedChildren can not be applied on " + node.getClass());
-*/                
-        }
-    }
-
-    private static final class AllAttributesOp implements NodeOperator {
-        public List operate(Object node) {
- // With 2.1 semantics it  makes more sense to just return a null and let the core 
- // throw an InvalidReferenceException and the template writer can use ?exists etcetera. (JR)
-            if (!(node instanceof Element)) {
-                return null;
-            }
-            return ((Element) node).getAttributes();
-/*
-            else
-                throw new TemplateModelException("_allAttributes can not be applied on " + node.getClass());
-*/                
-        }
-    }
-
-    private static final class NamedAttributeOp implements NamedNodeOperator {
-        public List operate(Object node, String localName, Namespace namespace) {
-            Attribute attr = null;
-            if (node instanceof Element) {
-                Element element = (Element) node;
-                attr = element.getAttribute(localName, namespace);
-            } else if (node instanceof ProcessingInstruction) {
-                ProcessingInstruction pi = (ProcessingInstruction) node;
-                if ("target".equals(localName))
-                    attr = new Attribute("target", pi.getTarget());
-                else if ("data".equals(localName))
-                    attr = new Attribute("data", pi.getData());
-                else
-                    attr = new Attribute(localName, pi.getValue(localName));
-            } else if (node instanceof DocType) {
-                DocType doctype = (DocType) node;
-                if ("publicId".equals(localName))
-                    attr = new Attribute("publicId", doctype.getPublicID());
-                else if ("systemId".equals(localName))
-                    attr = new Attribute("systemId", doctype.getSystemID());
-                else if ("elementName".equals(localName))
-                    attr = new Attribute("elementName", doctype.getElementName());
-            } 
-            // With 2.1 semantics it  makes more sense to just return a null and let the core 
-            // throw an InvalidReferenceException and the template writer can use ?exists etcetera. (JR)
-            else {
-                return null;
-            }
-/*            
-            else
-                throw new TemplateModelException("_allAttributes can not be applied on " + node.getClass());
-*/
-            return attr == null ? Collections.EMPTY_LIST : Collections.singletonList(attr);
-        }
-    }
-
-    private static final class NameOp implements NodeOperator {
-        public List operate(Object node) {
-            if (node instanceof Element)
-                return Collections.singletonList(((Element) node).getName());
-            else if (node instanceof Attribute)
-                return Collections.singletonList(((Attribute) node).getName());
-            else if (node instanceof EntityRef)
-                return Collections.singletonList(((EntityRef) node).getName());
-            else if (node instanceof ProcessingInstruction)
-                return Collections.singletonList(((ProcessingInstruction) node).getTarget());
-            else if (node instanceof DocType)
-                return Collections.singletonList(((DocType) node).getPublicID());
-            else
-                return null;
-            // With 2.1 semantics it  makes more sense to just return a null and let the core 
-            // throw an InvalidReferenceException and the template writer can use ?exists etcetera. (JR)
-//                throw new TemplateModelException("_name can not be applied on " + node.getClass());
-        }
-    }
-
-    private static final class QNameOp implements NodeOperator {
-        public List operate(Object node) {
-            if (node instanceof Element)
-                return Collections.singletonList(((Element) node).getQualifiedName());
-            else if (node instanceof Attribute)
-                return Collections.singletonList(((Attribute) node).getQualifiedName());
-            // With 2.1 semantics it  makes more sense to just return a null and let the core 
-            // throw an InvalidReferenceException and the template writer can use ?exists etcetera. (JR)
-            return null;
-//            throw new TemplateModelException("_qname can not be applied on " + node.getClass());
-        }
-    }
-
-    private static final class NamespaceUriOp implements NodeOperator {
-        public List operate(Object node) {
-            if (node instanceof Element)
-                return Collections.singletonList(((Element) node).getNamespace().getURI());
-            else if (node instanceof Attribute)
-                return Collections.singletonList(((Attribute) node).getNamespace().getURI());
-            // With 2.1 semantics it  makes more sense to just return a null and let the core 
-            // throw an InvalidReferenceException and the template writer can use ?exists etcetera. (JR)
-            return null;
-//            throw new TemplateModelException("_nsuri can not be applied on " + node.getClass());
-        }
-    }
-
-    private static final class NamespacePrefixOp implements NodeOperator {
-        public List operate(Object node) {
-            if (node instanceof Element)
-                return Collections.singletonList(((Element) node).getNamespace().getPrefix());
-            else if (node instanceof Attribute)
-                return Collections.singletonList(((Attribute) node).getNamespace().getPrefix());
-            // With 2.1 semantics it  makes more sense to just return a null and let the core 
-            // throw an InvalidReferenceException and the template writer can use ?exists etcetera. (JR)
-            return null;
-//            throw new TemplateModelException("_nsprefix can not be applied on " + node.getClass());
-        }
-    }
-
-    private static final class CanonicalNameOp implements NodeOperator {
-        public List operate(Object node) {
-            if (node instanceof Element) {
-                Element element = (Element) node;
-                return Collections.singletonList(element.getNamespace().getURI() + element.getName());
-            } else if (node instanceof Attribute) {
-                Attribute attribute = (Attribute) node;
-                return Collections.singletonList(attribute.getNamespace().getURI() + attribute.getName());
-            }
-            // With 2.1 semantics it  makes more sense to just return a null and let the core 
-            // throw an InvalidReferenceException and the template writer can use ?exists etcetera. (JR)
-            return null;
-//            throw new TemplateModelException("_cname can not be applied on " + node.getClass());
-        }
-    }
-
-
-    private static final Element getParent(Object node) {
-        if (node instanceof Element)
-            return((Element) node).getParent();
-        else if (node instanceof Attribute)
-            return((Attribute) node).getParent();
-        else if (node instanceof Text)
-            return((Text) node).getParent();
-        else if (node instanceof ProcessingInstruction)
-            return((ProcessingInstruction) node).getParent();
-        else if (node instanceof Comment)
-            return((Comment) node).getParent();
-        else if (node instanceof EntityRef)
-            return((EntityRef) node).getParent();
-        else
-            // With 2.1 semantics it  makes more sense to just return a null and let the core 
-            // throw an InvalidReferenceException and the template writer can use ?exists etcetera. (JR)
-            return null;
-//            throw new TemplateModelException("_parent can not be applied on " + node.getClass());
-    }
-
-    private static final class ParentOp implements NodeOperator {
-        public List operate(Object node) {
-            Element parent = getParent(node);
-            return parent == null ? Collections.EMPTY_LIST : Collections.singletonList(parent);
-        }
-    }
-
-    private static final class AncestorOp implements NodeOperator {
-        public List operate(Object node) {
-            Element parent = getParent(node);
-            if (parent == null) return Collections.EMPTY_LIST;
-            LinkedList list = new LinkedList();
-            do {
-                list.addFirst(parent);
-                parent = parent.getParent();
-            } while (parent != null);
-            return list;
-        }
-    }
-
-    private static final class AncestorOrSelfOp implements NodeOperator {
-        public List operate(Object node) {
-            Element parent = getParent(node);
-            if (parent == null) return Collections.singletonList(node);
-            LinkedList list = new LinkedList();
-            list.addFirst(node);
-            do {
-                list.addFirst(parent);
-                parent = parent.getParent();
-            } while (parent != null);
-            return list;
-        }
-    }
-
-    private static class DescendantOp implements NodeOperator {
-        public List operate(Object node) {
-            LinkedList list = new LinkedList();
-            if (node instanceof Element) {
-                addChildren((Element) node, list);
-            } else if (node instanceof Document) {
-                Element root = ((Document) node).getRootElement();
-                list.add(root);
-                addChildren(root, list);
-            } else
-                // With 2.1 semantics it  makes more sense to just return a null and let the core 
-                // throw an InvalidReferenceException and the template writer can use ?exists etcetera. (JR)
-                return null;
-//                throw new TemplateModelException("_descendant can not be applied on " + node.getClass());
-
-            return list;
-        }
-
-        private void addChildren(Element element, List list) {
-            List children = element.getChildren();
-            Iterator it = children.iterator();
-            while (it.hasNext()) {
-                Element child = (Element) it.next();
-                list.add(child);
-                addChildren(child, list);
-            }
-        }
-    }
-
-    private static final class DescendantOrSelfOp extends DescendantOp {
-        @Override
-        public List operate(Object node) {
-            LinkedList list = (LinkedList) super.operate(node);
-            list.addFirst(node);
-            return list;
-        }
-    }
-
-    private static final class DocumentOp implements NodeOperator {
-        public List operate(Object node) {
-            Document doc = null;
-            if (node instanceof Element)
-                doc = ((Element) node).getDocument();
-            else if (node instanceof Attribute) {
-                Element parent = ((Attribute) node).getParent();
-                doc = parent == null ? null : parent.getDocument();
-            } else if (node instanceof Text) {
-                Element parent = ((Text) node).getParent();
-                doc = parent == null ? null : parent.getDocument();
-            } else if (node instanceof Document)
-                doc = (Document) node;
-            else if (node instanceof ProcessingInstruction)
-                doc = ((ProcessingInstruction) node).getDocument();
-            else if (node instanceof EntityRef)
-                doc = ((EntityRef) node).getDocument();
-            else if (node instanceof Comment)
-                doc = ((Comment) node).getDocument();
-            else
-                // With 2.1 semantics it  makes more sense to just return a null and let the core 
-                // throw an InvalidReferenceException and the template writer can use ?exists etcetera. (JR)
-                return null;
-//                throw new TemplateModelException("_document can not be applied on " + node.getClass());
-
-            return doc == null ? Collections.EMPTY_LIST : Collections.singletonList(doc);
-        }
-    }
-
-    private static final class DocTypeOp implements NodeOperator {
-        public List operate(Object node) {
-            if (node instanceof Document) {
-                DocType doctype = ((Document) node).getDocType();
-                return doctype == null ? Collections.EMPTY_LIST : Collections.singletonList(doctype);
-            } else
-                // With 2.1 semantics it  makes more sense to just return a null and let the core 
-                // throw an InvalidReferenceException and the template writer can use ?exists etcetera. (JR)
-                return null;
-//                throw new TemplateModelException("_doctype can not be applied on " + node.getClass());
-        }
-    }
-
-    private static final class ContentOp implements NodeOperator {
-        public List operate(Object node) {
-            if (node instanceof Element)
-                return((Element) node).getContent();
-            else if (node instanceof Document)
-                return((Document) node).getContent();
-            // With 2.1 semantics it  makes more sense to just return a null and let the core 
-            // throw an InvalidReferenceException and the template writer can use ?exists etcetera. (JR)
-            return null;
-//            throw new TemplateModelException("_content can not be applied on " + node.getClass());
-        }
-    }
-
-    private static final class TextOp implements NodeOperator {
-        public List operate(Object node) {
-            if (node instanceof Element)
-                return Collections.singletonList(((Element) node).getTextTrim());
-            if (node instanceof Attribute)
-                return Collections.singletonList(((Attribute) node).getValue());
-            if (node instanceof CDATA)
-                return Collections.singletonList(((CDATA) node).getText());
-            if (node instanceof Comment)
-                return Collections.singletonList(((Comment) node).getText());
-            if (node instanceof ProcessingInstruction)
-                return Collections.singletonList(((ProcessingInstruction) node).getData());
-            // With 2.1 semantics it  makes more sense to just return a null and let the core 
-            // throw an InvalidReferenceException and the template writer can use ?exists etcetera. (JR)
-            return null;
-//            throw new TemplateModelException("_text can not be applied on " + node.getClass());
-        }
-    }
-
-    private static final List evaluateElementOperation(NodeOperator op, List nodes)
-    throws TemplateModelException {
-        int s = nodes.size();
-        List[] lists = new List[s];
-        int l = 0;
-        {
-            int i = 0;
-            Iterator it = nodes.iterator();
-            while (it.hasNext()) {
-                List list = op.operate(it.next());
-                if (list != null) {
-                    lists[i++] = list;
-                    l += list.size();
-                }
-            }
-        }
-        List retval = new ArrayList(l);
-        for (int i = 0; i < s; ++i) {
-            if (lists[i] != null) {
-                retval.addAll(lists[i]);
-            }
-        }
-        return retval;
-    }
-
-    private static final List evaluateNamedElementOperation(NamedNodeOperator op, String localName, Namespace namespace, List nodes)
-    throws TemplateModelException {
-        int s = nodes.size();
-        List[] lists = new List[s];
-        int l = 0;
-        {
-            int i = 0;
-            Iterator it = nodes.iterator();
-            while (it.hasNext()) {
-                List list = op.operate(it.next(), localName, namespace);
-                lists[i++] = list;
-                l += list.size();
-            }
-        }
-        List retval = new ArrayList(l);
-        for (int i = 0; i < s; ++i)
-            retval.addAll(lists[i]);
-        return retval;
-    }
-
-    private static final List removeDuplicates(List list) {
-        int s = list.size();
-        ArrayList ulist = new ArrayList(s);
-        Set set = new HashSet(s * 4 / 3, .75f);
-        Iterator it = list.iterator();
-        while (it.hasNext()) {
-            Object o = it.next();
-            if (set.add(o))
-                ulist.add(o);
-        }
-        ulist.trimToSize();
-        return ulist;
-    }
-
-    private static final Map createOperations() {
-        Map map = new HashMap();
-
-        map.put("_ancestor", new AncestorOp());
-        map.put("_ancestorOrSelf", new AncestorOrSelfOp());
-        map.put("_attributes", ALL_ATTRIBUTES_OP);
-        map.put("_children", ALL_CHILDREN_OP);
-        map.put("_cname", new CanonicalNameOp());
-        map.put("_content", new ContentOp());
-        map.put("_descendant", new DescendantOp());
-        map.put("_descendantOrSelf", new DescendantOrSelfOp());
-        map.put("_document", new DocumentOp());
-        map.put("_doctype", new DocTypeOp());
-        map.put("_name", new NameOp());
-        map.put("_nsprefix", new NamespacePrefixOp());
-        map.put("_nsuri", new NamespaceUriOp());
-        map.put("_parent", new ParentOp());
-        map.put("_qname", new QNameOp());
-        map.put("_text", new TextOp());
-
-        return map;
-    }
-
-    private static final Map createSpecialOperations() {
-        Map map = new HashMap();
-
-        Integer copy = Integer.valueOf(SPECIAL_OPERATION_COPY);
-        Integer unique = Integer.valueOf(SPECIAL_OPERATION_UNIQUE);
-        Integer fname = Integer.valueOf(SPECIAL_OPERATION_FILTER_NAME);
-        Integer ftype = Integer.valueOf(SPECIAL_OPERATION_FILTER_TYPE);
-        Integer type = Integer.valueOf(SPECIAL_OPERATION_QUERY_TYPE);
-        Integer regns = Integer.valueOf(SPECIAL_OPERATION_REGISTER_NAMESPACE);
-        Integer plaintext = Integer.valueOf(SPECIAL_OPERATION_PLAINTEXT);
-
-        map.put("_copy", copy);
-        map.put("_unique", unique);
-        map.put("_fname", fname);
-        map.put("_ftype", ftype);
-        map.put("_type", type);
-        map.put("_registerNamespace", regns);
-        map.put("_plaintext", plaintext);
-
-        // These are in for backward compatibility
-        map.put("x_copy", copy);
-        map.put("x_unique", unique);
-        map.put("x_fname", fname);
-        map.put("x_ftype", ftype);
-        map.put("x_type", type);
-
-        return map;
-    }
-
-    private final class RegisterNamespace implements TemplateMethodModel {
-        public boolean isEmpty() {
-            return false;
-        }
-
-        public Object exec(List arguments)
-        throws TemplateModelException {
-            if (arguments.size() != 2)
-                throw new TemplateModelException("_registerNamespace(prefix, uri) requires two arguments");
-
-            registerNamespace((String) arguments.get(0), (String) arguments.get(1));
-
-            return TemplateScalarModel.EMPTY_STRING;
-        }
-    }
-
-    private final class NameFilter implements TemplateMethodModel {
-        public boolean isEmpty() {
-            return false;
-        }
-
-        public Object exec(List arguments) {
-            Set names = new HashSet(arguments);
-            List list = new LinkedList(nodes);
-            Iterator it = list.iterator();
-            while (it.hasNext()) {
-                Object node = it.next();
-                String name = null;
-                if (node instanceof Element)
-                    name = ((Element) node).getName();
-                else if (node instanceof Attribute)
-                    name = ((Attribute) node).getName();
-                else if (node instanceof ProcessingInstruction)
-                    name = ((ProcessingInstruction) node).getTarget();
-                else if (node instanceof EntityRef)
-                    name = ((EntityRef) node).getName();
-                else if (node instanceof DocType)
-                    name = ((DocType) node).getPublicID();
-
-                if (name == null || !names.contains(name))
-                    it.remove();
-            }
-            return createNodeListModel(list, namespaces);
-        }
-    }
-
-    private final class TypeFilter implements TemplateMethodModel {
-        public boolean isEmpty() {
-            return false;
-        }
-
-        public Object exec(List arguments)
-        throws TemplateModelException {
-            if (arguments == null || arguments.size() == 0)
-                throw new TemplateModelException("_type expects exactly one argument");
-            String arg = (String) arguments.get(0);
-            boolean invert = arg.indexOf('!') != -1;
-            // NOTE: true in each of these variables means 'remove', not 'keep'
-            // This is so we don't invert their values in the loop. So,
-            // a is true <--> (a is not present in the string) xor invert.
-            boolean a = invert != (arg.indexOf('a') == -1);
-            boolean c = invert != (arg.indexOf('c') == -1);
-            boolean d = invert != (arg.indexOf('d') == -1);
-            boolean e = invert != (arg.indexOf('e') == -1);
-            boolean n = invert != (arg.indexOf('n') == -1);
-            boolean p = invert != (arg.indexOf('p') == -1);
-            boolean t = invert != (arg.indexOf('t') == -1);
-            boolean x = invert != (arg.indexOf('x') == -1);
-
-            LinkedList list = new LinkedList(nodes);
-            Iterator it = list.iterator();
-            while (it.hasNext()) {
-                Object node = it.next();
-                if ((node instanceof Element && e)
-                    || (node instanceof Attribute && a)
-                    || (node instanceof String && x)
-                    || (node instanceof Text && x)
-                    || (node instanceof ProcessingInstruction && p)
-                    || (node instanceof Comment && c)
-                    || (node instanceof EntityRef && n)
-                    || (node instanceof Document && d)
-                    || (node instanceof DocType && t))
-                    it.remove();
-            }
-            return createNodeListModel(list, namespaces);
-        }
-    }
-
-    /**
-     * Loads a template from a file passed as the first argument, loads an XML
-     * document from the standard input, passes it to the template as variable
-     * <tt>document</tt> and writes the result of template processing to
-     * standard output.
-     * 
-     * @deprecated Will be removed (main method in a library, often classified as CWE-489 "Leftover Debug Code").
-     */
-    @Deprecated
-    public static void main(String[] args)
-    throws Exception {
-        org.jdom.input.SAXBuilder builder = new org.jdom.input.SAXBuilder();
-        Document document = builder.build(System.in);
-        SimpleHash model = new SimpleHash();
-        model.put("document", new NodeListModel(document));
-        FileReader fr = new FileReader(args[0]);
-        Template template = new Template(args[0], fr);
-        Writer w = new java.io.OutputStreamWriter(System.out);
-        template.process(model, w);
-        w.flush();
-        w.close();
-    }
-
-    private static final class AttributeXMLOutputter extends XMLOutputter {
-        public void output(Attribute attribute, Writer out)
-        throws IOException {
-            out.write(" ");
-            out.write(attribute.getQualifiedName());
-            out.write("=");
-
-            out.write("\"");
-            out.write(escapeAttributeEntities(attribute.getValue()));
-            out.write("\"");
-        }
-    }
-
-    private static final class JDOMXPathEx
-    extends
-        JDOMXPath {
-        JDOMXPathEx(String path)
-        throws JaxenException {
-            super(path);
-        }
-
-        public List selectNodes(Object object, Map namespaces)
-        throws JaxenException {
-            Context context = getContext(object);
-            context.getContextSupport().setNamespaceContext(new NamespaceContextImpl(namespaces));
-            return selectNodesForContext(context);
-        } 
-
-        private static final class NamespaceContextImpl
-        implements
-            NamespaceContext {
-            private final Map namespaces;
-            
-            NamespaceContextImpl(Map namespaces) {
-                this.namespaces = namespaces;
-            }
-            
-            public String translateNamespacePrefixToUri(String prefix) {
-                // Empty prefix always maps to empty URL in XPath
-                if (prefix.length() == 0) {
-                    return prefix;
-                }
-                synchronized (namespaces) {
-                    Namespace ns = (Namespace) namespaces.get(prefix);
-                    return ns == null ? null : ns.getURI();
-                }   
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1588a7f5/src/main/java/freemarker/ext/jdom/package.html
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/jdom/package.html b/src/main/java/freemarker/ext/jdom/package.html
deleted file mode 100644
index dba93d8..0000000
--- a/src/main/java/freemarker/ext/jdom/package.html
+++ /dev/null
@@ -1,29 +0,0 @@
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-    http://www.apache.org/licenses/LICENSE-2.0
-  
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<html>
-<head>
-<title></title>
-</head>
-<body>
-
-<p>Deprecated, use W3C DOM ({@link freemarker.ext.dom}) instead;
-Exposes <a href="http://www.jdom.org/" target="_blank">JDOM</a> XML nodes to templates.
-
-</body>
-</html>

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1588a7f5/src/main/java/freemarker/ext/jsp/FreeMarkerJspFactory2.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/jsp/FreeMarkerJspFactory2.java b/src/main/java/freemarker/ext/jsp/FreeMarkerJspFactory2.java
deleted file mode 100644
index 88af211..0000000
--- a/src/main/java/freemarker/ext/jsp/FreeMarkerJspFactory2.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- * 
- *   http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package freemarker.ext.jsp;
-
-
-/**
- */
-class FreeMarkerJspFactory2 extends FreeMarkerJspFactory {
-    protected String getSpecificationVersion() {
-        return "2.0";
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1588a7f5/src/main/java/freemarker/ext/jsp/PageContextFactory.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/jsp/PageContextFactory.java b/src/main/java/freemarker/ext/jsp/PageContextFactory.java
index 653a805..9990d4c 100644
--- a/src/main/java/freemarker/ext/jsp/PageContextFactory.java
+++ b/src/main/java/freemarker/ext/jsp/PageContextFactory.java
@@ -37,13 +37,8 @@ class PageContextFactory {
                 PageContext.class.getMethod("getELContext", (Class[]) null);
                 return Class.forName("freemarker.ext.jsp._FreeMarkerPageContext21");
             } catch (NoSuchMethodException e1) {
-                try {
-                    PageContext.class.getMethod("getExpressionEvaluator", (Class[]) null);
-                    return Class.forName("freemarker.ext.jsp._FreeMarkerPageContext2");
-                } catch (NoSuchMethodException e2) {
-                    throw new IllegalStateException(
-                            "Since FreeMarker 2.3.24, JSP support requires at least JSP 2.0.");
-                }
+                throw new IllegalStateException(
+                        "Since FreeMarker 3.0.0, JSP support requires at least JSP 2.1.");
             }
         } catch (ClassNotFoundException e) {
             throw new NoClassDefFoundError(e.getMessage());

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1588a7f5/src/main/java/freemarker/ext/jsp/_FreeMarkerPageContext2.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/jsp/_FreeMarkerPageContext2.java b/src/main/java/freemarker/ext/jsp/_FreeMarkerPageContext2.java
deleted file mode 100644
index 2169157..0000000
--- a/src/main/java/freemarker/ext/jsp/_FreeMarkerPageContext2.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- * 
- *   http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package freemarker.ext.jsp;
-
-import freemarker.log.Logger;
-import freemarker.template.TemplateModelException;
-
-import javax.servlet.jsp.el.ExpressionEvaluator;
-import javax.servlet.jsp.el.VariableResolver;
-import javax.servlet.jsp.el.ELException;
-import javax.servlet.jsp.JspFactory;
-import javax.servlet.jsp.PageContext;
-import javax.servlet.ServletException;
-import java.io.IOException;
-
-/**
- * Don't use this class; it's only public to work around Google App Engine Java
- * compliance issues. FreeMarker developers only: treat this class as package-visible.
- * 
- * Implementation of PageContext that contains JSP 2.0 specific methods.
- */
-public class _FreeMarkerPageContext2 extends FreeMarkerPageContext {
-    private static final Logger LOG = Logger.getLogger("freemarker.jsp");
-
-    static {
-        if (JspFactory.getDefaultFactory() == null) {
-            JspFactory.setDefaultFactory(new FreeMarkerJspFactory2());
-        }
-        LOG.debug("Using JspFactory implementation class " + 
-                JspFactory.getDefaultFactory().getClass().getName());
-    }
-
-    public _FreeMarkerPageContext2() throws TemplateModelException {
-        super();
-    }
-
-    /**
-     * Attempts to locate and manufacture an expression evaulator instance. For this
-     * to work you <b>must</b> have the Apache Commons-EL package in the classpath. If
-     * Commons-EL is not available, this method will throw an UnsupportedOperationException. 
-     */
-    public ExpressionEvaluator getExpressionEvaluator() {
-        try {
-            Class type = Thread.currentThread().getContextClassLoader().loadClass
-                    ("org.apache.commons.el.ExpressionEvaluatorImpl");
-            return (ExpressionEvaluator) type.newInstance();
-        } catch (Exception e) {
-            throw new UnsupportedOperationException("In order for the getExpressionEvaluator() " +
-                "method to work, you must have downloaded the apache commons-el jar and " +
-                "made it available in the classpath.");
-        }
-    }
-
-    /**
-     * Returns a variable resolver that will resolve variables by searching through
-     * the page scope, request scope, session scope and application scope for an
-     * attribute with a matching name.
-     */
-    public VariableResolver getVariableResolver() {
-        final PageContext ctx = this;
-
-        return new VariableResolver() {
-            public Object resolveVariable(String name) throws ELException {
-                return ctx.findAttribute(name);
-            }
-        };
-    }
-
-    /**
-     * Includes the specified path. The flush argument is ignored!
-     */
-    public void include(String path, boolean flush) throws IOException, ServletException {
-        super.include(path);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1588a7f5/src/main/java/freemarker/ext/jsp/_FreeMarkerPageContext21.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/jsp/_FreeMarkerPageContext21.java b/src/main/java/freemarker/ext/jsp/_FreeMarkerPageContext21.java
index 58adbe8..a3f6aa3 100644
--- a/src/main/java/freemarker/ext/jsp/_FreeMarkerPageContext21.java
+++ b/src/main/java/freemarker/ext/jsp/_FreeMarkerPageContext21.java
@@ -39,8 +39,7 @@ import freemarker.template.utility.ClassUtil;
  * Don't use this class; it's only public to work around Google App Engine Java
  * compliance issues. FreeMarker developers only: treat this class as package-visible.
  * 
- * Implementation of PageContext that contains JSP 2.0 and JSP 2.1 specific 
- * methods.
+ * Implementation of PageContext that contains all JSP 2.1 methods.
  */
 public class _FreeMarkerPageContext21 extends FreeMarkerPageContext {
     private static final Logger LOG = Logger.getLogger("freemarker.jsp");
@@ -67,6 +66,7 @@ public class _FreeMarkerPageContext21 extends FreeMarkerPageContext {
         try {
             Class type = ((ClassLoader) AccessController.doPrivileged(
                     new PrivilegedAction() {
+                        @Override
                         public Object run() {
                             return Thread.currentThread().getContextClassLoader();
                         }
@@ -90,6 +90,7 @@ public class _FreeMarkerPageContext21 extends FreeMarkerPageContext {
         final PageContext ctx = this;
 
         return new VariableResolver() {
+            @Override
             public Object resolveVariable(String name) throws ELException {
                 return ctx.findAttribute(name);
             }

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1588a7f5/src/main/java/freemarker/ext/jython/JythonHashModel.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/jython/JythonHashModel.java b/src/main/java/freemarker/ext/jython/JythonHashModel.java
deleted file mode 100644
index b44488c..0000000
--- a/src/main/java/freemarker/ext/jython/JythonHashModel.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- * 
- *   http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package freemarker.ext.jython;
-
-import org.python.core.PyException;
-import org.python.core.PyObject;
-
-import freemarker.ext.util.ModelFactory;
-import freemarker.template.ObjectWrapper;
-import freemarker.template.TemplateCollectionModel;
-import freemarker.template.TemplateHashModelEx;
-import freemarker.template.TemplateModel;
-import freemarker.template.TemplateModelException;
-
-/**
- * Model for Jython dictionaries ({@link org.python.core.PyDictionary}
- * and {@link org.python.core.PyStringMap}).
- * Note that the basic {@link JythonModel} already provides access to the
- * {@link PyObject#__finditem__(String)} method. This class only adds 
- * {@link TemplateHashModelEx} functionality in a somewhat skewed way. One
- * could say it even violates TemplateHashModelEx semantics, as both the
- * returned keys and values are only those from the item mapping, while the
- * <code>get()</code> method works for attributes as well. However, in practice
- * when you ask for <code>dict?keys</code> inside a template, you'll really
- * want to retrieve only items, not attributes so this is considered OK.
- */
-public class JythonHashModel
-extends 
-    JythonModel 
-implements 
-    TemplateHashModelEx {
-    private static final String KEYS = "keys";
-    private static final String KEYSET = "keySet";
-    private static final String VALUES = "values";
-    
-    static final ModelFactory FACTORY =
-        new ModelFactory()
-        {
-            public TemplateModel create(Object object, ObjectWrapper wrapper) {
-                return new JythonHashModel((PyObject) object, (JythonWrapper) wrapper);
-            }
-        };
-        
-    public JythonHashModel(PyObject object, JythonWrapper wrapper) {
-        super(object, wrapper);
-    }
-    
-    /**
-     * Returns {@link PyObject#__len__()}.
-     */
-    public int size() throws TemplateModelException {
-        try {
-            return object.__len__();
-        } catch (PyException e) {
-            throw new TemplateModelException(e);
-        }
-    }
-
-    /**
-     * Returns either <code>object.__findattr__("keys").__call__()</code>
-     * or <code>object.__findattr__("keySet").__call__()</code>.
-     */
-    public TemplateCollectionModel keys() throws TemplateModelException {
-        try {
-            PyObject method = object.__findattr__(KEYS);
-            if (method == null) {
-                method = object.__findattr__(KEYSET);
-            }
-            if (method != null) {
-                return (TemplateCollectionModel) wrapper.wrap(method.__call__());
-            }
-        } catch (PyException e) {
-            throw new TemplateModelException(e);
-        }
-        throw new TemplateModelException(
-                "'?keys' is not supported as there is no 'keys' nor 'keySet' attribute on an instance of "
-                + JythonVersionAdapterHolder.INSTANCE.getPythonClassName(object));
-    }
-
-    /**
-     * Returns <code>object.__findattr__("values").__call__()</code>.
-     */
-    public TemplateCollectionModel values() throws TemplateModelException {
-        try {
-            PyObject method = object.__findattr__(VALUES);
-            if (method != null) {
-                return (TemplateCollectionModel) wrapper.wrap(method.__call__());
-            }
-        } catch (PyException e) {
-            throw new TemplateModelException(e);
-        }
-        throw new TemplateModelException(
-                "'?values' is not supported as there is no 'values' attribute on an instance of "
-                + JythonVersionAdapterHolder.INSTANCE.getPythonClassName(object));
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1588a7f5/src/main/java/freemarker/ext/jython/JythonModel.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/jython/JythonModel.java b/src/main/java/freemarker/ext/jython/JythonModel.java
deleted file mode 100644
index 2476c72..0000000
--- a/src/main/java/freemarker/ext/jython/JythonModel.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- * 
- *   http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package freemarker.ext.jython;
-
-import java.util.Iterator;
-import java.util.List;
-
-import org.python.core.Py;
-import org.python.core.PyException;
-import org.python.core.PyObject;
-
-import freemarker.ext.util.ModelFactory;
-import freemarker.ext.util.WrapperTemplateModel;
-import freemarker.template.AdapterTemplateModel;
-import freemarker.template.ObjectWrapper;
-import freemarker.template.TemplateBooleanModel;
-import freemarker.template.TemplateHashModel;
-import freemarker.template.TemplateMethodModelEx;
-import freemarker.template.TemplateModel;
-import freemarker.template.TemplateModelException;
-import freemarker.template.TemplateScalarModel;
-
-/**
- * Generic model for arbitrary Jython objects.
- */
-public class JythonModel
-implements TemplateBooleanModel, TemplateScalarModel, TemplateHashModel, 
-TemplateMethodModelEx, AdapterTemplateModel, WrapperTemplateModel {
-    protected final PyObject object;
-    protected final JythonWrapper wrapper;
-    
-    static final ModelFactory FACTORY =
-        new ModelFactory()
-        {
-            public TemplateModel create(Object object, ObjectWrapper wrapper) {
-                return new JythonModel((PyObject) object, (JythonWrapper) wrapper);
-            }
-        };
-        
-    public JythonModel(PyObject object, JythonWrapper wrapper) {
-        this.object = object;
-        this.wrapper = wrapper;
-    }
-
-    /**
-     * Returns the value of {@link PyObject#__nonzero__()}.
-     */
-    public boolean getAsBoolean() throws TemplateModelException {
-        try {
-            return object.__nonzero__();
-        } catch (PyException e) {
-            throw new TemplateModelException(e);
-        }
-    }
-
-    /**
-     * Returns the value of {@link Object#toString()}.
-     */
-    public String getAsString() throws TemplateModelException {
-        try {
-            return object.toString();
-        } catch (PyException e) {
-            throw new TemplateModelException(e);
-        }
-    }
-
-    /**
-     * Calls {@link PyObject#__findattr__(java.lang.String)}, then if it
-     * returns null calls {@link PyObject#__finditem__(java.lang.String)}.
-     * If {@link JythonWrapper#setAttributesShadowItems(boolean)} was called
-     * with <code>false</code>, the order of calls is reversed (that is, item
-     * lookup takes precedence over attribute lookup).
-     */
-    public TemplateModel get(String key)
-    throws TemplateModelException {
-        if (key != null) {
-            key = key.intern();
-        }
-        
-        PyObject obj = null;
-        
-        try {
-            if (wrapper.isAttributesShadowItems()) {
-                obj = object.__findattr__(key);
-                if (obj == null) {
-                    obj = object.__finditem__(key);
-                }
-            } else {
-                obj = object.__finditem__(key);
-                if (obj == null) {
-                    obj = object.__findattr__(key);
-                }
-            }
-        } catch (PyException e) {
-            throw new TemplateModelException(e);
-        }
-
-        return wrapper.wrap(obj);
-    }
-    
-    /**
-     * Returns {@link PyObject#__len__()}<code> == 0</code>.
-     */
-    public boolean isEmpty() throws TemplateModelException {
-        try {
-            return object.__len__() == 0;
-        } catch (PyException e) {
-            throw new TemplateModelException(e);
-        }
-    }
-
-    /**
-     * @see freemarker.template.TemplateMethodModel#exec(List)
-     */
-    public Object exec(List arguments) throws TemplateModelException {
-        int size = arguments.size();
-        try {
-            switch(size)
-            {
-                case 0:
-                {
-                    return wrapper.wrap(object.__call__());
-                }
-                case 1:
-                {
-                    return wrapper.wrap(object.__call__(wrapper.unwrap(
-                        (TemplateModel) arguments.get(0))));
-                }
-                default:
-                {
-                    PyObject[] pyargs = new PyObject[size];
-                    int i = 0;
-                    for (Iterator arg = arguments.iterator(); arg.hasNext(); ) {
-                        pyargs[i++] = wrapper.unwrap(
-                            (TemplateModel) arg.next());
-                    }
-                    return wrapper.wrap(object.__call__(pyargs));
-                }
-            }
-        } catch (PyException e) {
-            throw new TemplateModelException(e);
-        }
-    }
-
-    public Object getAdaptedObject(Class hint) {
-        if (object == null) {
-            return null;
-        }
-        Object view = object.__tojava__(hint);
-        if (view == Py.NoConversion) {
-            view = object.__tojava__(Object.class);
-        }
-        return view;
-    }
-    
-    public Object getWrappedObject() {
-        return object == null ? null : object.__tojava__(Object.class);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1588a7f5/src/main/java/freemarker/ext/jython/JythonModelCache.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/jython/JythonModelCache.java b/src/main/java/freemarker/ext/jython/JythonModelCache.java
deleted file mode 100644
index 1ffaab3..0000000
--- a/src/main/java/freemarker/ext/jython/JythonModelCache.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- * 
- *   http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package freemarker.ext.jython;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-
-import org.python.core.Py;
-import org.python.core.PyDictionary;
-import org.python.core.PyFloat;
-import org.python.core.PyInteger;
-import org.python.core.PyLong;
-import org.python.core.PyNone;
-import org.python.core.PyObject;
-import org.python.core.PySequence;
-import org.python.core.PyStringMap;
-
-import freemarker.ext.beans.BeansWrapper;
-import freemarker.ext.beans.DateModel;
-import freemarker.ext.util.ModelCache;
-import freemarker.template.TemplateModel;
-
-class JythonModelCache extends ModelCache {
-    private final JythonWrapper wrapper;
-    
-    JythonModelCache(JythonWrapper wrapper) {
-        this.wrapper = wrapper;
-    }
-
-    @Override
-    protected boolean isCacheable(Object object) {
-        return true;
-    }
-    
-    @Override
-    protected TemplateModel create(Object obj) {
-        boolean asHash = false;
-        boolean asSequence = false;
-        JythonVersionAdapter versionAdapter = JythonVersionAdapterHolder.INSTANCE;
-        if (versionAdapter.isPyInstance(obj)) {
-            Object jobj = versionAdapter.pyInstanceToJava(obj);
-            // FreeMarker-aware, Jython-wrapped Java objects are left intact 
-            if (jobj instanceof TemplateModel) {
-                return (TemplateModel) jobj; 
-            }
-            if (jobj instanceof Map) {
-                asHash = true;
-            }
-            if (jobj instanceof Date) {
-                return new DateModel((Date) jobj, BeansWrapper.getDefaultInstance());
-            } else if (jobj instanceof Collection) {
-                asSequence = true;
-                // FIXME: This is an ugly hack, but AFAIK, there's no better
-                // solution if we want to have Sets and other non-List
-                // collections managed by this layer, as Jython quite clearly
-                // doesn't support sets.  
-                if (!(jobj instanceof List)) {
-                    obj = new ArrayList((Collection) jobj); 
-                }
-            }
-        }
-        
-        // If it's not a PyObject, first make a PyObject out of it.
-        if (!(obj instanceof PyObject)) {
-            obj = Py.java2py(obj);
-        }
-        if (asHash || obj instanceof PyDictionary || obj instanceof PyStringMap) {
-            return JythonHashModel.FACTORY.create(obj, wrapper);
-        }
-        if (asSequence || obj instanceof PySequence) {
-            return JythonSequenceModel.FACTORY.create(obj, wrapper);
-        }
-        if (obj instanceof PyInteger || obj instanceof PyLong || obj instanceof PyFloat) {
-            return JythonNumberModel.FACTORY.create(obj, wrapper);
-        }
-        if (obj instanceof PyNone) {
-            return null;
-        }
-        return JythonModel.FACTORY.create(obj, wrapper);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1588a7f5/src/main/java/freemarker/ext/jython/JythonNumberModel.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/jython/JythonNumberModel.java b/src/main/java/freemarker/ext/jython/JythonNumberModel.java
deleted file mode 100644
index 036447e..0000000
--- a/src/main/java/freemarker/ext/jython/JythonNumberModel.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- * 
- *   http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package freemarker.ext.jython;
-
-import org.python.core.Py;
-import org.python.core.PyException;
-import org.python.core.PyObject;
-
-import freemarker.ext.util.ModelFactory;
-import freemarker.template.ObjectWrapper;
-import freemarker.template.TemplateModel;
-import freemarker.template.TemplateModelException;
-import freemarker.template.TemplateNumberModel;
-
-/**
- * Model for Jython numeric objects ({@link org.python.core.PyInteger}, {@link org.python.core.PyLong},
- * {@link org.python.core.PyFloat}).
- */
-public class JythonNumberModel
-extends
-    JythonModel
-implements
-    TemplateNumberModel {
-    static final ModelFactory FACTORY =
-        new ModelFactory()
-        {
-            public TemplateModel create(Object object, ObjectWrapper wrapper) {
-                return new JythonNumberModel((PyObject) object, (JythonWrapper) wrapper);
-            }
-        };
-        
-    public JythonNumberModel(PyObject object, JythonWrapper wrapper) {
-        super(object, wrapper);
-    }
-
-    /**
-     * Returns either {@link PyObject#__tojava__(java.lang.Class)} with
-     * {@link java.lang.Number}.class as argument. If that fails, returns 
-     * {@link PyObject#__float__()}.
-     */
-    public Number getAsNumber() throws TemplateModelException {
-        try {
-            Object value = object.__tojava__(java.lang.Number.class);
-            if (value == null || value == Py.NoConversion) {
-                return Double.valueOf(object.__float__().getValue());
-            }
-            return (Number) value;
-        } catch (PyException e) {
-            throw new TemplateModelException(e);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1588a7f5/src/main/java/freemarker/ext/jython/JythonSequenceModel.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/jython/JythonSequenceModel.java b/src/main/java/freemarker/ext/jython/JythonSequenceModel.java
deleted file mode 100644
index 6614094..0000000
--- a/src/main/java/freemarker/ext/jython/JythonSequenceModel.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- * 
- *   http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package freemarker.ext.jython;
-
-import org.python.core.PyException;
-import org.python.core.PyObject;
-
-import freemarker.ext.util.ModelFactory;
-import freemarker.template.ObjectWrapper;
-import freemarker.template.TemplateCollectionModel;
-import freemarker.template.TemplateModel;
-import freemarker.template.TemplateModelException;
-import freemarker.template.TemplateModelIterator;
-import freemarker.template.TemplateSequenceModel;
-
-/**
- * Model for Jython sequence objects ({@link org.python.core.PySequence} descendants).
- */
-public class JythonSequenceModel
-extends
-    JythonModel
-implements 
-    TemplateSequenceModel,
-    TemplateCollectionModel {
-    static final ModelFactory FACTORY =
-        new ModelFactory()
-        {
-            public TemplateModel create(Object object, ObjectWrapper wrapper) {
-                return new JythonSequenceModel((PyObject) object, (JythonWrapper) wrapper);
-            }
-        };
-        
-    public JythonSequenceModel(PyObject object, JythonWrapper wrapper) {
-        super(object, wrapper);
-    }
-
-    /**
-     * Returns {@link PyObject#__finditem__(int)}.
-     */
-    public TemplateModel get(int index) throws TemplateModelException {
-        try {
-            return wrapper.wrap(object.__finditem__(index));
-        } catch (PyException e) {
-            throw new TemplateModelException(e);
-        }
-    }
-
-    /**
-     * Returns {@link PyObject#__len__()}.
-     */
-    public int size() throws TemplateModelException {
-        try {
-            return object.__len__();
-        } catch (PyException e) {
-            throw new TemplateModelException(e);
-        }
-    }
-
-    public TemplateModelIterator iterator() {
-        return new TemplateModelIterator()
-        {
-            int i = 0;
-            
-            public boolean hasNext() throws TemplateModelException {
-                return i < size();
-            }
-
-            public TemplateModel next() throws TemplateModelException {
-                return get(i++);
-            }
-        };
-    }
-}



Mime
View raw message