package org.activityinfo.model.resource;
import com.google.gson.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
public class Resources {
/**
* The resource id of the user database.
*
* All registered users are resources owned by this
* resource.
*/
public static final String USER_DATABASE_ID = "_users";
public static final String ROOT_RESOURCE_ID = "_root";
public static Resource createResource() {
return new Resource();
}
public static Resource createResource(Record record) {
Resource resource = new Resource();
resource.setId(ResourceId.generateId());
resource.getProperties().putAll(record.getProperties());
return resource;
}
/**
* @return {@code} true if {@code x} and {@code y} have the same identity
* and have equal properties
*/
public static boolean deepEquals(Resource x, Resource y) {
if(x == y) {
return true;
}
if(!Objects.equals(x.getId(), y.getId()) ||
!Objects.equals(x.getOwnerId(), y.getOwnerId())) {
return false;
}
if(x.getProperties().size() != y.getProperties().size()) {
return false;
}
for(String propertyName : x.getProperties().keySet()) {
if(!Objects.equals(x.get(propertyName), y.get(propertyName))) {
return false;
}
}
return true;
}
public static Resource fromJson(String json) {
JsonParser parser = new JsonParser();
JsonObject resourceObject = parser.parse(json).getAsJsonObject();
return fromJson(resourceObject);
}
public static Resource fromJson(JsonObject resourceObject) {
Resource resource = Resources.createResource();
for(Map.Entry<String, JsonElement> property : resourceObject.entrySet()) {
String name = property.getKey();
switch (name) {
case "@id":
resource.setId(ResourceId.valueOf(resourceObject.getAsJsonPrimitive(name).getAsString()));
break;
case "@owner":
resource.setOwnerId(ResourceId.valueOf(resourceObject.getAsJsonPrimitive(name).getAsString()));
break;
default:
// normal value
if (!property.getValue().isJsonNull()) {
resource.set(property.getKey(), propertyFromJson(property.getValue()));
}
break;
}
}
return resource;
}
private static Object propertyFromJson(JsonElement propertyValue) {
assert !propertyValue.isJsonNull();
if(propertyValue.isJsonPrimitive()) {
JsonPrimitive value = propertyValue.getAsJsonPrimitive();
if(value.isString()) {
return value.getAsString();
} else if(value.isNumber()) {
return value.getAsDouble();
} else if(value.isBoolean()) {
return value.getAsBoolean();
} else {
throw new UnsupportedOperationException("value: " + value);
}
} else if(propertyValue.isJsonArray()) {
return arrayFromJson(propertyValue);
} else if(propertyValue.isJsonObject()) {
return recordFromJson(propertyValue.getAsJsonObject());
} else {
throw new UnsupportedOperationException("value: " + propertyValue);
}
}
private static Object arrayFromJson(JsonElement propertyValue) {
List list = new ArrayList();
JsonArray array = propertyValue.getAsJsonArray();
for(int i=0;i!=array.size();++i) {
list.add(propertyFromJson(array.get(i)));
}
return list;
}
private static Record recordFromJson(JsonObject jsonObject) {
Record record = new Record();
for(Map.Entry<String, JsonElement> field : jsonObject.entrySet()) {
if(!field.getValue().isJsonNull()) {
record.set(field.getKey(), propertyFromJson(field.getValue()));
}
}
return record;
}
public static String toJson(Resource resource) {
JsonObject resourceObject = toJsonObject(resource);
return resourceObject.toString();
}
public static JsonObject toJsonObject(Resource resource) {
JsonObject resourceObject = new JsonObject();
resourceObject.addProperty("@id", resource.getId().asString());
resourceObject.addProperty("@owner", resource.getOwnerId().asString());
for(Map.Entry<String, Object> property : resource.getProperties().entrySet()) {
if(property.getValue() != null) {
resourceObject.add(property.getKey(), propertyValueToJson(property.getValue()));
}
}
return resourceObject;
}
private static JsonElement propertyValueToJson(Object value) {
if(value instanceof String) {
return new JsonPrimitive((String)value);
} else if(value instanceof Number) {
return new JsonPrimitive((Number)value);
} else if(value instanceof Boolean) {
return new JsonPrimitive((Boolean)value);
} else if(value instanceof List) {
return toJsonArray((List)value);
} else if(value instanceof Record) {
return toJsonObject((Record)value);
} else {
throw new UnsupportedOperationException("value: " + value + " (" + value.getClass().getName() + ")") ;
}
}
public static JsonElement toJsonObject(Record value) {
JsonObject jsonObject = new JsonObject();
for(Map.Entry<String, Object> property : value.getProperties().entrySet()) {
if(property.getValue() != null) {
jsonObject.add(property.getKey(), propertyValueToJson(property.getValue()));
}
}
return jsonObject;
}
private static JsonElement toJsonArray(List array) {
JsonArray jsonArray = new JsonArray();
for(Object element : array) {
jsonArray.add(propertyValueToJson(element));
}
return jsonArray;
}
}