# HG changeset patch # User rupashka # Date 1258462869 -10800 # Node ID b4474a4716ddd659965c8175cfea6dca87dca58d # Parent 74c4e0c5d9361e02ac7e059e92659f13dedabdcd 6868611: FileSystemView throws NullPointerException Reviewed-by: peterz diff -r 74c4e0c5d936 -r b4474a4716dd jdk/src/share/classes/javax/swing/filechooser/FileSystemView.java --- a/jdk/src/share/classes/javax/swing/filechooser/FileSystemView.java Thu Nov 12 18:59:19 2009 +0900 +++ b/jdk/src/share/classes/javax/swing/filechooser/FileSystemView.java Tue Nov 17 16:01:09 2009 +0300 @@ -33,7 +33,8 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.text.MessageFormat; -import java.util.Vector; +import java.util.List; +import java.util.ArrayList; import java.lang.ref.WeakReference; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeEvent; @@ -173,22 +174,27 @@ * @since 1.4 */ public String getSystemDisplayName(File f) { - String name = null; - if (f != null) { - name = f.getName(); - if (!name.equals("..") && !name.equals(".") && - (useSystemExtensionHiding || - !isFileSystem(f) || - isFileSystemRoot(f)) && - ((f instanceof ShellFolder) || - f.exists())) { + if (f == null) { + return null; + } + + String name = f.getName(); + if (!name.equals("..") && !name.equals(".") && + (useSystemExtensionHiding || !isFileSystem(f) || isFileSystemRoot(f)) && + (f instanceof ShellFolder || f.exists())) { + + try { name = getShellFolder(f).getDisplayName(); - if (name == null || name.length() == 0) { - name = f.getPath(); // e.g. "/" - } + } catch (FileNotFoundException e) { + return null; + } + + if (name == null || name.length() == 0) { + name = f.getPath(); // e.g. "/" } } + return name; } @@ -222,16 +228,24 @@ * @since 1.4 */ public Icon getSystemIcon(File f) { - if (f != null) { - ShellFolder sf = getShellFolder(f); - Image img = sf.getIcon(false); - if (img != null) { - return new ImageIcon(img, sf.getFolderType()); - } else { - return UIManager.getIcon(f.isDirectory() ? "FileView.directoryIcon" : "FileView.fileIcon"); - } + if (f == null) { + return null; + } + + ShellFolder sf; + + try { + sf = getShellFolder(f); + } catch (FileNotFoundException e) { + return null; + } + + Image img = sf.getIcon(false); + + if (img != null) { + return new ImageIcon(img, sf.getFolderType()); } else { - return null; + return UIManager.getIcon(f.isDirectory() ? "FileView.directoryIcon" : "FileView.fileIcon"); } } @@ -446,24 +460,28 @@ * Gets the list of shown (i.e. not hidden) files. */ public File[] getFiles(File dir, boolean useFileHiding) { - Vector files = new Vector(); - + List files = new ArrayList(); // add all files in dir - File[] names; - if (!(dir instanceof ShellFolder)) { + if (!(dir instanceof ShellFolder)) { + try { dir = getShellFolder(dir); + } catch (FileNotFoundException e) { + return new File[0]; } + } - names = ((ShellFolder)dir).listFiles(!useFileHiding); - File f; + File[] names = ((ShellFolder) dir).listFiles(!useFileHiding); - int nameCount = (names == null) ? 0 : names.length; - for (int i = 0; i < nameCount; i++) { + if (names == null) { + return new File[0]; + } + + for (File f : names) { if (Thread.currentThread().isInterrupted()) { break; } - f = names[i]; + if (!(f instanceof ShellFolder)) { if (isFileSystemRoot(f)) { f = createFileSystemRoot(f); @@ -481,7 +499,7 @@ } } if (!useFileHiding || !isHiddenFile(f)) { - files.addElement(f); + files.add(f); } } @@ -497,42 +515,50 @@ * null if dir is null */ public File getParentDirectory(File dir) { - if (dir != null && dir.exists()) { - ShellFolder sf = getShellFolder(dir); - File psf = sf.getParentFile(); - if (psf != null) { - if (isFileSystem(psf)) { - File f = psf; - if (f != null && !f.exists()) { - // This could be a node under "Network Neighborhood". - File ppsf = psf.getParentFile(); - if (ppsf == null || !isFileSystem(ppsf)) { - // We're mostly after the exists() override for windows below. - f = createFileSystemRoot(f); - } - } - return f; - } else { - return psf; + if (dir == null || !dir.exists()) { + return null; + } + + ShellFolder sf; + + try { + sf = getShellFolder(dir); + } catch (FileNotFoundException e) { + return null; + } + + File psf = sf.getParentFile(); + + if (psf == null) { + return null; + } + + if (isFileSystem(psf)) { + File f = psf; + if (!f.exists()) { + // This could be a node under "Network Neighborhood". + File ppsf = psf.getParentFile(); + if (ppsf == null || !isFileSystem(ppsf)) { + // We're mostly after the exists() override for windows below. + f = createFileSystemRoot(f); } } + return f; + } else { + return psf; } - return null; } - ShellFolder getShellFolder(File f) { - if (!(f instanceof ShellFolder) - && !(f instanceof FileSystemRoot) - && isFileSystemRoot(f)) { - + /** + * Throws {@code FileNotFoundException} if file not found or current thread was interrupted + */ + ShellFolder getShellFolder(File f) throws FileNotFoundException { + if (!(f instanceof ShellFolder) && !(f instanceof FileSystemRoot) && isFileSystemRoot(f)) { f = createFileSystemRoot(f); } + try { return ShellFolder.getShellFolder(f); - } catch (FileNotFoundException e) { - System.err.println("FileSystemView.getShellFolder: f="+f); - e.printStackTrace(); - return null; } catch (InternalError e) { System.err.println("FileSystemView.getShellFolder: f="+f); e.printStackTrace(); @@ -596,9 +622,9 @@ // Unix - using OpenWindows' default folder name. Can't find one for Motif/CDE. newFolder = createFileObject(containingDir, newFolderString); int i = 1; - while (newFolder.exists() && (i < 100)) { + while (newFolder.exists() && i < 100) { newFolder = createFileObject(containingDir, MessageFormat.format( - newFolderNextString, new Object[] { new Integer(i) })); + newFolderNextString, new Integer(i))); i++; } @@ -612,7 +638,7 @@ } public boolean isFileSystemRoot(File dir) { - return (dir != null && dir.getAbsolutePath().equals("/")); + return dir != null && dir.getAbsolutePath().equals("/"); } public boolean isDrive(File dir) { @@ -654,7 +680,7 @@ public File getChild(File parent, String fileName) { if (fileName.startsWith("\\") - && !(fileName.startsWith("\\\\")) + && !fileName.startsWith("\\\\") && isFileSystem(parent)) { //Path is relative to the root of parent's drive @@ -677,9 +703,13 @@ * The Windows implementation gets information from the ShellFolder class. */ public String getSystemTypeDescription(File f) { - if (f != null) { + if (f == null) { + return null; + } + + try { return getShellFolder(f).getFolderType(); - } else { + } catch (FileNotFoundException e) { return null; } } @@ -701,9 +731,9 @@ // Using NT's default folder name File newFolder = createFileObject(containingDir, newFolderString); int i = 2; - while (newFolder.exists() && (i < 100)) { + while (newFolder.exists() && i < 100) { newFolder = createFileObject(containingDir, MessageFormat.format( - newFolderNextString, new Object[] { new Integer(i) })); + newFolderNextString, new Integer(i))); i++; } @@ -727,7 +757,7 @@ } }); - return (path != null && (path.equals("A:\\") || path.equals("B:\\"))); + return path != null && (path.equals("A:\\") || path.equals("B:\\")); } /** diff -r 74c4e0c5d936 -r b4474a4716dd jdk/test/javax/swing/JFileChooser/6868611/bug6868611.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/swing/JFileChooser/6868611/bug6868611.java Tue Nov 17 16:01:09 2009 +0300 @@ -0,0 +1,93 @@ +/* + * Copyright 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* @test + @bug 6868611 + @summary FileSystemView throws NullPointerException + @author Pavel Porvatov + @run main bug6868611 +*/ + +import javax.swing.*; +import javax.swing.filechooser.FileSystemView; +import java.io.File; + +public class bug6868611 { + private static final int COUNT = 1000; + + public static void main(String[] args) throws Exception { + String tempDirProp = System.getProperty("java.io.tmpdir"); + + final String tempDir = tempDirProp == null || !new File(tempDirProp).isDirectory() ? + System.getProperty("user.home") : tempDirProp; + + System.out.println("Temp directory: " + tempDir); + + // Create 1000 files + for (int i = 0; i < 1000; i++) { + new File(tempDir, "temp" + i).createNewFile(); + } + + // Init default FileSystemView + SwingUtilities.invokeAndWait(new Runnable() { + public void run() { + FileSystemView.getFileSystemView().getFiles(new File(tempDir), false); + } + }); + + for (int i = 0; i < COUNT; i++) { + Thread thread = new MyThread(tempDir); + + thread.start(); + + Thread.sleep((long) (Math.random() * 100)); + + thread.interrupt(); + + if (i % 100 == 0) { + System.out.print("*"); + } + } + + System.out.println(); + + // Remove 1000 files + for (int i = 0; i < 1000; i++) { + new File(tempDir, "temp" + i).delete(); + } + } + + private static class MyThread extends Thread { + private final String dir; + + private MyThread(String dir) { + this.dir = dir; + } + + public void run() { + FileSystemView fileSystemView = FileSystemView.getFileSystemView(); + + fileSystemView.getFiles(new File(dir), false); + } + } +}