Source Code Cross Referenced for AbstractFileObject.java in  » Library » Apache-commons-vfs-20070724-src » org » apache » commons » vfs » provider » 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 » Library » Apache commons vfs 20070724 src » org.apache.commons.vfs.provider 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Licensed to the Apache Software Foundation (ASF) under one or more
0003:         * contributor license agreements.  See the NOTICE file distributed with
0004:         * this work for additional information regarding copyright ownership.
0005:         * The ASF licenses this file to You under the Apache License, Version 2.0
0006:         * (the "License"); you may not use this file except in compliance with
0007:         * the License.  You may obtain a copy of the License at
0008:         *
0009:         *      http://www.apache.org/licenses/LICENSE-2.0
0010:         *
0011:         * Unless required by applicable law or agreed to in writing, software
0012:         * distributed under the License is distributed on an "AS IS" BASIS,
0013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014:         * See the License for the specific language governing permissions and
0015:         * limitations under the License.
0016:         */
0017:        package org.apache.commons.vfs.provider;
0018:
0019:        import org.apache.commons.vfs.Capability;
0020:        import org.apache.commons.vfs.FileContent;
0021:        import org.apache.commons.vfs.FileContentInfoFactory;
0022:        import org.apache.commons.vfs.FileName;
0023:        import org.apache.commons.vfs.FileObject;
0024:        import org.apache.commons.vfs.FileSelector;
0025:        import org.apache.commons.vfs.FileSystem;
0026:        import org.apache.commons.vfs.FileSystemException;
0027:        import org.apache.commons.vfs.FileType;
0028:        import org.apache.commons.vfs.FileUtil;
0029:        import org.apache.commons.vfs.NameScope;
0030:        import org.apache.commons.vfs.RandomAccessContent;
0031:        import org.apache.commons.vfs.Selectors;
0032:        import org.apache.commons.vfs.operations.DefaultFileOperations;
0033:        import org.apache.commons.vfs.operations.FileOperations;
0034:        import org.apache.commons.vfs.util.FileObjectUtils;
0035:        import org.apache.commons.vfs.util.RandomAccessMode;
0036:
0037:        import java.io.IOException;
0038:        import java.io.InputStream;
0039:        import java.io.OutputStream;
0040:        import java.net.MalformedURLException;
0041:        import java.net.URL;
0042:        import java.security.AccessController;
0043:        import java.security.PrivilegedActionException;
0044:        import java.security.PrivilegedExceptionAction;
0045:        import java.security.cert.Certificate;
0046:        import java.util.ArrayList;
0047:        import java.util.Arrays;
0048:        import java.util.Collections;
0049:        import java.util.List;
0050:        import java.util.Map;
0051:
0052:        /**
0053:         * A partial file object implementation.
0054:         *
0055:         * @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a>
0056:         * @author Gary D. Gregory
0057:         * @version $Revision: 537944 $ $Date: 2007-05-14 11:41:51 -0700 (Mon, 14 May 2007) $
0058:         * @todo Chop this class up - move all the protected methods to several
0059:         * interfaces, so that structure and content can be separately overridden.
0060:         * @todo Check caps in methods like getChildren(), etc, and give better error messages
0061:         * (eg 'this file type does not support listing children', vs 'this is not a folder')
0062:         */
0063:        public abstract class AbstractFileObject implements  FileObject {
0064:            // private static final FileObject[] EMPTY_FILE_ARRAY = {};
0065:            private static final FileName[] EMPTY_FILE_ARRAY = {};
0066:
0067:            private final AbstractFileName name;
0068:            private final AbstractFileSystem fs;
0069:
0070:            private FileContent content;
0071:
0072:            // Cached info
0073:            private boolean attached;
0074:            private FileType type;
0075:            private FileObject parent;
0076:
0077:            // Changed to hold only the name of the children and let the object
0078:            // go into the global files cache
0079:            // private FileObject[] children;
0080:            private FileName[] children;
0081:            private List objects;
0082:
0083:            /**
0084:             * FileServices instance.
0085:             */
0086:            private FileOperations operations;
0087:
0088:            protected AbstractFileObject(final FileName name,
0089:                    final AbstractFileSystem fs) {
0090:                this .name = (AbstractFileName) name;
0091:                this .fs = fs;
0092:                fs.fileObjectHanded(this );
0093:            }
0094:
0095:            /**
0096:             * Attaches this file object to its file resource.  This method is called
0097:             * before any of the doBlah() or onBlah() methods.  Sub-classes can use
0098:             * this method to perform lazy initialisation.
0099:             * <p/>
0100:             * This implementation does nothing.
0101:             */
0102:            protected void doAttach() throws Exception {
0103:            }
0104:
0105:            /**
0106:             * Detaches this file object from its file resource.
0107:             * <p/>
0108:             * <p>Called when this file is closed.  Note that the file object may be
0109:             * reused later, so should be able to be reattached.
0110:             * <p/>
0111:             * This implementation does nothing.
0112:             */
0113:            protected void doDetach() throws Exception {
0114:            }
0115:
0116:            /**
0117:             * Determines the type of this file.  Must not return null.  The return
0118:             * value of this method is cached, so the implementation can be expensive.
0119:             */
0120:            protected abstract FileType doGetType() throws Exception;
0121:
0122:            /**
0123:             * Determines if this file is hidden.  Is only called if {@link #doGetType}
0124:             * does not return {@link FileType#IMAGINARY}.
0125:             * <p/>
0126:             * This implementation always returns false.
0127:             */
0128:            protected boolean doIsHidden() throws Exception {
0129:                return false;
0130:            }
0131:
0132:            /**
0133:             * Determines if this file can be read.  Is only called if {@link #doGetType}
0134:             * does not return {@link FileType#IMAGINARY}.
0135:             * <p/>
0136:             * This implementation always returns true.
0137:             */
0138:            protected boolean doIsReadable() throws Exception {
0139:                return true;
0140:            }
0141:
0142:            /**
0143:             * Determines if this file can be written to.  Is only called if
0144:             * {@link #doGetType} does not return {@link FileType#IMAGINARY}.
0145:             * <p/>
0146:             * This implementation always returns true.
0147:             */
0148:            protected boolean doIsWriteable() throws Exception {
0149:                return true;
0150:            }
0151:
0152:            /**
0153:             * Lists the children of this file.  Is only called if {@link #doGetType}
0154:             * returns {@link FileType#FOLDER}.  The return value of this method
0155:             * is cached, so the implementation can be expensive.
0156:             */
0157:            protected abstract String[] doListChildren() throws Exception;
0158:
0159:            /**
0160:             * Lists the children of this file.  Is only called if {@link #doGetType}
0161:             * returns {@link FileType#FOLDER}.  The return value of this method
0162:             * is cached, so the implementation can be expensive.<br>
0163:             * Other than <code>doListChildren</code> you could return FileObject's to e.g. reinitialize the type of the file.<br>
0164:             * (Introduced for Webdav: "permission denied on resource" during getType())
0165:             */
0166:            protected FileObject[] doListChildrenResolved() throws Exception {
0167:                return null;
0168:            }
0169:
0170:            /**
0171:             * Deletes the file.  Is only called when:
0172:             * <ul>
0173:             * <li>{@link #doGetType} does not return {@link FileType#IMAGINARY}.
0174:             * <li>{@link #doIsWriteable} returns true.
0175:             * <li>This file has no children, if a folder.
0176:             * </ul>
0177:             * <p/>
0178:             * This implementation throws an exception.
0179:             */
0180:            protected void doDelete() throws Exception {
0181:                throw new FileSystemException(
0182:                        "vfs.provider/delete-not-supported.error");
0183:            }
0184:
0185:            /**
0186:             * Renames the file.  Is only called when:
0187:             * <ul>
0188:             * <li>{@link #doIsWriteable} returns true.
0189:             * </ul>
0190:             * <p/>
0191:             * This implementation throws an exception.
0192:             */
0193:            protected void doRename(FileObject newfile) throws Exception {
0194:                throw new FileSystemException(
0195:                        "vfs.provider/rename-not-supported.error");
0196:            }
0197:
0198:            /**
0199:             * Creates this file as a folder.  Is only called when:
0200:             * <ul>
0201:             * <li>{@link #doGetType} returns {@link FileType#IMAGINARY}.
0202:             * <li>The parent folder exists and is writeable, or this file is the
0203:             * root of the file system.
0204:             * </ul>
0205:             * <p/>
0206:             * This implementation throws an exception.
0207:             */
0208:            protected void doCreateFolder() throws Exception {
0209:                throw new FileSystemException(
0210:                        "vfs.provider/create-folder-not-supported.error");
0211:            }
0212:
0213:            /**
0214:             * Called when the children of this file change.  Allows subclasses to
0215:             * refresh any cached information about the children of this file.
0216:             * <p/>
0217:             * This implementation does nothing.
0218:             */
0219:            protected void onChildrenChanged(FileName child, FileType newType)
0220:                    throws Exception {
0221:            }
0222:
0223:            /**
0224:             * Called when the type or content of this file changes.
0225:             * <p/>
0226:             * This implementation does nothing.
0227:             */
0228:            protected void onChange() throws Exception {
0229:            }
0230:
0231:            /**
0232:             * Returns the last modified time of this file.  Is only called if
0233:             * {@link #doGetType} does not return {@link FileType#IMAGINARY}.
0234:             * <p/>
0235:             * This implementation throws an exception.
0236:             */
0237:            protected long doGetLastModifiedTime() throws Exception {
0238:                throw new FileSystemException(
0239:                        "vfs.provider/get-last-modified-not-supported.error");
0240:            }
0241:
0242:            /**
0243:             * Sets the last modified time of this file.  Is only called if
0244:             * {@link #doGetType} does not return {@link FileType#IMAGINARY}.
0245:             * <p/>
0246:             * This implementation throws an exception.
0247:             *
0248:             * @return false if it was not possible to change the time
0249:             */
0250:            protected boolean doSetLastModTime(final long modtime)
0251:                    throws Exception {
0252:                doSetLastModifiedTime(modtime);
0253:                return true;
0254:            }
0255:
0256:            /**
0257:             * Sets the last modified time of this file.  Is only called if
0258:             * {@link #doGetType} does not return {@link FileType#IMAGINARY}.
0259:             * <p/>
0260:             * This implementation throws an exception.
0261:             *
0262:             * @deprecated use {@link #doSetLastModTime}
0263:             */
0264:            protected void doSetLastModifiedTime(final long modtime)
0265:                    throws Exception {
0266:                throw new FileSystemException(
0267:                        "vfs.provider/set-last-modified-not-supported.error");
0268:            }
0269:
0270:            /**
0271:             * Returns the attributes of this file.  Is only called if {@link #doGetType}
0272:             * does not return {@link FileType#IMAGINARY}.
0273:             * <p/>
0274:             * This implementation always returns an empty map.
0275:             */
0276:            protected Map doGetAttributes() throws Exception {
0277:                return Collections.EMPTY_MAP;
0278:            }
0279:
0280:            /**
0281:             * Sets an attribute of this file.  Is only called if {@link #doGetType}
0282:             * does not return {@link FileType#IMAGINARY}.
0283:             * <p/>
0284:             * This implementation throws an exception.
0285:             */
0286:            protected void doSetAttribute(final String atttrName,
0287:                    final Object value) throws Exception {
0288:                throw new FileSystemException(
0289:                        "vfs.provider/set-attribute-not-supported.error");
0290:            }
0291:
0292:            /**
0293:             * Removes an attribute of this file.  Is only called if {@link #doGetType}
0294:             * does not return {@link FileType#IMAGINARY}.
0295:             * <p/>
0296:             * This implementation throws an exception.
0297:             * @returns true if removing the attribute succeed. In this case we remove the attribute from
0298:             * our cache
0299:             */
0300:            protected void doRemoveAttribute(final String atttrName)
0301:                    throws Exception {
0302:                throw new FileSystemException(
0303:                        "vfs.provider/remove-attribute-not-supported.error");
0304:            }
0305:
0306:            /**
0307:             * Returns the certificates used to sign this file.  Is only called if
0308:             * {@link #doGetType} does not return {@link FileType#IMAGINARY}.
0309:             * <p/>
0310:             * This implementation always returns null.
0311:             */
0312:            protected Certificate[] doGetCertificates() throws Exception {
0313:                return null;
0314:            }
0315:
0316:            /**
0317:             * Returns the size of the file content (in bytes).  Is only called if
0318:             * {@link #doGetType} returns {@link FileType#FILE}.
0319:             */
0320:            protected abstract long doGetContentSize() throws Exception;
0321:
0322:            /**
0323:             * Creates an input stream to read the file content from.  Is only called
0324:             * if {@link #doGetType} returns {@link FileType#FILE}.
0325:             * <p/>
0326:             * <p>It is guaranteed that there are no open output streams for this file
0327:             * when this method is called.
0328:             * <p/>
0329:             * <p>The returned stream does not have to be buffered.
0330:             */
0331:            protected abstract InputStream doGetInputStream() throws Exception;
0332:
0333:            /**
0334:             * Creates access to the file for random i/o.  Is only called
0335:             * if {@link #doGetType} returns {@link FileType#FILE}.
0336:             * <p/>
0337:             * <p>It is guaranteed that there are no open output streams for this file
0338:             * when this method is called.
0339:             * <p/>
0340:             */
0341:            protected RandomAccessContent doGetRandomAccessContent(
0342:                    final RandomAccessMode mode) throws Exception {
0343:                throw new FileSystemException(
0344:                        "vfs.provider/random-access-not-supported.error");
0345:            }
0346:
0347:            /**
0348:             * Creates an output stream to write the file content to.  Is only
0349:             * called if:
0350:             * <ul>
0351:             * <li>{@link #doIsWriteable} returns true.
0352:             * <li>{@link #doGetType} returns {@link FileType#FILE}, or
0353:             * {@link #doGetType} returns {@link FileType#IMAGINARY}, and the file's
0354:             * parent exists and is a folder.
0355:             * </ul>
0356:             * <p/>
0357:             * <p>It is guaranteed that there are no open stream (input or output) for
0358:             * this file when this method is called.
0359:             * <p/>
0360:             * <p>The returned stream does not have to be buffered.
0361:             * <p/>
0362:             * This implementation throws an exception.
0363:             */
0364:            protected OutputStream doGetOutputStream(boolean bAppend)
0365:                    throws Exception {
0366:                throw new FileSystemException(
0367:                        "vfs.provider/write-not-supported.error");
0368:            }
0369:
0370:            /**
0371:             * Returns the URI of the file.
0372:             */
0373:            public String toString() {
0374:                return name.getURI();
0375:            }
0376:
0377:            /**
0378:             * Returns the name of the file.
0379:             */
0380:            public FileName getName() {
0381:                return name;
0382:            }
0383:
0384:            /**
0385:             * Returns the file system this file belongs to.
0386:             */
0387:            public FileSystem getFileSystem() {
0388:                return fs;
0389:            }
0390:
0391:            /**
0392:             * Returns a URL representation of the file.
0393:             */
0394:            public URL getURL() throws FileSystemException {
0395:                final StringBuffer buf = new StringBuffer();
0396:                try {
0397:                    return (URL) AccessController
0398:                            .doPrivileged(new PrivilegedExceptionAction() {
0399:                                public Object run()
0400:                                        throws MalformedURLException {
0401:                                    return new URL(UriParser.extractScheme(name
0402:                                            .getURI(), buf), "", -1, buf
0403:                                            .toString(),
0404:                                            new DefaultURLStreamHandler(fs
0405:                                                    .getContext(), fs
0406:                                                    .getFileSystemOptions()));
0407:                                }
0408:                            });
0409:                } catch (final PrivilegedActionException e) {
0410:                    throw new FileSystemException("vfs.provider/get-url.error",
0411:                            name, e.getException());
0412:                }
0413:            }
0414:
0415:            /**
0416:             * Determines if the file exists.
0417:             */
0418:            public boolean exists() throws FileSystemException {
0419:                return (getType() != FileType.IMAGINARY);
0420:            }
0421:
0422:            /**
0423:             * Returns the file's type.
0424:             */
0425:            public FileType getType() throws FileSystemException {
0426:                synchronized (fs) {
0427:                    attach();
0428:                    return type;
0429:                }
0430:            }
0431:
0432:            /**
0433:             * Determines if this file can be read.
0434:             */
0435:            public boolean isHidden() throws FileSystemException {
0436:                try {
0437:                    if (exists()) {
0438:                        return doIsHidden();
0439:                    } else {
0440:                        return false;
0441:                    }
0442:                } catch (final Exception exc) {
0443:                    throw new FileSystemException(
0444:                            "vfs.provider/check-is-hidden.error", name, exc);
0445:                }
0446:            }
0447:
0448:            /**
0449:             * Determines if this file can be read.
0450:             */
0451:            public boolean isReadable() throws FileSystemException {
0452:                try {
0453:                    if (exists()) {
0454:                        return doIsReadable();
0455:                    } else {
0456:                        return false;
0457:                    }
0458:                } catch (final Exception exc) {
0459:                    throw new FileSystemException(
0460:                            "vfs.provider/check-is-readable.error", name, exc);
0461:                }
0462:            }
0463:
0464:            /**
0465:             * Determines if this file can be written to.
0466:             */
0467:            public boolean isWriteable() throws FileSystemException {
0468:                try {
0469:                    if (exists()) {
0470:                        return doIsWriteable();
0471:                    } else {
0472:                        final FileObject parent = getParent();
0473:                        if (parent != null) {
0474:                            return parent.isWriteable();
0475:                        }
0476:                        return true;
0477:                    }
0478:                } catch (final Exception exc) {
0479:                    throw new FileSystemException(
0480:                            "vfs.provider/check-is-writeable.error", name, exc);
0481:                }
0482:            }
0483:
0484:            /**
0485:             * Returns the parent of the file.
0486:             */
0487:            public FileObject getParent() throws FileSystemException {
0488:                if (this  == fs.getRoot()) {
0489:                    if (fs.getParentLayer() != null) {
0490:                        // Return the parent of the parent layer
0491:                        return fs.getParentLayer().getParent();
0492:                    } else {
0493:                        // Root file has no parent
0494:                        return null;
0495:                    }
0496:                }
0497:
0498:                synchronized (fs) {
0499:                    // Locate the parent of this file
0500:                    if (parent == null) {
0501:                        parent = (FileObject) fs.resolveFile(name.getParent());
0502:                    }
0503:                }
0504:                return parent;
0505:            }
0506:
0507:            /**
0508:             * Returns the children of the file.
0509:             */
0510:            public FileObject[] getChildren() throws FileSystemException {
0511:                synchronized (fs) {
0512:                    if (!getType().hasChildren()) {
0513:                        throw new FileSystemException(
0514:                                "vfs.provider/list-children-not-folder.error",
0515:                                name);
0516:                    }
0517:
0518:                    // Use cached info, if present
0519:                    if (children != null) {
0520:                        return resolveFiles(children);
0521:                    }
0522:
0523:                    // allow the filesystem to return resolved children. e.g. prefill type for webdav
0524:                    FileObject[] childrenObjects;
0525:                    try {
0526:                        childrenObjects = doListChildrenResolved();
0527:                        children = extractNames(childrenObjects);
0528:                    } catch (Exception exc) {
0529:                        throw new FileSystemException(
0530:                                "vfs.provider/list-children.error",
0531:                                new Object[] { name }, exc);
0532:                    }
0533:
0534:                    if (childrenObjects != null) {
0535:                        return childrenObjects;
0536:                    }
0537:
0538:                    // List the children
0539:                    final String[] files;
0540:                    try {
0541:                        files = doListChildren();
0542:                    } catch (Exception exc) {
0543:                        throw new FileSystemException(
0544:                                "vfs.provider/list-children.error",
0545:                                new Object[] { name }, exc);
0546:                    }
0547:
0548:                    if (files == null) {
0549:                        return null;
0550:                    } else if (files.length == 0) {
0551:                        // No children
0552:                        children = EMPTY_FILE_ARRAY;
0553:                    } else {
0554:                        // Create file objects for the children
0555:                        // children = new FileObject[files.length];
0556:                        children = new FileName[files.length];
0557:                        for (int i = 0; i < files.length; i++) {
0558:                            final String file = files[i];
0559:                            // children[i] = fs.resolveFile(name.resolveName(file, NameScope.CHILD));
0560:                            // children[i] = name.resolveName(file, NameScope.CHILD);
0561:                            children[i] = getFileSystem()
0562:                                    .getFileSystemManager().resolveName(name,
0563:                                            file, NameScope.CHILD);
0564:                        }
0565:                    }
0566:
0567:                    return resolveFiles(children);
0568:                }
0569:            }
0570:
0571:            private FileName[] extractNames(FileObject[] objects) {
0572:                if (objects == null) {
0573:                    return null;
0574:                }
0575:
0576:                FileName[] names = new FileName[objects.length];
0577:                for (int iterObjects = 0; iterObjects < objects.length; iterObjects++) {
0578:                    names[iterObjects] = objects[iterObjects].getName();
0579:                }
0580:
0581:                return names;
0582:            }
0583:
0584:            private FileObject[] resolveFiles(FileName[] children)
0585:                    throws FileSystemException {
0586:                if (children == null) {
0587:                    return null;
0588:                }
0589:
0590:                FileObject[] objects = new FileObject[children.length];
0591:                for (int iterChildren = 0; iterChildren < children.length; iterChildren++) {
0592:                    objects[iterChildren] = resolveFile(children[iterChildren]);
0593:                }
0594:
0595:                return objects;
0596:            }
0597:
0598:            private FileObject resolveFile(FileName child)
0599:                    throws FileSystemException {
0600:                return fs.resolveFile(child);
0601:            }
0602:
0603:            /**
0604:             * Returns a child of this file.
0605:             */
0606:            public FileObject getChild(final String name)
0607:                    throws FileSystemException {
0608:                // TODO - use a hashtable when there are a large number of children
0609:                FileObject[] children = getChildren();
0610:                for (int i = 0; i < children.length; i++) {
0611:                    // final FileObject child = children[i];
0612:                    final FileName child = children[i].getName();
0613:                    // TODO - use a comparator to compare names
0614:                    // if (child.getName().getBaseName().equals(name))
0615:                    if (child.getBaseName().equals(name)) {
0616:                        return resolveFile(child);
0617:                    }
0618:                }
0619:                return null;
0620:            }
0621:
0622:            /**
0623:             * Returns a child by name.
0624:             */
0625:            public FileObject resolveFile(final String name,
0626:                    final NameScope scope) throws FileSystemException {
0627:                // return fs.resolveFile(this.name.resolveName(name, scope));
0628:                return fs.resolveFile(getFileSystem().getFileSystemManager()
0629:                        .resolveName(this .name, name, scope));
0630:            }
0631:
0632:            /**
0633:             * Finds a file, relative to this file.
0634:             *
0635:             * @param path The path of the file to locate.  Can either be a relative
0636:             *             path, which is resolved relative to this file, or an
0637:             *             absolute path, which is resolved relative to the file system
0638:             *             that contains this file.
0639:             */
0640:            public FileObject resolveFile(final String path)
0641:                    throws FileSystemException {
0642:                final FileName otherName = getFileSystem()
0643:                        .getFileSystemManager().resolveName(name, path);
0644:                return fs.resolveFile(otherName);
0645:            }
0646:
0647:            /**
0648:             * Deletes this file, once all its children have been deleted
0649:             *
0650:             * @return true if this file has been deleted
0651:             */
0652:            private boolean deleteSelf() throws FileSystemException {
0653:                synchronized (fs) {
0654:                    /* Its possible to delete a read-only file if you have write-execute access to the directory
0655:                    if (!isWriteable())
0656:                    {
0657:                        throw new FileSystemException("vfs.provider/delete-read-only.error", name);
0658:                    }
0659:                     */
0660:
0661:                    if (getType() == FileType.IMAGINARY) {
0662:                        // File does not exist
0663:                        return false;
0664:                    }
0665:
0666:                    try {
0667:                        // Delete the file
0668:                        doDelete();
0669:
0670:                        // Update cached info
0671:                        handleDelete();
0672:                    } catch (final RuntimeException re) {
0673:                        throw re;
0674:                    } catch (final Exception exc) {
0675:                        throw new FileSystemException(
0676:                                "vfs.provider/delete.error",
0677:                                new Object[] { name }, exc);
0678:                    }
0679:
0680:                    return true;
0681:                }
0682:            }
0683:
0684:            /**
0685:             * Deletes this file.
0686:             *
0687:             * @return true if this object has been deleted
0688:             * @todo This will not fail if this is a non-empty folder.
0689:             */
0690:            public boolean delete() throws FileSystemException {
0691:                return delete(Selectors.SELECT_SELF) > 0;
0692:            }
0693:
0694:            /**
0695:             * Deletes this file, and all children.
0696:             *
0697:             * @return the number of deleted files
0698:             */
0699:            public int delete(final FileSelector selector)
0700:                    throws FileSystemException {
0701:                int nuofDeleted = 0;
0702:
0703:                if (getType() == FileType.IMAGINARY) {
0704:                    // File does not exist
0705:                    return nuofDeleted;
0706:                }
0707:
0708:                // Locate all the files to delete
0709:                ArrayList files = new ArrayList();
0710:                findFiles(selector, true, files);
0711:
0712:                // Delete 'em
0713:                final int count = files.size();
0714:                for (int i = 0; i < count; i++) {
0715:                    final AbstractFileObject file = FileObjectUtils
0716:                            .getAbstractFileObject((FileObject) files.get(i));
0717:                    // file.attach();
0718:
0719:                    // If the file is a folder, make sure all its children have been deleted
0720:                    if (file.getType().hasChildren()
0721:                            && file.getChildren().length != 0) {
0722:                        // Skip - as the selector forced us not to delete all files
0723:                        continue;
0724:                    }
0725:
0726:                    // Delete the file
0727:                    boolean deleted = file.deleteSelf();
0728:                    if (deleted) {
0729:                        nuofDeleted++;
0730:                    }
0731:                }
0732:
0733:                return nuofDeleted;
0734:            }
0735:
0736:            /**
0737:             * Creates this file, if it does not exist.
0738:             */
0739:            public void createFile() throws FileSystemException {
0740:                synchronized (fs) {
0741:                    try {
0742:                        if (exists() && !FileType.FILE.equals(getType())) {
0743:                            throw new FileSystemException(
0744:                                    "vfs.provider/create-file.error", name);
0745:                        }
0746:
0747:                        if (!exists()) {
0748:                            getOutputStream().close();
0749:                            endOutput();
0750:                        }
0751:                    } catch (final RuntimeException re) {
0752:                        throw re;
0753:                    } catch (final Exception e) {
0754:                        throw new FileSystemException(
0755:                                "vfs.provider/create-file.error", name, e);
0756:                    }
0757:                }
0758:            }
0759:
0760:            /**
0761:             * Creates this folder, if it does not exist.  Also creates any ancestor
0762:             * files which do not exist.
0763:             */
0764:            public void createFolder() throws FileSystemException {
0765:                synchronized (fs) {
0766:                    if (getType().hasChildren()) {
0767:                        // Already exists as correct type
0768:                        return;
0769:                    }
0770:                    if (getType() != FileType.IMAGINARY) {
0771:                        throw new FileSystemException(
0772:                                "vfs.provider/create-folder-mismatched-type.error",
0773:                                name);
0774:                    }
0775:                    if (!isWriteable()) {
0776:                        throw new FileSystemException(
0777:                                "vfs.provider/create-folder-read-only.error",
0778:                                name);
0779:                    }
0780:
0781:                    // Traverse up the heirarchy and make sure everything is a folder
0782:                    final FileObject parent = getParent();
0783:                    if (parent != null) {
0784:                        parent.createFolder();
0785:                    }
0786:
0787:                    try {
0788:                        // Create the folder
0789:                        doCreateFolder();
0790:
0791:                        // Update cached info
0792:                        handleCreate(FileType.FOLDER);
0793:                    } catch (final RuntimeException re) {
0794:                        throw re;
0795:                    } catch (final Exception exc) {
0796:                        throw new FileSystemException(
0797:                                "vfs.provider/create-folder.error", name, exc);
0798:                    }
0799:                }
0800:            }
0801:
0802:            /**
0803:             * Copies another file to this file.
0804:             */
0805:            public void copyFrom(final FileObject file,
0806:                    final FileSelector selector) throws FileSystemException {
0807:                if (!file.exists()) {
0808:                    throw new FileSystemException(
0809:                            "vfs.provider/copy-missing-file.error", file);
0810:                }
0811:                if (!isWriteable()) {
0812:                    throw new FileSystemException(
0813:                            "vfs.provider/copy-read-only.error", new Object[] {
0814:                                    file.getType(), file.getName(), this  },
0815:                            null);
0816:                }
0817:
0818:                // Locate the files to copy across
0819:                final ArrayList files = new ArrayList();
0820:                file.findFiles(selector, false, files);
0821:
0822:                // Copy everything across
0823:                final int count = files.size();
0824:                for (int i = 0; i < count; i++) {
0825:                    final FileObject srcFile = (FileObject) files.get(i);
0826:
0827:                    // Determine the destination file
0828:                    final String relPath = file.getName().getRelativeName(
0829:                            srcFile.getName());
0830:                    final FileObject destFile = resolveFile(relPath,
0831:                            NameScope.DESCENDENT_OR_SELF);
0832:
0833:                    // Clean up the destination file, if necessary
0834:                    if (destFile.exists()
0835:                            && destFile.getType() != srcFile.getType()) {
0836:                        // The destination file exists, and is not of the same type,
0837:                        // so delete it
0838:                        // TODO - add a pluggable policy for deleting and overwriting existing files
0839:                        destFile.delete(Selectors.SELECT_ALL);
0840:                    }
0841:
0842:                    // Copy across
0843:                    try {
0844:                        if (srcFile.getType().hasContent()) {
0845:                            FileUtil.copyContent(srcFile, destFile);
0846:                        } else if (srcFile.getType().hasChildren()) {
0847:                            destFile.createFolder();
0848:                        }
0849:                    } catch (final IOException e) {
0850:                        throw new FileSystemException(
0851:                                "vfs.provider/copy-file.error", new Object[] {
0852:                                        srcFile, destFile }, e);
0853:                    }
0854:                }
0855:            }
0856:
0857:            /**
0858:             * Moves (rename) the file to another one
0859:             */
0860:            public void moveTo(FileObject destFile) throws FileSystemException {
0861:                if (canRenameTo(destFile)) {
0862:                    if (!getParent().isWriteable()) {
0863:                        throw new FileSystemException(
0864:                                "vfs.provider/rename-parent-read-only.error",
0865:                                new FileName[] { getName(),
0866:                                        getParent().getName() });
0867:                    }
0868:                } else {
0869:                    if (!isWriteable()) {
0870:                        throw new FileSystemException(
0871:                                "vfs.provider/rename-read-only.error",
0872:                                getName());
0873:                    }
0874:                }
0875:
0876:                if (destFile.exists() && !isSameFile(destFile)) {
0877:                    destFile.delete(Selectors.SELECT_ALL);
0878:                    // throw new FileSystemException("vfs.provider/rename-dest-exists.error", destFile.getName());
0879:                }
0880:
0881:                if (canRenameTo(destFile)) {
0882:                    // issue rename on same filesystem
0883:                    try {
0884:                        attach();
0885:                        doRename(destFile);
0886:
0887:                        (FileObjectUtils.getAbstractFileObject(destFile))
0888:                                .handleCreate(getType());
0889:
0890:                        destFile.close(); // now the destFile is no longer imaginary. force reattach.
0891:
0892:                        handleDelete(); // fire delete-events. This file-object (src) is like deleted.
0893:                    } catch (final RuntimeException re) {
0894:                        throw re;
0895:                    } catch (final Exception exc) {
0896:                        throw new FileSystemException(
0897:                                "vfs.provider/rename.error", new Object[] {
0898:                                        getName(), destFile.getName() }, exc);
0899:                    }
0900:                } else {
0901:                    // different fs - do the copy/delete stuff
0902:
0903:                    destFile.copyFrom(this , Selectors.SELECT_SELF);
0904:
0905:                    if (((destFile.getType().hasContent() && destFile
0906:                            .getFileSystem().hasCapability(
0907:                                    Capability.SET_LAST_MODIFIED_FILE)) || (destFile
0908:                            .getType().hasChildren() && destFile
0909:                            .getFileSystem().hasCapability(
0910:                                    Capability.SET_LAST_MODIFIED_FOLDER)))
0911:                            && getFileSystem().hasCapability(
0912:                                    Capability.GET_LAST_MODIFIED)) {
0913:                        destFile.getContent().setLastModifiedTime(
0914:                                this .getContent().getLastModifiedTime());
0915:                    }
0916:
0917:                    deleteSelf();
0918:                }
0919:
0920:            }
0921:
0922:            /**
0923:             * Checks if this fileObject is the same file as <code>destFile</code> just with a different
0924:             * name.<br />
0925:             * E.g. for case insensitive filesystems like windows.
0926:             */
0927:            protected boolean isSameFile(FileObject destFile)
0928:                    throws FileSystemException {
0929:                attach();
0930:                return doIsSameFile(destFile);
0931:            }
0932:
0933:            /**
0934:             * Checks if this fileObject is the same file as <code>destFile</code> just with a different
0935:             * name.<br />
0936:             * E.g. for case insensitive filesystems like windows.
0937:             */
0938:            protected boolean doIsSameFile(FileObject destFile)
0939:                    throws FileSystemException {
0940:                return false;
0941:            }
0942:
0943:            /**
0944:             * Queries the object if a simple rename to the filename of <code>newfile</code>
0945:             * is possible.
0946:             *
0947:             * @param newfile the new filename
0948:             * @return true if rename is possible
0949:             */
0950:            public boolean canRenameTo(FileObject newfile) {
0951:                if (getFileSystem() == newfile.getFileSystem()) {
0952:                    return true;
0953:                }
0954:
0955:                return false;
0956:            }
0957:
0958:            /**
0959:             * Finds the set of matching descendents of this file, in depthwise
0960:             * order.
0961:             *
0962:             * @return list of files or null if the base file (this object) do not exist
0963:             */
0964:            public FileObject[] findFiles(final FileSelector selector)
0965:                    throws FileSystemException {
0966:                if (!exists()) {
0967:                    return null;
0968:                }
0969:
0970:                final ArrayList list = new ArrayList();
0971:                findFiles(selector, true, list);
0972:                return (FileObject[]) list.toArray(new FileObject[list.size()]);
0973:            }
0974:
0975:            /**
0976:             * Returns the file's content.
0977:             */
0978:            public FileContent getContent() throws FileSystemException {
0979:                synchronized (fs) {
0980:                    attach();
0981:                    if (content == null) {
0982:                        content = doCreateFileContent();
0983:                    }
0984:                    return content;
0985:                }
0986:            }
0987:
0988:            /**
0989:             * Create a FileContent implementation
0990:             */
0991:            protected FileContent doCreateFileContent()
0992:                    throws FileSystemException {
0993:                return new DefaultFileContent(this , getFileContentInfoFactory());
0994:            }
0995:
0996:            /**
0997:             * This will prepare the fileObject to get resynchronized with the underlaying filesystem if required
0998:             */
0999:            public void refresh() throws FileSystemException {
1000:                // Detach from the file
1001:                try {
1002:                    detach();
1003:                } catch (final Exception e) {
1004:                    throw new FileSystemException("vfs.provider/resync.error",
1005:                            name, e);
1006:                }
1007:            }
1008:
1009:            /**
1010:             * Closes this file, and its content.
1011:             */
1012:            public void close() throws FileSystemException {
1013:                FileSystemException exc = null;
1014:
1015:                // Close the content
1016:                if (content != null) {
1017:                    try {
1018:                        content.close();
1019:                        content = null;
1020:                    } catch (FileSystemException e) {
1021:                        exc = e;
1022:                    }
1023:                }
1024:
1025:                // Detach from the file
1026:                try {
1027:                    detach();
1028:                } catch (final Exception e) {
1029:                    exc = new FileSystemException("vfs.provider/close.error",
1030:                            name, e);
1031:                }
1032:
1033:                if (exc != null) {
1034:                    throw exc;
1035:                }
1036:            }
1037:
1038:            /**
1039:             * Returns an input stream to use to read the content of the file.
1040:             */
1041:            public InputStream getInputStream() throws FileSystemException {
1042:                if (!getType().hasContent()) {
1043:                    throw new FileSystemException(
1044:                            "vfs.provider/read-not-file.error", name);
1045:                }
1046:                if (!isReadable()) {
1047:                    throw new FileSystemException(
1048:                            "vfs.provider/read-not-readable.error", name);
1049:                }
1050:
1051:                // Get the raw input stream
1052:                try {
1053:                    return doGetInputStream();
1054:                } catch (final Exception exc) {
1055:                    throw new FileSystemException("vfs.provider/read.error",
1056:                            name, exc);
1057:                }
1058:            }
1059:
1060:            /**
1061:             * Returns an input/output stream to use to read and write the content of the file in and
1062:             * random manner.
1063:             */
1064:            public RandomAccessContent getRandomAccessContent(
1065:                    final RandomAccessMode mode) throws FileSystemException {
1066:                if (!getType().hasContent()) {
1067:                    throw new FileSystemException(
1068:                            "vfs.provider/read-not-file.error", name);
1069:                }
1070:
1071:                if (mode.requestRead()) {
1072:                    if (!getFileSystem().hasCapability(
1073:                            Capability.RANDOM_ACCESS_READ)) {
1074:                        throw new FileSystemException(
1075:                                "vfs.provider/random-access-read-not-supported.error");
1076:                    }
1077:                    if (!isReadable()) {
1078:                        throw new FileSystemException(
1079:                                "vfs.provider/read-not-readable.error", name);
1080:                    }
1081:                }
1082:
1083:                if (mode.requestWrite()) {
1084:                    if (!getFileSystem().hasCapability(
1085:                            Capability.RANDOM_ACCESS_WRITE)) {
1086:                        throw new FileSystemException(
1087:                                "vfs.provider/random-access-write-not-supported.error");
1088:                    }
1089:                    if (!isWriteable()) {
1090:                        throw new FileSystemException(
1091:                                "vfs.provider/write-read-only.error", name);
1092:                    }
1093:                }
1094:
1095:                // Get the raw input stream
1096:                try {
1097:                    return doGetRandomAccessContent(mode);
1098:                } catch (final Exception exc) {
1099:                    throw new FileSystemException(
1100:                            "vfs.provider/random-access.error", name, exc);
1101:                }
1102:            }
1103:
1104:            /**
1105:             * Prepares this file for writing.  Makes sure it is either a file,
1106:             * or its parent folder exists.  Returns an output stream to use to
1107:             * write the content of the file to.
1108:             */
1109:            public OutputStream getOutputStream() throws FileSystemException {
1110:                return getOutputStream(false);
1111:            }
1112:
1113:            /**
1114:             * Prepares this file for writing.  Makes sure it is either a file,
1115:             * or its parent folder exists.  Returns an output stream to use to
1116:             * write the content of the file to.<br>
1117:             *
1118:             * @param bAppend true when append to the file.<br>
1119:             *                Note: If the underlaying filesystem do not support this, it wont work.
1120:             */
1121:            public OutputStream getOutputStream(boolean bAppend)
1122:                    throws FileSystemException {
1123:                if (getType() != FileType.IMAGINARY && !getType().hasContent()) {
1124:                    throw new FileSystemException(
1125:                            "vfs.provider/write-not-file.error", name);
1126:                }
1127:                if (!isWriteable()) {
1128:                    throw new FileSystemException(
1129:                            "vfs.provider/write-read-only.error", name);
1130:                }
1131:                if (bAppend
1132:                        && !getFileSystem().hasCapability(
1133:                                Capability.APPEND_CONTENT)) {
1134:                    throw new FileSystemException(
1135:                            "vfs.provider/write-append-not-supported.error",
1136:                            name);
1137:                }
1138:
1139:                if (getType() == FileType.IMAGINARY) {
1140:                    // Does not exist - make sure parent does
1141:                    FileObject parent = getParent();
1142:                    if (parent != null) {
1143:                        parent.createFolder();
1144:                    }
1145:                }
1146:
1147:                // Get the raw output stream
1148:                try {
1149:                    return doGetOutputStream(bAppend);
1150:                } catch (RuntimeException re) {
1151:                    throw re;
1152:                } catch (Exception exc) {
1153:                    throw new FileSystemException("vfs.provider/write.error",
1154:                            new Object[] { name }, exc);
1155:                }
1156:            }
1157:
1158:            /**
1159:             * Detaches this file, invaliating all cached info.  This will force
1160:             * a call to {@link #doAttach} next time this file is used.
1161:             */
1162:            private void detach() throws Exception {
1163:                synchronized (fs) {
1164:                    if (attached) {
1165:                        try {
1166:                            doDetach();
1167:                        } finally {
1168:                            attached = false;
1169:                            setFileType(null);
1170:                            parent = null;
1171:
1172:                            // fs.fileDetached(this);
1173:
1174:                            removeChildrenCache();
1175:                            // children = null;
1176:                        }
1177:                    }
1178:                }
1179:            }
1180:
1181:            private void removeChildrenCache() {
1182:                /*
1183:                if (children != null)
1184:                {
1185:                    for (int iterChildren = 0; iterChildren < children.length; iterChildren++)
1186:                    {
1187:                        fs.removeFileFromCache(children[iterChildren].getName());
1188:                    }
1189:
1190:                    children = null;
1191:                }
1192:                 */
1193:                children = null;
1194:            }
1195:
1196:            /**
1197:             * Attaches to the file.
1198:             */
1199:            private void attach() throws FileSystemException {
1200:                synchronized (fs) {
1201:                    if (attached) {
1202:                        return;
1203:                    }
1204:
1205:                    try {
1206:                        // Attach and determine the file type
1207:                        doAttach();
1208:                        attached = true;
1209:                        // now the type could already be injected by doAttach (e.g from parent to child)
1210:                        if (type == null) {
1211:                            setFileType(doGetType());
1212:                        }
1213:                        if (type == null) {
1214:                            setFileType(FileType.IMAGINARY);
1215:                        }
1216:                    } catch (Exception exc) {
1217:                        throw new FileSystemException(
1218:                                "vfs.provider/get-type.error",
1219:                                new Object[] { name }, exc);
1220:                    }
1221:
1222:                    // fs.fileAttached(this);
1223:                }
1224:            }
1225:
1226:            /**
1227:             * Called when the ouput stream for this file is closed.
1228:             */
1229:            protected void endOutput() throws Exception {
1230:                if (getType() == FileType.IMAGINARY) {
1231:                    // File was created
1232:                    handleCreate(FileType.FILE);
1233:                } else {
1234:                    // File has changed
1235:                    onChange();
1236:                }
1237:            }
1238:
1239:            /**
1240:             * Called when this file is created.  Updates cached info and notifies
1241:             * the parent and file system.
1242:             */
1243:            protected void handleCreate(final FileType newType)
1244:                    throws Exception {
1245:                synchronized (fs) {
1246:                    if (attached) {
1247:                        // Fix up state
1248:                        injectType(newType);
1249:
1250:                        removeChildrenCache();
1251:                        // children = EMPTY_FILE_ARRAY;
1252:
1253:                        // Notify subclass
1254:                        onChange();
1255:                    }
1256:
1257:                    // Notify parent that its child list may no longer be valid
1258:                    notifyParent(this .getName(), newType);
1259:
1260:                    // Notify the file system
1261:                    fs.fireFileCreated(this );
1262:                }
1263:            }
1264:
1265:            /**
1266:             * Called when this file is deleted.  Updates cached info and notifies
1267:             * subclasses, parent and file system.
1268:             */
1269:            protected void handleDelete() throws Exception {
1270:                synchronized (fs) {
1271:                    if (attached) {
1272:                        // Fix up state
1273:                        injectType(FileType.IMAGINARY);
1274:                        removeChildrenCache();
1275:                        // children = null;
1276:
1277:                        // Notify subclass
1278:                        onChange();
1279:                    }
1280:
1281:                    // Notify parent that its child list may no longer be valid
1282:                    notifyParent(this .getName(), FileType.IMAGINARY);
1283:
1284:                    // Notify the file system
1285:                    fs.fireFileDeleted(this );
1286:                }
1287:            }
1288:
1289:            /**
1290:             * Called when this file is changed.<br />
1291:             * This will only happen if you monitor the file using {@link org.apache.commons.vfs.FileMonitor}.
1292:             */
1293:            protected void handleChanged() throws Exception {
1294:                // Notify the file system
1295:                fs.fireFileChanged(this );
1296:            }
1297:
1298:            /**
1299:             * Notifies the file that its children have changed.
1300:             *
1301:             * @deprecated use {@link #childrenChanged(FileName,FileType)}
1302:             */
1303:            protected void childrenChanged() throws Exception {
1304:                childrenChanged(null, null);
1305:            }
1306:
1307:            /**
1308:             * Notifies the file that its children have changed.
1309:             */
1310:            protected void childrenChanged(FileName childName, FileType newType)
1311:                    throws Exception {
1312:                // TODO - this may be called when not attached
1313:
1314:                if (children != null) {
1315:                    if (childName != null && newType != null) {
1316:                        // TODO - figure out if children[] can be replaced by list
1317:                        ArrayList list = new ArrayList(Arrays.asList(children));
1318:                        if (newType.equals(FileType.IMAGINARY)) {
1319:                            list.remove(childName);
1320:                        } else {
1321:                            list.add(childName);
1322:                        }
1323:                        children = new FileName[list.size()];
1324:                        list.toArray(children);
1325:                    }
1326:                }
1327:
1328:                // removeChildrenCache();
1329:                onChildrenChanged(childName, newType);
1330:            }
1331:
1332:            /**
1333:             * Notify the parent of a change to its children, when a child is created
1334:             * or deleted.
1335:             */
1336:            private void notifyParent(FileName childName, FileType newType)
1337:                    throws Exception {
1338:                if (parent == null) {
1339:                    FileName parentName = name.getParent();
1340:                    if (parentName != null) {
1341:                        // Locate the parent, if it is cached
1342:                        parent = fs.getFileFromCache(parentName);
1343:                    }
1344:                }
1345:
1346:                if (parent != null) {
1347:                    FileObjectUtils.getAbstractFileObject(parent)
1348:                            .childrenChanged(childName, newType);
1349:                }
1350:            }
1351:
1352:            /**
1353:             * Traverses the descendents of this file, and builds a list of selected
1354:             * files.
1355:             */
1356:            public void findFiles(final FileSelector selector,
1357:                    final boolean depthwise, final List selected)
1358:                    throws FileSystemException {
1359:                try {
1360:                    if (exists()) {
1361:                        // Traverse starting at this file
1362:                        final DefaultFileSelectorInfo info = new DefaultFileSelectorInfo();
1363:                        info.setBaseFolder(this );
1364:                        info.setDepth(0);
1365:                        info.setFile(this );
1366:                        traverse(info, selector, depthwise, selected);
1367:                    }
1368:                } catch (final Exception e) {
1369:                    throw new FileSystemException(
1370:                            "vfs.provider/find-files.error", name, e);
1371:                }
1372:            }
1373:
1374:            /**
1375:             * Traverses a file.
1376:             */
1377:            private static void traverse(
1378:                    final DefaultFileSelectorInfo fileInfo,
1379:                    final FileSelector selector, final boolean depthwise,
1380:                    final List selected) throws Exception {
1381:                // Check the file itself
1382:                final FileObject file = fileInfo.getFile();
1383:                final int index = selected.size();
1384:
1385:                // If the file is a folder, traverse it
1386:                if (file.getType().hasChildren()
1387:                        && selector.traverseDescendents(fileInfo)) {
1388:                    final int curDepth = fileInfo.getDepth();
1389:                    fileInfo.setDepth(curDepth + 1);
1390:
1391:                    // Traverse the children
1392:                    final FileObject[] children = file.getChildren();
1393:                    for (int i = 0; i < children.length; i++) {
1394:                        final FileObject child = children[i];
1395:                        fileInfo.setFile(child);
1396:                        traverse(fileInfo, selector, depthwise, selected);
1397:                    }
1398:
1399:                    fileInfo.setFile(file);
1400:                    fileInfo.setDepth(curDepth);
1401:                }
1402:
1403:                // Add the file if doing depthwise traversal
1404:                if (selector.includeFile(fileInfo)) {
1405:                    if (depthwise) {
1406:                        // Add this file after its descendents
1407:                        selected.add(file);
1408:                    } else {
1409:                        // Add this file before its descendents
1410:                        selected.add(index, file);
1411:                    }
1412:                }
1413:            }
1414:
1415:            /**
1416:             * Check if the content stream is open
1417:             *
1418:             * @return true if this is the case
1419:             */
1420:            public boolean isContentOpen() {
1421:                if (content == null) {
1422:                    return false;
1423:                }
1424:
1425:                return content.isOpen();
1426:            }
1427:
1428:            /**
1429:             * Check if the internal state is "attached"
1430:             *
1431:             * @return true if this is the case
1432:             */
1433:            public boolean isAttached() {
1434:                return attached;
1435:            }
1436:
1437:            /**
1438:             * create the filecontentinfo implementation
1439:             */
1440:            protected FileContentInfoFactory getFileContentInfoFactory() {
1441:                return getFileSystem().getFileSystemManager()
1442:                        .getFileContentInfoFactory();
1443:            }
1444:
1445:            protected void injectType(FileType fileType) {
1446:                setFileType(fileType);
1447:            }
1448:
1449:            private void setFileType(FileType type) {
1450:                if (type != null && type != FileType.IMAGINARY) {
1451:                    try {
1452:                        name.setType(type);
1453:                    } catch (FileSystemException e) {
1454:                        throw new RuntimeException(e.getMessage());
1455:                    }
1456:                }
1457:                this .type = type;
1458:            }
1459:
1460:            /**
1461:             * This method is meant to add a object where this object holds a strong reference then.
1462:             * E.g. a archive-filesystem creates a list of all childs and they shouldnt get
1463:             * garbage collected until the container is garbage collected
1464:             *
1465:             * @param strongRef
1466:             */
1467:            public void holdObject(Object strongRef) {
1468:                if (objects == null) {
1469:                    objects = new ArrayList(5);
1470:                }
1471:                objects.add(strongRef);
1472:            }
1473:
1474:            /**
1475:             * will be called after this file-object closed all its streams.
1476:             */
1477:            protected void notifyAllStreamsClosed() {
1478:            }
1479:
1480:            // --- OPERATIONS ---
1481:
1482:            /**
1483:             * @return FileOperations interface that provides access to the operations
1484:             *         API.
1485:             * @throws FileSystemException
1486:             */
1487:            public FileOperations getFileOperations()
1488:                    throws FileSystemException {
1489:                if (operations == null) {
1490:                    operations = new DefaultFileOperations(this );
1491:                }
1492:
1493:                return operations;
1494:            }
1495:
1496:            protected void finalize() throws Throwable {
1497:                fs.fileObjectDestroyed(this);
1498:
1499:                super.finalize();
1500:            }
1501:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.