/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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
*
* 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.apache.harmony.beans.tests.java.beans;
import java.beans.ExceptionListener;
import java.beans.Introspector;
import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.HashMap;
import java.util.Vector;
import java.lang.reflect.Array;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.apache.harmony.beans.tests.java.beans.EncoderTest.SampleBean;
import org.apache.harmony.beans.tests.java.beans.XMLEncoderTest.DependencyBean;
import org.apache.harmony.beans.tests.support.MockOwnerClass;
import org.apache.harmony.beans.tests.support.mock.MockBean4Codec;
import org.apache.harmony.beans.tests.support.mock.MockBean4Owner_Owner;
import org.apache.harmony.beans.tests.support.mock.MockBean4Owner_Target;
import org.apache.harmony.beans.tests.support.mock.MockBean4StaticField;
import org.apache.harmony.beans.tests.support.mock.MockExceptionListener;
/**
* Tests XMLDecoder
*/
public class XMLDecoderTest extends TestCase {
public static void main(String[] args) {
junit.textui.TestRunner.run(XMLDecoderTest.class);
}
static byte xml123bytes[] = null;
static {
ByteArrayOutputStream byteout = new ByteArrayOutputStream();
XMLEncoder enc = new XMLEncoder(byteout);
enc.writeObject(Integer.valueOf("1"));
enc.writeObject(Integer.valueOf("2"));
enc.writeObject(Integer.valueOf("3"));
enc.close();
xml123bytes = byteout.toByteArray();
}
static class MockClassLoader extends ClassLoader {
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
throw new ClassNotFoundException();
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
throw new ClassNotFoundException();
}
}
/*
* test XMLDecoder constructor with null inputStream argument
*/
public void test_Constructor_NullInputStream_scenario1() {
XMLDecoder xmlDecoder = new XMLDecoder(null);
assertNull(xmlDecoder.readObject());
assertNull(xmlDecoder.getOwner());
assertNotNull(xmlDecoder.getExceptionListener());
xmlDecoder.close();
}
/*
* test XMLDecoder constructor with null inputStream argument
*/
public void test_Constructor_NullInputStream_scenario2() {
XMLDecoder xmlDecoder = new XMLDecoder(null, null);
assertNull(xmlDecoder.readObject());
assertNull(xmlDecoder.getOwner());
assertNotNull(xmlDecoder.getExceptionListener());
xmlDecoder.close();
}
/*
* test XMLDecoder constructor with null inputStream argument
*/
public void test_Constructor_NullInputStream_scenario3() {
XMLDecoder xmlDecoder = new XMLDecoder(null, null, null);
assertNull(xmlDecoder.readObject());
assertNull(xmlDecoder.getOwner());
assertNotNull(xmlDecoder.getExceptionListener());
xmlDecoder.close();
}
/*
* test XMLDecoder constructor with null inputStream argument
*/
public void test_Constructor_NullInputStream_scenario4() {
XMLDecoder xmlDecoder = new XMLDecoder(null, null, null, null);
assertNull(xmlDecoder.readObject());
assertNull(xmlDecoder.getOwner());
assertNotNull(xmlDecoder.getExceptionListener());
xmlDecoder.close();
}
/*
* test XMLDecoder constructor
*/
public void test_Constructor_Normal() throws Exception {
XMLDecoder xmlDecoder;
xmlDecoder = new XMLDecoder(new ByteArrayInputStream(xml123bytes));
assertEquals(null, xmlDecoder.getOwner());
final Vector<Exception> exceptions = new Vector<Exception>();
ExceptionListener el = new ExceptionListener() {
public void exceptionThrown(Exception e) {
exceptions.addElement(e);
}
};
xmlDecoder = new XMLDecoder(new ByteArrayInputStream(xml123bytes), this, el);
assertEquals(el, xmlDecoder.getExceptionListener());
assertEquals(this, xmlDecoder.getOwner());
}
public void testConstructor_ClassLoader() {
XMLDecoder dec;
final Vector<Exception> exceptions = new Vector<Exception>();
ExceptionListener el = new ExceptionListener() {
public void exceptionThrown(Exception e) {
exceptions.addElement(e);
}
};
dec = new XMLDecoder(new ByteArrayInputStream(xml123bytes), this, el,
Thread.currentThread().getContextClassLoader());
assertEquals(Integer.valueOf("1"), dec.readObject());
assertEquals(0, exceptions.size());
dec.close();
dec = new XMLDecoder(new ByteArrayInputStream(xml123bytes), this, el,
new MockClassLoader());
try {
dec.readObject();
assertTrue(exceptions.size() > 0);
} catch (ArrayIndexOutOfBoundsException e) {
// also valid
}
dec.close();
}
public void testClose() {
XMLDecoder dec = new XMLDecoder(new ByteArrayInputStream(xml123bytes));
assertEquals(Integer.valueOf("1"), dec.readObject());
dec.close();
assertEquals(Integer.valueOf("2"), dec.readObject());
assertEquals(Integer.valueOf("3"), dec.readObject());
}
public void testGetExceptionListener() {
XMLDecoder dec = new XMLDecoder(new ByteArrayInputStream(xml123bytes));
assertNotNull(dec.getExceptionListener());
}
public void testGetOwner() {
XMLDecoder dec = new XMLDecoder(new ByteArrayInputStream(xml123bytes));
assertNull(dec.getOwner());
}
public void testReadObject_ArrayOutOfBounds() {
XMLDecoder dec = new XMLDecoder(new ByteArrayInputStream(xml123bytes));
assertEquals(Integer.valueOf("1"), dec.readObject());
assertEquals(Integer.valueOf("2"), dec.readObject());
assertEquals(Integer.valueOf("3"), dec.readObject());
try {
dec.readObject();
fail();
} catch (ArrayIndexOutOfBoundsException e) {
// expected
}
}
public void testReadObject_Null() {
XMLDecoder dec = new XMLDecoder(this.getClass().getResourceAsStream(
"/xml/null.xml"));
Object obj = dec.readObject();
assertNull(obj);
}
public void testReadObject_Integer() {
XMLDecoder dec = new XMLDecoder(this.getClass().getResourceAsStream(
"/xml/int.xml"));
Object obj = dec.readObject();
assertEquals(Integer.valueOf("3"), obj);
}
public void testReadObject_StringCodec() {
XMLDecoder dec = new XMLDecoder(this.getClass().getResourceAsStream(
"/xml/SampleBean_StringCodec.xml"));
SampleBean obj = (SampleBean) dec.readObject();
assertEquals("<Li Yang> & \"liyang'", obj.getMyid());
assertEquals("a child", obj.getRef().getMyid());
}
public void testReadObject_IntArray() {
XMLDecoder dec = new XMLDecoder(this.getClass().getResourceAsStream(
"/xml/IntArray.xml"));
int ints[] = (int[]) dec.readObject();
assertEquals(1, ints[0]);
assertEquals(2, ints[1]);
assertEquals(3, ints[2]);
}
public void testReadObject_Array_WithoutLength() {
// Read array of primitive types without length attribute
XMLDecoder dec = new XMLDecoder(this.getClass().getResourceAsStream(
"/xml/Array_Primitive.xml"));
Object[] arrays = (Object[]) dec.readObject();
boolean[] booleanArray = (boolean[]) arrays[0];
assertTrue(booleanArray[0]);
assertFalse(booleanArray[1]);
short[] shortArray = (short[]) arrays[1];
assertEquals(1, shortArray[0]);
assertEquals(1, shortArray[1]);
byte[] byteArray = (byte[]) arrays[2];
assertEquals(2, byteArray[0]);
assertEquals(2, byteArray[1]);
char[] charArray = (char[]) arrays[3];
assertEquals('c', charArray[0]);
assertEquals('c', charArray[1]);
int[] intArray = (int[]) arrays[4];
assertEquals(4, intArray[0]);
assertEquals(4, intArray[1]);
assertEquals(4, intArray[2]);
assertEquals(4, intArray[3]);
long[] longArray = (long[]) arrays[5];
assertEquals(5l, longArray[0]);
assertEquals(5l, longArray[1]);
assertEquals(5l, longArray[2]);
assertEquals(5l, longArray[3]);
assertEquals(5l, longArray[4]);
float[] floatArray = (float[]) arrays[6];
assertEquals(6f, floatArray[0]);
assertEquals(6f, floatArray[1]);
double[] doubleArray = (double[]) arrays[7];
assertEquals(7d, doubleArray[0]);
assertEquals(7d, doubleArray[1]);
// Read array of Object types without length attribute
dec = new XMLDecoder(this.getClass().getResourceAsStream(
"/xml/Array_Object.xml"));
Object[] array = (Object[]) dec.readObject();
assertTrue((Boolean) array[0]);
assertEquals(new Short((short) 1), (Short) array[1]);
assertEquals(new Byte((byte) 2), (Byte) array[2]);
assertEquals(new Character('c'), (Character) array[3]);
assertEquals(new Integer(4), (Integer) array[4]);
assertEquals(new Long(5), (Long) array[5]);
assertEquals(new Float(6), (Float) array[6]);
assertEquals(new Double(7), (Double) array[7]);
assertEquals("string", (String) array[8]);
// Read wrapper element in array of primitive types
dec = new XMLDecoder(this.getClass().getResourceAsStream(
"/xml/Array_Wrapper.xml"));
int[] integers = (int[]) dec.readObject();
assertEquals(11, integers[0]);
assertEquals(22, integers[1]);
}
public void testReadObject_Array_Special() {
// Read array of Object types in special case without length attribute
XMLDecoder dec = new XMLDecoder(this.getClass().getResourceAsStream(
"/xml/Array_Null.xml"));
Object[] array = (Object[]) dec.readObject();
assertNull(array[0]);
assertNull(array[1]);
assertEquals("", (String) array[2]);
// Read array with wrong type, it should return null,
// and throw a java.lang.IllegalArgumentException
dec = new XMLDecoder(this.getClass().getResourceAsStream(
"/xml/Array_Illegal.xml"));
array = (Object[]) dec.readObject();
assertNull(array);
}
public void testReadObject_PropertyDependency() {
XMLDecoder dec = new XMLDecoder(this.getClass().getResourceAsStream(
"/xml/DependencyBean.xml"));
DependencyBean b = (DependencyBean) dec.readObject();
assertEquals(888, b.getInts()[0]);
assertSame(b.getInts(), b.getRef());
}
public void testReadObject_NoChange() {
XMLDecoder dec = new XMLDecoder(this.getClass().getResourceAsStream(
"/xml/MockBean4Codec_NoChange.xml"));
dec.readObject();
}
public void testReadObject_BornFriendChange() {
XMLDecoder dec = new XMLDecoder(this.getClass().getResourceAsStream(
"/xml/MockBean4Codec_BornFriendChange.xml"));
MockBean4Codec b = (MockBean4Codec) dec.readObject();
assertEquals(888, b.getBornFriend().getZarr()[0]);
assertEquals(b.getBornFriend(), b.getNill());
}
public void testReadObject_ManyChanges() {
XMLDecoder dec = new XMLDecoder(this.getClass().getResourceAsStream(
"/xml/MockBean4Codec_ManyChanges.xml"));
MockBean4Codec b = (MockBean4Codec) dec.readObject();
assertEquals(127, b.getB());
assertSame(b, b.getBackRef());
assertEquals(new Byte((byte) 127), b.getBobj());
assertFalse(b.isBool());
assertEquals(Boolean.TRUE, b.getBoolobj());
assertEquals(Exception.class, b.getBornFriend().getClazz());
assertEquals(888, b.getBornFriend().getZarr()[0]);
assertEquals('Z', b.getC());
assertEquals(String.class, b.getClazz());
assertEquals(new Character('z'), b.getCobj());
assertEquals(123.456, b.getD(), 0);
assertEquals(new Double(123.456), b.getDobj());
assertEquals(12.34F, b.getF(), 0);
assertEquals(new Float(12.34F), b.getFobj());
assertEquals(MockBean4Codec.class, b.getFriend().getClazz());
assertEquals(999, b.getI());
assertEquals(new Integer(999), b.getIobj());
assertEquals(8888888, b.getL());
assertEquals(new Long(8888888), b.getLobj());
assertEquals("Li Yang", b.getName());
assertNull(b.getNill());
assertEquals(55, b.getS());
assertEquals(new Short((short) 55), b.getSobj());
assertEquals(3, b.getZarr().length);
assertEquals(3, b.getZarr()[0]);
assertEquals(2, b.getZarr()[1]);
assertEquals(1, b.getZarr()[2]);
assertEquals(1, b.getZarrarr().length);
assertEquals(3, b.getZarrarr()[0].length);
assertEquals("6", b.getZarrarr()[0][0]);
assertEquals("6", b.getZarrarr()[0][1]);
assertEquals("6", b.getZarrarr()[0][2]);
}
public void testReadObject_StaticField() {
XMLDecoder dec1 = new XMLDecoder(this.getClass().getResourceAsStream(
"/xml/MockBean4StaticField_Original.xml"));
MockBean4StaticField o1 = (MockBean4StaticField) dec1.readObject();
XMLDecoder dec2 = new XMLDecoder(this.getClass().getResourceAsStream(
"/xml/MockBean4StaticField.xml"));
MockBean4StaticField o2 = (MockBean4StaticField) dec2.readObject();
if (!o1.equals(o2)) {
System.out
.println("Loading object with static field, original xml: "
+ o1.getV());
System.out.println("Loading object with static field, field xml: "
+ o2.getV());
}
assertEquals(o1, o2);
}
public void testReadObject_Owner() {
MockBean4Owner_Owner o1 = new MockBean4Owner_Owner();
XMLDecoder dec1 = new XMLDecoder(this.getClass().getResourceAsStream(
"/xml/MockBean4Owner_SetOwner.xml"), o1);
MockBean4Owner_Target t1 = (MockBean4Owner_Target) dec1.readObject();
assertEquals(1, o1.getV());
assertEquals(o1, t1.getV());
}
public void testReadObject_Owner_Specific(){
String expectedValue = "expected value";
HashMap map = new HashMap();
map.put("key", expectedValue);
XMLDecoder decoder = new XMLDecoder(this.getClass().getResourceAsStream(
"/xml/MockOwner.xml"), map);
String actualValue = (String) decoder.readObject();
assertEquals(expectedValue,actualValue);
MockOwnerClass mock = new MockOwnerClass();
expectedValue = "I_Ljava.lang.String";
decoder = new XMLDecoder(this.getClass().getResourceAsStream(
"/xml/MockOwner_Specific.xml"), mock);
actualValue = (String) decoder.readObject();
assertEquals(expectedValue,actualValue);
decoder = new XMLDecoder(this.getClass().getResourceAsStream(
"/xml/MockOwner_Ambiguous.xml"), mock);
actualValue = (String) decoder.readObject();
assertNull(actualValue);
decoder = new XMLDecoder(this.getClass().getResourceAsStream(
"/xml/MockOwner_Null.xml"), mock);
actualValue = (String) decoder.readObject();
assertNull(actualValue);
}
public void testReadObject_Owner_WithWriteStatement() {
MockBean4Owner_Owner o2 = new MockBean4Owner_Owner();
XMLDecoder dec2 = new XMLDecoder(this.getClass().getResourceAsStream(
"/xml/MockBean4Owner_SetOwnerWithWriteStatement.xml"), o2);
MockBean4Owner_Target t2 = (MockBean4Owner_Target) dec2.readObject();
assertEquals(999, o2.getV());
assertEquals(o2, t2.getV());
}
public void testReadObject_Repeated() throws Exception {
final Vector<Exception> exceptionList = new Vector<Exception>();
final ExceptionListener exceptionListener = new ExceptionListener() {
public void exceptionThrown(Exception e) {
exceptionList.addElement(e);
}
};
XMLDecoder xmlDecoder = new XMLDecoder(new ByteArrayInputStream(
xml123bytes));
xmlDecoder.setExceptionListener(exceptionListener);
assertEquals(new Integer(1), xmlDecoder.readObject());
assertEquals(new Integer(2), xmlDecoder.readObject());
assertEquals(new Integer(3), xmlDecoder.readObject());
xmlDecoder.close();
assertEquals(0, exceptionList.size());
}
public void testSetExceptionListener_Called() throws Exception {
class MockExceptionListener implements ExceptionListener {
private boolean isCalled = false;
public void exceptionThrown(Exception e) {
isCalled = true;
}
public boolean isCalled() {
return isCalled;
}
}
XMLDecoder xmlDecoder = new XMLDecoder(new ByteArrayInputStream(
"<java><string/>".getBytes("UTF-8")));
MockExceptionListener mockListener = new MockExceptionListener();
xmlDecoder.setExceptionListener(mockListener);
assertFalse(mockListener.isCalled());
// Real Parsing should occur in method of ReadObject rather constructor.
assertNotNull(xmlDecoder.readObject());
assertTrue(mockListener.isCalled());
}
public void testSetExceptionListener() {
XMLDecoder dec = new XMLDecoder(new ByteArrayInputStream(xml123bytes));
Object defaultL = dec.getExceptionListener();
dec.setExceptionListener(null);
assertSame(defaultL, dec.getExceptionListener());
ExceptionListener newL = new MockExceptionListener();
dec.setExceptionListener(newL);
assertSame(newL, dec.getExceptionListener());
}
public void testSetExceptionListener_CatchException() {
MockExceptionListener l = new MockExceptionListener();
new XMLDecoder(XMLDecoderTest.class
.getResourceAsStream("/xml/bad_int.xml"), null, l);
assertTrue(l.size() > 0);
}
public void testSetOwner() {
XMLDecoder dec = new XMLDecoder(new ByteArrayInputStream(xml123bytes));
assertNull(dec.getOwner());
String owner = "owner";
dec.setOwner(owner);
assertSame(owner, dec.getOwner());
dec.setOwner(null);
assertNull(dec.getOwner());
}
/*
* Class under test for void XMLDecoder(java.io.InputStream)
*/
public void testXMLDecoderInputStream() {
XMLDecoder dec = new XMLDecoder(new ByteArrayInputStream(xml123bytes));
assertNull(dec.getOwner());
assertNotNull(dec.getExceptionListener());
}
/*
* Class under test for void XMLDecoder(java.io.InputStream,
* java.lang.Object)
*/
public void testXMLDecoderInputStreamObject() {
String owner = "owner";
XMLDecoder dec = new XMLDecoder(new ByteArrayInputStream(xml123bytes),
owner);
assertSame(owner, dec.getOwner());
assertNotNull(dec.getExceptionListener());
}
/*
* Class under test for void XMLDecoder(java.io.InputStream,
* java.lang.Object, java.beans.ExceptionListener)
*/
public void testXMLDecoderInputStreamObjectExceptionListener() {
String owner = "owner";
MockExceptionListener l = new MockExceptionListener();
XMLDecoder dec = new XMLDecoder(new ByteArrayInputStream(xml123bytes),
owner, l);
assertSame(owner, dec.getOwner());
assertSame(l, dec.getExceptionListener());
}
/**
* The test checks the code generation for XML from Test1.xml
*/
public void testDecodeLinkedList() throws Exception {
decode("xml/Test1.xml");
}
/**
* The test checks the code generation for XML from Test2.xml
*/
public void testDecodePrimitiveArrayByLength() throws Exception {
decode("xml/Test2.xml");
}
/**
* The test checks the code generation for XML from Test3.xml
*/
public void testDecodePrimitiveArrayByElements() throws Exception {
decode("xml/Test3.xml");
}
/**
* The test checks the code generation for XML from Test4.xml
*/
public void testDecodeObjectArrayByLength() throws Exception {
decode("xml/Test4.xml");
}
/**
* The test checks the code generation for XML from Test5.xml
*/
public void testDecodeObjectArrayByElements() throws Exception {
decode("xml/Test5.xml");
}
/**
* The test checks the code generation for XML from Test6.xml
*/
public void testDecodeReference() throws Exception {
decode("xml/Test6.xml");
}
/**
* The test checks the code generation for XML from Test7.xml
*/
public void testDecodeStringArray() throws Exception {
decode("xml/Test7.xml");
}
/**
* Regression test for HARMONY-1890
*/
public void testDecodeEmptyStringArray1890() {
ByteArrayOutputStream out = new ByteArrayOutputStream();
XMLEncoder encoder = new XMLEncoder(out);
XMLDecoder decoder;
Object obj;
encoder.writeObject(new String[10]);
encoder.close();
decoder = new XMLDecoder(new ByteArrayInputStream(out.toByteArray()));
obj = decoder.readObject();
decoder.close();
assertTrue("Returned object is not array", obj.getClass().isArray());
assertSame("String type expected", String.class,
obj.getClass().getComponentType());
assertEquals("Size mismatch", 10, Array.getLength(obj));
}
/*
* The test checks the code generation for XML from MainTest.xml
*
* public void testMain() { decode("xml/MainTest.xml"); }
*/
/**
*
*/
public static Test suite() {
return new TestSuite(XMLDecoderTest.class);
}
/**
*
*/
private void decode(String resourceName) throws Exception {
XMLDecoder d = null;
try {
Introspector.setBeanInfoSearchPath(new String[] {});
d = new XMLDecoder(new BufferedInputStream(ClassLoader
.getSystemClassLoader().getResourceAsStream(resourceName)));
while (true) {
d.readObject();
}
} catch (ArrayIndexOutOfBoundsException aibe) {
assertTrue(true);
} finally {
if (d != null) {
d.close();
}
}
}
}