/**
* Aptana Studio
* Copyright (c) 2005-2012 by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the GNU Public License (GPL) v3 (with exceptions).
* Please see the license.html included with this distribution for details.
* Any modifications to this file must keep this entire header intact.
*/
// $codepro.audit.disable closeWhereCreated
// $codepro.audit.disable questionableAssignment
// $codepro.audit.disable unnecessaryExceptions
// $codepro.audit.disable emptyCatchClause
// $codepro.audit.disable variableDeclaredInLoop
package com.aptana.filesystem.ftp.internal;
import java.io.ByteArrayInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.UnknownHostException;
import java.text.MessageFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import java.util.regex.Matcher;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.PerformanceStats;
import org.eclipse.core.runtime.Status;
import com.aptana.core.io.vfs.ExtendedFileInfo;
import com.aptana.core.io.vfs.IExtendedFileStore;
import com.aptana.core.util.ExpiringMap;
import com.aptana.filesystem.ftp.FTPPlugin;
import com.aptana.filesystem.ftp.IFTPConnectionFileManager;
import com.aptana.filesystem.ftp.IFTPConstants;
import com.aptana.filesystem.ftp.Policy;
import com.aptana.ide.core.io.ConnectionContext;
import com.aptana.ide.core.io.CoreIOPlugin;
import com.aptana.ide.core.io.PermissionDeniedException;
import com.aptana.ide.core.io.preferences.PermissionDirection;
import com.aptana.ide.core.io.preferences.PreferenceUtils;
import com.enterprisedt.net.ftp.FTPClient;
import com.enterprisedt.net.ftp.FTPClientInterface;
import com.enterprisedt.net.ftp.FTPConnectMode;
import com.enterprisedt.net.ftp.FTPConnectionClosedException;
import com.enterprisedt.net.ftp.FTPException;
import com.enterprisedt.net.ftp.FTPFile;
import com.enterprisedt.net.ftp.FTPFileFactory;
import com.enterprisedt.net.ftp.FTPInputStream;
import com.enterprisedt.net.ftp.FTPMessageListener;
import com.enterprisedt.net.ftp.FTPOutputStream;
import com.enterprisedt.net.ftp.FTPReply;
import com.enterprisedt.net.ftp.FTPTransferType;
import com.enterprisedt.net.ftp.MalformedReplyException;
import com.enterprisedt.net.ftp.pro.ProFTPClient;
/**
* @author Max Stepanov
*/
public class FTPConnectionFileManager extends BaseFTPConnectionFileManager implements IFTPConnectionFileManager,
IPoolConnectionManager
{
private static final String TMP_TIMEZONE_CHECK = "_tmp_tz_check"; //$NON-NLS-1$
private final static String WINDOWS_STR = "WINDOWS"; //$NON-NLS-1$
private final static SimpleDateFormat[] UTIME_FORMATS = new SimpleDateFormat[] {
new SimpleDateFormat("'UTIME' yyyyMMddHHmmss '{0}'"), //$NON-NLS-1$
new SimpleDateFormat("'UTIME {0}' yyyyMMddHHmmss yyyyMMddHHmmss yyyyMMddHHmmss 'UTC'"), //$NON-NLS-1$
};
protected FTPClient ftpClient;
private List<String> serverFeatures;
protected String transferType;
protected String timezone;
protected IPath cwd;
private FTPFileFactory fileFactory;
private Boolean statSupported = null;
private Boolean listASupported = null;
private int utimeFormat = -1;
private Map<IPath, FTPFile> ftpFileCache = new ExpiringMap<IPath, FTPFile>(CACHE_TTL);
private long serverToLocalTimeZoneShift = Integer.MIN_VALUE;
protected boolean hasServerInfo;
protected PrintWriter messageLogWriter;
protected FTPClientPool pool;
/*
* (non-Javadoc)
* @see com.aptana.ide.core.ftp.IFTPConnectionFileManager#init(java.lang.String, int,
* org.eclipse.core.runtime.IPath, java.lang.String, char[], boolean, java.lang.String, java.lang.String,
* java.lang.String)
*/
public void init(String host, int port, IPath basePath, String login, char[] password, boolean passive,
String transferType, String encoding, String timezone)
{
Assert.isTrue(ftpClient == null, Messages.FTPConnectionFileManager_already_initialized);
try
{
this.pool = new FTPClientPool(this);
this.ftpClient = new ProFTPClient();
this.host = host;
this.port = port;
this.login = login;
this.password = (password == null) ? EMPTY_PASSWORD : password;
this.basePath = (basePath != null) ? basePath : Path.ROOT;
this.authId = Policy.generateAuthId("FTP", login, host, port); //$NON-NLS-1$
this.transferType = transferType;
this.timezone = (timezone != null && timezone.length() == 0) ? null : timezone;
initFTPClient(ftpClient, passive, encoding);
}
catch (Exception e)
{
FTPPlugin.log(new Status(IStatus.WARNING, FTPPlugin.PLUGIN_ID,
Messages.FTPConnectionFileManager_initialization_failed, e));
ftpClient = null;
}
}
protected static void initFTPClient(FTPClient ftpClient, boolean passive, String encoding) throws IOException,
FTPException
{
ftpClient.setTimeout(TIMEOUT);
ftpClient.setControlEncoding(encoding);
ftpClient.setMonitorInterval(1024);
ftpClient.setConnectMode(passive ? FTPConnectMode.PASV : FTPConnectMode.ACTIVE);
ftpClient.setRetryCount(RETRY);
ftpClient.setRetryDelay(RETRY_DELAY);
ftpClient.setServerWakeupInterval(KEEPALIVE_INTERVAL);
ftpClient.setDeleteOnFailure(true);
ftpClient.setTransferBufferSize(TRANSFER_BUFFER_SIZE);
}
private static void connectFTPClient(FTPClient ftpClient) throws IOException, FTPException
{
PerformanceStats stats = PerformanceStats.getStats(
"com.aptana.filesystem.ftp/perf/connect", FTPConnectionFileManager.class.getName()); //$NON-NLS-1$
stats.startRun(ftpClient.getRemoteHost());
try
{
ftpClient.connect();
}
finally
{
stats.endRun();
}
}
protected void initAndAuthFTPClient(FTPClientInterface clientInterface, IProgressMonitor monitor)
throws IOException, FTPException
{
if (clientInterface.connected())
{
return;
}
FTPClient newFtpClient = (FTPClient) clientInterface;
initFTPClient(newFtpClient, FTPConnectMode.PASV.equals(ftpClient.getConnectMode()),
ftpClient.getControlEncoding());
newFtpClient.setRemoteHost(host);
newFtpClient.setRemotePort(port);
Policy.checkCanceled(monitor);
connectFTPClient(newFtpClient);
monitor.worked(1);
Policy.checkCanceled(monitor);
newFtpClient.login(login, String.copyValueOf(password));
monitor.worked(1);
}
protected static void setMessageLogger(FTPClient ftpClient, final PrintWriter writer)
{
FTPMessageListener listener = null;
if (writer != null && ftpClient.getMessageListener() == null)
{
listener = new FTPMessageListener()
{
public void logCommand(String command)
{
if (command.startsWith("---> ")) { //$NON-NLS-1$
command = command.substring(5);
}
Matcher matcher = PASS_COMMAND_PATTERN.matcher(command);
if (matcher.matches())
{
command = matcher.replaceFirst("$1********"); //$NON-NLS-1$
}
writer.print("ftp> "); //$NON-NLS-1$
writer.println(command);
writer.flush();
}
public void logReply(String reply)
{
writer.println(reply);
writer.flush();
}
};
}
ftpClient.setMessageListener(listener);
}
/*
* (non-Javadoc)
* @see com.aptana.core.io.vfs.IConnectionFileManager#connect(org.eclipse.core.runtime.IProgressMonitor)
*/
public void connect(IProgressMonitor monitor) throws CoreException
{
Assert.isTrue(ftpClient != null, Messages.FTPConnectionFileManager_not_initialized);
monitor = Policy.monitorFor(monitor);
try
{
cwd = null;
cleanup();
ConnectionContext context = CoreIOPlugin.getConnectionContext(this);
if (messageLogWriter == null)
{
if (context != null)
{
Object object = context.get(ConnectionContext.COMMAND_LOG);
if (object instanceof PrintWriter)
{
messageLogWriter = (PrintWriter) object;
}
else if (object instanceof OutputStream)
{
messageLogWriter = new PrintWriter((OutputStream) object);
}
}
if (messageLogWriter == null)
{
messageLogWriter = FTPPlugin.getDefault().getFTPLogWriter();
}
if (messageLogWriter != null)
{
messageLogWriter.println(MessageFormat.format("---------- FTP {0} ----------", host)); //$NON-NLS-1$
setMessageLogger(ftpClient, messageLogWriter);
}
}
else
{
messageLogWriter.println(MessageFormat.format("---------- RECONNECTING - FTP {0} ----------", host)); //$NON-NLS-1$
}
monitor.beginTask(Messages.FTPConnectionFileManager_establishing_connection, IProgressMonitor.UNKNOWN);
ftpClient.setRemoteHost(host);
ftpClient.setRemotePort(port);
while (true)
{
monitor.subTask(Messages.FTPConnectionFileManager_connecting);
connectFTPClient(ftpClient);
if (password.length == 0 && !IFTPConstants.LOGIN_ANONYMOUS.equals(login)
&& (context == null || !context.getBoolean(ConnectionContext.NO_PASSWORD_PROMPT)))
{
getOrPromptPassword(MessageFormat.format(Messages.FTPConnectionFileManager_ftp_auth, host),
Messages.FTPConnectionFileManager_specify_password);
}
Policy.checkCanceled(monitor);
monitor.subTask(Messages.FTPConnectionFileManager_authenticating);
try
{
ftpClient.login(login, String.copyValueOf(password));
}
catch (FTPException e)
{
Policy.checkCanceled(monitor);
if (ftpClient.getLastValidReply() == null
|| "331".equals(ftpClient.getLastValidReply().getReplyCode())) { //$NON-NLS-1$
if (context != null && context.getBoolean(ConnectionContext.NO_PASSWORD_PROMPT))
{
throw new CoreException(new Status(Status.ERROR, FTPPlugin.PLUGIN_ID, MessageFormat.format(
Messages.FTPConnectionFileManager_FailedAuthenticate, e.getLocalizedMessage()), e));
}
promptPassword(MessageFormat.format(Messages.FTPConnectionFileManager_ftp_auth, host),
Messages.FTPConnectionFileManager_invalid_password);
safeQuit();
continue;
}
throw e;
}
break;
}
Policy.checkCanceled(monitor);
changeCurrentDir(basePath);
ftpClient.setType(IFTPConstants.TRANSFER_TYPE_ASCII.equals(transferType) ? FTPTransferType.ASCII
: FTPTransferType.BINARY);
if ((hasServerInfo || (context != null && context.getBoolean(ConnectionContext.QUICK_CONNECT)))
&& !(context != null && context.getBoolean(ConnectionContext.DETECT_TIMEZONE)))
{
return;
}
getherServerInfo(context, monitor);
}
catch (OperationCanceledException e)
{
safeQuit();
throw e;
}
catch (CoreException e)
{
safeQuit();
throw e;
}
catch (UnknownHostException e)
{
safeQuit();
throw new CoreException(new Status(Status.ERROR, FTPPlugin.PLUGIN_ID,
Messages.FTPConnectionFileManager_HostNameNotFound + e.getLocalizedMessage(), e));
}
catch (FileNotFoundException e)
{
safeQuit();
throw new CoreException(new Status(Status.ERROR, FTPPlugin.PLUGIN_ID,
Messages.FTPConnectionFileManager_RemoteFolderNotFound + e.getLocalizedMessage(), e));
}
catch (Exception e)
{
safeQuit();
throw new CoreException(new Status(Status.ERROR, FTPPlugin.PLUGIN_ID,
Messages.FTPConnectionFileManager_connection_failed + e.getLocalizedMessage(), e));
}
finally
{
monitor.done();
}
}
@SuppressWarnings("deprecation")
protected void getherServerInfo(ConnectionContext context, IProgressMonitor monitor)
{
Policy.checkCanceled(monitor);
monitor.subTask(Messages.FTPConnectionFileManager_gethering_server_info);
serverFeatures = null;
try
{
String[] features = ftpClient.features();
if (features != null && features.length > 0)
{
serverFeatures = new ArrayList<String>();
for (int i = 0; i < features.length; ++i)
{
String feature = features[i].trim();
if (feature.indexOf(' ') > 0)
{
feature = feature.substring(0, feature.indexOf(' '));
}
serverFeatures.add(feature);
}
}
}
catch (Exception e)
{
e.getCause();
}
try
{
String[] validCodes = { "214" }; //$NON-NLS-1$
FTPReply reply = ftpClient.sendCommand("SITE HELP"); //$NON-NLS-1$
ftpClient.validateReply(reply, validCodes);
if (serverFeatures == null)
{
serverFeatures = new ArrayList<String>();
}
String[] data = reply.getReplyData();
for (int i = 0; i < data.length; ++i)
{
String cmd = data[i].trim();
if (cmd.startsWith("214")) { //$NON-NLS-1$
continue;
}
serverFeatures.add(MessageFormat.format("SITE {0}", cmd)); //$NON-NLS-1$
}
}
catch (Exception e)
{
e.getCause();
}
Policy.checkCanceled(monitor);
FTPFile[] rootFiles = null;
try
{
rootFiles = listFiles(Path.ROOT, monitor);
}
catch (Exception e)
{
}
if (context != null && context.getBoolean(ConnectionContext.DETECT_TIMEZONE))
{
serverToLocalTimeZoneShift = Integer.MIN_VALUE;
}
else if (timezone != null)
{
TimeZone tz = TimeZone.getTimeZone(timezone);
if (tz != null)
{
long time = new Date().getTime();
serverToLocalTimeZoneShift = TimeZone.getDefault().getOffset(time) - tz.getOffset(time);
}
}
if (serverToLocalTimeZoneShift == Integer.MIN_VALUE)
{
Policy.checkCanceled(monitor);
try
{
changeCurrentDir(Path.ROOT);
FTPFile file = null;
if (rootFiles != null)
{
for (FTPFile ftpFile : rootFiles)
{
if (ftpFile.isFile() && ftpFile.getName() != null
&& !ftpFile.getName().startsWith(".ht") //$NON-NLS-1$
&& !(ftpFile.lastModified().getHours() == 0 && ftpFile.lastModified().getMinutes() == 0 && ftpFile
.lastModified().getSeconds() == 0))
{
file = ftpFile;
break;
}
}
}
if (file == null && !Path.ROOT.equals(basePath))
{
FTPFile[] ftpFiles = listFiles(basePath, monitor);
for (FTPFile ftpFile : ftpFiles)
{
if (ftpFile.isFile() && ftpFile.getName() != null
&& !ftpFile.getName().startsWith(".ht") //$NON-NLS-1$
&& !(ftpFile.lastModified().getHours() == 0 && ftpFile.lastModified().getMinutes() == 0 && ftpFile
.lastModified().getSeconds() == 0))
{
file = ftpFile;
break;
}
}
}
Date lastModifiedLocal = null;
if (file == null)
{
changeCurrentDir(basePath);
lastModifiedLocal = new Date();
ftpClient.put(new ByteArrayInputStream(new byte[] {}), TMP_TIMEZONE_CHECK);
for (FTPFile ftpFile : listFiles(basePath, monitor))
{
if (TMP_TIMEZONE_CHECK.equals(ftpFile.getName()))
{
file = ftpFile;
defaultOwner = ftpFile.getOwner();
defaultGroup = ftpFile.getGroup();
break;
}
}
}
if (file != null)
{
Date serverTimeInLocalTZ = file.lastModified();
if (serverSupportsFeature("MDTM")) { //$NON-NLS-1$
Date gmtTimeInLocalTZ = ftpClient.modtime(file.getName());
if (gmtTimeInLocalTZ != null)
{
// align to minutes
long serverToGmtShift = (gmtTimeInLocalTZ.getTime() - gmtTimeInLocalTZ.getTime() % 60000)
- (serverTimeInLocalTZ.getTime() - serverTimeInLocalTZ.getTime() % 60000);
Calendar calendar = (Calendar) Calendar.getInstance().clone();
calendar.setTime(new Date());
serverToLocalTimeZoneShift = serverToGmtShift - calendar.get(Calendar.ZONE_OFFSET)
- calendar.get(Calendar.DST_OFFSET);
}
}
if (serverToLocalTimeZoneShift == Integer.MIN_VALUE && lastModifiedLocal != null)
{
long serverToLocalShift = (lastModifiedLocal.getTime() - lastModifiedLocal.getTime() % 60000)
- (serverTimeInLocalTZ.getTime() - serverTimeInLocalTZ.getTime() % 60000);
// align to 1/4 hour
long rem = serverToLocalShift % 900000;
if (rem < 450000)
{
serverToLocalShift -= rem;
}
else
{
serverToLocalShift += (900000 - rem);
}
serverToLocalTimeZoneShift = serverToLocalShift;
}
if (TMP_TIMEZONE_CHECK.equals(file.getName()))
{
ftpClient.delete(file.getName());
}
if (context != null && serverToLocalTimeZoneShift != Integer.MIN_VALUE)
{
Calendar cal = (Calendar) Calendar.getInstance().clone();
cal.setTime(new Date());
int rawOffset = (int) (cal.get(Calendar.ZONE_OFFSET) - serverToLocalTimeZoneShift);
context.put(ConnectionContext.SERVER_TIMEZONE, TimeZone.getAvailableIDs(rawOffset));
}
}
}
catch (OperationCanceledException e)
{
throw e;
}
catch (Exception e)
{
FTPPlugin.log(new Status(IStatus.WARNING, FTPPlugin.PLUGIN_ID,
Messages.FTPConnectionFileManager_server_tz_check, e));
}
if (serverToLocalTimeZoneShift == Integer.MIN_VALUE)
{
serverToLocalTimeZoneShift = 0;
}
}
hasServerInfo = true;
}
protected void safeQuit()
{
try
{
if (ftpClient.connected())
{
ftpClient.quit();
}
}
catch (Exception e)
{
try
{
ftpClient.quitImmediately();
}
catch (Exception ignore)
{
}
}
}
/*
* (non-Javadoc)
* @see com.aptana.core.io.vfs.IConnectionFileManager#isConnected()
*/
public boolean isConnected()
{
return ftpClient != null && ftpClient.connected();
}
/*
* (non-Javadoc)
* @see com.aptana.core.io.vfs.IConnectionFileManager#disconnect(org.eclipse.core.runtime.IProgressMonitor)
*/
public synchronized void disconnect(IProgressMonitor monitor) throws CoreException
{
if (!isConnected())
{
return;
}
monitor = Policy.monitorFor(monitor);
monitor.beginTask(Messages.FTPConnectionFileManager_closing_connection, IProgressMonitor.UNKNOWN);
try
{
ftpClient.quit();
}
catch (Exception e)
{
try
{
ftpClient.quitImmediately();
}
catch (Exception ignore)
{
}
}
finally
{
cwd = null;
pool.dispose();
cleanup();
monitor.done();
}
}
protected boolean serverSupportsFeature(String feature)
{
if (serverFeatures != null)
{
return serverFeatures.contains(feature);
}
return false; // assume doesn't supports be default
}
protected void changeCurrentDir(IPath path) throws FTPException, IOException
{
try
{
if (cwd == null)
{
cwd = new Path(ftpClient.pwd());
}
if (!cwd.equals(path))
{
ftpClient.chdir(path.toPortableString());
cwd = path;
}
}
catch (FTPException e)
{
throwFileNotFound(e, path);
}
catch (IOException e)
{
cwd = null;
throw e;
}
}
private static void throwFileNotFound(FTPException e, IPath path) throws FileNotFoundException, FTPException
{
int code = e.getReplyCode();
if (code == 550 || code == 450)
{
throw initFileNotFoundException(path, e);
}
throw e;
}
private static void fillFileInfo(ExtendedFileInfo fileInfo, FTPFile ftpFile)
{
fileInfo.setExists(true);
fileInfo.setName(ftpFile.getName());
fileInfo.setDirectory(ftpFile.isDir());
fileInfo.setLength(ftpFile.size());
fileInfo.setLastModified((ftpFile.lastModified() != null) ? ftpFile.lastModified().getTime() : 0);
fileInfo.setOwner(ftpFile.getOwner());
fileInfo.setGroup(ftpFile.getGroup());
fileInfo.setPermissions(Policy.permissionsFromString(ftpFile.getPermissions()));
if (ftpFile.isLink())
{
fileInfo.setAttribute(EFS.ATTRIBUTE_SYMLINK, true);
fileInfo.setStringAttribute(EFS.ATTRIBUTE_LINK_TARGET, ftpFile.getLinkedName().trim());
}
}
private static ExtendedFileInfo createFileInfo(FTPFile ftpFile)
{
ExtendedFileInfo fileInfo = new ExtendedFileInfo(ftpFile.getName());
fillFileInfo(fileInfo, ftpFile);
return fileInfo;
}
/*
* (non-Javadoc)
* @see com.aptana.ide.core.ftp.BaseFTPConnectionFileManager#clearCache(org.eclipse.core.runtime.IPath)
*/
@Override
protected void clearCache(IPath path)
{
super.clearCache(path);
clearCacheAbsolute(basePath.append(path));
}
private void clearCacheAbsolute(IPath path)
{
int segments = path.segmentCount();
for (IPath p : new ArrayList<IPath>(ftpFileCache.keySet()))
{
if (p.segmentCount() >= segments && path.matchingFirstSegments(p) == segments)
{
ftpFileCache.remove(p);
}
}
}
/*
* (non-Javadoc)
* @see com.aptana.core.io.vfs.BaseConnectionFileManager#interruptOperation()
*/
@Override
protected void interruptOperation()
{
try
{
if (ftpClient.connected())
{
ftpClient.quitImmediately();
}
}
catch (Exception ignore)
{
}
super.interruptOperation();
}
/*
* (non-Javadoc)
* @see
* com.aptana.filesystem.ftp.internal.BaseFTPConnectionFileManager#canUseTemporaryFile(org.eclipse.core.runtime.
* IPath, com.aptana.core.io.vfs.ExtendedFileInfo, org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
protected boolean canUseTemporaryFile(IPath path, ExtendedFileInfo fileInfo, IProgressMonitor monitor)
{
if (super.canUseTemporaryFile(path, fileInfo, monitor))
{
if (fileInfo.exists() && !serverSupportsFeature("SITE CHMOD")) { //$NON-NLS-1$
return false;
}
return true;
}
return false;
}
/*
* (non-Javadoc)
* @see com.aptana.ide.core.ftp.BaseFTPConnectionFileManager#checkConnected()
*/
@Override
protected void checkConnected() throws Exception
{ // $codepro.audit.disable declaredExceptions
if (ftpClient.connected())
{
try
{
ftpClient.noOperation();
ftpClient.setType(FTPTransferType.BINARY);
return;
}
catch (FTPConnectionClosedException e)
{
}
catch (FTPException e)
{
}
catch (IOException e)
{
}
ftpClient.quitImmediately();
}
}
/*
* (non-Javadoc)
* @see com.aptana.ide.core.ftp.BaseFTPConnectionFileManager#getRootCanonicalURI()
*/
@Override
protected URI getRootCanonicalURI()
{
try
{
return new URI(
"ftp", login, host, (port != IFTPConstants.FTP_PORT_DEFAULT) ? port : -1, Path.ROOT.toPortableString(), null, null); //$NON-NLS-1$
}
catch (URISyntaxException e)
{
return null;
}
}
/*
* (non-Javadoc)
* @see com.aptana.ide.core.ftp.BaseFTPConnectionFileManager#fetchFile(org.eclipse.core.runtime.IPath, int,
* org.eclipse.core.runtime.IProgressMonitor)
*/
@SuppressWarnings("deprecation")
@Override
protected ExtendedFileInfo fetchFile(IPath path, int options, IProgressMonitor monitor) throws CoreException,
FileNotFoundException
{
try
{
IPath dirPath = path.removeLastSegments(1);
String name = path.lastSegment();
FTPFile result = ftpFileCache.get(path);
if (result == null)
{
if ((options & IExtendedFileStore.EXISTENCE) != 0)
{
ExtendedFileInfo fileInfo = new ExtendedFileInfo(path.lastSegment());
try
{
changeCurrentDir(path);
fileInfo.setExists(true);
fileInfo.setDirectory(true);
}
catch (FileNotFoundException ignore)
{
}
if (!fileInfo.exists())
{
fileInfo.setExists(existsFile(path));
}
return fileInfo;
}
FTPFile[] ftpFiles = listFiles(dirPath, monitor);
for (FTPFile ftpFile : ftpFiles)
{
Date lastModifiedServerInLocalTZ = ftpFile.lastModified();
if (serverToLocalTimeZoneShift != 0 && lastModifiedServerInLocalTZ != null)
{
ftpFile.setLastModified(new Date(lastModifiedServerInLocalTZ.getTime()
+ serverToLocalTimeZoneShift));
}
String fileName = ftpFile.getName();
if (fileName == null || ".".equals(fileName) || "..".equals(fileName)) { //$NON-NLS-1$ //$NON-NLS-2$
if (Path.ROOT.equals(path) && ".".equals(fileName)) { //$NON-NLS-1$
ftpFile.setName(path.toPortableString());
ftpFileCache.put(path, ftpFile);
result = ftpFile;
}
continue;
}
ftpFileCache.put(dirPath.append(fileName), ftpFile);
if (name != null && name.equalsIgnoreCase(fileName))
{
result = ftpFile;
}
}
}
if ((options & IExtendedFileStore.DETAILED) != 0)
{
if (result != null && !result.isDir() && name != null && result.lastModified().getSeconds() == 0)
{
if (serverSupportsFeature("MDTM")) { //$NON-NLS-1$
changeCurrentDir(dirPath);
Policy.checkCanceled(monitor);
try
{
Date lastModifiedLocalTZ = ftpClient.modtime(name);
if (lastModifiedLocalTZ != null)
{
result.setLastModified(lastModifiedLocalTZ);
}
}
catch (FTPException e)
{
}
}
}
}
if (result == null && Path.ROOT.equals(path))
{
result = new FTPFile("", path.toPortableString(), 0, true, new Date(0)); //$NON-NLS-1$
}
if (result != null)
{
return createFileInfo(result);
}
}
catch (FileNotFoundException e)
{
throw e;
}
catch (OperationCanceledException e)
{
throw e;
}
catch (Exception e)
{
throw new CoreException(new Status(Status.ERROR, FTPPlugin.PLUGIN_ID,
Messages.FTPConnectionFileManager_fetch_failed, e));
}
ExtendedFileInfo fileInfo = new ExtendedFileInfo(path.lastSegment());
fileInfo.setExists(false);
return fileInfo;
}
/*
* (non-Javadoc)
* @see com.aptana.ide.core.ftp.BaseFTPConnectionFileManager#fetchFiles(org.eclipse.core.runtime.IPath, int,
* org.eclipse.core.runtime.IProgressMonitor)
*/
@SuppressWarnings("deprecation")
@Override
protected ExtendedFileInfo[] fetchFiles(IPath path, int options, IProgressMonitor monitor) throws CoreException,
FileNotFoundException
{
monitor = Policy.subMonitorFor(monitor, 1);
try
{
FTPFile[] ftpFiles = listFiles(path, monitor);
monitor.beginTask(Messages.FTPConnectionFileManager_gethering_file_details, ftpFiles.length);
List<ExtendedFileInfo> list = new ArrayList<ExtendedFileInfo>();
for (FTPFile ftpFile : ftpFiles)
{
String fileName = ftpFile.getName();
if (fileName == null || ".".equals(fileName) || "..".equals(fileName)) { //$NON-NLS-1$ //$NON-NLS-2$
monitor.worked(1);
continue;
}
Date lastModifiedServerInLocalTZ = ftpFile.lastModified();
if (serverToLocalTimeZoneShift != 0 && lastModifiedServerInLocalTZ != null)
{
ftpFile.setLastModified(new Date(lastModifiedServerInLocalTZ.getTime() + serverToLocalTimeZoneShift));
}
if ((options & IExtendedFileStore.DETAILED) != 0)
{
if (!ftpFile.isDir() && ftpFile.lastModified().getSeconds() == 0)
{
if (serverSupportsFeature("MDTM")) { //$NON-NLS-1$
changeCurrentDir(path);
Policy.checkCanceled(monitor);
try
{
Date lastModifiedLocalTZ = ftpClient.modtime(fileName);
if (lastModifiedLocalTZ != null)
{
ftpFile.setLastModified(lastModifiedLocalTZ);
}
}
catch (FTPException e)
{
}
}
}
}
IPath filePath = path.append(fileName);
ftpFileCache.put(filePath, ftpFile);
ExtendedFileInfo fileInfo = createFileInfo(ftpFile);
list.add(fileInfo);
monitor.worked(1);
}
return list.toArray(new ExtendedFileInfo[list.size()]);
}
catch (FileNotFoundException e)
{
throw e;
}
catch (OperationCanceledException e)
{
throw e;
}
catch (Exception e)
{
throw new CoreException(new Status(Status.ERROR, FTPPlugin.PLUGIN_ID,
Messages.FTPConnectionFileManager_fetching_directory_failed, e));
}
finally
{
monitor.done();
}
}
/*
* (non-Javadoc)
* @see com.aptana.ide.core.ftp.BaseFTPConnectionFileManager#listDirectory(org.eclipse.core.runtime.IPath,
* org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
protected String[] listDirectory(IPath path, IProgressMonitor monitor) throws CoreException, FileNotFoundException
{
try
{
FTPFile[] ftpFiles = listFiles(path, monitor);
List<String> list = new ArrayList<String>();
for (FTPFile ftpFile : ftpFiles)
{
String name = ftpFile.getName();
if (name == null || ".".equals(name) || "..".equals(name)) { //$NON-NLS-1$ //$NON-NLS-2$
continue;
}
ftpFileCache.put(path.append(name), ftpFile);
list.add(name);
}
return list.toArray(new String[list.size()]);
}
catch (FileNotFoundException e)
{
throw e;
}
catch (OperationCanceledException e)
{
throw e;
}
catch (Exception e)
{
throw new CoreException(new Status(Status.ERROR, FTPPlugin.PLUGIN_ID,
Messages.FTPConnectionFileManager_listing_directory_failed, e));
}
finally
{
monitor.done();
}
}
/*
* (non-Javadoc)
* @see com.aptana.ide.core.ftp.BaseFTPConnectionFileManager#readFile(org.eclipse.core.runtime.IPath,
* org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
protected InputStream readFile(IPath path, IProgressMonitor monitor) throws CoreException, FileNotFoundException
{
monitor.beginTask(Messages.FTPConnectionFileManager_initiating_download, 4);
FTPClient downloadFtpClient = (FTPClient) pool.checkOut();
try
{
initAndAuthFTPClient(downloadFtpClient, monitor);
Policy.checkCanceled(monitor);
setMessageLogger(downloadFtpClient, messageLogWriter);
downloadFtpClient.setType(IFTPConstants.TRANSFER_TYPE_ASCII.equals(transferType) ? FTPTransferType.ASCII
: FTPTransferType.BINARY);
try
{
downloadFtpClient.chdir(path.removeLastSegments(1).toPortableString());
}
catch (FTPException e)
{
throwFileNotFound(e, path.removeLastSegments(1));
}
monitor.worked(1);
Policy.checkCanceled(monitor);
try
{
return new FTPFileDownloadInputStream(pool, downloadFtpClient, new FTPInputStream(downloadFtpClient,
path.lastSegment()));
}
catch (FTPException e)
{
throwFileNotFound(e, path);
return null;
}
}
catch (Exception e)
{
setMessageLogger(downloadFtpClient, null);
pool.checkIn(downloadFtpClient);
if (e instanceof OperationCanceledException)
{
throw (OperationCanceledException) e;
}
else if (e instanceof FileNotFoundException)
{
throw (FileNotFoundException) e;
}
throw new CoreException(new Status(Status.ERROR, FTPPlugin.PLUGIN_ID,
Messages.FTPConnectionFileManager_opening_file_read_failed, e));
}
finally
{
monitor.done();
}
}
/*
* (non-Javadoc)
* @see com.aptana.filesystem.ftp.internal.BaseFTPConnectionFileManager#writeFile(org.eclipse.core.runtime.IPath,
* boolean, long, org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
protected OutputStream writeFile(final IPath path, boolean useTemporary, long permissions, IProgressMonitor monitor)
throws CoreException, FileNotFoundException
{
monitor.beginTask(Messages.FTPConnectionFileManager_initiating_file_upload, 4);
FTPClient uploadFtpClient = (FTPClient) pool.checkOut();
try
{
initAndAuthFTPClient(uploadFtpClient, monitor);
Policy.checkCanceled(monitor);
setMessageLogger(uploadFtpClient, messageLogWriter);
uploadFtpClient.setType(IFTPConstants.TRANSFER_TYPE_ASCII.equals(transferType) ? FTPTransferType.ASCII
: FTPTransferType.BINARY);
IPath dirPath = path.removeLastSegments(1);
try
{
uploadFtpClient.chdir(dirPath.toPortableString());
}
catch (FTPException e)
{
throwFileNotFound(e, dirPath);
}
monitor.worked(1);
Policy.checkCanceled(monitor);
return new FTPFileUploadOutputStream(pool, uploadFtpClient, new FTPOutputStream(uploadFtpClient,
useTemporary ? generateTempFileName(path.lastSegment()) : path.lastSegment()),
useTemporary ? path.lastSegment() : null, null, permissions, new Runnable()
{
public void run()
{
clearCacheAbsolute(path);
}
});
}
catch (Exception e)
{
setMessageLogger(uploadFtpClient, null);
pool.checkIn(uploadFtpClient);
if (e instanceof OperationCanceledException)
{
throw (OperationCanceledException) e;
}
else if (e instanceof FileNotFoundException)
{
throw (FileNotFoundException) e;
}
else if (e instanceof FTPException)
{
if (((FTPException) e).getReplyCode() == 553)
{
throw initFileNotFoundException(path, e);
}
}
throw new CoreException(new Status(Status.ERROR, FTPPlugin.PLUGIN_ID,
Messages.FTPConnectionFileManager_opening_file_write_failed, e));
}
finally
{
monitor.done();
}
}
/*
* (non-Javadoc)
* @see com.aptana.ide.core.ftp.BaseFTPConnectionFileManager#deleteDirectory(org.eclipse.core.runtime.IPath,
* org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
protected void deleteDirectory(IPath path, IProgressMonitor monitor) throws CoreException, FileNotFoundException
{
MultiStatus status = new MultiStatus(FTPPlugin.PLUGIN_ID, 0, null, null);
try
{
IPath dirPath = path.removeLastSegments(1);
changeCurrentDir(dirPath);
Policy.checkCanceled(monitor);
recursiveDeleteTree(path, monitor, status);
changeCurrentDir(dirPath);
ftpClient.rmdir(path.lastSegment());
}
catch (FileNotFoundException e)
{
throw e;
}
catch (OperationCanceledException e)
{
throw e;
}
catch (Exception e)
{
if (!status.isOK())
{
MultiStatus multiStatus = new MultiStatus(FTPPlugin.PLUGIN_ID, 0,
Messages.FTPConnectionFileManager_deleting_directory_failed, e);
multiStatus.addAll(status);
}
else
{
throw new CoreException(new Status(Status.ERROR, FTPPlugin.PLUGIN_ID,
Messages.FTPConnectionFileManager_deleting_directory_failed, e));
}
}
finally
{
monitor.done();
}
}
/*
* (non-Javadoc)
* @see com.aptana.ide.core.ftp.BaseFTPConnectionFileManager#deleteFile(org.eclipse.core.runtime.IPath,
* org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
protected void deleteFile(IPath path, IProgressMonitor monitor) throws CoreException, FileNotFoundException
{
try
{
IPath dirPath = path.removeLastSegments(1);
changeCurrentDir(dirPath);
Policy.checkCanceled(monitor);
try
{
ftpClient.delete(path.lastSegment());
}
catch (FTPException e)
{
if (e.getReplyCode() == 532)
{
throw new PermissionDeniedException(path.toPortableString(), e);
}
throw e;
}
}
catch (FileNotFoundException e)
{
throw e;
}
catch (OperationCanceledException e)
{
throw e;
}
catch (Exception e)
{
throw new CoreException(new Status(Status.ERROR, FTPPlugin.PLUGIN_ID, MessageFormat.format(
Messages.FTPConnectionFileManager_deleting_failed, path), e));
}
finally
{
monitor.done();
}
}
/*
* (non-Javadoc)
* @see com.aptana.filesystem.ftp.internal.BaseFTPConnectionFileManager#createFile(org.eclipse.core.runtime.IPath,
* org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
protected void createFile(IPath path, IProgressMonitor monitor) throws CoreException, FileNotFoundException,
PermissionDeniedException
{
try
{
IPath dirPath = path.removeLastSegments(1);
changeCurrentDir(dirPath);
Policy.checkCanceled(monitor);
try
{
ftpClient.put(new ByteArrayInputStream(new byte[] {}), path.lastSegment());
}
catch (FTPException e)
{
if (e.getReplyCode() == 532)
{
throw new PermissionDeniedException(path.toPortableString(), e);
}
throw e;
}
}
catch (FileNotFoundException e)
{
throw e;
}
catch (OperationCanceledException e)
{
throw e;
}
catch (Exception e)
{
throw new CoreException(new Status(Status.ERROR, FTPPlugin.PLUGIN_ID, MessageFormat.format(
Messages.FTPConnectionFileManager_CreateFile0Failed, path), e));
}
finally
{
monitor.done();
}
}
/*
* (non-Javadoc)
* @see com.aptana.ide.core.ftp.BaseFTPConnectionFileManager#createDirectory(org.eclipse.core.runtime.IPath,
* org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
protected void createDirectory(IPath path, IProgressMonitor monitor) throws CoreException, FileNotFoundException
{
try
{
try
{
try
{
changeCurrentDir(path);
return; // directory exists - return
}
catch (FileNotFoundException ignore)
{
}
ftpClient.mkdir(path.toPortableString());
if (PreferenceUtils.getUpdatePermissions(PermissionDirection.UPLOAD)
&& PreferenceUtils.getSpecificPermissions(PermissionDirection.UPLOAD))
{
changeFilePermissions(path, PreferenceUtils.getFolderPermissions(PermissionDirection.UPLOAD),
monitor);
}
}
catch (FTPException e)
{
throwFileNotFound(e, path);
}
}
catch (FileNotFoundException e)
{
throw e;
}
catch (Exception e)
{
throw new CoreException(new Status(Status.ERROR, FTPPlugin.PLUGIN_ID,
Messages.FTPConnectionFileManager_creating_directory_failed, e));
}
}
/*
* (non-Javadoc)
* @see com.aptana.ide.core.ftp.BaseFTPConnectionFileManager#renameFile(org.eclipse.core.runtime.IPath,
* org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
protected void renameFile(IPath sourcePath, IPath destinationPath, IProgressMonitor monitor) throws CoreException,
FileNotFoundException
{
try
{
changeCurrentDir(sourcePath.removeLastSegments(1));
Policy.checkCanceled(monitor);
try
{
ftpClient.rename(sourcePath.toPortableString(), destinationPath.toPortableString());
}
catch (FTPException e)
{
throwFileNotFound(e, sourcePath);
throw e;
}
}
catch (FileNotFoundException e)
{
throw e;
}
catch (OperationCanceledException e)
{
throw e;
}
catch (Exception e)
{
throw new CoreException(new Status(Status.ERROR, FTPPlugin.PLUGIN_ID,
Messages.FTPConnectionFileManager_renaming_failed, e));
}
finally
{
monitor.done();
}
}
/*
* (non-Javadoc)
* @see com.aptana.core.io.vfs.BaseConnectionFileManager#renameDirectory(org.eclipse.core.runtime.IPath,
* org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
protected void renameDirectory(IPath sourcePath, IPath destinationPath, IProgressMonitor monitor)
throws CoreException, FileNotFoundException
{
renameFile(sourcePath, destinationPath, monitor);
}
/*
* (non-Javadoc)
* @see com.aptana.ide.core.ftp.BaseFTPConnectionFileManager#setModificationTime(org.eclipse.core.runtime.IPath,
* long, org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
protected void setModificationTime(IPath path, long modificationTime, IProgressMonitor monitor)
throws CoreException, FileNotFoundException
{
if (!serverSupportsFeature("MFMT") && !serverSupportsFeature("SITE UTIME")) { //$NON-NLS-1$ //$NON-NLS-2$
return;
}
try
{
IPath dirPath = path.removeLastSegments(1);
changeCurrentDir(dirPath);
Policy.checkCanceled(monitor);
if (serverSupportsFeature("MFMT")) { //$NON-NLS-1$
ftpClient.setModTime(path.lastSegment(), new Date(modificationTime));
}
else if (serverSupportsFeature("SITE UTIME")) { //$NON-NLS-1$
Calendar cal = Calendar.getInstance();
long localTimezoneShift = cal.get(Calendar.ZONE_OFFSET) + cal.get(Calendar.DST_OFFSET);
Date date = new Date(modificationTime - localTimezoneShift);
if (utimeFormat == -1)
{
for (utimeFormat = 0; utimeFormat < UTIME_FORMATS.length; ++utimeFormat)
{
String format = UTIME_FORMATS[utimeFormat].format(date);
FTPReply reply = ftpClient
.sendCommand("SITE " + MessageFormat.format(format, path.lastSegment())); //$NON-NLS-1$
if (!"500".equals(reply.getReplyCode()) && !"501".equals(reply.getReplyCode())) { //$NON-NLS-1$ //$NON-NLS-2$
break;
}
}
}
else if (utimeFormat >= 0 && utimeFormat < UTIME_FORMATS.length)
{
String format = UTIME_FORMATS[utimeFormat].format(date);
ftpClient.site(MessageFormat.format(format, path.lastSegment()));
}
}
}
catch (FileNotFoundException e)
{
throw e;
}
catch (OperationCanceledException e)
{
throw e;
}
catch (Exception e)
{
throw new CoreException(new Status(Status.ERROR, FTPPlugin.PLUGIN_ID,
Messages.FTPConnectionFileManager_set_modification_time_failed, e));
}
finally
{
monitor.done();
}
}
/*
* (non-Javadoc)
* @see com.aptana.ide.core.ftp.BaseFTPConnectionFileManager#changeFilePermissions(org.eclipse.core.runtime.IPath,
* long, org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
protected void changeFilePermissions(IPath path, long permissions, IProgressMonitor monitor) throws CoreException,
FileNotFoundException
{
if (!serverSupportsFeature("SITE CHMOD")) { //$NON-NLS-1$
return;
}
try
{
IPath dirPath = path.removeLastSegments(1);
changeCurrentDir(dirPath);
Policy.checkCanceled(monitor);
ftpClient.site(MessageFormat.format("CHMOD {0} {1}", Long.toOctalString(permissions), path.lastSegment())); //$NON-NLS-1$
}
catch (FileNotFoundException e)
{
throw e;
}
catch (OperationCanceledException e)
{
throw e;
}
catch (Exception e)
{
throw new CoreException(new Status(Status.ERROR, FTPPlugin.PLUGIN_ID,
Messages.FTPConnectionFileManager_FailedSetPermissions, e));
}
finally
{
monitor.done();
}
}
/*
* (non-Javadoc)
* @see com.aptana.ide.core.ftp.BaseFTPConnectionFileManager#changeFileGroup(org.eclipse.core.runtime.IPath,
* java.lang.String, org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
protected void changeFileGroup(IPath path, String group, IProgressMonitor monitor) throws CoreException,
FileNotFoundException
{
if (!serverSupportsFeature("SITE CHGRP")) { //$NON-NLS-1$
return;
}
try
{
IPath dirPath = path.removeLastSegments(1);
changeCurrentDir(dirPath);
Policy.checkCanceled(monitor);
ftpClient.site(MessageFormat.format("CHGRP {0} {1}", group, path.lastSegment())); //$NON-NLS-1$
}
catch (FileNotFoundException e)
{
throw e;
}
catch (OperationCanceledException e)
{
throw e;
}
catch (Exception e)
{
throw new CoreException(new Status(Status.ERROR, FTPPlugin.PLUGIN_ID,
Messages.FTPConnectionFileManager_FailedSetGroup, e));
}
finally
{
monitor.done();
}
}
private boolean existsFile(IPath filePath) throws IOException, FTPException
{
return ftpClient.existsFile(filePath.toPortableString());
}
private FTPFile[] ftpSTAT(String dirname) throws IOException, FTPException, ParseException
{
setupFileFactory();
String[] validCodes = { "211", "212", "213" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
FTPReply reply = ftpClient.sendCommand("STAT " + dirname); //$NON-NLS-1$
ftpClient.validateReply(reply, validCodes);
String[] data = reply.getReplyData();
if (data == null)
{
return null;
}
for (int i = 0; i < data.length; ++i)
{
data[i] = data[i].trim();
}
FTPFile[] ftpFiles = fileFactory.parse(data);
for (FTPFile ftpFile : ftpFiles)
{
String name = ftpFile.getName();
if (name != null && name.indexOf('/') != -1)
{
ftpFile.setName(Path.fromPortableString(name).lastSegment());
}
}
return ftpFiles;
}
private FTPFile[] ftpLIST(IPath dirPath, IProgressMonitor monitor) throws IOException, ParseException, FTPException
{
setupFileFactory();
changeCurrentDir(dirPath);
Policy.checkCanceled(monitor);
if (!Boolean.FALSE.equals(listASupported))
{
try
{
FTPFile[] ftpFiles = fileFactory.parse(ftpClient.dir("-a", true)); //$NON-NLS-1$
listASupported = Boolean.TRUE;
return ftpFiles;
}
catch (FTPException e)
{
if (listASupported == null && e.getReplyCode() >= 500)
{
listASupported = Boolean.FALSE;
}
else
{
throw e;
}
}
}
return fileFactory.parse(ftpClient.dir(".", true)); //$NON-NLS-1$
}
private void setupFileFactory() throws IOException, FTPException
{
if (fileFactory == null)
{
try
{
fileFactory = new FTPFileFactory(ftpClient.system());
}
catch (FTPException ex)
{
fileFactory = new FTPFileFactory("UNIX"); //$NON-NLS-1$
}
fileFactory.setLocales(FTPClient.DEFAULT_LISTING_LOCALES);
}
}
private FTPFile[] listFiles(IPath dirPath, IProgressMonitor monitor) throws IOException, ParseException,
FTPException
{
FTPFile[] ftpFiles = null;
if (!Boolean.FALSE.equals(statSupported) && dirPath.toPortableString().indexOf(' ') == -1)
{
try
{
ftpFiles = ftpSTAT(dirPath.addTrailingSeparator().toPortableString());
}
catch (MalformedReplyException e)
{
statSupported = Boolean.FALSE;
}
catch (FTPException e)
{
if (e.getReplyCode() == 501 || e.getReplyCode() == 502 || e.getReplyCode() == 504)
{
statSupported = null;
}
else if (Boolean.TRUE.equals(statSupported) && e.getReplyCode() != 500 && e.getReplyCode() != 550)
{
throwFileNotFound(e, dirPath);
}
}
if (ftpFiles == null || ftpFiles.length == 0)
{
if (statSupported == null)
{
statSupported = Boolean.FALSE;
}
return ftpLIST(dirPath, monitor);
}
else if (ftpFiles[0].isLink())
{
return ftpLIST(dirPath, monitor);
}
else if (statSupported == null)
{
statSupported = Boolean.TRUE;
}
}
else
{
ftpFiles = ftpLIST(dirPath, monitor);
}
if (fileFactory.getSystem().toUpperCase().startsWith(WINDOWS_STR) && ftpFiles != null)
{
for (FTPFile ftpFile : ftpFiles)
{
if (ftpFile.getPermissions() == null)
{
ftpFile.setPermissions("-rw-r-----"); //$NON-NLS-1$
}
}
}
return ftpFiles;
}
private void recursiveDeleteTree(IPath path, IProgressMonitor monitor, MultiStatus status) throws IOException,
ParseException
{
try
{
changeCurrentDir(path);
FTPFile[] ftpFiles = listFiles(path, monitor);
List<String> dirs = new ArrayList<String>();
for (FTPFile ftpFile : ftpFiles)
{
String name = ftpFile.getName();
if (name == null || ".".equals(name) || "..".equals(name)) { //$NON-NLS-1$ //$NON-NLS-2$
continue;
}
if (ftpFile.isDir())
{
dirs.add(name);
continue;
}
Policy.checkCanceled(monitor);
monitor.subTask(path.append(name).toPortableString());
try
{
ftpClient.delete(name);
}
catch (FTPException e)
{
status.add(new Status(IStatus.ERROR, FTPPlugin.PLUGIN_ID, MessageFormat.format(
Messages.FTPConnectionFileManager_deleting_failed, path.append(name).toPortableString()), e));
}
monitor.worked(1);
}
for (String name : dirs)
{
monitor.subTask(path.append(name).toPortableString());
recursiveDeleteTree(path.append(name), monitor, status);
Policy.checkCanceled(monitor);
changeCurrentDir(path);
Policy.checkCanceled(monitor);
ftpClient.rmdir(name);
monitor.worked(1);
}
}
catch (IOException e)
{
throw e;
}
catch (Exception e)
{
status.add(new Status(IStatus.ERROR, FTPPlugin.PLUGIN_ID, MessageFormat.format(
Messages.FTPConnectionFileManager_deleting_failed, path.toPortableString()), e));
}
}
private static String generateTempFileName(String base)
{
StringBuffer sb = new StringBuffer();
sb.append(base).append(TMP_UPLOAD_SUFFIX);
String ext = Path.fromPortableString(base).getFileExtension();
if (ext != null)
{
sb.append(ext);
}
return sb.toString();
}
public FTPClient newClient()
{
return new ProFTPClient();
}
}