package com.lightboxtechnologies.spectrum;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
import org.codehaus.jackson.map.ObjectMapper;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Map;
public class FsEntryPut {
protected FsEntryPut() {}
private static final ObjectMapper mapper = new ObjectMapper();
private static final byte[] ZERO = { 0 };
public static void add(Put p, Map<String,?> map, byte[] colFam) {
// should this be in the -Common class?
byte[] col = null,
binVal = null;
String key = null;
Object val = null;
for (Map.Entry<String,?> pair : map.entrySet()) {
key = pair.getKey();
val = pair.getValue();
if (val == null) {
throw new RuntimeException("val was null for key " + key);
}
col = FsEntryHBaseCommon.createColSpec(val, key);
switch (col[0]) {
case FsEntryHBaseCommon.STRING:
binVal = Bytes.toBytes((String)val);
break;
case FsEntryHBaseCommon.LONG:
binVal = Bytes.toBytes(((Number)val).longValue());
break;
case FsEntryHBaseCommon.DATE:
binVal = Bytes.toBytes(((Date)val).getTime());
break;
case FsEntryHBaseCommon.JSON:
try {
binVal = mapper.writeValueAsBytes(val);
}
catch (IOException e) {
throw new RuntimeException("Failed to serialize to JSON: " + val);
}
break;
case FsEntryHBaseCommon.BYTE_ARRAY:
binVal = (byte[])val;
break;
case FsEntryHBaseCommon.BUFFER_STREAM:
binVal = ((BufferProxy)val).getBuffer();
break;
case FsEntryHBaseCommon.FILE_STREAM:
binVal = Bytes.toBytes(((FileProxy)val).getPath());
break;
case FsEntryHBaseCommon.EXTENTS_STREAM:
binVal = ZERO;
break;
default:
throw new RuntimeException("Didn't get something that could be converted to a byte[], " + val.toString() + " for key " + key);
}
p.add(colFam, col, binVal);
}
}
public static Put create(byte[] key, Map<String,Object> map, byte[] colFam) {
final Put p = new Put(key);
add(p, map, colFam);
return p;
}
public static Put create(ImmutableBytesWritable key, Map<String,Object> map, byte[] colFam) {
return create(key.get(), map, colFam);
}
@SuppressWarnings("unchecked")
public static Put create(byte[] key, FsEntry entry, byte[] colFam) {
final Put p = new Put(key);
// FIXME: this logic should really be in FsEntry proper
final Object o = entry.get("attrs");
if (o != null && null == entry.getStreams().get("Content")) {
String data = null;
for (Map<String,Object> attr : (List<Map<String,Object>>)o) {
final Number flags = (Number) attr.get("flags"),
type = (Number) attr.get("type");
final String name = (String) attr.get("name");
if (flags != null && (flags.longValue() & 0x04) != 0
&& type != null && (type.longValue() & 0x80) != 0
&& name != null && name.equals("$Data"))
{
data = (String) attr.get("rd_buf");
break;
}
}
if (data != null && data.length() > 0) {
byte[] v;
try {
v = Hex.decodeHex(data.toCharArray());
}
catch (DecoderException e) {
throw new IllegalArgumentException(e);
}
p.add(
colFam,
FsEntryHBaseCommon.createColSpec(
FsEntryHBaseCommon.BUFFER_STREAM,
"Content"
),
v
);
}
}
add(p, entry.getChangedItems(), colFam);
// add(p, entry.getStreams(), colFam);
return p;
}
}