/*
* 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.
IOException;
import java.io.
StringWriter;
import java.util.
Iterator;
import java.util.
List;
import org.jaxen.
Context;
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.
TemplateModelException;
/**
* 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.
*/
public class
_JdomNavigator extends
Navigator {
private static final
XMLOutputter OUTPUT = new
XMLOutputter();
public
_JdomNavigator() {
}
@
Override
void
getAsString(
Object node,
StringWriter sw)
throws
TemplateModelException {
try {
if (
node instanceof
Element) {
OUTPUT.
output((
Element)
node,
sw);
} else if (
node instanceof
Attribute) {
Attribute attribute = (
Attribute)
node;
sw.
write(" ");
sw.
write(
attribute.
getQualifiedName());
sw.
write("=\"");
sw.
write(
OUTPUT.
escapeAttributeEntities(
attribute.
getValue()));
sw.
write("\"");
} 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);
}
}
@
Override
void
getChildren(
Object node,
String localName,
String namespaceUri,
List result) {
if (
node instanceof
Element) {
Element e = (
Element)
node;
if (
localName == null) {
result.
addAll(
e.
getChildren());
} else {
result.
addAll(
e.
getChildren(
localName,
Namespace.
getNamespace("",
namespaceUri)));
}
} else if (
node instanceof
Document) {
Element root = ((
Document)
node).
getRootElement();
if (
localName == null || (
equal(
root.
getName(),
localName) &&
equal(
root.
getNamespaceURI(),
namespaceUri))) {
result.
add(
root);
}
}
}
@
Override
void
getAttributes(
Object node,
String localName,
String namespaceUri,
List result) {
if (
node instanceof
Element) {
Element e = (
Element)
node;
if (
localName == null) {
result.
addAll(
e.
getAttributes());
} else {
Attribute attr =
e.
getAttribute(
localName,
Namespace.
getNamespace("",
namespaceUri));
if (
attr != null) {
result.
add(
attr);
}
}
} else if (
node instanceof
ProcessingInstruction) {
ProcessingInstruction pi = (
ProcessingInstruction)
node;
if ("target".
equals(
localName)) {
result.
add(new
Attribute("target",
pi.
getTarget()));
} else if ("data".
equals(
localName)) {
result.
add(new
Attribute("data",
pi.
getData()));
} else {
result.
add(new
Attribute(
localName,
pi.
getValue(
localName)));
}
} else if (
node instanceof
DocType) {
DocType doctype = (
DocType)
node;
if ("publicId".
equals(
localName)) {
result.
add(new
Attribute("publicId",
doctype.
getPublicID()));
} else if ("systemId".
equals(
localName)) {
result.
add(new
Attribute("systemId",
doctype.
getSystemID()));
} else if ("elementName".
equals(
localName)) {
result.
add(new
Attribute("elementName",
doctype.
getElementName()));
}
}
}
@
Override
void
getDescendants(
Object node,
List result) {
if (
node instanceof
Document) {
Element root = ((
Document)
node).
getRootElement();
result.
add(
root);
getDescendants(
root,
result);
} else if (
node instanceof
Element) {
getDescendants((
Element)
node,
result);
}
}
private void getDescendants(
Element node,
List result) {
for (
Iterator iter =
node.
getChildren().
iterator();
iter.
hasNext(); ) {
Element subnode = (
Element)
iter.
next();
result.
add(
subnode);
getDescendants(
subnode,
result);
}
}
@
Override
Object getParent(
Object node) {
if (
node instanceof
Element) {
return((
Element)
node).
getParent();
}
if (
node instanceof
Attribute) {
return((
Attribute)
node).
getParent();
}
if (
node instanceof
Text) {
return((
Text)
node).
getParent();
}
if (
node instanceof
ProcessingInstruction) {
return((
ProcessingInstruction)
node).
getParent();
}
if (
node instanceof
Comment) {
return((
Comment)
node).
getParent();
}
if (
node instanceof
EntityRef) {
return((
EntityRef)
node).
getParent();
}
return null;
}
@
Override
Object getDocument(
Object node) {
if (
node instanceof
Element) {
return ((
Element)
node).
getDocument();
} else if (
node instanceof
Attribute) {
Element parent = ((
Attribute)
node).
getParent();
return
parent == null ? null :
parent.
getDocument();
} else if (
node instanceof
Text) {
Element parent = ((
Text)
node).
getParent();
return
parent == null ? null :
parent.
getDocument();
} else if (
node instanceof
Document)
return
node;
else if (
node instanceof
ProcessingInstruction) {
return ((
ProcessingInstruction)
node).
getDocument();
} else if (
node instanceof
EntityRef) {
return ((
EntityRef)
node).
getDocument();
} else if (
node instanceof
Comment) {
return ((
Comment)
node).
getDocument();
}
return null;
}
@
Override
Object getDocumentType(
Object node) {
return
node instanceof
Document
? ((
Document)
node).
getDocType()
: null;
}
@
Override
void
getContent(
Object node,
List result) {
if (
node instanceof
Element)
result.
addAll(((
Element)
node).
getContent());
else if (
node instanceof
Document)
result.
addAll(((
Document)
node).
getContent());
}
@
Override
String getText(
Object node) {
if (
node instanceof
Element) {
return ((
Element)
node).
getTextTrim();
}
if (
node instanceof
Attribute) {
return ((
Attribute)
node).
getValue();
}
if (
node instanceof
CDATA) {
return ((
CDATA)
node).
getText();
}
if (
node instanceof
Comment) {
return ((
Comment)
node).
getText();
}
if (
node instanceof
ProcessingInstruction) {
return ((
ProcessingInstruction)
node).
getData();
}
return null;
}
@
Override
String getLocalName(
Object node) {
if (
node instanceof
Element) {
return ((
Element)
node).
getName();
}
if (
node instanceof
Attribute) {
return ((
Attribute)
node).
getName();
}
if (
node instanceof
EntityRef) {
return ((
EntityRef)
node).
getName();
}
if (
node instanceof
ProcessingInstruction) {
return ((
ProcessingInstruction)
node).
getTarget();
}
if (
node instanceof
DocType) {
return ((
DocType)
node).
getElementName();
}
return null;
}
@
Override
String getNamespacePrefix(
Object node) {
if (
node instanceof
Element) {
return ((
Element)
node).
getNamespacePrefix();
}
if (
node instanceof
Attribute) {
return ((
Attribute)
node).
getNamespacePrefix();
}
return null;
}
@
Override
String getNamespaceUri(
Object node) {
if (
node instanceof
Element) {
return ((
Element)
node).
getNamespaceURI();
}
if (
node instanceof
Attribute) {
return ((
Attribute)
node).
getNamespaceURI();
}
return null;
}
@
Override
String getType(
Object node) {
if (
node instanceof
Attribute) {
return "attribute";
}
if (
node instanceof
CDATA) {
return "cdata";
}
if (
node instanceof
Comment) {
return "comment";
}
if (
node instanceof
Document) {
return "document";
}
if (
node instanceof
DocType) {
return "documentType";
}
if (
node instanceof
Element) {
return "element";
}
if (
node instanceof
EntityRef) {
return "entityReference";
}
if (
node instanceof
Namespace) {
return "namespace";
}
if (
node instanceof
ProcessingInstruction) {
return "processingInstruction";
}
if (
node instanceof
Text) {
return "text";
}
return "unknown";
}
@
Override
XPathEx createXPathEx(
String xpathString) throws
TemplateModelException {
try {
return new
JDOMXPathEx(
xpathString);
} catch (
Exception e) {
throw new
TemplateModelException(
e);
}
}
private static final class
JDOMXPathEx
extends
JDOMXPath
implements
XPathEx {
JDOMXPathEx(
String path)
throws
Exception {
super(
path);
}
public
List selectNodes(
Object object,
NamespaceContext namespaces)
throws
TemplateModelException {
Context context =
getContext(
object);
context.
getContextSupport().
setNamespaceContext(
namespaces);
try {
return
selectNodesForContext(
context);
} catch (
Exception e) {
throw new
TemplateModelException(
e);
}
}
}
}