1 package net.sourceforge.pmd.lang.xml.rule;
2
3 import static org.junit.Assert.assertEquals;
4 import static org.junit.Assert.assertNotNull;
5 import static org.junit.Assert.assertTrue;
6 import static org.junit.Assert.fail;
7
8 import java.io.StringReader;
9 import java.util.ArrayList;
10 import java.util.HashMap;
11 import java.util.List;
12 import java.util.Map;
13
14 import net.sourceforge.pmd.RuleContext;
15 import net.sourceforge.pmd.lang.Language;
16 import net.sourceforge.pmd.lang.Parser;
17 import net.sourceforge.pmd.lang.ast.Node;
18 import net.sourceforge.pmd.lang.xml.XmlParserOptions;
19 import net.sourceforge.pmd.lang.xml.ast.XmlNode;
20 import net.sourceforge.pmd.lang.xml.rule.AbstractDomXmlRule;
21
22 import org.jaxen.JaxenException;
23 import org.junit.Test;
24 import org.w3c.dom.Attr;
25 import org.w3c.dom.CharacterData;
26 import org.w3c.dom.Comment;
27 import org.w3c.dom.Document;
28 import org.w3c.dom.DocumentType;
29 import org.w3c.dom.Element;
30 import org.w3c.dom.Entity;
31 import org.w3c.dom.EntityReference;
32 import org.w3c.dom.Notation;
33 import org.w3c.dom.ProcessingInstruction;
34 import org.w3c.dom.Text;
35
36 public class AbstractDomXmlRuleTest {
37
38 @Test
39 public void testVisit() throws Exception {
40 String source = "<?xml version=\"1.0\"?><?mypi?><!DOCTYPE testDoc [<!ENTITY entity \"e\">]><!--Comment--><foo abc=\"abc\"><bar>TEXT</bar><![CDATA[cdata!]]>>&entity;<</foo>";
41 XmlParserOptions parserOptions = new XmlParserOptions();
42 parserOptions.setExpandEntityReferences(false);
43 Parser parser = Language.XML.getDefaultVersion()
44 .getLanguageVersionHandler().getParser(parserOptions);
45 XmlNode xmlNode = (XmlNode) parser
46 .parse(null, new StringReader(source));
47 List<XmlNode> nodes = new ArrayList<XmlNode>();
48 nodes.add(xmlNode);
49
50 MyRule rule = new MyRule();
51 rule.apply(nodes, null);
52
53 List<org.w3c.dom.Node> visited = rule.visitedNodes.get("Attr");
54 assertEquals(1, visited.size());
55 assertEquals("abc", visited.get(0).getLocalName());
56
57 visited = rule.visitedNodes.get("CharacterData");
58 assertEquals(1, visited.size());
59 assertEquals("cdata!", ((CharacterData) visited.get(0)).getData());
60
61 visited = rule.visitedNodes.get("Comment");
62 assertEquals("Comment", ((Comment) visited.get(0)).getData());
63
64 visited = rule.visitedNodes.get("Document");
65 assertEquals(1, visited.size());
66
67 visited = rule.visitedNodes.get("DocumentType");
68 assertEquals("testDoc", ((DocumentType) visited.get(0)).getName());
69
70 visited = rule.visitedNodes.get("Element");
71 assertEquals(2, visited.size());
72 assertEquals("foo", visited.get(0).getLocalName());
73 assertEquals("bar", visited.get(1).getLocalName());
74
75
76
77
78
79 visited = rule.visitedNodes.get("EntityReference");
80 assertEquals(1, visited.size());
81 assertEquals("entity", ((EntityReference) visited.get(0)).getNodeName());
82
83
84
85
86
87 visited = rule.visitedNodes.get("ProcessingInstruction");
88 assertEquals(1, visited.size());
89 assertEquals("mypi",
90 ((ProcessingInstruction) visited.get(0)).getTarget());
91
92 visited = rule.visitedNodes.get("Text");
93 assertEquals(4, visited.size());
94 assertEquals("TEXT", ((Text) visited.get(0)).getData());
95 assertEquals(">", ((Text) visited.get(1)).getData());
96 assertEquals("e", ((Text) visited.get(2)).getData());
97 assertEquals("<", ((Text) visited.get(3)).getData());
98 }
99
100 @Test
101 public void dtdIsNotLookedUp() {
102 String source = "<!DOCTYPE struts-config PUBLIC "
103 + " \"-//Apache Software Foundation//DTD Struts Configuration 1.1//EN \" "
104 + " \"http://jakarta.inexistinghost.org/struts/dtds/struts-config_1_1.dtd\" >"
105 + "<struts-config/>";
106 XmlParserOptions parserOptions = new XmlParserOptions();
107 parserOptions.setLookupDescriptorDoc(false);
108 Parser parser = Language.XML.getDefaultVersion()
109 .getLanguageVersionHandler().getParser(parserOptions);
110 XmlNode xmlNode = (XmlNode) parser
111 .parse(null, new StringReader(source));
112
113
114 MyRule rule = new MyRule();
115 List<XmlNode> nodes = new ArrayList<XmlNode>();
116 nodes.add(xmlNode);
117 rule.apply(nodes, null);
118
119
120 assertNotNull(rule.visitedNodes.get("Element"));
121
122 }
123
124 @Test
125 public void xsdIsNotLookedUp() {
126 String source = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> "
127 + "<web-app xmlns=\"http://java.sun.com/xml/ns/javaee\" "
128 + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
129 + "xsi:schemaLocation=\"http://java.sun.com/xml/ns/javaee http://java.inexisting.com/xml/ns/javaee/web-app_2_5.xsd\" "
130 + "version=\"2.5\">" + "</web-app>";
131 XmlParserOptions parserOptions = new XmlParserOptions();
132 Parser parser = Language.XML.getDefaultVersion()
133 .getLanguageVersionHandler().getParser(parserOptions);
134 XmlNode xmlNode = (XmlNode) parser
135 .parse(null, new StringReader(source));
136
137
138 MyRule rule = new MyRule();
139 List<XmlNode> nodes = new ArrayList<XmlNode>();
140 nodes.add(xmlNode);
141 rule.apply(nodes, null);
142
143 assertNotNull(rule.visitedNodes.get("Element"));
144
145 }
146
147 private static class MyRule extends AbstractDomXmlRule {
148 final Map<String, List<org.w3c.dom.Node>> visitedNodes = new HashMap<String, List<org.w3c.dom.Node>>();
149
150 public MyRule() {
151
152 }
153
154 private void visit(String key, org.w3c.dom.Node node) {
155 List<org.w3c.dom.Node> nodes = visitedNodes.get(key);
156 if (nodes == null) {
157 nodes = new ArrayList<org.w3c.dom.Node>();
158 visitedNodes.put(key, nodes);
159 }
160 nodes.add(node);
161 }
162
163 @Override
164 public void apply(List<? extends Node> nodes, RuleContext ctx) {
165 super.apply(nodes, ctx);
166 }
167
168 @Override
169 protected void visit(XmlNode node, Attr attr, RuleContext ctx) {
170 visit("Attr", attr);
171 super.visit(node, attr, ctx);
172 }
173
174 @Override
175 protected void visit(XmlNode node, CharacterData characterData,
176 RuleContext ctx) {
177 visit("CharacterData", characterData);
178 super.visit(node, characterData, ctx);
179 }
180
181 @Override
182 protected void visit(XmlNode node, Comment comment, RuleContext ctx) {
183 visit("Comment", comment);
184 super.visit(node, comment, ctx);
185 }
186
187 @Override
188 protected void visit(XmlNode node, Document document, RuleContext ctx) {
189 visit("Document", document);
190 super.visit(node, document, ctx);
191 }
192
193 @Override
194 protected void visit(XmlNode node, DocumentType documentType,
195 RuleContext ctx) {
196 visit("DocumentType", documentType);
197 super.visit(node, documentType, ctx);
198 }
199
200 @Override
201 protected void visit(XmlNode node, Element element, RuleContext ctx) {
202 visit("Element", element);
203 super.visit(node, element, ctx);
204 }
205
206 @Override
207 protected void visit(XmlNode node, Entity entity, RuleContext ctx) {
208 visit("Entity", entity);
209 super.visit(node, entity, ctx);
210 }
211
212 @Override
213 protected void visit(XmlNode node, EntityReference entityReference,
214 RuleContext ctx) {
215 visit("EntityReference", entityReference);
216 super.visit(node, entityReference, ctx);
217 }
218
219 @Override
220 protected void visit(XmlNode node, Notation notation, RuleContext ctx) {
221 visit("Notation", notation);
222 super.visit(node, notation, ctx);
223 }
224
225 @Override
226 protected void visit(XmlNode node,
227 ProcessingInstruction processingInstruction, RuleContext ctx) {
228 visit("ProcessingInstruction", processingInstruction);
229 super.visit(node, processingInstruction, ctx);
230 }
231
232 @Override
233 protected void visit(XmlNode node, Text text, RuleContext ctx) {
234 visit("Text", text);
235 super.visit(node, text, ctx);
236 }
237 }
238
239 public static junit.framework.Test suite() {
240 return new junit.framework.JUnit4TestAdapter(
241 AbstractDomXmlRuleTest.class);
242 }
243 }