blob: 47b7c76a0099a9a96bcfc4e1e559a71ca2452aea [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. The ASF
* licenses this file to You under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package org.apache.hugegraph.backend.query.serializer;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.apache.hugegraph.backend.query.Condition;
import org.apache.hugegraph.type.define.Directions;
import com.google.common.collect.ImmutableMap;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.reflect.TypeToken;
public class QueryAdapter extends AbstractSerializerAdapter<Condition> {
static ImmutableMap<String, Type> cls =
ImmutableMap.<String, Type>builder()
// TODO: uncomment later
.put("N", Condition.Not.class)
.put("A", Condition.And.class)
.put("O", Condition.Or.class)
.put("S", Condition.SyspropRelation.class)
.put("U", Condition.UserpropRelation.class)
.build();
static boolean isPrimitive(Class clz) {
try {
return (clz == Date.class) || ((Class) clz.getField("TYPE").get(null)).isPrimitive();
} catch (Exception e) {
return false;
}
}
@Override
public Map<String, Type> validType() {
return cls;
}
@Override
public Condition deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
Condition condition = super.deserialize(json, typeOfT, context);
if (condition instanceof Condition.Relation) {
JsonObject object = json.getAsJsonObject();
if (object.has("el")) {
JsonElement elElement = object.get("el");
JsonElement valueElement = elElement.getAsJsonObject().get("value");
if (valueElement.isJsonObject()) {
String cls = valueElement.getAsJsonObject().get("cls").getAsString();
try {
Class actualClass = Class.forName(cls);
Object obj = context.deserialize(valueElement, actualClass);
((Condition.Relation) condition).value(obj);
} catch (ClassNotFoundException e) {
throw new JsonParseException(e.getMessage());
}
} else if (elElement.getAsJsonObject().has("valuecls")) {
if (valueElement.isJsonArray()) {
String cls = elElement.getAsJsonObject().get("valuecls").getAsString();
try {
Class actualClass = Class.forName(cls);
Type type = TypeToken.getParameterized(ArrayList.class, actualClass)
.getType();
Object value = context.deserialize(valueElement, type);
((Condition.Relation) condition).value(value);
} catch (ClassNotFoundException e) {
throw new JsonParseException(e.getMessage());
}
} else {
String cls = elElement.getAsJsonObject().get("valuecls").getAsString();
try {
Class actualClass = Class.forName(cls);
Object obj = context.deserialize(valueElement, actualClass);
((Condition.Relation) condition).value(obj);
} catch (ClassNotFoundException e) {
throw new JsonParseException(e.getMessage());
}
}
} else if (valueElement.isJsonPrimitive() &&
valueElement.getAsJsonPrimitive().isString()) {
switch ((String) ((Condition.Relation) condition).value()) {
case "OUT":
((Condition.Relation) condition).value(Directions.OUT);
break;
case "IN":
((Condition.Relation) condition).value(Directions.IN);
break;
default:
break;
}
}
}
}
return condition;
}
@Override
public JsonElement serialize(Condition src, Type typeOfSrc, JsonSerializationContext context) {
JsonElement result = super.serialize(src, typeOfSrc, context);
if (src instanceof Condition.Relation) {
JsonObject object = result.getAsJsonObject();
JsonElement valueElement = object.get("el").getAsJsonObject().get("value");
if (valueElement.isJsonObject()) {
valueElement.getAsJsonObject()
.add("cls",
new JsonPrimitive(
((Condition.Relation) src).value().getClass().getName()));
} else if (isPrimitive(((Condition.Relation) src).value().getClass())) {
object.get("el").getAsJsonObject()
.add("valuecls",
new JsonPrimitive(
((Condition.Relation) src).value().getClass().getName()));
} else if (valueElement.isJsonArray()) {
if (((Condition.Relation) src).value() instanceof List) {
String valueCls =
((List) ((Condition.Relation) src).value()).get(0).getClass().getName();
object.get("el").getAsJsonObject().add("valuecls", new JsonPrimitive(valueCls));
}
}
}
return result;
}
}