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+
26+package sun.awt.shell;
27+
28+import javax.swing.*;
29+import java.awt.Image;
30+import java.awt.Toolkit;
31+import java.io.*;
32+import java.io.FileNotFoundException;
33+import java.util.*;
34+import java.util.concurrent.Callable;
35+
36+/**
37+ * @author Michael Martak
38+ * @since 1.4
39+ */
40+
41+public 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+}