blob: 83ba966421e8059ba72fa5e3109b916e619e0bd7 [file] [log] [blame]
package org.apache.tapestry5.internal.services;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.HashMap;
import org.apache.tapestry5.internal.services.XMLTokenStream;
import org.apache.tapestry5.internal.services.XMLTokenType;
import org.apache.tapestry5.ioc.MappedConfiguration;
import org.apache.tapestry5.ioc.Resource;
import org.apache.tapestry5.ioc.internal.util.AbstractResource;
import org.testng.Assert;
import org.testng.annotations.Test;
public class XMLTokenStreamTests
{
private static class MappedConfigurationStub<K,V> extends HashMap<K, V> implements MappedConfiguration<K, V>
{
public void add(K key, V value)
{
put(key,value);
}
public void override(K key, V value)
{
put(key,value);
}
public void addInstance(K key, Class<? extends V> clazz)
{
throw new UnsupportedOperationException();
}
public void overrideInstance(K key, Class<? extends V> clazz)
{
throw new UnsupportedOperationException();
}
}
private static class ResourceStub extends AbstractResource
{
final byte[] content;
public ResourceStub(byte[] content)
{
super("");
this.content=content;
}
public URL toURL()
{
return null;
}
protected Resource newResource(String path)
{
return null;
}
@Override
public InputStream openStream() throws IOException
{
return new ByteArrayInputStream(content);
}
}
protected void resetDefaultCharset() throws Exception
{
// The charset is cached after system start - so we ned to clear that cache to force a certain file.encoding
Field field=Charset.class.getDeclaredField("defaultCharset");
field.setAccessible(true);
field.set(null, null);
}
/**
* This test sets the system's default encoding to cp1252 (as on german windows) and tries to parse a non-ascii xml file
* with XMLTokenStream. This is to test a critical section within XMLTokenStream.openStream() where the
* binary file is converted to charcters and back before it is parsed.
* @throws Exception
*/
@Test
public void testStreamEncoding() throws Exception
{
String oldEncoding=System.getProperty("file.encoding");
System.setProperty("file.encoding","cp1252");
resetDefaultCharset();
try
{
MappedConfigurationStub<String, URL> parserUrlMap=new MappedConfigurationStub<String, URL>();
String unicodeString="\u00FC";
String testDocument="<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>"+unicodeString+"</root>\n";
XMLTokenStream xts=new XMLTokenStream(new ResourceStub(testDocument.getBytes("utf-8")),parserUrlMap);
// Ugly way to handle exceptions like java.io.IOException: Server returned HTTP response code: 503 for URL: http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent
// when running tests
int attempts = 0;
int maxAttempts = 10;
boolean success = false;
while (!success && attempts < maxAttempts)
{
try
{
xts.parse();
} catch (IOException e) {
e.printStackTrace();
Thread.sleep(5000);
attempts++;
continue;
}
success = true;
}
if (attempts == maxAttempts)
{
throw new RuntimeException("Maximum number of attempts reached");
}
Assert.assertEquals(xts.next(), XMLTokenType.START_ELEMENT);
Assert.assertEquals(xts.getLocalName(), "root");
Assert.assertEquals(xts.next(), XMLTokenType.CHARACTERS);
Assert.assertEquals(xts.getText(), unicodeString);
Assert.assertEquals(xts.next(), XMLTokenType.END_ELEMENT);
Assert.assertEquals(xts.next(), XMLTokenType.END_DOCUMENT);
}
finally
{
System.setProperty("file.encoding", oldEncoding);
resetDefaultCharset();
}
}
}