Source Code Cross Referenced for Win32ShellFolder2.java in  » 6.0-JDK-Platform » windows » sun » awt » shell » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Platform » windows » sun.awt.shell 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
0003:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004:         *
0005:         * This code is free software; you can redistribute it and/or modify it
0006:         * under the terms of the GNU General Public License version 2 only, as
0007:         * published by the Free Software Foundation.  Sun designates this
0008:         * particular file as subject to the "Classpath" exception as provided
0009:         * by Sun in the LICENSE file that accompanied this code.
0010:         *
0011:         * This code is distributed in the hope that it will be useful, but WITHOUT
0012:         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013:         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0014:         * version 2 for more details (a copy is included in the LICENSE file that
0015:         * accompanied this code).
0016:         *
0017:         * You should have received a copy of the GNU General Public License version
0018:         * 2 along with this work; if not, write to the Free Software Foundation,
0019:         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020:         *
0021:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022:         * CA 95054 USA or visit www.sun.com if you need additional information or
0023:         * have any questions.
0024:         */
0025:
0026:        package sun.awt.shell;
0027:
0028:        import java.awt.Image;
0029:        import java.awt.Toolkit;
0030:        import java.awt.image.BufferedImage;
0031:        import java.io.File;
0032:        import java.io.FileNotFoundException;
0033:        import java.io.IOException;
0034:        import java.util.*;
0035:        import javax.swing.SwingConstants;
0036:
0037:        // NOTE: This class supersedes Win32ShellFolder, which was removed from
0038:        //       distribution after version 1.4.2. 
0039:
0040:        /**
0041:         * Win32 Shell Folders
0042:         * <P>
0043:         * <BR>
0044:         * There are two fundamental types of shell folders : file system folders
0045:         * and non-file system folders.  File system folders are relatively easy
0046:         * to deal with.  Non-file system folders are items such as My Computer,
0047:         * Network Neighborhood, and the desktop.  Some of these non-file system
0048:         * folders have special values and properties.
0049:         * <P>
0050:         * <BR>
0051:         * Win32 keeps two basic data structures for shell folders.  The first
0052:         * of these is called an ITEMIDLIST.  Usually a pointer, called an
0053:         * LPITEMIDLIST, or more frequently just "PIDL".  This structure holds
0054:         * a series of identifiers and can be either relative to the desktop
0055:         * (an absolute PIDL), or relative to the shell folder that contains them.
0056:         * Some Win32 functions can take absolute or relative PIDL values, and
0057:         * others can only accept relative values.
0058:         * <BR>
0059:         * The second data structure is an IShellFolder COM interface.  Using
0060:         * this interface, one can enumerate the relative PIDLs in a shell
0061:         * folder, get attributes, etc.
0062:         * <BR>
0063:         * All Win32ShellFolder2 objects which are folder types (even non-file
0064:         * system folders) contain an IShellFolder object. Files are named in
0065:         * directories via relative PIDLs.
0066:         *
0067:         * @author Michael Martak
0068:         * @author Leif Samuelsson
0069:         * @author Kenneth Russell
0070:         * @since 1.4 */
0071:
0072:        final class Win32ShellFolder2 extends ShellFolder {
0073:
0074:            private static native void initIDs();
0075:
0076:            private static final boolean is98;
0077:
0078:            static {
0079:                String osName = System.getProperty("os.name");
0080:                is98 = (osName != null && osName.startsWith("Windows 98"));
0081:
0082:                initIDs();
0083:            }
0084:
0085:            // Win32 Shell Folder Constants
0086:            public static final int DESKTOP = 0x0000;
0087:            public static final int INTERNET = 0x0001;
0088:            public static final int PROGRAMS = 0x0002;
0089:            public static final int CONTROLS = 0x0003;
0090:            public static final int PRINTERS = 0x0004;
0091:            public static final int PERSONAL = 0x0005;
0092:            public static final int FAVORITES = 0x0006;
0093:            public static final int STARTUP = 0x0007;
0094:            public static final int RECENT = 0x0008;
0095:            public static final int SENDTO = 0x0009;
0096:            public static final int BITBUCKET = 0x000a;
0097:            public static final int STARTMENU = 0x000b;
0098:            public static final int DESKTOPDIRECTORY = 0x0010;
0099:            public static final int DRIVES = 0x0011;
0100:            public static final int NETWORK = 0x0012;
0101:            public static final int NETHOOD = 0x0013;
0102:            public static final int FONTS = 0x0014;
0103:            public static final int TEMPLATES = 0x0015;
0104:            public static final int COMMON_STARTMENU = 0x0016;
0105:            public static final int COMMON_PROGRAMS = 0X0017;
0106:            public static final int COMMON_STARTUP = 0x0018;
0107:            public static final int COMMON_DESKTOPDIRECTORY = 0x0019;
0108:            public static final int APPDATA = 0x001a;
0109:            public static final int PRINTHOOD = 0x001b;
0110:            public static final int ALTSTARTUP = 0x001d;
0111:            public static final int COMMON_ALTSTARTUP = 0x001e;
0112:            public static final int COMMON_FAVORITES = 0x001f;
0113:            public static final int INTERNET_CACHE = 0x0020;
0114:            public static final int COOKIES = 0x0021;
0115:            public static final int HISTORY = 0x0022;
0116:
0117:            // Win32 shell folder attributes
0118:            public static final int ATTRIB_CANCOPY = 0x00000001;
0119:            public static final int ATTRIB_CANMOVE = 0x00000002;
0120:            public static final int ATTRIB_CANLINK = 0x00000004;
0121:            public static final int ATTRIB_CANRENAME = 0x00000010;
0122:            public static final int ATTRIB_CANDELETE = 0x00000020;
0123:            public static final int ATTRIB_HASPROPSHEET = 0x00000040;
0124:            public static final int ATTRIB_DROPTARGET = 0x00000100;
0125:            public static final int ATTRIB_LINK = 0x00010000;
0126:            public static final int ATTRIB_SHARE = 0x00020000;
0127:            public static final int ATTRIB_READONLY = 0x00040000;
0128:            public static final int ATTRIB_GHOSTED = 0x00080000;
0129:            public static final int ATTRIB_HIDDEN = 0x00080000;
0130:            public static final int ATTRIB_FILESYSANCESTOR = 0x10000000;
0131:            public static final int ATTRIB_FOLDER = 0x20000000;
0132:            public static final int ATTRIB_FILESYSTEM = 0x40000000;
0133:            public static final int ATTRIB_HASSUBFOLDER = 0x80000000;
0134:            public static final int ATTRIB_VALIDATE = 0x01000000;
0135:            public static final int ATTRIB_REMOVABLE = 0x02000000;
0136:            public static final int ATTRIB_COMPRESSED = 0x04000000;
0137:            public static final int ATTRIB_BROWSABLE = 0x08000000;
0138:            public static final int ATTRIB_NONENUMERATED = 0x00100000;
0139:            public static final int ATTRIB_NEWCONTENT = 0x00200000;
0140:
0141:            // IShellFolder::GetDisplayNameOf constants
0142:            public static final int SHGDN_NORMAL = 0;
0143:            public static final int SHGDN_INFOLDER = 1;
0144:            public static final int SHGDN_INCLUDE_NONFILESYS = 0x2000;
0145:            public static final int SHGDN_FORADDRESSBAR = 0x4000;
0146:            public static final int SHGDN_FORPARSING = 0x8000;
0147:
0148:            // Values for system call LoadIcon()
0149:            public enum SystemIcon {
0150:                IDI_APPLICATION(32512), IDI_HAND(32513), IDI_ERROR(32513), IDI_QUESTION(
0151:                        32514), IDI_EXCLAMATION(32515), IDI_WARNING(32515), IDI_ASTERISK(
0152:                        32516), IDI_INFORMATION(32516), IDI_WINLOGO(32517);
0153:
0154:                private final int iconID;
0155:
0156:                SystemIcon(int iconID) {
0157:                    this .iconID = iconID;
0158:                }
0159:
0160:                public int getIconID() {
0161:                    return iconID;
0162:                }
0163:            }
0164:
0165:            static class FolderDisposer implements  sun.java2d.DisposerRecord {
0166:                /*
0167:                 * This is cached as a concession to getFolderType(), which needs
0168:                 * an absolute PIDL.
0169:                 */
0170:                long absolutePIDL;
0171:                /*
0172:                 * We keep track of shell folders through the IShellFolder
0173:                 * interface of their parents plus their relative PIDL.
0174:                 */
0175:                long pIShellFolder;
0176:                long relativePIDL;
0177:
0178:                boolean disposed;
0179:
0180:                public void dispose() {
0181:                    if (disposed)
0182:                        return;
0183:                    if (relativePIDL != 0) {
0184:                        releasePIDL(relativePIDL);
0185:                    }
0186:                    if (absolutePIDL != 0) {
0187:                        releasePIDL(absolutePIDL);
0188:                    }
0189:                    if (pIShellFolder != 0) {
0190:                        releaseIShellFolder(pIShellFolder);
0191:                    }
0192:                    disposed = true;
0193:                }
0194:            }
0195:
0196:            FolderDisposer disposer = new FolderDisposer();
0197:
0198:            private void setIShellFolder(long pIShellFolder) {
0199:                disposer.pIShellFolder = pIShellFolder;
0200:            }
0201:
0202:            private void setRelativePIDL(long relativePIDL) {
0203:                disposer.relativePIDL = relativePIDL;
0204:            }
0205:
0206:            /*
0207:             * The following are for caching various shell folder properties.
0208:             */
0209:            private long pIShellIcon = -1L;
0210:            private String folderType = null;
0211:            private String displayName = null;
0212:            private Image smallIcon = null;
0213:            private Image largeIcon = null;
0214:            private Boolean isDir = null;
0215:
0216:            /*
0217:             * The following is to identify the My Documents folder as being special
0218:             */
0219:            private boolean isPersonal;
0220:
0221:            /**
0222:             * Create a system special shell folder, such as the
0223:             * desktop or Network Neighborhood.
0224:             */
0225:            Win32ShellFolder2(int csidl) throws IOException {
0226:                // Desktop is parent of DRIVES and NETWORK, not necessarily
0227:                // other special shell folders.
0228:                super (
0229:                        null,
0230:                        (getFileSystemPath(csidl) == null) ? ("ShellFolder: 0x" + Integer
0231:                                .toHexString(csidl))
0232:                                : getFileSystemPath(csidl));
0233:                if (csidl == DESKTOP) {
0234:                    initDesktop();
0235:                } else {
0236:                    initSpecial(getDesktop().getIShellFolder(), csidl);
0237:                    // At this point, the native method initSpecial() has set our relativePIDL
0238:                    // relative to the Desktop, which may not be our immediate parent. We need
0239:                    // to traverse this ID list and break it into a chain of shell folders from
0240:                    // the top, with each one having an immediate parent and a relativePIDL
0241:                    // relative to that parent.
0242:                    long pIDL = disposer.relativePIDL;
0243:                    parent = getDesktop();
0244:                    while (pIDL != 0) {
0245:                        // Get a child pidl relative to 'parent'
0246:                        long childPIDL = copyFirstPIDLEntry(pIDL);
0247:                        if (childPIDL != 0) {
0248:                            // Get a handle to the the rest of the ID list
0249:                            // i,e, parent's grandchilren and down
0250:                            pIDL = getNextPIDLEntry(pIDL);
0251:                            if (pIDL != 0) {
0252:                                // Now we know that parent isn't immediate to 'this' because it
0253:                                // has a continued ID list. Create a shell folder for this child
0254:                                // pidl and make it the new 'parent'.
0255:                                parent = new Win32ShellFolder2(
0256:                                        (Win32ShellFolder2) parent, childPIDL);
0257:                            } else {
0258:                                // No grandchildren means we have arrived at the parent of 'this',
0259:                                // and childPIDL is directly relative to parent.
0260:                                disposer.relativePIDL = childPIDL;
0261:                            }
0262:                        } else {
0263:                            break;
0264:                        }
0265:                    }
0266:                }
0267:
0268:                sun.java2d.Disposer.addRecord(this , disposer);
0269:            }
0270:
0271:            /**
0272:             * Create a system shell folder
0273:             */
0274:            Win32ShellFolder2(Win32ShellFolder2 parent, long pIShellFolder,
0275:                    long relativePIDL, String path) {
0276:                super (parent, (path != null) ? path : "ShellFolder: ");
0277:                this .disposer.pIShellFolder = pIShellFolder;
0278:                this .disposer.relativePIDL = relativePIDL;
0279:                sun.java2d.Disposer.addRecord(this , disposer);
0280:            }
0281:
0282:            /**
0283:             * Creates a shell folder with a parent and relative PIDL
0284:             */
0285:            Win32ShellFolder2(Win32ShellFolder2 parent, long relativePIDL) {
0286:                super (parent, getFileSystemPath(parent.getIShellFolder(),
0287:                        relativePIDL));
0288:                this .disposer.relativePIDL = relativePIDL;
0289:                getAbsolutePath();
0290:                sun.java2d.Disposer.addRecord(this , disposer);
0291:            }
0292:
0293:            // Initializes the desktop shell folder
0294:            private native void initDesktop();
0295:
0296:            // Initializes a special, non-file system shell folder
0297:            // from one of the above constants
0298:            private native void initSpecial(long desktopIShellFolder, int csidl);
0299:
0300:            /** Marks this folder as being the My Documents (Personal) folder */
0301:            public void setIsPersonal() {
0302:                isPersonal = true;
0303:            }
0304:
0305:            /**
0306:             * This method is implemented to make sure that no instances
0307:             * of <code>ShellFolder</code> are ever serialized. If <code>isFileSystem()</code> returns
0308:             * <code>true</code>, then the object is representable with an instance of
0309:             * <code>java.io.File</code> instead. If not, then the object depends
0310:             * on native PIDL state and should not be serialized.
0311:             *
0312:             * @returns a <code>java.io.File</code> replacement object. If the folder
0313:             * is a not a normal directory, then returns the first non-removable
0314:             * drive (normally "C:\").
0315:             */
0316:            protected Object writeReplace()
0317:                    throws java.io.ObjectStreamException {
0318:                if (isFileSystem()) {
0319:                    return new File(getPath());
0320:                } else {
0321:                    Win32ShellFolder2 drives = Win32ShellFolderManager2
0322:                            .getDrives();
0323:                    if (drives != null) {
0324:                        File[] driveRoots = drives.listFiles();
0325:                        if (driveRoots != null) {
0326:                            for (int i = 0; i < driveRoots.length; i++) {
0327:                                if (driveRoots[i] instanceof  Win32ShellFolder2) {
0328:                                    Win32ShellFolder2 sf = (Win32ShellFolder2) driveRoots[i];
0329:                                    if (sf.isFileSystem()
0330:                                            && !sf
0331:                                                    .hasAttribute(ATTRIB_REMOVABLE)) {
0332:                                        return new File(sf.getPath());
0333:                                    }
0334:                                }
0335:                            }
0336:                        }
0337:                    }
0338:                    // Ouch, we have no hard drives. Return something "valid" anyway.
0339:                    return new File("C:\\");
0340:                }
0341:            }
0342:
0343:            /**
0344:             * Finalizer to clean up any COM objects or PIDLs used by this object.
0345:             */
0346:            protected void dispose() {
0347:                disposer.dispose();
0348:            }
0349:
0350:            // Given a (possibly multi-level) relative PIDL (with respect to
0351:            // the desktop, at least in all of the usage cases in this code),
0352:            // return a pointer to the next entry. Does not mutate the PIDL in
0353:            // any way. Returns 0 if the null terminator is reached.
0354:            // Needs to be accessible to Win32ShellFolderManager2
0355:            static native long getNextPIDLEntry(long pIDL);
0356:
0357:            // Given a (possibly multi-level) relative PIDL (with respect to
0358:            // the desktop, at least in all of the usage cases in this code),
0359:            // copy the first entry into a newly-allocated PIDL. Returns 0 if
0360:            // the PIDL is at the end of the list.
0361:            // Needs to be accessible to Win32ShellFolderManager2
0362:            static native long copyFirstPIDLEntry(long pIDL);
0363:
0364:            // Given a parent's absolute PIDL and our relative PIDL, build an absolute PIDL
0365:            private static native long combinePIDLs(long ppIDL, long pIDL);
0366:
0367:            // Release a PIDL object
0368:            // Needs to be accessible to Win32ShellFolderManager2
0369:            static native void releasePIDL(long pIDL);
0370:
0371:            // Release an IShellFolder object
0372:            private static native void releaseIShellFolder(long pIShellFolder);
0373:
0374:            /**
0375:             * Accessor for IShellFolder
0376:             */
0377:            public long getIShellFolder() {
0378:                if (disposer.pIShellFolder == 0) {
0379:                    assert (isDirectory());
0380:                    assert (parent != null);
0381:                    long parentIShellFolder = getParentIShellFolder();
0382:                    if (parentIShellFolder == 0) {
0383:                        throw new InternalError(
0384:                                "Parent IShellFolder was null for "
0385:                                        + getAbsolutePath());
0386:                    }
0387:                    // We are a directory with a parent and a relative PIDL.
0388:                    // We want to bind to the parent so we get an IShellFolder instance associated with us.
0389:                    disposer.pIShellFolder = bindToObject(parentIShellFolder,
0390:                            disposer.relativePIDL);
0391:                    if (disposer.pIShellFolder == 0) {
0392:                        throw new InternalError("Unable to bind "
0393:                                + getAbsolutePath() + " to parent");
0394:                    }
0395:                }
0396:                return disposer.pIShellFolder;
0397:            }
0398:
0399:            /**
0400:             * Get the parent ShellFolder's IShellFolder interface
0401:             */
0402:            public long getParentIShellFolder() {
0403:                Win32ShellFolder2 parent = (Win32ShellFolder2) getParentFile();
0404:                if (parent == null) {
0405:                    // Parent should only be null if this is the desktop, whose
0406:                    // relativePIDL is relative to its own IShellFolder.
0407:                    return getIShellFolder();
0408:                }
0409:                return parent.getIShellFolder();
0410:            }
0411:
0412:            /**
0413:             * Accessor for relative PIDL
0414:             */
0415:            public long getRelativePIDL() {
0416:                if (disposer.relativePIDL == 0) {
0417:                    throw new InternalError(
0418:                            "Should always have a relative PIDL");
0419:                }
0420:                return disposer.relativePIDL;
0421:            }
0422:
0423:            private long getAbsolutePIDL() {
0424:                if (parent == null) {
0425:                    // This is the desktop
0426:                    return getRelativePIDL();
0427:                } else {
0428:                    if (disposer.absolutePIDL == 0) {
0429:                        disposer.absolutePIDL = combinePIDLs(
0430:                                ((Win32ShellFolder2) parent).getAbsolutePIDL(),
0431:                                getRelativePIDL());
0432:                    }
0433:
0434:                    return disposer.absolutePIDL;
0435:                }
0436:            }
0437:
0438:            /**
0439:             * Helper function to return the desktop
0440:             */
0441:            public Win32ShellFolder2 getDesktop() {
0442:                return Win32ShellFolderManager2.getDesktop();
0443:            }
0444:
0445:            /**
0446:             * Helper function to return the desktop IShellFolder interface
0447:             */
0448:            public long getDesktopIShellFolder() {
0449:                return getDesktop().getIShellFolder();
0450:            }
0451:
0452:            private static boolean pathsEqual(String path1, String path2) {
0453:                // Same effective implementation as Win32FileSystem
0454:                return path1.equalsIgnoreCase(path2);
0455:            }
0456:
0457:            /**
0458:             * Check to see if two ShellFolder objects are the same
0459:             */
0460:            public boolean equals(Object o) {
0461:                if (o == null || !(o instanceof  Win32ShellFolder2)) {
0462:                    // Short-circuit circuitous delegation path
0463:                    if (!(o instanceof  File)) {
0464:                        return super .equals(o);
0465:                    }
0466:                    return pathsEqual(getPath(), ((File) o).getPath());
0467:                }
0468:                Win32ShellFolder2 rhs = (Win32ShellFolder2) o;
0469:                if ((parent == null && rhs.parent != null)
0470:                        || (parent != null && rhs.parent == null)) {
0471:                    return false;
0472:                }
0473:
0474:                if (isFileSystem() && rhs.isFileSystem()) {
0475:                    // Only folders with identical parents can be equal
0476:                    return (pathsEqual(getPath(), rhs.getPath()) && (parent == rhs.parent || parent
0477:                            .equals(rhs.parent)));
0478:                }
0479:
0480:                if (parent == rhs.parent || parent.equals(rhs.parent)) {
0481:                    return pidlsEqual(getParentIShellFolder(),
0482:                            disposer.relativePIDL, rhs.disposer.relativePIDL);
0483:                }
0484:
0485:                return false;
0486:            }
0487:
0488:            private static boolean pidlsEqual(long pIShellFolder, long pidl1,
0489:                    long pidl2) {
0490:                return (compareIDs(pIShellFolder, pidl1, pidl2) == 0);
0491:            }
0492:
0493:            private static native int compareIDs(long pParentIShellFolder,
0494:                    long pidl1, long pidl2);
0495:
0496:            /**
0497:             * @return Whether this is a file system shell folder
0498:             */
0499:            public boolean isFileSystem() {
0500:                return hasAttribute(ATTRIB_FILESYSTEM);
0501:            }
0502:
0503:            /**
0504:             * Return whether the given attribute flag is set for this object
0505:             */
0506:            public boolean hasAttribute(int attribute) {
0507:                // Caching at this point doesn't seem to be cost efficient
0508:                return (getAttributes0(getParentIShellFolder(),
0509:                        getRelativePIDL(), attribute) & attribute) != 0;
0510:            }
0511:
0512:            /**
0513:             * Returns the queried attributes specified in attrsMask.
0514:             *
0515:             * Could plausibly be used for attribute caching but have to be
0516:             * very careful not to touch network drives and file system roots
0517:             * with a full attrsMask
0518:             */
0519:            private static native int getAttributes0(long pParentIShellFolder,
0520:                    long pIDL, int attrsMask);
0521:
0522:            // Return the path to the underlying file system object
0523:            private static String getFileSystemPath(long parentIShellFolder,
0524:                    long relativePIDL) {
0525:                int linkedFolder = ATTRIB_LINK | ATTRIB_FOLDER;
0526:                if (parentIShellFolder == Win32ShellFolderManager2.getNetwork()
0527:                        .getIShellFolder()
0528:                        && getAttributes0(parentIShellFolder, relativePIDL,
0529:                                linkedFolder) == linkedFolder) {
0530:
0531:                    String s = getFileSystemPath(Win32ShellFolderManager2
0532:                            .getDesktop().getIShellFolder(), getLinkLocation(
0533:                            parentIShellFolder, relativePIDL, false));
0534:                    if (s != null && s.startsWith("\\\\")) {
0535:                        return s;
0536:                    }
0537:                }
0538:                return getDisplayNameOf(parentIShellFolder, relativePIDL,
0539:                        SHGDN_NORMAL | SHGDN_FORPARSING);
0540:            }
0541:
0542:            // Needs to be accessible to Win32ShellFolderManager2
0543:            static native String getFileSystemPath(int csidl)
0544:                    throws IOException;
0545:
0546:            // Return whether the path is a network root.
0547:            // Path is assumed to be non-null
0548:            private static boolean isNetworkRoot(String path) {
0549:                return (path.equals("\\\\") || path.equals("\\")
0550:                        || path.equals("//") || path.equals("/"));
0551:            }
0552:
0553:            /**
0554:             * @return The parent shell folder of this shell folder, null if
0555:             * there is no parent
0556:             */
0557:            public File getParentFile() {
0558:                return parent;
0559:            }
0560:
0561:            public boolean isDirectory() {
0562:                if (isDir == null) {
0563:                    // Folders with SFGAO_BROWSABLE have "shell extension" handlers and are
0564:                    // not traversable in JFileChooser. An exception is "My Documents" on
0565:                    // Windows 98.
0566:                    if ((hasAttribute(ATTRIB_HASSUBFOLDER) || hasAttribute(ATTRIB_FOLDER))
0567:                            && (!hasAttribute(ATTRIB_BROWSABLE) || (is98 && equals(Win32ShellFolderManager2
0568:                                    .getPersonal())))) {
0569:                        isDir = Boolean.TRUE;
0570:                    } else if (isLink()) {
0571:                        ShellFolder linkLocation = getLinkLocation(false);
0572:                        isDir = Boolean.valueOf(linkLocation != null
0573:                                && linkLocation.isDirectory());
0574:                    } else {
0575:                        isDir = Boolean.FALSE;
0576:                    }
0577:                }
0578:                return isDir.booleanValue();
0579:            }
0580:
0581:            /*
0582:             * Functions for enumerating an IShellFolder's children
0583:             */
0584:            // Returns an IEnumIDList interface for an IShellFolder.  The value
0585:            // returned must be released using releaseEnumObjects().
0586:            private long getEnumObjects(long pIShellFolder,
0587:                    boolean includeHiddenFiles) {
0588:                boolean isDesktop = (disposer.pIShellFolder == getDesktopIShellFolder());
0589:                return getEnumObjects(disposer.pIShellFolder, isDesktop,
0590:                        includeHiddenFiles);
0591:            }
0592:
0593:            // Returns an IEnumIDList interface for an IShellFolder.  The value
0594:            // returned must be released using releaseEnumObjects().
0595:            private native long getEnumObjects(long pIShellFolder,
0596:                    boolean isDesktop, boolean includeHiddenFiles);
0597:
0598:            // Returns the next sequential child as a relative PIDL
0599:            // from an IEnumIDList interface.  The value returned must
0600:            // be released using releasePIDL().
0601:            private native long getNextChild(long pEnumObjects);
0602:
0603:            // Releases the IEnumIDList interface
0604:            private native void releaseEnumObjects(long pEnumObjects);
0605:
0606:            // Returns the IShellFolder of a child from a parent IShellFolder
0607:            // and a relative PIDL.  The value returned must be released
0608:            // using releaseIShellFolder().
0609:            private static native long bindToObject(long parentIShellFolder,
0610:                    long pIDL);
0611:
0612:            /**
0613:             * @return An array of shell folders that are children of this shell folder
0614:             *         object. The array will be empty if the folder is empty.  Returns
0615:             *         <code>null</code> if this shellfolder does not denote a directory.
0616:             */
0617:            public File[] listFiles(boolean includeHiddenFiles) {
0618:                if (!isDirectory()) {
0619:                    return null;
0620:                }
0621:                // Links to directories are not directories and cannot be parents.
0622:                // This does not apply to folders in My Network Places (NetHood)
0623:                // because they are both links and real directories!
0624:                if (isLink() && !hasAttribute(ATTRIB_FOLDER)) {
0625:                    return new File[0];
0626:                }
0627:
0628:                Win32ShellFolder2 desktop = Win32ShellFolderManager2
0629:                        .getDesktop();
0630:                Win32ShellFolder2 personal = Win32ShellFolderManager2
0631:                        .getPersonal();
0632:
0633:                // If we are a directory, we have a parent and (at least) a
0634:                // relative PIDL. We must first ensure we are bound to the
0635:                // parent so we have an IShellFolder to query.
0636:                long pIShellFolder = getIShellFolder();
0637:                // Now we can enumerate the objects in this folder.
0638:                ArrayList list = new ArrayList();
0639:                long pEnumObjects = getEnumObjects(pIShellFolder,
0640:                        includeHiddenFiles);
0641:                if (pEnumObjects != 0) {
0642:                    long childPIDL = 0;
0643:                    int testedAttrs = ATTRIB_FILESYSTEM
0644:                            | ATTRIB_FILESYSANCESTOR;
0645:                    do {
0646:                        if (Thread.currentThread().isInterrupted()) {
0647:                            return new File[0];
0648:                        }
0649:                        childPIDL = getNextChild(pEnumObjects);
0650:                        boolean releasePIDL = true;
0651:                        if (childPIDL != 0
0652:                                && (getAttributes0(pIShellFolder, childPIDL,
0653:                                        testedAttrs) & testedAttrs) != 0) {
0654:                            Win32ShellFolder2 childFolder = null;
0655:                            if (this .equals(desktop)
0656:                                    && personal != null
0657:                                    && pidlsEqual(pIShellFolder, childPIDL,
0658:                                            personal.disposer.relativePIDL)) {
0659:                                childFolder = personal;
0660:                            } else {
0661:                                childFolder = new Win32ShellFolder2(this ,
0662:                                        childPIDL);
0663:                                releasePIDL = false;
0664:                            }
0665:                            list.add(childFolder);
0666:                        }
0667:                        if (releasePIDL) {
0668:                            releasePIDL(childPIDL);
0669:                        }
0670:                    } while (childPIDL != 0);
0671:                    releaseEnumObjects(pEnumObjects);
0672:                }
0673:                return (ShellFolder[]) list
0674:                        .toArray(new ShellFolder[list.size()]);
0675:            }
0676:
0677:            /**
0678:             * Look for (possibly special) child folder by it's path
0679:             *
0680:             * @return The child shellfolder, or null if not found.
0681:             */
0682:            Win32ShellFolder2 getChildByPath(String filePath) {
0683:                long pIShellFolder = getIShellFolder();
0684:                long pEnumObjects = getEnumObjects(pIShellFolder, true);
0685:                Win32ShellFolder2 child = null;
0686:                long childPIDL = 0;
0687:
0688:                while ((childPIDL = getNextChild(pEnumObjects)) != 0) {
0689:                    if (getAttributes0(pIShellFolder, childPIDL,
0690:                            ATTRIB_FILESYSTEM) != 0) {
0691:                        String path = getFileSystemPath(pIShellFolder,
0692:                                childPIDL);
0693:                        if (path != null && path.equalsIgnoreCase(filePath)) {
0694:                            long childIShellFolder = bindToObject(
0695:                                    pIShellFolder, childPIDL);
0696:                            child = new Win32ShellFolder2(this ,
0697:                                    childIShellFolder, childPIDL, path);
0698:                            break;
0699:                        }
0700:                    }
0701:                    releasePIDL(childPIDL);
0702:                }
0703:                releaseEnumObjects(pEnumObjects);
0704:                return child;
0705:            }
0706:
0707:            /**
0708:             * @return Whether this shell folder is a link
0709:             */
0710:            public boolean isLink() {
0711:                return hasAttribute(ATTRIB_LINK);
0712:            }
0713:
0714:            /**
0715:             * @return Whether this shell folder is marked as hidden
0716:             */
0717:            public boolean isHidden() {
0718:                return hasAttribute(ATTRIB_HIDDEN);
0719:            }
0720:
0721:            // Return the link location of a shell folder
0722:            private static native long getLinkLocation(long parentIShellFolder,
0723:                    long relativePIDL, boolean resolve);
0724:
0725:            /**
0726:             * @return The shell folder linked to by this shell folder, or null
0727:             * if this shell folder is not a link or is a broken or invalid link
0728:             */
0729:            public ShellFolder getLinkLocation() {
0730:                return getLinkLocation(true);
0731:            }
0732:
0733:            private ShellFolder getLinkLocation(boolean resolve) {
0734:                if (!isLink()) {
0735:                    return null;
0736:                }
0737:
0738:                ShellFolder location = null;
0739:                long linkLocationPIDL = getLinkLocation(
0740:                        getParentIShellFolder(), getRelativePIDL(), resolve);
0741:                if (linkLocationPIDL != 0) {
0742:                    try {
0743:                        location = Win32ShellFolderManager2
0744:                                .createShellFolderFromRelativePIDL(
0745:                                        getDesktop(), linkLocationPIDL);
0746:                    } catch (InternalError e) {
0747:                        // Could be a link to a non-bindable object, such as a network connection
0748:                        // TODO: getIShellFolder() should throw FileNotFoundException instead
0749:                    }
0750:                }
0751:                return location;
0752:            }
0753:
0754:            // Parse a display name into a PIDL relative to the current IShellFolder.
0755:            long parseDisplayName(String name) throws FileNotFoundException {
0756:                try {
0757:                    return parseDisplayName0(getIShellFolder(), name);
0758:                } catch (IOException e) {
0759:                    throw new FileNotFoundException("Could not find file "
0760:                            + name);
0761:                }
0762:            }
0763:
0764:            private static native long parseDisplayName0(long pIShellFolder,
0765:                    String name) throws IOException;
0766:
0767:            // Return the display name of a shell folder
0768:            private static native String getDisplayNameOf(
0769:                    long parentIShellFolder, long relativePIDL, int attrs);
0770:
0771:            /**
0772:             * @return The name used to display this shell folder
0773:             */
0774:            public String getDisplayName() {
0775:                if (displayName == null) {
0776:                    displayName = getDisplayNameOf(getParentIShellFolder(),
0777:                            getRelativePIDL(), SHGDN_NORMAL);
0778:                }
0779:                return displayName;
0780:            }
0781:
0782:            // Return the folder type of a shell folder
0783:            private static native String getFolderType(long pIDL);
0784:
0785:            /**
0786:             * @return The type of shell folder as a string
0787:             */
0788:            public String getFolderType() {
0789:                if (folderType == null) {
0790:                    folderType = getFolderType(getAbsolutePIDL());
0791:                }
0792:                return folderType;
0793:            }
0794:
0795:            // Return the executable type of a file system shell folder
0796:            private native String getExecutableType(String path);
0797:
0798:            /**
0799:             * @return The executable type as a string
0800:             */
0801:            public String getExecutableType() {
0802:                if (!isFileSystem()) {
0803:                    return null;
0804:                }
0805:                return getExecutableType(getAbsolutePath());
0806:            }
0807:
0808:            // Icons
0809:
0810:            private static Map smallSystemImages = new HashMap();
0811:            private static Map largeSystemImages = new HashMap();
0812:            private static Map smallLinkedSystemImages = new HashMap();
0813:            private static Map largeLinkedSystemImages = new HashMap();
0814:
0815:            private static native long getIShellIcon(long pIShellFolder);
0816:
0817:            private static native int getIconIndex(long parentIShellIcon,
0818:                    long relativePIDL);
0819:
0820:            // Return the icon of a file system shell folder in the form of an HICON
0821:            private static native long getIcon(String absolutePath,
0822:                    boolean getLargeIcon);
0823:
0824:            private static native long extractIcon(long parentIShellFolder,
0825:                    long relativePIDL, boolean getLargeIcon);
0826:
0827:            // Returns an icon from the Windows system icon list in the form of an HICON
0828:            private static native long getSystemIcon(int iconID);
0829:
0830:            private static native long getIconResource(String libName,
0831:                    int iconID, int cxDesired, int cyDesired,
0832:                    boolean useVGAColors);
0833:
0834:            // Note: useVGAColors is ignored on XP and later
0835:
0836:            // Return the bits from an HICON.  This has a side effect of setting
0837:            // the imageHash variable for efficient caching / comparing.
0838:            private static native int[] getIconBits(long hIcon, int iconSize);
0839:
0840:            // Dispose the HICON
0841:            private static native void disposeIcon(long hIcon);
0842:
0843:            public static native int[] getFileChooserBitmapBits();
0844:
0845:            private long getIShellIcon() {
0846:                if (pIShellIcon == -1L) {
0847:                    pIShellIcon = getIShellIcon(getIShellFolder());
0848:                }
0849:                return pIShellIcon;
0850:            }
0851:
0852:            static int[] fileChooserBitmapBits = null;
0853:            static Image[] fileChooserIcons = new Image[47];
0854:
0855:            static Image getFileChooserIcon(int i) {
0856:                if (fileChooserIcons[i] != null) {
0857:                    return fileChooserIcons[i];
0858:                } else {
0859:                    if (fileChooserBitmapBits == null) {
0860:                        fileChooserBitmapBits = getFileChooserBitmapBits();
0861:                    }
0862:                    if (fileChooserBitmapBits != null) {
0863:                        int nImages = fileChooserBitmapBits.length / (16 * 16);
0864:                        int[] bitmapBits = new int[16 * 16];
0865:                        for (int y = 0; y < 16; y++) {
0866:                            for (int x = 0; x < 16; x++) {
0867:                                bitmapBits[y * 16 + x] = fileChooserBitmapBits[y
0868:                                        * (nImages * 16) + (i * 16) + x];
0869:                            }
0870:                        }
0871:                        BufferedImage img = new BufferedImage(16, 16,
0872:                                BufferedImage.TYPE_INT_ARGB);
0873:                        img.setRGB(0, 0, 16, 16, bitmapBits, 0, 16);
0874:                        fileChooserIcons[i] = img;
0875:                    }
0876:                }
0877:                return fileChooserIcons[i];
0878:            }
0879:
0880:            private static Image makeIcon(long hIcon, boolean getLargeIcon) {
0881:                if (hIcon != 0L && hIcon != -1L) {
0882:                    // Get the bits.  This has the side effect of setting the imageHash value for this object.
0883:                    int size = getLargeIcon ? 32 : 16;
0884:                    int[] iconBits = getIconBits(hIcon, size);
0885:                    if (iconBits != null) {
0886:                        BufferedImage img = new BufferedImage(size, size,
0887:                                BufferedImage.TYPE_INT_ARGB);
0888:                        img.setRGB(0, 0, size, size, iconBits, 0, size);
0889:                        return img;
0890:                    }
0891:                }
0892:                return null;
0893:            }
0894:
0895:            /**
0896:             * @return The icon image used to display this shell folder
0897:             */
0898:            public Image getIcon(boolean getLargeIcon) {
0899:                Image icon = getLargeIcon ? largeIcon : smallIcon;
0900:                if (icon == null) {
0901:                    long parentIShellIcon = (parent != null) ? ((Win32ShellFolder2) parent)
0902:                            .getIShellIcon()
0903:                            : 0L;
0904:                    long relativePIDL = getRelativePIDL();
0905:
0906:                    if (isFileSystem()) {
0907:                        // These are cached per type (using the index in the system image list)
0908:                        int index = getIconIndex(parentIShellIcon, relativePIDL);
0909:                        if (index > 0) {
0910:                            Map imageCache;
0911:                            if (isLink()) {
0912:                                imageCache = getLargeIcon ? largeLinkedSystemImages
0913:                                        : smallLinkedSystemImages;
0914:                            } else {
0915:                                imageCache = getLargeIcon ? largeSystemImages
0916:                                        : smallSystemImages;
0917:                            }
0918:                            icon = (Image) imageCache.get(Integer
0919:                                    .valueOf(index));
0920:                            if (icon == null) {
0921:                                long hIcon = getIcon(getAbsolutePath(),
0922:                                        getLargeIcon);
0923:                                icon = makeIcon(hIcon, getLargeIcon);
0924:                                disposeIcon(hIcon);
0925:                                if (icon != null) {
0926:                                    imageCache
0927:                                            .put(Integer.valueOf(index), icon);
0928:                                }
0929:                            }
0930:                        }
0931:                    }
0932:
0933:                    if (icon == null) {
0934:                        // These are only cached per object
0935:                        long hIcon = extractIcon(getParentIShellFolder(),
0936:                                getRelativePIDL(), getLargeIcon);
0937:                        icon = makeIcon(hIcon, getLargeIcon);
0938:                        disposeIcon(hIcon);
0939:                    }
0940:
0941:                    if (getLargeIcon) {
0942:                        largeIcon = icon;
0943:                    } else {
0944:                        smallIcon = icon;
0945:                    }
0946:                }
0947:                if (icon == null) {
0948:                    icon = super .getIcon(getLargeIcon);
0949:                }
0950:                return icon;
0951:            }
0952:
0953:            /**
0954:             * Gets an icon from the Windows system icon list as an <code>Image</code>
0955:             */
0956:            static Image getSystemIcon(SystemIcon iconType) {
0957:                long hIcon = getSystemIcon(iconType.getIconID());
0958:                Image icon = makeIcon(hIcon, true);
0959:                disposeIcon(hIcon);
0960:                return icon;
0961:            }
0962:
0963:            /**
0964:             * Gets an icon from the Windows system icon list as an <code>Image</code>
0965:             */
0966:            static Image getShell32Icon(int iconID) {
0967:                boolean useVGAColors = true; // Will be ignored on XP and later
0968:
0969:                Toolkit toolkit = Toolkit.getDefaultToolkit();
0970:                String shellIconBPP = (String) toolkit
0971:                        .getDesktopProperty("win.icon.shellIconBPP");
0972:                if (shellIconBPP != null) {
0973:                    useVGAColors = shellIconBPP.equals("4");
0974:                }
0975:
0976:                long hIcon = getIconResource("shell32.dll", iconID, 16, 16,
0977:                        useVGAColors);
0978:                if (hIcon != 0) {
0979:                    Image icon = makeIcon(hIcon, false);
0980:                    disposeIcon(hIcon);
0981:                    return icon;
0982:                }
0983:                return null;
0984:            }
0985:
0986:            /**
0987:             * Returns the canonical form of this abstract pathname.  Equivalent to
0988:             * <code>new&nbsp;Win32ShellFolder2(getParentFile(), this.{@link java.io.File#getCanonicalPath}())</code>.
0989:             *
0990:             * @see java.io.File#getCanonicalFile
0991:             */
0992:            public File getCanonicalFile() throws IOException {
0993:                return this ;
0994:            }
0995:
0996:            /*
0997:             * Indicates whether this is a special folder (includes My Documents)
0998:             */
0999:            public boolean isSpecial() {
1000:                return isPersonal || !isFileSystem() || (this  == getDesktop());
1001:            }
1002:
1003:            /**
1004:             * Compares this object with the specified object for order.
1005:             *
1006:             * @see sun.awt.shell.ShellFolder#compareTo(File)
1007:             */
1008:            public int compareTo(File file2) {
1009:                if (!(file2 instanceof  Win32ShellFolder2)) {
1010:                    if (isFileSystem() && !isSpecial()) {
1011:                        return super .compareTo(file2);
1012:                    } else {
1013:                        return -1; // Non-file shellfolders sort before files
1014:                    }
1015:                }
1016:                return Win32ShellFolderManager2.compareShellFolders(this ,
1017:                        (Win32ShellFolder2) file2);
1018:            }
1019:
1020:            // native constants from commctrl.h
1021:            private static final int LVCFMT_LEFT = 0;
1022:            private static final int LVCFMT_RIGHT = 1;
1023:            private static final int LVCFMT_CENTER = 2;
1024:
1025:            public ShellFolderColumnInfo[] getFolderColumns() {
1026:                ShellFolderColumnInfo[] columns = doGetColumnInfo(getIShellFolder());
1027:
1028:                if (columns != null) {
1029:                    List<ShellFolderColumnInfo> notNullColumns = new ArrayList<ShellFolderColumnInfo>();
1030:                    for (int i = 0; i < columns.length; i++) {
1031:                        ShellFolderColumnInfo column = columns[i];
1032:                        if (column != null) {
1033:                            column
1034:                                    .setAlignment(column.getAlignment() == LVCFMT_RIGHT ? SwingConstants.RIGHT
1035:                                            : column.getAlignment() == LVCFMT_CENTER ? SwingConstants.CENTER
1036:                                                    : SwingConstants.LEADING);
1037:
1038:                            column.setComparator(new ColumnComparator(i));
1039:
1040:                            notNullColumns.add(column);
1041:                        }
1042:                    }
1043:                    columns = new ShellFolderColumnInfo[notNullColumns.size()];
1044:                    notNullColumns.toArray(columns);
1045:                }
1046:                return columns;
1047:            }
1048:
1049:            public Object getFolderColumnValue(int column) {
1050:                return doGetColumnValue(getParentIShellFolder(),
1051:                        getRelativePIDL(), column);
1052:            }
1053:
1054:            private native ShellFolderColumnInfo[] doGetColumnInfo(
1055:                    long iShellFolder2);
1056:
1057:            private native Object doGetColumnValue(long parentIShellFolder2,
1058:                    long childPIDL, int columnIdx);
1059:
1060:            private native int compareIDsByColumn(long pParentIShellFolder,
1061:                    long pidl1, long pidl2, int columnIdx);
1062:
1063:            private class ColumnComparator implements  Comparator {
1064:                private final int columnIdx;
1065:
1066:                public ColumnComparator(int columnIdx) {
1067:                    this .columnIdx = columnIdx;
1068:                }
1069:
1070:                // compares 2 objects within this folder by the specified column
1071:                public int compare(Object o, Object o1) {
1072:                    if (o instanceof  Win32ShellFolder2
1073:                            && o1 instanceof  Win32ShellFolder2) {
1074:                        // delegates comparison to native method
1075:                        return compareIDsByColumn(getIShellFolder(),
1076:                                ((Win32ShellFolder2) o).getRelativePIDL(),
1077:                                ((Win32ShellFolder2) o1).getRelativePIDL(),
1078:                                columnIdx);
1079:                    }
1080:                    return 0;
1081:                }
1082:            }
1083:
1084:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.