package me.osm.gazetter.striper;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.json.JSONArray;
import org.json.JSONObject;
/**
* Wrapper around @see JSONObject.
*
* Provides copy capabilities and writes features out with certain
* order of keys.
* */
public final class JSONFeature extends JSONObject {
public static JSONObject copy(JSONObject properties) {
@SuppressWarnings("unchecked")
Set<String> keys = properties.keySet();
return new JSONObject(properties, keys.toArray(new String[keys.size()]));
}
public JSONFeature(String line) {
super(line);
}
@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public Iterator keys() {
List<String> keys = new ArrayList<String>(keySet());
Collections.sort(keys, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
int i1 = "id".equals(o1) ? 0
: "ftype".equals(o1) ? 1
: GeoJsonWriter.TIMESTAMP.equals(o1) ? 2
: "action".equals(o1) ? 3
: "md5".equals(o2) ? 4
: "hhash".equals(o2) ? 5
: 10;
int i2 = "id".equals(o2) ? 0
: "ftype".equals(o2) ? 1
: GeoJsonWriter.TIMESTAMP.equals(o2) ? 2
: "action".equals(o2) ? 3
: "md5".equals(o2) ? 4
: "hhash".equals(o2) ? 5
: 10;
if(i1 == 10 && i2 == 10) {
return o1.compareTo(o2);
}
return i1 - i2;
}
});
return keys.iterator();
}
/**
* Instanciate copy (not deep, only direct children will be copied)
* */
public JSONFeature (JSONObject obj) {
super(obj, JSONObject.getNames(obj));
}
/**
* Instanciate copy (not deep, only direct children will be copied)
* but copy only provided keys
* */
public JSONFeature (JSONObject obj, String[] keys) {
super(obj, JSONObject.getNames(obj));
}
/**
* Default constructor
* */
public JSONFeature() {
super();
}
/**
* Copy id and tags
* */
public static JSONObject asRefer(JSONObject feature) {
JSONObject result = new JSONObject();
result.put("id", feature.getString("id"));
result.put(GeoJsonWriter.PROPERTIES, feature.getJSONObject(GeoJsonWriter.PROPERTIES));
return result;
}
/**
* Copy id and tags for collection
* */
public static List<JSONObject> asRefers(Collection<JSONObject> features) {
List<JSONObject> result = new ArrayList<>();
if(features != null) {
for(JSONObject obj : features) {
result.add(asRefer(obj));
}
}
return result;
}
/**
* Copy id and tags for collection
* */
public static List<JSONObject> asRefers(JSONArray features) {
List<JSONObject> result = new ArrayList<>();
if(features != null) {
for(int i = 0; i < features.length(); i++) {
result.add(asRefer(features.getJSONObject(i)));
}
}
return result;
}
@Override
public int hashCode() {
if (has("id")) {
if(get("timestamp") != null) {
return get("id").hashCode() * 123 + get("timestamp").hashCode();
}
else {
return get("id").hashCode();
}
}
else {
return super.hashCode();
}
}
@Override
public boolean equals(Object obj) {
if(obj == null) {
return false;
}
if(obj instanceof JSONFeature) {
return hashCode() == obj.hashCode();
}
return super.equals(obj);
}
@SuppressWarnings("unchecked")
public static void merge(JSONObject result, JSONObject forMerge) {
for(String key : (Collection<String>)forMerge.keySet()) {
result.put(key, forMerge.get(key));
}
}
}