Package com.google.gerrit.pgm.init

Source Code of com.google.gerrit.pgm.init.LibraryDownloader

// Copyright (C) 2009 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.gerrit.pgm.init;

import com.google.gerrit.pgm.util.ConsoleUI;
import com.google.gerrit.pgm.util.Die;
import com.google.gerrit.server.config.SitePaths;
import com.google.inject.Inject;

import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.util.HttpSupport;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.Proxy;
import java.net.ProxySelector;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/** Get optional or required 3rd party library files into $site_path/lib. */
class LibraryDownloader {
  private final ConsoleUI ui;
  private final File lib_dir;
  private final ReloadSiteLibrary reload;

  private boolean required;
  private String name;
  private String jarUrl;
  private String sha1;
  private File dst;

  @Inject
  LibraryDownloader(final ReloadSiteLibrary reload, final ConsoleUI ui,
      final SitePaths site) {
    this.ui = ui;
    this.lib_dir = site.lib_dir;
    this.reload = reload;
  }

  void setName(final String name) {
    this.name = name;
  }

  void setJarUrl(final String url) {
    this.jarUrl = url;
  }

  void setSHA1(final String sha1) {
    this.sha1 = sha1;
  }

  void downloadRequired() {
    this.required = true;
    download();
  }

  void downloadOptional() {
    this.required = false;
    download();
  }

  private void download() {
    if (jarUrl == null || !jarUrl.contains("/")) {
      throw new IllegalStateException("Invalid JarUrl for " + name);
    }

    final String jarName = jarUrl.substring(jarUrl.lastIndexOf('/') + 1);
    if (jarName.contains("/") || jarName.contains("\\")) {
      throw new IllegalStateException("Invalid JarUrl: " + jarUrl);
    }

    if (name == null) {
      name = jarName;
    }

    dst = new File(lib_dir, jarName);
    if (!dst.exists() && shouldGet()) {
      doGet();
    }
  }

  private boolean shouldGet() {
    if (ui.isBatch()) {
      return required;

    } else {
      final StringBuilder msg = new StringBuilder();
      msg.append("\n");
      msg.append("Gerrit Code Review is not shipped with %s\n");
      if (required) {
        msg.append("**  This library is required for your configuration. **\n");
      } else {
        msg.append("  If available, Gerrit can take advantage of features\n");
        msg.append("  in the library, but will also function without it.\n");
      }
      msg.append("Download and install it now");
      return ui.yesno(true, msg.toString(), name);
    }
  }

  private void doGet() {
    if (!lib_dir.exists() && !lib_dir.mkdirs()) {
      throw new Die("Cannot create " + lib_dir);
    }

    try {
      doGetByHttp();
      verifyFileChecksum();
    } catch (IOException err) {
      dst.delete();

      if (ui.isBatch()) {
        throw new Die("error: Cannot get " + jarUrl, err);
      }

      System.err.println();
      System.err.println();
      System.err.println("error: " + err.getMessage());
      System.err.println("Please download:");
      System.err.println();
      System.err.println("  " + jarUrl);
      System.err.println();
      System.err.println("and save as:");
      System.err.println();
      System.err.println("  " + dst.getAbsolutePath());
      System.err.println();
      System.err.flush();

      ui.waitForUser();

      if (dst.exists()) {
        verifyFileChecksum();

      } else if (!ui.yesno(!required, "Continue without this library")) {
        throw new Die("aborted by user");
      }
    }

    reload.reload();
  }

  private void doGetByHttp() throws IOException {
    System.err.print("Downloading " + jarUrl + " ...");
    System.err.flush();
    try {
      final ProxySelector proxySelector = ProxySelector.getDefault();
      final URL url = new URL(jarUrl);
      final Proxy proxy = HttpSupport.proxyFor(proxySelector, url);
      final HttpURLConnection c = (HttpURLConnection) url.openConnection(proxy);
      final InputStream in;

      switch (HttpSupport.response(c)) {
        case HttpURLConnection.HTTP_OK:
          in = c.getInputStream();
          break;

        case HttpURLConnection.HTTP_NOT_FOUND:
          throw new FileNotFoundException(url.toString());

        default:
          throw new IOException(url.toString() + ": " + HttpSupport.response(c)
              + " " + c.getResponseMessage());
      }

      try {
        final OutputStream out = new FileOutputStream(dst);
        try {
          final byte[] buf = new byte[8192];
          int n;
          while ((n = in.read(buf)) > 0) {
            out.write(buf, 0, n);
          }
        } finally {
          out.close();
        }
      } finally {
        in.close();
      }
      System.err.println(" OK");
      System.err.flush();
    } catch (IOException err) {
      dst.delete();
      System.err.println(" !! FAIL !!");
      System.err.flush();
      throw err;
    }
  }

  private void verifyFileChecksum() {
    if (sha1 != null) {
      try {
        final MessageDigest md = MessageDigest.getInstance("SHA-1");
        final FileInputStream in = new FileInputStream(dst);
        try {
          final byte[] buf = new byte[8192];
          int n;
          while ((n = in.read(buf)) > 0) {
            md.update(buf, 0, n);
          }
        } finally {
          in.close();
        }

        if (sha1.equals(ObjectId.fromRaw(md.digest()).name())) {
          System.err.println("Checksum " + dst.getName() + " OK");
          System.err.flush();

        } else if (ui.isBatch()) {
          dst.delete();
          throw new Die(dst + " SHA-1 checksum does not match");

        } else if (!ui.yesno(null /* force an answer */,
            "error: SHA-1 checksum does not match\n" + "Use %s anyway",//
            dst.getName())) {
          dst.delete();
          throw new Die("aborted by user");
        }

      } catch (IOException checksumError) {
        dst.delete();
        throw new Die("cannot checksum " + dst, checksumError);

      } catch (NoSuchAlgorithmException checksumError) {
        dst.delete();
        throw new Die("cannot checksum " + dst, checksumError);
      }
    }
  }
}
TOP

Related Classes of com.google.gerrit.pgm.init.LibraryDownloader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.