Source Code Cross Referenced for VFS.java in  » Swing-Library » jEdit » org » gjt » sp » jedit » io » 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 » Swing Library » jEdit » org.gjt.sp.jedit.io 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * VFS.java - Virtual filesystem implementation
0003:         * :tabSize=8:indentSize=8:noTabs=false:
0004:         * :folding=explicit:collapseFolds=1:
0005:         *
0006:         * Copyright (C) 2000, 2003 Slava Pestov
0007:         *
0008:         * This program is free software; you can redistribute it and/or
0009:         * modify it under the terms of the GNU General Public License
0010:         * as published by the Free Software Foundation; either version 2
0011:         * of the License, or any later version.
0012:         *
0013:         * This program is distributed in the hope that it will be useful,
0014:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
0015:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0016:         * GNU General Public License for more details.
0017:         *
0018:         * You should have received a copy of the GNU General Public License
0019:         * along with this program; if not, write to the Free Software
0020:         * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
0021:         */
0022:
0023:        package org.gjt.sp.jedit.io;
0024:
0025:        //{{{ Imports
0026:        import java.awt.Color;
0027:        import java.awt.Component;
0028:        import java.io.*;
0029:        import java.util.*;
0030:
0031:        import java.util.regex.Pattern;
0032:        import java.util.regex.PatternSyntaxException;
0033:
0034:        import org.gjt.sp.jedit.msg.PropertiesChanged;
0035:        import org.gjt.sp.jedit.*;
0036:        import org.gjt.sp.jedit.bufferio.BufferLoadRequest;
0037:        import org.gjt.sp.jedit.bufferio.BufferSaveRequest;
0038:        import org.gjt.sp.jedit.bufferio.BufferInsertRequest;
0039:        import org.gjt.sp.jedit.bufferio.BufferIORequest;
0040:        import org.gjt.sp.util.Log;
0041:        import org.gjt.sp.util.ProgressObserver;
0042:        import org.gjt.sp.util.IOUtilities;
0043:        import org.gjt.sp.util.StandardUtilities; //}}}
0044:        import org.gjt.sp.util.WorkThread;
0045:
0046:        /**
0047:         * A virtual filesystem implementation.<p>
0048:         *
0049:         * Plugins can provide virtual file systems by defining entries in their
0050:         * <code>services.xml</code> files like so:
0051:         *
0052:         * <pre>&lt;SERVICE CLASS="org.gjt.sp.jedit.io.VFS" NAME="<i>name</i>"&gt;
0053:         *    new <i>MyVFS</i>();
0054:         *&lt;/SERVICE&gt;</pre>
0055:         *
0056:         * URLs of the form <code><i>name</i>:<i>path</i></code> will then be handled
0057:         * by the VFS named <code><i>name</i></code>.<p>
0058:         *
0059:         * See {@link org.gjt.sp.jedit.ServiceManager} for details.<p>
0060:         *
0061:         * <h3>Session objects:</h3>
0062:         *
0063:         * A session is used to persist things like login information, any network
0064:         * sockets, etc. File system implementations that do not need this kind of
0065:         * persistence return a dummy object as a session.<p>
0066:         *
0067:         * Methods whose names are prefixed with "_" expect to be given a
0068:         * previously-obtained session object. A session must be obtained from the AWT
0069:         * thread in one of two ways:
0070:         *
0071:         * <ul>
0072:         * <li>{@link #createVFSSession(String,Component)}</li>
0073:         * <li>{@link #showBrowseDialog(Object[],Component)}</li>
0074:         * </ul>
0075:         *
0076:         * When done, the session must be disposed of using
0077:         * {@link #_endVFSSession(Object,Component)}.<p>
0078:         *
0079:         * <h3>Thread safety:</h3>
0080:         *
0081:         * The following methods cannot be called from an I/O thread:
0082:         *
0083:         * <ul>
0084:         * <li>{@link #createVFSSession(String,Component)}</li>
0085:         * <li>{@link #insert(View,Buffer,String)}</li>
0086:         * <li>{@link #load(View,Buffer,String)}</li>
0087:         * <li>{@link #save(View,Buffer,String)}</li>
0088:         * <li>{@link #showBrowseDialog(Object[],Component)}</li>
0089:         * </ul>
0090:         *
0091:         * All remaining methods are required to be thread-safe in subclasses.
0092:         *
0093:         * <h3>Implementing a VFS</h3>
0094:         *
0095:         * You can override as many or as few methods as you want. Make sure
0096:         * {@link #getCapabilities()} returns a value reflecting the functionality
0097:         * implemented by your VFS.
0098:         *
0099:         * @see VFSManager#getVFSForPath(String)
0100:         * @see VFSManager#getVFSForProtocol(String)
0101:         *
0102:         * @author Slava Pestov
0103:         * @author $Id: VFS.java 10773 2007-09-30 19:21:03Z kpouer $
0104:         */
0105:        public abstract class VFS {
0106:            //{{{ Capabilities
0107:
0108:            /**
0109:             * Read capability.
0110:             * @since jEdit 2.6pre2
0111:             */
0112:            public static final int READ_CAP = 1 << 0;
0113:
0114:            /**
0115:             * Write capability.
0116:             * @since jEdit 2.6pre2
0117:             */
0118:            public static final int WRITE_CAP = 1 << 1;
0119:
0120:            /**
0121:             * Browse capability
0122:             * @since jEdit 4.3pre11
0123:             *
0124:             * This was the official API for adding items to a file
0125:             * system browser's <b>Plugins</b> menu in jEdit 4.1 and earlier. In
0126:             * jEdit 4.2, there is a different way of doing this, you must provide
0127:             * a <code>browser.actions.xml</code> file in your plugin JAR, and
0128:             * define <code>plugin.<i>class</i>.browser-menu-item</code>
0129:             * or <code>plugin.<i>class</i>.browser-menu</code> properties.
0130:             * See {@link org.gjt.sp.jedit.EditPlugin} for details.
0131:             */
0132:            public static final int BROWSE_CAP = 1 << 2;
0133:
0134:            /**
0135:             * Delete file capability.
0136:             * @since jEdit 2.6pre2
0137:             */
0138:            public static final int DELETE_CAP = 1 << 3;
0139:
0140:            /**
0141:             * Rename file capability.
0142:             * @since jEdit 2.6pre2
0143:             */
0144:            public static final int RENAME_CAP = 1 << 4;
0145:
0146:            /**
0147:             * Make directory capability.
0148:             * @since jEdit 2.6pre2
0149:             */
0150:            public static final int MKDIR_CAP = 1 << 5;
0151:
0152:            /**
0153:             * Low latency capability. If this is not set, then a confirm dialog
0154:             * will be shown before doing a directory search in this VFS.
0155:             * @since jEdit 4.1pre1
0156:             */
0157:            public static final int LOW_LATENCY_CAP = 1 << 6;
0158:
0159:            /**
0160:             * Case insensitive file system capability.
0161:             * @since jEdit 4.1pre1
0162:             */
0163:            public static final int CASE_INSENSITIVE_CAP = 1 << 7;
0164:
0165:            //}}}
0166:
0167:            //{{{ Extended attributes
0168:            /**
0169:             * File type.
0170:             * @since jEdit 4.2pre1
0171:             */
0172:            public static final String EA_TYPE = "type";
0173:
0174:            /**
0175:             * File status (read only, read write, etc).
0176:             * @since jEdit 4.2pre1
0177:             */
0178:            public static final String EA_STATUS = "status";
0179:
0180:            /**
0181:             * File size.
0182:             * @since jEdit 4.2pre1
0183:             */
0184:            public static final String EA_SIZE = "size";
0185:
0186:            /**
0187:             * File last modified date.
0188:             * @since jEdit 4.2pre1
0189:             */
0190:            public static final String EA_MODIFIED = "modified";
0191:            //}}}
0192:
0193:            public static int IOBUFSIZE = 32678;
0194:
0195:            //{{{ VFS constructor
0196:            /**
0197:             * @deprecated Use the form where the constructor takes a capability
0198:             * list.
0199:             */
0200:            public VFS(String name) {
0201:                this (name, 0);
0202:            } //}}}
0203:
0204:            //{{{ VFS constructor
0205:            /**
0206:             * Creates a new virtual filesystem.
0207:             * @param name The name
0208:             * @param caps The capabilities
0209:             */
0210:            public VFS(String name, int caps) {
0211:                this .name = name;
0212:                this .caps = caps;
0213:                // reasonable defaults (?)
0214:                this .extAttrs = new String[] { EA_SIZE, EA_TYPE };
0215:            } //}}}
0216:
0217:            //{{{ VFS constructor
0218:            /**
0219:             * Creates a new virtual filesystem.
0220:             * @param name The name
0221:             * @param caps The capabilities
0222:             * @param extAttrs The extended attributes
0223:             * @since jEdit 4.2pre1
0224:             */
0225:            public VFS(String name, int caps, String[] extAttrs) {
0226:                this .name = name;
0227:                this .caps = caps;
0228:                this .extAttrs = extAttrs;
0229:            } //}}}
0230:
0231:            //{{{ getName() method
0232:            /**
0233:             * Returns this VFS's name. The name is used to obtain the
0234:             * label stored in the <code>vfs.<i>name</i>.label</code>
0235:             * property.
0236:             */
0237:            public String getName() {
0238:                return name;
0239:            } //}}}
0240:
0241:            //{{{ getCapabilities() method
0242:            /**
0243:             * Returns the capabilities of this VFS.
0244:             * @since jEdit 2.6pre2
0245:             */
0246:            public int getCapabilities() {
0247:                return caps;
0248:            } //}}}
0249:
0250:            //{{{ isMarkersFileSupported() method
0251:            /**
0252:             * Returns if an additional markers file can be saved by this VFS.
0253:             * Default is {@code true}.
0254:             * 
0255:             * @since jEdit 4.3pre10
0256:             */
0257:            public boolean isMarkersFileSupported() {
0258:                return true;
0259:            } //}}}
0260:
0261:            //{{{ getExtendedAttributes() method
0262:            /**
0263:             * Returns the extended attributes supported by this VFS.
0264:             * @since jEdit 4.2pre1
0265:             */
0266:            public String[] getExtendedAttributes() {
0267:                return extAttrs;
0268:            } //}}}
0269:
0270:            //{{{ showBrowseDialog() method
0271:            /**
0272:             * Displays a dialog box that should set up a session and return
0273:             * the initial URL to browse.
0274:             * @param session Where the VFS session will be stored
0275:             * @param comp The component that will parent error dialog boxes
0276:             * @return The URL
0277:             * @since jEdit 2.7pre1
0278:             * @deprecated This function is not used in the jEdit core anymore,
0279:             *             so it doesn't have to be provided anymore. If you want
0280:             *             to use it for another purpose like in the FTP plugin,
0281:             *             feel free to do so.
0282:             */
0283:            @Deprecated
0284:            public String showBrowseDialog(Object[] session, Component comp) {
0285:                return null;
0286:            } //}}}
0287:
0288:            //{{{ getFileName() method
0289:            /**
0290:             * Returns the file name component of the specified path.
0291:             * @param path The path
0292:             * @since jEdit 3.1pre4
0293:             */
0294:            public String getFileName(String path) {
0295:                if (path.equals("/"))
0296:                    return path;
0297:
0298:                while (path.endsWith("/") || path.endsWith(File.separator))
0299:                    path = path.substring(0, path.length() - 1);
0300:
0301:                int index = Math.max(path.lastIndexOf('/'), path
0302:                        .lastIndexOf(File.separatorChar));
0303:                if (index == -1)
0304:                    index = path.indexOf(':');
0305:
0306:                // don't want getFileName("roots:") to return ""
0307:                if (index == -1 || index == path.length() - 1)
0308:                    return path;
0309:
0310:                return path.substring(index + 1);
0311:            } //}}}
0312:
0313:            //{{{ getParentOfPath() method
0314:            /**
0315:             * Returns the parent of the specified path. This must be
0316:             * overridden to return a non-null value for browsing of this
0317:             * filesystem to work.
0318:             * @param path The path
0319:             * @since jEdit 2.6pre5
0320:             */
0321:            public String getParentOfPath(String path) {
0322:                // ignore last character of path to properly handle
0323:                // paths like /foo/bar/
0324:                int lastIndex = path.length() - 1;
0325:                while (lastIndex > 0
0326:                        && (path.charAt(lastIndex) == File.separatorChar || path
0327:                                .charAt(lastIndex) == '/')) {
0328:                    lastIndex--;
0329:                }
0330:
0331:                int count = Math.max(0, lastIndex);
0332:                int index = path.lastIndexOf(File.separatorChar, count);
0333:                if (index == -1)
0334:                    index = path.lastIndexOf('/', count);
0335:                if (index == -1) {
0336:                    // this ensures that getFileParent("protocol:"), for
0337:                    // example, is "protocol:" and not "".
0338:                    index = path.lastIndexOf(':');
0339:                }
0340:
0341:                return path.substring(0, index + 1);
0342:            } //}}}
0343:
0344:            //{{{ constructPath() method
0345:            /**
0346:             * Constructs a path from the specified directory and
0347:             * file name component. This must be overridden to return a
0348:             * non-null value, otherwise browsing this filesystem will
0349:             * not work.<p>
0350:             *
0351:             * Unless you are writing a VFS, this method should not be called
0352:             * directly. To ensure correct behavior, you <b>must</b> call
0353:             * {@link org.gjt.sp.jedit.MiscUtilities#constructPath(String,String)}
0354:             * instead.
0355:             *
0356:             * @param parent The parent directory
0357:             * @param path The path
0358:             * @since jEdit 2.6pre2
0359:             */
0360:            public String constructPath(String parent, String path) {
0361:                return parent + path;
0362:            } //}}}
0363:
0364:            //{{{ getFileSeparator() method
0365:            /**
0366:             * Returns the file separator used by this VFS.
0367:             * @since jEdit 2.6pre9
0368:             */
0369:            public char getFileSeparator() {
0370:                return '/';
0371:            } //}}}
0372:
0373:            //{{{ getTwoStageSaveName() method
0374:            /**
0375:             * Returns a temporary file name based on the given path.
0376:             *
0377:             * By default jEdit first saves a file to <code>#<i>name</i>#save#</code>
0378:             * and then renames it to the original file. However some virtual file
0379:             * systems might not support the <code>#</code> character in filenames,
0380:             * so this method permits the VFS to override this behavior.
0381:             *
0382:             * If this method returns <code>null</code>, two stage save will not
0383:             * be used for that particular file (introduced in jEdit 4.3pre1).
0384:             *
0385:             * @param path The path name
0386:             * @since jEdit 4.1pre7
0387:             */
0388:            public String getTwoStageSaveName(String path) {
0389:                return MiscUtilities.constructPath(getParentOfPath(path), '#'
0390:                        + getFileName(path) + "#save#");
0391:            } //}}}
0392:
0393:            //{{{ reloadDirectory() method
0394:            /**
0395:             * Called before a directory is reloaded by the file system browser.
0396:             * Can be used to flush a cache, etc.
0397:             * @since jEdit 4.0pre3
0398:             */
0399:            public void reloadDirectory(String path) {
0400:            } //}}}
0401:
0402:            //{{{ createVFSSession() method
0403:            /**
0404:             * Creates a VFS session. This method is called from the AWT thread,
0405:             * so it should not do any I/O. It could, however, prompt for
0406:             * a login name and password, for example.
0407:             * @param path The path in question
0408:             * @param comp The component that will parent any dialog boxes shown
0409:             * @return The session. The session can be null if there were errors
0410:             * @since jEdit 2.6pre3
0411:             */
0412:            public Object createVFSSession(String path, Component comp) {
0413:                return new Object();
0414:            } //}}}
0415:
0416:            //{{{ load() method
0417:            /**
0418:             * Loads the specified buffer. The default implementation posts
0419:             * an I/O request to the I/O thread.
0420:             * @param view The view
0421:             * @param buffer The buffer
0422:             * @param path The path
0423:             */
0424:            public boolean load(View view, Buffer buffer, String path) {
0425:                if ((getCapabilities() & READ_CAP) == 0) {
0426:                    VFSManager.error(view, path, "vfs.not-supported.load",
0427:                            new String[] { name });
0428:                    return false;
0429:                }
0430:
0431:                Object session = createVFSSession(path, view);
0432:                if (session == null)
0433:                    return false;
0434:
0435:                if ((getCapabilities() & WRITE_CAP) == 0)
0436:                    buffer.setReadOnly(true);
0437:
0438:                BufferIORequest request = new BufferLoadRequest(view, buffer,
0439:                        session, this , path);
0440:                if (buffer.isTemporary())
0441:                    // this makes HyperSearch much faster
0442:                    request.run();
0443:                else
0444:                    VFSManager.runInWorkThread(request);
0445:
0446:                return true;
0447:            } //}}}
0448:
0449:            //{{{ save() method
0450:            /**
0451:             * Saves the specifies buffer. The default implementation posts
0452:             * an I/O request to the I/O thread.
0453:             * @param view The view
0454:             * @param buffer The buffer
0455:             * @param path The path
0456:             */
0457:            public boolean save(View view, Buffer buffer, String path) {
0458:                if ((getCapabilities() & WRITE_CAP) == 0) {
0459:                    VFSManager.error(view, path, "vfs.not-supported.save",
0460:                            new String[] { name });
0461:                    return false;
0462:                }
0463:
0464:                Object session = createVFSSession(path, view);
0465:                if (session == null)
0466:                    return false;
0467:
0468:                /* When doing a 'save as', the path to save to (path)
0469:                 * will not be the same as the buffer's previous path
0470:                 * (buffer.getPath()). In that case, we want to create
0471:                 * a backup of the new path, even if the old path was
0472:                 * backed up as well (BACKED_UP property set) */
0473:                if (!path.equals(buffer.getPath()))
0474:                    buffer.unsetProperty(Buffer.BACKED_UP);
0475:
0476:                VFSManager.runInWorkThread(new BufferSaveRequest(view, buffer,
0477:                        session, this , path));
0478:                return true;
0479:            } //}}}
0480:
0481:            //{{{ copy() method
0482:            /**
0483:             * Copy a file to another using VFS.
0484:             *
0485:             * @param progress the progress observer. It could be null if you don't want to monitor progress. If not null
0486:             *                  you should probably launch this command in a WorkThread
0487:             * @param sourceVFS the source VFS
0488:             * @param sourceSession the VFS session
0489:             * @param sourcePath the source path
0490:             * @param targetVFS the target VFS
0491:             * @param targetSession the target session
0492:             * @param targetPath the target path
0493:             * @param comp comp The component that will parent error dialog boxes
0494:             * @return true if the copy was successful
0495:             * @throws IOException  IOException If an I/O error occurs
0496:             * @since jEdit 4.3pre3
0497:             */
0498:            public static boolean copy(ProgressObserver progress,
0499:                    VFS sourceVFS, Object sourceSession, String sourcePath,
0500:                    VFS targetVFS, Object targetSession, String targetPath,
0501:                    Component comp, boolean canStop) throws IOException {
0502:                if (progress != null)
0503:                    progress.setStatus("Initializing");
0504:
0505:                InputStream in = null;
0506:                OutputStream out = null;
0507:                try {
0508:                    if (progress != null) {
0509:                        VFSFile sourceVFSFile = sourceVFS._getFile(
0510:                                sourceSession, sourcePath, comp);
0511:                        if (sourceVFSFile == null)
0512:                            throw new FileNotFoundException(sourcePath);
0513:
0514:                        progress.setMaximum(sourceVFSFile.getLength());
0515:                    }
0516:                    in = new BufferedInputStream(sourceVFS._createInputStream(
0517:                            sourceSession, sourcePath, false, comp));
0518:                    out = new BufferedOutputStream(targetVFS
0519:                            ._createOutputStream(targetSession, targetPath,
0520:                                    comp));
0521:                    boolean copyResult = IOUtilities.copyStream(IOBUFSIZE,
0522:                            progress, in, out, canStop);
0523:                    VFSManager.sendVFSUpdate(targetVFS, targetPath, true);
0524:                    return copyResult;
0525:                } finally {
0526:                    IOUtilities.closeQuietly(in);
0527:                    IOUtilities.closeQuietly(out);
0528:                }
0529:            } //}}}
0530:
0531:            //{{{ copy() method
0532:            /**
0533:             * Copy a file to another using VFS.
0534:             *
0535:             * @param progress the progress observer. It could be null if you don't want to monitor progress. If not null
0536:             *                  you should probably launch this command in a WorkThread
0537:             * @param sourcePath the source path
0538:             * @param targetPath the target path
0539:             * @param comp comp The component that will parent error dialog boxes
0540:             * @param canStop if true the copy can be stopped
0541:             * @return true if the copy was successful
0542:             * @throws IOException IOException If an I/O error occurs
0543:             * @since jEdit 4.3pre3
0544:             */
0545:            public static boolean copy(ProgressObserver progress,
0546:                    String sourcePath, String targetPath, Component comp,
0547:                    boolean canStop) throws IOException {
0548:                VFS sourceVFS = VFSManager.getVFSForPath(sourcePath);
0549:                Object sourceSession = sourceVFS.createVFSSession(sourcePath,
0550:                        comp);
0551:                if (sourceSession == null) {
0552:                    Log.log(Log.WARNING, VFS.class,
0553:                            "Unable to get a valid session from " + sourceVFS
0554:                                    + " for path " + sourcePath);
0555:                    return false;
0556:                }
0557:                VFS targetVFS = VFSManager.getVFSForPath(targetPath);
0558:                Object targetSession = targetVFS.createVFSSession(targetPath,
0559:                        comp);
0560:                if (targetSession == null) {
0561:                    Log.log(Log.WARNING, VFS.class,
0562:                            "Unable to get a valid session from " + targetVFS
0563:                                    + " for path " + targetPath);
0564:                    return false;
0565:                }
0566:                return copy(progress, sourceVFS, sourceSession, sourcePath,
0567:                        targetVFS, targetSession, targetPath, comp, canStop);
0568:            } //}}}
0569:
0570:            //{{{ insert() method
0571:            /**
0572:             * Inserts a file into the specified buffer. The default implementation
0573:             * posts an I/O request to the I/O thread.
0574:             * @param view The view
0575:             * @param buffer The buffer
0576:             * @param path The path
0577:             */
0578:            public boolean insert(View view, Buffer buffer, String path) {
0579:                if ((getCapabilities() & READ_CAP) == 0) {
0580:                    VFSManager.error(view, path, "vfs.not-supported.load",
0581:                            new String[] { name });
0582:                    return false;
0583:                }
0584:
0585:                Object session = createVFSSession(path, view);
0586:                if (session == null)
0587:                    return false;
0588:
0589:                VFSManager.runInWorkThread(new BufferInsertRequest(view,
0590:                        buffer, session, this , path));
0591:                return true;
0592:            } //}}}
0593:
0594:            // A method name that starts with _ requires a session object
0595:
0596:            //{{{ _canonPath() method
0597:            /**
0598:             * Returns the canonical form of the specified path name. For example,
0599:             * <code>~</code> might be expanded to the user's home directory.
0600:             * @param session The session
0601:             * @param path The path
0602:             * @param comp The component that will parent error dialog boxes
0603:             * @exception IOException if an I/O error occurred
0604:             * @since jEdit 4.0pre2
0605:             */
0606:            public String _canonPath(Object session, String path, Component comp)
0607:                    throws IOException {
0608:                return path;
0609:            } //}}}
0610:
0611:            //{{{ _listDirectory() method
0612:            /**
0613:             * A convinience method that matches file names against globs, and can
0614:             * optionally list the directory recursively.
0615:             * @param session The session
0616:             * @param directory The directory. Note that this must be a full
0617:             * URL, including the host name, path name, and so on. The
0618:             * username and password (if needed by the VFS) is obtained from the
0619:             * session instance.
0620:             * @param glob Only file names matching this glob will be returned
0621:             * @param recursive If true, subdirectories will also be listed.
0622:             * @param comp The component that will parent error dialog boxes
0623:             * @exception IOException if an I/O error occurred
0624:             * @since jEdit 4.1pre1
0625:             */
0626:            public String[] _listDirectory(Object session, String directory,
0627:                    String glob, boolean recursive, Component comp)
0628:                    throws IOException {
0629:                String[] retval = null;
0630:                retval = _listDirectory(session, directory, glob, recursive,
0631:                        comp, true, false);
0632:                return retval;
0633:            } //}}}
0634:
0635:            //{{{ _listDirectory() method
0636:            /**
0637:             * A convinience method that matches file names against globs, and can
0638:             * optionally list the directory recursively.
0639:             * @param session The session
0640:             * @param directory The directory. Note that this must be a full
0641:             * URL, including the host name, path name, and so on. The
0642:             * username and password (if needed by the VFS) is obtained from the
0643:             * session instance.
0644:             * @param glob Only file names matching this glob will be returned
0645:             * @param recursive If true, subdirectories will also be listed.
0646:             * @param comp The component that will parent error dialog boxes
0647:             * @exception IOException if an I/O error occurred
0648:             * @param skipBinary ignore binary files (do not return them).
0649:             *    This will slow down the process since it will open the files
0650:             * @param skipHidden skips hidden files, directories, and
0651:             *        backup files. Ignores any file beginning with . or #, or ending with ~
0652:             *        or .bak
0653:             *
0654:             *
0655:             * @since jEdit 4.3pre5
0656:             */
0657:            public String[] _listDirectory(Object session, String directory,
0658:                    String glob, boolean recursive, Component comp,
0659:                    boolean skipBinary, boolean skipHidden) throws IOException {
0660:                VFSFileFilter filter = new GlobVFSFileFilter(glob);
0661:                return _listDirectory(session, directory, filter, recursive,
0662:                        comp, skipBinary, skipHidden);
0663:            } //}}}
0664:
0665:            //{{{ _listDirectory() method
0666:            /**
0667:             * A convinience method that filters the directory listing
0668:             * according to a filter, and can optionally list the directory
0669:             * recursively.
0670:             * @param session The session
0671:             * @param directory The directory. Note that this must be a full
0672:             * URL, including the host name, path name, and so on. The
0673:             * username and password (if needed by the VFS) is obtained from the
0674:             * session instance.
0675:             * @param filter The {@link VFSFileFilter} to use for filtering.
0676:             * @param recursive If true, subdirectories will also be listed.
0677:             * @param comp The component that will parent error dialog boxes
0678:             * @exception IOException if an I/O error occurred
0679:             * @param skipBinary ignore binary files (do not return them).
0680:             *    This will slow down the process since it will open the files
0681:             * @param skipHidden skips hidden files, directories, and
0682:             *        backup files. Ignores any file beginning with . or #, or ending with ~
0683:             *        or .bak
0684:             *
0685:             * @since jEdit 4.3pre7
0686:             */
0687:            public String[] _listDirectory(Object session, String directory,
0688:                    VFSFileFilter filter, boolean recursive, Component comp,
0689:                    boolean skipBinary, boolean skipHidden) throws IOException {
0690:                Log.log(Log.DEBUG, this , "Listing " + directory);
0691:                List<String> files = new ArrayList<String>(100);
0692:
0693:                listFiles(session, new HashSet<String>(), files, directory,
0694:                        filter, recursive, comp, skipBinary, skipHidden);
0695:
0696:                String[] retVal = files.toArray(new String[files.size()]);
0697:
0698:                Arrays.sort(retVal, new MiscUtilities.StringICaseCompare());
0699:
0700:                return retVal;
0701:            } //}}}
0702:
0703:            //{{{ _listFiles() method
0704:            /**
0705:             * Lists the specified directory.
0706:             * @param session The session
0707:             * @param directory The directory. Note that this must be a full
0708:             * URL, including the host name, path name, and so on. The
0709:             * username and password (if needed by the VFS) is obtained from the
0710:             * session instance.
0711:             * @param comp The component that will parent error dialog boxes
0712:             * @exception IOException if an I/O error occurred
0713:             * @since jEdit 4.3pre2
0714:             */
0715:            public VFSFile[] _listFiles(Object session, String directory,
0716:                    Component comp) throws IOException {
0717:                return _listDirectory(session, directory, comp);
0718:            } //}}}
0719:
0720:            //{{{ _listDirectory() method
0721:            /**
0722:             * @deprecated Use <code>_listFiles()</code> instead.
0723:             */
0724:            public DirectoryEntry[] _listDirectory(Object session,
0725:                    String directory, Component comp) throws IOException {
0726:                VFSManager.error(comp, directory, "vfs.not-supported.list",
0727:                        new String[] { name });
0728:                return null;
0729:            } //}}}
0730:
0731:            //{{{ _getFile() method
0732:            /**
0733:             * Returns the specified directory entry.
0734:             * @param session The session get it with {@link VFS#createVFSSession(String, Component)}
0735:             * @param path The path
0736:             * @param comp The component that will parent error dialog boxes
0737:             * @exception IOException if an I/O error occurred
0738:             * @return The specified directory entry, or null if it doesn't exist.
0739:             * @since jEdit 4.3pre2
0740:             */
0741:            public VFSFile _getFile(Object session, String path, Component comp)
0742:                    throws IOException {
0743:                return _getDirectoryEntry(session, path, comp);
0744:            } //}}}
0745:
0746:            //{{{ _getDirectoryEntry() method
0747:            /**
0748:             * Returns the specified directory entry.
0749:             * @param session The session get it with {@link VFS#createVFSSession(String, Component)}
0750:             * @param path The path
0751:             * @param comp The component that will parent error dialog boxes
0752:             * @exception IOException if an I/O error occurred
0753:             * @return The specified directory entry, or null if it doesn't exist.
0754:             * @since jEdit 2.7pre1
0755:             * @deprecated Use <code>_getFile()</code> instead.
0756:             */
0757:            public DirectoryEntry _getDirectoryEntry(Object session,
0758:                    String path, Component comp) throws IOException {
0759:                return null;
0760:            } //}}}
0761:
0762:            //{{{ DirectoryEntry class
0763:            /**
0764:             * @deprecated Use <code>VFSFile</code> instead.
0765:             */
0766:            public static class DirectoryEntry extends VFSFile {
0767:                //{{{ DirectoryEntry constructor
0768:                /**
0769:                 * @since jEdit 4.2pre2
0770:                 */
0771:                public DirectoryEntry() {
0772:                } //}}}
0773:
0774:                //{{{ DirectoryEntry constructor
0775:                public DirectoryEntry(String name, String path,
0776:                        String deletePath, int type, long length, boolean hidden) {
0777:                    this .name = name;
0778:                    this .path = path;
0779:                    this .deletePath = deletePath;
0780:                    this .symlinkPath = path;
0781:                    this .type = type;
0782:                    this .length = length;
0783:                    this .hidden = hidden;
0784:                    if (path != null) {
0785:                        // maintain backwards compatibility
0786:                        VFS vfs = VFSManager.getVFSForPath(path);
0787:                        canRead = ((vfs.getCapabilities() & READ_CAP) != 0);
0788:                        canWrite = ((vfs.getCapabilities() & WRITE_CAP) != 0);
0789:                    }
0790:                } //}}}
0791:            } //}}}
0792:
0793:            //{{{ _delete() method
0794:            /**
0795:             * Deletes the specified URL.
0796:             * @param session The VFS session
0797:             * @param path The path
0798:             * @param comp The component that will parent error dialog boxes
0799:             * @exception IOException if an I/O error occurs
0800:             * @since jEdit 2.7pre1
0801:             */
0802:            public boolean _delete(Object session, String path, Component comp)
0803:                    throws IOException {
0804:                return false;
0805:            } //}}}
0806:
0807:            //{{{ _rename() method
0808:            /**
0809:             * Renames the specified URL. Some filesystems might support moving
0810:             * URLs between directories, however others may not. Do not rely on
0811:             * this behavior.
0812:             * @param session The VFS session
0813:             * @param from The old path
0814:             * @param to The new path
0815:             * @param comp The component that will parent error dialog boxes
0816:             * @exception IOException if an I/O error occurs
0817:             * @since jEdit 2.7pre1
0818:             */
0819:            public boolean _rename(Object session, String from, String to,
0820:                    Component comp) throws IOException {
0821:                return false;
0822:            } //}}}
0823:
0824:            //{{{ _mkdir() method
0825:            /**
0826:             * Creates a new directory with the specified URL.
0827:             * @param session The VFS session
0828:             * @param directory The directory
0829:             * @param comp The component that will parent error dialog boxes
0830:             * @exception IOException if an I/O error occurs
0831:             * @since jEdit 2.7pre1
0832:             */
0833:            public boolean _mkdir(Object session, String directory,
0834:                    Component comp) throws IOException {
0835:                return false;
0836:            } //}}}
0837:
0838:            //{{{ _backup() method
0839:            /**
0840:             * Backs up the specified file. This should only be overriden by
0841:             * the local filesystem VFS.
0842:             * @param session The VFS session
0843:             * @param path The path
0844:             * @param comp The component that will parent error dialog boxes
0845:             * @exception IOException if an I/O error occurs
0846:             * @since jEdit 3.2pre2
0847:             */
0848:            public void _backup(Object session, String path, Component comp)
0849:                    throws IOException {
0850:            } //}}}
0851:
0852:            //{{{ _createInputStream() method
0853:            /**
0854:             * Creates an input stream. This method is called from the I/O
0855:             * thread.
0856:             * @param session the VFS session
0857:             * @param path The path
0858:             * @param ignoreErrors If true, file not found errors should be
0859:             * ignored
0860:             * @param comp The component that will parent error dialog boxes
0861:             * @return an inputstream or <code>null</code> if there was a problem
0862:             * @exception IOException If an I/O error occurs
0863:             * @since jEdit 2.7pre1
0864:             */
0865:            public InputStream _createInputStream(Object session, String path,
0866:                    boolean ignoreErrors, Component comp) throws IOException {
0867:                VFSManager.error(comp, path, "vfs.not-supported.load",
0868:                        new String[] { name });
0869:                return null;
0870:            } //}}}
0871:
0872:            //{{{ _createOutputStream() method
0873:            /**
0874:             * Creates an output stream. This method is called from the I/O
0875:             * thread.
0876:             * @param session the VFS session
0877:             * @param path The path
0878:             * @param comp The component that will parent error dialog boxes
0879:             * @exception IOException If an I/O error occurs
0880:             * @since jEdit 2.7pre1
0881:             */
0882:            public OutputStream _createOutputStream(Object session,
0883:                    String path, Component comp) throws IOException {
0884:                VFSManager.error(comp, path, "vfs.not-supported.save",
0885:                        new String[] { name });
0886:                return null;
0887:            } //}}}
0888:
0889:            //{{{ _saveComplete() method
0890:            /**
0891:             * Called after a file has been saved.
0892:             * @param session The VFS session
0893:             * @param buffer The buffer
0894:             * @param path The path the buffer was saved to (can be different from
0895:             * {@link org.gjt.sp.jedit.Buffer#getPath()} if the user invoked the
0896:             * <b>Save a Copy As</b> command, for example).
0897:             * @param comp The component that will parent error dialog boxes
0898:             * @exception IOException If an I/O error occurs
0899:             * @since jEdit 4.1pre9
0900:             */
0901:            public void _saveComplete(Object session, Buffer buffer,
0902:                    String path, Component comp) throws IOException {
0903:            } //}}}
0904:
0905:            //{{{ _finishTwoStageSave() method
0906:            /**
0907:             * Called after a file has been saved and we use twoStageSave (first saving to
0908:             * another file). This should re-apply permissions for example.
0909:
0910:             * @param session The VFS session
0911:             * @param buffer The buffer
0912:             * @param path The path the buffer was saved to (can be different from
0913:             * {@link org.gjt.sp.jedit.Buffer#getPath()} if the user invoked the
0914:             * <b>Save a Copy As</b> command, for example).
0915:             * @param comp The component that will parent error dialog boxes
0916:             * @exception IOException If an I/O error occurs
0917:             * @since jEdit 4.3pre4
0918:             */
0919:            public void _finishTwoStageSave(Object session, Buffer buffer,
0920:                    String path, Component comp) throws IOException {
0921:            } //}}}
0922:
0923:            //{{{ _endVFSSession() method
0924:            /**
0925:             * Finishes the specified VFS session. This must be called
0926:             * after all I/O with this VFS is complete, to avoid leaving
0927:             * stale network connections and such.
0928:             * @param session The VFS session
0929:             * @param comp The component that will parent error dialog boxes
0930:             * @exception IOException if an I/O error occurred
0931:             * @since jEdit 2.7pre1
0932:             */
0933:            public void _endVFSSession(Object session, Component comp)
0934:                    throws IOException {
0935:            } //}}}
0936:
0937:            //{{{ getDefaultColorFor() method
0938:            /**
0939:             * Returns color of the specified file name, by matching it against
0940:             * user-specified regular expressions.
0941:             * @since jEdit 4.0pre1
0942:             */
0943:            public static Color getDefaultColorFor(String name) {
0944:                synchronized (lock) {
0945:                    if (colors == null)
0946:                        loadColors();
0947:
0948:                    for (int i = 0; i < colors.size(); i++) {
0949:                        ColorEntry entry = colors.get(i);
0950:                        if (entry.re.matcher(name).matches())
0951:                            return entry.color;
0952:                    }
0953:
0954:                    return null;
0955:                }
0956:            } //}}}
0957:
0958:            //{{{ DirectoryEntryCompare class
0959:            /**
0960:             * Implementation of {@link Comparator}
0961:             * interface that compares {@link VFS.DirectoryEntry} instances.
0962:             * @since jEdit 4.2pre1
0963:             */
0964:            public static class DirectoryEntryCompare implements  Comparator {
0965:                private boolean sortIgnoreCase, sortMixFilesAndDirs;
0966:
0967:                /**
0968:                 * Creates a new <code>DirectoryEntryCompare</code>.
0969:                 * @param sortMixFilesAndDirs If false, directories are
0970:                 * put at the top of the listing.
0971:                 * @param sortIgnoreCase If false, upper case comes before
0972:                 * lower case.
0973:                 */
0974:                public DirectoryEntryCompare(boolean sortMixFilesAndDirs,
0975:                        boolean sortIgnoreCase) {
0976:                    this .sortMixFilesAndDirs = sortMixFilesAndDirs;
0977:                    this .sortIgnoreCase = sortIgnoreCase;
0978:                }
0979:
0980:                public int compare(Object obj1, Object obj2) {
0981:                    VFSFile file1 = (VFSFile) obj1;
0982:                    VFSFile file2 = (VFSFile) obj2;
0983:
0984:                    if (!sortMixFilesAndDirs) {
0985:                        if (file1.getType() != file2.getType())
0986:                            return file2.getType() - file1.getType();
0987:                    }
0988:
0989:                    return StandardUtilities.compareStrings(file1.getName(),
0990:                            file2.getName(), sortIgnoreCase);
0991:                }
0992:            } //}}}
0993:
0994:            //{{{ Private members
0995:            private String name;
0996:            private int caps;
0997:            private String[] extAttrs;
0998:            private static List<ColorEntry> colors;
0999:            private static final Object lock = new Object();
1000:
1001:            //{{{ Class initializer
1002:            static {
1003:                EditBus.addToBus(new EBComponent() {
1004:                    public void handleMessage(EBMessage msg) {
1005:                        if (msg instanceof  PropertiesChanged) {
1006:                            synchronized (lock) {
1007:                                colors = null;
1008:                            }
1009:                        }
1010:                    }
1011:                });
1012:            } //}}}
1013:
1014:            private long val;
1015:
1016:            //{{{ recursive listFiles() method
1017:            private void listFiles(Object session, Collection<String> stack,
1018:                    List<String> files, String directory, VFSFileFilter filter,
1019:                    boolean recursive, Component comp, boolean skipBinary,
1020:                    boolean skipHidden) throws IOException {
1021:                if (stack.contains(directory)) {
1022:                    Log.log(Log.ERROR, this , "Recursion in _listDirectory(): "
1023:                            + directory);
1024:                    return;
1025:                }
1026:
1027:                stack.add(directory);
1028:
1029:                Thread ct = Thread.currentThread();
1030:                WorkThread wt = null;
1031:                if (ct instanceof  WorkThread) {
1032:                    wt = (WorkThread) ct;
1033:                }
1034:
1035:                VFSFile[] _files = _listFiles(session, directory, comp);
1036:                if (_files == null || _files.length == 0)
1037:                    return;
1038:
1039:                for (int i = 0; i < _files.length; i++) {
1040:                    if (wt != null && wt.isAborted())
1041:                        break;
1042:                    VFSFile file = _files[i];
1043:                    if (skipHidden
1044:                            && (file.isHidden() || MiscUtilities.isBackup(file
1045:                                    .getName())))
1046:                        continue;
1047:                    if (!filter.accept(file))
1048:                        continue;
1049:                    if (file.getType() == VFSFile.DIRECTORY
1050:                            || file.getType() == VFSFile.FILESYSTEM) {
1051:                        if (recursive) {
1052:                            // resolve symlinks to avoid loops
1053:                            String canonPath = _canonPath(session, file
1054:                                    .getPath(), comp);
1055:                            if (!MiscUtilities.isURL(canonPath))
1056:                                canonPath = MiscUtilities
1057:                                        .resolveSymlinks(canonPath);
1058:
1059:                            listFiles(session, stack, files, canonPath, filter,
1060:                                    recursive, comp, skipBinary, skipHidden);
1061:                        }
1062:
1063:                    } else // It's a regular file
1064:                    {
1065:                        if (skipBinary) {
1066:                            try {
1067:                                if (file.isBinary(session)) {
1068:                                    Log.log(Log.NOTICE, this , file.getPath()
1069:                                            + ": skipped as a binary file");
1070:                                    continue;
1071:                                }
1072:                            } catch (IOException e) {
1073:                                Log.log(Log.ERROR, this , e);
1074:                                // may be not binary...
1075:                            }
1076:                        }
1077:
1078:                        Log.log(Log.DEBUG, this , file.getPath());
1079:                        files.add(file.getPath());
1080:                    }
1081:                }
1082:            } //}}}
1083:
1084:            //{{{ loadColors() method
1085:            private static void loadColors() {
1086:                synchronized (lock) {
1087:                    colors = new ArrayList<ColorEntry>();
1088:
1089:                    if (!jEdit.getBooleanProperty("vfs.browser.colorize"))
1090:                        return;
1091:
1092:                    String glob;
1093:                    int i = 0;
1094:                    while ((glob = jEdit.getProperty("vfs.browser.colors." + i
1095:                            + ".glob")) != null) {
1096:                        try {
1097:                            colors.add(new ColorEntry(Pattern
1098:                                    .compile(StandardUtilities.globToRE(glob)),
1099:                                    jEdit.getColorProperty(
1100:                                            "vfs.browser.colors." + i
1101:                                                    + ".color", Color.black)));
1102:                        } catch (PatternSyntaxException e) {
1103:                            Log.log(Log.ERROR, VFS.class,
1104:                                    "Invalid regular expression: " + glob);
1105:                            Log.log(Log.ERROR, VFS.class, e);
1106:                        }
1107:
1108:                        i++;
1109:                    }
1110:                }
1111:            } //}}}
1112:
1113:            //{{{ ColorEntry class
1114:            static class ColorEntry {
1115:                Pattern re;
1116:                Color color;
1117:
1118:                ColorEntry(Pattern re, Color color) {
1119:                    this .re = re;
1120:                    this .color = color;
1121:                }
1122:            } //}}}
1123:
1124:            //}}}
1125:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.