Example #1
0
  @Override
  protected void doDownload(Resource rsrc) throws IOException {
    // download the resource from the specified URL
    URLConnection conn = ConnectionUtil.open(rsrc.getRemote());
    conn.connect();

    // make sure we got a satisfactory response code
    if (conn instanceof HttpURLConnection) {
      HttpURLConnection hcon = (HttpURLConnection) conn;
      if (hcon.getResponseCode() != HttpURLConnection.HTTP_OK) {
        throw new IOException(
            "Unable to download resource " + rsrc.getRemote() + ": " + hcon.getResponseCode());
      }
    }

    long actualSize = conn.getContentLength();
    log.info("Downloading resource", "url", rsrc.getRemote(), "size", actualSize);
    InputStream in = null;
    FileOutputStream out = null;
    long currentSize = 0L;
    try {
      in = conn.getInputStream();
      out = new FileOutputStream(rsrc.getLocal());
      int read;

      // TODO: look to see if we have a download info file
      // containing info on potentially partially downloaded data;
      // if so, use a "Range: bytes=HAVE-" header.

      // read in the file data
      while ((read = in.read(_buffer)) != -1) {
        // write it out to our local copy
        out.write(_buffer, 0, read);

        // if we have no observer, then don't bother computing download statistics
        if (_obs == null) {
          continue;
        }

        // note that we've downloaded some data
        currentSize += read;
        updateObserver(rsrc, currentSize, actualSize);
      }
    } finally {
      StreamUtil.close(in);
      StreamUtil.close(out);
    }
  }
Example #2
0
  @Override
  protected long checkSize(Resource rsrc) throws IOException {
    URLConnection conn = ConnectionUtil.open(rsrc.getRemote());
    try {
      // if we're accessing our data via HTTP, we only need a HEAD request
      if (conn instanceof HttpURLConnection) {
        HttpURLConnection hcon = (HttpURLConnection) conn;
        hcon.setRequestMethod("HEAD");
        hcon.connect();
        // make sure we got a satisfactory response code
        if (hcon.getResponseCode() != HttpURLConnection.HTTP_OK) {
          throw new IOException(
              "Unable to check up-to-date for " + rsrc.getRemote() + ": " + hcon.getResponseCode());
        }
      }
      return conn.getContentLength();

    } finally {
      // let it be known that we're done with this connection
      conn.getInputStream().close();
    }
  }
Example #3
0
  protected void createPatch(
      File patch, ArrayList<Resource> orsrcs, ArrayList<Resource> nrsrcs, boolean verbose)
      throws IOException {
    MessageDigest md = Digest.getMessageDigest();
    JarOutputStream jout = null;
    try {
      jout = new JarOutputStream(new BufferedOutputStream(new FileOutputStream(patch)));

      // for each file in the new application, it either already exists
      // in the old application, or it is new
      for (Resource rsrc : nrsrcs) {
        int oidx = orsrcs.indexOf(rsrc);
        Resource orsrc = (oidx == -1) ? null : orsrcs.remove(oidx);
        if (orsrc != null) {
          // first see if they are the same
          String odig = orsrc.computeDigest(md, null);
          String ndig = rsrc.computeDigest(md, null);
          if (odig.equals(ndig)) {
            if (verbose) {
              System.out.println("Unchanged: " + rsrc.getPath());
            }
            // by leaving it out, it will be left as is during the
            // patching process
            continue;
          }

          // otherwise potentially create a jar diff
          if (rsrc.getPath().endsWith(".jar")) {
            if (verbose) {
              System.out.println("JarDiff: " + rsrc.getPath());
            }
            // here's a juicy one: JarDiff blindly pulls ZipEntry
            // objects out of one jar file and stuffs them into
            // another without clearing out things like the
            // compressed size, so if, for whatever reason (like
            // different JRE versions or phase of the moon) the
            // compressed size in the old jar file is different
            // than the compressed size generated when creating the
            // jardiff jar file, ZipOutputStream will choke and
            // we'll be hosed; so we recreate the jar files in
            // their entirety before running jardiff on 'em
            File otemp = rebuildJar(orsrc.getLocal());
            File temp = rebuildJar(rsrc.getLocal());
            jout.putNextEntry(new ZipEntry(rsrc.getPath() + Patcher.PATCH));
            jarDiff(otemp, temp, jout);
            otemp.delete();
            temp.delete();
            continue;
          }
        }

        if (verbose) {
          System.out.println("Addition: " + rsrc.getPath());
        }
        jout.putNextEntry(new ZipEntry(rsrc.getPath() + Patcher.CREATE));
        pipe(rsrc.getLocal(), jout);
      }

      // now any file remaining in orsrcs needs to be removed
      for (Resource rsrc : orsrcs) {
        // add an entry with the resource name and the deletion suffix
        if (verbose) {
          System.out.println("Removal: " + rsrc.getPath());
        }
        jout.putNextEntry(new ZipEntry(rsrc.getPath() + Patcher.DELETE));
      }

      StreamUtil.close(jout);
      System.out.println("Created patch file: " + patch);

    } catch (IOException ioe) {
      StreamUtil.close(jout);
      patch.delete();
      throw ioe;
    }
  }