/*
* Artcodes recognises a different marker scheme that allows the
* creation of aesthetically pleasing, even beautiful, codes.
* Copyright (C) 2013-2016 The University of Nottingham
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package uk.ac.horizon.artcodes;
import android.content.Context;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import uk.ac.horizon.artcodes.model.Experience;
import uk.ac.horizon.artcodes.scanner.R;
public class ExperienceParser
{
private static class ExperienceTypeAdapterFactor implements TypeAdapterFactory
{
@SuppressWarnings("unchecked")
// we use a runtime check to guarantee that 'C' and 'T' are equal
public final <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type)
{
return type.getRawType() == Experience.class ? (TypeAdapter<T>) customizeMyClassAdapter(gson, (TypeToken<Experience>) type) : null;
}
private TypeAdapter<Experience> customizeMyClassAdapter(Gson gson, TypeToken<Experience> type)
{
final TypeAdapter<Experience> delegate = gson.getDelegateAdapter(this, type);
final TypeAdapter<JsonElement> elementAdapter = gson.getAdapter(JsonElement.class);
return new TypeAdapter<Experience>()
{
@Override
public Experience read(JsonReader in) throws IOException
{
JsonElement tree = elementAdapter.read(in);
if (tree.isJsonObject())
{
JsonObject jsonObject = tree.getAsJsonObject();
if (jsonObject.has("threshold") && jsonObject.get("threshold").isJsonPrimitive())
{
jsonObject.remove("threshold");
}
if (jsonObject.has("id"))
{
String id = jsonObject.get("id").getAsString();
if (!id.contains(":"))
{
jsonObject.addProperty("id", "http://aestheticodes.appspot.com/experience/" + id);
}
}
if (!jsonObject.has("pipeline"))
{
JsonArray array = new JsonArray();
array.add(new JsonPrimitive("tile"));
if (jsonObject.has("embeddedChecksum")
&& jsonObject.get("embeddedChecksum") instanceof JsonPrimitive
&& jsonObject.get("embeddedChecksum").getAsBoolean())
{
array.add(new JsonPrimitive("detectEmbedded"));
}
else
{
array.add(new JsonPrimitive("detect"));
}
jsonObject.add("pipeline", array);
}
if (jsonObject.has("markers"))
{
JsonElement markers = jsonObject.get("markers");
jsonObject.add("actions", markers);
if (markers.isJsonArray())
{
JsonArray markerArray = markers.getAsJsonArray();
for (JsonElement element : markerArray)
{
if (element.isJsonObject())
{
JsonObject actionObject = element.getAsJsonObject();
if (actionObject.has("title"))
{
actionObject.add("name", actionObject.get("title"));
}
if (actionObject.has("action"))
{
actionObject.add("url", actionObject.get("action"));
}
if (actionObject.has("code"))
{
JsonArray codeArray = new JsonArray();
String codeString = actionObject.get("code").getAsString();
if(codeString.contains("+"))
{
String[] codes = codeString.split("\\+");
for(String code: codes)
{
codeArray.add(new JsonPrimitive(code));
}
actionObject.addProperty("match", "all");
}
else if(codeString.contains(">"))
{
String[] codes = codeString.split(">");
for(String code: codes)
{
codeArray.add(new JsonPrimitive(code));
}
actionObject.addProperty("match", "sequence");
}
else
{
codeArray.add(codeString);
actionObject.addProperty("match", "any");
}
actionObject.add("codes", codeArray);
}
}
}
}
}
}
return delegate.fromJsonTree(tree);
}
@Override
public void write(JsonWriter out, Experience value) throws IOException
{
delegate.write(out, value);
}
};
}
}
private static Gson gson;
public static Gson createGson(Context context)
{
if (gson == null)
{
GsonBuilder builder = new GsonBuilder();
if (context == null || Feature.get(context, R.bool.feature_load_old_experiences).isEnabled())
{
builder.registerTypeAdapterFactory(new ExperienceTypeAdapterFactor());
}
gson = builder.create();
}
return gson;
}
}