/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.servlet.view.xslt;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.ErrorListener;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
import javax.xml.transform.dom.DOMSource;
import junit.framework.TestCase;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Text;
import org.springframework.context.ApplicationContextException;
import org.springframework.core.JdkVersion;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
/**
* Unit tests for the {@link AbstractXsltView} class.
*
* @author Darren Davison
* @author Rick Evans
* @author Juergen Hoeller
* @since 11.03.2005
*/
public class TestXsltViewTests extends TestCase {
private TestXsltView view;
private int warnings = 0;
private int errors = 0;
private int fatal = 0;
public void setUp() {
this.view = new TestXsltView();
}
public void testNoSuchStylesheet() {
view.setStylesheetLocation(new FileSystemResource("/does/not/exist.xsl"));
try {
view.initApplicationContext();
fail("Must have thrown ApplicationContextException");
}
catch (ApplicationContextException expected) {
}
}
public void testCustomErrorListener() {
view.setErrorListener(new ErrorListener() {
public void warning(TransformerException ex) {
incWarnings();
}
public void error(TransformerException ex) {
incErrors();
}
public void fatalError(TransformerException ex) {
incFatals();
}
});
// loaded stylesheet is not well formed
view.setStylesheetLocation(new ClassPathResource("org/springframework/web/servlet/view/xslt/errors.xsl"));
try {
view.initApplicationContext();
}
catch (ApplicationContextException ex) {
// shouldn't really happen, but can be let through by XSLT engine
assertTrue(ex.getCause() instanceof TransformerException);
}
assertEquals(1, fatal);
assertEquals(1, errors);
assertEquals(0, warnings);
}
public void testRender() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
AbstractXsltView view = new AbstractXsltView() {
protected Source createXsltSource(Map model, String root, HttpServletRequest request, HttpServletResponse response) throws Exception {
Hero hero = (Hero) model.get("hero");
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
Element node = document.createElement(root);
node.setAttribute("name", hero.getName());
node.setAttribute("age", hero.getAge() + "");
node.setAttribute("catchphrase", hero.getCatchphrase());
return new DOMSource(node);
}
};
view.setStylesheetLocation(new ClassPathResource("org/springframework/web/servlet/view/xslt/sunnyDay.xsl"));
view.setIndent(true);
view.initApplicationContext();
view.render(new ModelAndView().addObject("hero", new Hero("Jet", 24, "BOOM")).getModel(), request, response);
assertEquals("text/html;charset=ISO-8859-1", response.getContentType());
String text = response.getContentAsString();
assertEquals("<hero name=\"Jet\" age=\"24\" catchphrase=\"BOOM\" sex=\"Female\"/>", text.trim());
}
public void testRenderWithCustomContentType() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
AbstractXsltView view = new AbstractXsltView() {
protected Source createXsltSource(Map model, String root, HttpServletRequest request, HttpServletResponse response) throws Exception {
Hero hero = (Hero) model.get("hero");
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
Element node = document.createElement(root);
node.setAttribute("name", hero.getName());
node.setAttribute("age", hero.getAge() + "");
node.setAttribute("catchphrase", hero.getCatchphrase());
return new DOMSource(node);
}
};
view.setContentType("text/plain");
view.setStylesheetLocation(new ClassPathResource("org/springframework/web/servlet/view/xslt/sunnyDay.xsl"));
view.setIndent(true);
view.initApplicationContext();
view.render(new ModelAndView().addObject("hero", new Hero("Jet", 24, "BOOM")).getModel(), request, response);
assertEquals("text/plain", response.getContentType());
String text = response.getContentAsString();
assertEquals("<hero name=\"Jet\" age=\"24\" catchphrase=\"BOOM\" sex=\"Female\"/>", text.trim());
}
public void testRenderWithSingleSourceInModel() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
AbstractXsltView view = new AbstractXsltView() {
protected Map getParameters(HttpServletRequest request) {
Map parameters = new HashMap();
parameters.put("sex", "Male");
return parameters;
}
};
view.setStylesheetLocation(new ClassPathResource("org/springframework/web/servlet/view/xslt/sunnyDay.xsl"));
Properties outputProperties = new Properties();
outputProperties.setProperty("indent", "false");
view.setOutputProperties(outputProperties);
view.initApplicationContext();
Hero hero = new Hero("Jet", 24, "BOOM");
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
Element node = document.createElement("hero");
node.setAttribute("name", hero.getName());
node.setAttribute("age", hero.getAge() + "");
node.setAttribute("catchphrase", hero.getCatchphrase());
view.render(new ModelAndView().addObject("hero", new DOMSource(node)).getModel(), request, response);
assertEquals("text/html;charset=ISO-8859-1", response.getContentType());
String text = response.getContentAsString();
assertEquals("<hero name=\"Jet\" age=\"24\" catchphrase=\"BOOM\" sex=\"Male\"/>", text.trim());
}
public void testRenderWithSingleNodeInModel() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
response.setWriterAccessAllowed(false);
AbstractXsltView view = new AbstractXsltView() {
protected Map getParameters(HttpServletRequest request) {
Map parameters = new HashMap();
parameters.put("sex", "Male");
return parameters;
}
};
view.setStylesheetLocation(new ClassPathResource("org/springframework/web/servlet/view/xslt/sunnyDay.xsl"));
view.initApplicationContext();
Hero hero = new Hero("Jet", 24, "BOOM");
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
Element node = document.createElement("hero");
node.setAttribute("name", hero.getName());
node.setAttribute("age", hero.getAge() + "");
node.setAttribute("catchphrase", hero.getCatchphrase());
view.render(new ModelAndView().addObject("hero", node).getModel(), request, response);
String text = response.getContentAsString();
assertEquals("<hero name=\"Jet\" age=\"24\" catchphrase=\"BOOM\" sex=\"Male\"/>", text.trim());
}
public void testRenderWithNoStylesheetSpecified() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
AbstractXsltView view = new AbstractXsltView() {
protected Map getParameters(HttpServletRequest request) {
Map parameters = new HashMap();
parameters.put("sex", "Male");
return parameters;
}
};
Properties outputProperties = new Properties();
outputProperties.setProperty("indent", "false");
view.setOutputProperties(outputProperties);
view.initApplicationContext();
Hero hero = new Hero("Jet", 24, "BOOM");
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
Element node = document.createElement("hero");
node.setAttribute("name", hero.getName());
node.setAttribute("age", hero.getAge() + "");
node.setAttribute("catchphrase", hero.getCatchphrase());
view.render(new ModelAndView().addObject("hero", new DOMSource(node)).getModel(), request, response);
assertEquals("text/xml;charset=ISO-8859-1", response.getContentType());
String text = response.getContentAsString().trim();
assertTrue(text.startsWith("<?xml"));
assertTrue(text.indexOf("<hero") != -1);
assertTrue(text.indexOf("age=\"24\"") != -1);
assertTrue(text.indexOf("catchphrase=\"BOOM\"") != -1);
assertTrue(text.indexOf("name=\"Jet\"") != -1);
}
public void testRenderSingleNodeInModelWithExplicitDocRootName() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
response.setOutputStreamAccessAllowed(false);
AbstractXsltView view = new AbstractXsltView() {
protected Source createXsltSource(Map model, String root, HttpServletRequest request, HttpServletResponse response) throws Exception {
Hero hero = (Hero) model.get("hero");
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
Element node = document.createElement(root);
node.setAttribute("name", hero.getName());
node.setAttribute("age", hero.getAge() + "");
node.setAttribute("catchphrase", hero.getCatchphrase());
return new DOMSource(node);
}
protected Map getParameters(HttpServletRequest request) {
Map parameters = new HashMap();
parameters.put("sex", "Male");
return parameters;
}
protected boolean useWriter() {
return true;
}
};
view.setStylesheetLocation(new ClassPathResource("org/springframework/web/servlet/view/xslt/sunnyDayExplicitRoot.xsl"));
view.setUseSingleModelNameAsRoot(false);
view.setRoot("baddie");
view.initApplicationContext();
view.render(new ModelAndView().addObject("hero", new Hero("Jet", 24, "BOOM")).getModel(), request, response);
String text = response.getContentAsString();
assertTrue(text.trim().startsWith("<baddie "));
}
/**
* Not a test per-se, but rather only here to validate the example
* given in the reference documentation.
*/
public void testMyFirstWordsExampleFromTheReferenceDocumentation() throws Exception {
// TODO: Why does this test not even work on JDK 1.4?
// Maybe because of the Xalan version there?
if (JdkVersion.getMajorJavaVersion() < JdkVersion.JAVA_15) {
return;
}
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
AbstractXsltView view = new AbstractXsltView() {
protected Source createXsltSource(
Map model, String rootName, HttpServletRequest request, HttpServletResponse response)
throws Exception {
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
Element root = document.createElement(rootName);
List words = (List) model.get("wordList");
for (Iterator it = words.iterator(); it.hasNext();) {
String nextWord = (String) it.next();
Element wordNode = document.createElement("word");
Text textNode = document.createTextNode(nextWord);
wordNode.appendChild(textNode);
root.appendChild(wordNode);
}
return new DOMSource(root);
}
};
view.setStylesheetLocation(new ClassPathResource("org/springframework/web/servlet/view/xslt/firstWords.xsl"));
view.setIndent(true);
view.initApplicationContext();
Map map = new HashMap();
List wordList = new ArrayList();
wordList.add("hello");
wordList.add("world");
map.put("wordList", wordList);
view.render(new ModelAndView("home", map).getModel(), request, response);
String text = response.getContentAsString();
assertTrue(text.trim().startsWith("<html"));
}
private void incWarnings() {
warnings++;
}
private void incErrors() {
errors++;
}
private void incFatals() {
fatal++;
}
private static final class TestXsltView extends AbstractXsltView {
}
private static final class Hero {
private String name;
private int age;
private String catchphrase;
public Hero() {
}
public Hero(String name, int age, String catchphrase) {
this.name = name;
this.age = age;
this.catchphrase = catchphrase;
}
public String getCatchphrase() {
return catchphrase;
}
public void setCatchphrase(String catchphrase) {
this.catchphrase = catchphrase;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
}