/*! * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * Copyright (c) 2002-2013 Pentaho Corporation.. All rights reserved. */ package org.pentaho.platform.util; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.util.HashMap; import java.util.Map; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; import org.apache.commons.lang.StringUtils; import org.dom4j.Document; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.dom4j.tree.DefaultElement; import org.junit.Assert; import org.pentaho.platform.util.messages.LocaleHelper; import org.pentaho.platform.util.xml.XmlHelper; import org.pentaho.platform.util.xml.dom4j.XmlDom4JHelper; import org.pentaho.platform.util.xml.w3c.XmlW3CHelper; import junit.framework.TestCase; @SuppressWarnings( { "all" } ) public class XmlHelperTest extends TestCase { public void testGetEncoding_Valid() { // these should succeed, and cause the specified (windows-1252) encoding to be returned String[] winXmls = { "<?xml version=\"1.0\" encoding=\"windows-1252\"?><root></root>", //$NON-NLS-1$ "<?xml encoding=\"windows-1252\" version=\"1.0\"?><root></root>", //$NON-NLS-1$ "<?xml encoding=\"windows-1252\" version='1.0'?><root></root>", //$NON-NLS-1$ "<?xml encoding='windows-1252' version=\"1.0\"?><root></root>", //$NON-NLS-1$ "<?xml encoding='windows-1252' version='1.0'?><root></root>" //$NON-NLS-1$ }; for ( String element : winXmls ) { String enc = XmlHelper.getEncoding( element ); assertTrue( enc.equals( "windows-1252" ) ); //$NON-NLS-1$ } } public void testGetEncoding_DefaultInsteadOfInvalid() { // these should fail, and cause the default system encoding to be returned String[] defaultXmls = { "<?xml encoding='UTF-8' version='1.0'?><root></root>", //$NON-NLS-1$ "<?xml encoding='UTF-8' version='1.0'?><root></root>", "<?xml encoding='UTF-8' version=\"1.0\"?><root></root>", // $NON-NLS-1$ //$NON-NLS-2$ "<?xml encoding='UTF-8' version='1.0'?><root>encoding=bad</root>" //$NON-NLS-1$ }; for ( String element : defaultXmls ) { String enc = XmlHelper.getEncoding( element ); assertTrue( enc.equals( LocaleHelper.getSystemEncoding() ) ); } } /** * Load an XML file into a dom4j.Document, convert that document to a string, load that string into a w3c.Document, * and turn it back into a string. * * @throws FileNotFoundException * @throws TransformerConfigurationException * @throws TransformerException */ public void testGetXMLFromDocument() throws Exception { InputStream in = prepareSampleXmlStream(); org.dom4j.Document doc = XmlDom4JHelper.getDocFromStream( in ); org.w3c.dom.Document w3cDoc = XmlW3CHelper.getDomFromString( doc.asXML() ); String converted = XmlDom4JHelper.docToString( w3cDoc ).toString(); assertFalse( StringUtils.isEmpty( converted ) ); } public void testEncode_NullStringIsEncodedToNull() { assertNull( XmlHelper.encode( (String) null ) ); } public void testEncode_NullArrayIsIgnored() { XmlHelper.encode( (String[]) null ); } public void testDecode_NullStringIsDecodedToNull() { assertNull( XmlHelper.decode( (String) null ) ); } public void testDecode_NullArrayIsIgnored() { XmlHelper.decode( (String[]) null ); } public void testEncodeDecode() { String encodedXml = " ABC 123 abc &amp;=& &lt;=< &gt;=> &apos;=' &quot;=" ABC123abc &" + "quot = " &apos; = ' &gt; = > &lt; = < &amp; = & ABC123abc "; //$NON-NLS-1$ String decodedXml = " ABC 123 abc &=& <=< >=> '=' "=\" ABC123abc " = \" ' = ' > = > < = < & " + "= & ABC123abc "; //$NON-NLS-1$ assertEquals( "Error in decode", decodedXml, XmlHelper.decode( encodedXml ) ); //$NON-NLS-1$ assertEquals( "Error in encode", encodedXml, XmlHelper.encode( decodedXml ) ); //$NON-NLS-1$ assertEquals( "Error encoding after decoding", encodedXml, XmlHelper.encode( XmlHelper.decode( encodedXml ) ) ); // $NON-NLS-1$ assertEquals( "Error decoding after encoding", decodedXml, XmlHelper.decode( XmlHelper.encode( decodedXml ) ) ); // $NON-NLS-1$ } public void testXForm() throws TransformerException { try { InputStream inStrm = new FileInputStream( "src/test/resources/solution/test/xml/XmlHelperTest1.xml" ); //$NON-NLS-1$ String xslName = "CustomReportParametersForPortlet.xsl"; //$NON-NLS-1$ String xslPath = "src/test/resources/solution/system/custom/xsl"; //$NON-NLS-1$ StringBuffer b = XmlHelper.transformXml( xslName, xslPath, inStrm, null, new TestEntityResolver() ); Assert.assertTrue( StringUtils.isNotEmpty( b.toString() ) ); } catch ( Throwable e ) { System.out.println( "Exception thrown " + e.getMessage() ); //$NON-NLS-1$ Assert.assertTrue( "Exception thrown " + e.getMessage(), false ); //$NON-NLS-1$ } } public void testFailureGetDocFromString() { try { Document doc = XmlDom4JHelper.getDocFromString( "1231231231231", null ); //$NON-NLS-1$ fail( "Unexpected XML parsing success" ); } catch ( Exception e ) { assertTrue( "Exception thrown " + e.getMessage(), true ); //$NON-NLS-1$ } } public void testSuccessGetDocFromString() throws Exception { Document doc = XmlDom4JHelper.getDocFromString( "<root><contents><value>One</value><value>Two</value></contents></root>", //$NON-NLS-1$ null ); assertNotNull( "Unexpected XML parsing failure", doc ); } public void testGetDocFromStream() throws Exception { InputStream in = prepareSampleXmlStream(); Document doc = XmlDom4JHelper.getDocFromStream( in ); assertNotNull( doc ); } public void testFailureTransformXML() throws Exception { String parameterXsl = "DefaultParameterForm.xsl"; //$NON-NLS-1$ String xslPath = "system/custom/xsl"; Map<String, String> parameters = new HashMap<String, String>(); String actionUrl = "http://localhost:8080/pentaho/ViewAction?"; //$NON-NLS-1$ String baseUrl = "http://localhost:8080/pentaho"; //$NON-NLS-1$ String displayUrl = "http://localhost:8080/pentaho"; //$NON-NLS-1$ parameters.put( "baseUrl", baseUrl ); //$NON-NLS-1$ parameters.put( "actionUrl", actionUrl ); //$NON-NLS-1$ parameters.put( "displayUrl", displayUrl ); // $NON-NLS-1$ Document document = XmlDom4JHelper.getDocFromString( "<?xml version=\"1.0\" encoding=\"windows-1252\"?><root></root>", null ); //$NON-NLS-1$ assertEquals( document.getRootElement().getName(), "root" ); //$NON-NLS-1$ XmlHelper.transformXml( parameterXsl, xslPath, document.asXML(), parameters, new JarEntityResolver() ); } public void testFailureTransformXML2() throws Exception { String parameterXsl = "DefaultParameterForm.xsl"; //$NON-NLS-1$ String xslPath = "system/custom/xsl"; Map parameters = new HashMap(); String actionUrl = "http://localhost:8080/pentaho/ViewAction?"; //$NON-NLS-1$ String baseUrl = "http://localhost:8080/pentaho"; //$NON-NLS-1$ String displayUrl = "http://localhost:8080/pentaho"; //$NON-NLS-1$ parameters.put( "baseUrl", baseUrl ); //$NON-NLS-1$ parameters.put( "actionUrl", actionUrl ); //$NON-NLS-1$ parameters.put( "displayUrl", displayUrl ); //$NON-NLS-1$ String xmlString = "<?xml version=\"1.0\" encoding=\"" + "UTF-8" + "\" ?><filters xmlns:xf=\"http://www.w3.org/2002/xforms\">" + // $NON-NLS-1$ // //$NON-NLS-2$ // //$NON-NLS-3$ "<Header/>" + "<id><![CDATA[" + //$NON-NLS-1$ //$NON-NLS-2$ "]]></id><description><![CDATA[" + //$NON-NLS-1$ "MyDescription" + "]]></description><icon><![CDATA[" + //$NON-NLS-1$ //$NON-NLS-2$ "GetIcon" + "]]></icon><help><![CDATA[" + //$NON-NLS-1$ //$NON-NLS-2$ "GetHelp" + "]]></help>" + //$NON-NLS-1$ //$NON-NLS-2$ "<action><![CDATA[" + actionUrl + "]]></action>" + //$NON-NLS-1$ //$NON-NLS-2$ "<display><![CDATA[" + displayUrl + "]]></display>" + //$NON-NLS-1$ //$NON-NLS-2$ "<Body/>" + "</filters>"; //$NON-NLS-1$ //$NON-NLS-2$ Document document = XmlDom4JHelper.getDocFromString( xmlString, null ); XmlHelper.transformXml( parameterXsl, xslPath, document.asXML(), parameters, new JarEntityResolver() ); } public void testFailureTransformXML3() throws Exception { String parameterXsl = "DefaultParameterForm.xsl"; //$NON-NLS-1$ String xslPath = "system/custom/xsl"; Map parameters = new HashMap(); String actionUrl = "http://localhost:8080/pentaho/ViewAction?"; //$NON-NLS-1$ String baseUrl = "http://localhost:8080/pentaho"; //$NON-NLS-1$ String displayUrl = "http://localhost:8080/pentaho"; //$NON-NLS-1$ parameters.put( "baseUrl", baseUrl ); //$NON-NLS-1$ parameters.put( "actionUrl", actionUrl ); //$NON-NLS-1$ parameters.put( "displayUrl", displayUrl ); //$NON-NLS-1$ Document document = XmlDom4JHelper.getDocFromString( "<?xml version=\"1.0\" encoding=\"" + "UTF-8" + "\" ?><filters xmlns:xf=\"http://www.w3.org/2002/xforms\">" + // $NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ "<Header/>" + "<id><![CDATA[" + //$NON-NLS-1$ //$NON-NLS-2$ "]]></id><description><![CDATA[" + //$NON-NLS-1$ "MyDescription" + "]]></description><icon><![CDATA[" + //$NON-NLS-1$ //$NON-NLS-2$ "GetIcon" + "]]></icon><help><![CDATA[" + //$NON-NLS-1$ //$NON-NLS-2$ "GetHelp" + "]]></help>" + //$NON-NLS-1$ //$NON-NLS-2$ "<action><![CDATA[" + actionUrl + "]]></action>" + //$NON-NLS-1$ //$NON-NLS-2$ "<display><![CDATA[" + displayUrl + "]]></display>" + //$NON-NLS-1$ //$NON-NLS-2$ "<Body/>" + "</filters>", null ); //$NON-NLS-1$ //$NON-NLS-2$ XmlHelper.transformXml( parameterXsl, xslPath, new ByteArrayInputStream( document.asXML().getBytes() ), parameters, new JarEntityResolver() ); } public void testEncoding() throws Exception { doEncodingTest( "rootElement", "hello", "UTF-8" ); doEncodingTest( "rootElement", "hello", "UTF-16" ); String unicodeElementText = new String( new char[] { '\uAA93', '\uAA94', '\uAA95' } ); doEncodingTest( "rootElement", unicodeElementText, "UTF-8" ); doEncodingTest( "rootElement", unicodeElementText, "UTF-16" ); } public void doEncodingTest( String rootElementName, String rootElementText, String encoding ) throws Exception { // Create the test document. Element rootElement = new DefaultElement( rootElementName ); Document document = DocumentHelper.createDocument( rootElement ); rootElement.setText( rootElementText ); // Write out the document to a byte array. ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); XmlDom4JHelper.saveDom( document, outputStream, encoding ); // Read in the document from the byte array, and make sure it's decoded properly. InputStream inputStream = new ByteArrayInputStream( outputStream.toByteArray() ); // Read in the XML string using a java reader and make sure the decoded string // contains the same strings as the encoded dom4j document. BufferedReader in = new BufferedReader( new InputStreamReader( inputStream, encoding ) ); StringBuffer stringBuffer = new StringBuffer(); int intValue = in.read(); while ( intValue != -1 ) { stringBuffer.append( (char) intValue ); intValue = in.read(); } assertTrue( stringBuffer.toString().indexOf( rootElementName ) != -1 ); assertTrue( stringBuffer.toString().indexOf( rootElementText ) != -1 ); inputStream.reset(); // Read in the XML string using the dom4j api and make sure the decoded xml // contains the same strings as the original document. document = XmlDom4JHelper.getDocFromStream( inputStream ); assertEquals( rootElementName, document.getRootElement().getName() ); assertEquals( rootElementText, document.getRootElement().getText() ); } private static InputStream prepareSampleXmlStream() { String sampleXml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<report name=\"Quadrant For Region\" orientation=\"portrait\" topmargin=\"0pt\" leftmargin=\"5pt\" " + "bottommargin=\"0pt\" rightmargin=\"5pt\" />"; return new ByteArrayInputStream( sampleXml.getBytes() ); } }