6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
Reviewed-by: malenkov, peterz
--- a/jdk/src/share/classes/javax/swing/JFileChooser.java Wed Jul 22 12:21:31 2009 +0400
+++ b/jdk/src/share/classes/javax/swing/JFileChooser.java Thu Jul 23 17:56:53 2009 +0400
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc. 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
@@ -739,6 +739,11 @@
dialog.show();
firePropertyChange("JFileChooserDialogIsClosingProperty", dialog, null);
+
+ // Remove all components from dialog. The MetalFileChooserUI.installUI() method (and other LAFs)
+ // registers AWT listener for dialogs and produces memory leaks. It happens when
+ // installUI invoked after the showDialog method.
+ dialog.getContentPane().removeAll();
dialog.dispose();
dialog = null;
return returnValue;
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java Wed Jul 22 12:21:31 2009 +0400
+++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java Thu Jul 23 17:56:53 2009 +0400
@@ -1,5 +1,5 @@
/*
- * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1998-2009 Sun Microsystems, Inc. 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
@@ -232,6 +232,10 @@
public void run0() {
FileSystemView fileSystem = filechooser.getFileSystemView();
+ if (isInterrupted()) {
+ return;
+ }
+
File[] list = fileSystem.getFiles(currentDirectory, filechooser.isFileHidingEnabled());
if (isInterrupted()) {
@@ -268,8 +272,8 @@
// To avoid loads of synchronizations with Invoker and improve performance we
// execute the whole block on the COM thread
- DoChangeContents doChangeContents = ShellFolder.getInvoker().invoke(new Callable<DoChangeContents>() {
- public DoChangeContents call() throws Exception {
+ DoChangeContents doChangeContents = ShellFolder.invoke(new Callable<DoChangeContents>() {
+ public DoChangeContents call() {
int newSize = newFileCache.size();
int oldSize = fileCache.size();
--- a/jdk/src/share/classes/sun/awt/shell/ShellFolder.java Wed Jul 22 12:21:31 2009 +0400
+++ b/jdk/src/share/classes/sun/awt/shell/ShellFolder.java Thu Jul 23 17:56:53 2009 +0400
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2000-2009 Sun Microsystems, Inc. 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
@@ -289,8 +289,8 @@
// To avoid loads of synchronizations with Invoker and improve performance we
// synchronize the whole code of the sort method once
- getInvoker().invoke(new Callable<Void>() {
- public Void call() throws Exception {
+ 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
@@ -330,8 +330,8 @@
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
- getInvoker().invoke(new Callable<Void>() {
- public Void call() throws Exception {
+ invoke(new Callable<Void>() {
+ public Void call() {
Collections.sort(files, FILE_COMPARATOR);
return null;
@@ -502,17 +502,61 @@
}
/**
+ * 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 getInvoker().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. If the {@code task} throws a checked exception,
- * it will be wrapped into a {@link RuntimeException}
+ * 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);
+ <T> T invoke(Callable<T> task) throws Exception;
}
/**
--- a/jdk/src/share/classes/sun/awt/shell/ShellFolderManager.java Wed Jul 22 12:21:31 2009 +0400
+++ b/jdk/src/share/classes/sun/awt/shell/ShellFolderManager.java Thu Jul 23 17:56:53 2009 +0400
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2000-2009 Sun Microsystems, Inc. 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
@@ -108,12 +108,8 @@
}
private static class DirectInvoker implements ShellFolder.Invoker {
- public <T> T invoke(Callable<T> task) {
- try {
- return task.call();
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
+ public <T> T invoke(Callable<T> task) throws Exception {
+ return task.call();
}
}
}
--- a/jdk/src/share/classes/sun/swing/FilePane.java Wed Jul 22 12:21:31 2009 +0400
+++ b/jdk/src/share/classes/sun/swing/FilePane.java Thu Jul 23 17:56:53 2009 +0400
@@ -1,6 +1,5 @@
-
/*
- * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003-2009 Sun Microsystems, Inc. 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
@@ -905,8 +904,8 @@
@Override
public void sort() {
- ShellFolder.getInvoker().invoke(new Callable<Void>() {
- public Void call() throws Exception {
+ ShellFolder.invoke(new Callable<Void>() {
+ public Void call() {
DetailsTableRowSorter.super.sort();
return null;
}
--- a/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolder2.java Wed Jul 22 12:21:31 2009 +0400
+++ b/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolder2.java Thu Jul 23 17:56:53 2009 +0400
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003-2009 Sun Microsystems, Inc. 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
@@ -29,7 +29,6 @@
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.File;
-import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.*;
@@ -185,8 +184,8 @@
boolean disposed;
public void dispose() {
if (disposed) return;
- ShellFolder.getInvoker().invoke(new Callable<Void>() {
- public Void call() throws Exception {
+ invoke(new Callable<Void>() {
+ public Void call() {
if (relativePIDL != 0) {
releasePIDL(relativePIDL);
}
@@ -224,7 +223,7 @@
*/
private boolean isPersonal;
- private static String composePathForCsidl(int csidl) throws IOException {
+ private static String composePathForCsidl(int csidl) throws IOException, InterruptedException {
String path = getFileSystemPath(csidl);
return path == null
? ("ShellFolder: 0x" + Integer.toHexString(csidl))
@@ -235,12 +234,13 @@
* Create a system special shell folder, such as the
* desktop or Network Neighborhood.
*/
- Win32ShellFolder2(final int csidl) throws IOException {
+ Win32ShellFolder2(final int csidl) throws IOException, InterruptedException {
// Desktop is parent of DRIVES and NETWORK, not necessarily
// other special shell folders.
super(null, composePathForCsidl(csidl));
- ShellFolder.getInvoker().invoke(new Callable<Void>() {
- public Void call() throws Exception {
+
+ invoke(new Callable<Void>() {
+ public Void call() throws InterruptedException {
if (csidl == DESKTOP) {
initDesktop();
} else {
@@ -276,7 +276,7 @@
}
return null;
}
- });
+ }, InterruptedException.class);
sun.java2d.Disposer.addRecord(this, disposer);
}
@@ -296,13 +296,13 @@
/**
* Creates a shell folder with a parent and relative PIDL
*/
- Win32ShellFolder2(final Win32ShellFolder2 parent, final long relativePIDL) {
+ Win32ShellFolder2(final Win32ShellFolder2 parent, final long relativePIDL) throws InterruptedException {
super(parent,
- ShellFolder.getInvoker().invoke(new Callable<String>() {
- public String call() throws Exception {
+ invoke(new Callable<String>() {
+ public String call() {
return getFileSystemPath(parent.getIShellFolder(), relativePIDL);
}
- })
+ }, RuntimeException.class)
);
this.disposer.relativePIDL = relativePIDL;
getAbsolutePath();
@@ -335,8 +335,8 @@
* drive (normally "C:\").
*/
protected Object writeReplace() throws java.io.ObjectStreamException {
- return ShellFolder.getInvoker().invoke(new Callable<File>() {
- public File call() throws Exception {
+ return invoke(new Callable<File>() {
+ public File call() {
if (isFileSystem()) {
return new File(getPath());
} else {
@@ -398,11 +398,11 @@
/**
* Accessor for IShellFolder
*/
- public long getIShellFolder() {
+ private long getIShellFolder() {
if (disposer.pIShellFolder == 0) {
- disposer.pIShellFolder =
- ShellFolder.getInvoker().invoke(new Callable<Long>() {
- public Long call() throws Exception {
+ try {
+ disposer.pIShellFolder = invoke(new Callable<Long>() {
+ public Long call() {
assert(isDirectory());
assert(parent != null);
long parentIShellFolder = getParentIShellFolder();
@@ -421,7 +421,10 @@
}
return pIShellFolder;
}
- });
+ }, RuntimeException.class);
+ } catch (InterruptedException e) {
+ // Ignore error
+ }
}
return disposer.pIShellFolder;
}
@@ -505,18 +508,23 @@
}
if (parent == rhs.parent || parent.equals(rhs.parent)) {
- return pidlsEqual(getParentIShellFolder(), disposer.relativePIDL, rhs.disposer.relativePIDL);
+ try {
+ return pidlsEqual(getParentIShellFolder(), disposer.relativePIDL, rhs.disposer.relativePIDL);
+ } catch (InterruptedException e) {
+ return false;
+ }
}
return false;
}
- private static boolean pidlsEqual(final long pIShellFolder, final long pidl1, final long pidl2) {
- return ShellFolder.getInvoker().invoke(new Callable<Boolean>() {
- public Boolean call() throws Exception {
- return (compareIDs(pIShellFolder, pidl1, pidl2) == 0);
+ private static boolean pidlsEqual(final long pIShellFolder, final long pidl1, final long pidl2)
+ throws InterruptedException {
+ return invoke(new Callable<Boolean>() {
+ public Boolean call() {
+ return compareIDs(pIShellFolder, pidl1, pidl2) == 0;
}
- });
+ }, RuntimeException.class);
}
// NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
@@ -539,14 +547,16 @@
* Return whether the given attribute flag is set for this object
*/
public boolean hasAttribute(final int attribute) {
- return ShellFolder.getInvoker().invoke(new Callable<Boolean>() {
- public Boolean call() throws Exception {
+ Boolean result = invoke(new Callable<Boolean>() {
+ public Boolean call() {
// Caching at this point doesn't seem to be cost efficient
return (getAttributes0(getParentIShellFolder(),
getRelativePIDL(), attribute)
& attribute) != 0;
}
});
+
+ return result != null && result;
}
/**
@@ -561,32 +571,29 @@
private static native int getAttributes0(long pParentIShellFolder, long pIDL, int attrsMask);
// Return the path to the underlying file system object
+ // Should be called from the COM thread
private static String getFileSystemPath(final long parentIShellFolder, final long relativePIDL) {
- return ShellFolder.getInvoker().invoke(new Callable<String>() {
- public String call() throws Exception {
- int linkedFolder = ATTRIB_LINK | ATTRIB_FOLDER;
- if (parentIShellFolder == Win32ShellFolderManager2.getNetwork().getIShellFolder() &&
- getAttributes0(parentIShellFolder, relativePIDL, linkedFolder) == linkedFolder) {
+ int linkedFolder = ATTRIB_LINK | ATTRIB_FOLDER;
+ if (parentIShellFolder == Win32ShellFolderManager2.getNetwork().getIShellFolder() &&
+ getAttributes0(parentIShellFolder, relativePIDL, linkedFolder) == linkedFolder) {
- String s =
- getFileSystemPath(Win32ShellFolderManager2.getDesktop().getIShellFolder(),
- getLinkLocation(parentIShellFolder, relativePIDL, false));
- if (s != null && s.startsWith("\\\\")) {
- return s;
- }
- }
- return getDisplayNameOf(parentIShellFolder, relativePIDL, SHGDN_FORPARSING);
+ String s =
+ getFileSystemPath(Win32ShellFolderManager2.getDesktop().getIShellFolder(),
+ getLinkLocation(parentIShellFolder, relativePIDL, false));
+ if (s != null && s.startsWith("\\\\")) {
+ return s;
}
- });
+ }
+ return getDisplayNameOf(parentIShellFolder, relativePIDL, SHGDN_FORPARSING);
}
// Needs to be accessible to Win32ShellFolderManager2
- static String getFileSystemPath(final int csidl) throws IOException {
- return ShellFolder.getInvoker().invoke(new Callable<String>() {
- public String call() throws Exception {
+ static String getFileSystemPath(final int csidl) throws IOException, InterruptedException {
+ return invoke(new Callable<String>() {
+ public String call() throws IOException {
return getFileSystemPath0(csidl);
}
- });
+ }, IOException.class);
}
// NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
@@ -630,13 +637,14 @@
*/
// Returns an IEnumIDList interface for an IShellFolder. The value
// returned must be released using releaseEnumObjects().
- private long getEnumObjects(long pIShellFolder, final boolean includeHiddenFiles) {
- final boolean isDesktop = (disposer.pIShellFolder == getDesktopIShellFolder());
- return ShellFolder.getInvoker().invoke(new Callable<Long>() {
- public Long call() throws Exception {
+ private long getEnumObjects(final boolean includeHiddenFiles) throws InterruptedException {
+ return invoke(new Callable<Long>() {
+ public Long call() {
+ boolean isDesktop = disposer.pIShellFolder == getDesktopIShellFolder();
+
return getEnumObjects(disposer.pIShellFolder, isDesktop, includeHiddenFiles);
}
- });
+ }, RuntimeException.class);
}
// Returns an IEnumIDList interface for an IShellFolder. The value
@@ -670,58 +678,62 @@
security.checkRead(getPath());
}
- return ShellFolder.getInvoker().invoke(new Callable<File[]>() {
- public File[] call() throws Exception {
- if (!isDirectory()) {
- return null;
- }
- // Links to directories are not directories and cannot be parents.
- // This does not apply to folders in My Network Places (NetHood)
- // because they are both links and real directories!
- if (isLink() && !hasAttribute(ATTRIB_FOLDER)) {
- return new File[0];
- }
+ try {
+ return invoke(new Callable<File[]>() {
+ public File[] call() throws InterruptedException {
+ if (!isDirectory()) {
+ return null;
+ }
+ // Links to directories are not directories and cannot be parents.
+ // This does not apply to folders in My Network Places (NetHood)
+ // because they are both links and real directories!
+ if (isLink() && !hasAttribute(ATTRIB_FOLDER)) {
+ return new File[0];
+ }
- Win32ShellFolder2 desktop = Win32ShellFolderManager2.getDesktop();
- Win32ShellFolder2 personal = Win32ShellFolderManager2.getPersonal();
+ Win32ShellFolder2 desktop = Win32ShellFolderManager2.getDesktop();
+ Win32ShellFolder2 personal = Win32ShellFolderManager2.getPersonal();
- // If we are a directory, we have a parent and (at least) a
- // relative PIDL. We must first ensure we are bound to the
- // parent so we have an IShellFolder to query.
- long pIShellFolder = getIShellFolder();
- // Now we can enumerate the objects in this folder.
- ArrayList<Win32ShellFolder2> list = new ArrayList<Win32ShellFolder2>();
- long pEnumObjects = getEnumObjects(pIShellFolder, includeHiddenFiles);
- if (pEnumObjects != 0) {
- long childPIDL;
- int testedAttrs = ATTRIB_FILESYSTEM | ATTRIB_FILESYSANCESTOR;
- do {
- childPIDL = getNextChild(pEnumObjects);
- boolean releasePIDL = true;
- if (childPIDL != 0 &&
- (getAttributes0(pIShellFolder, childPIDL, testedAttrs) & testedAttrs) != 0) {
- Win32ShellFolder2 childFolder;
- if (Win32ShellFolder2.this.equals(desktop)
- && personal != null
- && pidlsEqual(pIShellFolder, childPIDL, personal.disposer.relativePIDL)) {
- childFolder = personal;
- } else {
- childFolder = new Win32ShellFolder2(Win32ShellFolder2.this, childPIDL);
- releasePIDL = false;
+ // If we are a directory, we have a parent and (at least) a
+ // relative PIDL. We must first ensure we are bound to the
+ // parent so we have an IShellFolder to query.
+ long pIShellFolder = getIShellFolder();
+ // Now we can enumerate the objects in this folder.
+ ArrayList<Win32ShellFolder2> list = new ArrayList<Win32ShellFolder2>();
+ long pEnumObjects = getEnumObjects(includeHiddenFiles);
+ if (pEnumObjects != 0) {
+ long childPIDL;
+ int testedAttrs = ATTRIB_FILESYSTEM | ATTRIB_FILESYSANCESTOR;
+ do {
+ childPIDL = getNextChild(pEnumObjects);
+ boolean releasePIDL = true;
+ if (childPIDL != 0 &&
+ (getAttributes0(pIShellFolder, childPIDL, testedAttrs) & testedAttrs) != 0) {
+ Win32ShellFolder2 childFolder;
+ if (Win32ShellFolder2.this.equals(desktop)
+ && personal != null
+ && pidlsEqual(pIShellFolder, childPIDL, personal.disposer.relativePIDL)) {
+ childFolder = personal;
+ } else {
+ childFolder = new Win32ShellFolder2(Win32ShellFolder2.this, childPIDL);
+ releasePIDL = false;
+ }
+ list.add(childFolder);
}
- list.add(childFolder);
- }
- if (releasePIDL) {
- releasePIDL(childPIDL);
- }
- } while (childPIDL != 0 && !Thread.currentThread().isInterrupted());
- releaseEnumObjects(pEnumObjects);
+ if (releasePIDL) {
+ releasePIDL(childPIDL);
+ }
+ } while (childPIDL != 0 && !Thread.currentThread().isInterrupted());
+ releaseEnumObjects(pEnumObjects);
+ }
+ return Thread.currentThread().isInterrupted()
+ ? new File[0]
+ : list.toArray(new ShellFolder[list.size()]);
}
- return Thread.currentThread().isInterrupted()
- ? new File[0]
- : list.toArray(new ShellFolder[list.size()]);
- }
- });
+ }, InterruptedException.class);
+ } catch (InterruptedException e) {
+ return new File[0];
+ }
}
@@ -730,13 +742,13 @@
*
* @return The child shellfolder, or null if not found.
*/
- Win32ShellFolder2 getChildByPath(final String filePath) {
- return ShellFolder.getInvoker().invoke(new Callable<Win32ShellFolder2>() {
- public Win32ShellFolder2 call() throws Exception {
+ Win32ShellFolder2 getChildByPath(final String filePath) throws InterruptedException {
+ return invoke(new Callable<Win32ShellFolder2>() {
+ public Win32ShellFolder2 call() throws InterruptedException {
long pIShellFolder = getIShellFolder();
- long pEnumObjects = getEnumObjects(pIShellFolder, true);
+ long pEnumObjects = getEnumObjects(true);
Win32ShellFolder2 child = null;
- long childPIDL = 0;
+ long childPIDL;
while ((childPIDL = getNextChild(pEnumObjects)) != 0) {
if (getAttributes0(pIShellFolder, childPIDL, ATTRIB_FILESYSTEM) != 0) {
@@ -753,7 +765,7 @@
releaseEnumObjects(pEnumObjects);
return child;
}
- });
+ }, InterruptedException.class);
}
private Boolean cachedIsLink;
@@ -791,8 +803,8 @@
}
private ShellFolder getLinkLocation(final boolean resolve) {
- return ShellFolder.getInvoker().invoke(new Callable<ShellFolder>() {
- public ShellFolder call() throws Exception {
+ return invoke(new Callable<ShellFolder>() {
+ public ShellFolder call() {
if (!isLink()) {
return null;
}
@@ -805,6 +817,8 @@
location =
Win32ShellFolderManager2.createShellFolderFromRelativePIDL(getDesktop(),
linkLocationPIDL);
+ } catch (InterruptedException e) {
+ // Return null
} catch (InternalError e) {
// Could be a link to a non-bindable object, such as a network connection
// TODO: getIShellFolder() should throw FileNotFoundException instead
@@ -816,19 +830,12 @@
}
// Parse a display name into a PIDL relative to the current IShellFolder.
- long parseDisplayName(final String name) throws FileNotFoundException {
- try {
- return ShellFolder.getInvoker().invoke(new Callable<Long>() {
- public Long call() throws Exception {
- return parseDisplayName0(getIShellFolder(), name);
- }
- });
- } catch (RuntimeException e) {
- if (e.getCause() instanceof IOException) {
- throw new FileNotFoundException("Could not find file " + name);
+ long parseDisplayName(final String name) throws IOException, InterruptedException {
+ return invoke(new Callable<Long>() {
+ public Long call() throws IOException {
+ return parseDisplayName0(getIShellFolder(), name);
}
- throw e;
- }
+ }, IOException.class);
}
// NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
@@ -846,8 +853,8 @@
public String getDisplayName() {
if (displayName == null) {
displayName =
- ShellFolder.getInvoker().invoke(new Callable<String>() {
- public String call() throws Exception {
+ invoke(new Callable<String>() {
+ public String call() {
return getDisplayNameOf(getParentIShellFolder(),
getRelativePIDL(), SHGDN_NORMAL);
}
@@ -867,8 +874,8 @@
if (folderType == null) {
final long absolutePIDL = getAbsolutePIDL();
folderType =
- ShellFolder.getInvoker().invoke(new Callable<String>() {
- public String call() throws Exception {
+ invoke(new Callable<String>() {
+ public String call() {
return getFolderType(absolutePIDL);
}
});
@@ -926,15 +933,12 @@
public static native int[] getFileChooserBitmapBits();
+ // Should be called from the COM thread
private long getIShellIcon() {
if (pIShellIcon == -1L) {
- pIShellIcon =
- ShellFolder.getInvoker().invoke(new Callable<Long>() {
- public Long call() throws Exception {
- return getIShellIcon(getIShellFolder());
- }
- });
+ pIShellIcon = getIShellIcon(getIShellFolder());
}
+
return pIShellIcon;
}
@@ -988,8 +992,8 @@
Image icon = getLargeIcon ? largeIcon : smallIcon;
if (icon == null) {
icon =
- ShellFolder.getInvoker().invoke(new Callable<Image>() {
- public Image call() throws Exception {
+ invoke(new Callable<Image>() {
+ public Image call() {
Image newIcon = null;
if (isFileSystem()) {
long parentIShellIcon = (parent != null)
@@ -1113,8 +1117,8 @@
private static final int LVCFMT_CENTER = 2;
public ShellFolderColumnInfo[] getFolderColumns() {
- return ShellFolder.getInvoker().invoke(new Callable<ShellFolderColumnInfo[]>() {
- public ShellFolderColumnInfo[] call() throws Exception {
+ return invoke(new Callable<ShellFolderColumnInfo[]>() {
+ public ShellFolderColumnInfo[] call() {
ShellFolderColumnInfo[] columns = doGetColumnInfo(getIShellFolder());
if (columns != null) {
@@ -1143,8 +1147,8 @@
}
public Object getFolderColumnValue(final int column) {
- return ShellFolder.getInvoker().invoke(new Callable<Object>() {
- public Object call() throws Exception {
+ return invoke(new Callable<Object>() {
+ public Object call() {
return doGetColumnValue(getParentIShellFolder(), getRelativePIDL(), column);
}
});
@@ -1163,8 +1167,8 @@
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
- getInvoker().invoke(new Callable<Void>() {
- public Void call() throws Exception {
+ invoke(new Callable<Void>() {
+ public Void call() {
Collections.sort(files, new ColumnComparator(getIShellFolder(), 0));
return null;
@@ -1184,19 +1188,21 @@
// compares 2 objects within this folder by the specified column
public int compare(final File o, final File o1) {
- return ShellFolder.getInvoker().invoke(new Callable<Integer>() {
- public Integer call() throws Exception {
+ Integer result = invoke(new Callable<Integer>() {
+ public Integer call() {
if (o instanceof Win32ShellFolder2
- && o1 instanceof Win32ShellFolder2) {
+ && o1 instanceof Win32ShellFolder2) {
// delegates comparison to native method
return compareIDsByColumn(parentIShellFolder,
- ((Win32ShellFolder2) o).getRelativePIDL(),
- ((Win32ShellFolder2) o1).getRelativePIDL(),
- columnIdx);
+ ((Win32ShellFolder2) o).getRelativePIDL(),
+ ((Win32ShellFolder2) o1).getRelativePIDL(),
+ columnIdx);
}
return 0;
}
});
+
+ return result == null ? 0 : result;
}
}
}
--- a/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java Wed Jul 22 12:21:31 2009 +0400
+++ b/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java Thu Jul 23 17:56:53 2009 +0400
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003-2009 Sun Microsystems, Inc. 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
@@ -58,10 +58,15 @@
}
public ShellFolder createShellFolder(File file) throws FileNotFoundException {
- return createShellFolder(getDesktop(), file);
+ try {
+ return createShellFolder(getDesktop(), file);
+ } catch (InterruptedException e) {
+ throw new FileNotFoundException("Execution was interrupted");
+ }
}
- static Win32ShellFolder2 createShellFolder(Win32ShellFolder2 parent, File file) throws FileNotFoundException {
+ static Win32ShellFolder2 createShellFolder(Win32ShellFolder2 parent, File file)
+ throws FileNotFoundException, InterruptedException {
long pIDL;
try {
pIDL = parent.parseDisplayName(file.getCanonicalPath());
@@ -77,7 +82,8 @@
return folder;
}
- static Win32ShellFolder2 createShellFolderFromRelativePIDL(Win32ShellFolder2 parent, long 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);
@@ -108,7 +114,9 @@
try {
desktop = new Win32ShellFolder2(DESKTOP);
} catch (IOException e) {
- desktop = null;
+ // Ignore error
+ } catch (InterruptedException e) {
+ // Ignore error
}
}
return desktop;
@@ -119,7 +127,9 @@
try {
drives = new Win32ShellFolder2(DRIVES);
} catch (IOException e) {
- drives = null;
+ // Ignore error
+ } catch (InterruptedException e) {
+ // Ignore error
}
}
return drives;
@@ -132,8 +142,10 @@
if (path != null) {
recent = createShellFolder(getDesktop(), new File(path));
}
+ } catch (InterruptedException e) {
+ // Ignore error
} catch (IOException e) {
- recent = null;
+ // Ignore error
}
}
return recent;
@@ -144,7 +156,9 @@
try {
network = new Win32ShellFolder2(NETWORK);
} catch (IOException e) {
- network = null;
+ // Ignore error
+ } catch (InterruptedException e) {
+ // Ignore error
}
}
return network;
@@ -164,8 +178,10 @@
personal.setIsPersonal();
}
}
+ } catch (InterruptedException e) {
+ // Ignore error
} catch (IOException e) {
- personal = null;
+ // Ignore error
}
}
return personal;
@@ -267,6 +283,9 @@
}
} catch (IOException e) {
// Skip this value
+ } catch (InterruptedException e) {
+ // Return empty result
+ return new File[0];
}
} while (value != null);
@@ -476,33 +495,39 @@
return comThread;
}
- public <T> T invoke(Callable<T> task) {
- try {
- 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 {
- while (true) {
- Future<T> future = submit(task);
+ 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 {
+ Future<T> future;
+
+ try {
+ future = submit(task);
+ } catch (RejectedExecutionException e) {
+ throw new InterruptedException(e.getMessage());
+ }
- try {
- return future.get();
- } catch (InterruptedException e) {
- // Repeat the attempt
- future.cancel(true);
- }
+ try {
+ return future.get();
+ } catch (InterruptedException e) {
+ future.cancel(true);
+
+ 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);
}
- } catch (Exception e) {
- Throwable cause = (e instanceof ExecutionException) ? e.getCause() : e;
- if (cause instanceof RuntimeException) {
- throw (RuntimeException) cause;
- }
- if (cause instanceof Error) {
- throw (Error) cause;
- }
- throw new RuntimeException(cause);
}
}
}