jdk/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java
author rupashka
Fri, 15 May 2009 17:26:45 +0400
changeset 2817 f171f2417978
parent 2489 5052722686e2
child 3346 1c65be97eaa2
permissions -rw-r--r--
6713352: Deadlock in JFileChooser with synchronized custom FileSystemView Reviewed-by: malenkov, peterz
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
715
f16baef3a20e 6719955: Update copyright year
xdono
parents: 678
diff changeset
     2
 * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
90ce3da70b43 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Sun designates this
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
90ce3da70b43 Initial load
duke
parents:
diff changeset
     9
 * by Sun in the LICENSE file that accompanied this code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    21
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    22
 * CA 95054 USA or visit www.sun.com if you need additional information or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    23
 * have any questions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package sun.awt.shell;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.awt.Toolkit;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.io.File;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.io.FileNotFoundException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import java.io.IOException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
import java.security.AccessController;
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
    34
import java.security.PrivilegedAction;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
import java.util.*;
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
    36
import java.util.concurrent.*;
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
    37
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
import sun.security.action.LoadLibraryAction;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
import static sun.awt.shell.Win32ShellFolder2.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
import sun.awt.OSInfo;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
// NOTE: This class supersedes Win32ShellFolderManager, which was removed
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
//       from distribution after version 1.4.2.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 * @author Michael Martak
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
 * @author Leif Samuelsson
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 * @author Kenneth Russell
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 * @since 1.4
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
public class Win32ShellFolderManager2 extends ShellFolderManager {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
    static {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
        // Load library here
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
        AccessController.doPrivileged(new LoadLibraryAction("awt"));
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
    public ShellFolder createShellFolder(File file) throws FileNotFoundException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
        return createShellFolder(getDesktop(), file);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
    static Win32ShellFolder2 createShellFolder(Win32ShellFolder2 parent, File file) throws FileNotFoundException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
        long pIDL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
            pIDL = parent.parseDisplayName(file.getCanonicalPath());
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
        } catch (IOException ex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
            pIDL = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
        if (pIDL == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
            // Shouldn't happen but watch for it anyway
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
            throw new FileNotFoundException("File " + file.getAbsolutePath() + " not found");
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
        Win32ShellFolder2 folder = createShellFolderFromRelativePIDL(parent, pIDL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
        Win32ShellFolder2.releasePIDL(pIDL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
        return folder;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
    static Win32ShellFolder2 createShellFolderFromRelativePIDL(Win32ShellFolder2 parent, long pIDL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
        // Walk down this relative pIDL, creating new nodes for each of the entries
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
        while (pIDL != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
            long curPIDL = Win32ShellFolder2.copyFirstPIDLEntry(pIDL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
            if (curPIDL != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
                parent = new Win32ShellFolder2(parent, curPIDL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
                pIDL = Win32ShellFolder2.getNextPIDLEntry(pIDL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
                // The list is empty if the parent is Desktop and pIDL is a shortcut to Desktop
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
        return parent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
    // Special folders
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
    private static Win32ShellFolder2 desktop;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
    private static Win32ShellFolder2 drives;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
    private static Win32ShellFolder2 recent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
    private static Win32ShellFolder2 network;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
    private static Win32ShellFolder2 personal;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
    private static String osVersion = System.getProperty("os.version");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
    private static final boolean useShell32Icons =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
                        (osVersion != null && osVersion.compareTo("5.1") >= 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
    static Win32ShellFolder2 getDesktop() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
        if (desktop == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
                desktop = new Win32ShellFolder2(DESKTOP);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
            } catch (IOException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
                desktop = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
        return desktop;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
    static Win32ShellFolder2 getDrives() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
        if (drives == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
                drives = new Win32ShellFolder2(DRIVES);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
            } catch (IOException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
                drives = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
        return drives;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
    static Win32ShellFolder2 getRecent() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
        if (recent == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
                String path = Win32ShellFolder2.getFileSystemPath(RECENT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
                if (path != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
                    recent = createShellFolder(getDesktop(), new File(path));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
            } catch (IOException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
                recent = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
        return recent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
    static Win32ShellFolder2 getNetwork() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
        if (network == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
                network = new Win32ShellFolder2(NETWORK);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
            } catch (IOException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
                network = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
        return network;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
    static Win32ShellFolder2 getPersonal() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
        if (personal == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
                String path = Win32ShellFolder2.getFileSystemPath(PERSONAL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
                if (path != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
                    Win32ShellFolder2 desktop = getDesktop();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
                    personal = desktop.getChildByPath(path);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
                    if (personal == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
                        personal = createShellFolder(getDesktop(), new File(path));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
                    if (personal != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
                        personal.setIsPersonal();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
            } catch (IOException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
                personal = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
        return personal;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
    private static File[] roots;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
     * @param key a <code>String</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
     *  "fileChooserDefaultFolder":
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
     *    Returns a <code>File</code> - the default shellfolder for a new filechooser
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
     *  "roots":
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
     *    Returns a <code>File[]</code> - containing the root(s) of the displayable hierarchy
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
     *  "fileChooserComboBoxFolders":
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
     *    Returns a <code>File[]</code> - an array of shellfolders representing the list to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
     *    show by default in the file chooser's combobox
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
     *   "fileChooserShortcutPanelFolders":
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
     *    Returns a <code>File[]</code> - an array of shellfolders representing well-known
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
     *    folders, such as Desktop, Documents, History, Network, Home, etc.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
     *    This is used in the shortcut panel of the filechooser on Windows 2000
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
     *    and Windows Me.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
     *  "fileChooserIcon nn":
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
     *    Returns an <code>Image</code> - icon nn from resource 216 in shell32.dll,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
     *      or if not found there from resource 124 in comctl32.dll (Windows only).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
     *  "optionPaneIcon iconName":
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
     *    Returns an <code>Image</code> - icon from the system icon list
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
     * @return An Object matching the key string.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
    public Object get(String key) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
        if (key.equals("fileChooserDefaultFolder")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
            File file = getPersonal();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
            if (file == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
                file = getDesktop();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
            return file;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
        } else if (key.equals("roots")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
            // Should be "History" and "Desktop" ?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
            if (roots == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
                File desktop = getDesktop();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
                if (desktop != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
                    roots = new File[] { desktop };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
                    roots = (File[])super.get(key);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
            return roots;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
        } else if (key.equals("fileChooserComboBoxFolders")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
            Win32ShellFolder2 desktop = getDesktop();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
            if (desktop != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
                ArrayList<File> folders = new ArrayList<File>();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
                Win32ShellFolder2 drives = getDrives();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
                Win32ShellFolder2 recentFolder = getRecent();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
                if (recentFolder != null && OSInfo.getWindowsVersion().compareTo(OSInfo.WINDOWS_2000) >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
                    folders.add(recentFolder);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
                folders.add(desktop);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
                // Add all second level folders
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
                File[] secondLevelFolders = desktop.listFiles();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
                Arrays.sort(secondLevelFolders);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
                for (File secondLevelFolder : secondLevelFolders) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
                    Win32ShellFolder2 folder = (Win32ShellFolder2) secondLevelFolder;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
                    if (!folder.isFileSystem() || folder.isDirectory()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
                        folders.add(folder);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
                        // Add third level for "My Computer"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
                        if (folder.equals(drives)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
                            File[] thirdLevelFolders = folder.listFiles();
678
7d331a53a753 6571802: 'Shared Documents' listed in-between C,D drives in the JFileChooser, does not match with native
rupashka
parents: 454
diff changeset
   240
                            if (thirdLevelFolders != null && thirdLevelFolders.length > 0) {
7d331a53a753 6571802: 'Shared Documents' listed in-between C,D drives in the JFileChooser, does not match with native
rupashka
parents: 454
diff changeset
   241
                                List<File> thirdLevelFoldersList = Arrays.asList(thirdLevelFolders);
7d331a53a753 6571802: 'Shared Documents' listed in-between C,D drives in the JFileChooser, does not match with native
rupashka
parents: 454
diff changeset
   242
7d331a53a753 6571802: 'Shared Documents' listed in-between C,D drives in the JFileChooser, does not match with native
rupashka
parents: 454
diff changeset
   243
                                folder.sortChildren(thirdLevelFoldersList);
7d331a53a753 6571802: 'Shared Documents' listed in-between C,D drives in the JFileChooser, does not match with native
rupashka
parents: 454
diff changeset
   244
                                folders.addAll(thirdLevelFoldersList);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
                return folders.toArray(new File[folders.size()]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
                return super.get(key);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
        } else if (key.equals("fileChooserShortcutPanelFolders")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
            Toolkit toolkit = Toolkit.getDefaultToolkit();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
            ArrayList<File> folders = new ArrayList<File>();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
            int i = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
            Object value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
            do {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
                value = toolkit.getDesktopProperty("win.comdlg.placesBarPlace" + i++);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
                try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
                    if (value instanceof Integer) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
                        // A CSIDL
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
                        folders.add(new Win32ShellFolder2((Integer)value));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
                    } else if (value instanceof String) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
                        // A path
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
                        folders.add(createShellFolder(new File((String)value)));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
                } catch (IOException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
                    // Skip this value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
            } while (value != null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
            if (folders.size() == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
                // Use default list of places
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
                for (File f : new File[] {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
                    getRecent(), getDesktop(), getPersonal(), getDrives(), getNetwork()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
                }) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
                    if (f != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
                        folders.add(f);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
            return folders.toArray(new File[folders.size()]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
        } else if (key.startsWith("fileChooserIcon ")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
            int i = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
            String name = key.substring(key.indexOf(" ")+1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
                i = Integer.parseInt(name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
            } catch (NumberFormatException ex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
                if (name.equals("ListView")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
                    i = (useShell32Icons) ? 21 : 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
                } else if (name.equals("DetailsView")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
                    i = (useShell32Icons) ? 23 : 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
                } else if (name.equals("UpFolder")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
                    i = (useShell32Icons) ? 28 : 8;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
                } else if (name.equals("NewFolder")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
                    i = (useShell32Icons) ? 31 : 11;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
                } else if (name.equals("ViewMenu")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
                    i = (useShell32Icons) ? 21 : 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
            if (i >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
                return Win32ShellFolder2.getFileChooserIcon(i);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
        } else if (key.startsWith("optionPaneIcon ")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
            Win32ShellFolder2.SystemIcon iconType;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
            if (key == "optionPaneIcon Error") {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
                iconType = Win32ShellFolder2.SystemIcon.IDI_ERROR;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
            } else if (key == "optionPaneIcon Information") {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
                iconType = Win32ShellFolder2.SystemIcon.IDI_INFORMATION;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
            } else if (key == "optionPaneIcon Question") {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
                iconType = Win32ShellFolder2.SystemIcon.IDI_QUESTION;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
            } else if (key == "optionPaneIcon Warning") {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
                iconType = Win32ShellFolder2.SystemIcon.IDI_EXCLAMATION;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
                return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
            return Win32ShellFolder2.getSystemIcon(iconType);
454
2f4f4fef8880 6210674: FileChooser fails to load custom harddrive icon and gets NullPointerException
rupashka
parents: 2
diff changeset
   319
        } else if (key.startsWith("shell32Icon ") || key.startsWith("shell32LargeIcon ")) {
2f4f4fef8880 6210674: FileChooser fails to load custom harddrive icon and gets NullPointerException
rupashka
parents: 2
diff changeset
   320
            String name = key.substring(key.indexOf(" ") + 1);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
            try {
454
2f4f4fef8880 6210674: FileChooser fails to load custom harddrive icon and gets NullPointerException
rupashka
parents: 2
diff changeset
   322
                int i = Integer.parseInt(name);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
                if (i >= 0) {
454
2f4f4fef8880 6210674: FileChooser fails to load custom harddrive icon and gets NullPointerException
rupashka
parents: 2
diff changeset
   324
                    return Win32ShellFolder2.getShell32Icon(i, key.startsWith("shell32LargeIcon "));
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
            } catch (NumberFormatException ex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
        return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
     * Does <code>dir</code> represent a "computer" such as a node on the network, or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
     * "My Computer" on the desktop.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
    public boolean isComputerNode(File dir) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
        if (dir != null && dir == getDrives()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
            String path = dir.getAbsolutePath();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
            return (path.startsWith("\\\\") && path.indexOf("\\", 2) < 0);      //Network path
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
    public boolean isFileSystemRoot(File dir) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
        //Note: Removable drives don't "exist" but are listed in "My Computer"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
        if (dir != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
            Win32ShellFolder2 drives = getDrives();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
            if (dir instanceof Win32ShellFolder2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
                Win32ShellFolder2 sf = (Win32ShellFolder2)dir;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
                if (sf.isFileSystem()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
                    if (sf.parent != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
                        return sf.parent.equals(drives);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
                    // else fall through ...
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
                    return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
            String path = dir.getPath();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
            return (path.length() == 3
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
                    && path.charAt(1) == ':'
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
                    && Arrays.asList(drives.listFiles()).contains(dir));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
        return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
    private static List topFolderList = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
    static int compareShellFolders(Win32ShellFolder2 sf1, Win32ShellFolder2 sf2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
        boolean special1 = sf1.isSpecial();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
        boolean special2 = sf2.isSpecial();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
        if (special1 || special2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
            if (topFolderList == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
                ArrayList tmpTopFolderList = new ArrayList();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
                tmpTopFolderList.add(Win32ShellFolderManager2.getPersonal());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
                tmpTopFolderList.add(Win32ShellFolderManager2.getDesktop());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
                tmpTopFolderList.add(Win32ShellFolderManager2.getDrives());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
                tmpTopFolderList.add(Win32ShellFolderManager2.getNetwork());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
                topFolderList = tmpTopFolderList;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
            int i1 = topFolderList.indexOf(sf1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
            int i2 = topFolderList.indexOf(sf2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
            if (i1 >= 0 && i2 >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
                return (i1 - i2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
            } else if (i1 >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
                return -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
            } else if (i2 >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
                return 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
        // Non-file shellfolders sort before files
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
        if (special1 && !special2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
            return -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
        } else if (special2 && !special1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
            return  1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
        return compareNames(sf1.getAbsolutePath(), sf2.getAbsolutePath());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
    static int compareNames(String name1, String name2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
        // First ignore case when comparing
678
7d331a53a753 6571802: 'Shared Documents' listed in-between C,D drives in the JFileChooser, does not match with native
rupashka
parents: 454
diff changeset
   405
        int diff = name1.compareToIgnoreCase(name2);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
        if (diff != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
            return diff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
            // May differ in case (e.g. "mail" vs. "Mail")
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
            // We need this test for consistent sorting
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
            return name1.compareTo(name2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
    }
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   414
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   415
    @Override
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   416
    protected Invoker createInvoker() {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   417
        return new ComInvoker();
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   418
    }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   419
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   420
    private static class ComInvoker extends ThreadPoolExecutor implements ThreadFactory, ShellFolder.Invoker {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   421
        private static Thread comThread;
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   422
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   423
        private ComInvoker() {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   424
            super(1, 1, 0, TimeUnit.DAYS, new LinkedBlockingQueue<Runnable>());
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   425
            allowCoreThreadTimeOut(false);
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   426
            setThreadFactory(this);
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   427
            final Runnable shutdownHook = new Runnable() {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   428
                public void run() {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   429
                    AccessController.doPrivileged(new PrivilegedAction<Void>() {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   430
                        public Void run() {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   431
                            shutdownNow();
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   432
                            return null;
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   433
                        }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   434
                    });
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   435
                }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   436
            };
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   437
            AccessController.doPrivileged(new PrivilegedAction<Void>() {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   438
                public Void run() {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   439
                    Runtime.getRuntime().addShutdownHook(
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   440
                        new Thread(shutdownHook)
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   441
                    );
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   442
                    return null;
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   443
                }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   444
            });
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   445
        }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   446
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   447
        public synchronized Thread newThread(final Runnable task) {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   448
            final Runnable comRun = new Runnable() {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   449
                public void run() {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   450
                    try {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   451
                        initializeCom();
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   452
                        task.run();
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   453
                    } finally {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   454
                        uninitializeCom();
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   455
                    }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   456
                }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   457
            };
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   458
            comThread =
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   459
                AccessController.doPrivileged(
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   460
                    new PrivilegedAction<Thread>() {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   461
                        public Thread run() {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   462
                            /* The thread must be a member of a thread group
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   463
                             * which will not get GCed before VM exit.
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   464
                             * Make its parent the top-level thread group.
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   465
                             */
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   466
                            ThreadGroup tg = Thread.currentThread().getThreadGroup();
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   467
                            for (ThreadGroup tgn = tg;
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   468
                                 tgn != null;
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   469
                                 tg = tgn, tgn = tg.getParent());
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   470
                            Thread thread = new Thread(tg, comRun, "Swing-Shell");
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   471
                            thread.setDaemon(true);
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   472
                            return thread;
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   473
                        }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   474
                    }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   475
                );
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   476
            return comThread;
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   477
        }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   478
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   479
        public <T> T invoke(Callable<T> task) {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   480
            try {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   481
                if (Thread.currentThread() == comThread) {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   482
                    // if it's already called from the COM
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   483
                    // thread, we don't need to delegate the task
2817
f171f2417978 6713352: Deadlock in JFileChooser with synchronized custom FileSystemView
rupashka
parents: 2489
diff changeset
   484
                    return task.call();
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   485
                } else {
2817
f171f2417978 6713352: Deadlock in JFileChooser with synchronized custom FileSystemView
rupashka
parents: 2489
diff changeset
   486
                    while (true) {
f171f2417978 6713352: Deadlock in JFileChooser with synchronized custom FileSystemView
rupashka
parents: 2489
diff changeset
   487
                        Future<T> future = submit(task);
f171f2417978 6713352: Deadlock in JFileChooser with synchronized custom FileSystemView
rupashka
parents: 2489
diff changeset
   488
f171f2417978 6713352: Deadlock in JFileChooser with synchronized custom FileSystemView
rupashka
parents: 2489
diff changeset
   489
                        try {
f171f2417978 6713352: Deadlock in JFileChooser with synchronized custom FileSystemView
rupashka
parents: 2489
diff changeset
   490
                            return future.get();
f171f2417978 6713352: Deadlock in JFileChooser with synchronized custom FileSystemView
rupashka
parents: 2489
diff changeset
   491
                        } catch (InterruptedException e) {
f171f2417978 6713352: Deadlock in JFileChooser with synchronized custom FileSystemView
rupashka
parents: 2489
diff changeset
   492
                            // Repeat the attempt
f171f2417978 6713352: Deadlock in JFileChooser with synchronized custom FileSystemView
rupashka
parents: 2489
diff changeset
   493
                            future.cancel(true);
f171f2417978 6713352: Deadlock in JFileChooser with synchronized custom FileSystemView
rupashka
parents: 2489
diff changeset
   494
                        }
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   495
                    }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   496
                }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   497
            } catch (Exception e) {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   498
                Throwable cause = (e instanceof ExecutionException) ? e.getCause() : e;
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   499
                if (cause instanceof RuntimeException) {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   500
                    throw (RuntimeException) cause;
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   501
                }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   502
                if (cause instanceof Error) {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   503
                    throw (Error) cause;
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   504
                }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   505
                throw new RuntimeException(cause);
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   506
            }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   507
        }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   508
    }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   509
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   510
    static native void initializeCom();
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   511
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   512
    static native void uninitializeCom();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
}