/**
*
*/
package com.trendrr.oss.cache;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.trendrr.oss.DynMap;
import com.trendrr.oss.exceptions.TrendrrParseException;
/**
*
* Simple class that allows us to store aribitrary dynmap as metadata to the a byte array.
*
* @author Dustin Norlander
* @created Jan 9, 2012
*
*/
public class TrendrrCacheItem {
protected static Log log = LogFactory.getLog(TrendrrCacheItem.class);
public static TrendrrCacheItem instance(DynMap metadata, byte[] bytes) {
TrendrrCacheItem item = new TrendrrCacheItem();
item.setContentBytes(bytes);
item.setMetadata(metadata);
return item;
}
private byte[] bytes = new byte[0];
private DynMap metadata = new DynMap();
public byte[] getContentBytes() {
return bytes;
}
public void setContentBytes(byte[] bytes) {
this.bytes = bytes;
}
public DynMap getMetadata() {
return metadata;
}
public void setMetadata(DynMap metadata) {
this.metadata = metadata;
}
public byte[] serialize() {
try {
int length = 0;
byte[] meta = new byte[0];
if (metadata != null && metadata.size() > 0) {
meta = metadata.toJSONString().getBytes("utf8");
length = meta.length;
}
byte[] len = intToByteArray(length);
return this.concatAll(len, meta, this.bytes);
} catch (UnsupportedEncodingException e) {
log.warn("Gah, how'd you get an encodeing exception!?", e);
}
return null;
}
/**
* will deserialize the byte array
* @param vals
* @throws UnsupportedEncodingException
*/
public static TrendrrCacheItem deserialize(byte[] bytes) throws TrendrrParseException {
int length = byteArrayToInt(Arrays.copyOfRange(bytes, 0, 4));
byte[] metabytes = Arrays.copyOfRange(bytes, 4, 4+length);
DynMap metadata;
try {
metadata = DynMap.instance(new String(metabytes, "utf8"));
} catch (UnsupportedEncodingException e) {
throw new TrendrrParseException(e);
}
byte[] b = Arrays.copyOfRange(bytes, 4+length, bytes.length);
TrendrrCacheItem item = new TrendrrCacheItem();
item.setContentBytes(b);
item.setMetadata(metadata);
return item;
}
protected byte[] concatAll(byte[] first, byte[]... rest) {
int totalLength = first.length;
for (byte[] array : rest) {
totalLength += array.length;
}
byte[] result = Arrays.copyOf(first, totalLength);
int offset = first.length;
for (byte[] array : rest) {
System.arraycopy(array, 0, result, offset, array.length);
offset += array.length;
}
return result;
}
private static byte[] intToByteArray(int value) {
return new byte[] {
(byte)(value >>> 24),
(byte)(value >>> 16),
(byte)(value >>> 8),
(byte)value};
}
private static int byteArrayToInt(byte [] b) {
return (b[0] << 24)
+ ((b[1] & 0xFF) << 16)
+ ((b[2] & 0xFF) << 8)
+ (b[3] & 0xFF);
}
}