Java tutorial
/* * * The contents of this file are subject to the Terracotta Public 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://terracotta.org/legal/terracotta-public-license. * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for * the specific language governing rights and limitations under the License. * * The Covered Software is Terracotta Core. * * The Initial Developer of the Covered Software is * Terracotta, Inc., a Software AG company * */ package com.tc.object; import org.apache.commons.io.IOUtils; import com.tc.bytes.TCByteBuffer; import com.tc.io.TCByteBufferInputStream; import com.tc.io.TCByteBufferOutputStream; import com.tc.io.serializer.TCObjectInputStream; import com.tc.object.bytecode.MockClassProvider; import com.tc.object.dna.api.DNAEncoding; import com.tc.object.dna.impl.ClassInstance; import com.tc.object.dna.impl.SerializerDNAEncodingImpl; import com.tc.object.dna.impl.StorageDNAEncodingImpl; import com.tc.object.dna.impl.UTF8ByteCompressedDataHolder; import com.tc.object.dna.impl.UTF8ByteDataHolder; import com.tc.object.loaders.ClassProvider; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Random; import junit.framework.TestCase; @SuppressWarnings("resource") public class ApplicatorDNAEncodingTest extends TestCase { Random rnd = new Random(); ClassProvider classProvider = new MockClassProvider(); public void testZeroLengthByteArray() throws Exception { final TCByteBufferOutputStream output = new TCByteBufferOutputStream(); final byte[] b = new byte[] {}; final DNAEncoding encoding = getApplicatorEncoding(); encoding.encode(b, output); // The bug this test is for only happens if DNAEncoding gets back -1 from the input stream upon being asked to read // 0 bytes from a stream that is at EOF. ByteArrayInputStream happens to be one implemented in such a way final ByteArrayOutputStream baos = new ByteArrayOutputStream(); IOUtils.copy(new TCByteBufferInputStream(output.toArray()), baos); final TCObjectInputStream input = new TCObjectInputStream(new ByteArrayInputStream(baos.toByteArray())); assertTrue(Arrays.equals(b, (byte[]) encoding.decode(input))); assertEquals(0, input.available()); } public void testNonPrimitiveArrays2() throws Exception { final TCByteBufferOutputStream output = new TCByteBufferOutputStream(); final Integer[] array = new Integer[] { new Integer(43), new Integer(-1) }; final ObjectID[] array2 = new ObjectID[] {}; final DNAEncoding encoding = getApplicatorEncoding(); encoding.encodeArray(array, output); encoding.encodeArray(array2, output); final TCByteBufferInputStream input = new TCByteBufferInputStream(output.toArray()); assertTrue(Arrays.equals(array, (Object[]) encoding.decode(input))); assertTrue(Arrays.equals(array2, (Object[]) encoding.decode(input))); assertEquals(0, input.available()); } private DNAEncoding getApplicatorEncoding() { return new ApplicatorDNAEncodingImpl(this.classProvider); } public void testNonPrimitiveArrays() throws Exception { final TCByteBufferOutputStream output = new TCByteBufferOutputStream(); final Object[] array = new Object[] { new ObjectID(12), new Integer(34), new Double(Math.PI), ObjectID.NULL_ID, new Long(Long.MIN_VALUE + 34), "timmy" }; final DNAEncoding encoding = getApplicatorEncoding(); encoding.encodeArray(array, output); final TCByteBufferInputStream input = new TCByteBufferInputStream(output.toArray()); assertTrue(Arrays.equals(array, (Object[]) encoding.decode(input))); assertEquals(0, input.available()); } public void testNullArray() throws Exception { final TCByteBufferOutputStream output = new TCByteBufferOutputStream(); final DNAEncoding encoding = getApplicatorEncoding(); encoding.encodeArray(null, output); final TCByteBufferInputStream input = new TCByteBufferInputStream(output.toArray()); assertNull(encoding.decode(input)); assertEquals(0, input.available()); } public void testPrimitiveArrays() throws Exception { final DNAEncoding encoding = getApplicatorEncoding(); for (int iter = 0; iter < 250; iter++) { final TCByteBufferOutputStream output = new TCByteBufferOutputStream(); final byte[] b = makeByteArray(); final char[] c = makeCharArray(); final double[] d = makeDoubleArray(); final float[] f = makeFloatArray(); final int[] i = makeIntArray(); final long[] j = makeLongArray(); final short[] s = makeShortArray(); final boolean[] z = makeBooleanArray(); encoding.encodeArray(b, output); encoding.encodeArray(c, output); encoding.encodeArray(d, output); encoding.encodeArray(f, output); encoding.encodeArray(i, output); encoding.encodeArray(j, output); encoding.encodeArray(s, output); encoding.encodeArray(z, output); final TCByteBufferInputStream input = new TCByteBufferInputStream(output.toArray()); assertTrue(Arrays.equals(b, (byte[]) encoding.decode(input))); assertTrue(Arrays.equals(c, (char[]) encoding.decode(input))); assertTrue(Arrays.equals(d, (double[]) encoding.decode(input))); assertTrue(Arrays.equals(f, (float[]) encoding.decode(input))); assertTrue(Arrays.equals(i, (int[]) encoding.decode(input))); assertTrue(Arrays.equals(j, (long[]) encoding.decode(input))); assertTrue(Arrays.equals(s, (short[]) encoding.decode(input))); assertTrue(Arrays.equals(z, (boolean[]) encoding.decode(input))); assertEquals(0, input.available()); } } private short[] makeShortArray() { final short[] rv = new short[this.rnd.nextInt(10)]; for (int i = 0; i < rv.length; i++) { rv[i] = (short) this.rnd.nextInt(); } return rv; } private long[] makeLongArray() { final long[] rv = new long[this.rnd.nextInt(10)]; for (int i = 0; i < rv.length; i++) { rv[i] = this.rnd.nextLong(); } return rv; } private int[] makeIntArray() { final int[] rv = new int[this.rnd.nextInt(10)]; for (int i = 0; i < rv.length; i++) { rv[i] = this.rnd.nextInt(); } return rv; } private float[] makeFloatArray() { final float[] rv = new float[this.rnd.nextInt(10)]; for (int i = 0; i < rv.length; i++) { rv[i] = this.rnd.nextFloat(); } return rv; } private double[] makeDoubleArray() { final double[] rv = new double[this.rnd.nextInt(10)]; for (int i = 0; i < rv.length; i++) { rv[i] = this.rnd.nextDouble(); } return rv; } private char[] makeCharArray() { final char[] rv = new char[this.rnd.nextInt(10)]; for (int i = 0; i < rv.length; i++) { rv[i] = new Character((char) this.rnd.nextInt(Character.MAX_VALUE)).charValue(); } return rv; } private byte[] makeByteArray() { final byte[] rv = new byte[this.rnd.nextInt(10)]; for (int i = 0; i < rv.length; i++) { rv[i] = (byte) this.rnd.nextInt(); } return rv; } private boolean[] makeBooleanArray() { final boolean[] rv = new boolean[this.rnd.nextInt(10)]; for (int i = 0; i < rv.length; i++) { rv[i] = this.rnd.nextBoolean(); } return rv; } public void testUnicodeChars() throws Exception { final StringBuffer str = new StringBuffer(); for (int i = 0; i < 100; i++) { str.append('\u7aba'); str.append('\ucabb'); str.append('\uffcf'); str.append('\ufeb5'); str.append('\ud0e6'); str.append('\u204b'); } helpTestStringEncodingDecoding(str.toString(), true); } public void testUncompressedStringDecoding() throws Exception { final String littleString = new String("abc"); helpTestStringEncodingDecoding(littleString, false); } public void testCompressedStringDecoding() throws Exception { final String bigString = getBigString(100000); helpTestStringEncodingDecoding(bigString, true); } public void helpTestStringEncodingDecoding(String s, boolean compressed) throws Exception { // Encode string using applicator encoding into data final DNAEncoding applicatorEncoding = getApplicatorEncoding(); TCByteBufferOutputStream output = new TCByteBufferOutputStream(); applicatorEncoding.encode(s, output); final TCByteBuffer[] data = output.toArray(); // Decode string from data using storage encoding (into UTF8ByteDataHolder) into decoded final DNAEncoding storageEncoding = getStorageEncoder(); TCByteBufferInputStream input = new TCByteBufferInputStream(data); final UTF8ByteDataHolder decoded = (UTF8ByteDataHolder) storageEncoding.decode(input); if (compressed) { assertTrue(decoded instanceof UTF8ByteCompressedDataHolder); final UTF8ByteCompressedDataHolder compressedDecoded = (UTF8ByteCompressedDataHolder) decoded; assertEquals(s.getBytes("UTF-8").length, compressedDecoded.getUncompressedStringLength()); System.err.println("Compressed String length = " + compressedDecoded.getBytes().length); assertEquals(s.length(), compressedDecoded.getStringLength()); assertEquals(s.hashCode(), compressedDecoded.getStringHash()); } assertEquals(s, decoded.asString()); // Encode UTF8ByteDataHolder into data2 using storage encoding output = new TCByteBufferOutputStream(); storageEncoding.encode(decoded, output); final TCByteBuffer[] data2 = output.toArray(); // Decode UTF8ByteDataHolder from data2 into decoded2 using storage encoding input = new TCByteBufferInputStream(data2); final UTF8ByteDataHolder decoded2 = (UTF8ByteDataHolder) storageEncoding.decode(input); assertEquals(decoded, decoded2); // Decode from original data using applicator encoding into str input = new TCByteBufferInputStream(data); final String str = (String) applicatorEncoding.decode(input); assertEquals(s, str); // Decode from data2 using applicator encoding into str2 input = new TCByteBufferInputStream(data2); final String str2 = (String) applicatorEncoding.decode(input); assertEquals(s, str2); } private String getBigString(int length) { final String sample = "mold for Big String"; final StringBuffer sb = new StringBuffer(); while (sb.length() < length) { sb.append(sample); } return sb.toString(); } public void testStringDecode() throws Exception { final TCByteBufferOutputStream output = new TCByteBufferOutputStream(); DNAEncoding encoding = getApplicatorEncoding(); encoding.encode("timmy", output); UTF8ByteDataHolder orgUTF; encoding.encode((orgUTF = new UTF8ByteDataHolder("teck".getBytes("UTF-8"))), output); final TCByteBuffer[] data = output.toArray(); encoding = getStorageEncoder(); TCByteBufferInputStream input = new TCByteBufferInputStream(data); UTF8ByteDataHolder decoded = (UTF8ByteDataHolder) encoding.decode(input); assertTrue(Arrays.equals("timmy".getBytes("UTF-8"), decoded.getBytes())); decoded = (UTF8ByteDataHolder) encoding.decode(input); assertTrue(Arrays.equals("teck".getBytes("UTF-8"), decoded.getBytes())); assertEquals(0, input.available()); encoding = getApplicatorEncoding(); input = new TCByteBufferInputStream(data); String str = (String) encoding.decode(input); assertEquals("timmy", str); str = (String) encoding.decode(input); assertEquals("teck", str); assertEquals(0, input.available()); encoding = getSerializerEncoder(); input = new TCByteBufferInputStream(data); str = (String) encoding.decode(input); assertEquals("timmy", str); decoded = (UTF8ByteDataHolder) encoding.decode(input); assertEquals(orgUTF, decoded); assertEquals(0, input.available()); } private DNAEncoding getStorageEncoder() { return new StorageDNAEncodingImpl(); } private DNAEncoding getSerializerEncoder() { return new SerializerDNAEncodingImpl(); } public void testClassExpand() throws Exception { final TCByteBufferOutputStream output = new TCByteBufferOutputStream(); DNAEncoding encoding = getApplicatorEncoding(); encoding.encode(getClass(), output); Class<?> c = Object.class; final UTF8ByteDataHolder name = new UTF8ByteDataHolder(c.getName()); final ClassInstance ci = new ClassInstance(name); encoding.encode(ci, output); final TCByteBuffer[] data = output.toArray(); encoding = getStorageEncoder(); TCByteBufferInputStream input = new TCByteBufferInputStream(data); ClassInstance holder = (ClassInstance) encoding.decode(input); assertEquals(getClass().getName(), holder.getName().asString()); holder = (ClassInstance) encoding.decode(input); assertEquals(name, holder.getName()); assertEquals(0, input.available()); encoding = getApplicatorEncoding(); input = new TCByteBufferInputStream(data); c = (Class<?>) encoding.decode(input); assertEquals(getClass(), c); c = (Class<?>) encoding.decode(input); assertEquals(Object.class, c); assertEquals(0, input.available()); } public void testBasic() throws Exception { final TCByteBufferOutputStream output = new TCByteBufferOutputStream(); final List<Object> data = new ArrayList<Object>(); data.add(new ObjectID(1)); data.add("one"); data.add(new Boolean(true)); data.add("two"); data.add(new Byte((byte) 42)); data.add("three"); data.add(new Character('\t')); data.add("four"); data.add(new Double(Math.PI)); data.add("five"); data.add(new Float(Math.E)); data.add("six"); data.add(new Integer(Integer.MAX_VALUE)); data.add("seven"); data.add(new Long(System.currentTimeMillis() % 17)); data.add("eight"); data.add(new Short((short) -1)); final DNAEncoding encoding = getApplicatorEncoding(); for (Object d : data) { encoding.encode(d, output); } final TCByteBufferInputStream input = new TCByteBufferInputStream(output.toArray()); for (Object orig : data) { final Object decoded = encoding.decode(input); assertEquals(orig, decoded); } assertEquals(0, input.available()); } }