/**
Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved.
Contact:
SYSTAP, LLC DBA Blazegraph
2501 Calvert ST NW #106
Washington, DC 20008
licenses@blazegraph.com
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Created on Feb 10, 2016
*/
package com.bigdata.service.geospatial;
import java.io.Serializable;
import org.apache.log4j.Logger;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import com.bigdata.rdf.internal.impl.extensions.InvalidGeoSpatialDatatypeConfigurationError;
/**
* Configuration of a single field/component in a given geospatial (multi-dimensional)
* custom data type.
*
* @author <a href="mailto:ms@metaphacts.com">Michael Schmidt</a>
* @version $Id$
*/
public class GeoSpatialDatatypeFieldConfiguration implements Serializable {
private static final long serialVersionUID = 1L;
final static private transient Logger log =
Logger.getLogger(GeoSpatialDatatypeFieldConfiguration.class);
private final static String JSON_STR_VALUETYPE = "valueType";
private final static String JSON_STR_MINVALUE = "minValue";
private final static String JSON_STR_MULTIPLIER = "multiplier";
private final static String JSON_STR_SERVICEMAPPING = "serviceMapping";
/**
* We support fields of values LONG and DOUBLE right now. Note that DOUBLE
* values are internally converted to LONG based on the given precision.
*/
public enum ValueType {
LONG,
DOUBLE
}
/**
* Service mapping.
*/
public enum ServiceMapping {
LATITUDE,
LONGITUDE,
TIME,
COORD_SYSTEM,
CUSTOM
}
/**
* The valueType of the field.
*/
private final ValueType valueType;
/**
* The minimum value defining a shift in the bits. May be null (meaning there is no minValue defined).
*/
private Long minValue;
/**
* The multiplier (aka precision). Defaults to 1 (identity element for multiplication).
*/
private long multiplier;
/**
* Mapping to the service. If serviceMapping==CUSTOM, this is a string
* defined in variable customServiceMapping, otherwise the latter is null.
*/
private ServiceMapping serviceMapping = ServiceMapping.CUSTOM; // default
/**
* Custom service mapping string.
*/
private String customServiceMapping;
public GeoSpatialDatatypeFieldConfiguration(JSONObject fieldJson) throws InvalidGeoSpatialDatatypeConfigurationError {
/**
* Parse JSON structure such as:
* { "valueType": "LONG", "multiplier": "1", "minVal" : "0" , "serviceMapping" : "COORD_SYSTEM" },
* where minVal and multiplier are optional, the other two components are mandatory.
*/
try {
// component 1: valueType (required)
valueType = ValueType.valueOf((String)fieldJson.get(JSON_STR_VALUETYPE));
// component 2: minValue (optional)
minValue=null; // default
if (fieldJson.has(JSON_STR_MINVALUE)) {
final String minValueStr = (String)fieldJson.get(JSON_STR_MINVALUE);
if (minValueStr!=null && !minValueStr.isEmpty()) {
minValue = Long.valueOf(minValueStr);
} // else: stay with default
}
// component 3: multiplier (optional)
multiplier=1; // default
if (fieldJson.has(JSON_STR_MULTIPLIER)) {
final String multiplierStr = (String)fieldJson.get(JSON_STR_MULTIPLIER);
if (multiplierStr!=null && !multiplierStr.isEmpty()) {
multiplier = Long.valueOf(multiplierStr);
}
}
// component 4: serviceMapping (required)
final String serviceMappingStr = (String)fieldJson.get(JSON_STR_SERVICEMAPPING);
try {
serviceMapping = ServiceMapping.valueOf((String)fieldJson.get(JSON_STR_SERVICEMAPPING));
customServiceMapping = null;
} catch (Exception e) {
customServiceMapping = serviceMappingStr;
}
} catch (NumberFormatException e) {
log.warn("Expecting values that are of type long for minValue and multiplier.");
throw new InvalidGeoSpatialDatatypeConfigurationError(e.getMessage()); // forward exception
} catch (JSONException e) {
log.warn("Field could not be parsed: " + e.getMessage());
throw new InvalidGeoSpatialDatatypeConfigurationError(e.getMessage()); // forward exception
} catch (Exception e) {
log.warn("Exception while initializing field: " + e.getMessage());
throw new InvalidGeoSpatialDatatypeConfigurationError(e.getMessage()); // forward exception
}
}
/**
* Alternative constructor (to ease writing test cases). If used without test cases,
* please use with care -- this constructor does not implement input validation.
*
* @param uri
* @param fields
*/
public GeoSpatialDatatypeFieldConfiguration(
final ValueType valueType, final Long minValue,
final long multiplier, final ServiceMapping serviceMapping,
final String customServiceMapping) {
this.valueType = valueType;
this.minValue = minValue;
this.multiplier = multiplier;
this.serviceMapping = serviceMapping;
this.customServiceMapping = customServiceMapping;
}
public ValueType getValueType() {
return valueType;
}
public Long getMinValue() {
return minValue;
}
public long getMultiplier() {
return multiplier;
}
public ServiceMapping getServiceMapping() {
return serviceMapping;
}
public String getCustomServiceMapping() {
return customServiceMapping;
}
}