net.monofraps.gradlebukkit.tasks.DownloadCraftBukkit.java Source code

Java tutorial

Introduction

Here is the source code for net.monofraps.gradlebukkit.tasks.DownloadCraftBukkit.java

Source

/*
 * Copyright (C) 2014 Monofraps
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
    
 * This program 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 General Public License for more details.
    
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package net.monofraps.gradlebukkit.tasks;

import com.google.common.base.Strings;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import groovy.lang.Closure;
import net.monofraps.gradlebukkit.extensions.Bukkit;
import net.monofraps.gradlebukkit.models.BuildArtifact;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.FileUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.gradle.api.DefaultTask;
import org.gradle.api.tasks.TaskAction;
import org.gradle.mvn3.org.apache.maven.lifecycle.LifecycleExecutionException;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * @author monofraps
 */
public class DownloadCraftBukkit extends DefaultTask {
    /**
     * Artifact slug specifying the version of CraftBukkit to download.
     * Leave null or empty to inherit from bukkit project properties extension.
     */
    private String artifactSlug;

    private File bukkitServerJar;
    private File bukkitTargetDir;

    public DownloadCraftBukkit() {
        super();

        getOutputs().upToDateWhen(new UpToDateWhen(this));
        bukkitTargetDir = new File(getProject().getBuildDir(), "bukkit");

        getOutputs().dir(bukkitTargetDir);
    }

    private class UpToDateWhen extends Closure<Boolean> {

        private DownloadCraftBukkit owner;

        public UpToDateWhen(DownloadCraftBukkit owner) {
            super(owner);
            this.owner = owner;
        }

        @Override
        public Boolean call(Object params) {
            try {
                return !owner.needsUpdating();
            } catch (IOException | LifecycleExecutionException e) {
                e.printStackTrace();
            }

            return false;
        }
    }

    public boolean needsUpdating() throws IOException, LifecycleExecutionException {
        final BuildArtifact artifact = prepareExecution();
        return artifact != null;

    }

    private BuildArtifact prepareExecution() throws IOException, LifecycleExecutionException {
        final BuildArtifact artifact = getArtifactToDownload();

        bukkitServerJar = new File(bukkitTargetDir, "bukkit-" + artifact.getBuildNumber() + ".jar");
        final File bukkitPluginDir = new File(bukkitTargetDir, "plugins");

        if (bukkitServerJar.exists()) {
            final String localMd5 = DigestUtils.md5Hex(new FileInputStream(bukkitServerJar));
            if (!localMd5.equals(artifact.getFile().getMd5())) {
                getLogger().lifecycle("CraftBukkit MD5 sum mismatch. Going to update local copy.");
            } else {
                getLogger().lifecycle("File exists.");
                return null;
            }
        }

        if (!bukkitTargetDir.exists()) {
            if (!bukkitTargetDir.mkdir())
                throw new LifecycleExecutionException(
                        "Failed to create bukkit server directory " + bukkitTargetDir);
        }

        if (!bukkitPluginDir.exists()) {
            if (!bukkitPluginDir.mkdir())
                throw new LifecycleExecutionException(
                        "Failed to create bukkit plugin directory " + bukkitPluginDir);
        }

        return artifact;
    }

    @TaskAction
    public void doWork() throws IOException, LifecycleExecutionException {
        final BuildArtifact artifact = prepareExecution();

        getLogger()
                .lifecycle("I chose CraftBukkit " + artifact.getVersion() + " build " + artifact.getBuildNumber());

        if (artifact == null) {
            getLogger().lifecycle("Nothing to be done.");
            return;
        }

        downloadArtifact("http://dl.bukkit.org/" + artifact.getFile().getUrl(), artifact.getFile().getMd5());
    }

    private void downloadArtifact(final String url, final String referenceMd5)
            throws IOException, LifecycleExecutionException {
        getLogger().lifecycle("Going to download CraftBukkit from " + url);

        final HttpGet httpGet = new HttpGet(url);
        final HttpClient httpClient = HttpClientBuilder.create().build();
        final HttpResponse httpResponse = httpClient.execute(httpGet);

        if (!bukkitServerJar.exists()) {
            if (!bukkitServerJar.createNewFile())
                throw new LifecycleExecutionException("Failed to create bukkit server jar " + bukkitServerJar);
        }

        final HttpEntity httpEntity = httpResponse.getEntity();
        getLogger().lifecycle("Writing " + httpEntity.getContentLength() + " bytes to bukkit.jar");

        final byte[] data = EntityUtils.toByteArray(httpEntity);
        FileUtils.writeByteArrayToFile(bukkitServerJar, data);

        final String localMd5 = DigestUtils.md5Hex(new FileInputStream(bukkitServerJar));
        if (!localMd5.equals(referenceMd5)) {
            throw new LifecycleExecutionException("bukkit.jar MD5 sum mismatch. - Download failed.");
        }
    }

    private BuildArtifact getArtifactToDownload() throws IOException, LifecycleExecutionException {
        final String responseString;

        final String url = "http://dl.bukkit.org/api/1.0/downloads/projects/craftbukkit/view/" + getArtifactSlug()
                + "/";
        final HttpGet httpGet = new HttpGet(url);

        final HttpClient httpClient = HttpClientBuilder.create().build();
        final HttpResponse httpResponse = httpClient.execute(httpGet);

        if (httpResponse.getStatusLine().getStatusCode() != 200) {
            throw new LifecycleExecutionException(
                    "Failed to download CraftBukkit: Failed to download version information (HTTP "
                            + httpResponse.getStatusLine().getStatusCode() + ") from " + url);
        }

        final BufferedReader responseReader = new BufferedReader(
                new InputStreamReader(httpResponse.getEntity().getContent()));

        final StringBuilder response = new StringBuilder();
        String line;
        while ((line = responseReader.readLine()) != null) {
            response.append(line);
        }

        responseString = response.toString();

        final JsonElement jsonResponse = (new JsonParser()).parse(responseString);
        return BuildArtifact.fromJsonObject(jsonResponse.getAsJsonObject());
    }

    public String getArtifactSlug() {
        return Strings.nullToEmpty(artifactSlug).isEmpty()
                ? ((Bukkit) getProject().getExtensions().getByName("bukkit")).getArtifactSlug()
                : artifactSlug;
    }

    public void setArtifactSlug(final String artifactSlug) {
        this.artifactSlug = artifactSlug;
    }
}