History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/awt/shell/ShellFolder.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/awt/shell/ShellFolder.java+615−0
@@ -0,0 +1,615 @@
1/*
2 * Copyright (c) 2000, 2009, 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
26package sun.awt.shell;
27
28import javax.swing.*;
29import java.awt.Image;
30import java.awt.Toolkit;
31import java.io.*;
32import java.io.FileNotFoundException;
33import java.util.*;
34import java.util.concurrent.Callable;
35
36/**
37 * @author Michael Martak
38 * @since 1.4
39 */
40
41public abstract class ShellFolder extends File {
42 private static final String COLUMN_NAME = "FileChooser.fileNameHeaderText";
43 private static final String COLUMN_SIZE = "FileChooser.fileSizeHeaderText";
44 private static final String COLUMN_DATE = "FileChooser.fileDateHeaderText";
45
46 protected ShellFolder parent;
47
48 /**
49 * Create a file system shell folder from a file
50 */
51 ShellFolder(ShellFolder parent, String pathname) {
52 super((pathname != null) ? pathname : "ShellFolder");
53 this.parent = parent;
54 }
55
56 /**
57 * @return Whether this is a file system shell folder
58 */
59 public boolean isFileSystem() {
60 return (!getPath().startsWith("ShellFolder"));
61 }
62
63 /**
64 * This method must be implemented to make sure that no instances
65 * of <code>ShellFolder</code> are ever serialized. If <code>isFileSystem()</code> returns
66 * <code>true</code>, then the object should be representable with an instance of
67 * <code>java.io.File</code> instead. If not, then the object is most likely
68 * depending on some internal (native) state and cannot be serialized.
69 *
70 * @returns a <code>java.io.File</code> replacement object, or <code>null</code>
71 * if no suitable replacement can be found.
72 */
73 protected abstract Object writeReplace() throws java.io.ObjectStreamException;
74
75 /**
76 * Returns the path for this object's parent,
77 * or <code>null</code> if this object does not name a parent
78 * folder.
79 *
80 * @return the path as a String for this object's parent,
81 * or <code>null</code> if this object does not name a parent
82 * folder
83 *
84 * @see java.io.File#getParent()
85 * @since 1.4
86 */
87 public String getParent() {
88 if (parent == null && isFileSystem()) {
89 return super.getParent();
90 }
91 if (parent != null) {
92 return (parent.getPath());
93 } else {
94 return null;
95 }
96 }
97
98 /**
99 * Returns a File object representing this object's parent,
100 * or <code>null</code> if this object does not name a parent
101 * folder.
102 *
103 * @return a File object representing this object's parent,
104 * or <code>null</code> if this object does not name a parent
105 * folder
106 *
107 * @see java.io.File#getParentFile()
108 * @since 1.4
109 */
110 public File getParentFile() {
111 if (parent != null) {
112 return parent;
113 } else if (isFileSystem()) {
114 return super.getParentFile();
115 } else {
116 return null;
117 }
118 }
119
120 public File[] listFiles() {
121 return listFiles(true);
122 }
123
124 public File[] listFiles(boolean includeHiddenFiles) {
125 File[] files = super.listFiles();
126
127 if (!includeHiddenFiles) {
128 Vector v = new Vector();
129 int nameCount = (files == null) ? 0 : files.length;
130 for (int i = 0; i < nameCount; i++) {
131 if (!files[i].isHidden()) {
132 v.addElement(files[i]);
133 }
134 }
135 files = (File[])v.toArray(new File[v.size()]);
136 }
137
138 return files;
139 }
140
141
142 /**
143 * @return Whether this shell folder is a link
144 */
145 public abstract boolean isLink();
146
147 /**
148 * @return The shell folder linked to by this shell folder, or null
149 * if this shell folder is not a link
150 */
151 public abstract ShellFolder getLinkLocation() throws FileNotFoundException;
152
153 /**
154 * @return The name used to display this shell folder
155 */
156 public abstract String getDisplayName();
157
158 /**
159 * @return The type of shell folder as a string
160 */
161 public abstract String getFolderType();
162
163 /**
164 * @return The executable type as a string
165 */
166 public abstract String getExecutableType();
167
168 /**
169 * Compares this ShellFolder with the specified ShellFolder for order.
170 *
171 * @see #compareTo(Object)
172 */
173 public int compareTo(File file2) {
174 if (file2 == null || !(file2 instanceof ShellFolder)
175 || ((file2 instanceof ShellFolder) && ((ShellFolder)file2).isFileSystem())) {
176
177 if (isFileSystem()) {
178 return super.compareTo(file2);
179 } else {
180 return -1;
181 }
182 } else {
183 if (isFileSystem()) {
184 return 1;
185 } else {
186 return getName().compareTo(file2.getName());
187 }
188 }
189 }
190
191 /**
192 * @param getLargeIcon whether to return large icon (ignored in base implementation)
193 * @return The icon used to display this shell folder
194 */
195 public Image getIcon(boolean getLargeIcon) {
196 return null;
197 }
198
199
200 // Static
201
202 private static ShellFolderManager shellFolderManager;
203
204 private static Invoker invoker;
205
206 static {
207 String managerClassName = (String)Toolkit.getDefaultToolkit().
208 getDesktopProperty("Shell.shellFolderManager");
209 Class managerClass = null;
210 try {
211 managerClass = Class.forName(managerClassName);
212 // swallow the exceptions below and use default shell folder
213 } catch(ClassNotFoundException e) {
214 } catch(NullPointerException e) {
215 }
216
217 if (managerClass == null) {
218 managerClass = ShellFolderManager.class;
219 }
220 try {
221 shellFolderManager =
222 (ShellFolderManager)managerClass.newInstance();
223 } catch (InstantiationException e) {
224 throw new Error("Could not instantiate Shell Folder Manager: "
225 + managerClass.getName());
226 } catch (IllegalAccessException e) {
227 throw new Error ("Could not access Shell Folder Manager: "
228 + managerClass.getName());
229 }
230
231 invoker = shellFolderManager.createInvoker();
232 }
233
234 /**
235 * Return a shell folder from a file object
236 * @exception FileNotFoundException if file does not exist
237 */
238 public static ShellFolder getShellFolder(File file) throws FileNotFoundException {
239 if (file instanceof ShellFolder) {
240 return (ShellFolder)file;
241 }
242 if (!file.exists()) {
243 throw new FileNotFoundException();
244 }
245 return shellFolderManager.createShellFolder(file);
246 }
247
248 /**
249 * @param key a <code>String</code>
250 * @return An Object matching the string <code>key</code>.
251 * @see ShellFolderManager#get(String)
252 */
253 public static Object get(String key) {
254 return shellFolderManager.get(key);
255 }
256
257 /**
258 * Does <code>dir</code> represent a "computer" such as a node on the network, or
259 * "My Computer" on the desktop.
260 */
261 public static boolean isComputerNode(File dir) {
262 return shellFolderManager.isComputerNode(dir);
263 }
264
265 /**
266 * @return Whether this is a file system root directory
267 */
268 public static boolean isFileSystemRoot(File dir) {
269 return shellFolderManager.isFileSystemRoot(dir);
270 }
271
272 /**
273 * Canonicalizes files that don't have symbolic links in their path.
274 * Normalizes files that do, preserving symbolic links from being resolved.
275 */
276 public static File getNormalizedFile(File f) throws IOException {
277 File canonical = f.getCanonicalFile();
278 if (f.equals(canonical)) {
279 // path of f doesn't contain symbolic links
280 return canonical;
281 }
282
283 // preserve symbolic links from being resolved
284 return new File(f.toURI().normalize());
285 }
286
287 // Override File methods
288
289 public static void sort(final List<? extends File> files) {
290 if (files == null || files.size() <= 1) {
291 return;
292 }
293
294 // To avoid loads of synchronizations with Invoker and improve performance we
295 // synchronize the whole code of the sort method once
296 invoke(new Callable<Void>() {
297 public Void call() {
298 // Check that we can use the ShellFolder.sortChildren() method:
299 // 1. All files have the same non-null parent
300 // 2. All files is ShellFolders
301 File commonParent = null;
302
303 for (File file : files) {
304 File parent = file.getParentFile();
305
306 if (parent == null || !(file instanceof ShellFolder)) {
307 commonParent = null;
308
309 break;
310 }
311
312 if (commonParent == null) {
313 commonParent = parent;
314 } else {
315 if (commonParent != parent && !commonParent.equals(parent)) {
316 commonParent = null;
317
318 break;
319 }
320 }
321 }
322
323 if (commonParent instanceof ShellFolder) {
324 ((ShellFolder) commonParent).sortChildren(files);
325 } else {
326 Collections.sort(files, FILE_COMPARATOR);
327 }
328
329 return null;
330 }
331 });
332 }
333
334 public void sortChildren(final List<? extends File> files) {
335 // To avoid loads of synchronizations with Invoker and improve performance we
336 // synchronize the whole code of the sort method once
337 invoke(new Callable<Void>() {
338 public Void call() {
339 Collections.sort(files, FILE_COMPARATOR);
340
341 return null;
342 }
343 });
344 }
345
346 public boolean isAbsolute() {
347 return (!isFileSystem() || super.isAbsolute());
348 }
349
350 public File getAbsoluteFile() {
351 return (isFileSystem() ? super.getAbsoluteFile() : this);
352 }
353
354 public boolean canRead() {
355 return (isFileSystem() ? super.canRead() : true); // ((Fix?))
356 }
357
358 /**
359 * Returns true if folder allows creation of children.
360 * True for the "Desktop" folder, but false for the "My Computer"
361 * folder.
362 */
363 public boolean canWrite() {
364 return (isFileSystem() ? super.canWrite() : false); // ((Fix?))
365 }
366
367 public boolean exists() {
368 // Assume top-level drives exist, because state is uncertain for
369 // removable drives.
370 return (!isFileSystem() || isFileSystemRoot(this) || super.exists()) ;
371 }
372
373 public boolean isDirectory() {
374 return (isFileSystem() ? super.isDirectory() : true); // ((Fix?))
375 }
376
377 public boolean isFile() {
378 return (isFileSystem() ? super.isFile() : !isDirectory()); // ((Fix?))
379 }
380
381 public long lastModified() {
382 return (isFileSystem() ? super.lastModified() : 0L); // ((Fix?))
383 }
384
385 public long length() {
386 return (isFileSystem() ? super.length() : 0L); // ((Fix?))
387 }
388
389 public boolean createNewFile() throws IOException {
390 return (isFileSystem() ? super.createNewFile() : false);
391 }
392
393 public boolean delete() {
394 return (isFileSystem() ? super.delete() : false); // ((Fix?))
395 }
396
397 public void deleteOnExit() {
398 if (isFileSystem()) {
399 super.deleteOnExit();
400 } else {
401 // Do nothing // ((Fix?))
402 }
403 }
404
405 public boolean mkdir() {
406 return (isFileSystem() ? super.mkdir() : false);
407 }
408
409 public boolean mkdirs() {
410 return (isFileSystem() ? super.mkdirs() : false);
411 }
412
413 public boolean renameTo(File dest) {
414 return (isFileSystem() ? super.renameTo(dest) : false); // ((Fix?))
415 }
416
417 public boolean setLastModified(long time) {
418 return (isFileSystem() ? super.setLastModified(time) : false); // ((Fix?))
419 }
420
421 public boolean setReadOnly() {
422 return (isFileSystem() ? super.setReadOnly() : false); // ((Fix?))
423 }
424
425 public String toString() {
426 return (isFileSystem() ? super.toString() : getDisplayName());
427 }
428
429 public static ShellFolderColumnInfo[] getFolderColumns(File dir) {
430 ShellFolderColumnInfo[] columns = null;
431
432 if (dir instanceof ShellFolder) {
433 columns = ((ShellFolder) dir).getFolderColumns();
434 }
435
436 if (columns == null) {
437 columns = new ShellFolderColumnInfo[]{
438 new ShellFolderColumnInfo(COLUMN_NAME, 150,
439 SwingConstants.LEADING, true, null,
440 FILE_COMPARATOR),
441 new ShellFolderColumnInfo(COLUMN_SIZE, 75,
442 SwingConstants.RIGHT, true, null,
443 DEFAULT_COMPARATOR, true),
444 new ShellFolderColumnInfo(COLUMN_DATE, 130,
445 SwingConstants.LEADING, true, null,
446 DEFAULT_COMPARATOR, true)
447 };
448 }
449
450 return columns;
451 }
452
453 public ShellFolderColumnInfo[] getFolderColumns() {
454 return null;
455 }
456
457 public static Object getFolderColumnValue(File file, int column) {
458 if (file instanceof ShellFolder) {
459 Object value = ((ShellFolder)file).getFolderColumnValue(column);
460 if (value != null) {
461 return value;
462 }
463 }
464
465 if (file == null || !file.exists()) {
466 return null;
467 }
468
469 switch (column) {
470 case 0:
471 // By default, file name will be rendered using getSystemDisplayName()
472 return file;
473
474 case 1: // size
475 return file.isDirectory() ? null : Long.valueOf(file.length());
476
477 case 2: // date
478 if (isFileSystemRoot(file)) {
479 return null;
480 }
481 long time = file.lastModified();
482 return (time == 0L) ? null : new Date(time);
483
484 default:
485 return null;
486 }
487 }
488
489 public Object getFolderColumnValue(int column) {
490 return null;
491 }
492
493 /**
494 * Invokes the {@code task} which doesn't throw checked exceptions
495 * from its {@code call} method. If invokation is interrupted then Thread.currentThread().isInterrupted() will
496 * be set and result will be {@code null}
497 */
498 public static <T> T invoke(Callable<T> task) {
499 try {
500 return invoke(task, RuntimeException.class);
501 } catch (InterruptedException e) {
502 return null;
503 }
504 }
505
506 /**
507 * Invokes the {@code task} which throws checked exceptions from its {@code call} method.
508 * If invokation is interrupted then Thread.currentThread().isInterrupted() will
509 * be set and InterruptedException will be thrown as well.
510 */
511 public static <T, E extends Throwable> T invoke(Callable<T> task, Class<E> exceptionClass)
512 throws InterruptedException, E {
513 try {
514 return invoker.invoke(task);
515 } catch (Exception e) {
516 if (e instanceof RuntimeException) {
517 // Rethrow unchecked exceptions
518 throw (RuntimeException) e;
519 }
520
521 if (e instanceof InterruptedException) {
522 // Set isInterrupted flag for current thread
523 Thread.currentThread().interrupt();
524
525 // Rethrow InterruptedException
526 throw (InterruptedException) e;
527 }
528
529 if (exceptionClass.isInstance(e)) {
530 throw exceptionClass.cast(e);
531 }
532
533 throw new RuntimeException("Unexpected error", e);
534 }
535 }
536
537 /**
538 * Interface allowing to invoke tasks in different environments on different platforms.
539 */
540 public static interface Invoker {
541 /**
542 * Invokes a callable task.
543 *
544 * @param task a task to invoke
545 * @throws Exception {@code InterruptedException} or an exception that was thrown from the {@code task}
546 * @return the result of {@code task}'s invokation
547 */
548 <T> T invoke(Callable<T> task) throws Exception;
549 }
550
551 /**
552 * Provides a default comparator for the default column set
553 */
554 private static final Comparator DEFAULT_COMPARATOR = new Comparator() {
555 public int compare(Object o1, Object o2) {
556 int gt;
557
558 if (o1 == null && o2 == null) {
559 gt = 0;
560 } else if (o1 != null && o2 == null) {
561 gt = 1;
562 } else if (o1 == null && o2 != null) {
563 gt = -1;
564 } else if (o1 instanceof Comparable) {
565 gt = ((Comparable) o1).compareTo(o2);
566 } else {
567 gt = 0;
568 }
569
570 return gt;
571 }
572 };
573
574 private static final Comparator<File> FILE_COMPARATOR = new Comparator<File>() {
575 public int compare(File f1, File f2) {
576 ShellFolder sf1 = null;
577 ShellFolder sf2 = null;
578
579 if (f1 instanceof ShellFolder) {
580 sf1 = (ShellFolder) f1;
581 if (sf1.isFileSystem()) {
582 sf1 = null;
583 }
584 }
585 if (f2 instanceof ShellFolder) {
586 sf2 = (ShellFolder) f2;
587 if (sf2.isFileSystem()) {
588 sf2 = null;
589 }
590 }
591
592 if (sf1 != null && sf2 != null) {
593 return sf1.compareTo(sf2);
594 } else if (sf1 != null) {
595 // Non-file shellfolders sort before files
596 return -1;
597 } else if (sf2 != null) {
598 return 1;
599 } else {
600 String name1 = f1.getName();
601 String name2 = f2.getName();
602
603 // First ignore case when comparing
604 int diff = name1.compareToIgnoreCase(name2);
605 if (diff != 0) {
606 return diff;
607 } else {
608 // May differ in case (e.g. "mail" vs. "Mail")
609 // We need this test for consistent sorting
610 return name1.compareTo(name2);
611 }
612 }
613 }
614 };
615}