1 /*
2  * Copyright 2002-2007 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package org.springframework.web.servlet.view.xslt;
18 
19 import java.io.IOException;
20 import java.io.InputStreamReader;
21 import java.io.StringReader;
22 import java.util.HashMap;
23 import java.util.List;
24 import java.util.Map;
25 import javax.xml.parsers.DocumentBuilder;
26 import javax.xml.parsers.DocumentBuilderFactory;
27 import javax.xml.parsers.ParserConfigurationException;
28 import javax.xml.transform.Source;
29 import javax.xml.transform.stream.StreamSource;
30 
31 import org.dom4j.Document;
32 import org.dom4j.Element;
33 import org.dom4j.io.SAXReader;
34 import static org.junit.Assert.assertEquals;
35 import static org.junit.Assert.assertTrue;
36 import org.junit.Before;
37 import org.junit.Test;
38 import org.xml.sax.SAXException;
39 
40 import org.springframework.context.support.StaticApplicationContext;
41 import org.springframework.core.JdkVersion;
42 import org.springframework.core.io.ClassPathResource;
43 import org.springframework.core.io.Resource;
44 import org.springframework.mock.web.MockHttpServletRequest;
45 import org.springframework.mock.web.MockHttpServletResponse;
46 
47 /**
48  * @author Rob Harrop
49  * @author Juergen Hoeller
50  */
51 public class XsltViewTests {
52 
53 	private static final String HTML_OUTPUT = "/org/springframework/web/servlet/view/xslt/products.xsl";
54 
55 	private MockHttpServletRequest request;
56 
57 	private MockHttpServletResponse response;
58 
59 	@Before
setUp()60 	public void setUp() throws Exception {
61 		this.request = new MockHttpServletRequest();
62 		this.response = new MockHttpServletResponse();
63 	}
64 
65 	@Test(expected = IllegalArgumentException.class)
withNoSource()66 	public void withNoSource() throws Exception {
67 		final XsltView view = getXsltView(HTML_OUTPUT);
68 		view.render(new HashMap(), request, response);
69 	}
70 
71 	@Test(expected = IllegalArgumentException.class)
withoutUrl()72 	public void withoutUrl() throws Exception {
73 		final XsltView view = new XsltView();
74 		view.afterPropertiesSet();
75 	}
76 
77 	@Test
simpleTransformWithSource()78 	public void simpleTransformWithSource() throws Exception {
79 		Source source = new StreamSource(getProductDataResource().getInputStream());
80 		Map model = new HashMap();
81 		model.put("someKey", source);
82 		doTestWithModel(model);
83 	}
84 
85 	@Test
testSimpleTransformWithDocument()86 	public void testSimpleTransformWithDocument() throws Exception {
87 		org.w3c.dom.Document document = getDomDocument();
88 		Map model = new HashMap();
89 		model.put("someKey", document);
90 		doTestWithModel(model);
91 	}
92 
93 	@Test
testSimpleTransformWithNode()94 	public void testSimpleTransformWithNode() throws Exception {
95 		org.w3c.dom.Document document = getDomDocument();
96 		Map model = new HashMap();
97 		model.put("someKey", document.getDocumentElement());
98 		doTestWithModel(model);
99 	}
100 
101 	@Test
testSimpleTransformWithInputStream()102 	public void testSimpleTransformWithInputStream() throws Exception {
103 		Map model = new HashMap();
104 		model.put("someKey", getProductDataResource().getInputStream());
105 		doTestWithModel(model);
106 	}
107 
108 	@Test
testSimpleTransformWithReader()109 	public void testSimpleTransformWithReader() throws Exception {
110 		Map model = new HashMap();
111 		model.put("someKey", new InputStreamReader(getProductDataResource().getInputStream()));
112 		doTestWithModel(model);
113 	}
114 
115 	@Test
testSimpleTransformWithResource()116 	public void testSimpleTransformWithResource() throws Exception {
117 		Map model = new HashMap();
118 		model.put("someKey", getProductDataResource());
119 		doTestWithModel(model);
120 	}
121 
122 	@Test
testWithSourceKey()123 	public void testWithSourceKey() throws Exception {
124 		XsltView view = getXsltView(HTML_OUTPUT);
125 		view.setSourceKey("actualData");
126 
127 		Map model = new HashMap();
128 		model.put("actualData", getProductDataResource());
129 		model.put("otherData", new ClassPathResource("dummyData.xsl", getClass()));
130 
131 		view.render(model, this.request, this.response);
132 		assertHtmlOutput(this.response.getContentAsString());
133 	}
134 
135 	@Test
testContentTypeCarriedFromTemplate()136 	public void testContentTypeCarriedFromTemplate() throws Exception {
137 		XsltView view = getXsltView(HTML_OUTPUT);
138 
139 		Source source = new StreamSource(getProductDataResource().getInputStream());
140 		Map model = new HashMap();
141 		model.put("someKey", source);
142 
143 		view.render(model, this.request, this.response);
144 		assertTrue(this.response.getContentType().startsWith("text/html"));
145 		assertEquals("UTF-8", this.response.getCharacterEncoding());
146 	}
147 
148 	@Test
testModelParametersCarriedAcross()149 	public void testModelParametersCarriedAcross() throws Exception {
150 		Map model = new HashMap();
151 		model.put("someKey", getProductDataResource());
152 		model.put("title", "Product List");
153 		doTestWithModel(model);
154 		assertTrue(this.response.getContentAsString().indexOf("Product List") > -1);
155 	}
156 
157 	@Test
testStaticAttributesCarriedAcross()158 	public void testStaticAttributesCarriedAcross() throws Exception {
159 		XsltView view = getXsltView(HTML_OUTPUT);
160 		view.setSourceKey("actualData");
161 		view.addStaticAttribute("title", "Product List");
162 
163 		Map model = new HashMap();
164 		model.put("actualData", getProductDataResource());
165 		model.put("otherData", new ClassPathResource("dummyData.xsl", getClass()));
166 
167 		view.render(model, this.request, this.response);
168 		assertHtmlOutput(this.response.getContentAsString());
169 		assertTrue(this.response.getContentAsString().indexOf("Product List") > -1);
170 
171 	}
172 
getDomDocument()173 	private org.w3c.dom.Document getDomDocument() throws ParserConfigurationException, SAXException, IOException {
174 		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
175 		DocumentBuilder builder = dbf.newDocumentBuilder();
176 		org.w3c.dom.Document document = builder.parse(getProductDataResource().getInputStream());
177 		return document;
178 	}
179 
doTestWithModel(Map model)180 	private void doTestWithModel(Map model) throws Exception {
181 		XsltView view = getXsltView(HTML_OUTPUT);
182 		view.render(model, this.request, this.response);
183 		assertHtmlOutput(this.response.getContentAsString());
184 	}
185 
assertHtmlOutput(String output)186 	private void assertHtmlOutput(String output) throws Exception {
187 		if (JdkVersion.getMajorJavaVersion() < JdkVersion.JAVA_15) {
188 			// TODO: find out why the SAXReader.read call fails on JDK 1.4 and 1.3
189 			return;
190 		}
191 
192 		SAXReader reader = new SAXReader();
193 		Document document = reader.read(new StringReader(output));
194 		List nodes = document.getRootElement().selectNodes("/html/body/table/tr");
195 
196 		Element tr1 = (Element) nodes.get(0);
197 		assertRowElement(tr1, "1", "Whatsit", "12.99");
198 		Element tr2 = (Element) nodes.get(1);
199 		assertRowElement(tr2, "2", "Thingy", "13.99");
200 		Element tr3 = (Element) nodes.get(2);
201 		assertRowElement(tr3, "3", "Gizmo", "14.99");
202 		Element tr4 = (Element) nodes.get(3);
203 		assertRowElement(tr4, "4", "Cranktoggle", "11.99");
204 	}
205 
assertRowElement(Element elem, String id, String name, String price)206 	private void assertRowElement(Element elem, String id, String name, String price) {
207 		Element idElem = (Element) elem.elements().get(0);
208 		Element nameElem = (Element) elem.elements().get(1);
209 		Element priceElem = (Element) elem.elements().get(2);
210 
211 		assertEquals("ID incorrect.", id, idElem.getText());
212 		assertEquals("Name incorrect.", name, nameElem.getText());
213 		assertEquals("Price incorrect.", price, priceElem.getText());
214 	}
215 
getXsltView(String templatePath)216 	private XsltView getXsltView(String templatePath) {
217 		XsltView view = new XsltView();
218 		view.setUrl(templatePath);
219 		view.setApplicationContext(new StaticApplicationContext());
220 		view.initApplicationContext();
221 		return view;
222 	}
223 
getProductDataResource()224 	private Resource getProductDataResource() {
225 		return new ClassPathResource("productData.xml", getClass());
226 	}
227 }
228