/**
   * Returns true if the code was executed correctly. False if there was an error trying to share
   * the file. If the file was not supposed to be shared, and was not shared, true would still be
   * returned.
   */
  private boolean shareTorrentFile(File torrentFile) {
    if (torrentManager.isDownloadingTorrent(torrentFile)) {
      return true;
    }

    if (!SharingSettings.SHARE_DOWNLOADED_FILES_IN_NON_SHARED_DIRECTORIES.getValue()) {
      return true;
    }

    BTData btData = null;
    FileInputStream torrentInputStream = null;
    try {
      torrentInputStream = new FileInputStream(torrentFile);
      Map<?, ?> torrentFileMap = (Map<?, ?>) Token.parse(torrentInputStream.getChannel());
      btData = new BTDataImpl(torrentFileMap);
    } catch (IOException e) {
      LOG.error("Error reading torrent file: " + torrentFile, e);
      return false;
    } finally {
      FileUtils.close(torrentInputStream);
    }

    if (btData.isPrivate()) {
      gnutellaFileList.remove(torrentFile);
      return true;
    }

    File saveDir = SharingSettings.getSaveDirectory();
    File torrentParent = torrentFile.getParentFile();
    if (torrentParent.equals(saveDir)) {
      // already in saveDir
      gnutellaFileList.add(torrentFile);
      return true;
    }

    final File tFile = getSharedTorrentMetaDataFile(btData);
    if (tFile.equals(torrentFile)) {
      gnutellaFileList.add(tFile);
      return true;
    }

    gnutellaFileList.remove(tFile);
    File backup = null;
    if (tFile.exists()) {
      backup = new File(tFile.getParent(), tFile.getName().concat(".bak"));
      FileUtils.forceRename(tFile, backup);
    }

    if (FileUtils.copy(torrentFile, tFile)) {
      gnutellaFileList.add(tFile);
    } else {
      if (backup != null) {
        // restore backup
        if (FileUtils.forceRename(backup, tFile)) {
          gnutellaFileList.add(tFile);
        }
      }
    }
    return true;
  }
 /**
  * Adds a root to the tree if it's not already in there.
  *
  * @return false if dir is already in the tree
  */
 public boolean addRoot(File dir) {
   // remove from deselected in any case
   boolean changed = deselected.remove(dir);
   // check if already included
   for (File root : roots) {
     if (FileUtils.isAncestor(root, dir)) {
       if (root.equals(dir)) {
         if (changed) {
           directoryTreeModel.valueForPathChanged(getTreePath(dir), null);
         }
         return changed;
       }
       // make sure it is included
       removeFromPath(dir);
       TreePath path = getTreePath(dir);
       directoryTree.scrollPathToVisible(path);
       return changed;
     } else if (FileUtils.isAncestor(dir, root)) {
       removeRoot(root);
       addDirToTree(dir);
       // expand to root and its parent, since expand has no effect if root
       // doesn't have subfolders
       setExpanded(root);
       // guaranteed to not be null since at least dir is its real ancestor
       setExpanded(root.getParentFile());
       return true;
     }
   }
   addDirToTree(dir);
   setRootExpanded();
   return true;
 }
예제 #3
0
  void moveToCompleteFolder() {
    File parent = _incompleteFile.getParentFile();
    boolean success = _incompleteFile.renameTo(_completeFile);
    if (!success) {
      success = FileUtils.copy(_incompleteFile, _completeFile);
      if (success) _incompleteFile.delete();
    }

    if (success) FileUtils.deleteRecursive(parent);
  }
예제 #4
0
  /**
   * Opens a dialog asking the user to choose a file which is is used for saving to.
   *
   * @param parent the parent component the dialog is centered on
   * @param titleKey the key for the locale-specific string to use for the file dialog title
   * @param suggestedFile the suggested file for saving
   * @param the filter to use for what's shown.
   * @return the file or <code>null</code> when the user cancelled the dialog
   */
  public static File getSaveAsFile(
      Component parent, String titleKey, File suggestedFile, final FileFilter filter) {
    if (OSUtils.isAnyMac()) {
      FileDialog dialog =
          new FileDialog(GUIMediator.getAppFrame(), I18n.tr(titleKey), FileDialog.SAVE);
      dialog.setDirectory(suggestedFile.getParent());
      dialog.setFile(suggestedFile.getName());
      if (filter != null) {
        FilenameFilter f =
            new FilenameFilter() {
              public boolean accept(File dir, String name) {
                return filter.accept(new File(dir, name));
              }
            };
        dialog.setFilenameFilter(f);
      }

      dialog.setVisible(true);
      String dir = dialog.getDirectory();
      setLastInputDirectory(new File(dir));
      String file = dialog.getFile();
      if (dir != null && file != null) {

        if (suggestedFile != null) {
          String suggestedFileExtension = FileUtils.getFileExtension(suggestedFile);

          String newFileExtension = FileUtils.getFileExtension(file);

          if (newFileExtension == null && suggestedFileExtension != null) {
            file = file + "." + suggestedFileExtension;
          }
        }

        File f = new File(dir, file);
        if (filter != null && !filter.accept(f)) return null;
        else return f;
      } else {
        return null;
      }
    } else {
      JFileChooser chooser =
          getDirectoryChooser(titleKey, null, null, JFileChooser.FILES_ONLY, filter);
      chooser.setSelectedFile(suggestedFile);
      int ret = chooser.showSaveDialog(parent);
      File file = chooser.getSelectedFile();
      setLastInputDirectory(file);
      return ret != JFileChooser.APPROVE_OPTION ? null : file;
    }
  }
예제 #5
0
  /**
   * Deletes incomplete files more than INCOMPLETE_PURGE_TIME days old from disk Then removes
   * entries in this for which there is no file on disk.
   *
   * @param activeFiles which files are currently being downloaded.
   * @return true iff any entries were purged
   */
  public synchronized boolean initialPurge(Collection<File> activeFiles) {
    // Remove any files that are old.
    boolean ret = false;
    for (Iterator<File> iter = blocks.keySet().iterator(); iter.hasNext(); ) {
      File file = iter.next();
      try {
        file = FileUtils.getCanonicalFile(file);
      } catch (IOException iox) {
        file = file.getAbsoluteFile();
      }
      if (!file.exists() || (isOld(file) && !activeFiles.contains(file))) {
        ret = true;
        fileManager.get().getManagedFileList().remove(file);
        file.delete();
        iter.remove();
      }
    }
    for (Iterator<File> iter = hashes.values().iterator(); iter.hasNext(); ) {
      File file = iter.next();
      if (!file.exists()) {
        iter.remove();
        ret = true;
      }
    }

    return ret;
  }
예제 #6
0
  private void recursiveButtonSearch(Container container) {
    for (Component component : container.getComponents()) {
      if (component instanceof Container) {
        recursiveButtonSearch((Container) component);
      }
      if (component instanceof JButton) {
        JButton button = (JButton) component;
        String buttonText = button.getText();

        // Using end of button text to determine whether button shouild be disabled
        // then disable it.  This is because JEditorPane does not disable buttons
        // disabled in the form html
        if (buttonText.endsWith(":disabled")) {
          buttonText = buttonText.substring(0, buttonText.lastIndexOf(":disabled"));
          button.setText(buttonText);
          button.setEnabled(false);
        }

        String extension = FileUtils.getFileExtension(buttonText);
        if (!extension.isEmpty()) {
          Icon icon = iconManager.get().getIconForExtension(extension);
          button.setIcon(icon);
        }
      }
    }
  }
  private void handleCoreDownloader() {
    File possibleTorrentFile = null;

    possibleTorrentFile = downloader.getSaveFile();
    String fileExtension = FileUtils.getFileExtension(possibleTorrentFile);
    if ("torrent".equalsIgnoreCase(fileExtension)) {
      try {
        shareTorrentFile(possibleTorrentFile);
        downloadManager.downloadTorrent(possibleTorrentFile, null, false);
        downloadItems.remove(getDownloadItem(downloader));
      } catch (DownloadException e) {
        final File torrentFile = possibleTorrentFile;
        activityCallback.handleDownloadException(
            new DownloadAction() {
              @Override
              public void download(File saveDirectory, boolean overwrite) throws DownloadException {
                downloadManager.downloadTorrent(torrentFile, saveDirectory, overwrite);
                downloadItems.remove(getDownloadItem(downloader));
              }

              @Override
              public void downloadCanceled(DownloadException ignored) {
                // nothing to do
              }
            },
            e,
            false);
      }
    }
  }
예제 #8
0
  /** Loads a playlist. */
  public void importM3U(Playlist playlist) {
    File parentFile = FileChooserHandler.getLastInputDirectory();

    if (parentFile == null) parentFile = CommonUtils.getCurrentDirectory();

    final File selFile =
        FileChooserHandler.getInputFile(
            GUIMediator.getAppFrame(),
            I18nMarker.marktr("Open Playlist (.m3u)"),
            parentFile,
            new PlaylistListFileFilter());

    // nothing selected? exit.
    if (selFile == null || !selFile.isFile()) return;

    String path = selFile.getPath();
    try {
      path = FileUtils.getCanonicalPath(selFile);
    } catch (IOException ignored) {
      // LOG.warn("unable to get canonical path for file: " + selFile, ignored);
    }

    // create a new thread off of the event queue to process reading the files from
    //  disk
    loadM3U(playlist, selFile, path);
  }
예제 #9
0
  private static ThemeSetter loadCurrentTheme() {
    ThemeSetter currentTheme = DEFAULT_THEME;

    BufferedReader input = null;

    try {

      File skinsFile = ThemeSettings.SKINS_FILE;

      if (skinsFile.exists()) {
        input = new BufferedReader(new FileReader(skinsFile));
        String name = input.readLine();
        for (int i = 0; i < THEMES.size(); i++) {
          if (THEMES.get(i).getName().equals(name)) {
            currentTheme = THEMES.get(i);
            break;
          }
        }
      }

    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      FileUtils.close(input);
    }

    return currentTheme;
  }
    public boolean accept(File pathname) {
      if (FileUtils.isAncestor(SharingSettings.TORRENT_DATA_DIR_SETTING.getValue(), pathname)) {
        return false;
      }

      for (File f : LibrarySettings.DIRECTORIES_TO_INCLUDE_FROM_FROSTWIRE4.getValue()) {
        if (FileUtils.isAncestor(f, pathname)) {
          return false;
        }
      }

      if (FileUtils.isAncestor(LibrarySettings.USER_MUSIC_FOLDER.getValue(), pathname)) {
        return false;
      }

      return pathname.isDirectory() && !pathname.isHidden();
    }
 /** Returns true if dir is excluded from sharing or one of its ancestors is. */
 private boolean isExcluded(File dir) {
   for (File file : deselected) {
     if (FileUtils.isAncestor(file, dir)) {
       return true;
     }
   }
   return false;
 }
 /** Returns true if dir and all its subfolders are included. */
 private boolean isFullyIncluded(File dir) {
   for (File offspring : deselected) {
     if (FileUtils.isAncestor(dir, offspring)) {
       return false;
     }
   }
   return true;
 }
예제 #13
0
  /** Saves a playlist. */
  public void exportM3U(Playlist playlist) {

    if (playlist == null) {
      return;
    }

    String suggestedName = CommonUtils.convertFileName(playlist.getName());

    // get the user to select a new one.... avoid FrostWire installation folder.
    File suggested;
    File suggestedDirectory = FileChooserHandler.getLastInputDirectory();
    if (suggestedDirectory.equals(CommonUtils.getCurrentDirectory())) {
      suggestedDirectory = new File(CommonUtils.getUserHomeDir(), "Desktop");
    }

    suggested = new File(suggestedDirectory, suggestedName + ".m3u");

    File selFile =
        FileChooserHandler.getSaveAsFile(
            GUIMediator.getAppFrame(),
            I18nMarker.marktr("Save Playlist As"),
            suggested,
            new PlaylistListFileFilter());

    // didn't select a file?  nothing we can do.
    if (selFile == null) {
      return;
    }

    // if the file already exists and not the one just opened, ask if it should be
    //  overwritten.
    // TODO: this should be handled in the jfilechooser
    if (selFile.exists()) {
      DialogOption choice =
          GUIMediator.showYesNoMessage(
              I18n.tr(
                  "Warning: a file with the name {0} already exists in the folder. Overwrite this file?",
                  selFile.getName()),
              QuestionsHandler.PLAYLIST_OVERWRITE_OK,
              DialogOption.NO);
      if (choice != DialogOption.YES) return;
    }

    String path = selFile.getPath();
    try {
      path = FileUtils.getCanonicalPath(selFile);
    } catch (IOException ignored) {
      // LOG.warn("unable to get canonical path for file: " + selFile, ignored);
    }
    // force m3u on the end.
    if (!path.toLowerCase().endsWith(".m3u")) path += ".m3u";

    // create a new thread to handle saving the playlist to disk
    saveM3U(playlist, path);
  }
예제 #14
0
 boolean isAlreadyGoingToBeShared(File dir) {
   if (sharingPanel.getFoldersToExclude().contains(dir)) {
     return false;
   }
   for (File folder : sharingPanel.getRootsToShare()) {
     if (FileUtils.isAncestor(folder, dir)) {
       return true;
     }
   }
   return false;
 }
  public static void populateProperties(
      String fileName,
      long fileSize,
      long creationTime,
      Map<FilePropertyKey, Object> properties,
      LimeXMLDocument doc) {

    properties.put(FilePropertyKey.NAME, ""); // Make sure name defaults to empty.
    set(properties, FilePropertyKey.NAME, FileUtils.getFilenameNoExtension(fileName));
    set(properties, FilePropertyKey.DATE_CREATED, creationTime);
    set(properties, FilePropertyKey.FILE_SIZE, fileSize);

    String extension = FileUtils.getFileExtension(fileName);
    Category category = CategoryConverter.categoryForExtension(extension);

    if (doc != null) {
      for (FilePropertyKey filePropertyKey : FilePropertyKey.values()) {
        set(properties, doc, category, filePropertyKey);
      }

      Long bitrate, length;
      Integer quality;
      switch (category) {
        case AUDIO:
          bitrate = CommonUtils.parseLongNoException(doc.getValue(LimeXMLNames.AUDIO_BITRATE));
          length = CommonUtils.parseLongNoException(doc.getValue(LimeXMLNames.AUDIO_SECONDS));
          quality = toAudioQualityScore(extension, fileSize, bitrate, length);
          set(properties, FilePropertyKey.QUALITY, quality);
          break;
        case VIDEO:
          bitrate = CommonUtils.parseLongNoException(doc.getValue(LimeXMLNames.VIDEO_BITRATE));
          length = CommonUtils.parseLongNoException(doc.getValue(LimeXMLNames.VIDEO_LENGTH));
          Long height = CommonUtils.parseLongNoException(doc.getValue(LimeXMLNames.VIDEO_HEIGHT));
          Long width = CommonUtils.parseLongNoException(doc.getValue(LimeXMLNames.VIDEO_WIDTH));
          quality = toVideoQualityScore(extension, fileSize, bitrate, length, height, width);
          set(properties, FilePropertyKey.QUALITY, quality);
          break;
      }
    }
  }
예제 #16
0
  private static void saveCurrentTheme(ThemeSetter theme) throws IOException {
    File skinsFile = ThemeSettings.SKINS_FILE;

    BufferedWriter output = new BufferedWriter(new FileWriter(skinsFile));

    try {

      output.write(theme.getName());

    } finally {
      FileUtils.close(output);
    }
  }
 /**
  * Retains common ancestors and removes subfolders since they will be part of the recursive
  * sharing.
  */
 static Set<File> retainAncestors(File... roots) {
   if (roots == null) {
     return new HashSet<File>();
   }
   for (int i = 0; i < roots.length; i++) {
     for (int j = i + 1; j < roots.length && roots[i] != null; j++) {
       if (roots[j] != null) {
         if (FileUtils.isAncestor(roots[i], roots[j])) {
           roots[j] = null;
         } else if (FileUtils.isAncestor(roots[j], roots[i])) {
           roots[i] = null;
         }
       }
     }
   }
   Set<File> retained = new HashSet<File>(roots.length);
   for (File file : roots) {
     if (file != null) {
       retained.add(file);
     }
   }
   return retained;
 }
예제 #18
0
  /**
   * replaces tokens in the update command with info about the specific system i.e. <PATH> ->
   * C:\Documents And Settings....
   */
  private static void prepareUpdateCommand(UpdateData info) {
    if (info == null || info.getUpdateCommand() == null) return;

    File path = LibraryUtils.PREFERENCE_SHARE.getAbsoluteFile();
    String name = info.getUpdateFileName();

    try {
      path = FileUtils.getCanonicalFile(path);
    } catch (IOException bad) {
    }

    String command = info.getUpdateCommand();
    command = StringUtils.replace(command, "$", path.getPath() + File.separator);
    command = StringUtils.replace(command, "%", name);
    info.setUpdateCommand(command);
  }
  private void storeAndUpdate(byte[] data, SimppParser parser, UpdateType updateType) {
    if (LOG.isTraceEnabled())
      LOG.trace("Retrieved new data from: " + updateType + ", storing & updating");
    if (parser.getVersion() == IGNORE_ID && updateType == UpdateType.FROM_NETWORK)
      throw new IllegalStateException("shouldn't be here!");

    if (updateType == UpdateType.FROM_NETWORK && httpRequestControl.isRequestPending()) return;

    _lastId = parser.getVersion();
    _lastBytes = data;

    if (updateType != UpdateType.FROM_DISK) {
      FileUtils.verySafeSave(CommonUtils.getUserSettingsDir(), FILENAME, data);
    }

    for (SimppSettingsManager ssm : simppSettingsManagers)
      ssm.updateSimppSettings(parser.getPropsData());
    for (SimppListener listener : listeners) listener.simppUpdated(_lastId);
  }
 /**
  * Removes all files from <code>deselected</code> that are ancestors
  * of <code>file</code or vice versa.
  */
 private void removeFromPath(File file) {
   // remove all children, file itself is removed here too
   for (Iterator<File> i = deselected.iterator(); i.hasNext(); ) {
     File f = i.next();
     if (FileUtils.isAncestor(file, f)) {
       i.remove();
     }
   }
   while (file != null && !roots.contains(file)) {
     // mark other children of parent as excluded
     File parent = file.getParentFile();
     if (ancestorIsExcluded(parent)) {
       deselected.remove(parent);
       int childCount = directoryTreeModel.getChildCount(parent);
       for (int j = 0; j < childCount; j++) {
         File sibling = (File) directoryTreeModel.getChild(parent, j);
         if (sibling != null && !sibling.equals(file)) {
           deselected.add(sibling);
         }
       }
     }
     file = parent;
   }
 }
예제 #21
0
 /**
  * A utility method to close Closeable objects (Readers, Writers, Input- and OutputStreams and
  * RandomAccessFiles).
  */
 public static void close(Closeable closeable) {
   FileUtils.close(closeable);
 }
예제 #22
0
  /**
   * Returns true if a file with the given name is of this media type, i.e., the suffix of the
   * filename matches one of this' extensions.
   */
  public boolean matches(String filename) {
    if (exts == null) return true;

    return FileUtils.hasExtension(filename, extsArray);
  }
예제 #23
0
  /**
   * Stores the given data to disk & posts an update to neighboring connections. Starts the download
   * of any updates
   */
  private void storeAndUpdate(byte[] data, UpdateCollection uc, UpdateType updateType) {
    if (LOG.isTraceEnabled())
      LOG.trace("Retrieved new data from: " + updateType + ", storing & updating.");
    if (uc.getId() == IGNORE_ID && updateType == UpdateType.FROM_NETWORK)
      throw new IllegalStateException("shouldn't be here!");

    // If an http max request is pending, don't even bother with this stuff.
    // We want to get it straight from the source...
    if (updateType == UpdateType.FROM_NETWORK
        && httpRequestControl.isRequestPending()
        && httpRequestControl.getRequestReason() == HttpRequestControl.RequestReason.MAX) return;

    _lastId = uc.getId();

    _lastTimestamp = uc.getTimestamp();
    UpdateSettings.LAST_UPDATE_TIMESTAMP.setValue(_lastTimestamp);

    long delay = UpdateSettings.UPDATE_DOWNLOAD_DELAY.getValue();
    long random = Math.abs(RANDOM.nextLong() % delay);
    _nextDownloadTime = _lastTimestamp + random;

    _lastBytes = data;

    if (updateType != UpdateType.FROM_DISK) {
      // cancel any http and pretend we just updated.
      if (httpRequestControl.getRequestReason() == HttpRequestControl.RequestReason.TIMEOUT)
        httpRequestControl.cancelRequest();
      UpdateSettings.LAST_HTTP_FAILOVER.setValue(clock.now());

      FileUtils.verySafeSave(CommonUtils.getUserSettingsDir(), FILENAME, data);
      capabilitiesVMFactory.updateCapabilities();
      connectionManager.get().sendUpdatedCapabilities();
    }

    Version limeV;
    try {
      limeV = new Version(LimeWireUtils.getLimeWireVersion());
    } catch (VersionFormatException vfe) {
      LOG.warn("Invalid LimeWire version", vfe);
      return;
    }

    Version javaV = null;
    try {
      javaV = new Version(VersionUtils.getJavaVersion());
    } catch (VersionFormatException vfe) {
      LOG.warn("Invalid java version", vfe);
    }

    // don't allow someone to set the style to be above major.
    int style = Math.min(UpdateStyle.STYLE_MAJOR, UpdateSettings.UPDATE_STYLE.getValue());

    UpdateData updateInfo =
        uc.getUpdateDataFor(
            limeV, ApplicationSettings.getLanguage(), LimeWireUtils.isPro(), style, javaV);

    List<DownloadInformation> updatesToDownload = uc.getUpdatesWithDownloadInformation();
    _killingObsoleteNecessary = true;

    // if we have an update for our machine, prepare the command line
    // and move our update to the front of the list of updates
    if (updateInfo != null && updateInfo.getUpdateURN() != null) {
      prepareUpdateCommand(updateInfo);
      updatesToDownload = new LinkedList<DownloadInformation>(updatesToDownload);
      updatesToDownload.add(0, updateInfo);
    }

    _updateInfo = updateInfo;
    _updatesToDownload = updatesToDownload;

    downloadUpdates(updatesToDownload, null);
    if (updateInfo == null) {
      LOG.warn("No relevant update info to notify about.");
      return;
    } else if (updateInfo.getUpdateURN() == null || isHopeless(updateInfo)) {
      if (LOG.isDebugEnabled())
        LOG.debug(
            "we have an update, but it doesn't need a download.  "
                + "or all our updates are hopeles. Scheduling URL notification...");

      updateInfo.setUpdateCommand(null);

      backgroundExecutor.schedule(
          new NotificationFailover(_lastId),
          delay(clock.now(), uc.getTimestamp()),
          TimeUnit.MILLISECONDS);
    } else if (isMyUpdateDownloaded(updateInfo)) {
      LOG.debug("there is an update for me, but I happen to have it on disk");
      fireUpdate(updateInfo);
    } else LOG.debug("we have an update, it needs a download.  Rely on callbacks");
  }
예제 #24
0
  /**
   * Returns the fully-qualified temporary download file for the given file/location pair. If an
   * incomplete file already exists for this URN, that file is returned. Otherwise, the location of
   * the file is determined by the "incDir" variable. For example, getFile("test.txt", 1999) may
   * return "C:\Program Files\LimeWire\Incomplete\T-1999-Test.txt" if "incDir" is "C:\Program
   * Files\LimeWire\Incomplete". The disk is not modified, except for the file possibly being
   * created.
   *
   * <p>This method gives duplicate files the same temporary file, which is critical for resume and
   * swarmed downloads. That is, for all rfd_i and rfd_j
   *
   * <pre>
   *      similar(rfd_i, rfd_j) <==> getFile(rfd_i).equals(getFile(rfd_j))<p>
   * </pre>
   *
   * It is imperative that the files are compared as in their canonical formats to preserve the
   * integrity of the filesystem. Otherwise, multiple downloads could be downloading to "FILE A",
   * and "file a", although only "file a" exists on disk and is being written to by both.
   *
   * @throws IOException if there was an IOError while determining the file's name.
   */
  public synchronized File getFile(String name, URN sha1, long size, File incDir)
      throws IOException {
    boolean dirsMade = false;
    File baseFile = null;
    File canonFile = null;

    // make sure its created.. (the user might have deleted it)
    dirsMade = incDir.mkdirs();

    String convertedName = CommonUtils.convertFileName(name);

    try {

      if (sha1 != null) {
        File file = hashes.get(sha1);
        if (file != null) {
          // File already allocated for hash
          return file;
        } else {
          // Allocate unique file for hash.  By "unique" we mean not in
          // the value set of HASHES.  Because we allow risky resumes,
          // there's no need to look at BLOCKS as well...
          for (int i = 1; ; i++) {
            file = new File(incDir, tempName(convertedName, size, i));
            baseFile = file;
            file = canonicalize(file);
            canonFile = file;
            if (!hashes.values().contains(file)) break;
          }
          // ...and record the hash for later.
          hashes.put(sha1, file);
          // ...and make sure the file exists on disk, so that
          //   future File.getCanonicalFile calls will match this
          //   file.  This was a problem on OSX, where
          //   File("myfile") and File("MYFILE") aren't equal,
          //   but File("myfile").getCanonicalFile() will only return
          //   a File("MYFILE") if that already existed on disk.
          //   This means that in order for the canonical-checking
          //   within this class to work, the file must exist on disk.
          FileUtils.touch(file);

          return file;
        }
      } else {
        // No hash.
        File f = new File(incDir, tempName(convertedName, size, 0));
        baseFile = f;
        f = canonicalize(f);
        canonFile = f;
        return f;
      }

    } catch (IOException ioe) {
      IOException ioe2 =
          new IOException(
              "dirsMade: "
                  + dirsMade
                  + "\ndirExist: "
                  + incDir.exists()
                  + "\nbaseFile: "
                  + baseFile
                  + "\ncannFile: "
                  + canonFile);
      ioe2.initCause(ioe);
      throw ioe2;
    }
  }
예제 #25
0
 /**
  * A utility method to flush Flushable objects (Readers, Writers, Input- and OutputStreams and
  * RandomAccessFiles).
  */
 public static void flush(Flushable flushable) {
   FileUtils.flush(flushable);
 }
  /**
   * Override the default removal so we can actually stop sharing and delete the file. Deletes the
   * selected rows in the table. CAUTION: THIS WILL DELETE THE FILE FROM THE DISK.
   */
  public void removeSelection() {
    int[] rows = TABLE.getSelectedRows();
    if (rows.length == 0) return;

    if (TABLE.isEditing()) {
      TableCellEditor editor = TABLE.getCellEditor();
      editor.cancelCellEditing();
    }

    List<File> files = new ArrayList<File>(rows.length);

    // sort row indices and go backwards so list indices don't change when
    // removing the files from the model list
    Arrays.sort(rows);
    for (int i = rows.length - 1; i >= 0; i--) {
      File file = DATA_MODEL.getFile(rows[i]);
      files.add(file);
    }

    CheckBoxListPanel<File> listPanel =
        new CheckBoxListPanel<File>(files, new FileTextProvider(), true);
    listPanel.getList().setVisibleRowCount(4);

    // display list of files that should be deleted
    Object[] message =
        new Object[] {
          new MultiLineLabel(
              I18n.tr(
                  "Are you sure you want to delete the selected file(s), thus removing it from your computer?"),
              400),
          Box.createVerticalStrut(ButtonRow.BUTTON_SEP),
          listPanel,
          Box.createVerticalStrut(ButtonRow.BUTTON_SEP)
        };

    // get platform dependent options which are displayed as buttons in the dialog
    Object[] removeOptions = createRemoveOptions();

    int option =
        JOptionPane.showOptionDialog(
            MessageService.getParentComponent(),
            message,
            I18n.tr("Message"),
            JOptionPane.YES_NO_OPTION,
            JOptionPane.QUESTION_MESSAGE,
            null,
            removeOptions,
            removeOptions[0] /* default option */);

    if (option == removeOptions.length - 1 /* "cancel" option index */
        || option == JOptionPane.CLOSED_OPTION) {
      return;
    }

    // remove still selected files
    List<File> selected = listPanel.getSelectedElements();
    List<String> undeletedFileNames = new ArrayList<String>();

    boolean somethingWasRemoved = false;

    for (File file : selected) {
      // stop seeding if seeding
      BittorrentDownload dm = null;
      if ((dm = TorrentUtil.getDownloadManager(file)) != null) {
        dm.setDeleteDataWhenRemove(false);
        dm.setDeleteTorrentWhenRemove(false);
        BTDownloadMediator.instance().remove(dm);
      }

      // close media player if still playing
      if (MediaPlayer.instance().isThisBeingPlayed(file)) {
        MediaPlayer.instance().stop();
        MPlayerMediator.instance().showPlayerWindow(false);
      }

      // removeOptions > 2 => OS offers trash options
      boolean removed =
          FileUtils.delete(
              file, removeOptions.length > 2 && option == 0 /* "move to trash" option index */);
      if (removed) {
        somethingWasRemoved = true;
        DATA_MODEL.remove(DATA_MODEL.getRow(file));
      } else {
        undeletedFileNames.add(getCompleteFileName(file));
      }
    }

    clearSelection();

    if (somethingWasRemoved) {
      LibraryMediator.instance().getLibraryExplorer().refreshSelection(true);
    }

    if (undeletedFileNames.isEmpty()) {
      return;
    }

    // display list of files that could not be deleted
    message =
        new Object[] {
          new MultiLineLabel(
              I18n.tr(
                  "The following files could not be deleted. They may be in use by another application or are currently being downloaded to."),
              400),
          Box.createVerticalStrut(ButtonRow.BUTTON_SEP),
          new JScrollPane(createFileList(undeletedFileNames))
        };

    JOptionPane.showMessageDialog(
        MessageService.getParentComponent(), message, I18n.tr("Error"), JOptionPane.ERROR_MESSAGE);

    super.removeSelection();
  }
예제 #27
0
 /**
  * Deletes the incomplete files for this torrent file system. The torrent file system should
  * handle the possibility of this method being called multiple times.
  */
 public void deleteIncompleteFiles() {
   File parent = _incompleteFile.getParentFile();
   FileUtils.deleteRecursive(parent);
 }
예제 #28
0
  /**
   * Constructs the file system using the given BTData & hash information. If any of the information
   * is malformed, throws a ValueException.
   *
   * @param data contains all the data about a .torrent file
   * @param numHashes number of pieces the torrent was divided into
   * @param pieceLength size of divided up torrent file
   * @param infoHash a string of alphanumeric characters in the .torrent file that the client uses
   *     to verify the data that is being transferred
   * @throws ValueException
   */
  TorrentFileSystem(BTData data, int numHashes, long pieceLength, byte[] infoHash)
      throws IOException {
    // name of the torrent, also specifying the directory under which to save the torrents.
    _name = CommonUtils.convertFileName(data.getName());

    // we need to check the name of the torrent, security risk!
    if (_name.length() == 0) throw new ValueException("bad torrent name");

    _incompleteFile =
        new File(
            SharingSettings.INCOMPLETE_DIRECTORY.get(),
            Base32.encode(infoHash) + File.separator + _name);
    _completeFile = new File(SharingSettings.getSaveDirectory(_name), _name);

    if (!FileUtils.isReallyParent(SharingSettings.getSaveDirectory(_name), _completeFile)) {
      throw new SaveLocationException(LocationCode.SECURITY_VIOLATION, _completeFile);
    }

    if (data.getFiles() != null) {
      List<BTData.BTFileData> files = data.getFiles();
      List<TorrentFile> torrents = new ArrayList<TorrentFile>(files.size());
      long position = 0;
      for (BTData.BTFileData file : files) {
        String torrentPath = _name + file.getPath();
        TorrentFile f =
            new TorrentFile(
                file.getLength(),
                new File(_completeFile, file.getPath()).getAbsolutePath(),
                torrentPath);
        f.setBeginPiece((int) (position / pieceLength));
        f.setStartByte(position);
        position += f.length();
        f.setEndPiece((int) (position / pieceLength));
        f.setEndByte(position - 1);

        if (!FileUtils.isReallyInParentPath(_completeFile, f))
          throw new SaveLocationException(LocationCode.SECURITY_VIOLATION, f);
        torrents.add(f);
      }

      if (files.size() == 0) throw new ValueException("bad metainfo, no files!");

      _files = torrents;

      // add folders, for easier conflict checking later on
      for (String folderPath : data.getFolders()) _folders.add(new File(_completeFile, folderPath));
      _folders.add(_completeFile);
    } else {
      String torrentPath = data.getName();
      TorrentFile f =
          new TorrentFile(data.getLength(), _completeFile.getAbsolutePath(), torrentPath);
      f.setBeginPiece(0);
      f.setStartByte(0);
      f.setEndPiece(numHashes - 1);
      f.setEndByte(f.length());
      _files = new ArrayList<TorrentFile>(1);
      _files.add(f);
    }

    _unmodFiles = Collections.unmodifiableList(_files);
    _totalSize = calculateTotalSize(_files);
    if (_totalSize <= 0) throw new ValueException("invalid size " + _totalSize);
  }