/**
* Licensed to Apereo under one or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information regarding copyright ownership. Apereo
* licenses this file to you 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 the
* following location:
*
* <p>http://www.apache.org/licenses/LICENSE-2.0
*
* <p>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.apereo.portal.rendering.xslt;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.io.StringWriter;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.XMLEvent;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamSource;
import junit.framework.Assert;
import org.apereo.portal.io.xml.XmlTestException;
import org.apereo.portal.rendering.PipelineEventReader;
import org.apereo.portal.rendering.PipelineEventReaderImpl;
import org.apereo.portal.rendering.StAXPipelineComponent;
import org.custommonkey.xmlunit.Diff;
import org.custommonkey.xmlunit.XMLUnit;
import org.easymock.EasyMock;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
/**
* Test XSLT when going from DOM -> StAX -> XSLT -> StAX
*
*/
public class XSLTComponentTest {
protected final Logger logger = LoggerFactory.getLogger(getClass());
@Test
public void testXSLTComponent() throws Exception {
final MockHttpServletRequest mockReq = new MockHttpServletRequest();
final MockHttpServletResponse mockRes = new MockHttpServletResponse();
final XMLEventReader xmlEventReader = this.getXmlEventReader("juser.xml");
final PipelineEventReaderImpl<XMLEventReader, XMLEvent> cacheableEventReader =
new PipelineEventReaderImpl<XMLEventReader, XMLEvent>(xmlEventReader);
final Transformer transformer = this.getTransformer("columns.xsl");
final StAXPipelineComponent targetComponent =
EasyMock.createMock(StAXPipelineComponent.class);
final TransformerSource transformerSource = EasyMock.createMock(TransformerSource.class);
EasyMock.expect(targetComponent.getEventReader(mockReq, mockRes))
.andReturn(cacheableEventReader);
EasyMock.expect(transformerSource.getTransformer(mockReq, mockRes)).andReturn(transformer);
EasyMock.replay(targetComponent, transformerSource);
final XSLTComponent xsltComponent = new XSLTComponent();
xsltComponent.setWrappedComponent(targetComponent);
xsltComponent.setTransformerSource(transformerSource);
final PipelineEventReader<XMLEventReader, XMLEvent> eventReader =
xsltComponent.getEventReader(mockReq, mockRes);
Assert.assertNotNull(eventReader);
final String output = this.serializeXMLEventReader(eventReader.getEventReader());
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setValidating(false);
dbf.setFeature("http://xml.org/sax/features/namespaces", false);
dbf.setFeature("http://xml.org/sax/features/validation", false);
dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false);
dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
final DocumentBuilder db = dbf.newDocumentBuilder();
XMLUnit.setIgnoreWhitespace(true);
try {
final Document expected =
db.parse(
this.getClass()
.getResourceAsStream(
"/org/apereo/portal/rendering/xslt/expected.xml"),
"/org/apereo/portal/rendering/xslt/expected.xml");
final Document actual = db.parse(new InputSource(new StringReader(output)));
Diff d = new Diff(expected, actual);
assertTrue("Upgraded data doesn't match expected data: " + d, d.similar());
} catch (Exception e) {
throw new XmlTestException(
"Failed to assert similar between XSLT output and expected XML", output, e);
} catch (Error e) {
throw new XmlTestException(
"Failed to assert similar between XSLT output and expected XML", output, e);
}
EasyMock.verify(targetComponent, transformerSource);
}
protected String serializeXMLEventReader(XMLEventReader reader) {
final StringWriter writer = new StringWriter();
final XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
outputFactory.setProperty("javax.xml.stream.isRepairingNamespaces", true);
final XMLEventWriter xmlEventWriter;
try {
xmlEventWriter = outputFactory.createXMLEventWriter(writer);
} catch (XMLStreamException e) {
throw new RuntimeException("Failed to create XMLEventWriter", e);
}
try {
xmlEventWriter.setDefaultNamespace("http://www.w3.org/1999/xhtml");
xmlEventWriter.add(reader);
xmlEventWriter.flush();
xmlEventWriter.close();
} catch (XMLStreamException e) {
throw new RuntimeException("Failed to write events to Writer", e);
}
return writer.toString();
}
protected XMLEventReader getXmlEventReader(String file)
throws SAXException, IOException, ParserConfigurationException {
final InputStream xmlStream = this.getClass().getResourceAsStream(file);
final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
final DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
final Document document = documentBuilder.parse(xmlStream);
final XMLInputFactory inputFactory = XMLInputFactory.newInstance();
final XMLEventReader xmlEventReader;
try {
xmlEventReader = inputFactory.createXMLEventReader(new DOMSource(document, "foobar"));
} catch (XMLStreamException e) {
throw new RuntimeException(
"Failed to create XMLStreamReader for file '" + file + "'", e);
}
return xmlEventReader;
}
protected Transformer getTransformer(String file) {
final InputStream stylesheetStream = this.getClass().getResourceAsStream(file);
;
final TransformerFactory transformerFactory = TransformerFactory.newInstance();
try {
return transformerFactory.newTransformer(new StreamSource(stylesheetStream));
} catch (TransformerConfigurationException e) {
throw new RuntimeException("Failed to create Transformer for stylesheet: " + file, e);
}
}
}