/* * 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.type; import java.io.Serializable; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Collection; import java.util.List; import javax.annotation.Nullable; import javax.validation.constraints.NotNull; import org.json.JSONArray; import org.json.JSONException; import org.obiba.magma.Coordinate; import org.obiba.magma.MagmaEngine; import org.obiba.magma.MagmaRuntimeException; import org.obiba.magma.Value; import org.obiba.magma.ValueSequence; import com.google.common.collect.Iterables; public class LineStringType extends JSONAwareValueType { private static final long serialVersionUID = 1415659902603617833L; @SuppressWarnings("StaticNonFinalField") private static WeakReference<LineStringType> instance; private LineStringType() { } @SuppressWarnings("ConstantConditions") @edu.umd.cs.findbugs.annotations.SuppressWarnings("NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE") @NotNull public static LineStringType get() { if(instance == null || instance.get() == null) { instance = MagmaEngine.get().registerInstance(new LineStringType()); } return instance.get(); } @NotNull @Override public String getName() { return "linestring"; } @Override public Class<?> getJavaClass() { List<Coordinate> line; line = new ArrayList<>(); return line.getClass(); } @Override public boolean acceptsJavaClass(@NotNull Class<?> clazz) { List<Coordinate> line; line = new ArrayList<>(); return line.getClass().isAssignableFrom(clazz); } @Override public boolean isDateTime() { return false; } @Override public boolean isNumeric() { return false; } @Override public boolean isGeo() { return true; } @NotNull @Override public Value valueOf(@Nullable String string) { if(string == null) { return nullValue(); } try { JSONArray array = new JSONArray(string.trim()); return valueOf(array); } catch(JSONException e) { throw new MagmaRuntimeException("Invalid LineString format", e); } } public Value valueOf(@Nullable JSONArray array) { if(array == null) { return nullValue(); } Collection<Coordinate> line = new ArrayList<>(array.length()); for(int i = 0; i < array.length(); i++) { try { line.add(Coordinate.getCoordinateFrom(array.get(i))); } catch(JSONException e) { throw new MagmaRuntimeException("Invalid LineString format", e); } } if(line.isEmpty()) { throw new MagmaRuntimeException("The LineString can't be empty"); } return Factory.newValue(this, (Serializable) line); } @NotNull @Override public Value valueOf(@Nullable Object object) { if(object == null) { return nullValue(); } Class<?> type = object.getClass(); if(type.equals(String.class)) { return valueOf((String) object); } if(type.equals(JSONArray.class)) { return valueOf((JSONArray) object); } if(type.equals(getJavaClass())) { Collection<Coordinate> line = new ArrayList<>(); for(Object o : (List<?>) object) { line.add(Coordinate.getCoordinateFrom(o)); } if(line.isEmpty()) { throw new MagmaRuntimeException("The LineString can't be empty"); } return Factory.newValue(this, (Serializable) line); } if(object instanceof Value) { return convert((Value)object); } return valueOf(object.toString()); } @SuppressWarnings("unchecked") @Override public int compare(Value o1, Value o2) { if(o1.isNull() && o2.isNull()) return 0; if(o1.isNull()) return -1; if(o2.isNull()) return 1; Iterable<Coordinate> line1 = (Iterable<Coordinate>) o1.getValue(); Iterable<Coordinate> line2 = (Iterable<Coordinate>) o2.getValue(); if(Iterables.size(line1) == Iterables.size(line2)) { if(Iterables.elementsEqual(line1, line2)) return 0; return -1; } if(Iterables.size(line1) < Iterables.size(line2)) { return -1; } return 1; } @Nullable @Override protected String toString(@Nullable ValueSequence sequence) { return "[" + super.toString(sequence) + "]"; } }