net.segoia.event.eventbus.config.json.EventBusJsonConfigLoader.java Source code

Java tutorial

Introduction

Here is the source code for net.segoia.event.eventbus.config.json.EventBusJsonConfigLoader.java

Source

/**
 * event-bus - An event bus framework for event driven programming
 * Copyright (C) 2016  Adrian Cristian Ionescu - https://github.com/acionescu
 *
 * Licensed 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 net.segoia.event.eventbus.config.json;

import java.io.IOException;
import java.io.Reader;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

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.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.internal.Streams;
import com.google.gson.internal.bind.TreeTypeAdapter;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;

import net.segoia.event.conditions.AndCondition;
import net.segoia.event.conditions.Condition;
import net.segoia.event.conditions.ConditionWrapper;
import net.segoia.event.conditions.LooseEventMatchCondition;
import net.segoia.event.conditions.NotCondition;
import net.segoia.event.conditions.OrCondition;
import net.segoia.event.conditions.StrictEventMatchCondition;

public class EventBusJsonConfigLoader {
    private static Map<String, JsonDeserializer<?>> jsonDeserializers = new HashMap<String, JsonDeserializer<?>>();

    static {
        /* defaul deserializer for strict conditions */
        jsonDeserializers.put(null, new JsonDeserializer<Condition>() {

            @Override
            public Condition deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
                    throws JsonParseException {
                JsonObject jo = json.getAsJsonObject();
                String id = jo.get("id").getAsString();

                String et = jo.get("et").getAsString();

                Condition cond;

                String[] etArray = et.split(":");
                int alen = etArray.length;

                String scope = null;
                String category = null;
                String name = null;

                if (alen > 0) {
                    scope = (etArray[0].isEmpty()) ? null : etArray[0];
                }
                if (alen > 1) {
                    category = (etArray[1].isEmpty()) ? null : etArray[1];
                }
                if (alen > 2) {
                    name = (etArray[2].isEmpty()) ? null : etArray[2];
                }

                if (scope == null || category == null || name == null) {
                    LooseEventMatchCondition obj = new LooseEventMatchCondition(id);
                    obj.setScope(scope);
                    obj.setCategory(category);
                    obj.setName(name);
                    cond = obj;
                } else {

                    StrictEventMatchCondition obj = new StrictEventMatchCondition(id);
                    obj.setEt(et);
                    obj.setParams((Map) context.deserialize(jo.get("params"), LinkedHashMap.class));
                    cond = obj;
                }

                return cond;
            }
        });

        /* adding or deserializer */
        jsonDeserializers.put("or", new JsonDeserializer<Condition>() {

            @Override
            public Condition deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
                    throws JsonParseException {
                JsonObject jo = json.getAsJsonObject();
                OrCondition orCondition = new OrCondition(jo.get("id").getAsString(),
                        (Condition[]) context.deserialize(jo.get("conditions"), Condition[].class));

                return orCondition;

            }
        });

        /* adding and deserializer */
        jsonDeserializers.put("and", new JsonDeserializer<Condition>() {

            @Override
            public Condition deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
                    throws JsonParseException {
                JsonObject jo = json.getAsJsonObject();
                AndCondition condition = new AndCondition(jo.get("id").getAsString(),
                        (Condition[]) context.deserialize(jo.get("conditions"), Condition[].class));

                return condition;

            }
        });

        /* adding not deserializer */
        jsonDeserializers.put("not", new JsonDeserializer<Condition>() {

            @Override
            public Condition deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
                    throws JsonParseException {
                JsonObject jo = json.getAsJsonObject();
                NotCondition notCondition = new NotCondition(jo.get("id").getAsString(),
                        (Condition[]) context.deserialize(jo.get("conditions"), Condition[].class));

                return notCondition;

            }
        });

        /* condRef */

        jsonDeserializers.put("condRef", new JsonDeserializer<Condition>() {

            @Override
            public Condition deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
                    throws JsonParseException {

                JsonObject jo = json.getAsJsonObject();

                String refId = jo.get("id").getAsString();

                return new ConditionWrapper(refId + "-ref", refId);

            }
        });
    }

    public static EventBusJsonConfig load(Reader reader) {
        GsonBuilder gb = new GsonBuilder();

        gb.registerTypeAdapter(Condition.class, new JsonDeserializer<Condition>() {

            @Override
            public Condition deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
                    throws JsonParseException {
                JsonObject jo = json.getAsJsonObject();
                JsonElement conditionType = jo.get("ctype");
                String ctype = null;
                if (conditionType != null) {
                    ctype = conditionType.getAsString().trim();
                    if ("".equals(ctype)) {
                        ctype = null;
                    }
                }
                JsonDeserializer<?> deserializerForType = jsonDeserializers.get(ctype);
                if (deserializerForType == null) {
                    throw new JsonParseException("No deserializer defined for condition type " + ctype);
                }
                return (Condition) deserializerForType.deserialize(json, typeOfT, context);
            }
        });

        gb.registerTypeAdapterFactory(new TypeAdapterFactory() {

            @Override
            public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> type) {
                final TypeAdapter<T> delegateAdapter = gson.getDelegateAdapter(this, type);

                TypeAdapter<T> typeAdapter = new TypeAdapter<T>() {

                    @Override
                    public void write(JsonWriter out, T value) throws IOException {
                        delegateAdapter.write(out, value);
                    }

                    @Override
                    public T read(JsonReader in) throws IOException {
                        JsonElement value = Streams.parse(in);

                        if (value.isJsonNull()) {
                            return null;
                        }

                        if (!value.isJsonObject()) {
                            return delegateAdapter.fromJsonTree(value);
                        }
                        // System.out.println(value+" "+value.getClass());
                        JsonObject jo = value.getAsJsonObject();

                        JsonElement cnameElem = jo.remove("className");

                        if (cnameElem != null) {
                            String cname = cnameElem.getAsString();

                            try {
                                // System.out.println("using clazz " + cname);
                                return (T) gson.fromJson(value, Class.forName(cname));
                            } catch (ClassNotFoundException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                                return null;
                            }
                        } else {
                            return delegateAdapter.fromJsonTree(value);
                        }
                    }
                };

                return typeAdapter;

            }
        });

        final Gson gson = gb.create();

        EventBusJsonConfig ebusConfig = gson.fromJson(reader, EventBusJsonConfig.class);

        return ebusConfig;
    }
}