1 /* 2 * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.awt.shell; 27 28 import java.awt.*; 29 import java.awt.image.BufferedImage; 30 import java.awt.image.BaseMultiResolutionImage; 31 32 import java.io.File; 33 import java.io.FileNotFoundException; 34 import java.io.IOException; 35 import java.security.AccessController; 36 import java.security.PrivilegedAction; 37 import java.util.*; 38 import java.util.List; 39 import java.util.concurrent.*; 40 import java.util.stream.Stream; 41 42 import static sun.awt.shell.Win32ShellFolder2.*; 43 import sun.awt.OSInfo; 44 import sun.awt.util.ThreadGroupUtils; 45 // NOTE: This class supersedes Win32ShellFolderManager, which was removed 46 // from distribution after version 1.4.2. 47 48 /** 49 * @author Michael Martak 50 * @author Leif Samuelsson 51 * @author Kenneth Russell 52 * @since 1.4 53 */ 54 55 final class Win32ShellFolderManager2 extends ShellFolderManager { 56 57 static { 58 // Load library here 59 sun.awt.windows.WToolkit.loadLibraries(); 60 } 61 62 public ShellFolder createShellFolder(File file) throws FileNotFoundException { 63 try { 64 return createShellFolder(getDesktop(), file); 65 } catch (InterruptedException e) { 66 throw new FileNotFoundException("Execution was interrupted"); 67 } 68 } 69 70 static Win32ShellFolder2 createShellFolder(Win32ShellFolder2 parent, File file) 71 throws FileNotFoundException, InterruptedException { 72 long pIDL; 73 try { 74 pIDL = parent.parseDisplayName(file.getCanonicalPath()); 75 } catch (IOException ex) { 76 pIDL = 0; 128 129 STANDARD_VIEW_BUTTONS[iconIndex] = (size == 16) 130 ? img 131 : new MultiResolutionIconImage(16, img); 132 } 133 134 return STANDARD_VIEW_BUTTONS[iconIndex]; 135 } 136 137 // Special folders 138 private static Win32ShellFolder2 desktop; 139 private static Win32ShellFolder2 drives; 140 private static Win32ShellFolder2 recent; 141 private static Win32ShellFolder2 network; 142 private static Win32ShellFolder2 personal; 143 144 static Win32ShellFolder2 getDesktop() { 145 if (desktop == null) { 146 try { 147 desktop = new Win32ShellFolder2(DESKTOP); 148 } catch (SecurityException e) { 149 // Ignore error 150 } catch (IOException e) { 151 // Ignore error 152 } catch (InterruptedException e) { 153 // Ignore error 154 } 155 } 156 return desktop; 157 } 158 159 static Win32ShellFolder2 getDrives() { 160 if (drives == null) { 161 try { 162 drives = new Win32ShellFolder2(DRIVES); 163 } catch (SecurityException e) { 164 // Ignore error 165 } catch (IOException e) { 166 // Ignore error 167 } catch (InterruptedException e) { 168 // Ignore error 169 } 170 } 171 return drives; 172 } 173 174 static Win32ShellFolder2 getRecent() { 175 if (recent == null) { 176 try { 177 String path = Win32ShellFolder2.getFileSystemPath(RECENT); 178 if (path != null) { 179 recent = createShellFolder(getDesktop(), new File(path)); 180 } 181 } catch (SecurityException e) { 182 // Ignore error 183 } catch (InterruptedException e) { 184 // Ignore error 185 } catch (IOException e) { 186 // Ignore error 187 } 188 } 189 return recent; 190 } 191 192 static Win32ShellFolder2 getNetwork() { 193 if (network == null) { 194 try { 195 network = new Win32ShellFolder2(NETWORK); 196 } catch (SecurityException e) { 197 // Ignore error 198 } catch (IOException e) { 199 // Ignore error 200 } catch (InterruptedException e) { 201 // Ignore error 202 } 203 } 204 return network; 205 } 206 207 static Win32ShellFolder2 getPersonal() { 208 if (personal == null) { 209 try { 210 String path = Win32ShellFolder2.getFileSystemPath(PERSONAL); 211 if (path != null) { 212 Win32ShellFolder2 desktop = getDesktop(); 213 personal = desktop.getChildByPath(path); 214 if (personal == null) { 215 personal = createShellFolder(getDesktop(), new File(path)); 216 } 217 if (personal != null) { 218 personal.setIsPersonal(); 219 } 220 } 221 } catch (SecurityException e) { 222 // Ignore error 223 } catch (InterruptedException e) { 224 // Ignore error 225 } catch (IOException e) { 226 // Ignore error 227 } 228 } 229 return personal; 230 } 231 232 233 private static File[] roots; 234 235 /** 236 * @param key a {@code String} 237 * "fileChooserDefaultFolder": 238 * Returns a {@code File} - the default shellfolder for a new filechooser 239 * "roots": 240 * Returns a {@code File[]} - containing the root(s) of the displayable hierarchy 241 * "fileChooserComboBoxFolders": 242 * Returns a {@code File[]} - an array of shellfolders representing the list to 243 * show by default in the file chooser's combobox 244 * "fileChooserShortcutPanelFolders": 245 * Returns a {@code File[]} - an array of shellfolders representing well-known 246 * folders, such as Desktop, Documents, History, Network, Home, etc. 307 return checkFiles(folders); 308 } else { 309 return super.get(key); 310 } 311 } else if (key.equals("fileChooserShortcutPanelFolders")) { 312 Toolkit toolkit = Toolkit.getDefaultToolkit(); 313 ArrayList<File> folders = new ArrayList<File>(); 314 int i = 0; 315 Object value; 316 do { 317 value = toolkit.getDesktopProperty("win.comdlg.placesBarPlace" + i++); 318 try { 319 if (value instanceof Integer) { 320 // A CSIDL 321 folders.add(new Win32ShellFolder2((Integer)value)); 322 } else if (value instanceof String) { 323 // A path 324 folders.add(createShellFolder(new File((String)value))); 325 } 326 } catch (IOException e) { 327 // Skip this value 328 } catch (InterruptedException e) { 329 // Return empty result 330 return new File[0]; 331 } 332 } while (value != null); 333 334 if (folders.size() == 0) { 335 // Use default list of places 336 for (File f : new File[] { 337 getRecent(), getDesktop(), getPersonal(), getDrives(), getNetwork() 338 }) { 339 if (f != null) { 340 folders.add(f); 341 } 342 } 343 } 344 return checkFiles(folders); 345 } else if (key.startsWith("fileChooserIcon ")) { 346 String name = key.substring(key.indexOf(" ") + 1); 347 348 int iconIndex; | 1 /* 2 * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.awt.shell; 27 28 import java.awt.Image; 29 import java.awt.Toolkit; 30 import java.awt.image.BufferedImage; 31 import java.io.File; 32 import java.io.FileNotFoundException; 33 import java.io.IOException; 34 import java.security.AccessController; 35 import java.security.PrivilegedAction; 36 import java.util.ArrayList; 37 import java.util.Arrays; 38 import java.util.List; 39 import java.util.concurrent.Callable; 40 import java.util.concurrent.ExecutionException; 41 import java.util.concurrent.Future; 42 import java.util.concurrent.LinkedBlockingQueue; 43 import java.util.concurrent.RejectedExecutionException; 44 import java.util.concurrent.ThreadFactory; 45 import java.util.concurrent.ThreadPoolExecutor; 46 import java.util.concurrent.TimeUnit; 47 import java.util.stream.Stream; 48 49 import sun.awt.OSInfo; 50 import sun.awt.util.ThreadGroupUtils; 51 import sun.util.logging.PlatformLogger; 52 53 import static sun.awt.shell.Win32ShellFolder2.DESKTOP; 54 import static sun.awt.shell.Win32ShellFolder2.DRIVES; 55 import static sun.awt.shell.Win32ShellFolder2.Invoker; 56 import static sun.awt.shell.Win32ShellFolder2.MultiResolutionIconImage; 57 import static sun.awt.shell.Win32ShellFolder2.NETWORK; 58 import static sun.awt.shell.Win32ShellFolder2.PERSONAL; 59 import static sun.awt.shell.Win32ShellFolder2.RECENT; 60 // NOTE: This class supersedes Win32ShellFolderManager, which was removed 61 // from distribution after version 1.4.2. 62 63 /** 64 * @author Michael Martak 65 * @author Leif Samuelsson 66 * @author Kenneth Russell 67 * @since 1.4 68 */ 69 70 final class Win32ShellFolderManager2 extends ShellFolderManager { 71 72 private static final PlatformLogger 73 log = PlatformLogger.getLogger("sun.awt.shell.Win32ShellFolderManager2"); 74 75 static { 76 // Load library here 77 sun.awt.windows.WToolkit.loadLibraries(); 78 } 79 80 public ShellFolder createShellFolder(File file) throws FileNotFoundException { 81 try { 82 return createShellFolder(getDesktop(), file); 83 } catch (InterruptedException e) { 84 throw new FileNotFoundException("Execution was interrupted"); 85 } 86 } 87 88 static Win32ShellFolder2 createShellFolder(Win32ShellFolder2 parent, File file) 89 throws FileNotFoundException, InterruptedException { 90 long pIDL; 91 try { 92 pIDL = parent.parseDisplayName(file.getCanonicalPath()); 93 } catch (IOException ex) { 94 pIDL = 0; 146 147 STANDARD_VIEW_BUTTONS[iconIndex] = (size == 16) 148 ? img 149 : new MultiResolutionIconImage(16, img); 150 } 151 152 return STANDARD_VIEW_BUTTONS[iconIndex]; 153 } 154 155 // Special folders 156 private static Win32ShellFolder2 desktop; 157 private static Win32ShellFolder2 drives; 158 private static Win32ShellFolder2 recent; 159 private static Win32ShellFolder2 network; 160 private static Win32ShellFolder2 personal; 161 162 static Win32ShellFolder2 getDesktop() { 163 if (desktop == null) { 164 try { 165 desktop = new Win32ShellFolder2(DESKTOP); 166 } catch (final SecurityException ignored) { 167 // Ignore, the message may have sensitive information, not 168 // accessible other ways 169 } catch (IOException | InterruptedException e) { 170 if (log.isLoggable(PlatformLogger.Level.WARNING)) { 171 log.warning("Cannot access 'Desktop'", e); 172 } 173 } 174 } 175 return desktop; 176 } 177 178 static Win32ShellFolder2 getDrives() { 179 if (drives == null) { 180 try { 181 drives = new Win32ShellFolder2(DRIVES); 182 } catch (final SecurityException ignored) { 183 // Ignore, the message may have sensitive information, not 184 // accessible other ways 185 } catch (IOException | InterruptedException e) { 186 if (log.isLoggable(PlatformLogger.Level.WARNING)) { 187 log.warning("Cannot access 'Drives'", e); 188 } 189 } 190 } 191 return drives; 192 } 193 194 static Win32ShellFolder2 getRecent() { 195 if (recent == null) { 196 try { 197 String path = Win32ShellFolder2.getFileSystemPath(RECENT); 198 if (path != null) { 199 recent = createShellFolder(getDesktop(), new File(path)); 200 } 201 } catch (final SecurityException ignored) { 202 // Ignore, the message may have sensitive information, not 203 // accessible other ways 204 } catch (InterruptedException | IOException e) { 205 if (log.isLoggable(PlatformLogger.Level.WARNING)) { 206 log.warning("Cannot access 'Recent'", e); 207 } 208 } 209 } 210 return recent; 211 } 212 213 static Win32ShellFolder2 getNetwork() { 214 if (network == null) { 215 try { 216 network = new Win32ShellFolder2(NETWORK); 217 } catch (final SecurityException ignored) { 218 // Ignore, the message may have sensitive information, not 219 // accessible other ways 220 } catch (IOException | InterruptedException e) { 221 if (log.isLoggable(PlatformLogger.Level.WARNING)) { 222 log.warning("Cannot access 'Network'", e); 223 } 224 } 225 } 226 return network; 227 } 228 229 static Win32ShellFolder2 getPersonal() { 230 if (personal == null) { 231 try { 232 String path = Win32ShellFolder2.getFileSystemPath(PERSONAL); 233 if (path != null) { 234 Win32ShellFolder2 desktop = getDesktop(); 235 personal = desktop.getChildByPath(path); 236 if (personal == null) { 237 personal = createShellFolder(getDesktop(), new File(path)); 238 } 239 if (personal != null) { 240 personal.setIsPersonal(); 241 } 242 } 243 } catch (final SecurityException ignored) { 244 // Ignore, the message may have sensitive information, not 245 // accessible other ways 246 } catch (InterruptedException | IOException e) { 247 if (log.isLoggable(PlatformLogger.Level.WARNING)) { 248 log.warning("Cannot access 'Personal'", e); 249 } 250 } 251 } 252 return personal; 253 } 254 255 256 private static File[] roots; 257 258 /** 259 * @param key a {@code String} 260 * "fileChooserDefaultFolder": 261 * Returns a {@code File} - the default shellfolder for a new filechooser 262 * "roots": 263 * Returns a {@code File[]} - containing the root(s) of the displayable hierarchy 264 * "fileChooserComboBoxFolders": 265 * Returns a {@code File[]} - an array of shellfolders representing the list to 266 * show by default in the file chooser's combobox 267 * "fileChooserShortcutPanelFolders": 268 * Returns a {@code File[]} - an array of shellfolders representing well-known 269 * folders, such as Desktop, Documents, History, Network, Home, etc. 330 return checkFiles(folders); 331 } else { 332 return super.get(key); 333 } 334 } else if (key.equals("fileChooserShortcutPanelFolders")) { 335 Toolkit toolkit = Toolkit.getDefaultToolkit(); 336 ArrayList<File> folders = new ArrayList<File>(); 337 int i = 0; 338 Object value; 339 do { 340 value = toolkit.getDesktopProperty("win.comdlg.placesBarPlace" + i++); 341 try { 342 if (value instanceof Integer) { 343 // A CSIDL 344 folders.add(new Win32ShellFolder2((Integer)value)); 345 } else if (value instanceof String) { 346 // A path 347 folders.add(createShellFolder(new File((String)value))); 348 } 349 } catch (IOException e) { 350 if (log.isLoggable(PlatformLogger.Level.WARNING)) { 351 log.warning("Cannot read value = " + value, e); 352 } 353 // Skip this value 354 } catch (InterruptedException e) { 355 if (log.isLoggable(PlatformLogger.Level.WARNING)) { 356 log.warning("Cannot read value = " + value, e); 357 } 358 // Return empty result 359 return new File[0]; 360 } 361 } while (value != null); 362 363 if (folders.size() == 0) { 364 // Use default list of places 365 for (File f : new File[] { 366 getRecent(), getDesktop(), getPersonal(), getDrives(), getNetwork() 367 }) { 368 if (f != null) { 369 folders.add(f); 370 } 371 } 372 } 373 return checkFiles(folders); 374 } else if (key.startsWith("fileChooserIcon ")) { 375 String name = key.substring(key.indexOf(" ") + 1); 376 377 int iconIndex; |