freemarker.ext.xml.Navigator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of freemarker Show documentation
Show all versions of freemarker Show documentation
FreeMarker is a "template engine"; a generic tool to generate text output based on templates.
/*
* 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.xml;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
import org.jaxen.NamespaceContext;
import freemarker.template.TemplateModelException;
/**
*/
abstract class Navigator {
// Cache of already parsed XPath expressions
private final Map xpathCache = new WeakHashMap();
// Operators this navigator defines
private final Map operators = createOperatorMap();
private final NodeOperator attributeOperator = getOperator("_attributes");
private final NodeOperator childrenOperator = getOperator("_children");
NodeOperator getOperator(String key) {
return (NodeOperator) operators.get(key);
}
NodeOperator getAttributeOperator() {
return attributeOperator;
}
NodeOperator getChildrenOperator() {
return childrenOperator;
}
abstract void getAsString(Object node, StringWriter sw)
throws TemplateModelException;
List applyXPath(List nodes, String xpathString, Object namespaces)
throws TemplateModelException {
XPathEx xpath = null;
try {
synchronized (xpathCache) {
xpath = (XPathEx) xpathCache.get(xpathString);
if (xpath == null) {
xpath = createXPathEx(xpathString);
xpathCache.put(xpathString, xpath);
}
}
return xpath.selectNodes(nodes, (NamespaceContext) namespaces);
} catch (Exception e) {
throw new TemplateModelException("Could not evaulate XPath expression " + xpathString, e);
}
}
interface XPathEx {
List selectNodes(Object nodes, NamespaceContext namespaces) throws TemplateModelException;
}
abstract XPathEx createXPathEx(String xpathString) throws TemplateModelException;
abstract void getChildren(Object node, String localName, String namespaceUri, List result);
abstract void getAttributes(Object node, String localName, String namespaceUri, List result);
abstract void getDescendants(Object node, List result);
abstract Object getParent(Object node);
abstract Object getDocument(Object node);
abstract Object getDocumentType(Object node);
private void getAncestors(Object node, List result) {
for (; ; ) {
Object parent = getParent(node);
if (parent == null) {
break;
}
result.add(parent);
node = parent;
}
}
abstract void getContent(Object node, List result);
abstract String getText(Object node);
abstract String getLocalName(Object node);
abstract String getNamespacePrefix(Object node);
String getQualifiedName(Object node) {
String lname = getLocalName(node);
if (lname == null) {
return null;
}
String nsprefix = getNamespacePrefix(node);
if (nsprefix == null || nsprefix.length() == 0) {
return lname;
} else {
return nsprefix + ":" + lname;
}
}
abstract String getType(Object node);
abstract String getNamespaceUri(Object node);
boolean equal(String s1, String s2) {
return s1 == null ? s2 == null : s1.equals(s2);
}
private Map createOperatorMap() {
Map map = new HashMap();
map.put("_attributes", new AttributesOp());
map.put("@*", map.get("_attributes"));
map.put("_children", new ChildrenOp());
map.put("*", map.get("_children"));
map.put("_descendantOrSelf", new DescendantOrSelfOp());
map.put("_descendant", new DescendantOp());
map.put("_document", new DocumentOp());
map.put("_doctype", new DocumentTypeOp());
map.put("_ancestor", new AncestorOp());
map.put("_ancestorOrSelf", new AncestorOrSelfOp());
map.put("_content", new ContentOp());
map.put("_name", new LocalNameOp());
map.put("_nsprefix", new NamespacePrefixOp());
map.put("_nsuri", new NamespaceUriOp());
map.put("_parent", new ParentOp());
map.put("_qname", new QualifiedNameOp());
map.put("_text", new TextOp());
map.put("_type", new TypeOp());
return map;
}
private class ChildrenOp implements NodeOperator {
public void process(Object node, String localName, String namespaceUri, List result) {
getChildren(node, localName, namespaceUri, result);
}
}
private class AttributesOp implements NodeOperator {
public void process(Object node, String localName, String namespaceUri, List result) {
getAttributes(node, localName, namespaceUri, result);
}
}
private class DescendantOrSelfOp implements NodeOperator {
public void process(Object node, String localName, String namespaceUri, List result) {
result.add(node);
getDescendants(node, result);
}
}
private class DescendantOp implements NodeOperator {
public void process(Object node, String localName, String namespaceUri, List result) {
getDescendants(node, result);
}
}
private class AncestorOrSelfOp implements NodeOperator {
public void process(Object node, String localName, String namespaceUri, List result) {
result.add(node);
getAncestors(node, result);
}
}
private class AncestorOp implements NodeOperator {
public void process(Object node, String localName, String namespaceUri, List result) {
getAncestors(node, result);
}
}
private class ParentOp implements NodeOperator {
public void process(Object node, String localName, String namespaceUri, List result) {
Object parent = getParent(node);
if (parent != null) {
result.add(parent);
}
}
}
private class DocumentOp implements NodeOperator {
public void process(Object node, String localName, String namespaceUri, List result) {
Object document = getDocument(node);
if (document != null) {
result.add(document);
}
}
}
private class DocumentTypeOp implements NodeOperator {
public void process(Object node, String localName, String namespaceUri, List result) {
Object documentType = getDocumentType(node);
if (documentType != null) {
result.add(documentType);
}
}
}
private class ContentOp implements NodeOperator {
public void process(Object node, String localName, String namespaceUri, List result) {
getContent(node, result);
}
}
private class TextOp implements NodeOperator {
public void process(Object node, String localName, String namespaceUri, List result) {
String text = getText(node);
if (text != null) {
result.add(text);
}
}
}
private class LocalNameOp implements NodeOperator {
public void process(Object node, String localName, String namespaceUri, List result) {
String text = getLocalName(node);
if (text != null) {
result.add(text);
}
}
}
private class QualifiedNameOp implements NodeOperator {
public void process(Object node, String localName, String namespaceUri, List result) {
String qname = getQualifiedName(node);
if (qname != null) {
result.add(qname);
}
}
}
private class NamespacePrefixOp implements NodeOperator {
public void process(Object node, String localName, String namespaceUri, List result) {
String text = getNamespacePrefix(node);
if (text != null) {
result.add(text);
}
}
}
private class NamespaceUriOp implements NodeOperator {
public void process(Object node, String localName, String namespaceUri, List result) {
String text = getNamespaceUri(node);
if (text != null) {
result.add(text);
}
}
}
private class TypeOp implements NodeOperator {
public void process(Object node, String localName, String namespaceUri, List result) {
result.add(getType(node));
}
}
}