package kr.co.vcnc.haeinsa;

import java.util.Comparator;

import kr.co.vcnc.haeinsa.utils.NullableComparator;

import org.apache.commons.codec.binary.Hex;
import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.KeyValue.Type;
import org.apache.hadoop.hbase.util.Bytes;

import com.google.common.base.Objects;
import com.google.common.collect.ComparisonChain;

/**
 * Modified POJO container of {@link KeyValue} class in HBase.
 * Like {@link KeyValue}, contains only one Key-Value data.
 * 
 * <p>HaeinsaKeyValue contains row, family, qualifier, value information and Type information, but not timestamp.
 * Because haeinsa use timestamp for version control, user cannot manually control timestamp of HaeinsaKeyValue. 
 * Type is same Enum with {@link org.apache.hadoop.hbase.KeyValue.Type}.
 * 
 * <p>HaeinsaKeyValue has public static comparator which can be used in navigableMap.
 * This comparator is ComparisionChain of {@link NullableCompator} wrapped {@link org.apache.hadoop.hbase.util.Bytes#BYTES_COMPARATOR}.
 * The order of comparisonChain is row, family, qualifier, value and type.
 * 
 * @author Myungbo Kim
 *
 */
public class HaeinsaKeyValue {
	public static final Comparator<HaeinsaKeyValue> COMPARATOR =new Comparator<HaeinsaKeyValue>() {
		@Override
		public int compare(HaeinsaKeyValue o1, HaeinsaKeyValue o2) {
			return ComparisonChain.start()
					.compare(o1.getRow(), o2.getRow(), new NullableComparator<byte[]>(Bytes.BYTES_COMPARATOR))
					.compare(o1.getFamily(), o2.getFamily(), new NullableComparator<byte[]>(Bytes.BYTES_COMPARATOR))
					.compare(o1.getQualifier(), o2.getQualifier(), new NullableComparator<byte[]>(Bytes.BYTES_COMPARATOR))
					.compare(o1.getType(), o2.getType())
					.result();
		}
	};
	
	private byte[] row;
	private byte[] family;
	private byte[] qualifier;
	private byte[] value;
	private Type type;
	
	public HaeinsaKeyValue(){
	}
	
	public HaeinsaKeyValue(KeyValue keyValue){
		this(keyValue.getRow(), keyValue.getFamily(), keyValue.getQualifier(), keyValue.getValue(), KeyValue.Type.codeToType(keyValue.getType()));
	}
	
	public HaeinsaKeyValue(byte[] row, byte[] family, byte[] qualifier, byte[] value, Type type){
		this.row = row;
		this.family = family;
		this.qualifier = qualifier;
		this.value = value;
		this.type = type;
	}
	
	public byte[] getRow() {
		return row;
	}
	
	public void setRow(byte[] row) {
		this.row = row;
	}

	public byte[] getFamily() {
		return family;
	}

	public void setFamily(byte[] family) {
		this.family = family;
	}

	public byte[] getQualifier() {
		return qualifier;
	}

	public void setQualifier(byte[] qualifier) {
		this.qualifier = qualifier;
	}

	public byte[] getValue() {
		return value;
	}

	public void setValue(byte[] value) {
		this.value = value;
	}

	public Type getType() {
		return type;
	}

	public void setType(Type type) {
		this.type = type;
	}
	
	/**
	 * for debugging
	 */
	@Override
	public String toString(){
		return Objects.toStringHelper(this.getClass())
				.add("row", Bytes.toStringBinary(row))
	            .add("family", Bytes.toStringBinary(family))
	            .add("qualifier", Bytes.toStringBinary(qualifier))
	            .add("value", Bytes.toStringBinary(value))
	            .add("type", type)
	            .toString();
	}
	
	/**
	 * for {@link HaeinsaKeyValue#toString()}
	 * @param bytes
	 * @return
	 */
	private String bytesToString(byte[] bytes){
		String result = "";
		for(int i=0;i<bytes.length;i++){
			result += (0xff & bytes[i]) + " ";			
		}
		return result;
	}
}

@@ -109,52 +109,8 @@
 r;%0A%0A
-import org.apache.commons.codec.binary.Hex;%0A
 impo
@@ -3228,257 +3228,6 @@
 %0A%09%7D%0A
-%09%0A%09/**%0A%09 * for %7B@link HaeinsaKeyValue#toString()%7D%0A%09 * @param bytes%0A%09 * @return%0A%09 */%0A%09private String bytesToString(byte%5B%5D bytes)%7B%0A%09%09String result = %22%22;%0A%09%09for(int i=0;i%3Cbytes.length;i++)%7B%0A%09%09%09result += (0xff & bytes%5Bi%5D) + %22 %22;%09%09%09%0A%09%09%7D%0A%09%09return result;%0A%09%7D%0A
 %7D%0A

Remove unnecessary import Remove unnecessary function