feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
123
jdkSrc/jdk8/sun/awt/shell/DefaultShellFolder.java
Normal file
123
jdkSrc/jdk8/sun/awt/shell/DefaultShellFolder.java
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2002, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.awt.shell;
|
||||
|
||||
import java.io.File;
|
||||
import java.security.AccessController;
|
||||
import javax.swing.Icon;
|
||||
import sun.security.action.GetPropertyAction;
|
||||
|
||||
/**
|
||||
* @author Michael Martak
|
||||
* @since 1.4
|
||||
*/
|
||||
|
||||
class DefaultShellFolder extends ShellFolder {
|
||||
|
||||
/**
|
||||
* Create a file system shell folder from a file
|
||||
*/
|
||||
DefaultShellFolder(ShellFolder parent, File f) {
|
||||
super(parent, f.getAbsolutePath());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is implemented to make sure that no instances
|
||||
* of <code>ShellFolder</code> are ever serialized. An instance of
|
||||
* this default implementation can always be represented with a
|
||||
* <code>java.io.File</code> object instead.
|
||||
*
|
||||
* @returns a <code>java.io.File</code> replacement object.
|
||||
*/
|
||||
protected Object writeReplace() throws java.io.ObjectStreamException {
|
||||
return new File(getPath());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return An array of shell folders that are children of this shell folder
|
||||
* object, null if this shell folder is empty.
|
||||
*/
|
||||
public File[] listFiles() {
|
||||
File[] files = super.listFiles();
|
||||
if (files != null) {
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
files[i] = new DefaultShellFolder(this, files[i]);
|
||||
}
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether this shell folder is a link
|
||||
*/
|
||||
public boolean isLink() {
|
||||
return false; // Not supported by default
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether this shell folder is marked as hidden
|
||||
*/
|
||||
public boolean isHidden() {
|
||||
String fileName = getName();
|
||||
if (fileName.length() > 0) {
|
||||
return (fileName.charAt(0) == '.');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The shell folder linked to by this shell folder, or null
|
||||
* if this shell folder is not a link
|
||||
*/
|
||||
public ShellFolder getLinkLocation() {
|
||||
return null; // Not supported by default
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The name used to display this shell folder
|
||||
*/
|
||||
public String getDisplayName() {
|
||||
return getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The type of shell folder as a string
|
||||
*/
|
||||
public String getFolderType() {
|
||||
if (isDirectory()) {
|
||||
return "File Folder"; // TODO : LOCALIZE THIS STRING!!!
|
||||
} else {
|
||||
return "File"; // TODO : LOCALIZE THIS STRING!!!
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The executable type as a string
|
||||
*/
|
||||
public String getExecutableType() {
|
||||
return null; // Not supported by default
|
||||
}
|
||||
}
|
||||
619
jdkSrc/jdk8/sun/awt/shell/ShellFolder.java
Normal file
619
jdkSrc/jdk8/sun/awt/shell/ShellFolder.java
Normal file
@@ -0,0 +1,619 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.awt.shell;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.Image;
|
||||
import java.awt.Toolkit;
|
||||
import java.io.*;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
/**
|
||||
* @author Michael Martak
|
||||
* @since 1.4
|
||||
*/
|
||||
|
||||
public abstract class ShellFolder extends File {
|
||||
private static final String COLUMN_NAME = "FileChooser.fileNameHeaderText";
|
||||
private static final String COLUMN_SIZE = "FileChooser.fileSizeHeaderText";
|
||||
private static final String COLUMN_DATE = "FileChooser.fileDateHeaderText";
|
||||
|
||||
protected ShellFolder parent;
|
||||
|
||||
/**
|
||||
* Create a file system shell folder from a file
|
||||
*/
|
||||
ShellFolder(ShellFolder parent, String pathname) {
|
||||
super((pathname != null) ? pathname : "ShellFolder");
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether this is a file system shell folder
|
||||
*/
|
||||
public boolean isFileSystem() {
|
||||
return (!getPath().startsWith("ShellFolder"));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method must be implemented to make sure that no instances
|
||||
* of <code>ShellFolder</code> are ever serialized. If <code>isFileSystem()</code> returns
|
||||
* <code>true</code>, then the object should be representable with an instance of
|
||||
* <code>java.io.File</code> instead. If not, then the object is most likely
|
||||
* depending on some internal (native) state and cannot be serialized.
|
||||
*
|
||||
* @returns a <code>java.io.File</code> replacement object, or <code>null</code>
|
||||
* if no suitable replacement can be found.
|
||||
*/
|
||||
protected abstract Object writeReplace() throws java.io.ObjectStreamException;
|
||||
|
||||
/**
|
||||
* Returns the path for this object's parent,
|
||||
* or <code>null</code> if this object does not name a parent
|
||||
* folder.
|
||||
*
|
||||
* @return the path as a String for this object's parent,
|
||||
* or <code>null</code> if this object does not name a parent
|
||||
* folder
|
||||
*
|
||||
* @see java.io.File#getParent()
|
||||
* @since 1.4
|
||||
*/
|
||||
public String getParent() {
|
||||
if (parent == null && isFileSystem()) {
|
||||
return super.getParent();
|
||||
}
|
||||
if (parent != null) {
|
||||
return (parent.getPath());
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a File object representing this object's parent,
|
||||
* or <code>null</code> if this object does not name a parent
|
||||
* folder.
|
||||
*
|
||||
* @return a File object representing this object's parent,
|
||||
* or <code>null</code> if this object does not name a parent
|
||||
* folder
|
||||
*
|
||||
* @see java.io.File#getParentFile()
|
||||
* @since 1.4
|
||||
*/
|
||||
public File getParentFile() {
|
||||
if (parent != null) {
|
||||
return parent;
|
||||
} else if (isFileSystem()) {
|
||||
return super.getParentFile();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public File[] listFiles() {
|
||||
return listFiles(true);
|
||||
}
|
||||
|
||||
public File[] listFiles(boolean includeHiddenFiles) {
|
||||
File[] files = super.listFiles();
|
||||
|
||||
if (!includeHiddenFiles) {
|
||||
Vector v = new Vector();
|
||||
int nameCount = (files == null) ? 0 : files.length;
|
||||
for (int i = 0; i < nameCount; i++) {
|
||||
if (!files[i].isHidden()) {
|
||||
v.addElement(files[i]);
|
||||
}
|
||||
}
|
||||
files = (File[])v.toArray(new File[v.size()]);
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return Whether this shell folder is a link
|
||||
*/
|
||||
public abstract boolean isLink();
|
||||
|
||||
/**
|
||||
* @return The shell folder linked to by this shell folder, or null
|
||||
* if this shell folder is not a link
|
||||
*/
|
||||
public abstract ShellFolder getLinkLocation() throws FileNotFoundException;
|
||||
|
||||
/**
|
||||
* @return The name used to display this shell folder
|
||||
*/
|
||||
public abstract String getDisplayName();
|
||||
|
||||
/**
|
||||
* @return The type of shell folder as a string
|
||||
*/
|
||||
public abstract String getFolderType();
|
||||
|
||||
/**
|
||||
* @return The executable type as a string
|
||||
*/
|
||||
public abstract String getExecutableType();
|
||||
|
||||
/**
|
||||
* Compares this ShellFolder with the specified ShellFolder for order.
|
||||
*
|
||||
* @see #compareTo(Object)
|
||||
*/
|
||||
public int compareTo(File file2) {
|
||||
if (file2 == null || !(file2 instanceof ShellFolder)
|
||||
|| ((file2 instanceof ShellFolder) && ((ShellFolder)file2).isFileSystem())) {
|
||||
|
||||
if (isFileSystem()) {
|
||||
return super.compareTo(file2);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (isFileSystem()) {
|
||||
return 1;
|
||||
} else {
|
||||
return getName().compareTo(file2.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param getLargeIcon whether to return large icon (ignored in base implementation)
|
||||
* @return The icon used to display this shell folder
|
||||
*/
|
||||
public Image getIcon(boolean getLargeIcon) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// Static
|
||||
|
||||
private static final ShellFolderManager shellFolderManager;
|
||||
|
||||
private static final Invoker invoker;
|
||||
|
||||
static {
|
||||
String managerClassName = (String)Toolkit.getDefaultToolkit().
|
||||
getDesktopProperty("Shell.shellFolderManager");
|
||||
Class managerClass = null;
|
||||
try {
|
||||
managerClass = Class.forName(managerClassName, false, null);
|
||||
if (!ShellFolderManager.class.isAssignableFrom(managerClass)) {
|
||||
managerClass = null;
|
||||
}
|
||||
// swallow the exceptions below and use default shell folder
|
||||
} catch(ClassNotFoundException e) {
|
||||
} catch(NullPointerException e) {
|
||||
} catch(SecurityException e) {
|
||||
}
|
||||
|
||||
if (managerClass == null) {
|
||||
managerClass = ShellFolderManager.class;
|
||||
}
|
||||
try {
|
||||
shellFolderManager =
|
||||
(ShellFolderManager)managerClass.newInstance();
|
||||
} catch (InstantiationException e) {
|
||||
throw new Error("Could not instantiate Shell Folder Manager: "
|
||||
+ managerClass.getName());
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new Error ("Could not access Shell Folder Manager: "
|
||||
+ managerClass.getName());
|
||||
}
|
||||
|
||||
invoker = shellFolderManager.createInvoker();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a shell folder from a file object
|
||||
* @exception FileNotFoundException if file does not exist
|
||||
*/
|
||||
public static ShellFolder getShellFolder(File file) throws FileNotFoundException {
|
||||
if (file instanceof ShellFolder) {
|
||||
return (ShellFolder)file;
|
||||
}
|
||||
if (!file.exists()) {
|
||||
throw new FileNotFoundException();
|
||||
}
|
||||
return shellFolderManager.createShellFolder(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key a <code>String</code>
|
||||
* @return An Object matching the string <code>key</code>.
|
||||
* @see ShellFolderManager#get(String)
|
||||
*/
|
||||
public static Object get(String key) {
|
||||
return shellFolderManager.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Does <code>dir</code> represent a "computer" such as a node on the network, or
|
||||
* "My Computer" on the desktop.
|
||||
*/
|
||||
public static boolean isComputerNode(File dir) {
|
||||
return shellFolderManager.isComputerNode(dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether this is a file system root directory
|
||||
*/
|
||||
public static boolean isFileSystemRoot(File dir) {
|
||||
return shellFolderManager.isFileSystemRoot(dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Canonicalizes files that don't have symbolic links in their path.
|
||||
* Normalizes files that do, preserving symbolic links from being resolved.
|
||||
*/
|
||||
public static File getNormalizedFile(File f) throws IOException {
|
||||
File canonical = f.getCanonicalFile();
|
||||
if (f.equals(canonical)) {
|
||||
// path of f doesn't contain symbolic links
|
||||
return canonical;
|
||||
}
|
||||
|
||||
// preserve symbolic links from being resolved
|
||||
return new File(f.toURI().normalize());
|
||||
}
|
||||
|
||||
// Override File methods
|
||||
|
||||
public static void sort(final List<? extends File> files) {
|
||||
if (files == null || files.size() <= 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// To avoid loads of synchronizations with Invoker and improve performance we
|
||||
// synchronize the whole code of the sort method once
|
||||
invoke(new Callable<Void>() {
|
||||
public Void call() {
|
||||
// Check that we can use the ShellFolder.sortChildren() method:
|
||||
// 1. All files have the same non-null parent
|
||||
// 2. All files is ShellFolders
|
||||
File commonParent = null;
|
||||
|
||||
for (File file : files) {
|
||||
File parent = file.getParentFile();
|
||||
|
||||
if (parent == null || !(file instanceof ShellFolder)) {
|
||||
commonParent = null;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (commonParent == null) {
|
||||
commonParent = parent;
|
||||
} else {
|
||||
if (commonParent != parent && !commonParent.equals(parent)) {
|
||||
commonParent = null;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (commonParent instanceof ShellFolder) {
|
||||
((ShellFolder) commonParent).sortChildren(files);
|
||||
} else {
|
||||
Collections.sort(files, FILE_COMPARATOR);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void sortChildren(final List<? extends File> files) {
|
||||
// To avoid loads of synchronizations with Invoker and improve performance we
|
||||
// synchronize the whole code of the sort method once
|
||||
invoke(new Callable<Void>() {
|
||||
public Void call() {
|
||||
Collections.sort(files, FILE_COMPARATOR);
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public boolean isAbsolute() {
|
||||
return (!isFileSystem() || super.isAbsolute());
|
||||
}
|
||||
|
||||
public File getAbsoluteFile() {
|
||||
return (isFileSystem() ? super.getAbsoluteFile() : this);
|
||||
}
|
||||
|
||||
public boolean canRead() {
|
||||
return (isFileSystem() ? super.canRead() : true); // ((Fix?))
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if folder allows creation of children.
|
||||
* True for the "Desktop" folder, but false for the "My Computer"
|
||||
* folder.
|
||||
*/
|
||||
public boolean canWrite() {
|
||||
return (isFileSystem() ? super.canWrite() : false); // ((Fix?))
|
||||
}
|
||||
|
||||
public boolean exists() {
|
||||
// Assume top-level drives exist, because state is uncertain for
|
||||
// removable drives.
|
||||
return (!isFileSystem() || isFileSystemRoot(this) || super.exists()) ;
|
||||
}
|
||||
|
||||
public boolean isDirectory() {
|
||||
return (isFileSystem() ? super.isDirectory() : true); // ((Fix?))
|
||||
}
|
||||
|
||||
public boolean isFile() {
|
||||
return (isFileSystem() ? super.isFile() : !isDirectory()); // ((Fix?))
|
||||
}
|
||||
|
||||
public long lastModified() {
|
||||
return (isFileSystem() ? super.lastModified() : 0L); // ((Fix?))
|
||||
}
|
||||
|
||||
public long length() {
|
||||
return (isFileSystem() ? super.length() : 0L); // ((Fix?))
|
||||
}
|
||||
|
||||
public boolean createNewFile() throws IOException {
|
||||
return (isFileSystem() ? super.createNewFile() : false);
|
||||
}
|
||||
|
||||
public boolean delete() {
|
||||
return (isFileSystem() ? super.delete() : false); // ((Fix?))
|
||||
}
|
||||
|
||||
public void deleteOnExit() {
|
||||
if (isFileSystem()) {
|
||||
super.deleteOnExit();
|
||||
} else {
|
||||
// Do nothing // ((Fix?))
|
||||
}
|
||||
}
|
||||
|
||||
public boolean mkdir() {
|
||||
return (isFileSystem() ? super.mkdir() : false);
|
||||
}
|
||||
|
||||
public boolean mkdirs() {
|
||||
return (isFileSystem() ? super.mkdirs() : false);
|
||||
}
|
||||
|
||||
public boolean renameTo(File dest) {
|
||||
return (isFileSystem() ? super.renameTo(dest) : false); // ((Fix?))
|
||||
}
|
||||
|
||||
public boolean setLastModified(long time) {
|
||||
return (isFileSystem() ? super.setLastModified(time) : false); // ((Fix?))
|
||||
}
|
||||
|
||||
public boolean setReadOnly() {
|
||||
return (isFileSystem() ? super.setReadOnly() : false); // ((Fix?))
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return (isFileSystem() ? super.toString() : getDisplayName());
|
||||
}
|
||||
|
||||
public static ShellFolderColumnInfo[] getFolderColumns(File dir) {
|
||||
ShellFolderColumnInfo[] columns = null;
|
||||
|
||||
if (dir instanceof ShellFolder) {
|
||||
columns = ((ShellFolder) dir).getFolderColumns();
|
||||
}
|
||||
|
||||
if (columns == null) {
|
||||
columns = new ShellFolderColumnInfo[]{
|
||||
new ShellFolderColumnInfo(COLUMN_NAME, 150,
|
||||
SwingConstants.LEADING, true, null,
|
||||
FILE_COMPARATOR),
|
||||
new ShellFolderColumnInfo(COLUMN_SIZE, 75,
|
||||
SwingConstants.RIGHT, true, null,
|
||||
DEFAULT_COMPARATOR, true),
|
||||
new ShellFolderColumnInfo(COLUMN_DATE, 130,
|
||||
SwingConstants.LEADING, true, null,
|
||||
DEFAULT_COMPARATOR, true)
|
||||
};
|
||||
}
|
||||
|
||||
return columns;
|
||||
}
|
||||
|
||||
public ShellFolderColumnInfo[] getFolderColumns() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Object getFolderColumnValue(File file, int column) {
|
||||
if (file instanceof ShellFolder) {
|
||||
Object value = ((ShellFolder)file).getFolderColumnValue(column);
|
||||
if (value != null) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
if (file == null || !file.exists()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
switch (column) {
|
||||
case 0:
|
||||
// By default, file name will be rendered using getSystemDisplayName()
|
||||
return file;
|
||||
|
||||
case 1: // size
|
||||
return file.isDirectory() ? null : Long.valueOf(file.length());
|
||||
|
||||
case 2: // date
|
||||
if (isFileSystemRoot(file)) {
|
||||
return null;
|
||||
}
|
||||
long time = file.lastModified();
|
||||
return (time == 0L) ? null : new Date(time);
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Object getFolderColumnValue(int column) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes the {@code task} which doesn't throw checked exceptions
|
||||
* from its {@code call} method. If invokation is interrupted then Thread.currentThread().isInterrupted() will
|
||||
* be set and result will be {@code null}
|
||||
*/
|
||||
public static <T> T invoke(Callable<T> task) {
|
||||
try {
|
||||
return invoke(task, RuntimeException.class);
|
||||
} catch (InterruptedException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes the {@code task} which throws checked exceptions from its {@code call} method.
|
||||
* If invokation is interrupted then Thread.currentThread().isInterrupted() will
|
||||
* be set and InterruptedException will be thrown as well.
|
||||
*/
|
||||
public static <T, E extends Throwable> T invoke(Callable<T> task, Class<E> exceptionClass)
|
||||
throws InterruptedException, E {
|
||||
try {
|
||||
return invoker.invoke(task);
|
||||
} catch (Exception e) {
|
||||
if (e instanceof RuntimeException) {
|
||||
// Rethrow unchecked exceptions
|
||||
throw (RuntimeException) e;
|
||||
}
|
||||
|
||||
if (e instanceof InterruptedException) {
|
||||
// Set isInterrupted flag for current thread
|
||||
Thread.currentThread().interrupt();
|
||||
|
||||
// Rethrow InterruptedException
|
||||
throw (InterruptedException) e;
|
||||
}
|
||||
|
||||
if (exceptionClass.isInstance(e)) {
|
||||
throw exceptionClass.cast(e);
|
||||
}
|
||||
|
||||
throw new RuntimeException("Unexpected error", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface allowing to invoke tasks in different environments on different platforms.
|
||||
*/
|
||||
public static interface Invoker {
|
||||
/**
|
||||
* Invokes a callable task.
|
||||
*
|
||||
* @param task a task to invoke
|
||||
* @throws Exception {@code InterruptedException} or an exception that was thrown from the {@code task}
|
||||
* @return the result of {@code task}'s invokation
|
||||
*/
|
||||
<T> T invoke(Callable<T> task) throws Exception;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a default comparator for the default column set
|
||||
*/
|
||||
private static final Comparator DEFAULT_COMPARATOR = new Comparator() {
|
||||
public int compare(Object o1, Object o2) {
|
||||
int gt;
|
||||
|
||||
if (o1 == null && o2 == null) {
|
||||
gt = 0;
|
||||
} else if (o1 != null && o2 == null) {
|
||||
gt = 1;
|
||||
} else if (o1 == null && o2 != null) {
|
||||
gt = -1;
|
||||
} else if (o1 instanceof Comparable) {
|
||||
gt = ((Comparable) o1).compareTo(o2);
|
||||
} else {
|
||||
gt = 0;
|
||||
}
|
||||
|
||||
return gt;
|
||||
}
|
||||
};
|
||||
|
||||
private static final Comparator<File> FILE_COMPARATOR = new Comparator<File>() {
|
||||
public int compare(File f1, File f2) {
|
||||
ShellFolder sf1 = null;
|
||||
ShellFolder sf2 = null;
|
||||
|
||||
if (f1 instanceof ShellFolder) {
|
||||
sf1 = (ShellFolder) f1;
|
||||
if (sf1.isFileSystem()) {
|
||||
sf1 = null;
|
||||
}
|
||||
}
|
||||
if (f2 instanceof ShellFolder) {
|
||||
sf2 = (ShellFolder) f2;
|
||||
if (sf2.isFileSystem()) {
|
||||
sf2 = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (sf1 != null && sf2 != null) {
|
||||
return sf1.compareTo(sf2);
|
||||
} else if (sf1 != null) {
|
||||
// Non-file shellfolders sort before files
|
||||
return -1;
|
||||
} else if (sf2 != null) {
|
||||
return 1;
|
||||
} else {
|
||||
String name1 = f1.getName();
|
||||
String name2 = f2.getName();
|
||||
|
||||
// First ignore case when comparing
|
||||
int diff = name1.compareToIgnoreCase(name2);
|
||||
if (diff != 0) {
|
||||
return diff;
|
||||
} else {
|
||||
// May differ in case (e.g. "mail" vs. "Mail")
|
||||
// We need this test for consistent sorting
|
||||
return name1.compareTo(name2);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
133
jdkSrc/jdk8/sun/awt/shell/ShellFolderColumnInfo.java
Normal file
133
jdkSrc/jdk8/sun/awt/shell/ShellFolderColumnInfo.java
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.awt.shell;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.Comparator;
|
||||
|
||||
public class ShellFolderColumnInfo {
|
||||
private String title;
|
||||
private Integer width;
|
||||
private boolean visible;
|
||||
/**
|
||||
* Allowed values are {@link SwingConstants#LEFT}, {@link SwingConstants#RIGHT}, {@link SwingConstants#LEADING},
|
||||
* {@link SwingConstants#TRAILING}, {@link SwingConstants#CENTER}
|
||||
*/
|
||||
private Integer alignment;
|
||||
private SortOrder sortOrder;
|
||||
private Comparator comparator;
|
||||
/**
|
||||
* <code>false</code> (default) if the {@link comparator} expects folders as arguments,
|
||||
* and <code>true</code> if folder's column values. The first option is used default for comparison
|
||||
* on Windows and also for separating files from directories when sorting using
|
||||
* ShellFolderManager's inner comparator.
|
||||
*/
|
||||
private boolean compareByColumn;
|
||||
|
||||
public ShellFolderColumnInfo(String title, Integer width,
|
||||
Integer alignment, boolean visible,
|
||||
SortOrder sortOrder, Comparator comparator,
|
||||
boolean compareByColumn) {
|
||||
this.title = title;
|
||||
this.width = width;
|
||||
this.alignment = alignment;
|
||||
this.visible = visible;
|
||||
this.sortOrder = sortOrder;
|
||||
this.comparator = comparator;
|
||||
this.compareByColumn = compareByColumn;
|
||||
}
|
||||
|
||||
public ShellFolderColumnInfo(String title, Integer width,
|
||||
Integer alignment, boolean visible,
|
||||
SortOrder sortOrder, Comparator comparator) {
|
||||
this(title, width, alignment, visible, sortOrder, comparator, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* This constructor is used by native code when getting column set for
|
||||
* a folder under Windows
|
||||
*/
|
||||
public ShellFolderColumnInfo(String title, int width, int alignment,
|
||||
boolean visible) {
|
||||
this(title, width, alignment, visible, null, null);
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public Integer getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public void setWidth(Integer width) {
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
public Integer getAlignment() {
|
||||
return alignment;
|
||||
}
|
||||
|
||||
public void setAlignment(Integer alignment) {
|
||||
this.alignment = alignment;
|
||||
}
|
||||
|
||||
public boolean isVisible() {
|
||||
return visible;
|
||||
}
|
||||
|
||||
public void setVisible(boolean visible) {
|
||||
this.visible = visible;
|
||||
}
|
||||
|
||||
public SortOrder getSortOrder() {
|
||||
return sortOrder;
|
||||
}
|
||||
|
||||
public void setSortOrder(SortOrder sortOrder) {
|
||||
this.sortOrder = sortOrder;
|
||||
}
|
||||
|
||||
public Comparator getComparator() {
|
||||
return comparator;
|
||||
}
|
||||
|
||||
public void setComparator(Comparator comparator) {
|
||||
this.comparator = comparator;
|
||||
}
|
||||
|
||||
public boolean isCompareByColumn() {
|
||||
return compareByColumn;
|
||||
}
|
||||
|
||||
public void setCompareByColumn(boolean compareByColumn) {
|
||||
this.compareByColumn = compareByColumn;
|
||||
}
|
||||
}
|
||||
116
jdkSrc/jdk8/sun/awt/shell/ShellFolderManager.java
Normal file
116
jdkSrc/jdk8/sun/awt/shell/ShellFolderManager.java
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.awt.shell;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
/**
|
||||
* @author Michael Martak
|
||||
* @since 1.4
|
||||
*/
|
||||
|
||||
class ShellFolderManager {
|
||||
/**
|
||||
* Create a shell folder from a file.
|
||||
* Override to return machine-dependent behavior.
|
||||
*/
|
||||
public ShellFolder createShellFolder(File file) throws FileNotFoundException {
|
||||
return new DefaultShellFolder(null, file);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key a <code>String</code>
|
||||
* "fileChooserDefaultFolder":
|
||||
* Returns a <code>File</code> - the default shellfolder for a new filechooser
|
||||
* "roots":
|
||||
* Returns a <code>File[]</code> - containing the root(s) of the displayable hierarchy
|
||||
* "fileChooserComboBoxFolders":
|
||||
* Returns a <code>File[]</code> - an array of shellfolders representing the list to
|
||||
* show by default in the file chooser's combobox
|
||||
* "fileChooserShortcutPanelFolders":
|
||||
* Returns a <code>File[]</code> - an array of shellfolders representing well-known
|
||||
* folders, such as Desktop, Documents, History, Network, Home, etc.
|
||||
* This is used in the shortcut panel of the filechooser on Windows 2000
|
||||
* and Windows Me.
|
||||
* "fileChooserIcon <icon>":
|
||||
* Returns an <code>Image</code> - icon can be ListView, DetailsView, UpFolder, NewFolder or
|
||||
* ViewMenu (Windows only).
|
||||
*
|
||||
* @return An Object matching the key string.
|
||||
*/
|
||||
public Object get(String key) {
|
||||
if (key.equals("fileChooserDefaultFolder")) {
|
||||
// Return the default shellfolder for a new filechooser
|
||||
File homeDir = new File(System.getProperty("user.home"));
|
||||
try {
|
||||
return createShellFolder(homeDir);
|
||||
} catch (FileNotFoundException e) {
|
||||
return homeDir;
|
||||
}
|
||||
} else if (key.equals("roots")) {
|
||||
// The root(s) of the displayable hierarchy
|
||||
return File.listRoots();
|
||||
} else if (key.equals("fileChooserComboBoxFolders")) {
|
||||
// Return an array of ShellFolders representing the list to
|
||||
// show by default in the file chooser's combobox
|
||||
return get("roots");
|
||||
} else if (key.equals("fileChooserShortcutPanelFolders")) {
|
||||
// Return an array of ShellFolders representing well-known
|
||||
// folders, such as Desktop, Documents, History, Network, Home, etc.
|
||||
// This is used in the shortcut panel of the filechooser on Windows 2000
|
||||
// and Windows Me
|
||||
return new File[] { (File)get("fileChooserDefaultFolder") };
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does <code>dir</code> represent a "computer" such as a node on the network, or
|
||||
* "My Computer" on the desktop.
|
||||
*/
|
||||
public boolean isComputerNode(File dir) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isFileSystemRoot(File dir) {
|
||||
if (dir instanceof ShellFolder && !((ShellFolder) dir).isFileSystem()) {
|
||||
return false;
|
||||
}
|
||||
return (dir.getParentFile() == null);
|
||||
}
|
||||
|
||||
protected ShellFolder.Invoker createInvoker() {
|
||||
return new DirectInvoker();
|
||||
}
|
||||
|
||||
private static class DirectInvoker implements ShellFolder.Invoker {
|
||||
public <T> T invoke(Callable<T> task) throws Exception {
|
||||
return task.call();
|
||||
}
|
||||
}
|
||||
}
|
||||
1184
jdkSrc/jdk8/sun/awt/shell/Win32ShellFolder2.java
Normal file
1184
jdkSrc/jdk8/sun/awt/shell/Win32ShellFolder2.java
Normal file
File diff suppressed because it is too large
Load Diff
652
jdkSrc/jdk8/sun/awt/shell/Win32ShellFolderManager2.java
Normal file
652
jdkSrc/jdk8/sun/awt/shell/Win32ShellFolderManager2.java
Normal file
@@ -0,0 +1,652 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code 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
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.awt.shell;
|
||||
|
||||
import java.awt.Image;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import sun.awt.OSInfo;
|
||||
import sun.misc.ThreadGroupUtils;
|
||||
import sun.util.logging.PlatformLogger;
|
||||
|
||||
import static sun.awt.shell.Win32ShellFolder2.DESKTOP;
|
||||
import static sun.awt.shell.Win32ShellFolder2.DRIVES;
|
||||
import static sun.awt.shell.ShellFolder.Invoker;
|
||||
import static sun.awt.shell.Win32ShellFolder2.NETWORK;
|
||||
import static sun.awt.shell.Win32ShellFolder2.PERSONAL;
|
||||
import static sun.awt.shell.Win32ShellFolder2.RECENT;
|
||||
|
||||
// NOTE: This class supersedes Win32ShellFolderManager, which was removed
|
||||
// from distribution after version 1.4.2.
|
||||
|
||||
/**
|
||||
* @author Michael Martak
|
||||
* @author Leif Samuelsson
|
||||
* @author Kenneth Russell
|
||||
* @since 1.4
|
||||
*/
|
||||
|
||||
public class Win32ShellFolderManager2 extends ShellFolderManager {
|
||||
|
||||
private static final PlatformLogger
|
||||
log = PlatformLogger.getLogger("sun.awt.shell.Win32ShellFolderManager2");
|
||||
|
||||
static {
|
||||
// Load library here
|
||||
sun.awt.windows.WToolkit.loadLibraries();
|
||||
}
|
||||
|
||||
public ShellFolder createShellFolder(File file) throws FileNotFoundException {
|
||||
try {
|
||||
return createShellFolder(getDesktop(), file);
|
||||
} catch (InterruptedException e) {
|
||||
throw new FileNotFoundException("Execution was interrupted");
|
||||
}
|
||||
}
|
||||
|
||||
static Win32ShellFolder2 createShellFolder(Win32ShellFolder2 parent, File file)
|
||||
throws FileNotFoundException, InterruptedException {
|
||||
long pIDL;
|
||||
try {
|
||||
pIDL = parent.parseDisplayName(file.getCanonicalPath());
|
||||
} catch (IOException ex) {
|
||||
pIDL = 0;
|
||||
}
|
||||
if (pIDL == 0) {
|
||||
// Shouldn't happen but watch for it anyway
|
||||
throw new FileNotFoundException("File " + file.getAbsolutePath() + " not found");
|
||||
}
|
||||
|
||||
try {
|
||||
return createShellFolderFromRelativePIDL(parent, pIDL);
|
||||
} finally {
|
||||
Win32ShellFolder2.releasePIDL(pIDL);
|
||||
}
|
||||
}
|
||||
|
||||
static Win32ShellFolder2 createShellFolderFromRelativePIDL(Win32ShellFolder2 parent, long pIDL)
|
||||
throws InterruptedException {
|
||||
// Walk down this relative pIDL, creating new nodes for each of the entries
|
||||
while (pIDL != 0) {
|
||||
long curPIDL = Win32ShellFolder2.copyFirstPIDLEntry(pIDL);
|
||||
if (curPIDL != 0) {
|
||||
parent = new Win32ShellFolder2(parent, curPIDL);
|
||||
pIDL = Win32ShellFolder2.getNextPIDLEntry(pIDL);
|
||||
} else {
|
||||
// The list is empty if the parent is Desktop and pIDL is a shortcut to Desktop
|
||||
break;
|
||||
}
|
||||
}
|
||||
return parent;
|
||||
}
|
||||
|
||||
private static final int VIEW_LIST = 2;
|
||||
private static final int VIEW_DETAILS = 3;
|
||||
private static final int VIEW_PARENTFOLDER = 8;
|
||||
private static final int VIEW_NEWFOLDER = 11;
|
||||
|
||||
private static final Image[] STANDARD_VIEW_BUTTONS = new Image[12];
|
||||
|
||||
private static Image getStandardViewButton(int iconIndex) {
|
||||
Image result = STANDARD_VIEW_BUTTONS[iconIndex];
|
||||
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
|
||||
BufferedImage img = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);
|
||||
|
||||
img.setRGB(0, 0, 16, 16, Win32ShellFolder2.getStandardViewButton0(iconIndex), 0, 16);
|
||||
|
||||
STANDARD_VIEW_BUTTONS[iconIndex] = img;
|
||||
|
||||
return img;
|
||||
}
|
||||
|
||||
// Special folders
|
||||
private static Win32ShellFolder2 desktop;
|
||||
private static Win32ShellFolder2 drives;
|
||||
private static Win32ShellFolder2 recent;
|
||||
private static Win32ShellFolder2 network;
|
||||
private static Win32ShellFolder2 personal;
|
||||
|
||||
static Win32ShellFolder2 getDesktop() {
|
||||
if (desktop == null) {
|
||||
try {
|
||||
desktop = new Win32ShellFolder2(DESKTOP);
|
||||
} catch (final SecurityException ignored) {
|
||||
// Ignore, the message may have sensitive information, not
|
||||
// accessible other ways
|
||||
} catch (IOException | InterruptedException e) {
|
||||
if (log.isLoggable(PlatformLogger.Level.WARNING)) {
|
||||
log.warning("Cannot access 'Desktop'", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return desktop;
|
||||
}
|
||||
|
||||
static Win32ShellFolder2 getDrives() {
|
||||
if (drives == null) {
|
||||
try {
|
||||
drives = new Win32ShellFolder2(DRIVES);
|
||||
} catch (final SecurityException ignored) {
|
||||
// Ignore, the message may have sensitive information, not
|
||||
// accessible other ways
|
||||
} catch (IOException | InterruptedException e) {
|
||||
if (log.isLoggable(PlatformLogger.Level.WARNING)) {
|
||||
log.warning("Cannot access 'Drives'", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return drives;
|
||||
}
|
||||
|
||||
static Win32ShellFolder2 getRecent() {
|
||||
if (recent == null) {
|
||||
try {
|
||||
String path = Win32ShellFolder2.getFileSystemPath(RECENT);
|
||||
if (path != null) {
|
||||
recent = createShellFolder(getDesktop(), new File(path));
|
||||
}
|
||||
} catch (final SecurityException ignored) {
|
||||
// Ignore, the message may have sensitive information, not
|
||||
// accessible other ways
|
||||
} catch (InterruptedException | IOException e) {
|
||||
if (log.isLoggable(PlatformLogger.Level.WARNING)) {
|
||||
log.warning("Cannot access 'Recent'", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return recent;
|
||||
}
|
||||
|
||||
static Win32ShellFolder2 getNetwork() {
|
||||
if (network == null) {
|
||||
try {
|
||||
network = new Win32ShellFolder2(NETWORK);
|
||||
} catch (final SecurityException ignored) {
|
||||
// Ignore, the message may have sensitive information, not
|
||||
// accessible other ways
|
||||
} catch (IOException | InterruptedException e) {
|
||||
if (log.isLoggable(PlatformLogger.Level.WARNING)) {
|
||||
log.warning("Cannot access 'Network'", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return network;
|
||||
}
|
||||
|
||||
static Win32ShellFolder2 getPersonal() {
|
||||
if (personal == null) {
|
||||
try {
|
||||
String path = Win32ShellFolder2.getFileSystemPath(PERSONAL);
|
||||
if (path != null) {
|
||||
Win32ShellFolder2 desktop = getDesktop();
|
||||
personal = desktop.getChildByPath(path);
|
||||
if (personal == null) {
|
||||
personal = createShellFolder(getDesktop(), new File(path));
|
||||
}
|
||||
if (personal != null) {
|
||||
personal.setIsPersonal();
|
||||
}
|
||||
}
|
||||
} catch (final SecurityException ignored) {
|
||||
// Ignore, the message may have sensitive information, not
|
||||
// accessible other ways
|
||||
} catch (InterruptedException | IOException e) {
|
||||
if (log.isLoggable(PlatformLogger.Level.WARNING)) {
|
||||
log.warning("Cannot access 'Personal'", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return personal;
|
||||
}
|
||||
|
||||
|
||||
private static File[] roots;
|
||||
|
||||
/**
|
||||
* @param key a <code>String</code>
|
||||
* "fileChooserDefaultFolder":
|
||||
* Returns a <code>File</code> - the default shellfolder for a new filechooser
|
||||
* "roots":
|
||||
* Returns a <code>File[]</code> - containing the root(s) of the displayable hierarchy
|
||||
* "fileChooserComboBoxFolders":
|
||||
* Returns a <code>File[]</code> - an array of shellfolders representing the list to
|
||||
* show by default in the file chooser's combobox
|
||||
* "fileChooserShortcutPanelFolders":
|
||||
* Returns a <code>File[]</code> - an array of shellfolders representing well-known
|
||||
* folders, such as Desktop, Documents, History, Network, Home, etc.
|
||||
* This is used in the shortcut panel of the filechooser on Windows 2000
|
||||
* and Windows Me.
|
||||
* "fileChooserIcon <icon>":
|
||||
* Returns an <code>Image</code> - icon can be ListView, DetailsView, UpFolder, NewFolder or
|
||||
* ViewMenu (Windows only).
|
||||
* "optionPaneIcon iconName":
|
||||
* Returns an <code>Image</code> - icon from the system icon list
|
||||
*
|
||||
* @return An Object matching the key string.
|
||||
*/
|
||||
public Object get(String key) {
|
||||
if (key.equals("fileChooserDefaultFolder")) {
|
||||
File file = getPersonal();
|
||||
if (file == null) {
|
||||
file = getDesktop();
|
||||
}
|
||||
return checkFile(file);
|
||||
} else if (key.equals("roots")) {
|
||||
// Should be "History" and "Desktop" ?
|
||||
if (roots == null) {
|
||||
File desktop = getDesktop();
|
||||
if (desktop != null) {
|
||||
roots = new File[] { desktop };
|
||||
} else {
|
||||
roots = (File[])super.get(key);
|
||||
}
|
||||
}
|
||||
return checkFiles(roots);
|
||||
} else if (key.equals("fileChooserComboBoxFolders")) {
|
||||
Win32ShellFolder2 desktop = getDesktop();
|
||||
|
||||
if (desktop != null && checkFile(desktop) != null) {
|
||||
ArrayList<File> folders = new ArrayList<File>();
|
||||
Win32ShellFolder2 drives = getDrives();
|
||||
|
||||
Win32ShellFolder2 recentFolder = getRecent();
|
||||
if (recentFolder != null && OSInfo.getWindowsVersion().compareTo(OSInfo.WINDOWS_2000) >= 0) {
|
||||
folders.add(recentFolder);
|
||||
}
|
||||
|
||||
folders.add(desktop);
|
||||
// Add all second level folders
|
||||
File[] secondLevelFolders = checkFiles(desktop.listFiles());
|
||||
Arrays.sort(secondLevelFolders);
|
||||
for (File secondLevelFolder : secondLevelFolders) {
|
||||
Win32ShellFolder2 folder = (Win32ShellFolder2) secondLevelFolder;
|
||||
if (!folder.isFileSystem() || (folder.isDirectory() && !folder.isLink())) {
|
||||
folders.add(folder);
|
||||
// Add third level for "My Computer"
|
||||
if (folder.equals(drives)) {
|
||||
File[] thirdLevelFolders = checkFiles(folder.listFiles());
|
||||
if (thirdLevelFolders != null && thirdLevelFolders.length > 0) {
|
||||
List<File> thirdLevelFoldersList = Arrays.asList(thirdLevelFolders);
|
||||
|
||||
folder.sortChildren(thirdLevelFoldersList);
|
||||
folders.addAll(thirdLevelFoldersList);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return checkFiles(folders);
|
||||
} else {
|
||||
return super.get(key);
|
||||
}
|
||||
} else if (key.equals("fileChooserShortcutPanelFolders")) {
|
||||
Toolkit toolkit = Toolkit.getDefaultToolkit();
|
||||
ArrayList<File> folders = new ArrayList<File>();
|
||||
int i = 0;
|
||||
Object value;
|
||||
do {
|
||||
value = toolkit.getDesktopProperty("win.comdlg.placesBarPlace" + i++);
|
||||
try {
|
||||
if (value instanceof Integer) {
|
||||
// A CSIDL
|
||||
folders.add(new Win32ShellFolder2((Integer)value));
|
||||
} else if (value instanceof String) {
|
||||
// A path
|
||||
folders.add(createShellFolder(new File((String)value)));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
if (log.isLoggable(PlatformLogger.Level.WARNING)) {
|
||||
log.warning("Cannot read value = " + value, e);
|
||||
}
|
||||
// Skip this value
|
||||
} catch (InterruptedException e) {
|
||||
if (log.isLoggable(PlatformLogger.Level.WARNING)) {
|
||||
log.warning("Cannot read value = " + value, e);
|
||||
}
|
||||
// Return empty result
|
||||
return new File[0];
|
||||
}
|
||||
} while (value != null);
|
||||
|
||||
if (folders.size() == 0) {
|
||||
// Use default list of places
|
||||
for (File f : new File[] {
|
||||
getRecent(), getDesktop(), getPersonal(), getDrives(), getNetwork()
|
||||
}) {
|
||||
if (f != null) {
|
||||
folders.add(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
return checkFiles(folders);
|
||||
} else if (key.startsWith("fileChooserIcon ")) {
|
||||
String name = key.substring(key.indexOf(" ") + 1);
|
||||
|
||||
int iconIndex;
|
||||
|
||||
if (name.equals("ListView") || name.equals("ViewMenu")) {
|
||||
iconIndex = VIEW_LIST;
|
||||
} else if (name.equals("DetailsView")) {
|
||||
iconIndex = VIEW_DETAILS;
|
||||
} else if (name.equals("UpFolder")) {
|
||||
iconIndex = VIEW_PARENTFOLDER;
|
||||
} else if (name.equals("NewFolder")) {
|
||||
iconIndex = VIEW_NEWFOLDER;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
return getStandardViewButton(iconIndex);
|
||||
} else if (key.startsWith("optionPaneIcon ")) {
|
||||
Win32ShellFolder2.SystemIcon iconType;
|
||||
if (key == "optionPaneIcon Error") {
|
||||
iconType = Win32ShellFolder2.SystemIcon.IDI_ERROR;
|
||||
} else if (key == "optionPaneIcon Information") {
|
||||
iconType = Win32ShellFolder2.SystemIcon.IDI_INFORMATION;
|
||||
} else if (key == "optionPaneIcon Question") {
|
||||
iconType = Win32ShellFolder2.SystemIcon.IDI_QUESTION;
|
||||
} else if (key == "optionPaneIcon Warning") {
|
||||
iconType = Win32ShellFolder2.SystemIcon.IDI_EXCLAMATION;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
return Win32ShellFolder2.getSystemIcon(iconType);
|
||||
} else if (key.startsWith("shell32Icon ") || key.startsWith("shell32LargeIcon ")) {
|
||||
String name = key.substring(key.indexOf(" ") + 1);
|
||||
try {
|
||||
int i = Integer.parseInt(name);
|
||||
if (i >= 0) {
|
||||
return Win32ShellFolder2.getShell32Icon(i, key.startsWith("shell32LargeIcon "));
|
||||
}
|
||||
} catch (NumberFormatException ex) {
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static File checkFile(File file) {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
return (sm == null || file == null) ? file : checkFile(file, sm);
|
||||
}
|
||||
|
||||
private static File checkFile(File file, SecurityManager sm) {
|
||||
try {
|
||||
sm.checkRead(file.getPath());
|
||||
|
||||
if (file instanceof Win32ShellFolder2) {
|
||||
Win32ShellFolder2 f = (Win32ShellFolder2)file;
|
||||
if (f.isLink()) {
|
||||
Win32ShellFolder2 link = (Win32ShellFolder2)f.getLinkLocation();
|
||||
if (link != null)
|
||||
sm.checkRead(link.getPath());
|
||||
}
|
||||
}
|
||||
return file;
|
||||
} catch (SecurityException se) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static File[] checkFiles(File[] files) {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm == null || files == null || files.length == 0) {
|
||||
return files;
|
||||
}
|
||||
return checkFiles(Arrays.stream(files), sm);
|
||||
}
|
||||
|
||||
private static File[] checkFiles(List<File> files) {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm == null || files.isEmpty()) {
|
||||
return files.toArray(new File[files.size()]);
|
||||
}
|
||||
return checkFiles(files.stream(), sm);
|
||||
}
|
||||
|
||||
private static File[] checkFiles(Stream<File> filesStream, SecurityManager sm) {
|
||||
return filesStream.filter((file) -> checkFile(file, sm) != null)
|
||||
.toArray(File[]::new);
|
||||
}
|
||||
|
||||
/**
|
||||
* Does <code>dir</code> represent a "computer" such as a node on the network, or
|
||||
* "My Computer" on the desktop.
|
||||
*/
|
||||
public boolean isComputerNode(final File dir) {
|
||||
if (dir != null && dir == getDrives()) {
|
||||
return true;
|
||||
} else {
|
||||
String path = AccessController.doPrivileged(new PrivilegedAction<String>() {
|
||||
public String run() {
|
||||
return dir.getAbsolutePath();
|
||||
}
|
||||
});
|
||||
|
||||
return (path.startsWith("\\\\") && path.indexOf("\\", 2) < 0); //Network path
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isFileSystemRoot(File dir) {
|
||||
//Note: Removable drives don't "exist" but are listed in "My Computer"
|
||||
if (dir != null) {
|
||||
Win32ShellFolder2 drives = getDrives();
|
||||
if (dir instanceof Win32ShellFolder2) {
|
||||
Win32ShellFolder2 sf = (Win32ShellFolder2)dir;
|
||||
if (sf.isFileSystem()) {
|
||||
if (sf.parent != null) {
|
||||
return sf.parent.equals(drives);
|
||||
}
|
||||
// else fall through ...
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
String path = dir.getPath();
|
||||
|
||||
if (path.length() != 3 || path.charAt(1) != ':') {
|
||||
return false;
|
||||
}
|
||||
|
||||
File[] files = drives.listFiles();
|
||||
|
||||
return files != null && Arrays.asList(files).contains(dir);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static List topFolderList = null;
|
||||
static int compareShellFolders(Win32ShellFolder2 sf1, Win32ShellFolder2 sf2) {
|
||||
boolean special1 = sf1.isSpecial();
|
||||
boolean special2 = sf2.isSpecial();
|
||||
|
||||
if (special1 || special2) {
|
||||
if (topFolderList == null) {
|
||||
ArrayList tmpTopFolderList = new ArrayList();
|
||||
tmpTopFolderList.add(Win32ShellFolderManager2.getPersonal());
|
||||
tmpTopFolderList.add(Win32ShellFolderManager2.getDesktop());
|
||||
tmpTopFolderList.add(Win32ShellFolderManager2.getDrives());
|
||||
tmpTopFolderList.add(Win32ShellFolderManager2.getNetwork());
|
||||
topFolderList = tmpTopFolderList;
|
||||
}
|
||||
int i1 = topFolderList.indexOf(sf1);
|
||||
int i2 = topFolderList.indexOf(sf2);
|
||||
if (i1 >= 0 && i2 >= 0) {
|
||||
return (i1 - i2);
|
||||
} else if (i1 >= 0) {
|
||||
return -1;
|
||||
} else if (i2 >= 0) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Non-file shellfolders sort before files
|
||||
if (special1 && !special2) {
|
||||
return -1;
|
||||
} else if (special2 && !special1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return compareNames(sf1.getAbsolutePath(), sf2.getAbsolutePath());
|
||||
}
|
||||
|
||||
static int compareNames(String name1, String name2) {
|
||||
// First ignore case when comparing
|
||||
int diff = name1.compareToIgnoreCase(name2);
|
||||
if (diff != 0) {
|
||||
return diff;
|
||||
} else {
|
||||
// May differ in case (e.g. "mail" vs. "Mail")
|
||||
// We need this test for consistent sorting
|
||||
return name1.compareTo(name2);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Invoker createInvoker() {
|
||||
return new ComInvoker();
|
||||
}
|
||||
|
||||
private static class ComInvoker extends ThreadPoolExecutor implements ThreadFactory, ShellFolder.Invoker {
|
||||
private static Thread comThread;
|
||||
|
||||
private ComInvoker() {
|
||||
super(1, 1, 0, TimeUnit.DAYS, new LinkedBlockingQueue<Runnable>());
|
||||
allowCoreThreadTimeOut(false);
|
||||
setThreadFactory(this);
|
||||
final Runnable shutdownHook = new Runnable() {
|
||||
public void run() {
|
||||
AccessController.doPrivileged(new PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
shutdownNow();
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
AccessController.doPrivileged(new PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
Runtime.getRuntime().addShutdownHook(
|
||||
new Thread(shutdownHook)
|
||||
);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public synchronized Thread newThread(final Runnable task) {
|
||||
final Runnable comRun = new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
initializeCom();
|
||||
task.run();
|
||||
} finally {
|
||||
uninitializeCom();
|
||||
}
|
||||
}
|
||||
};
|
||||
comThread = AccessController.doPrivileged((PrivilegedAction<Thread>) () -> {
|
||||
/* The thread must be a member of a thread group
|
||||
* which will not get GCed before VM exit.
|
||||
* Make its parent the top-level thread group.
|
||||
*/
|
||||
ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup();
|
||||
Thread thread = new Thread(rootTG, comRun, "Swing-Shell");
|
||||
thread.setDaemon(true);
|
||||
return thread;
|
||||
}
|
||||
);
|
||||
return comThread;
|
||||
}
|
||||
|
||||
public <T> T invoke(Callable<T> task) throws Exception {
|
||||
if (Thread.currentThread() == comThread) {
|
||||
// if it's already called from the COM
|
||||
// thread, we don't need to delegate the task
|
||||
return task.call();
|
||||
} else {
|
||||
final Future<T> future;
|
||||
|
||||
try {
|
||||
future = submit(task);
|
||||
} catch (RejectedExecutionException e) {
|
||||
throw new InterruptedException(e.getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
return future.get();
|
||||
} catch (InterruptedException e) {
|
||||
AccessController.doPrivileged(new PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
future.cancel(true);
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
throw e;
|
||||
} catch (ExecutionException e) {
|
||||
Throwable cause = e.getCause();
|
||||
|
||||
if (cause instanceof Exception) {
|
||||
throw (Exception) cause;
|
||||
}
|
||||
|
||||
if (cause instanceof Error) {
|
||||
throw (Error) cause;
|
||||
}
|
||||
|
||||
throw new RuntimeException("Unexpected error", cause);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static native void initializeCom();
|
||||
|
||||
static native void uninitializeCom();
|
||||
}
|
||||
Reference in New Issue
Block a user