mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-06 07:45:50 +02:00
[198638][198645] Fix FTP caching and case sensitivity issues
This commit is contained in:
parent
2922a61fd1
commit
89d501fd49
1 changed files with 115 additions and 70 deletions
|
@ -53,6 +53,8 @@
|
||||||
* Javier Montalvo Orus (Symbian) - [198182] FTP export problem: RSEF8057E: Error occurred while exporting FILENAME: Operation failed. File system input or output error
|
* Javier Montalvo Orus (Symbian) - [198182] FTP export problem: RSEF8057E: Error occurred while exporting FILENAME: Operation failed. File system input or output error
|
||||||
* Javier Montalvo Orus (Symbian) - [192610] EFS operations on an FTP connection make Eclipse freeze
|
* Javier Montalvo Orus (Symbian) - [192610] EFS operations on an FTP connection make Eclipse freeze
|
||||||
* Javier Montalvo Orus (Symbian) - [195830] RSE performs unnecessary remote list commands
|
* Javier Montalvo Orus (Symbian) - [195830] RSE performs unnecessary remote list commands
|
||||||
|
* Martin Oberhuber (Wind River) - [198638] Fix invalid caching
|
||||||
|
* Martin Oberhuber (Wind River) - [198645] Fix case sensitivity issues
|
||||||
********************************************************************************/
|
********************************************************************************/
|
||||||
|
|
||||||
package org.eclipse.rse.internal.services.files.ftp;
|
package org.eclipse.rse.internal.services.files.ftp;
|
||||||
|
@ -68,8 +70,9 @@ import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Hashtable;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.apache.commons.net.ftp.FTP;
|
import org.apache.commons.net.ftp.FTP;
|
||||||
import org.apache.commons.net.ftp.FTPClient;
|
import org.apache.commons.net.ftp.FTPClient;
|
||||||
|
@ -121,7 +124,12 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
|
||||||
//to avoid accessing the remote target when not necessary (bug 195830)
|
//to avoid accessing the remote target when not necessary (bug 195830)
|
||||||
//In the future, it would be better that the IHostFile object were passed from
|
//In the future, it would be better that the IHostFile object were passed from
|
||||||
//the upper layer instead of the folder and file name.
|
//the upper layer instead of the folder and file name.
|
||||||
private Hashtable fileMap = new Hashtable();
|
//See bug 162950.
|
||||||
|
private String _fCachePreviousParent;
|
||||||
|
private long _fCachePreviousTimestamp;
|
||||||
|
private Map _fCachePreviousFiles = new HashMap();
|
||||||
|
private static long FTP_STATCACHE_TIMEOUT = 500; //msec
|
||||||
|
|
||||||
|
|
||||||
private class FTPBufferedInputStream extends BufferedInputStream {
|
private class FTPBufferedInputStream extends BufferedInputStream {
|
||||||
|
|
||||||
|
@ -355,6 +363,9 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
|
||||||
|
|
||||||
public void disconnect()
|
public void disconnect()
|
||||||
{
|
{
|
||||||
|
synchronized (_fCachePreviousFiles) {
|
||||||
|
_fCachePreviousFiles.clear();
|
||||||
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
getFTPClient().logout();
|
getFTPClient().logout();
|
||||||
|
@ -401,9 +412,19 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
* @see org.eclipse.rse.services.files.IFileService#getFile(org.eclipse.core.runtime.IProgressMonitor, java.lang.String, java.lang.String)
|
* @see org.eclipse.rse.services.files.IFileService#getFile(String, String, IProgressMonitor)
|
||||||
*/
|
*/
|
||||||
public IHostFile getFile(String remoteParent, String fileName, IProgressMonitor monitor) throws SystemMessageException
|
public IHostFile getFile(String remoteParent, String fileName, IProgressMonitor monitor) throws SystemMessageException
|
||||||
|
{
|
||||||
|
return getFileInternal(remoteParent, fileName, monitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return FTPHostFile object for a given parent dir and file name.
|
||||||
|
* @see org.eclipse.rse.services.files.IFileService#getFile(String, String, IProgressMonitor)
|
||||||
|
*/
|
||||||
|
protected FTPHostFile getFileInternal(String remoteParent, String fileName, IProgressMonitor monitor) throws SystemMessageException
|
||||||
{
|
{
|
||||||
if (monitor!=null){
|
if (monitor!=null){
|
||||||
if (monitor.isCanceled()) {
|
if (monitor.isCanceled()) {
|
||||||
|
@ -411,8 +432,27 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FTPHostFile file = null;
|
//Try the cache first, perhaps there is no need to acquire the Mutex
|
||||||
|
//The cache is case sensitive only on purpose. For case insensitive matches
|
||||||
|
//A fresh LIST is required.
|
||||||
|
//
|
||||||
|
//In the future, it would be better that the
|
||||||
|
//IHostFile object were passed from the upper layer instead of the
|
||||||
|
//folder and file name (Bug 162950)
|
||||||
|
synchronized(_fCachePreviousFiles) {
|
||||||
|
if (_fCachePreviousParent == null ? remoteParent==null : _fCachePreviousParent.equals(remoteParent)) {
|
||||||
|
Object result = _fCachePreviousFiles.get(fileName);
|
||||||
|
if (result!=null) {
|
||||||
|
long diff = System.currentTimeMillis() - _fCachePreviousTimestamp;
|
||||||
|
//System.out.println("FTPCache: "+diff+", "+remoteParent+", "+fileName); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||||
|
if (diff < FTP_STATCACHE_TIMEOUT) {
|
||||||
|
return (FTPHostFile)result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FTPHostFile file = null;
|
||||||
if(_commandMutex.waitForLock(monitor, Long.MAX_VALUE))
|
if(_commandMutex.waitForLock(monitor, Long.MAX_VALUE))
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -431,15 +471,24 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
|
||||||
throw new RemoteFileCancelledException();
|
throw new RemoteFileCancelledException();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < _ftpFiles.length; i++)
|
synchronized(_fCachePreviousFiles) {
|
||||||
{
|
cacheFiles(remoteParent);
|
||||||
FTPHostFile tempFile = new FTPHostFile(remoteParent,_ftpFiles[i]);
|
|
||||||
|
//Bug 198645: try exact match first
|
||||||
if(tempFile.getName().equalsIgnoreCase(fileName))
|
Object o = _fCachePreviousFiles.get(fileName);
|
||||||
{
|
if (o!=null) return (FTPHostFile)o;
|
||||||
file = tempFile;
|
|
||||||
break;
|
//try case insensitive match (usually never executed)
|
||||||
|
if (!isCaseSensitive()) {
|
||||||
|
for (int i = 0; i < _ftpFiles.length; i++) {
|
||||||
|
String tempName = _ftpFiles[i].getName();
|
||||||
|
if(tempName.equalsIgnoreCase(fileName)) {
|
||||||
|
file = (FTPHostFile)_fCachePreviousFiles.get(tempName);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if not found, create new object with non-existing flag
|
// if not found, create new object with non-existing flag
|
||||||
|
@ -511,49 +560,38 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
|
||||||
throw new RemoteFileCancelledException();
|
throw new RemoteFileCancelledException();
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i=0; i<_ftpFiles.length; i++)
|
synchronized (_fCachePreviousFiles) {
|
||||||
{
|
cacheFiles(parentPath);
|
||||||
if(_ftpFiles[i]==null)
|
|
||||||
|
for(int i=0; i<_ftpFiles.length; i++)
|
||||||
{
|
{
|
||||||
continue;
|
if(_ftpFiles[i]==null)
|
||||||
}
|
{
|
||||||
|
|
||||||
String rawListLine = _ftpFiles[i].getRawListing()+System.getProperty("line.separator"); //$NON-NLS-1$
|
|
||||||
_ftpLoggingOutputStream.write(rawListLine.getBytes());
|
|
||||||
|
|
||||||
FTPHostFile f = new FTPHostFile(parentPath, _ftpFiles[i]);
|
|
||||||
String name = f.getName();
|
|
||||||
|
|
||||||
if(f.isLink()) {
|
|
||||||
if(name.indexOf('.')==-1) {
|
|
||||||
//modify FTPHostFile to be shown as a folder
|
|
||||||
f.setIsDirectory(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isRightType(fileType,f)) {
|
|
||||||
|
|
||||||
if (name.equals(".") || name.equals("..")) { //$NON-NLS-1$ //$NON-NLS-2$
|
|
||||||
//Never return the default directory names
|
|
||||||
continue;
|
continue;
|
||||||
} else if (f.isDirectory() && fileType!=FILE_TYPE_FOLDERS) {
|
}
|
||||||
//get ALL directory names (unless looking for folders only)
|
|
||||||
results.add(f);
|
String rawListLine = _ftpFiles[i].getRawListing()+System.getProperty("line.separator"); //$NON-NLS-1$
|
||||||
} else if (filematcher.matches(name)) {
|
_ftpLoggingOutputStream.write(rawListLine.getBytes());
|
||||||
//filter all others by name.
|
|
||||||
results.add(f);
|
String name = _ftpFiles[i].getName();
|
||||||
|
FTPHostFile f = (FTPHostFile)_fCachePreviousFiles.get(name);
|
||||||
|
|
||||||
|
if (isRightType(fileType,f)) {
|
||||||
|
|
||||||
|
if (name.equals(".") || name.equals("..")) { //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
//Never return the default directory names
|
||||||
|
continue;
|
||||||
|
} else if (f.isDirectory() && fileType!=FILE_TYPE_FOLDERS) {
|
||||||
|
//get ALL directory names (unless looking for folders only)
|
||||||
|
results.add(f);
|
||||||
|
} else if (filematcher.matches(name)) {
|
||||||
|
//filter all others by name.
|
||||||
|
results.add(f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_ftpLoggingOutputStream.write(System.getProperty("line.separator").getBytes()); //$NON-NLS-1$
|
_ftpLoggingOutputStream.write(System.getProperty("line.separator").getBytes()); //$NON-NLS-1$
|
||||||
|
|
||||||
for (int i = 0; i < results.size(); i++) {
|
|
||||||
FTPHostFile file = (FTPHostFile)results.get(i);
|
|
||||||
fileMap.put(file.getAbsolutePath(), file);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@ -709,12 +747,7 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IHostFile remoteHostFile = (IHostFile)fileMap.get(remoteParent+getSeparator()+remoteFile);
|
IHostFile remoteHostFile = getFile(remoteParent, remoteFile, monitor);
|
||||||
|
|
||||||
if(remoteHostFile == null)
|
|
||||||
{
|
|
||||||
remoteHostFile = getFile(remoteParent,remoteFile,null);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(_commandMutex.waitForLock(monitor, Long.MAX_VALUE))
|
if(_commandMutex.waitForLock(monitor, Long.MAX_VALUE))
|
||||||
{
|
{
|
||||||
|
@ -832,12 +865,7 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
|
||||||
|
|
||||||
progressMonitor.init(FTPServiceResources.FTP_File_Service_Deleting_Task+fileName, 1);
|
progressMonitor.init(FTPServiceResources.FTP_File_Service_Deleting_Task+fileName, 1);
|
||||||
|
|
||||||
IHostFile file = (IHostFile)fileMap.get(remoteParent+getSeparator()+fileName);
|
IHostFile file = getFile(remoteParent, fileName, monitor);
|
||||||
|
|
||||||
if(file == null)
|
|
||||||
{
|
|
||||||
file = getFile(remoteParent,fileName,null);
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean isFile = file.isFile();
|
boolean isFile = file.isFile();
|
||||||
|
|
||||||
|
@ -1041,6 +1069,7 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
|
||||||
|
|
||||||
public boolean isCaseSensitive()
|
public boolean isCaseSensitive()
|
||||||
{
|
{
|
||||||
|
//TODO find out whether remote is case sensitive or not
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1113,10 +1142,32 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void cacheFiles(String parentPath) {
|
||||||
|
synchronized (_fCachePreviousFiles) {
|
||||||
|
_fCachePreviousFiles.clear();
|
||||||
|
_fCachePreviousTimestamp = System.currentTimeMillis();
|
||||||
|
_fCachePreviousParent = parentPath;
|
||||||
|
|
||||||
|
for(int i=0; i<_ftpFiles.length; i++) {
|
||||||
|
if(_ftpFiles[i]==null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
FTPHostFile f = new FTPHostFile(parentPath, _ftpFiles[i]);
|
||||||
|
String name = f.getName();
|
||||||
|
if(f.isLink()) {
|
||||||
|
if(name.indexOf('.') < 0) {
|
||||||
|
//modify FTPHostFile to be shown as a folder
|
||||||
|
f.setIsDirectory(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_fCachePreviousFiles.put(name, f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class MyProgressMonitor
|
private class MyProgressMonitor
|
||||||
{
|
{
|
||||||
|
@ -1187,18 +1238,12 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
|
||||||
boolean result = false;
|
boolean result = false;
|
||||||
int permissions = 0;
|
int permissions = 0;
|
||||||
|
|
||||||
FTPHostFile file = (FTPHostFile)fileMap.get(parent+getSeparator()+name);
|
FTPHostFile file = getFileInternal(parent,name, monitor);
|
||||||
|
|
||||||
if(file == null)
|
|
||||||
{
|
|
||||||
file =(FTPHostFile)getFile(parent,name, monitor);
|
|
||||||
}
|
|
||||||
|
|
||||||
int userPermissions = file.getUserPermissions();
|
int userPermissions = file.getUserPermissions();
|
||||||
int groupPermissions = file.getGroupPermissions();
|
int groupPermissions = file.getGroupPermissions();
|
||||||
int otherPermissions = file.getOtherPermissions();
|
int otherPermissions = file.getOtherPermissions();
|
||||||
|
|
||||||
|
|
||||||
if(readOnly)
|
if(readOnly)
|
||||||
{
|
{
|
||||||
userPermissions &= 5; // & 101b
|
userPermissions &= 5; // & 101b
|
||||||
|
|
Loading…
Add table
Reference in a new issue