/* * Copyright (c) 2017 OBiBa. All rights reserved. * * This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.obiba.magma.datasource.mongodb; import java.io.ByteArrayOutputStream; import java.io.IOException; import javax.annotation.Nullable; import javax.validation.constraints.NotNull; import org.bson.types.ObjectId; import org.json.JSONException; import org.json.JSONObject; import org.obiba.magma.MagmaRuntimeException; import org.obiba.magma.Value; import org.obiba.magma.ValueLoader; import org.obiba.magma.ValueLoaderFactory; import com.mongodb.gridfs.GridFSDBFile; import static org.obiba.magma.datasource.mongodb.MongoDBValueTableWriter.GRID_FILE_ID; import static org.obiba.magma.datasource.mongodb.MongoDBValueTableWriter.GRID_FILE_SIZE; public class MongoDBValueLoaderFactory implements ValueLoaderFactory { private final MongoDBFactory mongoDBFactory; public MongoDBValueLoaderFactory(MongoDBFactory mongoDBFactory) { this.mongoDBFactory = mongoDBFactory; } @Override public ValueLoader create(Value valueRef, @Nullable Integer occurrence) { return new MongoDBBinaryValueLoader(mongoDBFactory, valueRef); } private static final class MongoDBBinaryValueLoader implements ValueLoader { private static final long serialVersionUID = -5992432763907068814L; private final MongoDBFactory mongoDBFactory; private final Value valueRef; private byte[] value; private MongoDBBinaryValueLoader(MongoDBFactory mongoDBFactory, Value valueRef) { this.mongoDBFactory = mongoDBFactory; this.valueRef = valueRef; } @Override public boolean isNull() { return valueRef == null || valueRef.isNull(); } @NotNull @Override public Object getValue() { if(value == null) { String json = (String) valueRef.getValue(); try { JSONObject jsonObject = new JSONObject(json); if(jsonObject.has(GRID_FILE_ID)) { value = getByteArray(jsonObject.getString(GRID_FILE_ID)); } } catch(JSONException e) { throw new MagmaRuntimeException("Cannot retrieve grid file Id for " + json, e); } } return value; } private byte[] getByteArray(String fileId) { try(ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { GridFSDBFile file = mongoDBFactory.getGridFS().findOne(new ObjectId(fileId)); file.writeTo(outputStream); return outputStream.toByteArray(); } catch(IOException e) { throw new MagmaRuntimeException("Cannot retrieve content of gridFsFile [" + fileId + "]", e); } } @Override public long getLength() { if(valueRef.isNull()) return 0; try { JSONObject properties = new JSONObject((String) valueRef.getValue()); return properties.has(GRID_FILE_SIZE) ? properties.getLong(GRID_FILE_SIZE) : 0; } catch(JSONException e) { throw new MagmaRuntimeException("Cannot retrieve grid file size for " + valueRef.getValue(), e); } } } }