package org.limewire.ui.swing.options.actions;
import java.awt.Container;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Random;
import javax.swing.Action;
import javax.swing.JOptionPane;
import org.limewire.i18n.I18nMarker;
import org.limewire.ui.swing.action.AbstractAction;
import org.limewire.ui.swing.components.FocusJOptionPane;
import org.limewire.ui.swing.components.LabelTextField;
import org.limewire.ui.swing.util.FileChooser;
import org.limewire.ui.swing.util.I18n;
import org.limewire.util.FileUtils;
public class BrowseDirectoryAction extends AbstractAction {
private enum FolderErrors {
NOT_A_FOLDER (I18nMarker.marktr("{0} is not a folder")),
CANNOT_WRITE (I18nMarker.marktr("Cannot write to {0}")),
CANT_FIND (I18nMarker.marktr("Cannot find {0}")),
SUCCESS ("");
private String errorMessage;
FolderErrors(String errorMessage) {
this.errorMessage = errorMessage;
}
public String getErrorMessage() {
return errorMessage;
}
};
private Container parent;
private LabelTextField currentDirectoryTextField;
public BrowseDirectoryAction(Container parent, LabelTextField currentDirectoryTextField) {
this.parent = parent;
this.currentDirectoryTextField = currentDirectoryTextField;
putValue(Action.NAME, I18n.tr("Browse..."));
putValue(Action.SHORT_DESCRIPTION, I18n.tr("Choose a different Save Location"));
}
@Override
public void actionPerformed(ActionEvent e) {
String oldDirectory = currentDirectoryTextField.getText();
Window window = FocusJOptionPane.getWindowForComponent(parent);
File directory = FileChooser.getInputDirectory(window, new File(oldDirectory));
// no directory was selected
if (directory == null) {
return;
}
FolderErrors error = isSaveDirectoryValid(directory);
if (error == FolderErrors.SUCCESS) {
try {
String newDirectory = directory.getCanonicalPath();
currentDirectoryTextField.setText(newDirectory);
} catch (IOException ioe) {
FocusJOptionPane.showMessageDialog(window,
I18n.tr(error.getErrorMessage(), directory),
I18n.tr("Save Folder Error"),
JOptionPane.ERROR_MESSAGE);
}
} else {
FocusJOptionPane.showMessageDialog(window,
I18n.tr(error.getErrorMessage(), directory),
I18n.tr("Save Folder Error"),
JOptionPane.ERROR_MESSAGE);
}
}
/**
* Utility method for checking whether or not the save directory is valid.
*
* @param saveDir the save directory to check for validity
* @return <tt>true</tt> if the save directory is valid, otherwise
* <tt>false</tt>
*/
private static FolderErrors isSaveDirectoryValid(File saveDir) {
if (saveDir == null)
return FolderErrors.CANT_FIND;
if(saveDir.isFile())
return FolderErrors.NOT_A_FOLDER;
if (!saveDir.exists())
saveDir.mkdirs();
if (!saveDir.isDirectory())
return FolderErrors.NOT_A_FOLDER;
FileUtils.setWriteable(saveDir);
Random generator = new Random();
File testFile = null;
for (int i = 0; i < 10 && testFile == null; i++) {
StringBuilder name = new StringBuilder();
for (int j = 0; j < 8; j++) {
name.append((char) ('a' + generator.nextInt('z' - 'a')));
}
name.append(".tmp");
testFile = new File(saveDir, name.toString());
if (testFile.exists()) {
testFile = null; // try again!
}
}
if (testFile == null) {
return FolderErrors.CANNOT_WRITE;
}
RandomAccessFile testRAFile = null;
try {
testRAFile = new RandomAccessFile(testFile, "rw");
// Try to write something just to make extra sure we're OK.
testRAFile.write(7);
testRAFile.close();
} catch (FileNotFoundException e) {
// If we could not open the file, then we can't write to that
// directory.
return FolderErrors.CANNOT_WRITE;
} catch (IOException e) {
// The directory is invalid if there was an error writing to it.
return FolderErrors.CANNOT_WRITE;
} finally {
// Delete our test file.
testFile.delete();
try {
if (testRAFile != null)
testRAFile.close();
} catch (IOException ignored) {
}
}
if(FileUtils.canWrite(saveDir))
return FolderErrors.SUCCESS;
else
return FolderErrors.CANNOT_WRITE;
}
}