⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vfs.java

📁 开源的java 编辑器源代码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* * VFS.java - Virtual filesystem implementation * :tabSize=8:indentSize=8:noTabs=false: * :folding=explicit:collapseFolds=1: * * Copyright (C) 2000, 2003 Slava Pestov * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. */package org.gjt.sp.jedit.io;//{{{ Importsimport gnu.regexp.*;import java.awt.Color;import java.awt.Component;import java.io.*;import java.util.*;import org.gjt.sp.jedit.buffer.BufferIORequest;import org.gjt.sp.jedit.msg.PropertiesChanged;import org.gjt.sp.jedit.*;import org.gjt.sp.util.Log;//}}}/** * A virtual filesystem implementation.<p> * * Plugins can provide virtual file systems by defining entries in their * <code>services.xml</code> files like so: * * <pre>&lt;SERVICE CLASS="org.gjt.sp.jedit.io.VFS" NAME="<i>name</i>"&gt; *    new <i>MyVFS</i>(); *&lt;/SERVICE&gt;</pre> * * URLs of the form <code><i>name</i>:<i>path</i></code> will then be handled * by the VFS named <code><i>name</i></code>.<p> * * See {@link org.gjt.sp.jedit.ServiceManager} for details.<p> * * <h3>Session objects:</h3> * * A session is used to persist things like login information, any network * sockets, etc. File system implementations that do not need this kind of * persistence return a dummy object as a session.<p> * * Methods whose names are prefixed with "_" expect to be given a * previously-obtained session object. A session must be obtained from the AWT * thread in one of two ways: * * <ul> * <li>{@link #createVFSSession(String,Component)}</li> * <li>{@link #showBrowseDialog(Object[],Component)}</li> * </ul> * * When done, the session must be disposed of using * {@link #_endVFSSession(Object,Component)}.<p> * * <h3>Thread safety:</h3> * * The following methods cannot be called from an I/O thread: * * <ul> * <li>{@link #createVFSSession(String,Component)}</li> * <li>{@link #insert(View,Buffer,String)}</li> * <li>{@link #load(View,Buffer,String)}</li> * <li>{@link #save(View,Buffer,String)}</li> * <li>{@link #showBrowseDialog(Object[],Component)}</li> * </ul> * * All remaining methods are required to be thread-safe in subclasses. * * <h3>Implementing a VFS</h3> * * You can override as many or as few methods as you want. Make sure * {@link #getCapabilities()} returns a value reflecting the functionality * implemented by your VFS. * * @see VFSManager#getVFSForPath(String) * @see VFSManager#getVFSForProtocol(String) * * @author Slava Pestov * @author $Id: VFS.java,v 1.39 2003/09/08 01:24:11 spestov Exp $ */public abstract class VFS{	//{{{ Capabilities	/**	 * Read capability.	 * @since jEdit 2.6pre2	 */	public static final int READ_CAP = 1 << 0;	/**	 * Write capability.	 * @since jEdit 2.6pre2	 */	public static final int WRITE_CAP = 1 << 1;	/**	 * @deprecated Do not define this capability.<p>	 *	 * This was the official API for adding items to a file	 * system browser's <b>Plugins</b> menu in jEdit 4.1 and earlier. In	 * jEdit 4.2, there is a different way of doing this, you must provide	 * a <code>browser.actions.xml</code> file in your plugin JAR, and	 * define <code>plugin.<i>class</i>.browser-menu-item</code>	 * or <code>plugin.<i>class</i>.browser-menu</code> properties.	 * See {@link org.gjt.sp.jedit.EditPlugin} for details.	 */	public static final int BROWSE_CAP = 1 << 2;	/**	 * Delete file capability.	 * @since jEdit 2.6pre2	 */	public static final int DELETE_CAP = 1 << 3;	/**	 * Rename file capability.	 * @since jEdit 2.6pre2	 */	public static final int RENAME_CAP = 1 << 4;	/**	 * Make directory capability.	 * @since jEdit 2.6pre2	 */	public static final int MKDIR_CAP = 1 << 5;	/**	 * Low latency capability. If this is not set, then a confirm dialog	 * will be shown before doing a directory search in this VFS.	 * @since jEdit 4.1pre1	 */	public static final int LOW_LATENCY_CAP = 1 << 6;	/**	 * Case insensitive file system capability.	 * @since jEdit 4.1pre1	 */	public static final int CASE_INSENSITIVE_CAP = 1 << 7;	//}}}	//{{{ Extended attributes	/**	 * File type.	 * @since jEdit 4.2pre1	 */	public static final String EA_TYPE = "type";	/**	 * File status (read only, read write, etc).	 * @since jEdit 4.2pre1	 */	public static final String EA_STATUS = "status";	/**	 * File size.	 * @since jEdit 4.2pre1	 */	public static final String EA_SIZE = "size";	/**	 * File last modified date.	 * @since jEdit 4.2pre1	 */	public static final String EA_MODIFIED = "modified";	//}}}	//{{{ VFS constructor	/**	 * @deprecated Use the form where the constructor takes a capability	 * list.	 */	public VFS(String name)	{		this(name,0);	} //}}}	//{{{ VFS constructor	/**	 * Creates a new virtual filesystem.	 * @param name The name	 * @param caps The capabilities	 */	public VFS(String name, int caps)	{		this.name = name;		this.caps = caps;		// reasonable defaults (?)		this.extAttrs = new String[] { EA_SIZE, EA_TYPE };	} //}}}	//{{{ VFS constructor	/**	 * Creates a new virtual filesystem.	 * @param name The name	 * @param caps The capabilities	 * @param extAttrs The extended attributes	 * @since jEdit 4.2pre1	 */	public VFS(String name, int caps, String[] extAttrs)	{		this.name = name;		this.caps = caps;		this.extAttrs = extAttrs;	} //}}}	//{{{ getName() method	/**	 * Returns this VFS's name. The name is used to obtain the	 * label stored in the <code>vfs.<i>name</i>.label</code>	 * property.	 */	public String getName()	{		return name;	} //}}}	//{{{ getCapabilities() method	/**	 * Returns the capabilities of this VFS.	 * @since jEdit 2.6pre2	 */	public int getCapabilities()	{		return caps;	} //}}}	//{{{ getExtendedAttributes() method	/**	 * Returns the extended attributes supported by this VFS.	 * @since jEdit 4.2pre1	 */	public String[] getExtendedAttributes()	{		return extAttrs;	} //}}}	//{{{ showBrowseDialog() method	/**	 * Displays a dialog box that should set up a session and return	 * the initial URL to browse.	 * @param session Where the VFS session will be stored	 * @param comp The component that will parent error dialog boxes	 * @return The URL	 * @since jEdit 2.7pre1	 */	public String showBrowseDialog(Object[] session, Component comp)	{		return null;	} //}}}	//{{{ getFileName() method	/**	 * Returns the file name component of the specified path.	 * @param path The path	 * @since jEdit 3.1pre4	 */	public String getFileName(String path)	{		if(path.equals("/"))			return path;		if(path.endsWith("/") || path.endsWith(File.separator))			path = path.substring(0,path.length() - 1);		int index = Math.max(path.lastIndexOf('/'),			path.lastIndexOf(File.separatorChar));		if(index == -1)			index = path.indexOf(':');		// don't want getFileName("roots:") to return ""		if(index == -1 || index == path.length() - 1)			return path;		return path.substring(index + 1);	} //}}}	//{{{ getParentOfPath() method	/**	 * Returns the parent of the specified path. This must be	 * overridden to return a non-null value for browsing of this	 * filesystem to work.	 * @param path The path	 * @since jEdit 2.6pre5	 */	public String getParentOfPath(String path)	{		// ignore last character of path to properly handle		// paths like /foo/bar/		int count = Math.max(0,path.length() - 2);		int index = path.lastIndexOf(File.separatorChar,count);		if(index == -1)			index = path.lastIndexOf('/',count);		if(index == -1)		{			// this ensures that getFileParent("protocol:"), for			// example, is "protocol:" and not "".			index = path.lastIndexOf(':');		}		return path.substring(0,index + 1);	} //}}}	//{{{ constructPath() method	/**	 * Constructs a path from the specified directory and	 * file name component. This must be overridden to return a	 * non-null value, otherwise browsing this filesystem will	 * not work.<p>	 *	 * Unless you are writing a VFS, this method should not be called	 * directly. To ensure correct behavior, you <b>must</b> call	 * {@link org.gjt.sp.jedit.MiscUtilities#constructPath(String,String)}	 * instead.	 *	 * @param parent The parent directory	 * @param path The path	 * @since jEdit 2.6pre2	 */	public String constructPath(String parent, String path)	{		return parent + path;	} //}}}	//{{{ getFileSeparator() method	/**	 * Returns the file separator used by this VFS.	 * @since jEdit 2.6pre9	 */	public char getFileSeparator()	{		return '/';	} //}}}	//{{{ getTwoStageSaveName() method	/**	 * Returns a temporary file name based on the given path.	 *	 * By default jEdit first saves a file to <code>#<i>name</i>#save#</code>	 * and then renames it to the original file. However some virtual file	 * systems might not support the <code>#</code> character in filenames,	 * so this method permits the VFS to override this behavior.	 *	 * @param path The path name	 * @since jEdit 4.1pre7	 */	public String getTwoStageSaveName(String path)	{		return MiscUtilities.constructPath(getParentOfPath(path),			'#' + getFileName(path) + "#save#");	} //}}}	//{{{ reloadDirectory() method	/**	 * Called before a directory is reloaded by the file system browser.	 * Can be used to flush a cache, etc.	 * @since jEdit 4.0pre3	 */	public void reloadDirectory(String path) {} //}}}	//{{{ createVFSSession() method	/**	 * Creates a VFS session. This method is called from the AWT thread,	 * so it should not do any I/O. It could, however, prompt for	 * a login name and password, for example.	 * @param path The path in question	 * @param comp The component that will parent any dialog boxes shown	 * @return The session	 * @since jEdit 2.6pre3	 */	public Object createVFSSession(String path, Component comp)	{		return new Object();	} //}}}	//{{{ load() method	/**	 * Loads the specified buffer. The default implementation posts	 * an I/O request to the I/O thread.	 * @param view The view	 * @param buffer The buffer	 * @param path The path	 */	public boolean load(View view, Buffer buffer, String path)	{		if((getCapabilities() & READ_CAP) == 0)		{			VFSManager.error(view,path,"vfs.not-supported.load",new String[] { name });			return false;		}		Object session = createVFSSession(path,view);		if(session == null)			return false;		if((getCapabilities() & WRITE_CAP) == 0)			buffer.setReadOnly(true);		BufferIORequest request = new BufferIORequest(			BufferIORequest.LOAD,view,buffer,session,this,path);		if(buffer.isTemporary())			// this makes HyperSearch much faster			request.run();		else			VFSManager.runInWorkThread(request);		return true;	} //}}}	//{{{ save() method	/**	 * Saves the specifies buffer. The default implementation posts	 * an I/O request to the I/O thread.	 * @param view The view	 * @param buffer The buffer	 * @param path The path	 */	public boolean save(View view, Buffer buffer, String path)	{		if((getCapabilities() & WRITE_CAP) == 0)		{			VFSManager.error(view,path,"vfs.not-supported.save",new String[] { name });			return false;		}		Object session = createVFSSession(path,view);		if(session == null)			return false;		/* When doing a 'save as', the path to save to (path)		 * will not be the same as the buffer's previous path		 * (buffer.getPath()). In that case, we want to create		 * a backup of the new path, even if the old path was		 * backed up as well (BACKED_UP property set) */		if(!path.equals(buffer.getPath()))			buffer.unsetProperty(Buffer.BACKED_UP);		VFSManager.runInWorkThread(new BufferIORequest(			BufferIORequest.SAVE,view,buffer,session,this,path));		return true;	} //}}}	//{{{ insert() method	/**	 * Inserts a file into the specified buffer. The default implementation	 * posts an I/O request to the I/O thread.	 * @param view The view	 * @param buffer The buffer	 * @param path The path	 */	public boolean insert(View view, Buffer buffer, String path)	{		if((getCapabilities() & READ_CAP) == 0)		{			VFSManager.error(view,path,"vfs.not-supported.load",new String[] { name });			return false;		}		Object session = createVFSSession(path,view);		if(session == null)			return false;		VFSManager.runInWorkThread(new BufferIORequest(			BufferIORequest.INSERT,view,buffer,session,this,path));		return true;	} //}}}	// A method name that starts with _ requires a session object	//{{{ _canonPath() method	/**	 * Returns the canonical form of the specified path name. For example,	 * <code>~</code> might be expanded to the user's home directory.	 * @param session The session	 * @param path The path	 * @param comp The component that will parent error dialog boxes	 * @exception IOException if an I/O error occurred	 * @since jEdit 4.0pre2	 */	public String _canonPath(Object session, String path, Component comp)		throws IOException	{		return path;	} //}}}	//{{{ _listDirectory() method	/**	 * A convinience method that matches file names against globs, and can	 * optionally list the directory recursively.	 * @param session The session	 * @param directory The directory. Note that this must be a full	 * URL, including the host name, path name, and so on. The	 * username and password (if needed by the VFS) is obtained from the	 * session instance.	 * @param glob Only file names matching this glob will be returned	 * @param recursive If true, subdirectories will also be listed.	 * @param comp The component that will parent error dialog boxes	 * @exception IOException if an I/O error occurred	 * @since jEdit 4.1pre1	 */	public String[] _listDirectory(Object session, String directory,		String glob, boolean recursive, Component comp)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -