/* ******************************************************************************
* Copyright (c) 2006-2012 XMind Ltd. and others.
*
* This file is a part of XMind 3. XMind releases 3 and
* above are dual-licensed under the Eclipse Public License (EPL),
* which is available at http://www.eclipse.org/legal/epl-v10.html
* and the GNU Lesser General Public License (LGPL),
* which is available at http://www.gnu.org/licenses/lgpl.html
* See http://www.xmind.net/license.html for details.
*
* Contributors:
* XMind Ltd. - initial API and implementation
*******************************************************************************/
package org.xmind.ui.viewers;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.runtime.Platform;
import org.eclipse.swt.program.Program;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.internal.misc.StringMatcher;
public class FileUtils {
private static final String FILE_PROTOCOL = "file:"; //$NON-NLS-1$
private FileUtils() {
}
private static final long K = 1 << 10;
private static final long M = 1 << 20;
public static String fileLengthToString(long length) {
if (length < K) {
return Long.toString(length) + " B"; //$NON-NLS-1$
} else if (length >= K && length < M) {
double tmp = ((double) length) / (double) K;
return String.format("%,.2f KB", tmp); //$NON-NLS-1$
}
double tmp = ((double) length) / (double) (M);
return String.format("%,.2f MB", tmp); //$NON-NLS-1$
}
public static String[] list(File path) {
return list(path, null);
}
public static String[] list(File path, final FilenameFilter filter) {
return list(path, false, filter);
}
public static String[] list(File path, boolean extend,
final FilenameFilter filter) {
String pathName = path.getAbsolutePath();
if (path.isFile() && path.exists()) {
if (extend)
return list(
new File(path.getParentFile(), path.getName() + "*"), false, filter); //$NON-NLS-1$
if (filter == null
|| filter.accept(path.getParentFile(), path.getName()))
return new String[] { pathName };
} else if (path.isDirectory() && path.exists()) {
File[] subFiles = path.listFiles(filter);
if (subFiles != null) {
List<String> list = new ArrayList<String>();
for (File subFile : subFiles) {
list.add(subFile.getAbsolutePath());
}
return list.toArray(new String[0]);
}
} else {
int index = pathName.lastIndexOf(File.separatorChar);
if (index >= 0) {
String dirName = pathName.substring(0, index + 1);
String filePattern = pathName.substring(index + 1,
pathName.length());
if (extend && !filePattern.endsWith("*")) //$NON-NLS-1$
filePattern += "*"; //$NON-NLS-1$
File dir = new File(dirName);
if (dir.isDirectory()) {
final StringMatcher matcher = new StringMatcher(
filePattern, true, false);
return list(dir, false, new FilenameFilter() {
public boolean accept(File dir, String name) {
return matcher.match(name)
&& (filter == null || filter.accept(dir,
name));
}
});
}
}
}
return new String[0];
}
public static boolean launch(String path) {
File file = path.startsWith(FILE_PROTOCOL) ? new File(
path.substring(FILE_PROTOCOL.length())) : new File(path);
File cwd = new File(System.getProperty("user.home")); //$NON-NLS-1$
String os = Platform.getOS();
if (Platform.OS_WIN32.equals(os)) {
if (launchUsingSWT(cwd, path))
return true;
if (file.isDirectory()) {
if (launchUsingShell(cwd, "explorer.exe", quote(path))) //$NON-NLS-1$
return true;
}
if (launchUsingShell(cwd, "rundll32.exe", //$NON-NLS-1$
"SHELL32.DLL,ShellExec_RunDLL", quote(path))) //$NON-NLS-1$
return true;
} else if (Platform.OS_MACOSX.equals(os)) {
if (launchUsingSWT(cwd, path))
return true;
if (launchUsingShell(cwd, "open", path)) //$NON-NLS-1$
return true;
} else if (Platform.OS_LINUX.equals(os)) {
if (launchUsingShell(cwd, "xdg-open", path)) //$NON-NLS-1$
return true;
if (launchUsingShell(cwd, "gnome-open", path)) //$NON-NLS-1$
return true;
if (launchUsingSWT(cwd, path))
return true;
} else {
if (launchUsingSWT(cwd, path))
return true;
}
return false;
}
private static String quote(String path) {
return "\"" + path + "\""; //$NON-NLS-1$ //$NON-NLS-2$
}
private static String getFullPath(File file) {
try {
return file.getCanonicalPath();
} catch (IOException e) {
return file.getAbsolutePath();
}
}
private static boolean launchUsingSWT(File cwd, String path) {
Display display = Display.getCurrent();
if (display == null)
return false;
return Program.launch(path, cwd.getAbsolutePath());
}
private static boolean launchUsingShell(File cwd, String... args) {
try {
Process process = Runtime.getRuntime().exec(args, null, cwd);
waitForProcessToStart();
try {
int exitCode = process.exitValue();
return exitCode == 0;
} catch (IllegalThreadStateException e) {
return true;
}
} catch (Throwable e) {
return false;
}
}
private static final int PROCESS_CHECKING_DELAY = 100;
private static void waitForProcessToStart() {
Display display = Display.getCurrent();
if (display != null) {
final boolean[] ended = new boolean[1];
ended[0] = false;
display.timerExec(PROCESS_CHECKING_DELAY, new Runnable() {
public void run() {
ended[0] = true;
}
});
while (!ended[0] && !display.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
} else {
try {
Thread.sleep(PROCESS_CHECKING_DELAY);
} catch (InterruptedException e) {
}
}
}
public static boolean show(File file) {
File cwd = new File(System.getProperty("user.home")); //$NON-NLS-1$
String path = getFullPath(file);
String os = Platform.getOS();
if (Platform.OS_WIN32.equals(os)) {
if (launchUsingShell(cwd, "explorer.exe", "/select,", quote(path))) //$NON-NLS-1$ //$NON-NLS-2$
return true;
} else if (Platform.OS_MACOSX.equals(os)) {
if (launchUsingShell(cwd, "open", "-R", path)) //$NON-NLS-1$//$NON-NLS-2$
return true;
if (showUsingScriptForMacOSX(file))
return true;
if (launchUsingShell(cwd, "open", file.getParent())) //$NON-NLS-1$
return true;
} else if (Platform.OS_LINUX.equals(os)) {
if (launchUsingShell(cwd, "nautilus", path)) //$NON-NLS-1$
return true;
if (launchUsingShell(cwd, "xdg-open", file.getParent())) //$NON-NLS-1$
return true;
if (launchUsingShell(cwd, "gnome-open", file.getParent())) //$NON-NLS-1$
return true;
}
return launchUsingSWT(cwd, file.getParent());
}
private static boolean showUsingScriptForMacOSX(File file) {
try {
Process process = Runtime.getRuntime().exec(
new String[] { "/usr/bin/osascript" }); //$NON-NLS-1$
PrintStream ps = new PrintStream(process.getOutputStream());
try {
ps.println("tell application \"Finder\""); //$NON-NLS-1$
ps.println(" set fullpath to POSIX file \"" //$NON-NLS-1$
+ file.getAbsolutePath() + "\" as text"); //$NON-NLS-1$
ps.println(" reveal fullpath"); //$NON-NLS-1$
ps.println("end tell"); //$NON-NLS-1$
} finally {
ps.close();
}
int exitCode = process.waitFor();
return exitCode == 0;
} catch (IOException e) {
return false;
} catch (InterruptedException e) {
return false;
}
}
}