org.spoutcraft.launcher.rest.RestAPI.java Source code

Java tutorial

Introduction

Here is the source code for org.spoutcraft.launcher.rest.RestAPI.java

Source

/*
 * This file is part of Technic Launcher.
 *
 * Copyright (c) 2013-2013, Technic <http://www.technicpack.net/>
 * Technic Launcher is licensed under the Spout License Version 1.
 *
 * Technic Launcher is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * In addition, 180 days after any changes are published, you can use the
 * software, incorporating those changes, under the terms of the MIT license,
 * as described in the Spout License Version 1.
 *
 * Technic Launcher 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 Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License,
 * the MIT license and the Spout License Version 1 along with this program.
 * If not, see <http://www.gnu.org/licenses/> for the GNU Lesser General Public
 * License and see <http://www.spout.org/SpoutDevLicenseV1.txt> for the full license,
 * including the MIT license.
 */

package org.spoutcraft.launcher.rest;

import java.io.IOException;
import java.io.InputStream;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;

import org.apache.commons.io.IOUtils;
import org.codehaus.jackson.annotate.JsonProperty;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
import org.spoutcraft.launcher.Settings;
import org.spoutcraft.launcher.api.Launcher;
import org.spoutcraft.launcher.exceptions.RestfulAPIException;
import org.spoutcraft.launcher.rest.pack.RestModpack;
import org.spoutcraft.launcher.technic.CustomInfo;
import org.spoutcraft.launcher.technic.RestInfo;

public class RestAPI {
    private static final String DEFAULT_MIRROR = "http://mirror.technicpack.net/Technic/";
    private static final ObjectMapper mapper = new ObjectMapper();
    private static final String PLATFORM = "http://www.technicpack.net/";

    private static FullModpacks DEFAULT;
    private static RestAPI TECHNIC;
    private static Map<String, Minecraft> mcVersions;
    private static Modpacks modpacks;

    private final String modURL;
    private final String restInfoURL;
    private final String restURL;

    private String mirrorURL;

    public RestAPI(String url) {
        restURL = url;
        restInfoURL = restURL + "modpack/";
        modURL = restURL + "mod/";
        try {
            modpacks = setupModpacks();
            modpacks.setRest(this);
            mirrorURL = modpacks.getMirrorURL();

        } catch (RestfulAPIException e) {
            Launcher.getLogger().log(Level.SEVERE,
                    "Unable to connect to the Rest API at " + url + " Running Offline instead.");
            mirrorURL = "";
        }

        if (mcVersions == null) {
            try {
                mcVersions = getMinecraftVersions();
            } catch (RestfulAPIException e) {
                Launcher.getLogger().log(Level.SEVERE,
                        "Unable to load minecraft versions from " + getMinecraftVersionURL(), e);
                mcVersions = Collections.emptyMap();
            }
        }
    }

    public String getLatestBuild(String modpack) throws RestfulAPIException {
        return getModpackInfo(modpack).getLatest();
    }

    public String getMirrorURL() {
        return mirrorURL;
    }

    public String getModDownloadURL(String mod, String build) {
        return getMirrorURL() + "mods/" + mod + "/" + mod + "-" + build + ".zip";
    }

    public String getModMD5(String mod, String build) throws RestfulAPIException {
        TechnicMD5 result = getRestObject(TechnicMD5.class, getModMD5URL(mod, build));
        return result.getMD5();
    }

    public String getModMD5URL(String mod, String build) {
        return getModURL() + mod + "/" + build;
    }

    public RestModpack getModpack(RestInfo modpack, String build) throws RestfulAPIException {
        RestModpack result = getRestObject(RestModpack.class, getModpackURL(modpack.getName(), build));
        result.setRest(this);
        return result.setInfo(modpack, build);
    }

    public String getModpackBackgroundURL(String modpack) {
        return getMirrorURL() + modpack + "/resources/background.jpg";
    }

    public String getModpackIconURL(String modpack) {
        return getMirrorURL() + modpack + "/resources/icon.png";
    }

    public String getModpackImgURL(String modpack) {
        return getMirrorURL() + modpack + "/resources/logo_180.png";
    }

    public RestInfo getModpackInfo(String modpack) throws RestfulAPIException {
        RestInfo result;
        if (this.equals(getDefault())) {
            result = DEFAULT.getMap().get(modpack);
        } else {
            result = getRestObject(RestInfo.class, getModpackInfoURL(modpack));
        }

        result.setRest(this);
        result.init();

        return result;
    }

    public String getModpackInfoURL(String modpack) {
        return getRestInfoURL() + modpack;
    }

    public Modpacks getModpacks() {
        return modpacks;
    }

    public String getModpackURL(String modpack, String build) {
        return getRestInfoURL() + modpack + "/" + build;
    }

    public String getModURL() {
        return modURL;
    }

    public String getRecommendedBuild(String modpack) throws RestfulAPIException {
        return getModpackInfo(modpack).getRecommended();
    }

    public Collection<RestInfo> getRestInfos() throws RestfulAPIException {
        return modpacks.getModpacks();
    }

    public String getRestInfoURL() {
        return restInfoURL;
    }

    public String getRestURL() {
        return restURL;
    }

    private Modpacks setupModpacks() throws RestfulAPIException {
        Modpacks result = getRestObject(Modpacks.class, restInfoURL);
        result.setRest(this);
        return result;
    }

    public static CustomInfo getCustomModpack(String packURL) throws RestfulAPIException {
        CustomInfo info = getRestObject(CustomInfo.class, packURL);
        return info;
    }

    public static String getCustomPackURL(String modpack) {
        return getPlatformAPI() + "modpack/" + modpack;
    }

    public static RestAPI getDefault() {
        if (TECHNIC == null) {
            TECHNIC = new RestAPI("http://solder.technicpack.net/api/");
            setupDefault();
        }

        return TECHNIC;
    }

    public static Collection<RestInfo> getDefaults() {
        getDefault();
        if (DEFAULT != null) {
            return DEFAULT.getModpacks();
        } else {
            return Collections.emptyList();
        }
    }

    public static String getDownloadCountURL(String modpack) {
        if (Settings.isPackCustom(modpack)) {
            return getCustomPackURL(modpack) + "/download";
        }
        return getDefault().getRestURL() + "";
    }

    public static String getFmlLibURL() {
        return DEFAULT_MIRROR + "lib/fml/";
    }

    public static String getFmlLibZip(String minecraft) {
        if (minecraft.startsWith("1.4")) {
            return "fml_libs.zip";
        }
        if (minecraft.startsWith("1.5")) {
            return "fml_libs15.zip";
        }
        return null;
    }

    public static int getLatestLauncherBuild(String stream) throws RestfulAPIException {
        LauncherBuild result = getRestObject(LauncherBuild.class, getPlatformAPI() + "launcher/version/" + stream);
        return result.getLatestBuild();
    }

    public static String getLauncherDownloadURL(int version, Boolean isJar) throws RestfulAPIException {
        String ext = null;
        if (isJar) {
            ext = "jar";
        } else {
            ext = "exe";
        }

        String url = getPlatformAPI() + "launcher/url/" + version + "/" + ext;
        LauncherURL result = getRestObject(LauncherURL.class, url);
        return result.getLauncherURL();
    }

    public static String getLwjglNativeURL(String version, String os) {
        return DEFAULT_MIRROR + "lib/lwjgl/lwjgl-natives-" + os + "-" + version + ".zip";
    }

    public static String getLwjglURL(String version) {
        return DEFAULT_MIRROR + "lib/lwjgl/lwjgl-jar-" + version + ".zip";
    }

    public static String getMinecraftMD5(String version) {
        Minecraft minecraft = mcVersions.get(version);
        if (shouldUsePatch(version)) {
            version = Minecraft.PATCH_VERSION;
        }
        minecraft = mcVersions.get(version);

        if (minecraft == null) {
            return null;
        }
        return minecraft.getMd5();
    }

    public static String getMinecraftURL(String version) {
        Minecraft minecraft = mcVersions.get(version);
        System.out.println(minecraft);
        if (minecraft == null || minecraft.shouldUsePatch()) {
            version = Minecraft.PATCH_VERSION;
        }

        if (Arrays.asList(Minecraft.OLD_ASSETS).contains(version)) {
            version = version.replace('.', '_');
            return "http://assets.minecraft.net/" + version + "/minecraft.jar";
        }
        return "https://s3.amazonaws.com/Minecraft.Download/versions/" + version + "/" + version + ".jar";
    }

    public static HashMap<String, Minecraft> getMinecraftVersions() throws RestfulAPIException {
        InputStream stream = null;
        try {
            URLConnection conn = new URL(getMinecraftVersionURL()).openConnection();
            conn.setRequestProperty("User-Agent",
                    "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.4; en-US; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2");
            conn.setConnectTimeout(15000);
            conn.setReadTimeout(15000);

            stream = conn.getInputStream();
            HashMap<String, Minecraft> versions = mapper.readValue(stream,
                    new TypeReference<Map<String, Minecraft>>() {
                    });

            for (Minecraft result : versions.values()) {
                if (result.hasError()) {
                    throw new RestfulAPIException("Error in json response: " + result.getError());
                }
            }

            return versions;
        } catch (SocketTimeoutException e) {
            throw new RestfulAPIException("Timed out accessing URL [" + getMinecraftVersionURL() + "]", e);
        } catch (IOException e) {
            throw new RestfulAPIException("Error accessing URL [" + getMinecraftVersionURL() + "]", e);
        } finally {
            IOUtils.closeQuietly(stream);
        }
    }

    public static String getMinecraftVersionURL() {
        return getPlatformAPI() + "minecraft";
    }

    public static List<Article> getNews() throws RestfulAPIException {
        InputStream stream = null;
        try {
            URLConnection conn = new URL(getPlatformAPI() + "news/").openConnection();
            conn.setRequestProperty("User-Agent",
                    "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.4; en-US; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2");
            conn.setConnectTimeout(15000);
            conn.setReadTimeout(15000);

            stream = conn.getInputStream();
            List<Article> versions = mapper.readValue(stream, new TypeReference<List<Article>>() {
            });

            for (Article result : versions) {
                if (result.hasError()) {
                    throw new RestfulAPIException("Error in json response: " + result.getError());
                }
            }

            return versions;
        } catch (SocketTimeoutException e) {
            throw new RestfulAPIException("Timed out accessing URL [" + getMinecraftVersionURL() + "]", e);
        } catch (IOException e) {
            throw new RestfulAPIException("Error accessing URL [" + getMinecraftVersionURL() + "]", e);
        } finally {
            IOUtils.closeQuietly(stream);
        }
    }

    public static String get123PatchURL() {
        return DEFAULT_MIRROR + "/Patches/Minecraft/minecraft_" + Minecraft.PATCH_VERSION + "-1.2.3.patch";
    }

    public static String getPlatformAPI() {
        return PLATFORM + "api/";
    }

    public static String getPlatformURL() {
        return PLATFORM;
    }

    public static <T extends RestObject> T getRestObject(Class<T> restObject, String url)
            throws RestfulAPIException {
        InputStream stream = null;
        try {
            URLConnection conn = new URL(url).openConnection();
            conn.setRequestProperty("User-Agent",
                    "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.4; en-US; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2");
            conn.setConnectTimeout(15000);
            conn.setReadTimeout(15000);

            stream = conn.getInputStream();
            T result = mapper.readValue(stream, restObject);
            if (result.hasError()) {
                throw new RestfulAPIException("Error in json response: " + result.getError());
            }

            return result;
        } catch (SocketTimeoutException e) {
            throw new RestfulAPIException("Timed out accessing URL [" + url + "]", e);
        } catch (IOException e) {
            throw new RestfulAPIException("Error accessing URL [" + url + "]", e);
        } finally {
            IOUtils.closeQuietly(stream);
        }
    }

    public static String getRunCountURL(String modpack) {
        if (Settings.isPackCustom(modpack)) {
            return getCustomPackURL(modpack) + "/run";
        }
        return getDefault().getRestURL() + "";
    }

    public static void setupDefault() {
        if (DEFAULT != null) {
            return;
        }
        try {
            DEFAULT = getRestObject(FullModpacks.class, getDefault().getRestInfoURL() + "?include=full");
        } catch (RestfulAPIException e) {
            Launcher.getLogger().log(Level.SEVERE, "Unable to connect to the Rest API at "
                    + TECHNIC.getRestInfoURL() + "?include=full" + " Running Offline instead.", e);
        }
    }

    public static boolean shouldUsePatch(String version) {
        Minecraft minecraft = mcVersions.get(version);
        boolean shouldPatch = false;
        if (minecraft == null && version.equals("1.2.3")) {
            shouldPatch = true;
        } else if (minecraft != null) {
            shouldPatch = minecraft.shouldUsePatch();
        }
        return shouldPatch;
    }

    private static class LauncherBuild extends RestObject {
        @JsonProperty("LatestBuild")
        private int latestBuild;

        public int getLatestBuild() {
            return latestBuild;
        }
    }

    private static class LauncherURL extends RestObject {
        @JsonProperty("URL")
        private String launcherURL;

        public String getLauncherURL() {
            return launcherURL;
        }
    }

    private static class TechnicMD5 extends RestObject {
        @JsonProperty("md5")
        private String md5;

        public String getMD5() {
            return md5;
        }
    }
}