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


001:        /*
002:         * Licensed to the Apache Software Foundation (ASF) under one or more
003:         * contributor license agreements.  See the NOTICE file distributed with
004:         * this work for additional information regarding copyright ownership.
005:         * The ASF licenses this file to You under the Apache License, Version 2.0
006:         * (the "License"); you may not use this file except in compliance with
007:         * the License.  You may obtain a copy of the License at
008:         *
009:         *      http://www.apache.org/licenses/LICENSE-2.0
010:         *
011:         * Unless required by applicable law or agreed to in writing, software
012:         * distributed under the License is distributed on an "AS IS" BASIS,
013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         * See the License for the specific language governing permissions and
015:         * limitations under the License.
016:         */
017:        package org.apache.commons.vfs.provider.ftp;
018:
019:        import org.apache.commons.logging.Log;
020:        import org.apache.commons.logging.LogFactory;
021:        import org.apache.commons.net.ftp.FTPFile;
022:        import org.apache.commons.vfs.FileName;
023:        import org.apache.commons.vfs.FileObject;
024:        import org.apache.commons.vfs.FileSystemException;
025:        import org.apache.commons.vfs.FileType;
026:        import org.apache.commons.vfs.RandomAccessContent;
027:        import org.apache.commons.vfs.provider.AbstractFileObject;
028:        import org.apache.commons.vfs.provider.UriParser;
029:        import org.apache.commons.vfs.util.Messages;
030:        import org.apache.commons.vfs.util.MonitorInputStream;
031:        import org.apache.commons.vfs.util.MonitorOutputStream;
032:        import org.apache.commons.vfs.util.RandomAccessMode;
033:        import org.apache.commons.vfs.util.FileObjectUtils;
034:
035:        import java.io.IOException;
036:        import java.io.InputStream;
037:        import java.io.OutputStream;
038:        import java.util.Calendar;
039:        import java.util.Collections;
040:        import java.util.Iterator;
041:        import java.util.Map;
042:        import java.util.TreeMap;
043:
044:        /**
045:         * An FTP file.
046:         *
047:         * @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a>
048:         * @version $Revision: 520100 $ $Date: 2007-03-19 13:54:27 -0700 (Mon, 19 Mar 2007) $
049:         */
050:        public class FtpFileObject extends AbstractFileObject {
051:            private Log log = LogFactory.getLog(FtpFileObject.class);
052:
053:            private static final Map EMPTY_FTP_FILE_MAP = Collections
054:                    .unmodifiableMap(new TreeMap());
055:
056:            private final FtpFileSystem ftpFs;
057:            private final String relPath;
058:
059:            // Cached info
060:            private FTPFile fileInfo;
061:            private Map children;
062:            private FileObject linkDestination;
063:
064:            private boolean inRefresh = false;
065:
066:            protected FtpFileObject(final FileName name,
067:                    final FtpFileSystem fileSystem, final FileName rootName)
068:                    throws FileSystemException {
069:                super (name, fileSystem);
070:                ftpFs = fileSystem;
071:                String relPath = UriParser.decode(rootName
072:                        .getRelativeName(name));
073:                if (".".equals(relPath)) {
074:                    // do not use the "." as path against the ftp-server
075:                    // e.g. the uu.net ftp-server do a recursive listing then
076:                    // this.relPath = UriParser.decode(rootName.getPath());
077:                    // this.relPath = ".";
078:                    this .relPath = null;
079:                } else {
080:                    this .relPath = relPath;
081:                }
082:            }
083:
084:            /**
085:             * Called by child file objects, to locate their ftp file info.
086:             *
087:             * @param name  the filename in its native form ie. without uri stuff (%nn)
088:             * @param flush recreate children cache
089:             */
090:            private FTPFile getChildFile(final String name, final boolean flush)
091:                    throws IOException {
092:                /* If we should flush cached children, clear our children map unless
093:                 * we're in the middle of a refresh in which case we've just recently
094:                 * refreshed our children. No need to do it again when our children are
095:                 * refresh()ed, calling getChildFile() for themselves from within
096:                 * getInfo(). See getChildren(). */
097:                if (flush && !inRefresh) {
098:                    children = null;
099:                }
100:
101:                // List the children of this file
102:                doGetChildren();
103:
104:                // Look for the requested child
105:                FTPFile ftpFile = (FTPFile) children.get(name);
106:                return ftpFile;
107:            }
108:
109:            /**
110:             * Fetches the children of this file, if not already cached.
111:             */
112:            private void doGetChildren() throws IOException {
113:                if (children != null) {
114:                    return;
115:                }
116:
117:                final FtpClient client = ftpFs.getClient();
118:                try {
119:                    final FTPFile[] tmpChildren = client.listFiles(relPath);
120:                    if (tmpChildren == null || tmpChildren.length == 0) {
121:                        children = EMPTY_FTP_FILE_MAP;
122:                    } else {
123:                        children = new TreeMap();
124:
125:                        // Remove '.' and '..' elements
126:                        for (int i = 0; i < tmpChildren.length; i++) {
127:                            final FTPFile child = tmpChildren[i];
128:                            if (child == null) {
129:                                if (log.isDebugEnabled()) {
130:                                    log
131:                                            .debug(Messages
132:                                                    .getString(
133:                                                            "vfs.provider.ftp/invalid-directory-entry.debug",
134:                                                            new Object[] {
135:                                                                    new Integer(
136:                                                                            i),
137:                                                                    relPath }));
138:                                }
139:                                continue;
140:                            }
141:                            if (!".".equals(child.getName())
142:                                    && !"..".equals(child.getName())) {
143:                                children.put(child.getName(), child);
144:                            }
145:                        }
146:                    }
147:                } finally {
148:                    ftpFs.putClient(client);
149:                }
150:            }
151:
152:            /**
153:             * Attaches this file object to its file resource.
154:             */
155:            protected void doAttach() throws IOException {
156:                // Get the parent folder to find the info for this file
157:                getInfo(false);
158:            }
159:
160:            /**
161:             * Fetches the info for this file.
162:             */
163:            private void getInfo(boolean flush) throws IOException {
164:                final FtpFileObject parent = (FtpFileObject) FileObjectUtils
165:                        .getAbstractFileObject(getParent());
166:                FTPFile newFileInfo;
167:                if (parent != null) {
168:                    newFileInfo = parent.getChildFile(UriParser
169:                            .decode(getName().getBaseName()), flush);
170:                } else {
171:                    // Assume the root is a directory and exists
172:                    newFileInfo = new FTPFile();
173:                    newFileInfo.setType(FTPFile.DIRECTORY_TYPE);
174:                }
175:
176:                this .fileInfo = newFileInfo;
177:            }
178:
179:            /**
180:             * @throws FileSystemException
181:             */
182:            public void refresh() throws FileSystemException {
183:                if (!inRefresh) {
184:                    try {
185:                        inRefresh = true;
186:                        super .refresh();
187:                        try {
188:                            // this will tell the parent to recreate its children collection
189:                            getInfo(true);
190:                        } catch (IOException e) {
191:                            throw new FileSystemException(e);
192:                        }
193:                    } finally {
194:                        inRefresh = false;
195:                    }
196:                }
197:            }
198:
199:            /**
200:             * Detaches this file object from its file resource.
201:             */
202:            protected void doDetach() {
203:                this .fileInfo = null;
204:                children = null;
205:            }
206:
207:            /**
208:             * Called when the children of this file change.
209:             */
210:            protected void onChildrenChanged(FileName child, FileType newType) {
211:                if (children != null && newType.equals(FileType.IMAGINARY)) {
212:                    try {
213:                        children.remove(UriParser.decode(child.getBaseName()));
214:                    } catch (FileSystemException e) {
215:                        throw new RuntimeException(e.getMessage());
216:                    }
217:                } else {
218:                    // if child was added we have to rescan the children
219:                    // TODO - get rid of this
220:                    children = null;
221:                }
222:            }
223:
224:            /**
225:             * Called when the type or content of this file changes.
226:             */
227:            protected void onChange() throws IOException {
228:                children = null;
229:
230:                if (getType().equals(FileType.IMAGINARY)) {
231:                    // file is deleted, avoid server lookup
232:                    this .fileInfo = null;
233:                    return;
234:                }
235:
236:                getInfo(true);
237:            }
238:
239:            /**
240:             * Determines the type of the file, returns null if the file does not
241:             * exist.
242:             */
243:            protected FileType doGetType() throws Exception {
244:                if (this .fileInfo == null) {
245:                    return FileType.IMAGINARY;
246:                } else if (this .fileInfo.isDirectory()) {
247:                    return FileType.FOLDER;
248:                } else if (this .fileInfo.isFile()) {
249:                    return FileType.FILE;
250:                } else if (this .fileInfo.isSymbolicLink()) {
251:                    return getLinkDestination().getType();
252:                }
253:
254:                throw new FileSystemException(
255:                        "vfs.provider.ftp/get-type.error", getName());
256:            }
257:
258:            private FileObject getLinkDestination() throws FileSystemException {
259:                if (linkDestination == null) {
260:                    final String path = this .fileInfo.getLink();
261:                    FileName relativeTo = getName().getParent();
262:                    if (relativeTo == null) {
263:                        relativeTo = getName();
264:                    }
265:                    FileName linkDestinationName = getFileSystem()
266:                            .getFileSystemManager().resolveName(relativeTo,
267:                                    path);
268:                    linkDestination = getFileSystem().resolveFile(
269:                            linkDestinationName);
270:                }
271:
272:                return linkDestination;
273:            }
274:
275:            protected FileObject[] doListChildrenResolved() throws Exception {
276:                if (this .fileInfo.isSymbolicLink()) {
277:                    return getLinkDestination().getChildren();
278:                }
279:
280:                return null;
281:            }
282:
283:            /**
284:             * Returns the file's list of children.
285:             *
286:             * @return The list of children
287:             * @throws FileSystemException If there was a problem listing children
288:             * @see AbstractFileObject#getChildren()
289:             * @since 1.0
290:             */
291:            public FileObject[] getChildren() throws FileSystemException {
292:                try {
293:                    /* Wrap our parent implementation, noting that we're refreshing so
294:                     * that we don't refresh() ourselves and each of our parents for
295:                     * each children. Note that refresh() will list children. Meaning,
296:                     * if if this file has C children, P parents, there will be (C * P)
297:                     * listings made with (C * (P + 1)) refreshes, when there should
298:                     * really only be 1 listing and C refreshes. */
299:
300:                    this .inRefresh = true;
301:                    return super .getChildren();
302:                } finally {
303:                    this .inRefresh = false;
304:                }
305:            }
306:
307:            /**
308:             * Lists the children of the file.
309:             */
310:            protected String[] doListChildren() throws Exception {
311:                // List the children of this file
312:                doGetChildren();
313:
314:                // TODO - get rid of this children stuff
315:                final String[] childNames = new String[children.size()];
316:                int childNum = -1;
317:                Iterator iterChildren = children.values().iterator();
318:                while (iterChildren.hasNext()) {
319:                    childNum++;
320:                    final FTPFile child = (FTPFile) iterChildren.next();
321:                    childNames[childNum] = child.getName();
322:                }
323:
324:                return UriParser.encode(childNames);
325:            }
326:
327:            /**
328:             * Deletes the file.
329:             */
330:            protected void doDelete() throws Exception {
331:                final boolean ok;
332:                final FtpClient ftpClient = ftpFs.getClient();
333:                try {
334:                    if (this .fileInfo.isDirectory()) {
335:                        ok = ftpClient.removeDirectory(relPath);
336:                    } else {
337:                        ok = ftpClient.deleteFile(relPath);
338:                    }
339:                } finally {
340:                    ftpFs.putClient(ftpClient);
341:                }
342:
343:                if (!ok) {
344:                    throw new FileSystemException(
345:                            "vfs.provider.ftp/delete-file.error", getName());
346:                }
347:                this .fileInfo = null;
348:                children = EMPTY_FTP_FILE_MAP;
349:            }
350:
351:            /**
352:             * Renames the file
353:             */
354:            protected void doRename(FileObject newfile) throws Exception {
355:                final boolean ok;
356:                final FtpClient ftpClient = ftpFs.getClient();
357:                try {
358:                    String oldName = getName().getPath();
359:                    String newName = newfile.getName().getPath();
360:                    ok = ftpClient.rename(oldName, newName);
361:                } finally {
362:                    ftpFs.putClient(ftpClient);
363:                }
364:
365:                if (!ok) {
366:                    throw new FileSystemException(
367:                            "vfs.provider.ftp/rename-file.error", new Object[] {
368:                                    getName().toString(), newfile });
369:                }
370:                this .fileInfo = null;
371:                children = EMPTY_FTP_FILE_MAP;
372:            }
373:
374:            /**
375:             * Creates this file as a folder.
376:             */
377:            protected void doCreateFolder() throws Exception {
378:                final boolean ok;
379:                final FtpClient client = ftpFs.getClient();
380:                try {
381:                    ok = client.makeDirectory(relPath);
382:                } finally {
383:                    ftpFs.putClient(client);
384:                }
385:
386:                if (!ok) {
387:                    throw new FileSystemException(
388:                            "vfs.provider.ftp/create-folder.error", getName());
389:                }
390:            }
391:
392:            /**
393:             * Returns the size of the file content (in bytes).
394:             */
395:            protected long doGetContentSize() throws Exception {
396:                if (this .fileInfo.isSymbolicLink()) {
397:                    return getLinkDestination().getContent().getSize();
398:                } else {
399:                    return this .fileInfo.getSize();
400:                }
401:            }
402:
403:            /**
404:             * get the last modified time on an ftp file
405:             *
406:             * @see org.apache.commons.vfs.provider.AbstractFileObject#doGetLastModifiedTime()
407:             */
408:            protected long doGetLastModifiedTime() throws Exception {
409:                if (this .fileInfo.isSymbolicLink()) {
410:                    return getLinkDestination().getContent()
411:                            .getLastModifiedTime();
412:                } else {
413:                    Calendar timestamp = this .fileInfo.getTimestamp();
414:                    if (timestamp == null) {
415:                        return 0L;
416:                    } else {
417:                        return (timestamp.getTime().getTime());
418:                    }
419:                }
420:            }
421:
422:            /**
423:             * Creates an input stream to read the file content from.
424:             */
425:            protected InputStream doGetInputStream() throws Exception {
426:                final FtpClient client = ftpFs.getClient();
427:                final InputStream instr = client.retrieveFileStream(relPath);
428:                return new FtpInputStream(client, instr);
429:            }
430:
431:            protected RandomAccessContent doGetRandomAccessContent(
432:                    final RandomAccessMode mode) throws Exception {
433:                return new FtpRandomAccessContent(this , mode);
434:            }
435:
436:            /**
437:             * Creates an output stream to write the file content to.
438:             */
439:            protected OutputStream doGetOutputStream(boolean bAppend)
440:                    throws Exception {
441:                final FtpClient client = ftpFs.getClient();
442:                OutputStream out = null;
443:                if (bAppend) {
444:                    out = client.appendFileStream(relPath);
445:                } else {
446:                    out = client.storeFileStream(relPath);
447:                }
448:
449:                if (out == null) {
450:                    throw new FileSystemException(
451:                            "vfs.provider.ftp/output-error.debug",
452:                            new Object[] { this .getName(),
453:                                    client.getReplyString() });
454:                }
455:
456:                return new FtpOutputStream(client, out);
457:            }
458:
459:            String getRelPath() {
460:                return relPath;
461:            }
462:
463:            FtpInputStream getInputStream(long filePointer) throws IOException {
464:                final FtpClient client = ftpFs.getClient();
465:                final InputStream instr = client.retrieveFileStream(relPath,
466:                        filePointer);
467:                if (instr == null) {
468:                    throw new FileSystemException(
469:                            "vfs.provider.ftp/input-error.debug", new Object[] {
470:                                    this .getName(), client.getReplyString() });
471:                }
472:                return new FtpInputStream(client, instr);
473:            }
474:
475:            /**
476:             * An InputStream that monitors for end-of-file.
477:             */
478:            class FtpInputStream extends MonitorInputStream {
479:                private final FtpClient client;
480:
481:                public FtpInputStream(final FtpClient client,
482:                        final InputStream in) {
483:                    super (in);
484:                    this .client = client;
485:                }
486:
487:                void abort() throws IOException {
488:                    client.abort();
489:                    close();
490:                }
491:
492:                /**
493:                 * Called after the stream has been closed.
494:                 */
495:                protected void onClose() throws IOException {
496:                    final boolean ok;
497:                    try {
498:                        ok = client.completePendingCommand();
499:                    } finally {
500:                        ftpFs.putClient(client);
501:                    }
502:
503:                    if (!ok) {
504:                        throw new FileSystemException(
505:                                "vfs.provider.ftp/finish-get.error", getName());
506:                    }
507:                }
508:            }
509:
510:            /**
511:             * An OutputStream that monitors for end-of-file.
512:             */
513:            private class FtpOutputStream extends MonitorOutputStream {
514:                private final FtpClient client;
515:
516:                public FtpOutputStream(final FtpClient client,
517:                        final OutputStream outstr) {
518:                    super (outstr);
519:                    this .client = client;
520:                }
521:
522:                /**
523:                 * Called after this stream is closed.
524:                 */
525:                protected void onClose() throws IOException {
526:                    final boolean ok;
527:                    try {
528:                        ok = client.completePendingCommand();
529:                    } finally {
530:                        ftpFs.putClient(client);
531:                    }
532:
533:                    if (!ok) {
534:                        throw new FileSystemException(
535:                                "vfs.provider.ftp/finish-put.error", getName());
536:                    }
537:                }
538:            }
539:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.