Revamped file dialog handling.

This commit is contained in:
sk89q 2011-01-30 21:32:52 -08:00
parent 888699cae0
commit c6537a783d
6 changed files with 193 additions and 12 deletions

View File

@ -543,7 +543,18 @@ public abstract class LocalPlayer {
* @param extensions null to allow all * @param extensions null to allow all
* @return * @return
*/ */
public File openFileDialog(String[] extensions) { public File openFileOpenDialog(String[] extensions) {
printError("File dialogs are not supported in your environment.");
return null;
}
/**
* Open a file save dialog.
*
* @param extensions null to allow all
* @return
*/
public File openFileSaveDialog(String[] extensions) {
printError("File dialogs are not supported in your environment."); printError("File dialogs are not supported in your environment.");
return null; return null;
} }

View File

@ -355,15 +355,59 @@ public class WorldEdit {
* @param dir sub-directory to look in * @param dir sub-directory to look in
* @param filename filename (user-submitted) * @param filename filename (user-submitted)
* @param defaultExt append an extension if missing one, null to not use * @param defaultExt append an extension if missing one, null to not use
* @param extensions list of extensions, null for any
* @return * @return
* @throws FilenameException * @throws FilenameException
*/ */
public File getSafeFile(LocalPlayer player, File dir, String filename, public File getSafeSaveFile(LocalPlayer player, File dir, String filename,
String defaultExt) throws FilenameException { String defaultExt, String[] extensions)
throws FilenameException {
return getSafeFile(player, dir, filename, defaultExt, extensions, true);
}
/**
* Gets the path to a file. This method will check to see if the filename
* has valid characters and has an extension. It also prevents directory
* traversal exploits by checking the root directory and the file directory.
* On success, a <code>java.io.File</code> object will be returned.
*
* @param dir sub-directory to look in
* @param filename filename (user-submitted)
* @param defaultExt append an extension if missing one, null to not use
* @param extensions list of extensions, null for any
* @return
* @throws FilenameException
*/
public File getSafeOpenFile(LocalPlayer player, File dir, String filename,
String defaultExt, String[] extensions)
throws FilenameException {
return getSafeFile(player, dir, filename, defaultExt, extensions, false);
}
/**
* Get a safe path to a file.
*
* @param player
* @param dir
* @param filename
* @param defaultExt
* @param extensions
* @param isSave
* @return
* @throws FilenameException
*/
private File getSafeFile(LocalPlayer player, File dir, String filename,
String defaultExt, String[] extensions, boolean isSave)
throws FilenameException {
File f; File f;
if (filename.equals("#")) { if (filename.equals("#")) {
f = player.openFileDialog(null); if (isSave) {
f = player.openFileSaveDialog(extensions);
} else {
f = player.openFileOpenDialog(extensions);
}
if (f == null) { if (f == null) {
throw new FileSelectionAbortedException("No file selected"); throw new FileSelectionAbortedException("No file selected");
} }

View File

@ -181,7 +181,8 @@ public class ClipboardCommands {
String filename = args.getString(0); String filename = args.getString(0);
File dir = we.getWorkingDirectoryFile(config.saveDir); File dir = we.getWorkingDirectoryFile(config.saveDir);
File f = we.getSafeFile(player, dir, filename, "schematic"); File f = we.getSafeOpenFile(player, dir, filename, "schematic",
new String[] {"schematic"});
try { try {
String filePath = f.getCanonicalPath(); String filePath = f.getCanonicalPath();
@ -218,7 +219,8 @@ public class ClipboardCommands {
String filename = args.getString(0); String filename = args.getString(0);
File dir = we.getWorkingDirectoryFile(config.saveDir); File dir = we.getWorkingDirectoryFile(config.saveDir);
File f = we.getSafeFile(player, dir, filename, "schematic"); File f = we.getSafeSaveFile(player, dir, filename, "schematic",
new String[] {"schematic"});
if (!dir.exists()) { if (!dir.exists()) {
if (!dir.mkdir()) { if (!dir.mkdir()) {

View File

@ -48,7 +48,8 @@ public class ScriptingCommands {
session.setLastScript(args.getString(0)); session.setLastScript(args.getString(0));
File dir = we.getWorkingDirectoryFile(we.getConfiguration().scriptsDir); File dir = we.getWorkingDirectoryFile(we.getConfiguration().scriptsDir);
File f = we.getSafeFile(player, dir, args.getString(0), "js"); File f = we.getSafeOpenFile(player, dir, args.getString(0), "js",
new String[] {"js"});
we.runScript(player, f, scriptArgs); we.runScript(player, f, scriptArgs);
} }
@ -76,7 +77,8 @@ public class ScriptingCommands {
String[] scriptArgs = args.getSlice(0); String[] scriptArgs = args.getSlice(0);
File dir = we.getWorkingDirectoryFile(we.getConfiguration().scriptsDir); File dir = we.getWorkingDirectoryFile(we.getConfiguration().scriptsDir);
File f = we.getSafeFile(player, dir, lastScript, "js"); File f = we.getSafeOpenFile(player, dir, lastScript, "js",
new String[] {"js"});
we.runScript(player, f, scriptArgs); we.runScript(player, f, scriptArgs);

View File

@ -210,23 +210,55 @@ public class CraftScriptContext extends CraftScriptEnvironment {
* @return * @return
* @throws FilenameException * @throws FilenameException
*/ */
@Deprecated
public File getSafeFile(String folder, String filename) throws FilenameException { public File getSafeFile(String folder, String filename) throws FilenameException {
File dir = controller.getWorkingDirectoryFile(folder); File dir = controller.getWorkingDirectoryFile(folder);
return controller.getSafeFile(player, dir, filename, null); return controller.getSafeOpenFile(player, dir, filename, null, null);
} }
/** /**
* This version will append an extension if one doesn't exist. * Gets the path to a file for opening. This method will check to see if the
* filename has valid characters and has an extension. It also prevents
* directory traversal exploits by checking the root directory and the file
* directory. On success, a <code>java.io.File</code> object will be
* returned.
*
* <p>Use this method if you need to read a file from a directory.</p>
* *
* @param folder sub-directory to look in * @param folder sub-directory to look in
* @param filename filename (user-submitted) * @param filename filename (user-submitted)
* @param defaultExt default extension to append if there is none * @param defaultExt default extension to append if there is none
* @param exts list of extensions for file open dialog, null for no filter
* @return * @return
* @throws FilenameException * @throws FilenameException
*/ */
public File getSafeFile(String folder, String filename, String defaultExt) public File getSafeOpenFile(String folder, String filename,
String defaultExt, String[] exts)
throws FilenameException { throws FilenameException {
File dir = controller.getWorkingDirectoryFile(folder); File dir = controller.getWorkingDirectoryFile(folder);
return controller.getSafeFile(player, dir, filename, defaultExt); return controller.getSafeOpenFile(player, dir, filename, defaultExt, exts);
}
/**
* Gets the path to a file for saving. This method will check to see if the
* filename has valid characters and has an extension. It also prevents
* directory traversal exploits by checking the root directory and the file
* directory. On success, a <code>java.io.File</code> object will be
* returned.
*
* <p>Use this method if you need to read a file from a directory.</p>
*
* @param folder sub-directory to look in
* @param filename filename (user-submitted)
* @param defaultExt default extension to append if there is none
* @param exts list of extensions for file save dialog, null for no filter
* @return
* @throws FilenameException
*/
public File getSafeSaveFile(String folder, String filename,
String defaultExt, String[] exts)
throws FilenameException {
File dir = controller.getWorkingDirectoryFile(folder);
return controller.getSafeSaveFile(player, dir, filename, defaultExt, exts);
} }
} }

View File

@ -0,0 +1,90 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010, 2011 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.util;
import java.io.*;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileFilter;
import com.sk89q.util.StringUtil;
public class FileDialogUtil {
public static File showSaveDialog(String[] exts) {
JFileChooser dialog = new JFileChooser();
if (exts != null) {
dialog.setFileFilter(new ExtensionFilter(exts));
}
int returnVal = dialog.showSaveDialog(null);
if (returnVal == JFileChooser.APPROVE_OPTION) {
return dialog.getSelectedFile();
}
return null;
}
public static File showOpenDialog(String[] exts) {
JFileChooser dialog = new JFileChooser();
if (exts != null) {
dialog.setFileFilter(new ExtensionFilter(exts));
}
int returnVal = dialog.showOpenDialog(null);
if (returnVal == JFileChooser.APPROVE_OPTION) {
return dialog.getSelectedFile();
}
return null;
}
private static class ExtensionFilter extends FileFilter {
private Set<String> exts;
private String desc;
public ExtensionFilter(String[] exts) {
this.exts = new HashSet<String>(Arrays.asList(exts));
desc = StringUtil.joinString(exts, ",");
}
public boolean accept(File f) {
if (f.isDirectory()) {
return true;
}
String path = f.getPath();
int index = path.lastIndexOf('.');
if (index == -1 || index == path.length() - 1) {
return false;
} else {
return exts.contains(path.indexOf(index + 1));
}
}
public String getDescription() {
return desc;
}
}
}