Source Code Cross Referenced for FileObject.java in  » IDE-Netbeans » openide » org » openide » filesystems » 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 » IDE Netbeans » openide » org.openide.filesystems 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003:         *
0004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005:         *
0006:         * The contents of this file are subject to the terms of either the GNU
0007:         * General Public License Version 2 only ("GPL") or the Common
0008:         * Development and Distribution License("CDDL") (collectively, the
0009:         * "License"). You may not use this file except in compliance with the
0010:         * License. You can obtain a copy of the License at
0011:         * http://www.netbeans.org/cddl-gplv2.html
0012:         * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013:         * specific language governing permissions and limitations under the
0014:         * License.  When distributing the software, include this License Header
0015:         * Notice in each file and include the License file at
0016:         * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
0017:         * particular file as subject to the "Classpath" exception as provided
0018:         * by Sun in the GPL Version 2 section of the License file that
0019:         * accompanied this code. If applicable, add the following below the
0020:         * License Header, with the fields enclosed by brackets [] replaced by
0021:         * your own identifying information:
0022:         * "Portions Copyrighted [year] [name of copyright owner]"
0023:         *
0024:         * Contributor(s):
0025:         *
0026:         * The Original Software is NetBeans. The Initial Developer of the Original
0027:         * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
0028:         * Microsystems, Inc. All Rights Reserved.
0029:         *
0030:         * If you wish your version of this file to be governed by only the CDDL
0031:         * or only the GPL Version 2, indicate your decision by adding
0032:         * "[Contributor] elects to include this software in this distribution
0033:         * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034:         * single choice of license, a recipient has the option to distribute
0035:         * your version of this file under either the CDDL, the GPL Version 2 or
0036:         * to extend the choice of license to its licensees as provided above.
0037:         * However, if you add GPL Version 2 code and therefore, elected the GPL
0038:         * Version 2 license, then the option applies only if the new code is
0039:         * made subject to such option by the copyright holder.
0040:         */
0041:
0042:        package org.openide.filesystems;
0043:
0044:        import java.io.File;
0045:        import java.io.FileNotFoundException;
0046:        import java.io.FilterOutputStream;
0047:        import java.io.IOException;
0048:        import java.io.InputStream;
0049:        import java.io.OutputStream;
0050:        import java.io.Serializable;
0051:        import java.net.URL;
0052:        import java.util.ArrayList;
0053:        import java.util.Arrays;
0054:        import java.util.Collection;
0055:        import java.util.Collections;
0056:        import java.util.Enumeration;
0057:        import java.util.LinkedList;
0058:        import java.util.List;
0059:        import java.util.StringTokenizer;
0060:        import org.openide.util.Enumerations;
0061:        import org.openide.util.Exceptions;
0062:        import org.openide.util.NbBundle;
0063:
0064:        /** This is the base for all implementations of file objects on a filesystem.
0065:         * Provides basic information about the object (its name, parent,
0066:         * whether it exists, etc.) and operations on it (move, delete, etc.).
0067:         *
0068:         * @author Jaroslav Tulach, Petr Hamernik, Ian Formanek
0069:         */
0070:        public abstract class FileObject extends Object implements  Serializable {
0071:            /** generated Serialized Version UID */
0072:            static final long serialVersionUID = 85305031923497718L;
0073:
0074:            /** Get the name without extension of this file or folder.
0075:             * Period at first position is not considered as extension-separator
0076:             * For the root folder of a filesystem, this will be the empty
0077:             * string (the extension will also be the empty string, and the
0078:             * fully qualified name with any delimiters will also be the
0079:             * empty string).
0080:             * @return name of the file or folder(in its enclosing folder)
0081:             */
0082:            public abstract String getName();
0083:
0084:            /** Get the extension of this file or folder.
0085:             * Period at first position is not considered as extension-separator
0086:             * This is the string after the last dot of the full name, if any.
0087:             *
0088:             * @return extension of the file or folder (if any) or empty string if there is none
0089:             */
0090:            public abstract String getExt();
0091:
0092:            /** Renames this file (or folder).
0093:             * Both the new basename and new extension should be specified.
0094:             * <p>
0095:             * Note that using this call, it is currently only possible to rename <em>within</em>
0096:             * a parent folder, and not to do moves <em>across</em> folders.
0097:             * Conversely, implementing filesystems need only implement "simple" renames.
0098:             * If you wish to move a file across folders, you should call {@link FileUtil#moveFile}.
0099:             * @param lock File must be locked before renaming.
0100:             * @param name new basename of file
0101:             * @param ext new extension of file (ignored for folders)
0102:             */
0103:            public abstract void rename(FileLock lock, String name, String ext)
0104:                    throws IOException;
0105:
0106:            /** Copies this file. This allows the filesystem to perform any additional
0107:             * operation associated with the copy. But the default implementation is simple
0108:             * copy of the file and its attributes
0109:             *
0110:             * @param target target folder to move this file to
0111:             * @param name new basename of file
0112:             * @param ext new extension of file (ignored for folders)
0113:             * @return the newly created file object representing the moved file
0114:             */
0115:            public FileObject copy(FileObject target, String name, String ext)
0116:                    throws IOException {
0117:                if (isFolder()) {
0118:                    throw new IOException(NbBundle.getBundle(FileObject.class)
0119:                            .getString("EXC_FolderCopy"));
0120:                }
0121:
0122:                FileObject dest = FileUtil
0123:                        .copyFileImpl(this , target, name, ext);
0124:
0125:                return dest;
0126:            }
0127:
0128:            /** Moves this file. This allows the filesystem to perform any additional
0129:             * operation associated with the move. But the default implementation is encapsulated
0130:             * as copy and delete.
0131:             *
0132:             * @param lock File must be locked before renaming.
0133:             * @param target target folder to move this file to
0134:             * @param name new basename of file
0135:             * @param ext new extension of file (ignored for folders)
0136:             * @return the newly created file object representing the moved file
0137:             */
0138:            public FileObject move(FileLock lock, FileObject target,
0139:                    String name, String ext) throws IOException {
0140:                if (getParent().equals(target)) {
0141:                    // it is possible to do only rename
0142:                    rename(lock, name, ext);
0143:
0144:                    return this ;
0145:                } else {
0146:                    // have to do copy
0147:                    FileObject dest = copy(target, name, ext);
0148:                    delete(lock);
0149:
0150:                    return dest;
0151:                }
0152:            }
0153:
0154:            /**
0155:             * Gets a textual represtentation of this <code>FileObject</code>.
0156:             * The precise format is not defined. In particular it is probably
0157:             * <em>not</em> a resource path.
0158:             * For that purpose use {@link #getPath} directly.
0159:             * <p>Typically it is useful for debugging purposes. Example of correct usage:
0160:             * <pre>
0161:             * <font class="type">FileObject</font> <font class="variable-name">fo</font> = getSomeFileObject();
0162:             * ErrorManager.getDefault().log(<font class="string">"Got a change from "</font> + fo);
0163:             * </pre>
0164:             * @return some representation of this file object
0165:             */
0166:            public String toString() {
0167:                String cname = getClass().getName();
0168:                String cnameShort = cname.substring(cname.lastIndexOf('.') + 1);
0169:
0170:                try {
0171:                    return cnameShort
0172:                            + '@'
0173:                            + Integer
0174:                                    .toHexString(System.identityHashCode(this ))
0175:                            + '['
0176:                            + (isRoot() ? "root of " + getFileSystem()
0177:                                    : getPath()) + ']'; // NOI18N
0178:                } catch (FileStateInvalidException x) {
0179:                    return cnameShort
0180:                            + '@'
0181:                            + Integer
0182:                                    .toHexString(System.identityHashCode(this ))
0183:                            + "[???]"; // NOI18N
0184:                }
0185:            }
0186:
0187:            /** Get the full resource path of this file object starting from the filesystem root.
0188:             * Folders are separated with forward slashes. File extensions, if present,
0189:             * are included. The root folder's path is the empty string. The path of a folder
0190:             * never ends with a slash.
0191:             * <p>Subclasses are strongly encouraged to override this method.
0192:             * <p>Never use this to get a display name for the file! Use {@link FileUtil#getFileDisplayName}.
0193:             * <p>Do not use this method to find a file path on disk! Use {@link FileUtil#toFile}.
0194:             * @return the path, for example <samp>path/from/root.ext</samp>
0195:             * @see FileSystem#findResource
0196:             * @since 3.7
0197:             */
0198:            public String getPath() {
0199:                StringBuilder sb = new StringBuilder();
0200:                constructName(sb, '/');
0201:
0202:                return sb.toString();
0203:            }
0204:
0205:            /** Get fully-qualified filename. Does so by walking through all folders
0206:             * to the root of the filesystem. Separates files with provided <code>separatorChar</code>.
0207:             * The extension, if present, is separated from the basename with <code>extSepChar</code>.
0208:             * <p><strong>Note:</strong> <samp>fo.getPath()</samp> will have the
0209:             * same effect as using this method with <samp>/</samp> and <samp>.</samp> (the standard
0210:             * path and extension delimiters).
0211:             * @param separatorChar char to separate folders and files
0212:             * @param extSepChar char to separate extension
0213:             * @return the fully-qualified filename
0214:             * @deprecated Please use the <a href="@org-netbeans-api-java@/org/netbeans/api/java/classpath/ClassPath.html">ClassPath API</a> instead.
0215:             */
0216:            @Deprecated
0217:            public String getPackageNameExt(char separatorChar, char extSepChar) {
0218:                assert FileUtil.assertDeprecatedMethod();
0219:
0220:                StringBuilder sb = new StringBuilder();
0221:
0222:                if (isRoot() || getParent().isRoot()) {
0223:                    return getNameExt();
0224:                }
0225:
0226:                getParent().constructName(sb, separatorChar);
0227:
0228:                String ext = getExt();
0229:
0230:                if ((ext == null) || ext.equals("")) { // NOI18N
0231:                    sb.append(separatorChar).append(getNameExt());
0232:                } else {
0233:                    sb.append(separatorChar).append(getName()).append(
0234:                            extSepChar).append(getExt());
0235:                }
0236:
0237:                return sb.toString();
0238:            }
0239:
0240:            /** Get fully-qualified filename, but without extension.
0241:             * Like {@link #getPackageNameExt} but omits the extension.
0242:             * @param separatorChar char to separate folders and files
0243:             * @return the fully-qualified filename
0244:             * @deprecated Please use the <a href="@org-netbeans-api-java@/org/netbeans/api/java/classpath/ClassPath.html">ClassPath API</a> instead.
0245:             */
0246:            @Deprecated
0247:            public String getPackageName(char separatorChar) {
0248:                assert FileUtil.assertDeprecatedMethod();
0249:
0250:                StringBuilder sb = new StringBuilder();
0251:
0252:                if (isRoot() || getParent().isRoot()) {
0253:                    return (isFolder()) ? getNameExt() : getName();
0254:                }
0255:
0256:                getParent().constructName(sb, separatorChar);
0257:
0258:                //sb.append (separatorChar).append ((isFolder ()) ? getNameExt() : getName ());
0259:                sb.append(separatorChar).append(getName());
0260:
0261:                return sb.toString();
0262:            }
0263:
0264:            /** Getter for name and extension of a file object. Dot is used
0265:             * as separator between name and ext.
0266:             * @return string name of the file in the folder (with extension)
0267:             */
0268:            public String getNameExt() {
0269:                String n = getName();
0270:                String e = getExt();
0271:
0272:                return ((e == null) || (e.length() == 0)) ? n : (n + '.' + e);
0273:            }
0274:
0275:            /** Constructs path of file.
0276:             * @param sb string buffer
0277:             * @param sepChar separator character
0278:             */
0279:            private void constructName(StringBuilder sb, char sepChar) {
0280:                FileObject parent = getParent();
0281:
0282:                if ((parent != null) && !parent.isRoot()) {
0283:                    parent.constructName(sb, sepChar);
0284:                    sb.append(sepChar);
0285:                }
0286:
0287:                sb.append(getNameExt());
0288:            }
0289:
0290:            /** Get the filesystem containing this file.
0291:             * <p>
0292:             * Note that it may be possible for a stale file object to exist which refers to a now-defunct filesystem.
0293:             * If this is the case, this method will throw an exception.
0294:             * @return the filesystem
0295:             * @exception FileStateInvalidException if the reference to the file
0296:             *   system has been lost (e.g., if the filesystem was deleted)
0297:             */
0298:            public abstract FileSystem getFileSystem()
0299:                    throws FileStateInvalidException;
0300:
0301:            /** Get parent folder.
0302:             * The returned object will satisfy {@link #isFolder}.
0303:             *
0304:             * @return the parent folder or <code>null</code> if this object {@link #isRoot}.
0305:             */
0306:            public abstract FileObject getParent();
0307:
0308:            /** Test whether this object is a folder.
0309:             * @return true if the file object is a folder (i.e., can have children)
0310:             */
0311:            public abstract boolean isFolder();
0312:
0313:            /**
0314:             * Get last modification time.
0315:             * @return the date
0316:             */
0317:            public abstract java.util.Date lastModified();
0318:
0319:            /** Test whether this object is the root folder.
0320:             * The root should always be a folder.
0321:             * @return true if the object is the root of a filesystem
0322:             */
0323:            public abstract boolean isRoot();
0324:
0325:            /** Test whether this object is a data object.
0326:             * This is exclusive with {@link #isFolder}.
0327:             * @return true if the file object represents data (i.e., can be read and written)
0328:             */
0329:            public abstract boolean isData();
0330:
0331:            /** Test whether the file is valid. The file can be invalid if it has been deserialized
0332:             * and the file no longer exists on disk; or if the file has been deleted.
0333:             *
0334:             * @return true if the file object is valid
0335:             */
0336:            public abstract boolean isValid();
0337:
0338:            /** Test whether there is a file with the same basename and only a changed extension in the same folder.
0339:             * The default implementation asks this file's parent using {@link #getFileObject(String name, String ext)}.
0340:             *
0341:             * @param ext the alternate extension
0342:             * @return true if there is such a file
0343:             */
0344:            public boolean existsExt(String ext) {
0345:                FileObject parent = getParent();
0346:
0347:                return (parent != null)
0348:                        && (parent.getFileObject(getName(), ext) != null);
0349:            }
0350:
0351:            /** Delete this file. If the file is a folder and it is not empty then
0352:             * all of its contents are also recursively deleted.
0353:             *
0354:             * @param lock the lock obtained by a call to {@link #lock}
0355:             * @exception IOException if the file could not be deleted
0356:             */
0357:            public abstract void delete(FileLock lock) throws IOException;
0358:
0359:            /** Delete this file. If the file is a folder and it is not empty then
0360:             * all of its contents are also recursively deleted. FileObject is locked
0361:             * before delete and finally is this lock released.
0362:             *
0363:             * @exception IOException if the file could not be deleted or
0364:             * FileAlreadyLockedException if the file is already locked {@link #lock}
0365:             * @since 1.15
0366:             */
0367:            public final void delete() throws IOException {
0368:                FileLock lock = lock();
0369:
0370:                try {
0371:                    delete(lock);
0372:                } finally {
0373:                    lock.releaseLock();
0374:                }
0375:            }
0376:
0377:            /** Get the file attribute with the specified name.
0378:             * @param attrName name of the attribute
0379:             * @return appropriate (serializable) value or <CODE>null</CODE> if the attribute is unset (or could not be properly restored for some reason)
0380:             */
0381:            abstract public Object getAttribute(String attrName);
0382:
0383:            /** Set the file attribute with the specified name.
0384:             * @param attrName name of the attribute
0385:             * @param value new value or <code>null</code> to clear the attribute. Must be serializable, although particular filesystems may or may not use serialization to store attribute values.
0386:             * @exception IOException if the attribute cannot be set. If serialization is used to store it, this may in fact be a subclass such as {@link java.io.NotSerializableException}.
0387:             */
0388:            abstract public void setAttribute(String attrName, Object value)
0389:                    throws IOException;
0390:
0391:            /** Get all file attribute names for this file.
0392:             * @return enumeration of keys (as strings)
0393:             */
0394:            abstract public Enumeration<String> getAttributes();
0395:
0396:            /** Test whether this file has the specified extension.
0397:             * @param ext the extension the file should have
0398:             * @return true if the text after the last period (<code>.</code>) is equal to the given extension
0399:             */
0400:            public final boolean hasExt(String ext) {
0401:                if (isHasExtOverride()) {
0402:                    return hasExtOverride(ext);
0403:                }
0404:
0405:                return getExt().equals(ext);
0406:            }
0407:
0408:            /** Overriden in AbstractFolder */
0409:            boolean isHasExtOverride() {
0410:                return false;
0411:            }
0412:
0413:            /** Overridden in AbstractFolder */
0414:            boolean hasExtOverride(String ext) {
0415:                return false;
0416:            }
0417:
0418:            /** Add new listener to this object.
0419:             * @param fcl the listener
0420:             */
0421:            public abstract void addFileChangeListener(FileChangeListener fcl);
0422:
0423:            /** Remove listener from this object.
0424:             * @param fcl the listener
0425:             */
0426:            public abstract void removeFileChangeListener(FileChangeListener fcl);
0427:
0428:            /** Fire data creation event.
0429:             * @param en listeners that should receive the event
0430:             * @param fe the event to fire in this object
0431:             */
0432:            protected void fireFileDataCreatedEvent(
0433:                    Enumeration<FileChangeListener> en, FileEvent fe) {
0434:                dispatchEvent(FCLSupport.Op.DATA_CREATED, en, fe);
0435:            }
0436:
0437:            /** Fire folder creation event.
0438:             * @param en listeners that should receive the event
0439:             * @param fe the event to fire in this object
0440:             */
0441:            protected void fireFileFolderCreatedEvent(
0442:                    Enumeration<FileChangeListener> en, FileEvent fe) {
0443:                dispatchEvent(FCLSupport.Op.FOLDER_CREATED, en, fe);
0444:            }
0445:
0446:            /** Fire file change event.
0447:             * @param en listeners that should receive the event
0448:             * @param fe the event to fire in this object
0449:             */
0450:            protected void fireFileChangedEvent(
0451:                    Enumeration<FileChangeListener> en, FileEvent fe) {
0452:                dispatchEvent(FCLSupport.Op.FILE_CHANGED, en, fe);
0453:            }
0454:
0455:            /** Fire file deletion event.
0456:             * @param en listeners that should receive the event
0457:             * @param fe the event to fire in this object
0458:             */
0459:            protected void fireFileDeletedEvent(
0460:                    Enumeration<FileChangeListener> en, FileEvent fe) {
0461:                dispatchEvent(FCLSupport.Op.FILE_DELETED, en, fe);
0462:            }
0463:
0464:            /** Fire file attribute change event.
0465:             * @param en listeners that should receive the event
0466:             * @param fe the event to fire in this object
0467:             */
0468:            protected void fireFileAttributeChangedEvent(
0469:                    Enumeration<FileChangeListener> en, FileAttributeEvent fe) {
0470:                dispatchEvent(FCLSupport.Op.ATTR_CHANGED, en, fe);
0471:            }
0472:
0473:            /** Fire file rename event.
0474:             * @param en listeners that should receive the event
0475:             * @param fe the event to fire in this object
0476:             */
0477:            protected void fireFileRenamedEvent(
0478:                    Enumeration<FileChangeListener> en, FileRenameEvent fe) {
0479:                dispatchEvent(FCLSupport.Op.FILE_RENAMED, en, fe);
0480:            }
0481:
0482:            /** Puts the dispatch event into the filesystem.
0483:             */
0484:            private final void dispatchEvent(FCLSupport.Op op,
0485:                    Enumeration<FileChangeListener> en, FileEvent fe) {
0486:                try {
0487:                    FileSystem fs = getFileSystem();
0488:                    fs.dispatchEvent(new ED(op, en, fe));
0489:                } catch (FileStateInvalidException ex) {
0490:                    // no filesystem, no notification
0491:                }
0492:            }
0493:
0494:            final void dispatchEvent(Enumeration<FileChangeListener> en,
0495:                    FileEvent fe) {
0496:                try {
0497:                    getFileSystem().dispatchEvent(new ED(en, fe));
0498:                } catch (FileStateInvalidException ex) {
0499:                    // no filesystem, no notification
0500:                }
0501:            }
0502:
0503:            /** Get the MIME type of this file.
0504:             * The MIME type identifies the type of the file's contents and should be used in the same way as in the <B>Java
0505:             * Activation Framework</B> or in the {@link java.awt.datatransfer} package.
0506:             * <P>
0507:             * The default implementation calls {@link FileUtil#getMIMEType}.
0508:             * (As a fallback return value, <code>content/unknown</code> is used.)
0509:             * @return the MIME type textual representation, e.g. <code>"text/plain"</code>; never <code>null</code>
0510:             */
0511:            public String getMIMEType() {
0512:                return FileUtil.getMIMETypeOrDefault(this );
0513:            }
0514:
0515:            /** Get the size of the file.
0516:             * @return the size of the file in bytes or zero if the file does not contain data (does not
0517:             *  exist or is a folder).
0518:             */
0519:            public abstract long getSize();
0520:
0521:            /** Get input stream.
0522:             * @return an input stream to read the contents of this file
0523:             * @exception FileNotFoundException if the file does not exists, is a folder
0524:             * rather than a regular file  or is invalid
0525:             */
0526:            public abstract InputStream getInputStream()
0527:                    throws FileNotFoundException;
0528:
0529:            /** Get output stream.
0530:             * @param lock the lock that belongs to this file (obtained by a call to
0531:             *   {@link #lock})
0532:             * @return output stream to overwrite the contents of this file
0533:             * @exception IOException if an error occures (the file is invalid, etc.)
0534:             */
0535:            public abstract OutputStream getOutputStream(FileLock lock)
0536:                    throws IOException;
0537:
0538:            /** Get output stream.
0539:             * @return output stream to overwrite the contents of this file
0540:             * @throws IOException if an error occurs (the file is invalid, etc.)
0541:             * @throws FileAlreadyLockedException if the file is already locked
0542:             * @since 6.6
0543:             */
0544:            public final OutputStream getOutputStream()
0545:                    throws FileAlreadyLockedException, IOException {
0546:                final FileLock lock = lock();
0547:                final OutputStream os;
0548:                try {
0549:                    os = getOutputStream(lock);
0550:                    return new FilterOutputStream(os) {
0551:                        public void close() throws IOException {
0552:                            try {
0553:                                super .close();
0554:                                lock.releaseLock();
0555:                            } catch (IOException iex) {
0556:                                if (lock.isValid()) {
0557:                                    lock.releaseLock();
0558:                                }
0559:                                throw iex;
0560:                            }
0561:                        }
0562:                    };
0563:                } catch (IOException iex) {
0564:                    if (lock.isValid()) {
0565:                        lock.releaseLock();
0566:                    }
0567:                    throw iex;
0568:                }
0569:            }
0570:
0571:            /** Lock this file.
0572:             * @return lock that can be used to perform various modifications on the file
0573:             * @throws FileAlreadyLockedException if the file is already locked
0574:             * @throws UserQuestionException in case when the lock cannot be obtained now,
0575:             *    but the underlaying implementation is able to do it after some
0576:             *    complex/dangerous/long-lasting operation and request confirmation
0577:             *    from the user
0578:             *
0579:             */
0580:            public abstract FileLock lock() throws IOException;
0581:
0582:            /**
0583:             * Test if file is locked
0584:             * @return true if file is locked
0585:             * @since 7.3
0586:             */
0587:            public boolean isLocked() {
0588:                FileLock fLock = null;
0589:                try {
0590:                    fLock = lock();
0591:                } catch (FileAlreadyLockedException fax) {
0592:                    return true;
0593:                } catch (IOException ex) {
0594:                    return false;
0595:                } finally {
0596:                    if (fLock != null) {
0597:                        fLock.releaseLock();
0598:                    }
0599:                }
0600:                return fLock == null;
0601:            }
0602:
0603:            /** Indicate whether this file is important from a user perspective.
0604:             * This method allows a filesystem to distingush between important and
0605:             * unimportant files when this distinction is possible.
0606:             * <P>
0607:             * <em>For example:</em> Java sources have important <code>.java</code> files and
0608:             * unimportant <code>.class</code> files. If the filesystem provides
0609:             * an "archive" feature it should archive only <code>.java</code> files.
0610:             * @param b true if the file should be considered important
0611:             * @deprecated No longer used. Instead use
0612:             * <a href="@PROJECTS/QUERIES@/org/netbeans/api/queries/SharabilityQuery.html"><code>SharabilityQuery</code></a>.
0613:             */
0614:            @Deprecated
0615:            public abstract void setImportant(boolean b);
0616:
0617:            /** Get all children of this folder (files and subfolders). If the file does not have children
0618:             * (does not exist or is not a folder) then an empty array should be returned. No particular order is assumed.
0619:             *
0620:             * @return array of direct children
0621:             * @see #getChildren(boolean)
0622:             * @see #getFolders
0623:             * @see #getData
0624:             */
0625:            public abstract FileObject[] getChildren();
0626:
0627:            /** Enumerate all children of this folder. If the children should be enumerated
0628:             * recursively, first all direct children are listed; then children of direct subfolders; and so on.
0629:             *
0630:             * @param rec whether to enumerate recursively
0631:             * @return enumeration of type <code>FileObject</code>
0632:             */
0633:            public Enumeration<? extends FileObject> getChildren(
0634:                    final boolean rec) {
0635:                class WithChildren implements 
0636:                        Enumerations.Processor<FileObject, FileObject> {
0637:                    public FileObject process(FileObject fo,
0638:                            Collection<FileObject> toAdd) {
0639:                        if (rec && fo.isFolder()) {
0640:                            toAdd.addAll(Arrays.asList(fo.getChildren()));
0641:                        }
0642:
0643:                        return fo;
0644:                    }
0645:                }
0646:
0647:                return Enumerations.queue(Enumerations.array(getChildren()),
0648:                        new WithChildren());
0649:            }
0650:
0651:            /** Enumerate the subfolders of this folder.
0652:             * @param rec whether to recursively list subfolders
0653:             * @return enumeration of type <code>FileObject</code> (satisfying {@link #isFolder})
0654:             */
0655:            public Enumeration<? extends FileObject> getFolders(boolean rec) {
0656:                return Enumerations.filter(getChildren(rec), new OnlyFolders(
0657:                        true));
0658:            }
0659:
0660:            /** Enumerate all data files in this folder.
0661:             * @param rec whether to recursively search subfolders
0662:             * @return enumeration of type <code>FileObject</code> (satisfying {@link #isData})
0663:             */
0664:            public Enumeration<? extends FileObject> getData(boolean rec) {
0665:                return Enumerations.filter(getChildren(rec), new OnlyFolders(
0666:                        false));
0667:            }
0668:
0669:            /** Retrieve file or folder contained in this folder by name.
0670:             * <em>Note</em> that neither file nor folder is created on disk.
0671:             * @param name basename of the file or folder (in this folder)
0672:             * @param ext extension of the file; <CODE>null</CODE> or <code>""</code>
0673:             *    if the file should have no extension or if folder is requested
0674:             * @return the object representing this file or <CODE>null</CODE> if the file
0675:             *   or folder does not exist
0676:             * @exception IllegalArgumentException if <code>this</code> is not a folder
0677:             */
0678:            public abstract FileObject getFileObject(String name, String ext);
0679:
0680:            /** Retrieve file or folder relative to a current folder, with a given relative path.
0681:             * <em>Note</em> that neither file nor folder is created on disk. This method isn't final since revision 1.93.
0682:             * @param relativePath is just basename of the file or (since 4.16) the relative path delimited by '/'
0683:             * @return the object representing this file or <CODE>null</CODE> if the file
0684:             *   or folder does not exist
0685:             * @exception IllegalArgumentException if <code>this</code> is not a folder
0686:             */
0687:            public FileObject getFileObject(String relativePath) {
0688:                if (relativePath.startsWith("/")) {
0689:                    relativePath = relativePath.substring(1);
0690:                }
0691:
0692:                FileObject myObj = this ;
0693:                StringTokenizer st = new StringTokenizer(relativePath, "/");
0694:
0695:                while ((myObj != null) && st.hasMoreTokens()) {
0696:                    String nameExt = st.nextToken();
0697:                    myObj = myObj.getFileObject(nameExt, null);
0698:                }
0699:
0700:                return myObj;
0701:            }
0702:
0703:            /**
0704:             * Create a new folder below this one with the specified name.
0705:             * Fires {@link FileChangeListener#fileFolderCreated}.
0706:             *
0707:             * @param name the name of folder to create. Periods in name are allowed (but no slashes).
0708:             * @return the new folder
0709:             * @exception IOException if the folder cannot be created (e.g. already exists), or if <code>this</code> is not a folder
0710:             * @see FileUtil#createFolder
0711:             */
0712:            public abstract FileObject createFolder(String name)
0713:                    throws IOException;
0714:
0715:            /**
0716:             * Create new data file in this folder with the specified name.
0717:             * Fires {@link FileChangeListener#fileDataCreated}.
0718:             *
0719:             * @param name the name of data object to create (can contain a period, but no slashes)
0720:             * @param ext the extension of the file (or <code>null</code> or <code>""</code>)
0721:             * @return the new data file object
0722:             * @exception IOException if the file cannot be created (e.g. already exists), or if <code>this</code> is not a folder
0723:             * @see FileUtil#createData
0724:             */
0725:            public abstract FileObject createData(String name, String ext)
0726:                    throws IOException;
0727:
0728:            /**
0729:             * Create new data file in this folder with the specified name.
0730:             * Fires {@link FileChangeListener#fileDataCreated}.
0731:             *
0732:             * @param name the name of data object to create (can contain a period, but no slashes)
0733:             * @return the new data file object
0734:             * @exception IOException if the file cannot be created (e.g. already exists), or if <code>this</code> is not a folder
0735:             * @since 1.17
0736:             * @see FileUtil#createData
0737:             */
0738:            public FileObject createData(String name) throws IOException {
0739:                return createData(name, ""); // NOI18N        
0740:            }
0741:
0742:            /** Test whether this file can be written to or not.
0743:             * <P>
0744:             * The value returned from this method should indicate the capabilities of the
0745:             * file from the point of view of users of the FileObject's API, the actual
0746:             * state of the file on a disk does not matter if the implementation of the
0747:             * filesystem can change it when requested.
0748:             * <P>
0749:             * The result returned from this method should be tight together with
0750:             * the expected behaviour of <code>getOutputStream</code>. If it is
0751:             * likely that the method successfully returns a stream that can be
0752:             * written to, let the <code>isReadOnly</code> return <code>false</code>.
0753:             * <P>
0754:             * Also other fileobject methods like <code>delete</code>
0755:             * are suggested to be connected to result of this method. If not
0756:             * read only, then it can be deleted, etc.
0757:             * <p>
0758:             * It is a good idea to call this method before attempting to perform any
0759:             * operation on the FileObject that might throw an IOException simply
0760:             * because it is read-only. If isReadOnly returns true, the operation may
0761:             * be skipped, or the user notified that it cannot be done.
0762:             * <em>However</em> it is often desirable for the user to be able to
0763:             * continue the operation in case the filesystem supports making a file
0764:             * writable. In this case calling code should:
0765:             * <ol>
0766:             * <li>Call {@link #lock} and catch any exception thrown.
0767:             * <li>Then:
0768:             * <ul>
0769:             * <li>If no exception is thrown, proceed with the operation.
0770:             * <li>If a <code>UserQuestionException</code> is thrown,
0771:             * call {@link org.openide.util.UserQuestionException#confirmed} on it
0772:             * (asynchronously - do not block any important threads). If <code>true</code>,
0773:             * proceed with the operation. If <code>false</code>, exit.
0774:             * If an <code>IOException</code> is thrown, notify it and exit.
0775:             * <li>If another <code>IOException</code> is thrown, call {@link #isReadOnly}.
0776:             * If <code>true</code>, ignore the exception (it is expected).
0777:             * If <code>false</code>, notify it.
0778:             * </ul>
0779:             * In either case, exit.
0780:             * </ol>
0781:             * <p>
0782:             *
0783:             * @return <CODE>true</CODE> if file is read-only
0784:             * @deprecated Please use the {@link #canWrite}.
0785:             */
0786:            @Deprecated
0787:            public abstract boolean isReadOnly();
0788:
0789:            /**
0790:             * Tests if this file can be written to.
0791:             * <P>
0792:             * The default implementation simply uses <code> java.io.File.canWrite </code>
0793:             * if there exists conversion to <code> java.io.File</code> (see {@link FileUtil#toFile}).
0794:             * If conversion is not possible, then deprecated method {@link #isReadOnly} is used.
0795:             * @return true if this file can be written, false if not.
0796:             * @since 3.31
0797:             */
0798:            public boolean canWrite() {
0799:                File f = FileUtil.toFile(this );
0800:
0801:                if (f != null) {
0802:                    return f.canWrite();
0803:                }
0804:
0805:                return !isReadOnly();
0806:            }
0807:
0808:            /**
0809:             * Tests if this file can be read.
0810:             * <P>
0811:             * The default implementation simply uses <code> java.io.File.canRead </code>
0812:             * if there exists conversion to <code> java.io.File</code> (see {@link FileUtil#toFile}).
0813:             * If conversion is not possible, then <code>true </code> is returned.
0814:             * @return true if this file can be read, false if not.
0815:             * @since 3.31
0816:             */
0817:            public boolean canRead() {
0818:                File f = FileUtil.toFile(this );
0819:
0820:                if (f != null) {
0821:                    return f.canRead();
0822:                }
0823:
0824:                return true;
0825:            }
0826:
0827:            /** Should check for external modifications. For folders it should reread
0828:             * the content of disk, for data file it should check for the last
0829:             * time the file has been modified.
0830:             *
0831:             * @param expected should the file events be marked as expected change or not?
0832:             * @see FileEvent#isExpected
0833:             */
0834:            public void refresh(boolean expected) {
0835:            }
0836:
0837:            /** Should check for external modifications. For folders it should reread
0838:             * the content of disk, for data file it should check for the last
0839:             * time the file has been modified.
0840:             * <P>
0841:             * The file events are marked as unexpected.
0842:             */
0843:            public void refresh() {
0844:                refresh(false);
0845:            }
0846:
0847:            /** Get URL that can be used to access this file.
0848:             * If the file object does not correspond to a disk file or JAR entry,
0849:             * the URL will only be usable within NetBeans as it uses a special protocol handler.
0850:             * Otherwise an attempt is made to produce an external URL.
0851:             * @return URL of this file object
0852:             * @exception FileStateInvalidException if the file is not valid
0853:             * @see URLMapper#findURL
0854:             * @see URLMapper#INTERNAL
0855:             */
0856:            public final URL getURL() throws FileStateInvalidException {
0857:                // XXX why does this still throw FSIE? need not
0858:                return URLMapper.findURL(this , URLMapper.INTERNAL);
0859:            }
0860:
0861:            /**
0862:             * Tests if file really exists or is missing. Some operation on it may be restricted.
0863:             * @return true indicates that the file is missing.
0864:             * @since 1.9
0865:             */
0866:            public boolean isVirtual() {
0867:                return false;
0868:            }
0869:
0870:            /** Listeners registered from MultiFileObject are considered as priority
0871:             *  listeners.
0872:             */
0873:            static boolean isPriorityListener(FileChangeListener fcl) {
0874:                if (fcl instanceof  PriorityFileChangeListener) {
0875:                    return true;
0876:                } else {
0877:                    return false;
0878:                }
0879:            }
0880:
0881:            interface PriorityFileChangeListener extends FileChangeListener {
0882:            }
0883:
0884:            private class ED extends FileSystem.EventDispatcher {
0885:                private FCLSupport.Op op;
0886:                private Enumeration<FileChangeListener> en;
0887:                final private List<FileChangeListener> fsList;
0888:                final private List<FileChangeListener> repList;
0889:
0890:                private FileEvent fe;
0891:
0892:                public ED(FCLSupport.Op op, Enumeration<FileChangeListener> en,
0893:                        FileEvent fe) {
0894:                    this .op = op;
0895:                    this .en = en;
0896:                    this .fe = fe;
0897:                    FileSystem fs = null;
0898:                    try {
0899:                        fs = this .fe.getFile().getFileSystem();
0900:                    } catch (FileStateInvalidException ex) {
0901:                        ExternalUtil.exception(ex);
0902:                    }
0903:                    ListenerList<FileChangeListener> fsll = (fs != null) ? fs
0904:                            .getFCLSupport().listeners : null;
0905:                    ListenerList<FileChangeListener> repll = (fs != null && fs
0906:                            .getRepository() != null) ? fs.getRepository()
0907:                            .getFCLSupport().listeners : null;
0908:                    fsList = (fsll != null) ? new ArrayList<FileChangeListener>(
0909:                            fsll.getAllListeners())
0910:                            : new ArrayList<FileChangeListener>();
0911:                    repList = (repll != null) ? new ArrayList<FileChangeListener>(
0912:                            repll.getAllListeners())
0913:                            : new ArrayList<FileChangeListener>();
0914:
0915:                }
0916:
0917:                public ED(Enumeration<FileChangeListener> en, FileEvent fe) {
0918:                    this (null, en, fe);
0919:                }
0920:
0921:                /** @param onlyPriority if true then invokes only priority listeners
0922:                 *  else all listeners are invoked.
0923:                 */
0924:                protected void dispatch(boolean onlyPriority) {
0925:                    if (this .op == null) {
0926:                        this .op = fe.getFile().isFolder() ? FCLSupport.Op.FOLDER_CREATED
0927:                                : FCLSupport.Op.DATA_CREATED;
0928:                    }
0929:
0930:                    LinkedList<FileChangeListener> newEnum = new LinkedList<FileChangeListener>(); // later lazy                
0931:
0932:                    while (en.hasMoreElements()) {
0933:                        FileChangeListener fcl = en.nextElement();
0934:
0935:                        if (onlyPriority && !isPriorityListener(fcl)) {
0936:                            newEnum.add(fcl);
0937:
0938:                            continue;
0939:                        }
0940:                        FCLSupport.dispatchEvent(fcl, fe, op);
0941:                    }
0942:
0943:                    if (onlyPriority) {
0944:                        this .en = Collections.enumeration(newEnum);
0945:                    }
0946:
0947:                    /** FileEvents are forked in may cases. But FileEvents fired from
0948:                     * FileSystem and from Repository mustn`t be forked.
0949:                     */
0950:                    FileObject fo = fe.getFile();
0951:                    boolean transmit = false;
0952:                    if (fo != null) {
0953:                        switch (op) {
0954:                        case FILE_CHANGED:
0955:                            transmit = fo.equals(fe.getSource());
0956:                            break;
0957:                        default:
0958:                            transmit = !fo.equals(fe.getSource());
0959:                            if (!transmit && fe instanceof  Enumeration
0960:                                    && !((Enumeration) fe).hasMoreElements()) {
0961:                                transmit = true;
0962:                            }
0963:                        }
0964:
0965:                    }
0966:
0967:                    if (!en.hasMoreElements() && transmit && !onlyPriority) {
0968:                        FileSystem fs = null;
0969:                        Repository rep = null;
0970:
0971:                        try {
0972:                            fs = fe.getFile().getFileSystem();
0973:                            rep = fs.getRepository();
0974:                        } catch (FileStateInvalidException fsix) {
0975:                            return;
0976:                        }
0977:                        if (fs != null && fsList != null) {
0978:                            for (FileChangeListener fcl : fsList) {
0979:                                fs.getFCLSupport().dispatchEvent(fcl, fe, op);
0980:                            }
0981:                        }
0982:
0983:                        if (rep != null && repList != null) {
0984:                            for (FileChangeListener fcl : repList) {
0985:                                rep.getFCLSupport().dispatchEvent(fcl, fe, op);
0986:                            }
0987:                        }
0988:                    }
0989:                }
0990:
0991:                protected void setAtomicActionLink(
0992:                        EventControl.AtomicActionLink propID) {
0993:                    fe.setAtomicActionLink(propID);
0994:                }
0995:            }
0996:
0997:            /** Filters folders or data files.
0998:             */
0999:            private static final class OnlyFolders implements 
1000:                    Enumerations.Processor<FileObject, FileObject> {
1001:                private boolean folders;
1002:
1003:                public OnlyFolders(boolean folders) {
1004:                    this .folders = folders;
1005:                }
1006:
1007:                public FileObject process(FileObject obj,
1008:                        Collection<FileObject> coll) {
1009:                    FileObject fo = obj;
1010:
1011:                    if (folders) {
1012:                        return fo.isFolder() ? fo : null;
1013:                    } else {
1014:                        return fo.isData() ? fo : null;
1015:                    }
1016:                }
1017:            }
1018:            // end of OnlyFolders
1019:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.