View Javadoc

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!]]>&gt;&entity;&lt;</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  		// TODO Figure out how to trigger this.
76  		// visited = rule.visitedNodes.get("Entity");
77  		// assertEquals(0, visited.size());
78  
79  		visited = rule.visitedNodes.get("EntityReference");
80  		assertEquals(1, visited.size());
81  		assertEquals("entity", ((EntityReference) visited.get(0)).getNodeName());
82  
83  		// TODO Figure out how to trigger this.
84  		// visited = rule.visitedNodes.get("Notation");
85  		// assertEquals(0, visited.size());
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 		// no exception should be thrown
113 
114 		MyRule rule = new MyRule();
115 		List<XmlNode> nodes = new ArrayList<XmlNode>();
116 		nodes.add(xmlNode);
117 		rule.apply(nodes, null);
118 				
119 		// first element is still parsed
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 		// no exception should be thrown
137 		// first element is still parsed
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 }