![JAR search and dependency download from the Maven repository](/logo.png)
freemarker.template.utility.DOMNodeModel 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.template.utility;
import java.util.HashMap;
import java.util.List;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import freemarker.template.SimpleHash;
import freemarker.template.SimpleScalar;
import freemarker.template.TemplateBooleanModel;
import freemarker.template.TemplateHashModel;
import freemarker.template.TemplateMethodModel;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;
import freemarker.template.TemplateSequenceModel;
/**
* A convenient wrapper class for wrapping a Node in the W3C DOM API.
*/
public class DOMNodeModel implements TemplateHashModel {
static private HashMap equivalenceTable = new HashMap();
static {
equivalenceTable.put("*", "children");
equivalenceTable.put("@*", "attributes");
}
private Node node;
private HashMap cache = new HashMap();
public DOMNodeModel(Node node) {
this.node = node;
}
public TemplateModel get(String key) throws TemplateModelException {
TemplateModel result = null;
if (equivalenceTable.containsKey(key)) {
key = (String) equivalenceTable.get(key);
}
if (cache.containsKey(key)) {
result = (TemplateModel) cache.get(key);
}
if (result == null) {
if ("attributes".equals(key)) {
NamedNodeMap attributes = node.getAttributes();
if (attributes != null) {
SimpleHash hash = new SimpleHash();
for (int i = 0; i < attributes.getLength(); i++) {
Attr att = (Attr) attributes.item(i);
hash.put(att.getName(), att.getValue());
}
result = hash;
}
} else if (key.charAt(0) == '@') {
if (node instanceof Element) {
String attValue = ((Element) node).getAttribute(key.substring(1));
result = new SimpleScalar(attValue);
} else {
throw new TemplateModelException("Trying to get an attribute value for a non-element node");
}
} else if ("is_element".equals(key)) {
result = (node instanceof Element) ?
TemplateBooleanModel.TRUE : TemplateBooleanModel.FALSE;
} else if ("is_text".equals(key)) {
result = (node instanceof Text) ?
TemplateBooleanModel.TRUE : TemplateBooleanModel.FALSE;
} else if ("name".equals(key)) {
result = new SimpleScalar(node.getNodeName());
} else if ("children".equals(key)) {
result = new NodeListTM(node.getChildNodes());
} else if ("parent".equals(key)) {
Node parent = node.getParentNode();
result = (parent == null) ? null : new DOMNodeModel(parent);
} else if ("ancestorByName".equals(key)) {
result = new AncestorByName();
} else if ("nextSibling".equals(key)) {
Node next = node.getNextSibling();
result = (next == null) ? null : new DOMNodeModel(next);
} else if ("previousSibling".equals(key)) {
Node previous = node.getPreviousSibling();
result = (previous == null) ? null : new DOMNodeModel(previous);
} else if ("nextSiblingElement".equals(key)) {
Node next = nextSiblingElement(node);
result = (next == null) ? null : new DOMNodeModel(next);
} else if ("previousSiblingElement".equals(key)) {
Node previous = previousSiblingElement(node);
result = (previous == null) ? null : new DOMNodeModel(previous);
} else if ("nextElement".equals(key)) {
Node next = nextElement(node);
result = (next == null) ? null : new DOMNodeModel(next);
} else if ("previousElement".equals(key)) {
Node previous = previousElement(node);
result = (previous == null) ? null : new DOMNodeModel(previous);
} else if ("text".equals(key)) {
result = new SimpleScalar(getText(node));
}
cache.put(key, result);
}
return result;
}
public boolean isEmpty() {
return false;
}
static private String getText(Node node) {
String result = "";
if (node instanceof Text) {
result = ((Text) node).getData();
} else if (node instanceof Element) {
NodeList children = node.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
result += getText(children.item(i));
}
}
return result;
}
static private Element nextSiblingElement(Node node) {
Node next = node;
while (next != null) {
next = next.getNextSibling();
if (next instanceof Element) {
return (Element) next;
}
}
return null;
}
static private Element previousSiblingElement(Node node) {
Node previous = node;
while (previous != null) {
previous = previous.getPreviousSibling();
if (previous instanceof Element) {
return (Element) previous;
}
}
return null;
}
static private Element nextElement(Node node) {
if (node.hasChildNodes()) {
NodeList children = node.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
Node child = children.item(i);
if (child instanceof Element) {
return (Element) child;
}
}
}
Element nextSiblingElement = nextSiblingElement(node);
if (nextSiblingElement != null) {
return nextSiblingElement;
}
Node parent = node.getParentNode();
while (parent instanceof Element) {
Element next = nextSiblingElement(parent);
if (next != null) {
return next;
}
parent = parent.getParentNode();
}
return null;
}
static private Element previousElement(Node node) {
Element result = previousSiblingElement(node);
if (result != null) {
return result;
}
Node parent = node.getParentNode();
if (parent instanceof Element) {
return (Element) parent;
}
return null;
}
void setParent(DOMNodeModel parent) {
if (parent != null) {
cache.put("parent", parent);
}
}
String getNodeName() {
return node.getNodeName();
}
class AncestorByName implements TemplateMethodModel {
public Object exec(List arguments) throws TemplateModelException {
if (arguments.size() != 1) {
throw new TemplateModelException("Expecting exactly one string argument here");
}
String nodeName = (String) arguments.get(0);
DOMNodeModel ancestor = (DOMNodeModel) DOMNodeModel.this.get("parent");
while (ancestor != null) {
if (nodeName.equals(ancestor.getNodeName())) {
return ancestor;
}
ancestor = (DOMNodeModel) ancestor.get("parent");
}
return null;
}
}
class NodeListTM implements TemplateSequenceModel, TemplateMethodModel {
private NodeList nodeList;
private TemplateModel[] nodes;
NodeListTM(NodeList nodeList) {
this.nodeList = nodeList;
nodes = new TemplateModel[nodeList.getLength()];
}
public TemplateModel get(int index) {
DOMNodeModel result = (DOMNodeModel) nodes[index];
if (result == null) {
result = new DOMNodeModel(nodeList.item(index));
nodes[index] = result;
result.setParent(DOMNodeModel.this);
}
return result;
}
public int size() {
return nodes.length;
}
public Object exec(List arguments) throws TemplateModelException {
if (arguments.size() != 1) {
throw new TemplateModelException("Expecting exactly one string argument here");
}
if (!(node instanceof Element)) {
throw new TemplateModelException("Expecting element here.");
}
Element elem = (Element) node;
return new NodeListTM(elem.getElementsByTagName((String) arguments.get(0)));
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy