/** * 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); } }
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; } } }
/** * 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! }
/** * 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()); } } } }