From ac20528b77c02504904c3fd840a1f16dd9747604 Mon Sep 17 00:00:00 2001 From: David McKnight Date: Fri, 2 Nov 2007 19:02:13 +0000 Subject: [PATCH] [162195] new APIs for upload multi and download multi --- .../dstore/files/DStoreFileService.java | 346 +++++++++++++++--- .../dstore/util/DownloadListener.java | 17 +- .../services/files/AbstractFileService.java | 46 ++- .../rse/services/files/IFileService.java | 40 +- .../FileServiceSubSystem.java | 198 ++++++++-- .../core/subsystems/IRemoteFileSubSystem.java | 67 ++++ 6 files changed, 638 insertions(+), 76 deletions(-) diff --git a/rse/plugins/org.eclipse.rse.services.dstore/src/org/eclipse/rse/internal/services/dstore/files/DStoreFileService.java b/rse/plugins/org.eclipse.rse.services.dstore/src/org/eclipse/rse/internal/services/dstore/files/DStoreFileService.java index 9a66c9d6094..76c240c9a5f 100644 --- a/rse/plugins/org.eclipse.rse.services.dstore/src/org/eclipse/rse/internal/services/dstore/files/DStoreFileService.java +++ b/rse/plugins/org.eclipse.rse.services.dstore/src/org/eclipse/rse/internal/services/dstore/files/DStoreFileService.java @@ -22,6 +22,7 @@ * Xuan Chen (IBM) - [190824] Incorrect result for DStore#getSeparator() function when parent is "/" * David McKnight (IBM) - [207095] check for null datastore * David McKnight (IBM) - [207178] changing list APIs for file service and subsystems + * David McKnight (IBM) - [162195] new APIs for upload multi and download multi ********************************************************************************/ package org.eclipse.rse.internal.services.dstore.files; @@ -627,43 +628,22 @@ public class DStoreFileService extends AbstractDStoreService implements IFileSer public boolean download(String remoteParent, String remoteFile, File localFile, boolean isBinary, String encoding, IProgressMonitor monitor) throws SystemMessageException { + DataStore ds = getDataStore(); DataElement universaltemp = getMinerElement(); - - if (!localFile.exists()) - { - File parentDir = localFile.getParentFile(); - parentDir.mkdirs(); - } - - try - { - if (localFile.exists()) - localFile.delete(); - localFile.createNewFile(); - } - catch (IOException e) - { -// UniversalSystemPlugin.logError(CLASSNAME + "." + "copy: " + "error creating local file " + destination, e); -// throw new RemoteFileIOException(e); - return false; - } - -/* int mode; - - if (isBinary) - { - mode = IUniversalDataStoreConstants.BINARY_MODE; - } - else - { - mode = IUniversalDataStoreConstants.TEXT_MODE; - }*/ - + // just download as binary since we do not have to convert to UTF-8 anyway // the miner does a binary download anyway int mode = IUniversalDataStoreConstants.BINARY_MODE; - DataStore ds = getDataStore(); + if (!makeSureLocalExists(localFile)) + { + return false; + } + + + + + String remotePath = remoteParent + getSeparator(remoteParent) + remoteFile; DataElement de = getElementFor(remotePath); @@ -701,20 +681,23 @@ public class DStoreFileService extends AbstractDStoreService implements IFileSer try { DownloadListener dlistener = new DownloadListener(status, localFile, remotePath, fileLength, monitor); - try + if (!dlistener.isDone()) { - dlistener.waitForUpdate(); - } - catch (InterruptedException e) - { - // cancel monitor if it's still not canceled - if (monitor != null && !monitor.isCanceled()) + try { - monitor.setCanceled(true); + dlistener.waitForUpdate(); + } + catch (InterruptedException e) + { + // cancel monitor if it's still not canceled + if (monitor != null && !monitor.isCanceled()) + { + monitor.setCanceled(true); + } + + //InterruptedException is used to report user cancellation, so no need to log + //This should be reviewed (use OperationCanceledException) with bug #190750 } - - //InterruptedException is used to report user cancellation, so no need to log - //This should be reviewed (use OperationCanceledException) with bug #190750 } } catch (Exception e) @@ -784,6 +767,255 @@ public class DStoreFileService extends AbstractDStoreService implements IFileSer return true; } + private boolean makeSureLocalExists(File localFile) + { + if (!localFile.exists()) + { + File parentDir = localFile.getParentFile(); + parentDir.mkdirs(); + } + + try + { + if (localFile.exists()) + localFile.delete(); + localFile.createNewFile(); + } + catch (IOException e) + { + return false; + } + return true; + } + + /** + * Default implementation - just iterate through each file + */ + public boolean downloadMulti(String[] remoteParents, String[] remoteFiles, + File[] localFiles, boolean[] isBinaries, String[] hostEncodings, + IProgressMonitor monitor) throws SystemMessageException + { + boolean result = true; + + + List downloadListeners = new ArrayList(); + List remoteElements = new ArrayList(); + + DataStore ds = getDataStore(); + DataElement universaltemp = getMinerElement(); + + // get the subjects + String[] paths = getPathsFor(remoteParents, remoteFiles); + DataElement[] des = getElementsFor(paths); + + DataElement queryCmd = null; + DataElement bufferSizeElement = null; + + // if any elements are unresolved, do a query on them + List unresolved = new ArrayList(); + for (int d = 0; d < des.length; d++) + { + DataElement de = des[d]; + if (de.getType().equals(IUniversalDataStoreConstants.UNIVERSAL_FILTER_DESCRIPTOR)) + { + unresolved.add(de); + } + } + // query the unresolved + if (!unresolved.isEmpty()) + { + String[] parents = new String[unresolved.size()]; + String[] names = new String[unresolved.size()]; + for (int u = 0; u < unresolved.size(); u++) + { + DataElement de = (DataElement)unresolved.get(u); + parents[u] = de.getValue(); + names[u] = de.getName(); + } + + // I think the de should be reused since getElement should find it? + getFileMulti(parents, names, monitor); + } + + + // kick off all downloads + int mode = IUniversalDataStoreConstants.BINARY_MODE; + + for (int i = 0; i < des.length && result == true; i++) + { + DataElement de = des[i]; + String remotePath = paths[i]; + + File localFile = localFiles[i]; + String hostEncoding = hostEncodings[i]; + + if (!makeSureLocalExists(localFile)) + { + return false; + } + + long fileLength = DStoreHostFile.getFileLength(de.getSource()); + if (monitor != null) + { + monitor.beginTask(remotePath, (int)fileLength); + } + + DataElement remoteElement = ds.createObject(universaltemp, de.getType(), remotePath, String.valueOf(mode)); + DataElement localElement = ds.createObject(universaltemp, de.getType(), localFile.getAbsolutePath(), hostEncoding); + + // only do this once + if (bufferSizeElement == null) + bufferSizeElement = ds.createObject(universaltemp, "buffer_size", "" + getBufferDownloadSize(), ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + // only do this once + if (queryCmd == null) + queryCmd = getCommandDescriptor(de,IUniversalDataStoreConstants.C_DOWNLOAD_FILE); + + + ArrayList argList = new ArrayList(); + argList.add(remoteElement); + argList.add(localElement); + argList.add(bufferSizeElement); + + DataElement subject = ds.createObject(universaltemp, de.getType(), remotePath, String.valueOf(mode)); + + DataElement status = ds.command(queryCmd, argList, subject); + if (status == null) + { + System.out.println("no download descriptor for "+remoteElement); //$NON-NLS-1$ + return false; + } + + DownloadListener dlistener = new DownloadListener(status, localFile, remotePath, fileLength, monitor); + downloadListeners.add(dlistener); + remoteElements.add(remoteElement); + } + + // all downloads have been started + // now wait for each to complete + for (int j = 0; j < downloadListeners.size(); j++) + { + DownloadListener dlistener = (DownloadListener)downloadListeners.get(j); + try + { + if (!dlistener.isDone()) + { + try + { + dlistener.waitForUpdate(); + } + catch (InterruptedException e) + { + // cancel monitor if it's still not canceled + if (monitor != null && !monitor.isCanceled()) + { + monitor.setCanceled(true); + } + + //InterruptedException is used to report user cancellation, so no need to log + //This should be reviewed (use OperationCanceledException) with bug #190750 + } + } + } + catch (Exception e) + { + return false; + } + + // now wait till we have all the bytes local + File localFile = localFiles[j]; + long localBytes = localFile.length(); + long lastLocalBytes = 0; + long fileLength = dlistener.getTotalLength(); + while (localBytes < fileLength && (monitor == null || !monitor.isCanceled()) && lastLocalBytes != localBytes) + { + try + { + lastLocalBytes= localBytes; + Thread.sleep(100); + localBytes = localFile.length(); + + } + catch (Exception e) + { + } + } + + DataElement remoteElement = (DataElement)remoteElements.get(j); + List resultList = remoteElement.getNestedData(); + DataElement resultChild = null; + + for (int i = 0; i < resultList.size(); i++) + { + + resultChild = (DataElement) resultList.get(i); + + if (resultChild.getType().equals(IUniversalDataStoreConstants.DOWNLOAD_RESULT_SUCCESS_TYPE)) + { + result = true; + } + else if (resultChild.getType().equals(IUniversalDataStoreConstants.DOWNLOAD_RESULT_FILE_NOT_FOUND_EXCEPTION)) + { + localFile.delete(); + SystemMessage msg = getMessage("RSEF1001").makeSubstitution(IUniversalDataStoreConstants.DOWNLOAD_RESULT_FILE_NOT_FOUND_EXCEPTION); //$NON-NLS-1$ + throw new SystemMessageException(msg); + } + else if (resultChild.getType().equals(IUniversalDataStoreConstants.DOWNLOAD_RESULT_UNSUPPORTED_ENCODING_EXCEPTION)) + { + //SystemMessage msg = getMessage(); + //throw new SystemMessageException(msg); + //UnsupportedEncodingException e = new UnsupportedEncodingException(resultChild.getName()); + //UniversalSystemPlugin.logError(CLASSNAME + "." + "copy: " + "error reading file " + remotePath, e); + //throw new RemoteFileIOException(e); + result = false; + } + + else if (resultChild.getType().equals(IUniversalDataStoreConstants.DOWNLOAD_RESULT_IO_EXCEPTION)) + { + localFile.delete(); + SystemMessage msg = getMessage("RSEF1001").makeSubstitution(IUniversalDataStoreConstants.DOWNLOAD_RESULT_IO_EXCEPTION); //$NON-NLS-1$ + throw new SystemMessageException(msg); + //IOException e = new IOException(resultChild.getName()); + //UniversalSystemPlugin.logError(CLASSNAME + "." + "copy: " + "error reading file " + remotePath, e); + //throw new RemoteFileIOException(e); + } + else + { + result = false; + } + } + + if (monitor != null) + { + //monitor.done(); + } + } + return result; + } + + /** + * Default implementation - just iterate through each file + */ + public boolean uploadMulti(File[] localFiles, String[] remoteParents, + String[] remoteFiles, boolean[] isBinaries, String[] srcEncodings, + String[] hostEncodings, IProgressMonitor monitor) + throws SystemMessageException + { + boolean result = true; + for (int i = 0; i < localFiles.length && result == true; i++) + { + File localFile = localFiles[i]; + String remoteParent = remoteParents[i]; + String remoteFile = remoteFiles[i]; + + boolean isBinary = isBinaries[i]; + String srcEncoding = srcEncodings[i]; + String hostEncoding = hostEncodings[i]; + result = upload(localFile, remoteParent, remoteFile, isBinary, srcEncoding, hostEncoding, monitor); + } + return result; + } + private DataElement getSubjectFor(String remoteParent, String name) { DataElement de = null; @@ -1358,6 +1590,34 @@ public class DStoreFileService extends AbstractDStoreService implements IFileSer return fetchMulti(remoteParents, fileFilters, queryString, monitor); } + protected String[] getPathsFor(String[] remoteParents, String[] remoteFiles) + { + String[] results = new String[remoteParents.length]; + String sep = null; + for (int i = 0; i < remoteParents.length; i++) + { + String remoteParent = remoteParents[i]; + String remoteFile = remoteFiles[i]; + if (sep == null) + { + sep = getSeparator(remoteParent); + } + + results[i] = remoteParent + sep + remoteFile; + } + return results; + } + + + protected DataElement[] getElementsFor(String[] paths) + { + DataElement[] results = new DataElement[paths.length]; + for (int i = 0; i < paths.length; i++) + { + results[i] = getElementFor(paths[i]); + } + return results; + } protected DataElement getElementFor(String path) { diff --git a/rse/plugins/org.eclipse.rse.services.dstore/src/org/eclipse/rse/services/dstore/util/DownloadListener.java b/rse/plugins/org.eclipse.rse.services.dstore/src/org/eclipse/rse/services/dstore/util/DownloadListener.java index 5f51fad6d8a..64c3431b49b 100644 --- a/rse/plugins/org.eclipse.rse.services.dstore/src/org/eclipse/rse/services/dstore/util/DownloadListener.java +++ b/rse/plugins/org.eclipse.rse.services.dstore/src/org/eclipse/rse/services/dstore/util/DownloadListener.java @@ -11,7 +11,8 @@ * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley. * * Contributors: - * Martin Oberhuber (Wind River) - [186128][refactoring] Move IProgressMonitor last in public base classes + * Martin Oberhuber (Wind River) - [186128][refactoring] Move IProgressMonitor last in public base classes + * David McKnight (IBM) - [162195] new APIs for upload multi and download multi ********************************************************************************/ package org.eclipse.rse.services.dstore.util; @@ -78,13 +79,23 @@ public class DownloadListener implements IDomainListener { updateDownloadState(); setDone(true); - } - + } } + + public long getTotalLength() + { + return _totalLength; + } + public boolean isCancelled() { return _isCancelled; } + + public boolean isDone() + { + return _isDone; + } public DataElement getStatus() { diff --git a/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/files/AbstractFileService.java b/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/files/AbstractFileService.java index 7cbfb18f7dc..e17e80353fe 100644 --- a/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/files/AbstractFileService.java +++ b/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/files/AbstractFileService.java @@ -13,10 +13,12 @@ * Contributors: * Martin Oberhuber (Wind River) - [186128] Move IProgressMonitor last in all API * David McKnight (IBM) - [207178] changing list APIs for file service and subsystems + * David McKnight (IBM) - [162195] new APIs for upload multi and download multi ********************************************************************************/ package org.eclipse.rse.services.files; +import java.io.File; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; @@ -30,7 +32,6 @@ import org.eclipse.rse.services.clientserver.messages.SystemMessageException; public abstract class AbstractFileService implements IFileService { - protected abstract IHostFile[] internalFetch(String parentPath, String fileFilter, int fileType, IProgressMonitor monitor) throws SystemMessageException; public IHostFile[] getFileMulti(String remoteParents[], String names[], IProgressMonitor monitor) @@ -114,6 +115,49 @@ public abstract class AbstractFileService implements IFileService return ok; } + /** + * Default implementation - just iterate through each file + */ + public boolean downloadMulti(String[] remoteParents, String[] remoteFiles, + File[] localFiles, boolean[] isBinaries, String[] hostEncodings, + IProgressMonitor monitor) throws SystemMessageException + { + boolean result = true; + for (int i = 0; i < remoteParents.length && result == true; i++) + { + String remoteParent = remoteParents[i]; + String remoteFile = remoteFiles[i]; + File localFile = localFiles[i]; + boolean isBinary = isBinaries[i]; + String hostEncoding = hostEncodings[i]; + result = download(remoteParent, remoteFile, localFile, isBinary, hostEncoding, monitor); + } + return result; + } + + /** + * Default implementation - just iterate through each file + */ + public boolean uploadMulti(File[] localFiles, String[] remoteParents, + String[] remoteFiles, boolean[] isBinaries, String[] srcEncodings, + String[] hostEncodings, IProgressMonitor monitor) + throws SystemMessageException + { + boolean result = true; + for (int i = 0; i < localFiles.length && result == true; i++) + { + File localFile = localFiles[i]; + String remoteParent = remoteParents[i]; + String remoteFile = remoteFiles[i]; + + boolean isBinary = isBinaries[i]; + String srcEncoding = srcEncodings[i]; + String hostEncoding = hostEncodings[i]; + result = upload(localFile, remoteParent, remoteFile, isBinary, srcEncoding, hostEncoding, monitor); + } + return result; + } + /** * Returns the local platform encoding by default. Subclasses should override to return the actual remote encoding. * @see org.eclipse.rse.services.files.IFileService#getEncoding(org.eclipse.core.runtime.IProgressMonitor) diff --git a/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/files/IFileService.java b/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/files/IFileService.java index 8fcadfa64b3..7d2556fbfa5 100644 --- a/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/files/IFileService.java +++ b/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/services/files/IFileService.java @@ -16,6 +16,7 @@ * Martin Oberhuber (Wind River) - [199548] Avoid touching files on setReadOnly() if unnecessary * Martin Oberhuber (Wind River) - [204710] Update Javadoc to mention that getUserHome() may return null * David McKnight (IBM) - [207178] changing list APIs for file service and subsystems + * David McKnight (IBM) - [162195] new APIs for upload multi and download multi ********************************************************************************/ package org.eclipse.rse.services.files; @@ -77,10 +78,29 @@ public interface IFileService extends IService */ public boolean upload(File localFile, String remoteParent, String remoteFile, boolean isBinary, String srcEncoding, String hostEncoding, IProgressMonitor monitor) throws SystemMessageException; + + /** + * Copy files to the remote file system. The remote target is denoted by + * strings representing the parents and strings representing the files. + * @param localFiles - real files in the local file system. + * @param remoteParents - strings designating the parent folders of the target for the files. + * @param remoteFiles - strings designating the names of the files to be written on the remote system. + * @param isBinary - indicates whether the files are text or binary + * @param srcEncodings - the src encodings of the files (if text) + * @param hostEncodings - the tgt encodings of the files (if text) + * @param monitor the monitor for this potentially long running operation + * @return true if the files were uploaded + * @throws SystemMessageException if an error occurs. + * Typically this would be one of those in the + * {@link RemoteFileException} family. + */ + public boolean uploadMulti(File[] localFiles, String[] remoteParents, String[] remoteFiles, boolean[] isBinary, String[] srcEncodings, String[] hostEncodings, IProgressMonitor monitor) throws SystemMessageException; + + /** * Copy a file from the remote file system to the local system. * @param remoteParent - a String designating the remote parent. - * @param remoteFile - a String designating the remote file residing in the parent. + * @param remoteFile - a String designating the remote file residing in the parents. * @param localFile - The file that is to be written. If the file exists it is * overwritten. * @param isBinary - indicates whether the file is text on binary @@ -93,6 +113,24 @@ public interface IFileService extends IService */ public boolean download(String remoteParent, String remoteFile, File localFile, boolean isBinary, String hostEncoding, IProgressMonitor monitor) throws SystemMessageException; + /** + * Copy files from the remote file system to the local system. + * @param remoteParents - string designating the remote parents. + * @param remoteFiles - Strings designating the remote files residing in the parents. + * @param localFiles - The files that are to be written. If the files exists they are + * overwritten. + * @param isBinary - indicates whether the files are text on binary + * @param hostEncodings - the encodings on the host (if text) + * @param monitor the monitor for this potentially long running operation + * @return true if the files were copied from the remote system. + * @throws SystemMessageException if an error occurs. + * Typically this would be one of those in the + * {@link RemoteFileException} family. + */ + public boolean downloadMulti(String[] remoteParents, String[] remoteFiles, File[] localFiles, boolean[] isBinary, String[] hostEncodings, IProgressMonitor monitor) throws SystemMessageException; + + + /** * @param remoteParent * @param name diff --git a/rse/plugins/org.eclipse.rse.subsystems.files.core/src/org/eclipse/rse/subsystems/files/core/servicesubsystem/FileServiceSubSystem.java b/rse/plugins/org.eclipse.rse.subsystems.files.core/src/org/eclipse/rse/subsystems/files/core/servicesubsystem/FileServiceSubSystem.java index 4b46c00cf54..964a80b2d63 100644 --- a/rse/plugins/org.eclipse.rse.subsystems.files.core/src/org/eclipse/rse/subsystems/files/core/servicesubsystem/FileServiceSubSystem.java +++ b/rse/plugins/org.eclipse.rse.subsystems.files.core/src/org/eclipse/rse/subsystems/files/core/servicesubsystem/FileServiceSubSystem.java @@ -22,6 +22,7 @@ * David McKnight (IBM) - [207095] Implicit connect on getRemoteFileObject * David McKnight (IBM) - [207100] fire event after upload and download * David McKnight (IBM) - [207178] changing list APIs for file service and subsystems + * David McKnight (IBM) - [162195] new APIs for upload multi and download multi *******************************************************************************/ package org.eclipse.rse.subsystems.files.core.servicesubsystem; @@ -469,34 +470,6 @@ public final class FileServiceSubSystem extends RemoteFileSubSystem implements I return results; } - - - /* - * (non-Javadoc) - * @see org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFileSubSystem#download(org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFile, java.lang.String, java.lang.String, org.eclipse.core.runtime.IProgressMonitor) - */ - public void download(IRemoteFile file, String localpath, String encoding, IProgressMonitor monitor) throws SystemMessageException - { - //Fixing bug 158534. TODO remove when bug 162688 is fixed. - if (monitor==null) { - monitor = new NullProgressMonitor(); - } - String parentPath = file.getParentPath(); - File localFile = new File(localpath); - getFileService().download(parentPath, file.getName(), localFile, isBinary(file), file.getEncoding(), monitor); - if (monitor.isCanceled()) - { - localFile.delete(); - } - else - { - // notify that the file was downloaded - ISystemRegistry sr = RSECorePlugin.getTheSystemRegistry(); - sr.fireEvent(new SystemRemoteChangeEvent(ISystemRemoteChangeEvents.SYSTEM_REMOTE_RESOURCE_DOWNLOADED, file, file.getParentRemoteFile(), this)); - - } - } - protected boolean isBinary(String localEncoding, String hostEncoding, String remotePath) { return SystemFileTransferModeRegistry.getInstance().isBinary(remotePath) || @@ -562,7 +535,175 @@ public final class FileServiceSubSystem extends RemoteFileSubSystem implements I ISystemRegistry sr = RSECorePlugin.getTheSystemRegistry(); sr.fireEvent(new SystemRemoteChangeEvent(ISystemRemoteChangeEvents.SYSTEM_REMOTE_RESOURCE_UPLOADED, destination, destination.getParentRemoteFile(), this)); } + + public void uploadMulti(String[] sources, String[] srcEncodings, + String[] remotePaths, String[] rmtEncodings, + IProgressMonitor monitor) throws SystemMessageException + { + // create list of stuff + File[] sourceFiles = new File[sources.length]; + boolean[] isBinaries = new boolean[sources.length]; + String[] remoteParentPaths = new String[sources.length]; + String[] remoteFileNames = new String[sources.length]; + + // gather info + for (int i = 0; i < sources.length; i++) + { + sourceFiles[i] = new File(sources[i]); + String remotePath = remotePaths[i]; + int slashIndex = remotePath.lastIndexOf(getSeparator()); + if (slashIndex > -1) { + remoteParentPaths[i] = remotePath.substring(0, slashIndex); + remoteFileNames[i] = remotePath.substring(slashIndex + 1, remotePath.length()); + isBinaries[i] = isBinary(srcEncodings[i], rmtEncodings[i], remotePath); + if (ArchiveHandlerManager.isVirtual(remotePath)) + { + AbsoluteVirtualPath avp = new AbsoluteVirtualPath(remotePath); + remoteParentPaths[i] = avp.getPath(); + remoteFileNames[i] = avp.getName(); + } + } + else // unexpected + { + // throw an exception here + //SystemMessage msg = RSEUIPlugin.getPluginMessage("RSEF5003").makeSubstitution(remoteFileNames[i], getHostName()); //$NON-NLS-1$ + //throw new SystemMessageException(msg); + } + } + + // upload + getFileService().uploadMulti(sourceFiles, remoteParentPaths, remoteFileNames, isBinaries, srcEncodings, rmtEncodings, monitor); + + // notification + // notify that the file was uploaded + ISystemRegistry sr = RSECorePlugin.getTheSystemRegistry(); + for (int j = 0; j < remotePaths.length; j++) + { + String remotePath = remotePaths[j]; + String remoteParentPath = remoteParentPaths[j]; + sr.fireEvent(new SystemRemoteChangeEvent(ISystemRemoteChangeEvents.SYSTEM_REMOTE_RESOURCE_UPLOADED, remotePath, remoteParentPath, this)); + } + } + public void uploadMulti(String[] sources, IRemoteFile[] destinations, + String[] encodings, IProgressMonitor monitor) + throws SystemMessageException +{ + // create list of stuff + File[] sourceFiles = new File[sources.length]; + boolean[] isBinaries = new boolean[sources.length]; + String[] remoteParentPaths = new String[sources.length]; + String[] remoteFileNames = new String[sources.length]; + String[] hostEncodings = new String[sources.length]; + + // gather info + for (int i = 0; i < sources.length; i++) + { + sourceFiles[i] = new File(sources[i]); + IRemoteFile destination = destinations[i]; + + remoteParentPaths[i] = destination.getAbsolutePath(); + remoteFileNames[i] = destination.getName(); + + if (!destination.canWrite()) + { + SystemMessage msg = RSEUIPlugin.getPluginMessage("RSEF5003").makeSubstitution(remoteFileNames[i], getHostName()); //$NON-NLS-1$ + throw new SystemMessageException(msg); + } + + hostEncodings[i] = destination.getEncoding(); + isBinaries[i] = isBinary(encodings[i], hostEncodings[i], destination.getAbsolutePath()); + + } + + // upload + getFileService().uploadMulti(sourceFiles, remoteParentPaths, remoteFileNames, isBinaries, encodings, hostEncodings, monitor); + + // notification + // notify that the file was uploaded + ISystemRegistry sr = RSECorePlugin.getTheSystemRegistry(); + for (int j = 0; j < destinations.length; j++) + { + IRemoteFile destination = destinations[j]; + sr.fireEvent(new SystemRemoteChangeEvent(ISystemRemoteChangeEvents.SYSTEM_REMOTE_RESOURCE_UPLOADED, destination, destination.getParentRemoteFile(), this)); + } + + } + + /* + * (non-Javadoc) + * @see org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFileSubSystem#download(org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFile, java.lang.String, java.lang.String, org.eclipse.core.runtime.IProgressMonitor) + */ + public void download(IRemoteFile file, String localpath, String encoding, IProgressMonitor monitor) throws SystemMessageException + { + //Fixing bug 158534. TODO remove when bug 162688 is fixed. + if (monitor==null) { + monitor = new NullProgressMonitor(); + } + String parentPath = file.getParentPath(); + File localFile = new File(localpath); + + // FIXME why are we using file.getEncoding() instead of the specified encoding? + getFileService().download(parentPath, file.getName(), localFile, isBinary(file), file.getEncoding(), monitor); + if (monitor.isCanceled()) + { + localFile.delete(); + } + else + { + // notify that the file was downloaded + ISystemRegistry sr = RSECorePlugin.getTheSystemRegistry(); + sr.fireEvent(new SystemRemoteChangeEvent(ISystemRemoteChangeEvents.SYSTEM_REMOTE_RESOURCE_DOWNLOADED, file, file.getParentRemoteFile(), this)); + + } + } + + public void downloadMulti(IRemoteFile[] sources, String[] destinations, + String[] encodings, IProgressMonitor monitor) + throws SystemMessageException + { + //Fixing bug 158534. TODO remove when bug 162688 is fixed. + if (monitor==null) { + monitor = new NullProgressMonitor(); + } + + // get arrays of parent paths and local files + String[] parentPaths = new String[sources.length]; + String[] names = new String[sources.length]; + boolean[] isBinaries = new boolean[sources.length]; + File[] localFiles = new File[sources.length]; + + for (int i = 0; i < sources.length; i++) + { + IRemoteFile file = sources[i]; + parentPaths[i] = file.getParentPath(); + names[i] = file.getName(); + isBinaries[i] = isBinary(file); + localFiles[i] = new File(destinations[i]); + } + + getFileService().downloadMulti(parentPaths, names, localFiles, isBinaries, encodings, monitor); + if (monitor.isCanceled()) + { + for (int d = 0; d < localFiles.length; d++) + { + File f = localFiles[d]; + f.delete(); + } + } + else + { + // notify that the file was downloaded + ISystemRegistry sr = RSECorePlugin.getTheSystemRegistry(); + + for (int r = 0; r < sources.length; r++) + { + IRemoteFile file = sources[r]; + sr.fireEvent(new SystemRemoteChangeEvent(ISystemRemoteChangeEvents.SYSTEM_REMOTE_RESOURCE_DOWNLOADED, file, file.getParentRemoteFile(), this)); + } + } + } + /* * (non-Javadoc) * @see org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFileSubSystem#copy(org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFile, org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFile, java.lang.String, org.eclipse.core.runtime.IProgressMonitor) @@ -985,4 +1126,5 @@ public final class FileServiceSubSystem extends RemoteFileSubSystem implements I { return getFileService().getFilesAndFolders(parentPath, fileNameFilter, monitor); } + } \ No newline at end of file diff --git a/rse/plugins/org.eclipse.rse.subsystems.files.core/src/org/eclipse/rse/subsystems/files/core/subsystems/IRemoteFileSubSystem.java b/rse/plugins/org.eclipse.rse.subsystems.files.core/src/org/eclipse/rse/subsystems/files/core/subsystems/IRemoteFileSubSystem.java index db145a784d3..1a95155b380 100644 --- a/rse/plugins/org.eclipse.rse.subsystems.files.core/src/org/eclipse/rse/subsystems/files/core/subsystems/IRemoteFileSubSystem.java +++ b/rse/plugins/org.eclipse.rse.subsystems.files.core/src/org/eclipse/rse/subsystems/files/core/subsystems/IRemoteFileSubSystem.java @@ -16,6 +16,7 @@ * Martin Oberhuber (Wind River) - [186128] Move IProgressMonitor last in all API * Martin Oberhuber (Wind River) - [183824] Forward SystemMessageException from IRemoteFileSubsystem * David McKnight (IBM) - [207178] changing list APIs for file service and subsystems + * David McKnight (IBM) - [162195] new APIs for upload multi and download multi *******************************************************************************/ package org.eclipse.rse.subsystems.files.core.subsystems; @@ -454,6 +455,30 @@ public interface IRemoteFileSubSystem extends ISubSystem { */ public void download(IRemoteFile source, String destination, String encoding, IProgressMonitor monitor) throws SystemMessageException; + + /** + * Get the remote files and save them locally. + * + * The files are saved in the encodings specified, with two exceptions: + * + * @param sources remote files that represent the files to be obtained + * @param destinations the absolute paths of the local files + * @param encodings the encodings of the local files + * @param monitor the progress monitor + * @throws SystemMessageException if an error occurs. + * Typically this would be one of those in the + * {@link RemoteFileException} family. + */ + public void downloadMulti(IRemoteFile[] sources, String[] destinations, String[] encoding, IProgressMonitor monitor) throws SystemMessageException; + + + + /** * Put the local copy of the remote file back to the remote location. * @@ -496,6 +521,48 @@ public interface IRemoteFileSubSystem extends ISubSystem { */ public void upload(String source, String srcEncoding, String remotePath, String rmtEncoding, IProgressMonitor monitor) throws SystemMessageException; + /** + * Put the local copies of the remote files to the remote locations. + * + * The files are assumed to be in the encodings specified, with + * two exceptions: + * + * @param sources the absolute paths of the local copies + * @param destinations remote files that represent the files on the server + * @param encodings the encodings of the local copies + * @param monitor the progress monitor + * @throws SystemMessageException if an error occurs. + * Typically this would be one of those in the + * {@link RemoteFileException} family. + */ + public void uploadMulti(String[] sources, IRemoteFile[] destinations, String[] encodings, IProgressMonitor monitor) throws SystemMessageException; + + /** + * Put the local copies of the remote files to the remote locations. + * + * The files are assumed to be in the encodings of the local operating system, + * with two exceptions: + * + * @param sources the absolute paths of the local copies + * @param srcEncodings the encodings of the local copies + * @param remotePaths remote files that represents the files on the server + * @param rmtEncodings the encodings of the remote files. + * @throws SystemMessageException if an error occurs. + * Typically this would be one of those in the + * {@link RemoteFileException} family. + */ + public void uploadMulti(String sources[], String[] srcEncodings, String[] remotePaths, String[] rmtEncodings, IProgressMonitor monitor) throws SystemMessageException; + /** * Returns a language utility factory associated with this subsystem. * @return the language utility factory associated with this subsystem.