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 }