org.spongepowered.plugin.meta.gson.ModMetadataAdapter.java Source code

Java tutorial

Introduction

Here is the source code for org.spongepowered.plugin.meta.gson.ModMetadataAdapter.java

Source

/*
 * This file is part of plugin-meta, licensed under the MIT License (MIT).
 *
 * Copyright (c) SpongePowered <https://www.spongepowered.org>
 * Copyright (c) contributors
 *
 * 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 org.spongepowered.plugin.meta.gson;

import com.google.common.collect.ImmutableMap;
import com.google.gson.Gson;
import com.google.gson.JsonParseException;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import org.spongepowered.plugin.meta.PluginMetadata;

import java.io.IOException;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public final class ModMetadataAdapter extends TypeAdapter<PluginMetadata> {

    public static final ModMetadataAdapter DEFAULT = new ModMetadataAdapter(new Gson(), ImmutableMap.of());

    private final Gson gson;
    private final ImmutableMap<String, Class<?>> extensions;

    public ModMetadataAdapter(Gson gson, ImmutableMap<String, Class<?>> extensions) {
        this.gson = gson;
        this.extensions = extensions;
    }

    public Gson getGson() {
        return this.gson;
    }

    public ImmutableMap<String, Class<?>> getExtensions() {
        return this.extensions;
    }

    public Class<?> getExtension(String key) {
        Class<?> result = this.extensions.get(key);
        return result != null ? result : Object.class;
    }

    @Override
    public PluginMetadata read(JsonReader in) throws IOException {
        in.beginObject();

        final Set<String> processedKeys = new HashSet<>();

        final PluginMetadata result = new PluginMetadata("unknown");
        String id = null;

        while (in.hasNext()) {
            final String name = in.nextName();
            if (!processedKeys.add(name)) {
                throw new JsonParseException("Duplicate key '" + name + "' in " + in);
            }

            switch (name) {
            case "modid":
                id = in.nextString();
                result.setId(id);
                break;
            case "name":
                result.setName(in.nextString());
                break;
            case "version":
                result.setVersion(in.nextString());
                break;
            case "description":
                result.setDescription(in.nextString());
                break;
            case "url":
                result.setUrl(in.nextString());
                break;
            case "authorList":
                in.beginArray();
                while (in.hasNext()) {
                    result.addAuthor(in.nextString());
                }
                in.endArray();
                break;
            case "requiredMods":
                in.beginArray();
                while (in.hasNext()) {
                    result.addRequiredDependency(ModDependencyAdapter.INSTANCE.read(in));
                }
                in.endArray();
                break;
            case "dependencies":
                in.beginArray();
                while (in.hasNext()) {
                    result.loadAfter(ModDependencyAdapter.INSTANCE.read(in));
                }
                in.endArray();
                break;
            case "dependants":
                in.beginArray();
                while (in.hasNext()) {
                    result.loadBefore(ModDependencyAdapter.INSTANCE.read(in));
                }
                in.endArray();
                break;
            default:
                result.setExtension(name, this.gson.fromJson(in, getExtension(name)));
            }
        }

        in.endObject();

        if (id == null) {
            throw new JsonParseException("Mod metadata is missing required element 'modid'");
        }

        return result;
    }

    @Override
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public void write(JsonWriter out, PluginMetadata meta) throws IOException {
        out.beginObject();
        out.name("modid").value(meta.getId());
        writeIfPresent(out, "name", meta.getName());
        writeIfPresent(out, "version", meta.getVersion());
        writeIfPresent(out, "description", meta.getDescription());
        writeIfPresent(out, "url", meta.getUrl());

        if (!meta.getAuthors().isEmpty()) {
            out.name("authorList").beginArray();
            for (String author : meta.getAuthors()) {
                out.value(author);
            }
            out.endArray();
        }

        writeDependencies(out, "requiredMods", meta.getRequiredDependencies());
        writeDependencies(out, "dependencies", meta.getLoadAfter());
        writeDependencies(out, "dependants", meta.getLoadBefore());

        if (!meta.getExtensions().isEmpty()) {
            for (Map.Entry<String, Object> entry : meta.getExtensions().entrySet()) {
                final String key = entry.getKey();
                final Object value = entry.getValue();

                out.name(key);
                this.gson.toJson(value, getExtension(key), out);
            }
        }

        out.endObject();
    }

    private static void writeIfPresent(JsonWriter out, String key, String value) throws IOException {
        if (value != null) {
            out.name(key).value(value);
        }
    }

    private static void writeDependencies(JsonWriter out, String key, Set<PluginMetadata.Dependency> dependencies)
            throws IOException {
        if (!dependencies.isEmpty()) {
            out.name(key).beginArray();
            for (PluginMetadata.Dependency dependency : dependencies) {
                ModDependencyAdapter.INSTANCE.write(out, dependency);
            }
            out.endArray();
        }
    }

}