/**
* Copyright 2005-2012 Akiban Technologies, Inc.
*
* Licensed 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 com.persistit.unit;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamException;
import java.io.ObjectStreamField;
import java.io.Serializable;
import java.util.ArrayList;
import org.junit.Test;
import com.persistit.DefaultValueCoder;
import com.persistit.Exchange;
import com.persistit.Persistit;
import com.persistit.PersistitUnitTestCase;
import com.persistit.Value;
import com.persistit.encoding.CoderContext;
import com.persistit.encoding.CoderManager;
import com.persistit.encoding.SerialValueCoder;
import com.persistit.encoding.ValueCoder;
import com.persistit.encoding.ValueRenderer;
import com.persistit.exception.PersistitException;
public class ValueTest3 extends PersistitUnitTestCase {
/**
* Tests JSA 1.1 default serialization. Requires the
* enableCompatibleConstructors to be true.
*/
Exchange _exchange;
public static class CustomSet extends ArrayList {
private final static long serialVersionUID = 1L;
}
private static class T implements Serializable {
private final static long serialVersionUID = 1L;
private String _a;
private String _b;
private T(final String a, final String b) {
_a = a;
_b = b;
}
private T(final String a, final String b, final boolean f) {
_a = a;
_b = b;
assertTrue("T 3-arg constructor should not be called", false);
}
private T(final int x, final boolean y, final String z) {
assertTrue("T 3-arg constructor should not be called", false);
}
@Override
public String toString() {
return "T:" + _a + _b;
}
}
private static class TT extends T {
private final static long serialVersionUID = 1L;
private TT(final String a, final String b) {
super(a, b);
}
private TT(final String a, final String b, final boolean f) {
super(a, b, f);
}
private TT(final int x, final boolean y, final String z) {
super(x, y, z);
}
@Override
public String toString() {
return "T" + super.toString();
}
}
private static class TTT extends TT {
private final static long serialVersionUID = 1L;
private TTT(final String a, final String b) {
super(a, b);
assertTrue(a != null);
}
private TTT(final String a, final String b, final boolean f) {
super(a, b, f);
assertTrue(a != null);
}
private TTT(final int x, final boolean y, final String z) {
super(x, y, z);
}
@Override
public String toString() {
return "T" + super.toString();
}
}
private static class TTTValueCoder extends DefaultValueCoder {
static int _getCounter;
TTTValueCoder(final Persistit persistit) {
super(persistit, TTT.class);
}
@Override
public Object get(final Value value, final Class clazz, final CoderContext context) {
_getCounter++;
final TTT ttt = new TTT("x", "y");
value.registerEncodedObject(ttt);
render(value, ttt, clazz, context);
return ttt;
}
}
private static class S implements Serializable {
String _a;
String _b;
private final static long serialVersionUID = 1L;
public void readObject(final ObjectInputStream ois) throws IOException, ClassNotFoundException {
ois.defaultReadObject();
}
public void writeObject(final ObjectOutputStream oos) throws IOException {
oos.defaultWriteObject();
}
@Override
public String toString() {
return "S:" + _a + _b;
}
}
private static class SS extends S {
private final static long serialVersionUID = 1L;
private final String _c;
private final String _d;
protected String _ff; // Can only be marked final on JDK 1.5 and above
private SS(final String c, final String d) {
_c = c;
_d = d;
_ff = "Final field";
}
@Override
public String toString() {
return "S" + super.toString() + _c + _d;
}
}
private static class SSS extends SS {
private final static long serialVersionUID = 1L;
R _e;
private final W _f;
private SSS(final String c, final String d, final boolean e, final int f) {
super(c, d);
_e = new R(e);
_f = new W(f);
}
@Override
public String toString() {
return "S" + super.toString() + _e + _f;
}
}
private static class SSSS extends SSS {
private final static long serialVersionUID = 1L;
private String _g;
private String _h;
private SSSS() {
super("SSSS-c", "SSSS-d", true, 42);
_g = "Field g";
_h = "Field h";
}
private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField("_g", String.class), };
@Override
public String toString() {
return "S" + super.toString() + _g + _h + _ff;
}
}
private static class R implements Serializable {
private final static long serialVersionUID = 1L;
final static R R_TRUE = new R(true);
final static R R_FALSE = new R(false);
boolean _value;
R(final boolean b) {
_value = b;
}
public Object readResolve() throws ObjectStreamException {
return _value ? R_TRUE : R_FALSE;
}
@Override
public String toString() {
if (this == R_TRUE) {
return "true";
} else if (this == R_FALSE) {
return "false";
} else {
return "notReplaced";
}
}
}
private static class W implements Serializable {
private final static long serialVersionUID = 1L;
int _value;
W(final int v) {
_value = v;
}
private Object writeReplace() throws ObjectStreamException {
return new WReplacement(_value);
}
@Override
public String toString() {
return "W:" + _value;
}
}
private static class WReplacement implements Serializable {
private final static long serialVersionUID = 1L;
int _value;
WReplacement(final int v) {
_value = v;
}
private Object readResolve() throws ObjectStreamException {
return new W(_value);
}
@Override
public String toString() {
return "WReplacement:" + _value;
}
}
private static class E implements Externalizable {
private final static long serialVersionUID = 1L;
String _a;
String _b;
public E() {
}
@Override
public void readExternal(final ObjectInput oi) throws IOException {
oi.readUTF(); // "foo"
_a = oi.readUTF();
_b = oi.readUTF();
}
@Override
public void writeExternal(final ObjectOutput oo) throws IOException {
oo.writeUTF("hello");
oo.writeUTF(_a);
oo.writeUTF(_b);
}
@Override
public String toString() {
return "E:" + _a + _b;
}
}
private static class EE extends E {
private final static long serialVersionUID = 1L;
private final Thread _thread = Thread.currentThread(); // intentionally
// Externalizable -- requires a public no-arg constructor
@SuppressWarnings("unused")
public EE() {
super();
}
EE(final String a, final String b) {
_a = a;
_b = b;
}
@Override
public String toString() {
return "E" + super.toString() + (_thread != null ? "" : "");
}
}
@Override
public void setUp() throws Exception {
super.setUp();
_exchange = _persistit.getExchange("persistit", getClass().getSimpleName(), true);
}
@Override
public void tearDown() throws Exception {
_persistit.releaseExchange(_exchange);
_exchange = null;
super.tearDown();
}
@Test
public void test1() throws PersistitException {
final S s = new S();
s._a = "1";
s._b = "2";
_exchange.getValue().put(s);
_exchange.clear().append("test1").store();
final Object x = _exchange.getValue().get();
assertEquals("S:12", x.toString());
}
@Test
public void test2() throws PersistitException {
final SS ss = new SS("3", "4");
ss._a = "1";
ss._b = "2";
_exchange.getValue().put(ss);
_exchange.clear().append("test2").store();
final Object x = _exchange.getValue().get();
assertEquals("SS:1234", x.toString());
}
@Test
public void test3() throws PersistitException {
final E e = new E();
e._a = "1";
e._b = "2";
_exchange.getValue().put(e);
_exchange.clear().append("test3").store();
final Object x = _exchange.getValue().get();
assertEquals("E:12", x.toString());
}
@Test
public void test4() throws PersistitException {
final EE ee = new EE("6", "7");
ee._a = "1";
ee._b = "2";
_exchange.getValue().put(ee);
_exchange.clear().append("test4").store();
final Object x = _exchange.getValue().get();
assertEquals("EE:12", x.toString());
}
@Test
public void test5() throws PersistitException {
final T t = new T("1", "2");
_exchange.getValue().put(t);
_exchange.clear().append("test5").store();
final Object x = _exchange.getValue().get();
assertEquals("T:12", x.toString());
}
@Test
public void test6() throws PersistitException {
final TT tt = new TT("1", "2");
_exchange.getValue().put(tt);
_exchange.clear().append("test6").store();
final Object x = _exchange.getValue().get();
assertEquals("TT:12", x.toString());
}
@Test
public void test7() throws PersistitException {
final CoderManager cm = _persistit.getCoderManager();
cm.registerValueCoder(TTT.class, new TTTValueCoder(_persistit));
TTTValueCoder._getCounter = 0;
final TTT ttt = new TTT("1", "2");
_exchange.getValue().put(ttt);
_exchange.clear().append("test7").store();
final Object x = _exchange.getValue().get();
assertEquals("TTT:12", x.toString());
assertEquals(1, TTTValueCoder._getCounter);
cm.unregisterValueCoder(TTT.class);
}
@Test
public void test8() throws PersistitException {
final CoderManager cm = _persistit.getCoderManager();
cm.registerValueCoder(TTT.class, new TTTValueCoder(_persistit));
TTTValueCoder._getCounter = 0;
final TTT ttt = new TTT("1", "2");
_exchange.getValue().put(ttt);
_exchange.clear().append("test8").store();
final Object x = _exchange.getValue().get();
assertEquals("TTT:12", x.toString());
assertEquals(1, TTTValueCoder._getCounter);
cm.unregisterValueCoder(TTT.class);
}
@Test
public void test9() throws PersistitException {
final SSS sss = new SSS("3", "4", true, 5);
sss._a = "1";
sss._b = "2";
_exchange.getValue().put(sss);
_exchange.clear().append("test9").store();
final Object x = _exchange.getValue().get();
assertEquals("SSS:1234trueW:5", x.toString());
}
@Test
public void test10() throws PersistitException {
final SSS sss = new SSS("3", "4", true, 5);
sss._a = "1";
sss._b = "2";
_exchange.getValue().put(sss);
_exchange.clear().append("test10").store();
final Object x = _exchange.getValue().get();
assertEquals("SSS:1234trueW:5", x.toString());
}
@Test
public void test11() throws PersistitException {
final SSSS ssss = new SSSS();
ssss._a = "Field a";
ssss._b = "Field b";
ssss._g = "Field g";
ssss._h = "Field h";
_exchange.getValue().put(ssss);
_exchange.clear().append("test11").store();
final Object x = _exchange.getValue().get();
assertEquals("SSSS:Field aField bSSSS-cSSSS-dtrueW:42Field gnullFinal field", x.toString());
}
@Test
public void test12() throws PersistitException {
final CoderManager cm = _persistit.getCoderManager();
final ValueCoder defaultCoder = cm.getValueCoder(SSSS.class);
_persistit.getCoderManager().registerValueCoder(SSSS.class, new SerialValueCoder(SSSS.class));
final SSSS ssss = new SSSS();
ssss._a = "Field a";
ssss._b = "Field b";
ssss._g = "Field g";
ssss._h = "Field h";
_exchange.getValue().put(ssss);
_exchange.clear().append("test12").store();
final Object x = _exchange.getValue().get();
assertEquals("SSSS:Field aField bSSSS-cSSSS-dtrueW:42Field gnullFinal field", x.toString());
cm.registerValueCoder(SSSS.class, defaultCoder);
}
@Test
public void testDirectPutAndGet() throws PersistitException {
final Value value = _exchange.getValue();
final CoderManager cm = _persistit.getCoderManager();
final ValueRenderer vr = new TTTValueCoder(_persistit);
cm.registerValueCoder(TTT.class, vr);
TTTValueCoder._getCounter = 0;
final TTT t = new TTT("1", "2");
value.put(t);
_exchange.clear().append("test7").store();
value.clear();
_exchange.fetch();
final Object x = value.directGet(vr, TTT.class, null);
assertEquals("TTT:12", x.toString());
assertEquals(1, TTTValueCoder._getCounter);
final Object y = value.directGet(vr, TTT.class, null);
assertEquals("TTT:12", y.toString());
final TTT z = new TTT("3", "4");
value.directPut(vr, z, null);
assertEquals(z.toString(), value.get().toString());
assertEquals(z.toString(), value.directGet(vr, TTT.class, null).toString());
value.directPut(vr, t, null);
assertEquals(t.toString(), value.directGet(vr, TTT.class, null).toString());
value.directPut(vr, t, null);
assertEquals(t.toString(), value.directGet(vr, TTT.class, null).toString());
cm.unregisterValueCoder(TTT.class);
}
public static void main(final String[] args) throws Exception {
new ValueTest3().initAndRunTest();
}
}