org.gjt.sp.jedit.io.VFSManager Maven / Gradle / Ivy
/*
* VFSManager.java - Main class of virtual filesystem
* :tabSize=8:indentSize=8:noTabs=false:
* :folding=explicit:collapseFolds=1:
*
* Copyright (C) 2000, 2005 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;
//{{{ Imports
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import java.awt.Component;
import java.awt.Frame;
import java.io.IOException;
import java.util.*;
import org.gjt.sp.jedit.*;
import org.gjt.sp.util.Log;
import org.gjt.sp.util.StandardUtilities;
//}}}
/**
* jEdit's virtual filesystem allows it to transparently edit files
* stored elsewhere than the local filesystem, for example on an FTP
* site. See the {@link VFS} class for implementation details.
*
* Note that most of the jEdit API is not thread-safe, so special care
* must be taken when making jEdit API calls. Also, it is not safe to
* call SwingUtilities.invokeAndWait()
from a work request;
* it can cause a deadlock if the given runnable then later calls
* {@link #waitForRequests()}.
*
* @author Slava Pestov
* @version $Id: VFSManager.java 12504 2008-04-22 23:12:43Z ezust $
*/
public class VFSManager
{
/**
* The service type. See {@link org.gjt.sp.jedit.ServiceManager}.
* @since jEdit 4.2pre1
*/
public static final String SERVICE = "org.gjt.sp.jedit.io.VFS";
//{{{ init() method
/**
* Do not call.
*/
public static void init()
{
} //}}}
//{{{ start() method
/**
* Do not call.
*/
public static void start()
{
} //}}}
//{{{ VFS methods
//{{{ getFileVFS() method
/**
* Returns the local filesystem VFS.
* @since jEdit 2.5pre1
*/
public static VFS getFileVFS()
{
return fileVFS;
} //}}}
//{{{ getUrlVFS() method
/**
* Returns the URL VFS.
* @since jEdit 2.5pre1
*/
public static VFS getUrlVFS()
{
return urlVFS;
} //}}}
//{{{ getVFSByName() method
/**
* @deprecated Use getVFSForProtocol()
instead.
*/
public static VFS getVFSByName(String name)
{
// in new api, protocol always equals name
VFS vfs = (VFS)ServiceManager.getService(SERVICE,name);
if(vfs == null)
return vfsHash.get(name);
else
return vfs;
} //}}}
//{{{ getVFSForProtocol() method
/**
* Returns the VFS for the specified protocol.
* @param protocol The protocol
* @since jEdit 2.5pre1
*/
public static VFS getVFSForProtocol(String protocol)
{
if(protocol.equals("file"))
return fileVFS;
else
{
VFS vfs = (VFS)ServiceManager.getService(SERVICE,protocol);
if(vfs == null)
vfs = protocolHash.get(protocol);
if(vfs != null)
return vfs;
else
return urlVFS;
}
} //}}}
//{{{ getVFSForPath() method
/**
* Returns the VFS for the specified path.
* @param path The path
* @since jEdit 2.6pre4
*/
public static VFS getVFSForPath(String path)
{
if(MiscUtilities.isURL(path))
return getVFSForProtocol(MiscUtilities.getProtocolOfURL(path));
else
return fileVFS;
} //}}}
//{{{ registerVFS() method
/**
* @deprecated Write a services.xml
file instead;
* see {@link org.gjt.sp.jedit.ServiceManager}.
*/
public static void registerVFS(String protocol, VFS vfs)
{
Log.log(Log.DEBUG,VFSManager.class,"Registered "
+ vfs.getName() + " filesystem for "
+ protocol + " protocol");
vfsHash.put(vfs.getName(),vfs);
protocolHash.put(protocol,vfs);
} //}}}
//{{{ getFilesystems() method
/**
* @deprecated Use getVFSs()
instead.
*/
public static Enumeration getFilesystems()
{
return vfsHash.elements();
} //}}}
//{{{ getVFSs() method
/**
* Returns a list of all registered filesystems.
* @since jEdit 4.2pre1
*/
public static String[] getVFSs()
{
// the sooner ppl move to the new api, the less we'll need
// crap like this
List returnValue = new LinkedList();
String[] newAPI = ServiceManager.getServiceNames(SERVICE);
if(newAPI != null)
{
for(int i = 0; i < newAPI.length; i++)
{
returnValue.add(newAPI[i]);
}
}
Enumeration oldAPI = vfsHash.keys();
while(oldAPI.hasMoreElements())
returnValue.add(oldAPI.nextElement());
return returnValue.toArray(new String[returnValue.size()]);
} //}}}
//}}}
//{{{ I/O request methods
//{{{ errorOccurred() method
/**
* Returns if the last request caused an error.
*/
public static boolean errorOccurred()
{
return error;
} //}}}
//{{{ error() method
/**
* Handle an I/O error.
* @since jEdit 4.3pre3
*/
public static void error(IOException e, String path, Component comp)
{
Log.log(Log.ERROR,VFSManager.class,e);
VFSManager.error(comp,path,"ioerror",new String[] { e.toString() });
} //}}}
//{{{ error() method
/**
* @deprecated Call the other error()
method instead.
*/
public static void error(final Component comp, final String error, final Object[] args)
{
// the 'error' chicanery ensures that stuff like:
// VFSManager.waitForRequests()
// if(VFSManager.errorOccurred())
// ...
// will work (because the below runnable will only be
// executed in the next event)
VFSManager.error = true;
} //}}}
//{{{ error() method
/**
* Reports an I/O error.
*
* @param comp The component
* @param path The path name that caused the error
* @param messageProp The error message property name
* @param args Positional parameters
* @since jEdit 4.0pre3
*/
public static void error(Component comp,
final String path,
String messageProp,
Object[] args)
{
final Frame frame = JOptionPane.getFrameForComponent(comp);
synchronized(errorLock)
{
error = true;
}
} //}}}
//{{{ sendVFSUpdate() method
/**
* Sends a VFS update message.
* @param vfs The VFS
* @param path The path that changed
* @param parent True if an update should be sent for the path's
* parent too
* @since jEdit 2.6pre4
*/
public static void sendVFSUpdate(VFS vfs, String path, boolean parent)
{
if(parent)
{
sendVFSUpdate(vfs,vfs.getParentOfPath(path),false);
sendVFSUpdate(vfs,path,false);
}
else
{
// have to do this hack until VFSPath class is written
if(path.length() != 1 && (path.endsWith("/")
|| path.endsWith(java.io.File.separator)))
path = path.substring(0,path.length() - 1);
}
} //}}}
//{{{ SendVFSUpdatesSafely class
static class SendVFSUpdatesSafely implements Runnable
{
public void run()
{
}
} //}}}
//{{{ Private members
//{{{ Static variables
private static VFS fileVFS;
private static VFS urlVFS;
private static final Hashtable vfsHash;
private static final Map protocolHash;
private static boolean error;
private static final Object errorLock = new Object();
private static final Object vfsUpdateLock = new Object();
//}}}
//{{{ Class initializer
static
{
fileVFS = new FileVFS();
urlVFS = new UrlVFS();
vfsHash = new Hashtable();
protocolHash = new Hashtable();
} //}}}
private VFSManager() {}
//}}}
}