AddRecord.java

package org.microspace.replicator.record;

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.List;

import org.microspace.table.Entry;
import org.microspace.table.column.Accessor;
import org.microspace.table.column.GetSetPair;

/**
 * This Record is used when data is replicated.
 * 
 * @author Gaspar Sinai - {@literal gaspar.sinai@microspace.org}
 * @version 2016-06-26
 */
public class AddRecord implements RecordData, Externalizable, Comparable<AddRecord> {
	
	private static final long serialVersionUID = 2012062410490100001L;
	
	String className;
	Object key;
	Object[] fields;
	BigInteger updateCount;
	
	public AddRecord () {
	}
	
	public AddRecord (String className, Object key, Object[] fields) {
		this.className = className;
		this.key = key;
		this.fields = Arrays.copyOf(fields, fields.length);
		this.updateCount = BigInteger.ZERO;
	}
	
	public AddRecord (Entry<?> entry) {
		className = entry.getSpaceEntry().getClass().getName();
		key = entry.getPrimaryKey();
		fields = entry.getFields();
		updateCount = entry.getUpdateCount();
	}
	
	public <T> Entry<T> convert (Accessor<T> accessor) {
		T object = accessor.getBlankObject();
		Object[] fields =  getFields();
		List<GetSetPair<T>> pairs = accessor.getGetSetPairs();
		for (GetSetPair<T> pair : pairs) {
			pair.set (object, fields[pair.getIndex()]);
		}
		Entry<T> ret = new Entry<T>(object, accessor);
		ret.setUpdateCount(updateCount);
		return ret;
	}	

	// Testing
	void setClassName (String className) {
		this.className = className;
	}

	public <T> AddRecord (Accessor<T> accessor, T data) {
		this.className = data.getClass().getName();
		this.key = accessor.getPrimaryKeyGetSetPair().get(data);
		List<GetSetPair<T>> pairs = accessor.getGetSetPairs();
		this.fields = new Object [pairs.size()];
		for (GetSetPair<T> pair : pairs) {
			this.fields[pair.getIndex()] = pair.get(data);
		}
		this.updateCount = BigInteger.ZERO;
	}

	public String getClassName() {
		return className;
	}

	public Object getKey() {
		return key;
	}

	public Object[] getFields() {
		return Arrays.copyOf(fields, fields.length);
	}
	
	boolean isSameFields (AddRecord ar) {
		if (!key.equals(ar.key)) {
			System.err.println ("key different" + getClassName());
			return false;
		}
		if (fields.length != ar.fields.length) {
			System.err.println ("length different" + getClassName());
			return false;
		}
		for (int i=0; i<fields.length; i++) {
			if (fields[i] != ar.fields[i]) {
				System.err.println ("fields different" + getClassName());
				return false;
			}
		}
		return true;
	}
	
	public void writeExternal(ObjectOutput out) throws IOException {
		out.writeObject(className);
		out.writeObject(key);
		out.writeInt(fields.length);
		for (int i=0; i<fields.length; i++) {
			out.writeObject (fields[i]);
		}
		out.writeObject(updateCount);
	}

	public void readExternal(ObjectInput in) throws IOException {
		int size = 0;
		try {
			className = (String) in.readObject();
			key = in.readObject();
			size = in.readInt();
		} catch (ClassNotFoundException cnf) {
			cnf.printStackTrace();
		}
		fields = new Object[size];
		for (int i=0; i<size; i++) {
			try {
				fields[i] = in.readObject();
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}
		}
		try {
			updateCount = (BigInteger) in.readObject();
		} catch (ClassNotFoundException cnfu) {
			cnfu.printStackTrace();
		}
	}

	public BigInteger getUpdateCount() {
		return updateCount;
	}

	public void setUpdateCount(BigInteger updateCount) {
		this.updateCount = updateCount;
	}
	@Override
	public int compareTo(AddRecord o) {
		return updateCount.compareTo(o.updateCount);
	}
	@Override
	public boolean equals (Object o) {
		if (! (o instanceof AddRecord)) return false;
		AddRecord oa = (AddRecord) o;
		return compareTo(oa) == 0;
	}
	@Override
	public int hashCode () {
		return updateCount.intValue();
	}

}