uk.ac.horizon.artcodes.ExperienceParser.java Source code

Java tutorial

Introduction

Here is the source code for uk.ac.horizon.artcodes.ExperienceParser.java

Source

/*
 * 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;
    }
}