View | Details | Raw Unified | Return to bug 198638
Collapse All | Expand All

(-)src/org/eclipse/rse/internal/services/files/ftp/FTPService.java (-69 / +114 lines)
Lines 53-58 Link Here
53
 * Javier Montalvo Orus (Symbian) - [198182] FTP export problem: RSEF8057E: Error occurred while exporting FILENAME: Operation failed. File system input or output error
53
 * Javier Montalvo Orus (Symbian) - [198182] FTP export problem: RSEF8057E: Error occurred while exporting FILENAME: Operation failed. File system input or output error
54
 * Javier Montalvo Orus (Symbian) - [192610] EFS operations on an FTP connection make Eclipse freeze
54
 * Javier Montalvo Orus (Symbian) - [192610] EFS operations on an FTP connection make Eclipse freeze
55
 * Javier Montalvo Orus (Symbian) - [195830] RSE performs unnecessary remote list commands
55
 * Javier Montalvo Orus (Symbian) - [195830] RSE performs unnecessary remote list commands
56
 * Martin Oberhuber (Wind River) - [198638] Fix invalid caching
57
 * Martin Oberhuber (Wind River) - [198645] Fix case sensitivity issues
56
 ********************************************************************************/
58
 ********************************************************************************/
57
59
58
package org.eclipse.rse.internal.services.files.ftp;
60
package org.eclipse.rse.internal.services.files.ftp;
Lines 68-75 Link Here
68
import java.io.OutputStream;
70
import java.io.OutputStream;
69
import java.text.MessageFormat;
71
import java.text.MessageFormat;
70
import java.util.ArrayList;
72
import java.util.ArrayList;
71
import java.util.Hashtable;
73
import java.util.HashMap;
72
import java.util.List;
74
import java.util.List;
75
import java.util.Map;
73
76
74
import org.apache.commons.net.ftp.FTP;
77
import org.apache.commons.net.ftp.FTP;
75
import org.apache.commons.net.ftp.FTPClient;
78
import org.apache.commons.net.ftp.FTPClient;
Lines 121-127 Link Here
121
	//to avoid accessing the remote target when not necessary (bug 195830)
124
	//to avoid accessing the remote target when not necessary (bug 195830)
122
	//In the future, it would be better that the IHostFile object were passed from
125
	//In the future, it would be better that the IHostFile object were passed from
123
	//the upper layer instead of the folder and file name.
126
	//the upper layer instead of the folder and file name.
124
	private Hashtable fileMap = new Hashtable();
127
	//See bug 162950.
128
	private String _fCachePreviousParent;
129
	private long _fCachePreviousTimestamp;
130
	private Map _fCachePreviousFiles = new HashMap();
131
	private static long FTP_STATCACHE_TIMEOUT = 500; //msec
132
	
125
	
133
	
126
	private class FTPBufferedInputStream extends BufferedInputStream {
134
	private class FTPBufferedInputStream extends BufferedInputStream {
127
		
135
		
Lines 355-360 Link Here
355
	
363
	
356
	public void disconnect()
364
	public void disconnect()
357
	{
365
	{
366
		synchronized (_fCachePreviousFiles) {
367
			_fCachePreviousFiles.clear();
368
		}
358
		try
369
		try
359
		{
370
		{
360
			getFTPClient().logout();
371
			getFTPClient().logout();
Lines 401-409 Link Here
401
	
412
	
402
	/*
413
	/*
403
	 * (non-Javadoc)
414
	 * (non-Javadoc)
404
	 * @see org.eclipse.rse.services.files.IFileService#getFile(org.eclipse.core.runtime.IProgressMonitor, java.lang.String, java.lang.String)
415
	 * @see org.eclipse.rse.services.files.IFileService#getFile(String, String, IProgressMonitor)
416
	 */
417
	public IHostFile getFile(String remoteParent, String fileName, IProgressMonitor monitor) throws SystemMessageException
418
	{
419
		return getFileInternal(remoteParent, fileName, monitor);
420
	}
421
422
	
423
	/**
424
	 * Return FTPHostFile object for a given parent dir and file name.
425
	 * @see org.eclipse.rse.services.files.IFileService#getFile(String, String, IProgressMonitor)
405
	 */
426
	 */
406
	public IHostFile getFile(String remoteParent, String fileName, IProgressMonitor monitor) throws SystemMessageException 
427
	protected FTPHostFile getFileInternal(String remoteParent, String fileName, IProgressMonitor monitor) throws SystemMessageException
407
	{
428
	{
408
		if (monitor!=null){
429
		if (monitor!=null){
409
			if (monitor.isCanceled()) {
430
			if (monitor.isCanceled()) {
Lines 411-418 Link Here
411
			}	
432
			}	
412
		}
433
		}
413
		
434
		
414
		FTPHostFile file = null;
435
		//Try the cache first, perhaps there is no need to acquire the Mutex
436
		//The cache is case sensitive only on purpose. For case insensitive matches
437
		//A fresh LIST is required.
438
		//
439
	    //In the future, it would be better that the
440
	    //IHostFile object were passed from the upper layer instead of the
441
	    //folder and file name (Bug 162950)
442
		synchronized(_fCachePreviousFiles) {
443
			if (_fCachePreviousParent == null ? remoteParent==null : _fCachePreviousParent.equals(remoteParent)) {
444
				Object result = _fCachePreviousFiles.get(fileName);
445
				if (result!=null) {
446
					long diff = System.currentTimeMillis() - _fCachePreviousTimestamp;
447
					//System.out.println("FTPCache: "+diff+", "+remoteParent+", "+fileName); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
448
					if (diff < FTP_STATCACHE_TIMEOUT) {
449
						return (FTPHostFile)result;
450
					}
451
				}
452
			}
453
		}
415
		
454
		
455
		FTPHostFile file = null;
416
		if(_commandMutex.waitForLock(monitor, Long.MAX_VALUE))
456
		if(_commandMutex.waitForLock(monitor, Long.MAX_VALUE))
417
		{
457
		{
418
		
458
		
Lines 431-445 Link Here
431
					throw new RemoteFileCancelledException();
471
					throw new RemoteFileCancelledException();
432
				}
472
				}
433
				
473
				
434
				for (int i = 0; i < _ftpFiles.length; i++) 
474
				synchronized(_fCachePreviousFiles) {
435
				{
475
					cacheFiles(remoteParent);
436
					FTPHostFile tempFile = new FTPHostFile(remoteParent,_ftpFiles[i]);
476
437
					
477
					//Bug 198645: try exact match first
438
					if(tempFile.getName().equalsIgnoreCase(fileName))
478
					Object o = _fCachePreviousFiles.get(fileName);
439
					{
479
					if (o!=null) return (FTPHostFile)o;
440
						file = tempFile;
480
441
						break;
481
					//try case insensitive match (usually never executed)
482
					if (!isCaseSensitive()) {
483
						for (int i = 0; i < _ftpFiles.length; i++) {
484
							String tempName = _ftpFiles[i].getName();
485
							if(tempName.equalsIgnoreCase(fileName)) {
486
								file = (FTPHostFile)_fCachePreviousFiles.get(tempName);
487
								break;
488
							}
489
						}
442
					}
490
					}
491
443
				}
492
				}
444
				
493
				
445
				// if not found, create new object with non-existing flag
494
				// if not found, create new object with non-existing flag
Lines 511-559 Link Here
511
					throw new RemoteFileCancelledException();
560
					throw new RemoteFileCancelledException();
512
				}
561
				}
513
				
562
				
514
				for(int i=0; i<_ftpFiles.length; i++)
563
				synchronized (_fCachePreviousFiles) {
515
				{
564
					cacheFiles(parentPath);
516
					if(_ftpFiles[i]==null)
517
					{
518
						continue;
519
					}
520
					
521
					String rawListLine = _ftpFiles[i].getRawListing()+System.getProperty("line.separator"); //$NON-NLS-1$
522
					_ftpLoggingOutputStream.write(rawListLine.getBytes());
523
					
565
					
524
					FTPHostFile f = new FTPHostFile(parentPath, _ftpFiles[i]);
566
					for(int i=0; i<_ftpFiles.length; i++)
525
					String name = f.getName();
567
					{
526
					
568
						if(_ftpFiles[i]==null)
527
					if(f.isLink()) {
569
						{
528
						if(name.indexOf('.')==-1) {
570
							continue;
529
							//modify FTPHostFile to be shown as a folder
530
							f.setIsDirectory(true);
531
						}
571
						}
532
					}
533
					
534
					if (isRightType(fileType,f)) {
535
						
572
						
536
						if (name.equals(".") || name.equals("..")) { //$NON-NLS-1$ //$NON-NLS-2$
573
						String rawListLine = _ftpFiles[i].getRawListing()+System.getProperty("line.separator"); //$NON-NLS-1$
537
							//Never return the default directory names
574
						_ftpLoggingOutputStream.write(rawListLine.getBytes());
538
							continue;
575
						
539
						} else if (f.isDirectory() && fileType!=FILE_TYPE_FOLDERS) {
576
						String name = _ftpFiles[i].getName();
540
							//get ALL directory names (unless looking for folders only)
577
						FTPHostFile f = (FTPHostFile)_fCachePreviousFiles.get(name);
541
							results.add(f);
578
						
542
						} else if (filematcher.matches(name)) { 
579
						if (isRightType(fileType,f)) {
543
							//filter all others by name.
580
							
544
							results.add(f);
581
							if (name.equals(".") || name.equals("..")) { //$NON-NLS-1$ //$NON-NLS-2$
582
								//Never return the default directory names
583
								continue;
584
							} else if (f.isDirectory() && fileType!=FILE_TYPE_FOLDERS) {
585
								//get ALL directory names (unless looking for folders only)
586
								results.add(f);
587
							} else if (filematcher.matches(name)) { 
588
								//filter all others by name.
589
								results.add(f);
590
							}
545
						}
591
						}
546
					}
592
					}
547
				}
593
				}
548
				
549
				_ftpLoggingOutputStream.write(System.getProperty("line.separator").getBytes()); //$NON-NLS-1$
594
				_ftpLoggingOutputStream.write(System.getProperty("line.separator").getBytes()); //$NON-NLS-1$
550
				
551
				for (int i = 0; i < results.size(); i++) {
552
					FTPHostFile file = (FTPHostFile)results.get(i);
553
					fileMap.put(file.getAbsolutePath(), file);
554
				}
555
				
556
				
557
			}
595
			}
558
			catch (Exception e)
596
			catch (Exception e)
559
			{			
597
			{			
Lines 709-720 Link Here
709
			}	
747
			}	
710
		}
748
		}
711
		
749
		
712
		IHostFile remoteHostFile = (IHostFile)fileMap.get(remoteParent+getSeparator()+remoteFile);
750
		IHostFile remoteHostFile = getFile(remoteParent, remoteFile, monitor);
713
		
714
		if(remoteHostFile == null)
715
		{
716
			remoteHostFile = getFile(remoteParent,remoteFile,null);
717
		}
718
		
751
		
719
		if(_commandMutex.waitForLock(monitor, Long.MAX_VALUE))
752
		if(_commandMutex.waitForLock(monitor, Long.MAX_VALUE))
720
		{
753
		{
Lines 832-843 Link Here
832
		
865
		
833
		progressMonitor.init(FTPServiceResources.FTP_File_Service_Deleting_Task+fileName, 1);  
866
		progressMonitor.init(FTPServiceResources.FTP_File_Service_Deleting_Task+fileName, 1);  
834
		
867
		
835
		IHostFile file = (IHostFile)fileMap.get(remoteParent+getSeparator()+fileName);
868
		IHostFile file = getFile(remoteParent, fileName, monitor);
836
		
837
		if(file == null)
838
		{
839
			file = getFile(remoteParent,fileName,null);
840
		}	
841
			
869
			
842
		boolean isFile = file.isFile();
870
		boolean isFile = file.isFile();
843
		
871
		
Lines 1041-1046 Link Here
1041
1069
1042
	public boolean isCaseSensitive()
1070
	public boolean isCaseSensitive()
1043
	{
1071
	{
1072
		//TODO find out whether remote is case sensitive or not
1044
		return true;
1073
		return true;
1045
	}
1074
	}
1046
	
1075
	
Lines 1113-1122 Link Here
1113
			}
1142
			}
1114
				
1143
				
1115
		}
1144
		}
1116
		
1145
1117
		return result;
1146
		return result;
1118
	}
1147
	}
1119
	
1148
	
1149
	private void cacheFiles(String parentPath) {
1150
		synchronized (_fCachePreviousFiles) {
1151
			_fCachePreviousFiles.clear();
1152
			_fCachePreviousTimestamp = System.currentTimeMillis();
1153
			_fCachePreviousParent = parentPath;
1154
			
1155
			for(int i=0; i<_ftpFiles.length; i++) {
1156
				if(_ftpFiles[i]==null) {
1157
					continue;
1158
				}
1159
				FTPHostFile f = new FTPHostFile(parentPath, _ftpFiles[i]);
1160
				String name = f.getName();
1161
				if(f.isLink()) {
1162
					if(name.indexOf('.') < 0) {
1163
						//modify FTPHostFile to be shown as a folder
1164
						f.setIsDirectory(true);
1165
					}
1166
				}
1167
				_fCachePreviousFiles.put(name, f);
1168
			}
1169
		}
1170
	}
1120
	
1171
	
1121
	private class MyProgressMonitor
1172
	private class MyProgressMonitor
1122
	{
1173
	{
Lines 1187-1204 Link Here
1187
		boolean result = false;
1238
		boolean result = false;
1188
		int permissions = 0;
1239
		int permissions = 0;
1189
		
1240
		
1190
		FTPHostFile file = (FTPHostFile)fileMap.get(parent+getSeparator()+name);
1241
		FTPHostFile file = getFileInternal(parent,name, monitor);
1191
		
1192
		if(file == null)
1193
		{
1194
			file =(FTPHostFile)getFile(parent,name, monitor);
1195
		}
1196
		
1242
		
1197
		int userPermissions = file.getUserPermissions();
1243
		int userPermissions = file.getUserPermissions();
1198
		int groupPermissions = file.getGroupPermissions();
1244
		int groupPermissions = file.getGroupPermissions();
1199
		int otherPermissions = file.getOtherPermissions();
1245
		int otherPermissions = file.getOtherPermissions();
1200
		
1246
		
1201
		
1202
		if(readOnly)
1247
		if(readOnly)
1203
		{
1248
		{
1204
			userPermissions &= 5; // & 101b
1249
			userPermissions &= 5; // & 101b

Return to bug 198638