mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-09 01:55:24 +02:00
Fixing 162585 - [FTP] fetch children cannot be canceled
Fixing 161209 - Need a Log of ftp commands Fixing 163264 - FTP Only can not delete first subfolder
This commit is contained in:
parent
f76cf1434b
commit
e32b10f6f3
2 changed files with 480 additions and 161 deletions
|
@ -8,6 +8,8 @@ Bundle-Vendor: %providerName
|
||||||
Bundle-Localization: plugin
|
Bundle-Localization: plugin
|
||||||
Require-Bundle: org.eclipse.core.runtime,
|
Require-Bundle: org.eclipse.core.runtime,
|
||||||
org.eclipse.rse.services,
|
org.eclipse.rse.services,
|
||||||
org.apache.commons.net
|
org.apache.commons.net,
|
||||||
|
org.eclipse.ui.console,
|
||||||
|
org.eclipse.jface
|
||||||
Eclipse-LazyStart: true
|
Eclipse-LazyStart: true
|
||||||
Export-Package: org.eclipse.rse.services.files.ftp
|
Export-Package: org.eclipse.rse.services.files.ftp
|
||||||
|
|
|
@ -26,23 +26,34 @@
|
||||||
* Javier Montalvo Orus (Symbian) - Fixing 162511 - FTP file service does not process filter strings correctly
|
* Javier Montalvo Orus (Symbian) - Fixing 162511 - FTP file service does not process filter strings correctly
|
||||||
* Javier Montalvo Orus (Symbian) - Fixing 162782 - File filter does not display correct result in RC3
|
* Javier Montalvo Orus (Symbian) - Fixing 162782 - File filter does not display correct result in RC3
|
||||||
* Javier Montalvo Orus (Symbian) - Fixing 162878 - New file and new folder dialogs don't work in FTP in a folder with subfolders
|
* Javier Montalvo Orus (Symbian) - Fixing 162878 - New file and new folder dialogs don't work in FTP in a folder with subfolders
|
||||||
|
* Javier Montalvo Orus (Symbian) - Fixing 162585 - [FTP] fetch children cannot be canceled
|
||||||
|
* Javier Montalvo Orus (Symbian) - Fixing 161209 - Need a Log of ftp commands
|
||||||
|
* Javier Montalvo Orus (Symbian) - Fixing 163264 - FTP Only can not delete first subfolder
|
||||||
********************************************************************************/
|
********************************************************************************/
|
||||||
|
|
||||||
package org.eclipse.rse.services.files.ftp;
|
package org.eclipse.rse.services.files.ftp;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.BufferedOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.text.MessageFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
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;
|
||||||
import org.apache.commons.net.ftp.FTPFile;
|
import org.apache.commons.net.ftp.FTPFile;
|
||||||
|
import org.apache.commons.net.ftp.FTPReply;
|
||||||
import org.eclipse.core.runtime.IProgressMonitor;
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
|
import org.eclipse.core.runtime.IStatus;
|
||||||
|
import org.eclipse.core.runtime.Path;
|
||||||
|
import org.eclipse.core.runtime.Status;
|
||||||
|
import org.eclipse.core.runtime.jobs.Job;
|
||||||
import org.eclipse.rse.services.clientserver.FileTypeMatcher;
|
import org.eclipse.rse.services.clientserver.FileTypeMatcher;
|
||||||
import org.eclipse.rse.services.clientserver.IMatcher;
|
import org.eclipse.rse.services.clientserver.IMatcher;
|
||||||
import org.eclipse.rse.services.clientserver.NamePatternMatcher;
|
import org.eclipse.rse.services.clientserver.NamePatternMatcher;
|
||||||
|
@ -50,21 +61,27 @@ import org.eclipse.rse.services.clientserver.messages.SystemMessageException;
|
||||||
import org.eclipse.rse.services.files.AbstractFileService;
|
import org.eclipse.rse.services.files.AbstractFileService;
|
||||||
import org.eclipse.rse.services.files.IFileService;
|
import org.eclipse.rse.services.files.IFileService;
|
||||||
import org.eclipse.rse.services.files.IHostFile;
|
import org.eclipse.rse.services.files.IHostFile;
|
||||||
|
import org.eclipse.rse.services.files.RemoteFileIOException;
|
||||||
|
import org.eclipse.rse.services.files.RemoteFolderNotEmptyException;
|
||||||
|
import org.eclipse.ui.console.ConsolePlugin;
|
||||||
|
import org.eclipse.ui.console.IConsole;
|
||||||
|
import org.eclipse.ui.console.MessageConsole;
|
||||||
|
|
||||||
|
|
||||||
public class FTPService extends AbstractFileService implements IFileService, IFTPService
|
public class FTPService extends AbstractFileService implements IFileService, IFTPService
|
||||||
{
|
{
|
||||||
private FTPClient _ftpClient;
|
private FTPClient _ftpClient;
|
||||||
|
private FTPFile[] _ftpFiles;
|
||||||
|
|
||||||
private String _userHome;
|
private String _userHome;
|
||||||
|
private transient String _hostName;
|
||||||
private transient String _hostname;
|
|
||||||
private transient String _userId;
|
private transient String _userId;
|
||||||
private transient String _password;
|
private transient String _password;
|
||||||
private transient int _portNumber;
|
private transient int _portNumber;
|
||||||
|
|
||||||
|
private OutputStream _ftpConsoleOutputStream;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
* @see org.eclipse.rse.services.IService#getName()
|
* @see org.eclipse.rse.services.IService#getName()
|
||||||
|
@ -85,7 +102,7 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
|
||||||
|
|
||||||
public void setHostName(String hostname)
|
public void setHostName(String hostname)
|
||||||
{
|
{
|
||||||
_hostname = hostname;
|
_hostName = hostname;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPortNumber(int portNumber) {
|
public void setPortNumber(int portNumber) {
|
||||||
|
@ -104,26 +121,43 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
|
||||||
|
|
||||||
public void connect() throws Exception
|
public void connect() throws Exception
|
||||||
{
|
{
|
||||||
FTPClient ftp = getFTPClient();
|
if (_ftpClient == null)
|
||||||
if (_portNumber == 0) {
|
|
||||||
ftp.connect(_hostname);
|
|
||||||
} else {
|
|
||||||
ftp.connect(_hostname, _portNumber);
|
|
||||||
}
|
|
||||||
ftp.login(_userId, _password);
|
|
||||||
|
|
||||||
_userHome = ftp.printWorkingDirectory();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void reconnect()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
connect();
|
_ftpClient = new FTPClient();
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
|
||||||
{
|
if(_ftpConsoleOutputStream==null)
|
||||||
|
{
|
||||||
|
MessageConsole messageConsole=null;
|
||||||
|
|
||||||
|
IConsole[] consoles = ConsolePlugin.getDefault().getConsoleManager().getConsoles();
|
||||||
|
for (int i = 0; i < consoles.length; i++) {
|
||||||
|
if(consoles[i].getName().equals("FTP log: "+_hostName+":"+_portNumber)) { //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
messageConsole = (MessageConsole)consoles[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(messageConsole==null){
|
||||||
|
messageConsole = new MessageConsole("FTP log: "+_hostName+":"+_portNumber, null); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
ConsolePlugin.getDefault().getConsoleManager().addConsoles(new IConsole[]{ messageConsole });
|
||||||
|
}
|
||||||
|
|
||||||
|
_ftpConsoleOutputStream = messageConsole.newOutputStream();
|
||||||
|
ConsolePlugin.getDefault().getConsoleManager().showConsoleView(messageConsole);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_ftpClient.registerSpyStream(_ftpConsoleOutputStream);
|
||||||
|
|
||||||
|
if (_portNumber == 0) {
|
||||||
|
_ftpClient.connect(_hostName);
|
||||||
|
} else {
|
||||||
|
_ftpClient.connect(_hostName, _portNumber);
|
||||||
|
}
|
||||||
|
_ftpClient.login(_userId, _password);
|
||||||
|
|
||||||
|
_userHome = _ftpClient.printWorkingDirectory();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void disconnect()
|
public void disconnect()
|
||||||
|
@ -144,7 +178,21 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
|
||||||
if (_ftpClient == null)
|
if (_ftpClient == null)
|
||||||
{
|
{
|
||||||
_ftpClient = new FTPClient();
|
_ftpClient = new FTPClient();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(_hostName!=null)
|
||||||
|
{
|
||||||
|
try{
|
||||||
|
_ftpClient.sendNoOp();
|
||||||
|
}catch (IOException e){
|
||||||
|
try {
|
||||||
|
connect();
|
||||||
|
} catch (Exception e1) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return _ftpClient;
|
return _ftpClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,39 +200,38 @@ 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(org.eclipse.core.runtime.IProgressMonitor, java.lang.String, java.lang.String)
|
||||||
*/
|
*/
|
||||||
public IHostFile getFile(IProgressMonitor monitor, String remoteParent, String fileName)
|
public IHostFile getFile(IProgressMonitor monitor, String remoteParent, String fileName) throws SystemMessageException
|
||||||
{
|
{
|
||||||
|
if (monitor!=null){
|
||||||
|
if (monitor.isCanceled()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FTPHostFile file = null;
|
FTPHostFile file = null;
|
||||||
|
|
||||||
try{
|
try{
|
||||||
|
|
||||||
//try to retrieve the file
|
//try to retrieve the file
|
||||||
FTPClient ftp = getFTPClient();
|
_ftpClient = getFTPClient();
|
||||||
try
|
|
||||||
{
|
|
||||||
ftp.noop();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
disconnect();
|
|
||||||
reconnect();
|
|
||||||
ftp = getFTPClient();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!ftp.changeWorkingDirectory(remoteParent))
|
if(!_ftpClient.changeWorkingDirectory(remoteParent))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
String systemName = ftp.getSystemName();
|
String systemName = _ftpClient.getSystemName();
|
||||||
|
|
||||||
FTPFile[] ftpFiles = ftp.listFiles();
|
if(!listFiles(monitor))
|
||||||
|
|
||||||
for (int i = 0; i < ftpFiles.length; i++)
|
|
||||||
{
|
{
|
||||||
if(ftpFiles[i].getName().equalsIgnoreCase(fileName))
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < _ftpFiles.length; i++)
|
||||||
|
{
|
||||||
|
if(_ftpFiles[i].getName().equalsIgnoreCase(fileName))
|
||||||
{
|
{
|
||||||
file = new FTPHostFile(remoteParent,ftpFiles[i],systemName);
|
file = new FTPHostFile(remoteParent,_ftpFiles[i],systemName);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -196,8 +243,8 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}catch (IOException e){
|
}catch (Exception e){
|
||||||
//file will be null
|
throw new RemoteFileIOException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return file;
|
return file;
|
||||||
|
@ -205,23 +252,35 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
|
||||||
|
|
||||||
public boolean isConnected()
|
public boolean isConnected()
|
||||||
{
|
{
|
||||||
return getFTPClient().isConnected();
|
boolean isConnected = false;
|
||||||
|
|
||||||
|
if(_ftpClient!=null) {
|
||||||
|
isConnected = _ftpClient.isConnected();
|
||||||
|
}
|
||||||
|
|
||||||
|
return isConnected;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
* @see org.eclipse.rse.services.files.AbstractFileService#internalFetch(org.eclipse.core.runtime.IProgressMonitor, java.lang.String, java.lang.String, int)
|
* @see org.eclipse.rse.services.files.AbstractFileService#internalFetch(org.eclipse.core.runtime.IProgressMonitor, java.lang.String, java.lang.String, int)
|
||||||
*/
|
*/
|
||||||
protected IHostFile[] internalFetch(IProgressMonitor monitor, String parentPath, String fileFilter, int fileType)
|
protected IHostFile[] internalFetch(IProgressMonitor monitor, String parentPath, String fileFilter, int fileType) throws SystemMessageException
|
||||||
{
|
{
|
||||||
|
if (monitor!=null){
|
||||||
|
if (monitor.isCanceled()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (fileFilter == null)
|
if (fileFilter == null)
|
||||||
{
|
{
|
||||||
fileFilter = "*";
|
fileFilter = "*"; //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
IMatcher filematcher = null;
|
IMatcher filematcher = null;
|
||||||
if (fileFilter.endsWith(",")) {
|
if (fileFilter.endsWith(",")) { //$NON-NLS-1$
|
||||||
String[] types = fileFilter.split(",");
|
String[] types = fileFilter.split(","); //$NON-NLS-1$
|
||||||
filematcher = new FileTypeMatcher(types, true);
|
filematcher = new FileTypeMatcher(types, true);
|
||||||
} else {
|
} else {
|
||||||
filematcher = new NamePatternMatcher(fileFilter, true, true);
|
filematcher = new NamePatternMatcher(fileFilter, true, true);
|
||||||
|
@ -230,40 +289,32 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
FTPClient ftp = getFTPClient();
|
_ftpClient = getFTPClient();
|
||||||
try
|
|
||||||
{
|
|
||||||
ftp.noop();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
disconnect();
|
|
||||||
|
|
||||||
reconnect();
|
|
||||||
ftp = getFTPClient();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!ftp.changeWorkingDirectory(parentPath))
|
if(!_ftpClient.changeWorkingDirectory(parentPath))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
String systemName = ftp.getSystemName();
|
if(!listFiles(monitor))
|
||||||
|
|
||||||
FTPFile[] ftpFiles = ftp.listFiles();
|
|
||||||
|
|
||||||
for(int i=0; i<ftpFiles.length; i++)
|
|
||||||
{
|
{
|
||||||
FTPFile f = ftpFiles[i];
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String systemName = _ftpClient.getSystemName();
|
||||||
|
|
||||||
|
for(int i=0; i<_ftpFiles.length; i++)
|
||||||
|
{
|
||||||
|
FTPFile f = _ftpFiles[i];
|
||||||
if(filematcher.matches(f.getName()) || f.isDirectory())
|
if(filematcher.matches(f.getName()) || f.isDirectory())
|
||||||
{
|
{
|
||||||
results.add(new FTPHostFile(parentPath,ftpFiles[i],systemName));
|
results.add(new FTPHostFile(parentPath,_ftpFiles[i],systemName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
e.printStackTrace();
|
throw new RemoteFileIOException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (IHostFile[])results.toArray(new IHostFile[results.size()]);
|
return (IHostFile[])results.toArray(new IHostFile[results.size()]);
|
||||||
|
@ -272,75 +323,148 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
|
||||||
|
|
||||||
public String getSeparator()
|
public String getSeparator()
|
||||||
{
|
{
|
||||||
return "/";
|
return "/"; //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
* @see org.eclipse.rse.services.files.IFileService#upload(org.eclipse.core.runtime.IProgressMonitor, java.io.File, java.lang.String, java.lang.String, boolean, java.lang.String, java.lang.String)
|
* @see org.eclipse.rse.services.files.IFileService#upload(org.eclipse.core.runtime.IProgressMonitor, java.io.File, java.lang.String, java.lang.String, boolean, java.lang.String, java.lang.String)
|
||||||
*/
|
*/
|
||||||
public boolean upload(IProgressMonitor monitor, File localFile, String remoteParent, String remoteFile, boolean isBinary, String srcEncoding, String hostEncoding)
|
public boolean upload(IProgressMonitor monitor, File localFile, String remoteParent, String remoteFile, boolean isBinary, String srcEncoding, String hostEncoding) throws SystemMessageException
|
||||||
{
|
{
|
||||||
|
boolean retValue = true;
|
||||||
|
|
||||||
|
if (monitor!=null){
|
||||||
|
if (monitor.isCanceled()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FTPClient ftpClient = getFTPClient();
|
||||||
|
|
||||||
|
MyProgressMonitor progressMonitor = new MyProgressMonitor(monitor);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
FileInputStream fis = new FileInputStream(localFile);
|
|
||||||
return upload(monitor, fis, remoteParent, remoteFile, isBinary, hostEncoding);
|
ftpClient.changeWorkingDirectory(remoteParent);
|
||||||
|
|
||||||
|
if (isBinary)
|
||||||
|
ftpClient.setFileTransferMode(FTP.BINARY_FILE_TYPE);
|
||||||
|
else
|
||||||
|
ftpClient.setFileTransferMode(FTP.ASCII_FILE_TYPE);
|
||||||
|
|
||||||
|
FileInputStream input = new FileInputStream(localFile);
|
||||||
|
OutputStream output = ftpClient.storeFileStream(remoteFile);
|
||||||
|
|
||||||
|
progressMonitor.init(0, localFile.getName(), remoteFile, localFile.length());
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
input.close();
|
||||||
|
output.flush();
|
||||||
|
output.close();
|
||||||
|
|
||||||
|
ftpClient.completePendingCommand();
|
||||||
|
|
||||||
|
if(retValue==false) {
|
||||||
|
ftpClient.deleteFile(remoteFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
progressMonitor.end();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
e.printStackTrace();
|
throw new RemoteFileIOException(e);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return retValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
* @see org.eclipse.rse.services.files.IFileService#upload(org.eclipse.core.runtime.IProgressMonitor, java.io.InputStream, java.lang.String, java.lang.String, boolean, java.lang.String)
|
* @see org.eclipse.rse.services.files.IFileService#upload(org.eclipse.core.runtime.IProgressMonitor, java.io.InputStream, java.lang.String, java.lang.String, boolean, java.lang.String)
|
||||||
*/
|
*/
|
||||||
public boolean upload(IProgressMonitor monitor, InputStream stream, String remoteParent, String remoteFile, boolean isBinary, String hostEncoding)
|
public boolean upload(IProgressMonitor monitor, InputStream stream, String remoteParent, String remoteFile, boolean isBinary, String hostEncoding) throws SystemMessageException
|
||||||
{
|
{
|
||||||
boolean retValue = false;
|
boolean retValue = true;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
FTPClient ftp = getFTPClient();
|
BufferedInputStream bis = new BufferedInputStream(stream);
|
||||||
ftp.changeWorkingDirectory(remoteParent);
|
File tempFile = File.createTempFile("ftpup", "temp"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
FileOutputStream os = new FileOutputStream(tempFile);
|
||||||
if (isBinary)
|
BufferedOutputStream bos = new BufferedOutputStream(os);
|
||||||
ftp.setFileTransferMode(FTP.BINARY_FILE_TYPE);
|
|
||||||
else
|
byte[] buffer = new byte[4096];
|
||||||
ftp.setFileTransferMode(FTP.ASCII_FILE_TYPE);
|
int readCount;
|
||||||
|
while( (readCount = bis.read(buffer)) > 0)
|
||||||
retValue = ftp.storeFile(remoteFile, stream);
|
{
|
||||||
|
bos.write(buffer, 0, readCount);
|
||||||
stream.close();
|
if (monitor!=null){
|
||||||
|
if (monitor.isCanceled()) {
|
||||||
|
retValue = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bos.close();
|
||||||
|
|
||||||
|
if(retValue == true){
|
||||||
|
retValue = upload(monitor, tempFile, remoteParent, remoteFile, isBinary, "", hostEncoding); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e) {
|
||||||
{
|
throw new RemoteFileIOException(e);
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return retValue;
|
return retValue;
|
||||||
}
|
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
* @see org.eclipse.rse.services.files.IFileService#download(org.eclipse.core.runtime.IProgressMonitor, java.lang.String, java.lang.String, java.io.File, boolean, java.lang.String)
|
* @see org.eclipse.rse.services.files.IFileService#download(org.eclipse.core.runtime.IProgressMonitor, java.lang.String, java.lang.String, java.io.File, boolean, java.lang.String)
|
||||||
*/
|
*/
|
||||||
public boolean download(IProgressMonitor monitor, String remoteParent, String remoteFile, File localFile, boolean isBinary, String hostEncoding)
|
public boolean download(IProgressMonitor monitor, String remoteParent, String remoteFile, File localFile, boolean isBinary, String hostEncoding) throws SystemMessageException
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if (monitor!=null){
|
||||||
|
if (monitor.isCanceled()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MyProgressMonitor progressMonitor = new MyProgressMonitor(monitor);
|
||||||
|
|
||||||
|
IHostFile remoteHostFile = getFile(null,remoteParent,remoteFile);
|
||||||
|
|
||||||
boolean retValue = false;
|
boolean retValue = false;
|
||||||
|
|
||||||
|
FTPClient ftpClient = getFTPClient();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
FTPClient ftp = getFTPClient();
|
|
||||||
ftp.changeWorkingDirectory(remoteParent);
|
ftpClient.changeWorkingDirectory(remoteParent);
|
||||||
|
|
||||||
if (isBinary)
|
if (isBinary)
|
||||||
ftp.setFileTransferMode(FTP.BINARY_FILE_TYPE);
|
ftpClient.setFileTransferMode(FTP.BINARY_FILE_TYPE);
|
||||||
else
|
else
|
||||||
ftp.setFileTransferMode(FTP.ASCII_FILE_TYPE);
|
ftpClient.setFileTransferMode(FTP.ASCII_FILE_TYPE);
|
||||||
|
|
||||||
if (!localFile.exists())
|
if (!localFile.exists())
|
||||||
{
|
{
|
||||||
|
@ -353,15 +477,36 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
|
||||||
}
|
}
|
||||||
|
|
||||||
OutputStream output = new FileOutputStream(localFile);
|
OutputStream output = new FileOutputStream(localFile);
|
||||||
|
InputStream input = ftpClient.retrieveFileStream(remoteFile);
|
||||||
|
|
||||||
retValue = ftp.retrieveFile(remoteFile, output);
|
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();
|
output.flush();
|
||||||
|
input.close();
|
||||||
output.close();
|
output.close();
|
||||||
|
|
||||||
|
ftpClient.completePendingCommand();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
e.printStackTrace();
|
throw new RemoteFileIOException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return retValue;
|
return retValue;
|
||||||
|
@ -374,14 +519,14 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
|
||||||
public IHostFile getUserHome()
|
public IHostFile getUserHome()
|
||||||
{
|
{
|
||||||
|
|
||||||
int lastSlash = _userHome.lastIndexOf('/');
|
int lastSlash = _userHome.lastIndexOf('/');
|
||||||
String name = _userHome.substring(lastSlash + 1);
|
String name = _userHome.substring(lastSlash + 1);
|
||||||
String parent = _userHome.substring(0, lastSlash);
|
String parent = _userHome.substring(0, lastSlash);
|
||||||
|
|
||||||
// if home is root
|
// if home is root
|
||||||
if(parent.equals(""))
|
if(parent.equals("")) //$NON-NLS-1$
|
||||||
{
|
{
|
||||||
parent = "/";
|
parent = "/"; //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
return new FTPHostFile(parent,name,true,true,0,0,true);
|
return new FTPHostFile(parent,name,true,true,0,0,true);
|
||||||
|
@ -394,30 +539,56 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
|
||||||
*/
|
*/
|
||||||
public IHostFile[] getRoots(IProgressMonitor monitor)
|
public IHostFile[] getRoots(IProgressMonitor monitor)
|
||||||
{
|
{
|
||||||
return new IHostFile[]{new FTPHostFile(null, "/", true, true, 0, 0, true)};
|
return new IHostFile[]{new FTPHostFile(null, "/", true, true, 0, 0, true)}; //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.eclipse.rse.services.files.IFileService#delete(org.eclipse.core.runtime.IProgressMonitor, java.lang.String, java.lang.String)
|
* @see org.eclipse.rse.services.files.IFileService#delete(org.eclipse.core.runtime.IProgressMonitor, java.lang.String, java.lang.String)
|
||||||
*/
|
*/
|
||||||
public boolean delete(IProgressMonitor monitor, String remoteParent, String fileName) {
|
public boolean delete(IProgressMonitor monitor, String remoteParent, String fileName) throws SystemMessageException {
|
||||||
boolean hasSucceeded = false;
|
boolean hasSucceeded = false;
|
||||||
|
|
||||||
|
FTPClient ftpClient = getFTPClient();
|
||||||
|
|
||||||
|
MyProgressMonitor progressMonitor = new MyProgressMonitor(monitor);
|
||||||
|
|
||||||
|
progressMonitor.init("Deleting "+fileName, 1); //$NON-NLS-1$
|
||||||
|
|
||||||
|
boolean isFile = getFile(null,remoteParent,fileName).isFile();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
getFTPClient().cwd(remoteParent);
|
hasSucceeded = FTPReply.isPositiveCompletion(ftpClient.cwd(remoteParent));
|
||||||
|
|
||||||
//attempt to remove an empty folder folder
|
|
||||||
hasSucceeded = getFTPClient().removeDirectory(fileName);
|
|
||||||
|
|
||||||
if(!hasSucceeded)
|
if(hasSucceeded)
|
||||||
{
|
{
|
||||||
//attempt to remove a file
|
if(isFile)
|
||||||
hasSucceeded = getFTPClient().deleteFile(fileName);
|
{
|
||||||
|
hasSucceeded = ftpClient.deleteFile(fileName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hasSucceeded = ftpClient.removeDirectory(fileName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!hasSucceeded){
|
||||||
|
throw new Exception(ftpClient.getReplyString()+" ("+fileName+")");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
progressMonitor.worked(1);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
catch (Exception e) {
|
||||||
// Changing folder raised an exception
|
if(isFile){
|
||||||
hasSucceeded = false;
|
throw new RemoteFileIOException(e);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
throw new RemoteFolderNotEmptyException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return hasSucceeded;
|
return hasSucceeded;
|
||||||
|
@ -426,22 +597,24 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.eclipse.rse.services.files.IFileService#rename(org.eclipse.core.runtime.IProgressMonitor, java.lang.String, java.lang.String, java.lang.String)
|
* @see org.eclipse.rse.services.files.IFileService#rename(org.eclipse.core.runtime.IProgressMonitor, java.lang.String, java.lang.String, java.lang.String)
|
||||||
*/
|
*/
|
||||||
public boolean rename(IProgressMonitor monitor, String remoteParent, String oldName, String newName) {
|
public boolean rename(IProgressMonitor monitor, String remoteParent, String oldName, String newName) throws SystemMessageException {
|
||||||
|
|
||||||
|
FTPClient ftpClient = getFTPClient();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
if(newName.startsWith("/"))
|
if(newName.startsWith("/")) //$NON-NLS-1$
|
||||||
{
|
{
|
||||||
getFTPClient().rename(remoteParent + getSeparator() + oldName, newName);
|
ftpClient.rename(remoteParent + getSeparator() + oldName, newName);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
getFTPClient().rename(remoteParent + getSeparator() + oldName, remoteParent + getSeparator() + newName);
|
ftpClient.rename(remoteParent + getSeparator() + oldName, remoteParent + getSeparator() + newName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (Exception e) {
|
||||||
return false;
|
throw new RemoteFileIOException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -461,41 +634,60 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.eclipse.rse.services.files.IFileService#move(org.eclipse.core.runtime.IProgressMonitor, java.lang.String, java.lang.String, java.lang.String, java.lang.String)
|
* @see org.eclipse.rse.services.files.IFileService#move(org.eclipse.core.runtime.IProgressMonitor, java.lang.String, java.lang.String, java.lang.String, java.lang.String)
|
||||||
*/
|
*/
|
||||||
public boolean move(IProgressMonitor monitor, String srcParent, String srcName, String tgtParent, String tgtName) {
|
public boolean move(IProgressMonitor monitor, String srcParent, String srcName, String tgtParent, String tgtName) throws SystemMessageException{
|
||||||
boolean hasSucceeded = false;
|
|
||||||
|
boolean success = false;
|
||||||
|
|
||||||
|
FTPClient ftpClient = getFTPClient();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
int returnedValue;
|
int returnedValue = getFTPClient().sendCommand("RNFR " + srcParent + getSeparator() + srcName); //$NON-NLS-1$
|
||||||
returnedValue = getFTPClient().sendCommand("RNFR " + srcParent + getSeparator() + srcName);
|
|
||||||
|
|
||||||
if (returnedValue > 0) {
|
//350: origin file exits, ready for destination
|
||||||
returnedValue = getFTPClient().sendCommand("RNTO " + tgtParent + getSeparator() + tgtName);
|
if (FTPReply.CODE_350 == returnedValue) {
|
||||||
hasSucceeded = (returnedValue > 0);
|
returnedValue = getFTPClient().sendCommand("RNTO " + tgtParent + getSeparator() + tgtName); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
}catch (IOException e) {}
|
success = FTPReply.isPositiveCompletion(returnedValue);
|
||||||
|
|
||||||
return hasSucceeded;
|
if(!success)
|
||||||
|
{
|
||||||
|
throw new Exception(getFTPClient().getReplyString());
|
||||||
|
}
|
||||||
|
|
||||||
|
}catch (Exception e) {
|
||||||
|
throw new RemoteFileIOException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.eclipse.rse.services.files.IFileService#createFolder(org.eclipse.core.runtime.IProgressMonitor, java.lang.String, java.lang.String)
|
* @see org.eclipse.rse.services.files.IFileService#createFolder(org.eclipse.core.runtime.IProgressMonitor, java.lang.String, java.lang.String)
|
||||||
*/
|
*/
|
||||||
public IHostFile createFolder(IProgressMonitor monitor, String remoteParent, String folderName)
|
public IHostFile createFolder(IProgressMonitor monitor, String remoteParent, String folderName) throws SystemMessageException
|
||||||
{
|
{
|
||||||
|
|
||||||
|
FTPClient ftpClient = getFTPClient();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
FTPClient ftp = getFTPClient();
|
|
||||||
|
|
||||||
if(!ftp.changeWorkingDirectory(remoteParent))
|
if(!ftpClient.changeWorkingDirectory(remoteParent))
|
||||||
{
|
{
|
||||||
return null;
|
throw new Exception(ftpClient.getReplyString()+" ("+remoteParent+")"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
}
|
}
|
||||||
|
|
||||||
ftp.makeDirectory(folderName);
|
if(!ftpClient.makeDirectory(folderName))
|
||||||
|
{
|
||||||
|
throw new Exception(ftpClient.getReplyString()+" ("+folderName+")"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
throw new RemoteFileIOException(e);
|
||||||
}
|
}
|
||||||
catch (Exception e) {}
|
|
||||||
|
|
||||||
return getFile(monitor, remoteParent, folderName);
|
return getFile(monitor, remoteParent, folderName);
|
||||||
}
|
}
|
||||||
|
@ -503,35 +695,44 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.eclipse.rse.services.files.IFileService#createFile(org.eclipse.core.runtime.IProgressMonitor, java.lang.String, java.lang.String)
|
* @see org.eclipse.rse.services.files.IFileService#createFile(org.eclipse.core.runtime.IProgressMonitor, java.lang.String, java.lang.String)
|
||||||
*/
|
*/
|
||||||
public IHostFile createFile(IProgressMonitor monitor, String remoteParent, String fileName) {
|
public IHostFile createFile(IProgressMonitor monitor, String remoteParent, String fileName) throws SystemMessageException{
|
||||||
|
|
||||||
try {
|
try {
|
||||||
File tempFile = File.createTempFile("ftp", "temp");
|
File tempFile = File.createTempFile("ftp", "temp"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
tempFile.deleteOnExit();
|
tempFile.deleteOnExit();
|
||||||
upload(monitor, tempFile, remoteParent, fileName, true, null, null);
|
boolean success = upload(monitor, tempFile, remoteParent, fileName, true, null, null);
|
||||||
|
|
||||||
|
if(!success)
|
||||||
|
{
|
||||||
|
throw new Exception(getFTPClient().getReplyString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
e.printStackTrace();
|
throw new RemoteFileIOException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return getFile(monitor, remoteParent, fileName);
|
return getFile(monitor, remoteParent, fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
public boolean copy(IProgressMonitor monitor, String srcParent, String srcName, String tgtParent, String tgtName) throws SystemMessageException
|
||||||
/********************************************************
|
|
||||||
*
|
|
||||||
* The following APIs need to be implemented
|
|
||||||
*
|
|
||||||
********************************************************/
|
|
||||||
|
|
||||||
public boolean copy(IProgressMonitor monitor, String srcParent, String srcName, String tgtParent, String tgtName)
|
|
||||||
{
|
{
|
||||||
return false;
|
throw new RemoteFileIOException(new Exception("FTP copy not supported, use move instead")); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean copyBatch(IProgressMonitor monitor, String[] srcParents, String[] srcNames, String tgtParent) throws SystemMessageException
|
public boolean copyBatch(IProgressMonitor monitor, String[] srcParents, String[] srcNames, String tgtParent) throws SystemMessageException
|
||||||
{
|
{
|
||||||
return false;
|
boolean hasSucceeded = false;
|
||||||
|
|
||||||
|
for(int i=0; i<srcNames.length; i++)
|
||||||
|
{
|
||||||
|
hasSucceeded = copy(monitor, srcParents[i], srcNames[i], tgtParent, srcNames[i]);
|
||||||
|
if(!hasSucceeded)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return hasSucceeded;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initService(IProgressMonitor monitor)
|
public void initService(IProgressMonitor monitor)
|
||||||
|
@ -547,4 +748,120 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
private boolean listFiles(IProgressMonitor monitor) throws Exception
|
||||||
|
{
|
||||||
|
boolean result = true;
|
||||||
|
|
||||||
|
Job fetchJob = new Job("Listing files..."){ //$NON-NLS-1$
|
||||||
|
protected IStatus run(IProgressMonitor monitor) {
|
||||||
|
try {
|
||||||
|
_ftpFiles = _ftpClient.listFiles();
|
||||||
|
} catch (IOException e) {
|
||||||
|
return new Status(IStatus.ERROR, "org.eclipse.rse.services.files.ftp",IStatus.ERROR,e.getMessage(),e); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
return new Status(IStatus.OK,"org.eclipse.rse.services.files.ftp",IStatus.OK,"Success",null); //$NON-NLS-1$
|
||||||
|
}};
|
||||||
|
|
||||||
|
IStatus fetchResult = null;
|
||||||
|
|
||||||
|
if(monitor!=null)
|
||||||
|
{
|
||||||
|
if(!monitor.isCanceled())
|
||||||
|
fetchJob.schedule();
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fetchJob.schedule();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(monitor!=null)
|
||||||
|
{
|
||||||
|
while(!monitor.isCanceled() && (fetchResult = fetchJob.getResult())==null)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
Thread.sleep(500);
|
||||||
|
} catch (InterruptedException e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(monitor.isCanceled() && fetchJob.getState()!=Job.NONE)
|
||||||
|
{
|
||||||
|
fetchJob.cancel();
|
||||||
|
_ftpClient.completePendingCommand();
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fetchJob.join();
|
||||||
|
fetchResult = fetchJob.getResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(fetchResult==null)
|
||||||
|
{
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(fetchResult.getSeverity()==IStatus.ERROR)
|
||||||
|
{
|
||||||
|
throw new RemoteFileIOException(new Exception(fetchResult.getException()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private class MyProgressMonitor
|
||||||
|
{
|
||||||
|
private IProgressMonitor fMonitor;
|
||||||
|
private double fWorkPercentFactor;
|
||||||
|
private Long fMaxWorkKB;
|
||||||
|
private long fWorkToDate;
|
||||||
|
|
||||||
|
public MyProgressMonitor(IProgressMonitor monitor) {
|
||||||
|
fMonitor = monitor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init(int op, String src, String dest, long max){
|
||||||
|
fWorkPercentFactor = 1.0 / max;
|
||||||
|
fMaxWorkKB = new Long(max / 1024L);
|
||||||
|
fWorkToDate = 0;
|
||||||
|
String srcFile = new Path(src).lastSegment();
|
||||||
|
String desc = srcFile;
|
||||||
|
fMonitor.beginTask(desc, (int)max);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init(String label, int max){
|
||||||
|
fMonitor.beginTask(label, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean count(long count){
|
||||||
|
fWorkToDate += count;
|
||||||
|
Long workToDateKB = new Long(fWorkToDate / 1024L);
|
||||||
|
Double workPercent = new Double(fWorkPercentFactor * fWorkToDate);
|
||||||
|
String subDesc = MessageFormat.format(
|
||||||
|
"{0,number,integer} KB of {1,number,integer} KB complete ({2,number,percent})", //$NON-NLS-1$
|
||||||
|
new Object[] {
|
||||||
|
workToDateKB, fMaxWorkKB, workPercent
|
||||||
|
});
|
||||||
|
fMonitor.subTask(subDesc);
|
||||||
|
fMonitor.worked((int)count);
|
||||||
|
return !(fMonitor.isCanceled());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void worked(int work){
|
||||||
|
fMonitor.worked(work);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void end(){
|
||||||
|
fMonitor.done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue