1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.xmlfield.core.impl.dom;
17
18 import static com.google.common.base.Preconditions.checkArgument;
19 import static com.google.common.base.Preconditions.checkNotNull;
20 import static org.apache.commons.lang.StringUtils.substringAfter;
21
22 import org.apache.commons.lang.StringUtils;
23 import org.w3c.dom.Attr;
24 import org.w3c.dom.Document;
25 import org.w3c.dom.Element;
26 import org.w3c.dom.NamedNodeMap;
27 import org.w3c.dom.Node;
28 import org.xmlfield.core.api.XmlFieldNode;
29 import org.xmlfield.core.api.XmlFieldNodeList;
30 import org.xmlfield.core.api.XmlFieldNodeModifier;
31 import org.xmlfield.core.impl.dom.cleanup.InputSanitizer;
32 import org.xmlfield.core.internal.NamespaceMap;
33 import org.xmlfield.core.internal.XPathUtils;
34
35
36
37
38
39
40
41
42
43 public class DomNodeModifier implements XmlFieldNodeModifier {
44
45 private static Element _createElement(final NamespaceMap namespaces,
46 final Document document, final String elementName) {
47
48 String prefix = XPathUtils.getElementPrefix(elementName);
49
50 if (prefix == null) {
51 return document.createElement(elementName);
52 }
53
54 if (namespaces == null) {
55 throw new IllegalArgumentException("No namespaceURI defined for <"
56 + elementName + ">");
57 }
58
59 String uri = namespaces.get(prefix);
60
61 if (uri == null) {
62 throw new IllegalArgumentException("No namespaceURI defined for <"
63 + elementName + ">");
64 }
65
66 String localName = substringAfter(elementName, ":");
67
68 return document.createElementNS(uri, localName);
69
70 }
71
72 @Override
73 public void createAttribute(XmlFieldNode node, String attributeName,
74 String textContent) {
75 checkNotNull(node, "node");
76 checkNotNull(attributeName, "attributeName");
77 final Document document = getNodeDocument((Node) node.getNode());
78
79 final Attr attribute = document.createAttribute(attributeName);
80
81 ((Element) node.getNode()).setAttributeNode(attribute);
82
83 if (textContent != null) {
84
85 attribute.setTextContent(InputSanitizer.sanitizeText(textContent));
86 }
87
88 }
89
90 @Override
91 public XmlFieldNode createElement(NamespaceMap namespaces,
92 XmlFieldNode node, String elementName) {
93 return createElement(namespaces, node, elementName, null);
94 }
95
96 @Override
97 public XmlFieldNode createElement(NamespaceMap namespaces,
98 XmlFieldNode node, String elementName, String textContent) {
99 checkNotNull(node, "node");
100 checkArgument(node.getNode() instanceof Node);
101 if (StringUtils.isEmpty(elementName)) {
102 return node;
103 }
104
105 final Document document = getNodeDocument((Node) node.getNode());
106
107 final Element element = _createElement(namespaces, document,
108 elementName);
109
110 ((Node) node.getNode()).appendChild(element);
111
112 if (textContent != null) {
113
114 element.appendChild(document.createTextNode(InputSanitizer
115 .sanitizeText(textContent)));
116 }
117
118 return new DomNode(element);
119 }
120
121 private Document getNodeDocument(final Node node) {
122
123 checkNotNull(node, "node");
124
125 for (Node n = node; n != null; n = n.getParentNode()) {
126
127 if (Document.class.isInstance(n)) {
128
129 return (Document) n;
130 }
131 }
132
133 throw new IllegalArgumentException("Node has no Document ancestor.");
134 }
135
136 @Override
137 public XmlFieldNode insertBefore(XmlFieldNode contextNode,
138 XmlFieldNode newChild, XmlFieldNode refChild) {
139 checkNotNull(contextNode, "contextNode");
140 checkNotNull(newChild, "newChild");
141 checkNotNull(refChild, "refChild");
142 Node insertedNode = ((Node) contextNode.getNode()).insertBefore(
143 (Node) newChild.getNode(), (Node) refChild.getNode());
144 return new DomNode(insertedNode);
145 }
146
147 @Override
148 public XmlFieldNode removeAttribute(XmlFieldNode node, String attributeName) {
149 checkNotNull(node, "node");
150 checkNotNull(attributeName, "attributeName");
151 NamedNodeMap nnMap = ((Node) node.getNode()).getAttributes();
152 if (nnMap.getNamedItem(attributeName) == null) {
153 return null;
154 }
155 return new DomNode(nnMap.removeNamedItem(attributeName));
156 }
157
158 @Override
159 public XmlFieldNode removeChild(XmlFieldNode node, XmlFieldNode oldChild) {
160 checkNotNull(node, "node");
161 checkNotNull(oldChild, "oldChild");
162 Node removedNode = ((Node) node.getNode()).removeChild((Node) oldChild
163 .getNode());
164 if (removedNode != null) {
165 return oldChild;
166 }
167 return null;
168 }
169
170 @Override
171 public void removeChildren(final XmlFieldNodeList nodesToRemove) {
172 checkNotNull(nodesToRemove, "nodesToRemove");
173 for (int i = nodesToRemove.getLength() - 1; i >= 0; i--) {
174 final Node currentNode = (Node) nodesToRemove.item(i).getNode();
175 currentNode.getParentNode().removeChild(currentNode);
176 }
177 }
178 }