/* * 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.util.List; import javax.validation.constraints.NotNull; import org.bson.BSONObject; import org.json.JSONException; import org.json.JSONObject; import org.obiba.magma.MagmaRuntimeException; import org.obiba.magma.NoSuchValueSetException; import org.obiba.magma.Timestamps; import org.obiba.magma.Value; import org.obiba.magma.ValueLoaderFactory; import org.obiba.magma.ValueSet; import org.obiba.magma.ValueTable; import org.obiba.magma.ValueType; import org.obiba.magma.VariableEntity; import org.obiba.magma.datasource.mongodb.converter.ValueConverter; import org.obiba.magma.type.BinaryType; import org.obiba.magma.type.DateTimeType; import org.obiba.magma.type.TextType; import com.google.common.collect.Lists; import com.mongodb.BasicDBObjectBuilder; import com.mongodb.DBObject; import static org.obiba.magma.datasource.mongodb.MongoDBValueTableWriter.GRID_FILE_ID; import static org.obiba.magma.datasource.mongodb.MongoDBValueTableWriter.GRID_FILE_MD5; import static org.obiba.magma.datasource.mongodb.MongoDBValueTableWriter.GRID_FILE_SIZE; class MongoDBValueSet implements ValueSet { private final MongoDBValueTable valueTable; private final VariableEntity entity; private BSONObject object; private final MongoDBValueSetFetcher fetcher; MongoDBValueSet(MongoDBValueTable valueTable, VariableEntity entity) { this.valueTable = valueTable; this.entity = entity; this.fetcher = new MongoDBValueSetFetcher(valueTable); } @Override public ValueTable getValueTable() { return valueTable; } @Override public VariableEntity getVariableEntity() { return entity; } Value getValue(MongoDBVariable variable) { BSONObject valueObject = getDBObject(); ValueType valueType = variable.getValueType(); return valueType.equals(BinaryType.get()) ? getBinaryValue(variable, valueObject) : ValueConverter.unmarshall(variable, valueObject); } @SuppressWarnings("unchecked") private Value getBinaryValue(MongoDBVariable variable, BSONObject valueObject) { return getBinaryValue(valueTable.getMongoDBFactory(), variable, valueObject); } public static Value getBinaryValue(MongoDBFactory mongoDBFactory, MongoDBVariable variable, BSONObject valueObject) { ValueLoaderFactory factory = new MongoDBValueLoaderFactory(mongoDBFactory); BSONObject fileMetadata = (BSONObject) valueObject.get(variable.getId()); if(fileMetadata == null) { return TextType.get().nullValue(); } if(variable.isRepeatable()) { List<Value> sequenceValues = Lists.newArrayList(); for(BSONObject occurrenceObj : (Iterable<BSONObject>) fileMetadata) { sequenceValues.add(getBinaryMetadata(occurrenceObj)); } return BinaryType.get().sequenceOfReferences(factory, TextType.get().sequenceOf(sequenceValues)); } return BinaryType.get().valueOfReference(factory, getBinaryMetadata(fileMetadata)); } private static Value getBinaryMetadata(BSONObject valueObject) { if(!valueObject.containsField(GRID_FILE_ID)) { return TextType.get().nullValue(); } try { JSONObject properties = new JSONObject(); properties.put(GRID_FILE_ID, valueObject.get(GRID_FILE_ID)); properties.put(GRID_FILE_SIZE, valueObject.containsField(GRID_FILE_SIZE) ? valueObject.get(GRID_FILE_SIZE) : Integer.valueOf(0)); properties.put(GRID_FILE_MD5, valueObject.get(GRID_FILE_MD5)); return TextType.get().valueOf(properties.toString()); } catch(JSONException e) { throw new MagmaRuntimeException(e); } } @NotNull @Override public Timestamps getTimestamps() { return new Timestamps() { @NotNull @Override public Value getLastUpdate() { return getTimestamp("updated"); } @NotNull @Override public Value getCreated() { return getTimestamp("created"); } private Value getTimestamp(String key) { BSONObject timestamps = (BSONObject) getDBObject().get(MongoDBDatasource.TIMESTAMPS_FIELD); return ValueConverter.unmarshall(DateTimeType.get(), timestamps.get(key)); } }; } @NotNull private BSONObject getDBObject() { if(object == null) { object = fetcher.getDBObject(entity); if(object == null) { throw new NoSuchValueSetException(valueTable, entity); } } return object; } void setDBObject(BSONObject object) { this.object = object; } }