< prev index next >

src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolder2.java

Print this page

        

@@ -27,10 +27,11 @@
 
 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.util.*;
 import java.util.concurrent.*;
 import javax.swing.SwingConstants;
 

@@ -231,10 +232,11 @@
     private String folderType = null;
     private String displayName = null;
     private Image smallIcon = null;
     private Image largeIcon = null;
     private Boolean isDir = null;
+    private final boolean isLib;
 
     /*
      * The following is to identify the My Documents folder as being special
      */
     private boolean isPersonal;

@@ -252,10 +254,11 @@
      */
     Win32ShellFolder2(final int csidl) throws IOException, InterruptedException {
         // Desktop is parent of DRIVES and NETWORK, not necessarily
         // other special shell folders.
         super(null, composePathForCsidl(csidl));
+        isLib = false;
 
         invoke(new Callable<Void>() {
             public Void call() throws InterruptedException {
                 if (csidl == DESKTOP) {
                     initDesktop();

@@ -277,11 +280,11 @@
                             pIDL = getNextPIDLEntry(pIDL);
                             if (pIDL != 0) {
                                 // Now we know that parent isn't immediate to 'this' because it
                                 // has a continued ID list. Create a shell folder for this child
                                 // pidl and make it the new 'parent'.
-                                parent = new Win32ShellFolder2((Win32ShellFolder2) parent, childPIDL);
+                                parent = createShellFolder((Win32ShellFolder2) parent, childPIDL);
                             } else {
                                 // No grandchildren means we have arrived at the parent of 'this',
                                 // and childPIDL is directly relative to parent.
                                 disposer.relativePIDL = childPIDL;
                             }

@@ -299,31 +302,35 @@
 
 
     /**
      * Create a system shell folder
      */
-    Win32ShellFolder2(Win32ShellFolder2 parent, long pIShellFolder, long relativePIDL, String path) {
+    Win32ShellFolder2(Win32ShellFolder2 parent, long pIShellFolder, long relativePIDL, String path, boolean isLib) {
         super(parent, (path != null) ? path : "ShellFolder: ");
+        this.isLib = isLib;
         this.disposer.pIShellFolder = pIShellFolder;
         this.disposer.relativePIDL = relativePIDL;
         sun.java2d.Disposer.addRecord(this, disposer);
     }
 
 
     /**
      * Creates a shell folder with a parent and relative PIDL
      */
-    Win32ShellFolder2(final Win32ShellFolder2 parent, final long relativePIDL) throws InterruptedException {
-        super(parent,
-            invoke(new Callable<String>() {
+    static Win32ShellFolder2 createShellFolder(Win32ShellFolder2 parent, long pIDL)
+            throws InterruptedException {
+        String path = invoke(new Callable<String>() {
                 public String call() {
-                    return getFileSystemPath(parent.getIShellFolder(), relativePIDL);
+                return getFileSystemPath(parent.getIShellFolder(), pIDL);
+            }
+        }, RuntimeException.class);
+        String libPath = resolveLibrary(path);
+        if (libPath == null) {
+            return new Win32ShellFolder2(parent, 0, pIDL, path, false);
+        } else {
+            return new Win32ShellFolder2(parent, 0, pIDL, libPath, true);
                 }
-            }, RuntimeException.class)
-        );
-        this.disposer.relativePIDL = relativePIDL;
-        sun.java2d.Disposer.addRecord(this, disposer);
     }
 
     // Initializes the desktop shell folder
     // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
     private native void initDesktop();

@@ -599,24 +606,28 @@
                 return s;
             }
         }
         String path = getDisplayNameOf(parentIShellFolder, relativePIDL,
                         SHGDN_FORPARSING);
+        return path;
+    }
+
+    private static String resolveLibrary(String path) {
         // if this is a library its default save location is taken as a path
         // this is a temp fix until java.io starts support Libraries
         if( path != null && path.startsWith("::{") &&
                 path.toLowerCase().endsWith(".library-ms")) {
             for (KnownFolderDefinition kf : KnownFolderDefinition.libraries) {
-                if( path.toLowerCase().endsWith(
-                            kf.relativePath.toLowerCase()) &&
+                if (path.toLowerCase().endsWith(
+                        "\\" + kf.relativePath.toLowerCase()) &&
                             path.toUpperCase().startsWith(
-                            kf.parsingName.substring(0, 40).toUpperCase()) ) {
+                        kf.parsingName.substring(0, 40).toUpperCase())) {
                     return kf.saveLocation;
                 }
             }
         }
-        return path;
+        return null;
     }
 
     // Needs to be accessible to Win32ShellFolderManager2
     static String getFileSystemPath(final int csidl) throws IOException, InterruptedException {
         String path = invoke(new Callable<String>() {

@@ -748,11 +759,11 @@
                                     if (Win32ShellFolder2.this.equals(desktop)
                                             && personal != null
                                             && pidlsEqual(pIShellFolder, childPIDL, personal.disposer.relativePIDL)) {
                                         childFolder = personal;
                                     } else {
-                                        childFolder = new Win32ShellFolder2(Win32ShellFolder2.this, childPIDL);
+                                        childFolder = createShellFolder(Win32ShellFolder2.this, childPIDL);
                                         releasePIDL = false;
                                     }
                                     list.add(childFolder);
                                 }
                                 if (releasePIDL) {

@@ -788,14 +799,15 @@
                 long childPIDL;
 
                 while ((childPIDL = getNextChild(pEnumObjects)) != 0) {
                     if (getAttributes0(pIShellFolder, childPIDL, ATTRIB_FILESYSTEM) != 0) {
                         String path = getFileSystemPath(pIShellFolder, childPIDL);
+                        if(isLib) path = resolveLibrary( path );
                         if (path != null && path.equalsIgnoreCase(filePath)) {
                             long childIShellFolder = bindToObject(pIShellFolder, childPIDL);
                             child = new Win32ShellFolder2(Win32ShellFolder2.this,
-                                    childIShellFolder, childPIDL, path);
+                                    childIShellFolder, childPIDL, path, isLib);
                             break;
                         }
                     }
                     releasePIDL(childPIDL);
                 }

@@ -1127,10 +1139,12 @@
     private static final int LVCFMT_LEFT = 0;
     private static final int LVCFMT_RIGHT = 1;
     private static final int LVCFMT_CENTER = 2;
 
     public ShellFolderColumnInfo[] getFolderColumns() {
+        ShellFolder library = resolveLibrary();
+        if (library != null) return library.getFolderColumns();
         return invoke(new Callable<ShellFolderColumnInfo[]>() {
             public ShellFolderColumnInfo[] call() {
                 ShellFolderColumnInfo[] columns = doGetColumnInfo(getIShellFolder());
 
                 if (columns != null) {

@@ -1157,17 +1171,41 @@
             }
         });
     }
 
     public Object getFolderColumnValue(final int column) {
+        if(!isLibrary()) {
+            ShellFolder library = resolveLibrary();
+            if (library != null) return library.getFolderColumnValue(column);
+        }
         return invoke(new Callable<Object>() {
             public Object call() {
                 return doGetColumnValue(getParentIShellFolder(), getRelativePIDL(), column);
             }
         });
     }
 
+    boolean isLibrary() {
+        return isLib;
+    }
+
+    private ShellFolder resolveLibrary() {
+        for (ShellFolder f = this; f != null; f = f.parent) {
+            if (!f.isFileSystem()) {
+                if (f instanceof Win32ShellFolder2 &&
+                                           ((Win32ShellFolder2)f).isLibrary()) {
+                    try {
+                        return getShellFolder(new File(getPath()));
+                    } catch (FileNotFoundException e) {
+                    }
+                }
+                break;
+            }
+        }
+        return null;
+    }
+
     // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
     private native ShellFolderColumnInfo[] doGetColumnInfo(long iShellFolder2);
 
     // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
     private native Object doGetColumnValue(long parentIShellFolder2, long childPIDL, int columnIdx);
< prev index next >