package mil.nga.giat.geowave.adapter.raster.adapter; import java.awt.image.DataBuffer; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.nio.ByteBuffer; import javax.media.jai.remote.SerializableState; import javax.media.jai.remote.SerializerFactory; import mil.nga.giat.geowave.core.index.Mergeable; import mil.nga.giat.geowave.core.index.Persistable; import mil.nga.giat.geowave.core.index.PersistenceUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class RasterTile<T extends Persistable> implements Mergeable { private final static Logger LOGGER = LoggerFactory.getLogger(RasterTile.class); private DataBuffer dataBuffer; private T metadata; protected RasterTile() { super(); } public RasterTile( final DataBuffer dataBuffer, final T metadata ) { this.dataBuffer = dataBuffer; this.metadata = metadata; } public DataBuffer getDataBuffer() { return dataBuffer; } public T getMetadata() { return metadata; } protected static byte[] getDataBufferBinary( final DataBuffer dataBuffer ) { final SerializableState serializableDataBuffer = SerializerFactory.getState(dataBuffer); try { final ByteArrayOutputStream baos = new ByteArrayOutputStream(); final ObjectOutputStream oos = new ObjectOutputStream( baos); oos.writeObject(serializableDataBuffer); return baos.toByteArray(); } catch (final IOException e) { LOGGER.warn( "Unable to serialize data buffer", e); } return new byte[] {}; } protected static DataBuffer getDataBuffer( final byte[] binary ) throws IOException, ClassNotFoundException { final ByteArrayInputStream bais = new ByteArrayInputStream( binary); final ObjectInputStream ois = new ObjectInputStream( bais); final Object o = ois.readObject(); if ((o instanceof SerializableState) && (((SerializableState) o).getObject() instanceof DataBuffer)) { return (DataBuffer) ((SerializableState) o).getObject(); } return null; } @Override public byte[] toBinary() { final byte[] dataBufferBinary = getDataBufferBinary(dataBuffer); byte[] metadataBytes; if (metadata != null) { metadataBytes = PersistenceUtils.toBinary(metadata); } else { metadataBytes = new byte[] {}; } final ByteBuffer buf = ByteBuffer.allocate(metadataBytes.length + dataBufferBinary.length + 4); buf.putInt(metadataBytes.length); buf.put(metadataBytes); buf.put(dataBufferBinary); return buf.array(); } @Override public void fromBinary( final byte[] bytes ) { try { final ByteBuffer buf = ByteBuffer.wrap(bytes); final int metadataLength = buf.getInt(); if (metadataLength > 0) { final byte[] metadataBytes = new byte[metadataLength]; buf.get(metadataBytes); metadata = (T) PersistenceUtils.fromBinary( metadataBytes, Persistable.class); } final byte[] dataBufferBytes = new byte[bytes.length - metadataLength - 4]; buf.get(dataBufferBytes); dataBuffer = getDataBuffer(dataBufferBytes); } catch (final Exception e) { LOGGER.warn( "Unable to deserialize data buffer", e); } } public void setDataBuffer( final DataBuffer dataBuffer ) { this.dataBuffer = dataBuffer; } public void setMetadata( final T metadata ) { this.metadata = metadata; } @Override public void merge( final Mergeable merge ) { // This will get wrapped as a MergeableRasterTile by the combiner to // support merging } }