예제 #1
0
  /**
   * Given a file and a source this will start a worker-less file downloading.
   *
   * @param nF
   * @param bestSource
   */
  private void startFileDownloading(DownloadFile nF, DownloadSource bestSource) {
    // first ensure that the file is not already complete on disk:
    if (downloadFileCompleteOnDisk(nF)) {
      Logger.warn("Complete download: " + nF + " was in the queue. Issueing completion.");
      nF.downloadComplete(); // issue completion
      wereCompleteItemsInQueue = true;
      return;
    }

    // Create a new info container for the file (if it has never been started before, or if for some
    // reason there are no chunks in it (corrupt for some reason? broken code in the past probably))
    if (nF.active == null) {
      if (nF.getSize() == 0) {
        // zero byte files do not need downloading. (and indeed they will fail to dispatch correctly
        // as they will never have any incomplete chunks)
        try {
          nF.getFile().createNewFile();
          nF.downloadComplete();
          wereCompleteItemsInQueue = true;
          return;
        } catch (IOException e) {
          Logger.severe(
              "Empty file: " + nF.getFile().getPath() + " couldn't be created on disk: " + e);
        }
      }
      nF.active = new DownloadInfo(nF);
    } else {
      if (nF.active.isComplete()) {
        Logger.warn("Complete download: " + nF + " was in the queue. Issueing completion.");
        nF.downloadComplete();
        wereCompleteItemsInQueue = true;
        return;
      } else if (nF.active.chunks.size() == 0) {
        Logger.warn(
            "Active download '"
                + nF
                + "' in queue with no chunks. Restarting download from the beginning.");
        nF.active = new DownloadInfo(nF);
      }
    }

    try {
      // Create the new worker:
      DownloadWorker w = DownloadWorker.getDownloadWorker(this, nF.active);
      nF.active.worker = w;
      workers.add(w);

      // Start one of the download chunks present in the info:
      for (DownloadChunk c : w.getIncompleteInactiveChunks()) {
        w.downloadChunk(c, bestSource, downloadThreadPool);
        break;
      }
    } catch (IOException e) {
      Logger.severe("Unable to dispatch a download: " + e);
      Logger.log(e);
    }
  }
예제 #2
0
  private void dispatchLoop() {
    while (true) {
      long lastIteration = System.currentTimeMillis();

      try {
        // Logger.log("dispatch: "+lastIteration);

        if (mustShutdown) return;
        // 1) kill downloads over the limits
        clipDownloadCount();

        if (mustShutdown) return;

        int canQueue = maxActiveSlots - getActiveSlotCount();
        // only consider dispatching another if there are free slots:
        while (canQueue > 0) {
          // 2) dispatch another file: (this means we prefer to give slots to new files rather than
          // split existing chunks)
          if (!dispatchFile()) break; // stop iterating if the queue is empty.

          if (mustShutdown) return;
          canQueue--;
        }

        if (mustShutdown) return;

        if (canQueue > 0) { // if there are potentially still slots:
          // 3) find chunks ripe for splitting and split and dispatch them:
          chunkWorkers();
        }

        if (mustShutdown) return;

      } catch (Exception e) {
        Logger.warn("Dispatch iteration failed: " + e);
        Logger.log(e);
      }

      // Throttle this loop so that it does not spin exceedinly fast if there is nothing to do.
      long now = System.currentTimeMillis();
      long remaining =
          (lastIteration + FS2Constants.CLIENT_DOWNLOAD_DISPATCH_ITERATION_THROTTLE) - now;
      try {
        if (remaining > 0 && !wereCompleteItemsInQueue) {
          synchronized (this) {
            this.wait(remaining);
          }
        }
        wereCompleteItemsInQueue = false;
      } catch (InterruptedException e) {
        if (mustShutdown) return;
      }
    }
  }
예제 #3
0
  /**
   * Checks if the downloadFile specified has been completed already. This returns true iff: ) file
   * exists ) is expected size ) hashes to the same fs2 hash.
   *
   * @param f
   * @return
   */
  private boolean downloadFileCompleteOnDisk(DownloadFile f) {
    try {
      File onDisk = f.getFile();
      if (!onDisk.isFile()) return false;
      if (onDisk.length() != f.size) return false;
      if (!ThrottledFileDigester.fs2DigestFile(onDisk, null).equals(f.hash)) return false;
    } catch (Exception e) {
      Logger.warn("Couldn't test for file completion on disk: " + e);
      Logger.log(e);
      return false;
    }

    return true; // it's already complete!
  }
예제 #4
0
  /**
   * Check all the merged cells for borders. If the merge record has borders, then we need to rejig
   * the cell formats to take account of this. This is called by the write method of the
   * WritableWorkbookImpl, so that any new XFRecords that are created may be written out with the
   * others
   */
  void checkMergedBorders() {
    Range[] mcells = mergedCells.getMergedCells();
    ArrayList borderFormats = new ArrayList();
    for (int mci = 0; mci < mcells.length; mci++) {
      Range range = mcells[mci];
      Cell topLeft = range.getTopLeft();
      XFRecord tlformat = (XFRecord) topLeft.getCellFormat();

      if (tlformat != null && tlformat.hasBorders() == true && !tlformat.isRead()) {
        try {
          CellXFRecord cf1 = new CellXFRecord(tlformat);
          Cell bottomRight = range.getBottomRight();

          cf1.setBorder(Border.ALL, BorderLineStyle.NONE, Colour.BLACK);
          cf1.setBorder(
              Border.LEFT,
              tlformat.getBorderLine(Border.LEFT),
              tlformat.getBorderColour(Border.LEFT));
          cf1.setBorder(
              Border.TOP, tlformat.getBorderLine(Border.TOP), tlformat.getBorderColour(Border.TOP));

          if (topLeft.getRow() == bottomRight.getRow()) {
            cf1.setBorder(
                Border.BOTTOM,
                tlformat.getBorderLine(Border.BOTTOM),
                tlformat.getBorderColour(Border.BOTTOM));
          }

          if (topLeft.getColumn() == bottomRight.getColumn()) {
            cf1.setBorder(
                Border.RIGHT,
                tlformat.getBorderLine(Border.RIGHT),
                tlformat.getBorderColour(Border.RIGHT));
          }

          int index = borderFormats.indexOf(cf1);
          if (index != -1) {
            cf1 = (CellXFRecord) borderFormats.get(index);
          } else {
            borderFormats.add(cf1);
          }
          ((WritableCell) topLeft).setCellFormat(cf1);

          // Handle the bottom left corner
          if (bottomRight.getRow() > topLeft.getRow()) {
            // Handle the corner cell
            if (bottomRight.getColumn() != topLeft.getColumn()) {
              CellXFRecord cf2 = new CellXFRecord(tlformat);
              cf2.setBorder(Border.ALL, BorderLineStyle.NONE, Colour.BLACK);
              cf2.setBorder(
                  Border.LEFT,
                  tlformat.getBorderLine(Border.LEFT),
                  tlformat.getBorderColour(Border.LEFT));
              cf2.setBorder(
                  Border.BOTTOM,
                  tlformat.getBorderLine(Border.BOTTOM),
                  tlformat.getBorderColour(Border.BOTTOM));

              index = borderFormats.indexOf(cf2);
              if (index != -1) {
                cf2 = (CellXFRecord) borderFormats.get(index);
              } else {
                borderFormats.add(cf2);
              }

              sheet.addCell(new Blank(topLeft.getColumn(), bottomRight.getRow(), cf2));
            }

            // Handle the cells down the left hand side (and along the
            // right too, if necessary)
            for (int i = topLeft.getRow() + 1; i < bottomRight.getRow(); i++) {
              CellXFRecord cf3 = new CellXFRecord(tlformat);
              cf3.setBorder(Border.ALL, BorderLineStyle.NONE, Colour.BLACK);
              cf3.setBorder(
                  Border.LEFT,
                  tlformat.getBorderLine(Border.LEFT),
                  tlformat.getBorderColour(Border.LEFT));

              if (topLeft.getColumn() == bottomRight.getColumn()) {
                cf3.setBorder(
                    Border.RIGHT,
                    tlformat.getBorderLine(Border.RIGHT),
                    tlformat.getBorderColour(Border.RIGHT));
              }

              index = borderFormats.indexOf(cf3);
              if (index != -1) {
                cf3 = (CellXFRecord) borderFormats.get(index);
              } else {
                borderFormats.add(cf3);
              }

              sheet.addCell(new Blank(topLeft.getColumn(), i, cf3));
            }
          }

          // Handle the top right corner
          if (bottomRight.getColumn() > topLeft.getColumn()) {
            if (bottomRight.getRow() != topLeft.getRow()) {
              // Handle the corner cell
              CellXFRecord cf6 = new CellXFRecord(tlformat);
              cf6.setBorder(Border.ALL, BorderLineStyle.NONE, Colour.BLACK);
              cf6.setBorder(
                  Border.RIGHT,
                  tlformat.getBorderLine(Border.RIGHT),
                  tlformat.getBorderColour(Border.RIGHT));
              cf6.setBorder(
                  Border.TOP,
                  tlformat.getBorderLine(Border.TOP),
                  tlformat.getBorderColour(Border.TOP));
              index = borderFormats.indexOf(cf6);
              if (index != -1) {
                cf6 = (CellXFRecord) borderFormats.get(index);
              } else {
                borderFormats.add(cf6);
              }

              sheet.addCell(new Blank(bottomRight.getColumn(), topLeft.getRow(), cf6));
            }

            // Handle the cells along the right
            for (int i = topLeft.getRow() + 1; i < bottomRight.getRow(); i++) {
              CellXFRecord cf7 = new CellXFRecord(tlformat);
              cf7.setBorder(Border.ALL, BorderLineStyle.NONE, Colour.BLACK);
              cf7.setBorder(
                  Border.RIGHT,
                  tlformat.getBorderLine(Border.RIGHT),
                  tlformat.getBorderColour(Border.RIGHT));

              index = borderFormats.indexOf(cf7);
              if (index != -1) {
                cf7 = (CellXFRecord) borderFormats.get(index);
              } else {
                borderFormats.add(cf7);
              }

              sheet.addCell(new Blank(bottomRight.getColumn(), i, cf7));
            }

            // Handle the cells along the top, and along the bottom too
            for (int i = topLeft.getColumn() + 1; i < bottomRight.getColumn(); i++) {
              CellXFRecord cf8 = new CellXFRecord(tlformat);
              cf8.setBorder(Border.ALL, BorderLineStyle.NONE, Colour.BLACK);
              cf8.setBorder(
                  Border.TOP,
                  tlformat.getBorderLine(Border.TOP),
                  tlformat.getBorderColour(Border.TOP));

              if (topLeft.getRow() == bottomRight.getRow()) {
                cf8.setBorder(
                    Border.BOTTOM,
                    tlformat.getBorderLine(Border.BOTTOM),
                    tlformat.getBorderColour(Border.BOTTOM));
              }

              index = borderFormats.indexOf(cf8);
              if (index != -1) {
                cf8 = (CellXFRecord) borderFormats.get(index);
              } else {
                borderFormats.add(cf8);
              }

              sheet.addCell(new Blank(i, topLeft.getRow(), cf8));
            }
          }

          // Handle the bottom right corner
          if (bottomRight.getColumn() > topLeft.getColumn()
              || bottomRight.getRow() > topLeft.getRow()) {
            // Handle the corner cell
            CellXFRecord cf4 = new CellXFRecord(tlformat);
            cf4.setBorder(Border.ALL, BorderLineStyle.NONE, Colour.BLACK);
            cf4.setBorder(
                Border.RIGHT,
                tlformat.getBorderLine(Border.RIGHT),
                tlformat.getBorderColour(Border.RIGHT));
            cf4.setBorder(
                Border.BOTTOM,
                tlformat.getBorderLine(Border.BOTTOM),
                tlformat.getBorderColour(Border.BOTTOM));

            if (bottomRight.getRow() == topLeft.getRow()) {
              cf4.setBorder(
                  Border.TOP,
                  tlformat.getBorderLine(Border.TOP),
                  tlformat.getBorderColour(Border.TOP));
            }

            if (bottomRight.getColumn() == topLeft.getColumn()) {
              cf4.setBorder(
                  Border.LEFT,
                  tlformat.getBorderLine(Border.LEFT),
                  tlformat.getBorderColour(Border.LEFT));
            }

            index = borderFormats.indexOf(cf4);
            if (index != -1) {
              cf4 = (CellXFRecord) borderFormats.get(index);
            } else {
              borderFormats.add(cf4);
            }

            sheet.addCell(new Blank(bottomRight.getColumn(), bottomRight.getRow(), cf4));

            // Handle the cells along the bottom (and along the top
            // as well, if appropriate)
            for (int i = topLeft.getColumn() + 1; i < bottomRight.getColumn(); i++) {
              CellXFRecord cf5 = new CellXFRecord(tlformat);
              cf5.setBorder(Border.ALL, BorderLineStyle.NONE, Colour.BLACK);
              cf5.setBorder(
                  Border.BOTTOM,
                  tlformat.getBorderLine(Border.BOTTOM),
                  tlformat.getBorderColour(Border.BOTTOM));

              if (topLeft.getRow() == bottomRight.getRow()) {
                cf5.setBorder(
                    Border.TOP,
                    tlformat.getBorderLine(Border.TOP),
                    tlformat.getBorderColour(Border.TOP));
              }

              index = borderFormats.indexOf(cf5);
              if (index != -1) {
                cf5 = (CellXFRecord) borderFormats.get(index);
              } else {
                borderFormats.add(cf5);
              }

              sheet.addCell(new Blank(i, bottomRight.getRow(), cf5));
            }
          }
        } catch (WriteException e) {
          // just log e.toString(), not the whole stack trace
          logger.warn(e.toString());
        }
      }
    }
  }