0

I've got a widget that allows the user to drag and drop an email message or a file into the widget to copy it to their file system. It's the FileExplorer project in OpenNTF, designed by people far more experienced than I am. I want to modify it to provide a new filename if the current filename already exists in the location they're dropping it on. With emails I'd hoped to be able to grab the sender and date, but I've been throwing errors when I try to access the file contents during a drag-and-drop of email.

So, my issue is actually simple. I've got the 'if' to determine if the filename is taken, but I'm overwhelmed trying to figure out how to test multiple options for the filename (like numbering then 'file1.eml', 'file2.eml', 'file3.eml'). I tried, below, inserting the word DUPLICATE, but I'm having no joy.

try {
    if (source.isDirectory()) {
        File dirTarget = new File(fDest.getAbsoluteFile() + File.separator + source.getName());
        if (!dirTarget.exists()) {
            dirTarget.mkdir();
        }
        copyDir(monitor, source, dirTarget);
    }
    if (source.isFile()) {
        File dest = new File(fDest.getAbsolutePath() + File.separator + source.getName());

        if (dest.getAbsolutePath().compareTo(source.getAbsolutePath()) != 0) {
            copyFile(monitor, source, dest);
        } else {
            dest = new File(fDest.getAbsolutePath() + File.separator + "DUPLICATE" + File.separator + source.getName());
            copyFile(monitor, source, dest);
        }
    }
} catch (IOException e) {
}

For reference, the copyFile method's parameters are

private void copyFile(IProgressMonitor monitor, File fSource, File fTarget) throws IOException
stwissel
  • 20,110
  • 6
  • 54
  • 101
David Navarre
  • 1,022
  • 10
  • 27

1 Answers1

1

You need to construct your file name different.

  File.seperator

results in / \ or : depending on your platform since it is the char separating the directory from the file.

Since you are dropping a file, you don't need check for the directory, up to you. You need a loop to test file names. To make it easy use (DUPLICATE 1) (DUPLICATE 2) etc. Something like this:

private final static String DUPLICATE = "DUPLICATE";

private void copyOut(File source, File fDest, Monitor monitor) { 
   try {
         if (!source.exists() || !fDest.exists()) {
            // one or two files missing, can't copy
            // handle error here!
         } else {
           String destName = fDest.getAbsolutePath()+ File.separator + source.getName();
           File dest = new File(destName);

           if (source.isDirectory()) {
               if (!dest.exists()) {
                  destPath.mkdirs(); // Fix missing
               } else if (dest.isFile()) {
                 // Raise an error. Destination exists as file source is directory!!!
               }
           } else  { // We checked for existence and dir, so it is a file
             // Don't overwrite an existing file  
             dest = this.checkforDuplicate(dest); 
           }

           copyFile(monitor, source, dest);
        }
      } catch (IOException e) {
        // Error handling missing here!
      }
}

private File checkforDuplicate(File dest) {
    if (!dest.exists()) {
        return dest;
    }
    int duplicateNum = 1; 
    while (true) {
        ArrayList<String> pieces = Arrays.asList(dest.getAbsolutePath().split("."));
        pieces.add(pieces.size()-1, DUPLICATE);
        if (duplicateNum > 1) {
            pieces.add(pieces.size()-1,Integer.toString(duplicateNum));
        }
        duplicateNum++;
        StringBuilder newName = newStringBuilder();
        for (String s : pieces) {
            newName.append(s);
            newName.append(".");
        }
        // Strip the last .
        String outName = newName.substring(0, newName.length()-2);
        File result = new File(outName);
        if (!result.exists()) {
            return result;
        }

    }
}

Check the code, written off memory, will contain typos. also doesn't deal with file names that don't contain a dot.

stwissel
  • 20,110
  • 6
  • 54
  • 101