Java tutorial
// This file is part of MongoMVCC. // // Copyright (c) 2012 Fraunhofer IGD // // MongoMVCC is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // MongoMVCC is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with MongoMVCC. If not, see <http://www.gnu.org/licenses/>. package de.fhg.igd.mongomvcc.impl; import java.io.BufferedInputStream; import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.ByteBuffer; import java.nio.FloatBuffer; import java.util.ArrayList; import java.util.List; import com.mongodb.BasicDBObject; import com.mongodb.gridfs.GridFS; import com.mongodb.gridfs.GridFSDBFile; import com.mongodb.gridfs.GridFSInputFile; import de.fhg.igd.mongomvcc.VCounter; import de.fhg.igd.mongomvcc.helper.FloatArrayInputStream; /** * The default convert strategy handles different types of binary data * which is stores in a MongoDB GridFS * @author Michel Kraemer */ public class DefaultConvertStrategy implements ConvertStrategy { /** * Binary types */ private static final int BYTEARRAY = 0; private static final int INPUTSTREAM = 1; private static final int BYTEBUFFER = 2; private static final int FLOATARRAY = 3; private static final int FLOATBUFFER = 4; /** * The metadata attribute that denotes the binary type */ private static final String BINARY_TYPE = "binary_type"; /** * The MongoDB GridFS storing binary data */ private final GridFS _gridFS; /** * A counter to generate replacement OIDs */ private final VCounter _counter; /** * The files that have been created by this convert strategy */ private final List<GridFSInputFile> _convertedFiles = new ArrayList<GridFSInputFile>(); /** * Constructs a new convert strategy * @param gridFS the MongoDB GridFS storing binary data * @param counter a counter to generate replacement OIDs */ public DefaultConvertStrategy(GridFS gridFS, VCounter counter) { _gridFS = gridFS; _counter = counter; } /** * @return the files that have been created by this convert strategy */ public List<GridFSInputFile> getConvertedFiles() { return _convertedFiles; } @Override public long convert(Object data) { GridFSInputFile file; if (data instanceof byte[]) { file = _gridFS.createFile((byte[]) data); file.put(BINARY_TYPE, BYTEARRAY); } else if (data instanceof float[]) { file = _gridFS.createFile(new FloatArrayInputStream((float[]) data)); file.put(BINARY_TYPE, FLOATARRAY); } else if (data instanceof InputStream) { file = _gridFS.createFile((InputStream) data); file.put(BINARY_TYPE, INPUTSTREAM); } else if (data instanceof ByteBuffer) { ByteBuffer bb = (ByteBuffer) data; byte[] buf; if (bb.hasArray()) { buf = bb.array(); } else { bb.rewind(); buf = new byte[bb.remaining()]; bb.get(buf); } file = _gridFS.createFile(buf); file.put(BINARY_TYPE, BYTEBUFFER); } else if (data instanceof FloatBuffer) { FloatBuffer bb = (FloatBuffer) data; float[] buf; if (bb.hasArray()) { buf = bb.array(); } else { bb.rewind(); buf = new float[bb.remaining()]; bb.get(buf); } file = _gridFS.createFile(new FloatArrayInputStream(buf)); file.put(BINARY_TYPE, FLOATBUFFER); } else { return 0; } long oid = _counter.getNextId(); file.put(MongoDBVLargeCollection.OID, oid); _convertedFiles.add(file); return oid; } @Override public Object convert(long oid) throws IOException { GridFSDBFile file = _gridFS.findOne(new BasicDBObject(MongoDBVLargeCollection.OID, oid)); if (file == null) { return null; } int type = (Integer) file.get(BINARY_TYPE); Object r; if (type == BYTEARRAY) { r = toByteArray(file); } else if (type == INPUTSTREAM) { r = file.getInputStream(); } else if (type == BYTEBUFFER) { r = ByteBuffer.wrap(toByteArray(file)); } else if (type == FLOATARRAY) { r = toFloatArray(file); } else if (type == FLOATBUFFER) { r = FloatBuffer.wrap(toFloatArray(file)); } else { //no information. simply forward the input stream r = file.getInputStream(); } return r; } /** * Converts the contents of a GridFS file to a byte array * @param file the file * @return the byte array * @throws IOException if the file could not be read */ private byte[] toByteArray(GridFSDBFile file) throws IOException { InputStream is = file.getInputStream(); int len = (int) file.getLength(); int pos = 0; byte[] b = new byte[len]; while (len > 0) { int read = is.read(b, pos, len); pos += read; len -= read; } return b; } /** * Converts the contents of a GridFS file to a float array * @param file the file * @return the float array * @throws IOException if the file could not be read */ private float[] toFloatArray(GridFSDBFile file) throws IOException { DataInputStream is = new DataInputStream(new BufferedInputStream(file.getInputStream())); int len = (int) file.getLength() / (Float.SIZE / Byte.SIZE); float[] b = new float[len]; for (int i = 0; i < len; ++i) { b[i] = is.readFloat(); } return b; } }