blob: 23fe2d34fdbe09b6c8df068f98d7aa02f7b9d5c9 [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.rya.api.domain;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;
import org.apache.rya.api.persist.RdfDAOException;
import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
import com.google.common.base.Preconditions;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
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.JsonSerializer;
public class StatementMetadata {
private static Gson gson = new GsonBuilder().enableComplexMapKeySerialization()
.registerTypeHierarchyAdapter(RyaType.class, new RyaTypeAdapter()).create();
public static StatementMetadata EMPTY_METADATA = new StatementMetadata();
private Map<RyaURI, RyaType> metadataMap = new HashMap<>();
@SuppressWarnings("serial")
private Type type = new TypeToken<Map<RyaURI, RyaType>>(){}.getType();
public StatementMetadata() {}
public StatementMetadata(byte[] value) throws RdfDAOException {
try {
if (value == null) {
metadataMap = new HashMap<>();
} else {
// try to convert back to a json string and then back to the
// map.
String metadataString = new String(value, "UTF8");
metadataMap = gson.fromJson(metadataString, type);
if (metadataMap == null) {
metadataMap = new HashMap<>();
}
}
} catch (UnsupportedEncodingException e) {
throw new RdfDAOException(e);
}
}
public StatementMetadata(String statementMetadata) {
try {
metadataMap = gson.fromJson(statementMetadata, type);
} catch (Exception e) {
throw new RdfDAOException(e);
}
}
public void addMetadata(RyaURI key, RyaType value) {
metadataMap.put(key, value);
}
public Map<RyaURI, RyaType> getMetadata() {
return metadataMap;
}
public String toString() {
return gson.toJson(metadataMap, type);
}
public byte[] toBytes() {
// convert the map to a json string
if (metadataMap.isEmpty()) {
return null;
}
// TODO may want to cache this for performance reasons
try {
return toString().getBytes("UTF8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
public static class RyaTypeAdapter implements JsonSerializer<RyaType>, JsonDeserializer<RyaType> {
@Override
public JsonElement serialize(RyaType src, Type typeOfSrc, JsonSerializationContext context) {
JsonObject result = new JsonObject();
result.add("type", new JsonPrimitive(src.getClass().getName()));
StringBuilder builder = new StringBuilder();
builder.append(src.getData()).append("\u0000").append(src.getDataType().toString());
result.add("properties", new JsonPrimitive(builder.toString()));
return result;
}
@Override
public RyaType deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
JsonObject jsonObject = json.getAsJsonObject();
String type = jsonObject.get("type").getAsString();
JsonElement element = jsonObject.get("properties");
String[] array = element.getAsJsonPrimitive().getAsString().split("\u0000");
Preconditions.checkArgument(array.length == 2);
if(type.equals(RyaURI.class.getName())){
return new RyaURI(array[0]);
} else if(type.equals(RyaType.class.getName())){
RyaType ryaType = new RyaType(SimpleValueFactory.getInstance().createIRI(array[1]), array[0]);
return ryaType;
} else {
throw new IllegalArgumentException("Unparseable RyaType.");
}
}
}
}