de.instantouch.model.io.SnakeJSONReader.java Source code

Java tutorial

Introduction

Here is the source code for de.instantouch.model.io.SnakeJSONReader.java

Source

/*******************************************************************************
 * Copyright (c) 2014 Joachim Tessmer.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     Joachim Tessmer - initial API and implementation
 ******************************************************************************/
package de.instantouch.model.io;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;

import org.eclipse.core.runtime.Platform;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import org.json.simple.parser.ParseException;
import org.osgi.framework.Bundle;

import de.instantouch.model.base.SnakeType;
import de.instantouch.model.base.ref.SnakeReference;
import de.instantouch.model.collections.SnakeEntity;
import de.instantouch.model.collections.SnakeList;
import de.instantouch.model.collections.SnakeMap;
import de.instantouch.model.exception.SnakeModelException;
import de.instantouch.model.exception.SnakeNotFoundException;
import de.instantouch.model.exception.SnakeNotInitializedException;
import de.instantouch.model.exception.SnakeWrongTypeException;
import de.instantouch.model.log.SnakeLog;

public class SnakeJSONReader {

    protected String content = null;
    protected Reader reader = null;
    protected InputStream input = null;

    public SnakeJSONReader(String jsonStr) {
        this.content = jsonStr;
    }

    public SnakeJSONReader(InputStream input) {
        this.input = input;
        this.reader = new InputStreamReader(input);
    }

    public Object parse() throws IOException, SnakeModelException {
        Object jsonObject = null;

        try {
            if (content != null) {
                jsonObject = JSONValue.parseWithException(content);
            } else if (reader != null) {
                jsonObject = JSONValue.parseWithException(reader);
            }
        } catch (ParseException e) {
            throw new SnakeModelException(e);
        }

        return jsonObject;
    }

    public void read(SnakeType type, Object value) throws SnakeModelException, IOException, InstantiationException,
            IllegalAccessException, ClassNotFoundException {

        if (type.hasReference()) {
            SnakeReference ref = type.getReference();
            if (ref == null) {
                throw new SnakeNotInitializedException("reference is not initialized");
            }

            SnakeType key = ref.getKey();
            if (key == null) {
                throw new SnakeNotInitializedException("no reference key container os given");
            }

            read(key, value);
        } else {
            if (type instanceof SnakeEntity) {
                readEntity((SnakeEntity) type, value);
            } else if (type instanceof SnakeList) {
                readList((SnakeList) type, value);
            } else if (type instanceof SnakeMap) {
                readMap((SnakeMap) type, value);
            } else if (value == null) {
                type.setNull();
            } else if (value instanceof String) {
                type.set(value.toString());
            } else if (value instanceof Boolean) {
                type.set(value.toString());
            } else if (value instanceof Number) {
                Number number = (Number) value;

                if (value instanceof Double) {
                    type.set(number.doubleValue());
                } else if (value instanceof Float) {
                    type.set(number.floatValue());
                } else if (value instanceof Byte) {
                    type.set(number.byteValue());
                } else if (value instanceof Short) {
                    type.set(number.shortValue());
                } else if (value instanceof Integer) {
                    type.set(number.intValue());
                } else if (value instanceof Long) {
                    type.set(number.longValue());
                }
            }
        }

    }

    public void readEntity(SnakeEntity entity, Object value) throws SnakeModelException, IOException,
            InstantiationException, IllegalAccessException, ClassNotFoundException {
        if (!(value instanceof JSONObject)) {
            throw new SnakeWrongTypeException(
                    "wrong type for entity: " + entity.getName() + " candidate: " + value);
        }

        JSONObject jsonObject = (JSONObject) value;

        for (SnakeType member : entity.getChildren()) {
            Object object = jsonObject.get(member.getName());
            if (object != null) {
                read(member, object);
            }
        }

        // dynamic members
        for (Object key : jsonObject.keySet()) {
            String name = key.toString();
            SnakeType member = entity.findByName(name);
            if (member == null) {
                Object obj = jsonObject.get(key);
                if (obj instanceof JSONObject) {
                    JSONObject inner = (JSONObject) obj;

                    Object classInfo = inner.get("entityClass");
                    Object bundleInfo = inner.get("bundle");

                    Bundle bundle = Platform.getBundle(bundleInfo.toString());
                    SnakeEntity child = (SnakeEntity) bundle.loadClass(classInfo.toString()).newInstance();
                    child.setName(name);

                    readEntity(child, inner);
                    entity.replace(name, child);
                }
            }
        }

    }

    public void readList(SnakeList<SnakeType> myList, Object value) throws SnakeModelException, IOException,
            ClassNotFoundException, InstantiationException, IllegalAccessException {

        if (!(value instanceof JSONArray)) {
            throw new SnakeWrongTypeException(
                    "couldn't extract list: " + myList.getName() + " from json object:" + value);
        }

        JSONArray jsonArray = (JSONArray) value;

        myList.clear();
        for (int i = 0; i < jsonArray.size(); i++) {
            Object object = jsonArray.get(i);

            SnakeType child = myList.newElement();
            if (child == null) {
                SnakeLog.error(
                        "couldn't read list data: " + object + "for: " + myList.getClass().getCanonicalName());
                break;
            }

            child.setParent(myList);
            read(child, object);

            myList.add(child);
        }

    }

    public void readMap(SnakeMap<SnakeType, SnakeType> myMap, Object jsonObject) throws SnakeModelException,
            IOException, InstantiationException, IllegalAccessException, ClassNotFoundException {

        if (!(jsonObject instanceof JSONArray)) {
            throw new SnakeWrongTypeException(
                    "wrong type for map: " + myMap.getName() + " candidate: " + jsonObject);
        }

        myMap.clear();
        JSONArray jsonMap = (JSONArray) jsonObject;
        for (Object obj : jsonMap) {
            if (!(obj instanceof JSONObject)) {
                throw new SnakeWrongTypeException(
                        "wrong element for map: " + myMap.getName() + " candidate: " + obj);
            }

            JSONObject single = (JSONObject) obj;
            Object key = single.get("key");
            if (key == null) {
                throw new SnakeNotFoundException(
                        "couldn't extract key from entry: " + single + " for map: " + myMap.getName());
            }

            SnakeType newKey = myMap.newKey();
            read(newKey, key);

            Object value = single.get("value");
            if (value == null) {
                throw new SnakeNotFoundException(
                        "couldn't extract value from entry: " + single + " for map: " + myMap.getName());
            }
            SnakeType newValue = myMap.newValue();
            read(newValue, value);

            myMap.put(newKey, newValue);
        }
    }

    public void parseFor(SnakeType type) throws InstantiationException, IllegalAccessException,
            ClassNotFoundException, SnakeModelException, IOException {

        Object jsonObject = parse();
        read(type, jsonObject);
    }

    public SnakeEntity parseEntity() throws InstantiationException, IllegalAccessException, ClassNotFoundException,
            SnakeModelException, IOException {

        Object value = parse();
        if (!(value instanceof JSONObject)) {
            throw new SnakeWrongTypeException("wrong type for entity");
        }

        JSONObject jsonObject = (JSONObject) value;

        Object classInfo = jsonObject.get("entityClass");
        Object bundleInfo = jsonObject.get("bundle");

        Bundle bundle = Platform.getBundle(bundleInfo.toString());
        SnakeEntity entity = (SnakeEntity) bundle.loadClass(classInfo.toString()).newInstance();

        readEntity(entity, jsonObject);

        return entity;
    }

    public void close() {
        if (reader != null) {
            try {
                reader.close();
            } catch (IOException e) {
                SnakeLog.log(e);
            }
        }

        if (input != null) {
            try {
                input.close();
            } catch (IOException e) {
                SnakeLog.log(e);
            }
        }

    }

}