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