org.obiba.magma.datasource.mongodb.converter.ValueConverter.java Source code

Java tutorial

Introduction

Here is the source code for org.obiba.magma.datasource.mongodb.converter.ValueConverter.java

Source

/*
 * Copyright (c) 2013 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.converter;

import java.util.Collection;

import javax.annotation.Nullable;

import org.bson.BSONObject;
import org.obiba.magma.Coordinate;
import org.obiba.magma.MagmaDate;
import org.obiba.magma.Value;
import org.obiba.magma.ValueType;
import org.obiba.magma.Variable;
import org.obiba.magma.datasource.mongodb.MongoDBVariable;
import org.obiba.magma.type.LineStringType;
import org.obiba.magma.type.LocaleType;
import org.obiba.magma.type.PointType;
import org.obiba.magma.type.PolygonType;

import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.mongodb.BasicDBList;

public class ValueConverter {

    private ValueConverter() {
    }

    public static Object marshall(Variable variable, Value value) {
        if (value == null || value.isNull())
            return null;

        if (variable.isRepeatable()) {
            Collection<Object> list = new BasicDBList();
            for (Value val : value.asSequence().getValues()) {
                list.add(marshall(val));
            }
            return list;
        }
        return marshall(value);
    }

    public static Value unmarshall(MongoDBVariable variable, BSONObject object) {
        return unmarshall(variable.getValueType(), variable.isRepeatable(), variable.getId(), object);
    }

    public static Value unmarshall(ValueType type, boolean repeatable, String field, BSONObject object) {
        if (object == null || !object.containsField(field)) {
            return repeatable ? type.nullSequence() : type.nullValue();
        }

        if (repeatable) {
            Iterable<?> values = (Iterable<?>) object.get(field);
            if (values == null)
                return type.nullSequence();
            ImmutableList.Builder<Value> list = ImmutableList.builder();
            for (Object o : values) {
                list.add(unmarshall(type, o));
            }
            return type.sequenceOf(list.build());
        }
        return unmarshall(type, object.get(field));
    }

    public static Value unmarshall(ValueType type, Object value) {
        if (value == null)
            return type.nullValue();

        if (type.isGeo()) {
            // will be turned to a JSON string
            return type.valueOf(value.toString());
        }

        return type.valueOf(value);
    }

    //
    // Private methods
    //

    private static Object marshall(Value value) {
        if (value == null || value.isNull())
            return null;
        ValueType type = value.getValueType();
        Object rawValue = value.getValue();
        if (rawValue instanceof MagmaDate) {
            return ((MagmaDate) rawValue).asDate();
        }
        if (type.isGeo()) {
            return marshallGeo(value);
        }
        return type.equals(LocaleType.get()) ? type.toString(value) : value.getValue();
    }

    @SuppressWarnings("unchecked")
    private static Object marshallGeo(Value value) {
        if (value == null || value.isNull())
            return null;

        ValueType type = value.getValueType();
        if (PointType.get().equals(type)) {
            return marshallPoint((Coordinate) value.getValue());
        }
        if (LineStringType.get().equals(type)) {
            return marshallLine((Iterable<Coordinate>) value.getValue());
        }
        if (PolygonType.get().equals(type)) {
            return marshallPolygon((Iterable<Iterable<Coordinate>>) value.getValue());
        }
        throw new RuntimeException("Geo value type expected: " + value.getValueType());
    }

    private static Object marshallPoint(Coordinate point) {
        return point.toArray();
    }

    private static Iterable<double[]> marshallLine(Iterable<Coordinate> line) {
        return Iterables.transform(line, new Function<Coordinate, double[]>() {
            @Nullable
            @Override
            public double[] apply(@Nullable Coordinate input) {
                return input == null ? null : input.toArray();
            }
        });
    }

    private static Object marshallPolygon(Iterable<Iterable<Coordinate>> line) {
        return Iterables.transform(line, new Function<Iterable<Coordinate>, Iterable<double[]>>() {
            @Nullable
            @Override
            public Iterable<double[]> apply(@Nullable Iterable<Coordinate> input) {
                return input == null ? null : marshallLine(input);
            }
        });
    }

}