diff --git a/rse/plugins/org.eclipse.rse.services.files.ftp/META-INF/MANIFEST.MF b/rse/plugins/org.eclipse.rse.services.files.ftp/META-INF/MANIFEST.MF
index aa8f8990a1f..85b3162b3d2 100644
--- a/rse/plugins/org.eclipse.rse.services.files.ftp/META-INF/MANIFEST.MF
+++ b/rse/plugins/org.eclipse.rse.services.files.ftp/META-INF/MANIFEST.MF
@@ -1,7 +1,7 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
-Bundle-SymbolicName: org.eclipse.rse.services.files.ftp
+Bundle-SymbolicName: org.eclipse.rse.services.files.ftp;singleton:=true
Bundle-Version: 2.0.0.qualifier
Bundle-Activator: org.eclipse.rse.internal.services.files.ftp.Activator
Bundle-Vendor: %providerName
@@ -9,7 +9,9 @@ Bundle-Localization: plugin
Require-Bundle: org.eclipse.core.runtime,
org.eclipse.rse.services,
org.apache.commons.net,
- org.eclipse.rse.core
+ org.eclipse.rse.core,
+ org.eclipse.core.resources
Eclipse-LazyStart: true
-Export-Package: org.eclipse.rse.internal.services.files.ftp;x-friends:="org.eclipse.rse.subsystems.files.ftp"
+Export-Package: org.eclipse.rse.internal.services.files.ftp;x-friends:="org.eclipse.rse.subsystems.files.ftp",
+ org.eclipse.rse.internal.services.files.ftp.parser;x-friends:="org.eclipse.rse.subsystems.files.ftp"
Bundle-RequiredExecutionEnvironment: J2SE-1.4
diff --git a/rse/plugins/org.eclipse.rse.services.files.ftp/plugin.xml b/rse/plugins/org.eclipse.rse.services.files.ftp/plugin.xml
new file mode 100644
index 00000000000..a34a1a69b91
--- /dev/null
+++ b/rse/plugins/org.eclipse.rse.services.files.ftp/plugin.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/rse/plugins/org.eclipse.rse.services.files.ftp/schema/ftpFileEntryParser.exsd b/rse/plugins/org.eclipse.rse.services.files.ftp/schema/ftpFileEntryParser.exsd
new file mode 100644
index 00000000000..6cca44b1f52
--- /dev/null
+++ b/rse/plugins/org.eclipse.rse.services.files.ftp/schema/ftpFileEntryParser.exsd
@@ -0,0 +1,189 @@
+
+
+
+
+
+
+
+
+ Extension point that allows providing extra parsers for the FTP LIST command output.
+Apache commons net provides some APIs and factories to costumize the parser and this extension
+provides an easy way to setup a custom parser and integrate it into RSE.
+The provided extension points will be available as a list in the property "FTP Settings",
+allowing the user to select them overriding the default parser.
+The string attributes <code>defaultDateFormatStr</code> <code>recentDateFormatStr</code>
+ <code>serverLanguageCode</code> <code>serverTimeZoneId</code> <code>shortMonthNames</code> have to
+ follow the format described by <code>org.apache.commons.net.ftp.FTPClientConfig</code>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name that will be displayed in the UI
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ RSE 2.0
+
+
+
+
+
+
+
+
+ <!-- Default UNIX parser provided by Apache commons net package -->
+<parser
+ class="org.apache.commons.net.ftp.parser.UnixFTPEntryParser"
+ name="UNIX">
+</parser>
+
+<!-- Custom parser implementing org.apache.commons.net.ftp.Configurable and org.apache.commons.net.ftp.FTPFileEntryParser -->
+<parser
+ class="com.mycompany.MyParser"
+ name="MyParser">
+</parser>
+
+<!-- UNIX server that uses Danish month names and "European" date formatting in Denmark's time zone -->
+<parser
+ class="org.apache.commons.net.ftp.parser.UnixFTPEntryParser"
+ name="UNIX_Danish"
+ defaultDateFormatStr = "d MMM yyyy"
+ recentDateFormatStr = "d MMM HH:mm"
+ serverLanguageCode = "da"
+ serverTimeZoneId = "Europe/Copenhagen"
+ >
+</parser>
+
+<!-- VMS server that uses month names in a language not supported but uses the standard date formatting -->
+<parser
+ class="org.apache.commons.net.ftp.parser.VMSFTPEntryParser"
+ name="VMS_custom"
+ shortMonthNames="jan|feb|mar|apr|ma\u00ED|j\u00FAn|j\u00FAl|\u00e1g\u00FA|sep|okt|n\u00F3v|des"
+ >
+</parser>
+
+
+
+
+
+
+
+
+ The provider of a new FTPEntryParser must implement <samp>org.apache.commons.net.ftp.Configurable</samp> and <samp>org.apache.commons.net.ftp.FTPFileEntryParser</samp>
+
+
+
+
+
+
+
+
+ Customized VMS and WinNT implementations are supplied in the <code>org.eclipse.rse.services.files.ftp</code> plug-in.
+
+
+
+
+
+
+
+
+ Copyright (c) 2007 Symbian Software Ltd. All rights reserved.
+This program and the accompanying materials are made available under the terms
+of the Eclipse Public License v1.0 which accompanies this distribution, and is
+available at http://www.eclipse.org/legal/epl-v10.html
+
+Contributors:
+ Javier Montalvo Orus (Symbian) - initial API and implementation
+
+
+
+
diff --git a/rse/plugins/org.eclipse.rse.services.files.ftp/src/org/eclipse/rse/internal/services/files/ftp/FTPHostFile.java b/rse/plugins/org.eclipse.rse.services.files.ftp/src/org/eclipse/rse/internal/services/files/ftp/FTPHostFile.java
index 6d03607b453..30746a06f54 100644
--- a/rse/plugins/org.eclipse.rse.services.files.ftp/src/org/eclipse/rse/internal/services/files/ftp/FTPHostFile.java
+++ b/rse/plugins/org.eclipse.rse.services.files.ftp/src/org/eclipse/rse/internal/services/files/ftp/FTPHostFile.java
@@ -15,7 +15,8 @@
* Javier Montalvo OrĂºs (Symbian) - Migrate to jakarta commons net FTP client
* Javier Montalvo Orus (Symbian) - Fixing 161211 - Cannot expand /pub folder as
* anonymous on ftp.wacom.com
- * Javier Montalvo Orus (Symbian) - Fixing 161238 - [ftp] connections to VMS servers are not usable
+ * Javier Montalvo Orus (Symbian) - Fixing 161238 - [ftp] connections to VMS servers are not usable
+ * Javier Montalvo Orus (Symbian) - Fixing 176216 - [api] FTP sould provide API to allow clients register their own FTPListingParser
********************************************************************************/
package org.eclipse.rse.internal.services.files.ftp;
@@ -23,7 +24,6 @@ package org.eclipse.rse.internal.services.files.ftp;
import java.io.File;
-import org.apache.commons.net.ftp.FTPClientConfig;
import org.apache.commons.net.ftp.FTPFile;
import org.eclipse.rse.services.clientserver.archiveutils.ArchiveHandlerManager;
import org.eclipse.rse.services.files.IHostFile;
@@ -56,46 +56,27 @@ public class FTPHostFile implements IHostFile
_isRoot = isRoot;
_exists = exists;
}
-
- public FTPHostFile(String parentPath, FTPFile ftpFile, String systemName)
+
+ public FTPHostFile(String parentPath, FTPFile ftpFile)
{
_parentPath = parentPath;
_ftpFile = ftpFile;
- if(systemName.equals(FTPClientConfig.SYST_VMS))
- {
- _name = ftpFile.getName();
- if(_name.indexOf(".DIR")!=-1) //$NON-NLS-1$
- {
- _name = _name.substring(0,_name.indexOf(".DIR")); //$NON-NLS-1$
- }
- else
- {
- _name = _name.substring(0,_name.indexOf(";")); //$NON-NLS-1$
- }
- }
- else
- {
- _name = ftpFile.getName();
- }
+ _name = ftpFile.getName();
_isDirectory = ftpFile.isDirectory();
_lastModified = ftpFile.getTimestamp().getTimeInMillis();
_size = ftpFile.getSize();
_isArchive = internalIsArchive();
- //In Windows r/w is not listed
- //In VMS it is not implemented in the Jakarta parser
- if(!systemName.equals(FTPClientConfig.SYST_NT) && !systemName.equals(FTPClientConfig.SYST_VMS))
- {
- _canRead = ftpFile.hasPermission(FTPFile.USER_ACCESS, FTPFile.READ_PERMISSION);
- _canWrite = ftpFile.hasPermission(FTPFile.USER_ACCESS, FTPFile.WRITE_PERMISSION);
- }
+ _canRead = ftpFile.hasPermission(FTPFile.USER_ACCESS, FTPFile.READ_PERMISSION);
+ _canWrite = ftpFile.hasPermission(FTPFile.USER_ACCESS, FTPFile.WRITE_PERMISSION);
_isRoot = false;
_exists = true;
}
+
public long getSize()
{
return _size;
@@ -188,30 +169,58 @@ public class FTPHostFile implements IHostFile
public int getUserPermissions()
{
+ int userRead = 0;
+ int userWrite = 0;
+ int userExec = 0;
+
//user
- int userRead = _ftpFile.hasPermission(FTPFile.USER_ACCESS, FTPFile.READ_PERMISSION) || _canRead ? 1 : 0;
- int userWrite = _ftpFile.hasPermission(FTPFile.USER_ACCESS, FTPFile.WRITE_PERMISSION) || _canWrite ? 1 : 0;
- int userExec = _ftpFile.hasPermission(FTPFile.USER_ACCESS, FTPFile.EXECUTE_PERMISSION) ? 1 : 0;
+ if(_ftpFile!=null)
+ {
+ userRead = _ftpFile.hasPermission(FTPFile.USER_ACCESS, FTPFile.READ_PERMISSION) ? 1 : 0;
+ userWrite = _ftpFile.hasPermission(FTPFile.USER_ACCESS, FTPFile.WRITE_PERMISSION) ? 1 : 0;
+ userExec = _ftpFile.hasPermission(FTPFile.USER_ACCESS, FTPFile.EXECUTE_PERMISSION) ? 1 : 0;
+ }
+ else
+ {
+ userRead = _canRead ? 1 : 0;
+ userWrite = _canWrite ? 1 : 0;
+ userExec = 0;
+
+ }
return userRead << 2 | userWrite << 1 | userExec;
}
public int getGroupPermissions()
{
+ int groupRead = 0;
+ int groupWrite = 0;
+ int groupExec = 0;
+
//group
- int groupRead = _ftpFile.hasPermission(FTPFile.GROUP_ACCESS, FTPFile.READ_PERMISSION) ? 1 : 0;
- int groupWrite = _ftpFile.hasPermission(FTPFile.GROUP_ACCESS, FTPFile.WRITE_PERMISSION) ? 1 : 0;
- int groupExec = _ftpFile.hasPermission(FTPFile.GROUP_ACCESS, FTPFile.EXECUTE_PERMISSION) ? 1 : 0;
+ if(_ftpFile!=null)
+ {
+ groupRead = _ftpFile.hasPermission(FTPFile.GROUP_ACCESS, FTPFile.READ_PERMISSION) ? 1 : 0;
+ groupWrite = _ftpFile.hasPermission(FTPFile.GROUP_ACCESS, FTPFile.WRITE_PERMISSION) ? 1 : 0;
+ groupExec = _ftpFile.hasPermission(FTPFile.GROUP_ACCESS, FTPFile.EXECUTE_PERMISSION) ? 1 : 0;
+ }
return groupRead << 2 | groupWrite << 1 | groupExec;
}
public int getOtherPermissions()
{
+ int otherRead = 0;
+ int otherWrite = 0;
+ int otherExec = 0;
+
//other
- int otherRead = _ftpFile.hasPermission(FTPFile.WORLD_ACCESS, FTPFile.READ_PERMISSION) ? 1 : 0;
- int otherWrite = _ftpFile.hasPermission(FTPFile.WORLD_ACCESS, FTPFile.WRITE_PERMISSION) ? 1 : 0;
- int otherExec = _ftpFile.hasPermission(FTPFile.WORLD_ACCESS, FTPFile.EXECUTE_PERMISSION) ? 1 : 0;
+ if(_ftpFile!=null)
+ {
+ otherRead = _ftpFile.hasPermission(FTPFile.WORLD_ACCESS, FTPFile.READ_PERMISSION) ? 1 : 0;
+ otherWrite = _ftpFile.hasPermission(FTPFile.WORLD_ACCESS, FTPFile.WRITE_PERMISSION) ? 1 : 0;
+ otherExec = _ftpFile.hasPermission(FTPFile.WORLD_ACCESS, FTPFile.EXECUTE_PERMISSION) ? 1 : 0;
+ }
return otherRead << 2 | otherWrite << 1 | otherExec;
}
diff --git a/rse/plugins/org.eclipse.rse.services.files.ftp/src/org/eclipse/rse/internal/services/files/ftp/FTPService.java b/rse/plugins/org.eclipse.rse.services.files.ftp/src/org/eclipse/rse/internal/services/files/ftp/FTPService.java
index b60771cda8b..b128435468c 100644
--- a/rse/plugins/org.eclipse.rse.services.files.ftp/src/org/eclipse/rse/internal/services/files/ftp/FTPService.java
+++ b/rse/plugins/org.eclipse.rse.services.files.ftp/src/org/eclipse/rse/internal/services/files/ftp/FTPService.java
@@ -37,6 +37,7 @@
* Javier Montalvo Orus (Symbian) - Fixing 168120 - [ftp] root filter resolves to home dir
* Javier Montalvo Orus (Symbian) - Fixing 169680 - [ftp] FTP files subsystem and service should use passive mode
* Javier Montalvo Orus (Symbian) - Fixing 174828 - [ftp] Folders are attempted to be removed as files
+ * Javier Montalvo Orus (Symbian) - Fixing 176216 - [api] FTP sould provide API to allow clients register their own FTPListingParser
********************************************************************************/
package org.eclipse.rse.internal.services.files.ftp;
@@ -52,8 +53,6 @@ import java.io.OutputStream;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
@@ -63,6 +62,7 @@ import org.apache.commons.net.ftp.FTPReply;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.rse.core.model.IPropertySet;
+import org.eclipse.rse.internal.services.files.ftp.parser.FTPClientConfigFactory;
import org.eclipse.rse.services.Mutex;
import org.eclipse.rse.services.clientserver.FileTypeMatcher;
import org.eclipse.rse.services.clientserver.IMatcher;
@@ -80,9 +80,9 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
private FTPClient _ftpClient;
private FTPFile[] _ftpFiles;
- private Mutex _downloadMutex = new Mutex();
+ private Mutex _commandMutex = new Mutex();
- private String _systemName;
+ private String _parser;
private String _userHome;
private transient String _hostName;
private transient String _userId;
@@ -93,6 +93,9 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
private IPropertySet _ftpPropertySet;
private Exception _exception;
+ private boolean _isBinaryFileType = true;
+ private boolean _isPassiveDataConnectionMode = false;
+
private class FTPBufferedInputStream extends BufferedInputStream {
private FTPClient client;
@@ -224,10 +227,10 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
public void connect() throws Exception
{
+
if (_ftpClient == null)
{
_ftpClient = new FTPClient();
-
}
if(_ftpLoggingOutputStream!=null)
@@ -274,75 +277,85 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
throw new Exception(lastMessage);
}
- //SYSTEM PARSER
+ //System parser
- FTPClientConfig ftpClientConfig;
+ _parser = _ftpPropertySet.getPropertyValue("parser"); //$NON-NLS-1$
- _systemName = _ftpClient.getSystemName().toUpperCase();
- if(_systemName.indexOf(' ')!=-1)
+ if(!_parser.equalsIgnoreCase("AUTO")) //$NON-NLS-1$
{
- _systemName = _systemName.substring(0,_systemName.indexOf(' '));
+ _ftpClient.setParserFactory(FTPClientConfigFactory.getParserFactory());
+ _ftpClient.configure(FTPClientConfigFactory.getParserFactory().getFTPClientConfig(_parser));
+ }
+ else
+ {
+ //try to guess
+
+ String systemName = _ftpClient.getSystemName().toUpperCase();
+ if(systemName.indexOf(' ')!=-1)
+ {
+ systemName = systemName.substring(0,systemName.indexOf(' '));
+ }
+
+ //FTPClientConfig.SYST_NT = "WINDOWS"
+ if(systemName.startsWith(FTPClientConfig.SYST_NT))
+ {
+ _ftpClient.setParserFactory(FTPClientConfigFactory.getParserFactory());
+ _ftpClient.configure(FTPClientConfigFactory.getParserFactory().getFTPClientConfig("WinNT")); //$NON-NLS-1$
+ }else
+ //FTPClientConfig.SYST_MVS = "MVS"
+ if(systemName.startsWith(FTPClientConfig.SYST_MVS))
+ {
+ _ftpClient.configure(new FTPClientConfig(FTPClientConfig.SYST_MVS));
+ }else
+ //FTPClientConfig.SYST_OS2 = "OS/2"
+ if(systemName.startsWith(FTPClientConfig.SYST_OS2))
+ {
+ _ftpClient.configure(new FTPClientConfig(FTPClientConfig.SYST_OS2));
+ }else
+ //FTPClientConfig.SYST_OS400 = "OS/400"
+ if(systemName.startsWith(FTPClientConfig.SYST_OS400))
+ {
+ _ftpClient.configure(new FTPClientConfig(FTPClientConfig.SYST_OS400));
+ }else
+ //FTPClientConfig.SYST_VMS = "VMS"
+ if(systemName.startsWith(FTPClientConfig.SYST_VMS))
+ {
+ _ftpClient.setParserFactory(FTPClientConfigFactory.getParserFactory());
+ _ftpClient.configure(FTPClientConfigFactory.getParserFactory().getFTPClientConfig("VMS_improved")); //$NON-NLS-1$
+ }else
+ //Default UNIX-like parsing
+ //FTPClientConfig.SYST_UNIX = "UNIX"
+ {
+ _ftpClient.configure(new FTPClientConfig(FTPClientConfig.SYST_UNIX));
+ }
+ }
+
+ // Initial active/passive mode. This action will be refreshed later using setDataConnectionMode()
+
+ if(_ftpPropertySet.getPropertyValue("passive").equalsIgnoreCase("true")) //$NON-NLS-1$ //$NON-NLS-2$
+ {
+ _ftpClient.enterLocalPassiveMode();
+ _isPassiveDataConnectionMode = true;
+ }
+ else
+ {
+ _ftpClient.enterLocalActiveMode();
+ _isPassiveDataConnectionMode = false;
}
- //FTPClientConfig.SYST_NT = "WINDOWS"
- if(_systemName.startsWith(FTPClientConfig.SYST_NT))
- {
- _systemName = FTPClientConfig.SYST_NT;
- ftpClientConfig = new FTPClientConfig(FTPClientConfig.SYST_NT);
- }else
- //FTPClientConfig.SYST_MVS = "MVS"
- if(_systemName.startsWith(FTPClientConfig.SYST_MVS))
- {
- _systemName = FTPClientConfig.SYST_MVS;
- ftpClientConfig = new FTPClientConfig(FTPClientConfig.SYST_MVS);
- }else
- //FTPClientConfig.SYST_OS2 = "OS/2"
- if(_systemName.startsWith(FTPClientConfig.SYST_OS2))
- {
- _systemName = FTPClientConfig.SYST_OS2;
- ftpClientConfig = new FTPClientConfig(FTPClientConfig.SYST_OS2);
- }else
- //FTPClientConfig.SYST_OS400 = "OS/400"
- if(_systemName.startsWith(FTPClientConfig.SYST_OS400))
- {
- _systemName = FTPClientConfig.SYST_OS400;
- ftpClientConfig = new FTPClientConfig(FTPClientConfig.SYST_OS400);
- }else
- //FTPClientConfig.SYST_VMS = "VMS"
- if(_systemName.startsWith(FTPClientConfig.SYST_VMS))
- {
- _systemName = FTPClientConfig.SYST_VMS;
- ftpClientConfig = new FTPClientConfig(FTPClientConfig.SYST_VMS);
- }else
- //Default UNIX-like parsing
- //FTPClientConfig.SYST_UNIX = "UNIX"
- {
- _systemName = FTPClientConfig.SYST_UNIX;
- ftpClientConfig = new FTPClientConfig(FTPClientConfig.SYST_UNIX);
- }
-
- _ftpClient.configure(ftpClientConfig);
+ // Initial ASCII/Binary mode. This action will be refreshed later using setFileType()
+ _ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
+ _isBinaryFileType = true;
_userHome = _ftpClient.printWorkingDirectory();
//For VMS, normalize the home location
- if(_systemName.equals(FTPClientConfig.SYST_VMS))
+ if(_userHome.indexOf(':')!=-1)
{
_userHome = _userHome.replaceAll(":\\[", "/"); //$NON-NLS-1$ //$NON-NLS-2$
_userHome = '/'+_userHome.substring(0,_userHome.lastIndexOf(']'));
}
- if(_ftpPropertySet != null)
- {
- if(_ftpPropertySet.getPropertyValue("passive").equalsIgnoreCase("true")) //$NON-NLS-1$ //$NON-NLS-2$
- {
- _ftpClient.enterLocalPassiveMode();
- }
- else
- {
- _ftpClient.enterLocalActiveMode();
- }
- }
}
public void disconnect()
@@ -352,10 +365,11 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
getFTPClient().logout();
_ftpClient = null;
}
- catch (Exception e)
+ catch (IOException e)
{
_ftpClient = null;
}
+
}
/**
@@ -372,19 +386,6 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
if (_ftpClient == null)
{
_ftpClient = new FTPClient();
-
- }
-
- if(_ftpPropertySet != null)
- {
- if(_ftpPropertySet.getPropertyValue("passive").equalsIgnoreCase("true")) //$NON-NLS-1$ //$NON-NLS-2$
- {
- _ftpClient.enterLocalPassiveMode();
- }
- else
- {
- _ftpClient.enterLocalActiveMode();
- }
}
if(_hostName!=null)
@@ -397,7 +398,8 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
} catch (Exception e1) {}
}
}
-
+
+ setDataConnectionMode();
return _ftpClient;
}
@@ -416,43 +418,47 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
FTPHostFile file = null;
- try{
+ if(_commandMutex.waitForLock(monitor, Long.MAX_VALUE))
+ {
- //try to retrieve the file
- _ftpClient = getFTPClient();
+ try{
- remoteParent = adaptPath(remoteParent);
-
- if(!_ftpClient.changeWorkingDirectory(remoteParent))
- {
- throw new RemoteFileIOException(new Exception(_ftpClient.getReplyString()));
- }
-
- if(!listFiles(monitor))
- {
- throw new RemoteFileCancelledException();
- }
-
- for (int i = 0; i < _ftpFiles.length; i++)
- {
- FTPHostFile tempFile = new FTPHostFile(remoteParent,_ftpFiles[i],_systemName);
+ //try to retrieve the file
+ _ftpClient = getFTPClient();
- if(tempFile.getName().equalsIgnoreCase(fileName))
+ if(!_ftpClient.changeWorkingDirectory(remoteParent))
{
- file = tempFile;
- break;
+ throw new RemoteFileIOException(new Exception(_ftpClient.getReplyString()));
+ }
+
+ if(!listFiles(monitor))
+ {
+ throw new RemoteFileCancelledException();
+ }
+
+ for (int i = 0; i < _ftpFiles.length; i++)
+ {
+ FTPHostFile tempFile = new FTPHostFile(remoteParent,_ftpFiles[i]);
+
+ if(tempFile.getName().equalsIgnoreCase(fileName))
+ {
+ file = tempFile;
+ break;
+ }
+ }
+
+ // if not found, create new object with non-existing flag
+ if(file == null)
+ {
+ file = new FTPHostFile(remoteParent,fileName, false, false, 0, 0, false);
}
- }
- // if not found, create new object with non-existing flag
- if(file == null)
- {
- file = new FTPHostFile(remoteParent,fileName, false, false, 0, 0, false);
- }
-
-
- }catch (Exception e){
- throw new RemoteFileIOException(e);
+
+ }catch (Exception e){
+ throw new RemoteFileIOException(e);
+ } finally {
+ _commandMutex.release();
+ }
}
return file;
@@ -481,48 +487,54 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
}
}
-
- if (fileFilter == null)
- {
- fileFilter = "*"; //$NON-NLS-1$
- }
- IMatcher filematcher = null;
- if (fileFilter.endsWith(",")) { //$NON-NLS-1$
- String[] types = fileFilter.split(","); //$NON-NLS-1$
- filematcher = new FileTypeMatcher(types, true);
- } else {
- filematcher = new NamePatternMatcher(fileFilter, true, true);
- }
List results = new ArrayList();
- try
+ if(_commandMutex.waitForLock(monitor, Long.MAX_VALUE))
{
- _ftpClient = getFTPClient();
-
- parentPath = adaptPath(parentPath);
-
- if(!_ftpClient.changeWorkingDirectory(parentPath))
+
+ if (fileFilter == null)
{
- throw new RemoteFileIOException(new Exception(_ftpClient.getReplyString()));
+ fileFilter = "*"; //$NON-NLS-1$
+ }
+ IMatcher filematcher = null;
+ if (fileFilter.endsWith(",")) { //$NON-NLS-1$
+ String[] types = fileFilter.split(","); //$NON-NLS-1$
+ filematcher = new FileTypeMatcher(types, true);
+ } else {
+ filematcher = new NamePatternMatcher(fileFilter, true, true);
}
- if(!listFiles(monitor))
- {
- throw new RemoteFileCancelledException();
- }
- for(int i=0; i<_ftpFiles.length; i++)
+ try
{
- FTPHostFile f = new FTPHostFile(parentPath,_ftpFiles[i],_systemName);
- if((filematcher.matches(f.getName()) || f.isDirectory()) && !(f.getName().equals(".") || f.getName().equals(".."))) //$NON-NLS-1$ //$NON-NLS-2$
+ _ftpClient = getFTPClient();
+
+ if(!_ftpClient.changeWorkingDirectory(parentPath))
{
- results.add(f);
+ throw new RemoteFileIOException(new Exception(_ftpClient.getReplyString()));
+ }
+
+ if(!listFiles(monitor))
+ {
+ throw new RemoteFileCancelledException();
+ }
+
+ for(int i=0; i<_ftpFiles.length; i++)
+ {
+ FTPHostFile f = new FTPHostFile(parentPath, _ftpFiles[i]);
+
+ if((filematcher.matches(f.getName()) || f.isDirectory()) && !(f.getName().equals(".") || f.getName().equals(".."))) //$NON-NLS-1$ //$NON-NLS-2$
+ {
+ results.add(f);
+ }
}
}
- }
- catch (Exception e)
- {
- throw new RemoteFileIOException(e);
+ catch (Exception e)
+ {
+ throw new RemoteFileIOException(e);
+ } finally {
+ _commandMutex.release();
+ }
}
return (IHostFile[])results.toArray(new IHostFile[results.size()]);
@@ -533,7 +545,7 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
{
char separator = '/';
- if((_systemName.equals(FTPClientConfig.SYST_NT) || _userHome.indexOf('\\')!=-1) && _userHome.indexOf('/')==-1)
+ if(_userHome.indexOf('\\')!=-1 && _userHome.indexOf('/')==-1)
{
separator = '\\';
}
@@ -556,58 +568,59 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
}
}
- FTPClient ftpClient = getFTPClient();
-
- MyProgressMonitor progressMonitor = new MyProgressMonitor(monitor);
-
- try
+ if(_commandMutex.waitForLock(monitor, Long.MAX_VALUE))
{
+
+ FTPClient ftpClient = getFTPClient();
- remoteParent = adaptPath(remoteParent);
+ MyProgressMonitor progressMonitor = new MyProgressMonitor(monitor);
- ftpClient.changeWorkingDirectory(remoteParent);
-
- if (isBinary)
- ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
- else
- ftpClient.setFileType(FTP.ASCII_FILE_TYPE);
-
- FileInputStream input = new FileInputStream(localFile);
- OutputStream output = ftpClient.storeFileStream(remoteFile);
-
- progressMonitor.init(0, localFile.getName(), remoteFile, localFile.length());
- long bytes=0;
- byte[] buffer = new byte[4096];
-
- int readCount;
- while((readCount = input.read(buffer)) > 0)
+ try
{
- bytes+=readCount;
- output.write(buffer, 0, readCount);
- progressMonitor.count(readCount);
- if (monitor!=null){
- if (monitor.isCanceled()) {
- retValue = false;
- break;
- }
+
+ ftpClient.changeWorkingDirectory(remoteParent);
+
+ setFileType(isBinary);
+
+ FileInputStream input = new FileInputStream(localFile);
+ OutputStream output = ftpClient.storeFileStream(remoteFile);
+
+ progressMonitor.init(0, localFile.getName(), remoteFile, localFile.length());
+ long bytes=0;
+ byte[] buffer = new byte[4096];
+
+ int readCount;
+ while((readCount = input.read(buffer)) > 0)
+ {
+ bytes+=readCount;
+ output.write(buffer, 0, readCount);
+ progressMonitor.count(readCount);
+ if (monitor!=null){
+ if (monitor.isCanceled()) {
+ retValue = false;
+ break;
+ }
+ }
}
+
+ input.close();
+ output.flush();
+ output.close();
+
+ ftpClient.completePendingCommand();
+
+ if(retValue==false) {
+ ftpClient.deleteFile(remoteFile);
+ }
+
+ progressMonitor.end();
}
-
- input.close();
- output.flush();
- output.close();
-
- ftpClient.completePendingCommand();
-
- if(retValue==false) {
- ftpClient.deleteFile(remoteFile);
- }
-
- progressMonitor.end();
- }
- catch (Exception e)
- {
- throw new RemoteFileIOException(e);
+ catch (Exception e)
+ {
+ throw new RemoteFileIOException(e);
+ } finally {
+ _commandMutex.release();
+ }
}
return retValue;
@@ -623,6 +636,7 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
try
{
+
BufferedInputStream bis = new BufferedInputStream(stream);
File tempFile = File.createTempFile("ftpup", "temp"); //$NON-NLS-1$ //$NON-NLS-2$
FileOutputStream os = new FileOutputStream(tempFile);
@@ -643,16 +657,18 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
bos.close();
if(retValue == true){
- retValue = upload(monitor, tempFile, remoteParent, remoteFile, isBinary, "", hostEncoding); //$NON-NLS-1$
+ setFileType(isBinary);
+ retValue = upload(monitor, tempFile, remoteParent, remoteFile, isBinary, "", hostEncoding); //$NON-NLS-1$
}
}
catch (Exception e) {
throw new RemoteFileIOException(e);
- }
- return retValue;
+ }
+
+ return retValue;
- }
+ }
/*
* (non-Javadoc)
@@ -660,7 +676,7 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
*/
public boolean download(IProgressMonitor monitor, String remoteParent, String remoteFile, File localFile, boolean isBinary, String hostEncoding) throws SystemMessageException
{
- boolean retValue = false;
+ boolean retValue = true;
if (monitor!=null){
if (monitor.isCanceled()) {
@@ -668,21 +684,22 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
}
}
- if(_downloadMutex.waitForLock(monitor, Long.MAX_VALUE))
+ IHostFile remoteHostFile = getFile(null,remoteParent,remoteFile);
+
+ FTPClient ftpClient = getFTPClient();
+
+ if(_commandMutex.waitForLock(monitor, Long.MAX_VALUE))
{
+ MyProgressMonitor progressMonitor = new MyProgressMonitor(monitor);
+ //IHostFile remoteHostFile = null;
+ OutputStream output = null;
+ InputStream input = null;
+
try
{
- MyProgressMonitor progressMonitor = new MyProgressMonitor(monitor);
- IHostFile remoteHostFile = getFile(null,remoteParent,remoteFile);
- FTPClient ftpClient = getFTPClient();
-
- remoteParent = adaptPath(remoteParent);
ftpClient.changeWorkingDirectory(remoteParent);
- if (isBinary)
- ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
- else
- ftpClient.setFileType(FTP.ASCII_FILE_TYPE);
+ setFileType(isBinary);
if (!localFile.exists())
{
@@ -694,40 +711,55 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
localFile.createNewFile();
}
- OutputStream output = new FileOutputStream(localFile);
- InputStream input = ftpClient.retrieveFileStream(remoteFile);
+ output = new FileOutputStream(localFile);
+ input = ftpClient.retrieveFileStream(remoteFile);
- progressMonitor.init(0, remoteFile, localFile.getName(), remoteHostFile.getSize());
-
- byte[] buffer = new byte[4096];
-
- int readCount;
- while((readCount = input.read(buffer)) > 0)
- {
- output.write(buffer, 0, readCount);
- progressMonitor.count(readCount);
- if (monitor!=null){
- if (monitor.isCanceled()) {
- retValue = false;
- break;
- }
- }
- }
-
- progressMonitor.end();
-
- output.flush();
- input.close();
- output.close();
-
- ftpClient.completePendingCommand();
}
catch (Exception e)
{
throw new RemoteFileIOException(e);
- } finally {
- _downloadMutex.release();
- }
+ }
+
+
+ if(remoteHostFile != null && input != null)
+ {
+ progressMonitor.init(0, remoteFile, localFile.getName(), remoteHostFile.getSize());
+
+ byte[] buffer = new byte[4096];
+
+ int readCount;
+
+ try{
+
+ while((readCount = input.read(buffer)) > 0)
+ {
+ output.write(buffer, 0, readCount);
+ progressMonitor.count(readCount);
+ if (monitor!=null){
+ if (monitor.isCanceled()) {
+ retValue = false;
+ break;
+ }
+ }
+ }
+
+ progressMonitor.end();
+
+ output.flush();
+ input.close();
+ output.close();
+
+ ftpClient.completePendingCommand();
+
+ }catch(IOException e)
+ {
+ e.printStackTrace();
+ }
+ finally {
+ _commandMutex.release();
+ }
+ }
+
}
return retValue;
}
@@ -890,9 +922,6 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
try
{
-
- remoteParent = adaptPath(remoteParent);
-
if(!ftpClient.changeWorkingDirectory(remoteParent))
{
throw new Exception(ftpClient.getReplyString()+" ("+remoteParent+")"); //$NON-NLS-1$ //$NON-NLS-2$
@@ -919,7 +948,7 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
try {
File tempFile = File.createTempFile("ftp", "temp"); //$NON-NLS-1$ //$NON-NLS-2$
tempFile.deleteOnExit();
- boolean success = upload(monitor, tempFile, remoteParent, fileName, true, null, null);
+ boolean success = upload(monitor, tempFile, remoteParent, fileName, _isBinaryFileType, null, null);
if(!success)
{
@@ -968,7 +997,7 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
}
- private synchronized boolean listFiles(IProgressMonitor monitor) throws Exception
+ private boolean listFiles(IProgressMonitor monitor) throws Exception
{
boolean result = true;
@@ -1028,25 +1057,6 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
return result;
}
- private String adaptPath(String path)
- {
- Matcher matcher = Pattern.compile("[\\\\/](\\w:.*)").matcher(path); //$NON-NLS-1$
-
- if(matcher.matches())
- {
- path = matcher.group(1);
- }
-
-
- if(path.length()>1)
- {
- path = getSeparator() == '/' ? path.replace('\\', getSeparator()) : path.replace('/', getSeparator());
- }
-
- return path;
- }
-
-
private class MyProgressMonitor
{
@@ -1163,16 +1173,8 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
InputStream stream = null;
try {
- remoteParent = adaptPath(remoteParent);
- ftpClient.changeWorkingDirectory(remoteParent);
-
- if (isBinary) {
- ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
- }
- else {
- ftpClient.setFileType(FTP.ASCII_FILE_TYPE);
- }
+ setFileType(isBinary);
stream = new FTPBufferedInputStream(ftpClient.retrieveFileStream(remoteFile), ftpClient);
}
@@ -1203,16 +1205,9 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
try {
- remoteParent = adaptPath(remoteParent);
-
ftpClient.changeWorkingDirectory(remoteParent);
-
- if (isBinary) {
- ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
- }
- else {
- ftpClient.setFileType(FTP.ASCII_FILE_TYPE);
- }
+
+ setFileType(isBinary);
stream = new FTPBufferedOutputStream(ftpClient.storeFileStream(remoteFile), ftpClient);
}
@@ -1222,4 +1217,38 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
return stream;
}
+
+ private void setDataConnectionMode()
+ {
+ if(_ftpPropertySet != null)
+ {
+ if(_ftpPropertySet.getPropertyValue("passive").equalsIgnoreCase("true") && !_isPassiveDataConnectionMode) //$NON-NLS-1$ //$NON-NLS-2$
+ {
+ _ftpClient.enterLocalPassiveMode();
+ _isPassiveDataConnectionMode = true;
+ }
+ else if(_ftpPropertySet.getPropertyValue("passive").equalsIgnoreCase("false") && _isPassiveDataConnectionMode) //$NON-NLS-1$ //$NON-NLS-2$
+ {
+ _ftpClient.enterLocalActiveMode();
+ _isPassiveDataConnectionMode = false;
+ }
+ }
+ }
+
+ private void setFileType(boolean isBinaryFileType) throws IOException
+ {
+ if(!isBinaryFileType && _isBinaryFileType)
+ {
+ _ftpClient.setFileType(FTP.ASCII_FILE_TYPE);
+ _isBinaryFileType = isBinaryFileType;
+ } else if(isBinaryFileType && !_isBinaryFileType)
+ {
+ _ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
+ _isBinaryFileType = isBinaryFileType;
+ }
+ }
+
+
+
+
}
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.rse.services.files.ftp/src/org/eclipse/rse/internal/services/files/ftp/parser/FTPClientConfigFactory.java b/rse/plugins/org.eclipse.rse.services.files.ftp/src/org/eclipse/rse/internal/services/files/ftp/parser/FTPClientConfigFactory.java
new file mode 100644
index 00000000000..7ee4f7076e1
--- /dev/null
+++ b/rse/plugins/org.eclipse.rse.services.files.ftp/src/org/eclipse/rse/internal/services/files/ftp/parser/FTPClientConfigFactory.java
@@ -0,0 +1,128 @@
+/********************************************************************************
+ * Copyright (c) 2007 Symbian Software Ltd. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Javier Montalvo Orus (Symbian) - initial API and implementation
+ ********************************************************************************/
+
+package org.eclipse.rse.internal.services.files.ftp.parser;
+
+import java.util.Hashtable;
+import java.util.Set;
+
+import org.apache.commons.net.ftp.FTPClientConfig;
+import org.apache.commons.net.ftp.FTPFileEntryParser;
+import org.apache.commons.net.ftp.parser.FTPFileEntryParserFactory;
+import org.apache.commons.net.ftp.parser.ParserInitializationException;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.Platform;
+
+public class FTPClientConfigFactory implements FTPFileEntryParserFactory {
+
+private static FTPClientConfigFactory factory = null;
+
+ private Hashtable ftpConfig = new Hashtable();
+ private Hashtable ftpFileEntryParser = new Hashtable();
+
+ /**
+ * Constructor of the parser factory
+ * @return an instance of the factory
+ */
+ public static FTPClientConfigFactory getParserFactory()
+ {
+ if(factory==null)
+ {
+ factory = new FTPClientConfigFactory();
+ }
+
+ return factory;
+ }
+
+ private FTPClientConfigFactory() {
+
+ FTPClientConfig config = null;
+
+ IExtensionPoint ep = Platform.getExtensionRegistry().getExtensionPoint("org.eclipse.rse.services.files.ftp","ftpFileEntryParser"); //$NON-NLS-1$ //$NON-NLS-2$
+ IConfigurationElement[] ce = ep.getConfigurationElements();
+ for (int i = 0; i < ce.length; i++) {
+
+ config = null;
+
+ String name = ce[i].getAttribute("name"); //$NON-NLS-1$
+ String clas = ce[i].getAttribute("class"); //$NON-NLS-1$
+
+ FTPFileEntryParser entryParser=null;
+ try {
+ entryParser = (FTPFileEntryParser)ce[i].createExecutableExtension("class"); //$NON-NLS-1$
+ } catch (CoreException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ ftpFileEntryParser.put(clas, entryParser);
+
+ String defaultDateFormatStr = ce[i].getAttribute("defaultDateFormatStr"); //$NON-NLS-1$
+ String recentDateFormatStr = ce[i].getAttribute("recentDateFormatStr"); //$NON-NLS-1$
+ String serverLanguageCode = ce[i].getAttribute("serverLanguageCode"); //$NON-NLS-1$
+ String shortMonthNames = ce[i].getAttribute("shortMonthNames"); //$NON-NLS-1$
+ String serverTimeZoneId = ce[i].getAttribute("serverTimeZoneId"); //$NON-NLS-1$
+
+ config = new FTPClientConfig(clas);
+
+ //not necessary checking for null, as null is valid input
+ config.setDefaultDateFormatStr(defaultDateFormatStr);
+ config.setRecentDateFormatStr(recentDateFormatStr);
+ config.setServerLanguageCode(serverLanguageCode);
+ config.setShortMonthNames(shortMonthNames);
+ config.setServerTimeZoneId(serverTimeZoneId);
+
+ ftpConfig.put(name, config);
+
+ }
+ }
+
+ /**
+ *
+ * @param key name attribute of the extension point to be returned
+ * @return FTPClientConfig instance created from the attributes passed in the extension point
+ */
+ public FTPClientConfig getFTPClientConfig(String key)
+ {
+ return (FTPClientConfig)ftpConfig.get(key);
+ }
+
+ /**
+ * Returns a Set of key names
+ * @return a Set containing the name attribute of the extension points
+ */
+ public Set getKeySet()
+ {
+ return ftpConfig.keySet();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.apache.commons.net.ftp.parser.FTPFileEntryParserFactory#createFileEntryParser(java.lang.String)
+ */
+ public FTPFileEntryParser createFileEntryParser(String key) throws ParserInitializationException {
+ return (FTPFileEntryParser)ftpFileEntryParser.get(key);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.apache.commons.net.ftp.parser.FTPFileEntryParserFactory#createFileEntryParser(org.apache.commons.net.ftp.FTPClientConfig)
+ */
+ public FTPFileEntryParser createFileEntryParser(FTPClientConfig config)
+ throws ParserInitializationException {
+
+ String key = config.getServerSystemKey();
+ return createFileEntryParser(key);
+
+ }
+
+}
diff --git a/rse/plugins/org.eclipse.rse.services.files.ftp/src/org/eclipse/rse/internal/services/files/ftp/parser/RSENTFTPEntryParser.java b/rse/plugins/org.eclipse.rse.services.files.ftp/src/org/eclipse/rse/internal/services/files/ftp/parser/RSENTFTPEntryParser.java
new file mode 100644
index 00000000000..61d1e99fac6
--- /dev/null
+++ b/rse/plugins/org.eclipse.rse.services.files.ftp/src/org/eclipse/rse/internal/services/files/ftp/parser/RSENTFTPEntryParser.java
@@ -0,0 +1,82 @@
+/********************************************************************************
+ * Copyright (c) 2007 Symbian Software Ltd. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Javier Montalvo Orus (Symbian) - initial API and implementation
+ ********************************************************************************/
+
+package org.eclipse.rse.internal.services.files.ftp.parser;
+
+import java.text.ParseException;
+
+import org.apache.commons.net.ftp.FTPFile;
+import org.apache.commons.net.ftp.parser.NTFTPEntryParser;
+
+public class RSENTFTPEntryParser extends NTFTPEntryParser {
+
+ /**
+ * Parses a line of an NT FTP server file listing and converts it into a
+ * usable format in the form of an FTPFile
instance. If the
+ * file listing line doesn't describe a file, null
is
+ * returned, otherwise a FTPFile
instance representing the
+ * files in the directory is returned. This extension enables the R/W permission
+ * for NT parsing, setting it as true by default.
+ *
+ * @param entry A line of text from the file listing
+ * @return An FTPFile instance corresponding to the supplied entry
+ */
+ public FTPFile parseFTPEntry(String entry)
+ {
+ FTPFile f = new FTPFile();
+ f.setRawListing(entry);
+
+ if (matches(entry))
+ {
+ String datestr = group(1)+" "+group(2); //$NON-NLS-1$
+ String dirString = group(3);
+ String size = group(4);
+ String name = group(5);
+ try
+ {
+ f.setTimestamp(super.parseTimestamp(datestr));
+ }
+ catch (ParseException e)
+ {
+ return null; // this is a parsing failure too.
+ }
+
+ if (null == name || name.equals(".") || name.equals("..")) //$NON-NLS-1$//$NON-NLS-2$
+ {
+ return (null);
+ }
+ f.setName(name);
+
+
+ if ("
".equals(dirString)) //$NON-NLS-1$
+ {
+ f.setType(FTPFile.DIRECTORY_TYPE);
+ f.setSize(0);
+ }
+ else
+ {
+ f.setType(FTPFile.FILE_TYPE);
+ if (null != size)
+ {
+ f.setSize(Long.parseLong(size));
+ }
+ }
+
+ // only USER permission is shown in RSE
+ f.setPermission(FTPFile.USER_ACCESS, FTPFile.READ_PERMISSION, true);
+ f.setPermission(FTPFile.USER_ACCESS, FTPFile.WRITE_PERMISSION, true);
+ f.setPermission(FTPFile.USER_ACCESS, FTPFile.EXECUTE_PERMISSION, true);
+
+ return (f);
+ }
+ return null;
+ }
+
+}
diff --git a/rse/plugins/org.eclipse.rse.services.files.ftp/src/org/eclipse/rse/internal/services/files/ftp/parser/RSEVMSFTPEntryParser.java b/rse/plugins/org.eclipse.rse.services.files.ftp/src/org/eclipse/rse/internal/services/files/ftp/parser/RSEVMSFTPEntryParser.java
new file mode 100644
index 00000000000..b49b3adc553
--- /dev/null
+++ b/rse/plugins/org.eclipse.rse.services.files.ftp/src/org/eclipse/rse/internal/services/files/ftp/parser/RSEVMSFTPEntryParser.java
@@ -0,0 +1,224 @@
+/********************************************************************************
+ * Copyright (c) 2007 Symbian Software Ltd. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Javier Montalvo Orus (Symbian) - initial API and implementation
+ ********************************************************************************/
+
+package org.eclipse.rse.internal.services.files.ftp.parser;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.text.ParseException;
+import java.util.StringTokenizer;
+
+import org.apache.commons.net.ftp.FTPClientConfig;
+import org.apache.commons.net.ftp.FTPFile;
+import org.apache.commons.net.ftp.parser.ConfigurableFTPFileEntryParserImpl;
+
+public class RSEVMSFTPEntryParser extends ConfigurableFTPFileEntryParserImpl {
+
+ private static final String DEFAULT_DATE_FORMAT
+ = "d-MMM-yyyy HH:mm:ss"; //9-NOV-2001 12:30:24 //$NON-NLS-1$
+
+ private static final String REGEX =
+ "(.*;[0-9]+)\\s*" //$NON-NLS-1$
+ + "(\\d+)/\\d+\\s*" //$NON-NLS-1$
+ +"(\\S+)\\s+(\\S+)\\s+" //$NON-NLS-1$
+ + "\\[(([0-9$A-Za-z_]+)|([0-9$A-Za-z_]+),([0-9$a-zA-Z_]+))\\]?\\s*" //$NON-NLS-1$
+ + "(\\([a-zA-Z]*,[a-zA-Z]*,[a-zA-Z]*,[a-zA-Z]*\\))"; //$NON-NLS-1$
+
+ /**
+ * Constructor for a VMSFTPEntryParser object.
+ *
+ * @exception IllegalArgumentException
+ * Thrown if the regular expression is unparseable. Should not be seen
+ * under normal conditions. It it is seen, this is a sign that
+ * REGEX
is not a valid regular expression.
+ */
+ public RSEVMSFTPEntryParser()
+ {
+ this(null);
+ }
+
+ /**
+ * This constructor allows the creation of a VMSFTPEntryParser object with
+ * something other than the default configuration.
+ *
+ * @param config The {@link FTPClientConfig configuration} object used to
+ * configure this parser.
+ * @exception IllegalArgumentException
+ * Thrown if the regular expression is unparseable. Should not be seen
+ * under normal conditions. It it is seen, this is a sign that
+ * REGEX
is not a valid regular expression.
+ * @since 1.4
+ */
+ public RSEVMSFTPEntryParser(FTPClientConfig config)
+ {
+ super(REGEX);
+ configure(config);
+ }
+
+ /**
+ * Parses a line of a VMS FTP server file listing and converts it into a
+ * usable format in the form of an FTPFile
instance. If the
+ * file listing line doesn't describe a file, null
is
+ * returned, otherwise a FTPFile
instance representing the
+ * files in the directory is returned.
+ *
+ * @param entry A line of text from the file listing
+ * @return An FTPFile instance corresponding to the supplied entry
+ */
+ public FTPFile parseFTPEntry(String entry)
+ {
+ //one block in VMS equals 512 bytes
+ long longBlock = 512;
+
+ if (matches(entry))
+ {
+ FTPFile f = new FTPFile();
+ f.setRawListing(entry);
+ String name = group(1);
+ String size = group(2);
+ String datestr = group(3)+" "+group(4); //$NON-NLS-1$
+ String owner = group(5);
+ String permissions = group(9);
+ try
+ {
+ f.setTimestamp(super.parseTimestamp(datestr));
+ }
+ catch (ParseException e)
+ {
+ return null; // this is a parsing failure too.
+ }
+
+
+ String grp;
+ String user;
+ StringTokenizer t = new StringTokenizer(owner, ","); //$NON-NLS-1$
+ switch (t.countTokens()) {
+ case 1:
+ grp = null;
+ user = t.nextToken();
+ break;
+ case 2:
+ grp = t.nextToken();
+ user = t.nextToken();
+ break;
+ default:
+ grp = null;
+ user = null;
+ }
+
+ if (name.lastIndexOf(".DIR") != -1) //$NON-NLS-1$
+ {
+ f.setType(FTPFile.DIRECTORY_TYPE);
+ }
+ else
+ {
+ f.setType(FTPFile.FILE_TYPE);
+ }
+ //set FTPFile name
+ //Check also for versions to be returned or not
+ if (isVersioning())
+ {
+ f.setName(name);
+ }
+ else
+ {
+ name = name.substring(0, name.lastIndexOf(";")); //$NON-NLS-1$
+ if(name.lastIndexOf(".DIR")!=-1) //$NON-NLS-1$
+ {
+ name = name.substring(0, name.lastIndexOf(".DIR")); //$NON-NLS-1$
+ }
+ f.setName(name);
+ }
+ //size is retreived in blocks and needs to be put in bytes
+ //for us humans and added to the FTPFile array
+ long sizeInBytes = Long.parseLong(size) * longBlock;
+ f.setSize(sizeInBytes);
+
+ f.setGroup(grp);
+ f.setUser(user);
+ //set group and owner
+
+ //Set file permission.
+ //VMS has (SYSTEM,OWNER,GROUP,WORLD) users that can contain
+ //R (read) W (write) E (execute) D (delete)
+
+ t = new StringTokenizer(permissions, ","); //$NON-NLS-1$
+
+ //discard SYSTEM permission
+ t.nextElement();
+
+ //iterate for OWNER GROUP WORLD permissions
+ for (int access = 0; access < 3; access++)
+ {
+ String token = t.nextToken();
+
+ f.setPermission(access, FTPFile.READ_PERMISSION, token.indexOf('R')!=-1);
+ f.setPermission(access, FTPFile.WRITE_PERMISSION, token.indexOf('W')!=-1);
+ f.setPermission(access, FTPFile.EXECUTE_PERMISSION, token.indexOf('E')!=-1);
+ }
+
+ return f;
+ }
+ return null;
+ }
+
+
+ /**
+ * Reads the next entry using the supplied BufferedReader object up to
+ * whatever delemits one entry from the next. This parser cannot use
+ * the default implementation of simply calling BufferedReader.readLine(),
+ * because one entry may span multiple lines.
+ *
+ * @param reader The BufferedReader object from which entries are to be
+ * read.
+ *
+ * @return A string representing the next ftp entry or null if none found.
+ * @exception IOException thrown on any IO Error reading from the reader.
+ */
+ public String readNextEntry(BufferedReader reader) throws IOException
+ {
+ String line = reader.readLine();
+ StringBuffer entry = new StringBuffer();
+ while (line != null)
+ {
+ if (line.startsWith("Directory") || line.startsWith("Total")) { //$NON-NLS-1$//$NON-NLS-2$
+ line = reader.readLine();
+ continue;
+ }
+
+ entry.append(line);
+ if (line.trim().endsWith(")")) //$NON-NLS-1$
+ {
+ break;
+ }
+ line = reader.readLine();
+ }
+ return (entry.length() == 0 ? null : entry.toString());
+ }
+
+ protected boolean isVersioning() {
+ return false;
+ }
+
+ /**
+ * Defines a default configuration to be used when this class is
+ * instantiated without a {@link FTPClientConfig FTPClientConfig}
+ * parameter being specified.
+ * @return the default configuration for this parser.
+ */
+protected FTPClientConfig getDefaultConfiguration() {
+ return new FTPClientConfig(
+ FTPClientConfig.SYST_VMS,
+ DEFAULT_DATE_FORMAT,
+ null, null, null, null);
+ }
+
+
+}
diff --git a/rse/plugins/org.eclipse.rse.subsystems.files.ftp/META-INF/MANIFEST.MF b/rse/plugins/org.eclipse.rse.subsystems.files.ftp/META-INF/MANIFEST.MF
index 57b521d33f4..6457914d2d5 100644
--- a/rse/plugins/org.eclipse.rse.subsystems.files.ftp/META-INF/MANIFEST.MF
+++ b/rse/plugins/org.eclipse.rse.subsystems.files.ftp/META-INF/MANIFEST.MF
@@ -13,7 +13,8 @@ Require-Bundle: org.eclipse.ui,
org.eclipse.rse.subsystems.files.core,
org.eclipse.rse.core,
org.eclipse.rse.ui,
- org.eclipse.ui.console
+ org.eclipse.ui.console,
+ org.apache.commons.net
Eclipse-LazyStart: true
Export-Package: org.eclipse.rse.internal.subsystems.files.ftp;x-internal:=true,
org.eclipse.rse.internal.subsystems.files.ftp.connectorservice;x-internal:=true,
diff --git a/rse/plugins/org.eclipse.rse.subsystems.files.ftp/plugin.xml b/rse/plugins/org.eclipse.rse.subsystems.files.ftp/plugin.xml
index 403c1c9af3b..a0da901b16d 100644
--- a/rse/plugins/org.eclipse.rse.subsystems.files.ftp/plugin.xml
+++ b/rse/plugins/org.eclipse.rse.subsystems.files.ftp/plugin.xml
@@ -42,5 +42,5 @@ Javier Montalvo Orus (Symbian) - [plan] Improve Discovery and Autodetect in RSE
serviceType="_ftp._tcp">
-
+
diff --git a/rse/plugins/org.eclipse.rse.subsystems.files.ftp/src/org/eclipse/rse/internal/subsystems/files/ftp/connectorservice/FTPConnectorService.java b/rse/plugins/org.eclipse.rse.subsystems.files.ftp/src/org/eclipse/rse/internal/subsystems/files/ftp/connectorservice/FTPConnectorService.java
index e14cb5d5d75..d76ad052a4d 100644
--- a/rse/plugins/org.eclipse.rse.subsystems.files.ftp/src/org/eclipse/rse/internal/subsystems/files/ftp/connectorservice/FTPConnectorService.java
+++ b/rse/plugins/org.eclipse.rse.subsystems.files.ftp/src/org/eclipse/rse/internal/subsystems/files/ftp/connectorservice/FTPConnectorService.java
@@ -16,11 +16,14 @@
* Javier Montalvo Orus (Symbian) - Bug 169680 - [ftp] FTP files subsystem and service should use passive mode
* David Dykstal (IBM) - 168977: refactoring IConnectorService and ServerLauncher hierarchies
* Martin Oberhuber (Wind River) - [cleanup] move FTPSubsystemResources out of core
+ * Javier Montalvo Orus (Symbian) - Fixing 176216 - [api] FTP sould provide API to allow clients register their own FTPListingParser
********************************************************************************/
package org.eclipse.rse.internal.subsystems.files.ftp.connectorservice;
import java.io.OutputStream;
+import java.util.Arrays;
+import java.util.Set;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.rse.core.model.IHost;
@@ -28,6 +31,7 @@ import org.eclipse.rse.core.model.IPropertySet;
import org.eclipse.rse.core.model.PropertyType;
import org.eclipse.rse.core.model.SystemSignonInformation;
import org.eclipse.rse.internal.services.files.ftp.FTPService;
+import org.eclipse.rse.internal.services.files.ftp.parser.FTPClientConfigFactory;
import org.eclipse.rse.internal.subsystems.files.ftp.FTPSubsystemResources;
import org.eclipse.rse.services.files.IFileService;
import org.eclipse.rse.ui.subsystems.StandardConnectorService;
@@ -51,8 +55,21 @@ public class FTPConnectorService extends StandardConnectorService
if(_propertySet==null)
{
+
+ //Active - passive mode
_propertySet = createPropertySet("FTP Settings"); //$NON-NLS-1$
_propertySet.addProperty("passive","false",PropertyType.getEnumPropertyType(new String[]{"true","false"})); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+
+ // FTP List parser
+ Set keys = FTPClientConfigFactory.getParserFactory().getKeySet();
+ String[] keysArray = new String[keys.size()+1];
+
+ keys.toArray(keysArray);
+ keysArray[keysArray.length-1]="AUTO"; //$NON-NLS-1$
+
+ Arrays.sort(keysArray);
+
+ _propertySet.addProperty("parser","AUTO",PropertyType.getEnumPropertyType(keysArray)); //$NON-NLS-1$ //$NON-NLS-2$
}
}
@@ -63,14 +80,7 @@ public class FTPConnectorService extends StandardConnectorService
private void internalConnect() throws Exception
{
- _propertySet = getPropertySet("FTP Settings"); //$NON-NLS-1$
-
- if(_propertySet==null)
- {
- _propertySet = createPropertySet("FTP Settings"); //$NON-NLS-1$
- _propertySet.addProperty("passive","false",PropertyType.getEnumPropertyType(new String[]{"true","false"})); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
- }
-
+
SystemSignonInformation info = getSignonInformation();
_ftpService.setHostName(info.getHostname());
_ftpService.setUserId(info.getUserId());