private void load(String pkg) {
    try {
      URL infourl =
          Application.getRessourceURL(JD_CONTROLLING_RECONNECT_PLUGINS + pkg + "/info.json");
      if (infourl == null) {
        LogController.CL().finer("Could not load Reconnect Plugin " + pkg);
        return;
      }

      ReconnectPluginInfo plgInfo =
          JSonStorage.restoreFromString(
              IO.readURLToString(infourl), new TypeRef<ReconnectPluginInfo>() {}, null);
      if (plgInfo == null) {
        LogController.CL().finer("Could not load Reconnect Plugin (no info.json)" + pkg);
        return;
      }
      Class<?> clazz =
          getClass()
              .getClassLoader()
              .loadClass(
                  JD_CONTROLLING_RECONNECT_PLUGINS.replace("/", ".")
                      + pkg
                      + "."
                      + plgInfo.getClassName());
      for (RouterPlugin plg : plugins) {
        if (plg.getClass() == clazz) {
          LogController.CL().finer("Dupe found: " + pkg);
          return;
        }
      }
      plugins.add((RouterPlugin) clazz.newInstance());
    } catch (Throwable e) {
      LogController.CL().log(e);
    }
  }
 private File copyCaptcha(String method, File file) throws Exception {
   final File copy =
       Application.getResource(
           "captchas/"
               + method
               + "/"
               + Hash.getMD5(file)
               + "."
               + Files.getExtension(file.getName()));
   copy.delete();
   copy.getParentFile().mkdirs();
   IO.copyFile(file, copy);
   return copy;
 }
    protected void onChunksReady() {
        logger.info("Close connections if they are not closed yet");
        try {
            for (RAFChunk c : this.getChunks()) {
                c.closeConnections();
            }
        } finally {
            logger.info("Close File. Let AV programs run");
            try {
                outputPartFile.close();
            } catch (Throwable e) {
            }
        }
        downloadLink.getLinkStatus().setStatusText(null);
        if (!handleErrors()) return;
        try {
            File part = new File(outputCompleteFile.getAbsolutePath() + ".part");
            /* lets check the hash/crc/sfv */
            if (JsonConfig.create(GeneralSettings.class).isHashCheckEnabled()) {
                synchronized (HASHCHECKLOCK) {
                    /*
                     * we only want one hashcheck running at the same time. many finished downloads can cause heavy diskusage here
                     */
                    String hash = null;
                    String type = null;
                    Boolean success = null;

                    // StatsManager
                    if ((hash = downloadLink.getMD5Hash()) != null && hash.length() == 32) {
                        /* MD5 Check */
                        type = "MD5";
                        downloadLink.getLinkStatus().setStatusText(_JDT._.system_download_doCRC2("MD5"));
                        String hashFile = Hash.getMD5(part);
                        success = hash.equalsIgnoreCase(hashFile);
                    } else if (!StringUtils.isEmpty(hash = downloadLink.getSha1Hash()) && hash.length() == 40) {
                        /* SHA1 Check */
                        type = "SHA1";
                        downloadLink.getLinkStatus().setStatusText(_JDT._.system_download_doCRC2("SHA1"));
                        String hashFile = Hash.getSHA1(part);
                        success = hash.equalsIgnoreCase(hashFile);
                    } else if ((hash = new Regex(downloadLink.getName(), ".*?\\[([A-Fa-f0-9]{8})\\]").getMatch(0)) != null) {
                        type = "CRC32";
                        String hashFile = Long.toHexString(Hash.getCRC32(part));
                        success = hash.equalsIgnoreCase(hashFile);
                    } else {
                        DownloadLink sfv = null;
                        synchronized (downloadLink.getFilePackage()) {
                            for (DownloadLink dl : downloadLink.getFilePackage().getChildren()) {
                                if (dl.getFileOutput().toLowerCase().endsWith(".sfv")) {
                                    sfv = dl;
                                    break;
                                }
                            }
                        }
                        /* SFV File Available, lets use it */
                        if (sfv != null && sfv.getLinkStatus().hasStatus(LinkStatus.FINISHED)) {
                            String sfvText = IO.readFileToString(new File(sfv.getFileOutput()));
                            if (sfvText != null) {
                                /* Delete comments */
                                sfvText = sfvText.replaceAll(";(.*?)[\r\n]{1,2}", "");
                                if (sfvText != null && sfvText.contains(downloadLink.getName())) {
                                    downloadLink.getLinkStatus().setStatusText(_JDT._.system_download_doCRC2("CRC32"));
                                    type = "CRC32";
                                    String crc = Long.toHexString(Hash.getCRC32(part));
                                    success = new Regex(sfvText, downloadLink.getName() + "\\s*" + crc).matches();
                                }
                            }
                        }
                    }
                    if (success != null) {
                        hashCheckFinished(type, success);
                    }
                }
            }

            boolean renameOkay = false;
            int retry = 5;
            /* rename part file to final filename */
            while (retry > 0) {
                /* first we try normal rename method */
                if ((renameOkay = part.renameTo(outputCompleteFile)) == true) {
                    break;
                }
                /* this may fail because something might lock the file */
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    break;
                }
                retry--;
            }
            /* Fallback */
            if (renameOkay == false) {
                /* rename failed, lets try fallback */
                logger.severe("Could not rename file " + part + " to " + outputCompleteFile);
                logger.severe("Try copy workaround!");
                try {
                    //DISKSPACECHECK freeSpace = DownloadWatchDog.getInstance().checkFreeDiskSpace(part.getParentFile(), part.length());
                    //if (DISKSPACECHECK.FAILED.equals(freeSpace)) throw new Throwable("not enough diskspace free to copy part to complete file");
                    IO.copyFile(part, outputCompleteFile);
                    renameOkay = true;
                    part.deleteOnExit();
                    part.delete();
                } catch (Throwable e) {
                    LogSource.exception(logger, e);
                    /* error happened, lets delete complete file */
                    if (outputCompleteFile.exists() && outputCompleteFile.length() != part.length()) {
                        outputCompleteFile.delete();
                        outputCompleteFile.deleteOnExit();
                    }
                }
                if (!renameOkay) {
                    logger.severe("Copy workaround: :(");
                    error(LinkStatus.ERROR_LOCAL_IO, _JDT._.system_download_errors_couldnotrename());
                } else {
                    logger.severe("Copy workaround: :)");
                }
            }
            if (renameOkay) {

                /*if (StatsManager.I().isEnabled()) {
                    long speed = 0;
                    long startDelay = -1;
                    try {
                        speed = (outputCompleteFile.length() - Math.max(0, sizeBefore)) / ((System.currentTimeMillis() - getStartTimeStamp()) / 1000);
                    } catch (final Throwable e) {
                        LogSource.exception(logger, e);
                    }
                    try {
                        startDelay = System.currentTimeMillis() - downloadLink.getDownloadLinkController().getStartTimestamp();
                    } catch (final Throwable e) {
                        LogSource.exception(logger, e);
                    }
                    StatsManager.I().onFileDownloaded(outputCompleteFile, downloadLink, speed, startDelay, getChunks().size());
                }*/

                /* save absolutepath as final location property */
                downloadLink.setProperty(DownloadLink.PROPERTY_FINALLOCATION, outputCompleteFile.getAbsolutePath());
                Date last = TimeFormatter.parseDateString(connection.getHeaderField("Last-Modified"));
                if (last != null && JsonConfig.create(GeneralSettings.class).isUseOriginalLastModified()) {
                    /* set original lastModified timestamp */
                    outputCompleteFile.setLastModified(last.getTime());
                } else {
                    /* set current timestamp as lastModified timestamp */
                    outputCompleteFile.setLastModified(System.currentTimeMillis());
                }
            }
        } catch (Exception e) {
            logger.log(Level.SEVERE, "Exception", e);
            addException(e);
        }
    }
 private LinkedList<FilePackage> load(File file) {
   synchronized (SAVELOADLOCK) {
     LinkedList<FilePackage> ret = null;
     if (file != null && file.exists()) {
       ZipIOReader zip = null;
       try {
         zip = new ZipIOReader(file);
         /* lets restore the FilePackages from Json */
         HashMap<Integer, FilePackage> map = new HashMap<Integer, FilePackage>();
         DownloadControllerStorable dcs = null;
         InputStream is = null;
         for (ZipEntry entry : zip.getZipFiles()) {
           try {
             if (entry.getName().matches("^\\d+$")) {
               int packageIndex = Integer.parseInt(entry.getName());
               is = zip.getInputStream(entry);
               byte[] bytes = IO.readStream((int) entry.getSize(), is);
               String json = new String(bytes, "UTF-8");
               bytes = null;
               FilePackageStorable storable =
                   JSonStorage.stringToObject(json, new TypeRef<FilePackageStorable>() {}, null);
               json = null;
               if (storable != null) {
                 map.put(packageIndex, storable._getFilePackage());
               } else {
                 throw new WTFException("restored a null FilePackageStorable");
               }
             } else if ("extraInfo".equalsIgnoreCase(entry.getName())) {
               is = zip.getInputStream(entry);
               byte[] bytes = IO.readStream((int) entry.getSize(), is);
               String json = new String(bytes, "UTF-8");
               bytes = null;
               dcs =
                   JSonStorage.stringToObject(
                       json, new TypeRef<DownloadControllerStorable>() {}, null);
               json = null;
             }
           } finally {
             try {
               is.close();
             } catch (final Throwable e) {
             }
           }
         }
         /* sort positions */
         java.util.List<Integer> positions = new ArrayList<Integer>(map.keySet());
         Collections.sort(positions);
         /* build final ArrayList of FilePackages */
         java.util.List<FilePackage> ret2 = new ArrayList<FilePackage>(positions.size());
         for (Integer position : positions) {
           ret2.add(map.get(position));
         }
         if (dcs != null
             && JsonConfig.create(GeneralSettings.class).isConvertRelativePathesJDRoot()) {
           try {
             String oldRootPath = dcs.getRootPath();
             if (!StringUtils.isEmpty(oldRootPath)) {
               String newRoot = JDUtilities.getJDHomeDirectoryFromEnvironment().getAbsolutePath();
               /*
                * convert pathes relative to JDownloader root,only in jared version
                */
               for (FilePackage pkg : ret2) {
                 if (!CrossSystem.isAbsolutePath(pkg.getDownloadDirectory())) {
                   /* no need to convert relative pathes */
                   continue;
                 }
                 String pkgPath = getDownloadDirectory(pkg).getAbsolutePath();
                 if (pkgPath.startsWith(oldRootPath + "/")) {
                   /*
                    * folder is inside JDRoot, lets update it
                    */
                   String restPath = pkgPath.substring(oldRootPath.length());
                   String newPath = new File(newRoot, restPath).getAbsolutePath();
                   pkg.setDownloadDirectory(newPath);
                 }
               }
             }
           } catch (final Throwable e) {
             /* this method can throw exceptions, eg in SVN */
             logger.log(e);
           }
         }
         map = null;
         positions = null;
         ret = new LinkedList<FilePackage>(ret2);
       } catch (final Throwable e) {
         logger.log(e);
       } finally {
         try {
           zip.close();
         } catch (final Throwable e) {
         }
       }
     }
     return ret;
   }
 }
 protected void download(String filename, boolean resume)
     throws IOException, PluginException, SkipReasonException {
   final File file = outputPartFile;
   if (!simpleFTP.isBinary()) {
     logger.info("Warning: Download in ASCII mode may fail!");
   }
   final InetSocketAddress pasv = simpleFTP.pasv();
   resumed = false;
   if (resume) {
     final long resumePosition = file.length();
     if (resumePosition > 0) {
       resumed = true;
       totalLinkBytesLoadedLive.set(resumePosition);
       simpleFTP.sendLine("REST " + resumePosition);
       try {
         simpleFTP.readLines(new int[] {350}, "Resume not supported");
         downloadable.setResumeable(true);
       } catch (final IOException e) {
         cleanupDownladInterface();
         if (e.getMessage().contains("Resume not")) {
           file.delete();
           downloadable.setResumeable(false);
           throw new PluginException(LinkStatus.ERROR_RETRY);
         }
         throw e;
       }
     }
   }
   final RandomAccessFile raf;
   try {
     raf = IO.open(file, "rw");
   } catch (final IOException e) {
     throw new SkipReasonException(SkipReason.INVALID_DESTINATION, e);
   }
   Socket dataSocket = null;
   MeteredThrottledInputStream input = null;
   try {
     dataSocket =
         simpleFTP.createSocket(new InetSocketAddress(pasv.getHostName(), pasv.getPort()));
     dataSocket.setSoTimeout(30 * 1000);
     simpleFTP.sendLine("RETR " + filename);
     simpleFTP.readLines(new int[] {150, 125}, null);
     input =
         new MeteredThrottledInputStream(dataSocket.getInputStream(), new AverageSpeedMeter(10));
     connectionHandler.addThrottledConnection(input);
     if (resumed) {
       /* in case we do resume, reposition the writepointer */
       totalLinkBytesLoaded = file.length();
       raf.seek(totalLinkBytesLoaded);
     } else {
       totalLinkBytesLoaded = 0;
     }
     final byte[] buffer = new byte[32767];
     int bytesRead = 0;
     while ((bytesRead = input.read(buffer)) != -1) {
       if (abort.get()) {
         break;
       }
       if (bytesRead > 0) {
         raf.write(buffer, 0, bytesRead);
         totalLinkBytesLoaded += bytesRead;
         totalLinkBytesLoadedLive.addAndGet(bytesRead);
       }
     }
     /* max 10 seks wait for buggy servers */
     simpleFTP.getSocket().setSoTimeout(20 * 1000);
     simpleFTP.shutDownSocket(dataSocket);
     input.close();
     try {
       simpleFTP.readLine();
     } catch (SocketTimeoutException e) {
       LogSource.exception(logger, e);
     }
   } catch (SocketTimeoutException e) {
     LogSource.exception(logger, e);
     error(
         new PluginException(
             LinkStatus.ERROR_DOWNLOAD_INCOMPLETE,
             _JDT.T.download_error_message_networkreset(),
             LinkStatus.VALUE_NETWORK_IO_ERROR));
   } catch (SocketException e) {
     LogSource.exception(logger, e);
     error(
         new PluginException(
             LinkStatus.ERROR_TEMPORARILY_UNAVAILABLE,
             _JDT.T.download_error_message_networkreset(),
             1000l * 60 * 5));
   } catch (ConnectException e) {
     LogSource.exception(logger, e);
     error(
         new PluginException(
             LinkStatus.ERROR_TEMPORARILY_UNAVAILABLE,
             _JDT.T.download_error_message_networkreset(),
             1000l * 60 * 5));
   } finally {
     close(raf);
     close(input);
     close(dataSocket);
     cleanupDownladInterface();
     if (totalLinkBytesLoaded >= 0) {
       downloadable.setDownloadBytesLoaded(totalLinkBytesLoaded);
     }
   }
 }