com.voxelplugineering.voxelsniper.service.persistence.JsonDataSource.java Source code

Java tutorial

Introduction

Here is the source code for com.voxelplugineering.voxelsniper.service.persistence.JsonDataSource.java

Source

/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2014 The Voxel Plugineering Team
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package com.voxelplugineering.voxelsniper.service.persistence;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.Map;
import java.util.Map.Entry;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonPrimitive;
import com.google.gson.stream.JsonReader;
import com.voxelplugineering.voxelsniper.api.service.persistence.DataContainer;
import com.voxelplugineering.voxelsniper.api.service.persistence.DataSerializable;
import com.voxelplugineering.voxelsniper.api.service.persistence.DataSource;

/**
 * A data source which serializes data to a file as Json.
 */
public class JsonDataSource extends FileDataSource {

    /**
     * A {@link FileDataSource.Builder} for json data sources.
     */
    public static Builder BUILDER = new Builder() {

        /**
         * {@inheritDoc}
         */
        @Override
        public DataSource build(File f) {
            return new JsonDataSource(f);
        }

    };

    /**
     * Creates a new {@link JsonDataSource} based on the given file.
     * 
     * @param file The file
     */
    public JsonDataSource(File file) {
        super(file);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void write(DataContainer container) throws IOException {
        if (this.file.exists()) {
            this.file.delete();
        }
        Writer writer = null;
        try {
            this.file.createNewFile();

            writer = new FileWriter(this.file);

            Gson gson = new GsonBuilder().create();
            JsonObject json = fromContainer(container);

            gson.toJson(json, writer);
        } finally {
            if (writer != null) {
                writer.close();
            }
        }
    }

    /**
     * Recursively converts the given {@link DataContainer} to a
     * {@link JsonObject}.
     * 
     * @param container The container to convert
     * @return The json object representing the container
     */
    public JsonObject fromContainer(DataContainer container) {
        JsonObject json = new JsonObject();

        for (Map.Entry<String, Object> entry : container.extrySet()) {
            Class<?> type = entry.getValue().getClass();
            if (type == Byte.class || type == byte.class || type == Short.class || type == short.class
                    || type == Integer.class || type == int.class || type == Long.class || type == long.class
                    || type == Float.class || type == float.class || type == Double.class || type == double.class) {
                json.addProperty(entry.getKey(), (Number) entry.getValue());
            } else if (type == Boolean.class || type == boolean.class) {
                json.addProperty(entry.getKey(), (Boolean) entry.getValue());
            } else if (type == Character.class || type == char.class) {
                json.addProperty(entry.getKey(), (Character) entry.getValue());
            } else if (type == String.class) {
                json.addProperty(entry.getKey(), (String) entry.getValue());
            } else if (DataContainer.class.isAssignableFrom(type)) {
                json.add(entry.getKey(), fromContainer((DataContainer) entry.getValue()));
            } else if (DataSerializable.class.isAssignableFrom(type)) {
                json.add(entry.getKey(), fromContainer(((DataSerializable) entry.getValue()).toContainer()));
            }
        }
        return json;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public DataContainer read() throws IOException {
        JsonReader reader = null;
        DataContainer container = null;
        try {
            reader = new JsonReader(new FileReader(this.file));
            JsonParser parser = new JsonParser();
            JsonElement rootelement = parser.parse(reader);
            container = toContainer(rootelement);

        } finally {
            if (reader != null) {
                reader.close();
            }
        }
        return container;
    }

    /**
     * Recursively converts the given {@link JsonElement} to a
     * {@link DataContainer}.
     * 
     * @param rootelement The element to convert
     * @return The new {@link DataContainer}
     */
    public DataContainer toContainer(JsonElement rootelement) {
        DataContainer container = new MemoryContainer("");

        if (rootelement.isJsonObject()) {
            JsonObject root = rootelement.getAsJsonObject();
            for (Entry<String, JsonElement> entry : root.entrySet()) {
                String key = entry.getKey();
                JsonElement element = entry.getValue();
                if (element.isJsonPrimitive()) {
                    JsonPrimitive primitive = element.getAsJsonPrimitive();
                    if (primitive.isBoolean()) {
                        container.writeBoolean(key, primitive.getAsBoolean());
                    } else if (primitive.isString()) {
                        container.writeString(key, primitive.getAsString());
                    } else if (primitive.isNumber()) {
                        container.writeNumber(key, primitive.getAsNumber());
                    }
                } else if (element.isJsonObject()) {
                    container.writeContainer(key, toContainer(element));
                }
            }
        }

        return container;

    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void write(DataSerializable serial) throws IOException {
        write(serial.toContainer());
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public <T extends DataSerializable> T read(T object) throws IOException {
        object.fromContainer(read());
        return object;
    }

}