blob: 1c264f019b9728d7dda077aeac9704dd518481e9 [file] [log] [blame]
/******************************************************************************
* Copyright (c) 2006 IBM Corporation.
* 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:
* IBM Corporation - Initial Implementation
*
*****************************************************************************/
package org.eclipse.ptp.remotetools.environment.launcher.internal;
import java.io.File;
import java.io.PrintWriter;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileInfo;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.filesystem.IFileSystem;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.osgi.util.NLS;
import org.eclipse.ptp.remotetools.core.IRemoteCopyTools;
import org.eclipse.ptp.remotetools.core.IRemoteExecutionManager;
import org.eclipse.ptp.remotetools.core.IRemoteFileEnumeration;
import org.eclipse.ptp.remotetools.core.IRemoteFileTools;
import org.eclipse.ptp.remotetools.core.IRemoteItem;
import org.eclipse.ptp.remotetools.core.IRemoteStatusTools;
import org.eclipse.ptp.remotetools.environment.launcher.core.LinuxPath;
import org.eclipse.ptp.remotetools.environment.launcher.data.DownloadRule;
import org.eclipse.ptp.remotetools.environment.launcher.data.ExecutionConfiguration;
import org.eclipse.ptp.remotetools.environment.launcher.data.OverwritePolicies;
import org.eclipse.ptp.remotetools.exception.CancelException;
import org.eclipse.ptp.remotetools.exception.RemoteConnectionException;
import org.eclipse.ptp.remotetools.exception.RemoteOperationException;
public class DownloadRuleAction implements IRuleAction {
private ILaunchProcessCallback process;
private DownloadRule rule;
private ExecutionConfiguration configuration;
private PrintWriter outputWriter;
private PrintWriter errorWriter;
private IRemoteExecutionManager manager;
public DownloadRuleAction(ILaunchProcessCallback process, DownloadRule rule) {
super();
this.process = process;
this.rule = rule;
configuration = process.getConfiguration();
outputWriter = process.getOutputWriter();
errorWriter = process.getErrorWriter();
manager = process.getExecutionManager();
}
public void run() throws CoreException, CancelException, RemoteConnectionException {
Assert.isNotNull(process);
Assert.isNotNull(rule);
Assert.isNotNull(configuration);
Assert.isNotNull(outputWriter);
Assert.isNotNull(errorWriter);
Assert.isNotNull(manager);
/*
* If overwrite policy depends on time, then get remote clock skew.
*/
long clockSkew = 0;
if (rule.getOverwritePolicy() == OverwritePolicies.NEWER) {
IRemoteStatusTools statusTools = manager.getRemoteStatusTools();
long localTime;
long remoteTime;
try {
localTime = System.currentTimeMillis();
remoteTime = statusTools.getTime();
clockSkew = localTime -remoteTime;
} catch (RemoteOperationException e) {
errorWriter.println(NLS.bind(Messages.DownloadRuleAction_FailedCalculateClockDifference, e.getMessage()));
errorWriter.println(Messages.DownloadRuleAction_FailedCalculateClockDifference2);
clockSkew = 0;
}
if (clockSkew < -15000) {
errorWriter.println(Messages.DownloadRuleAction_WarningClockForward);
} else if (clockSkew > 15000) {
errorWriter.println(Messages.DownloadRuleAction_WarningClockBackward);
}
}
/*
* Determine local path. Make it absolute. Create if necessary
*/
IPath localPath = new Path(rule.getLocalDirectory());
if (! localPath.isAbsolute()) {
IPath workspace = ResourcesPlugin.getWorkspace().getRoot().getLocation();
localPath = workspace.append(localPath);
}
Assert.isTrue(localPath.isAbsolute(), "localPath.isAbsolute()"); //$NON-NLS-1$
File localDir = localPath.toFile();
if (! localDir.exists()) {
if (! localDir.mkdirs()) {
errorWriter.println(NLS.bind(Messages.DownloadRuleAction_FailedCreateLocalDirectory, localPath.toString()));
return;
}
} else if (! localDir.isDirectory()) {
errorWriter.println(NLS.bind(Messages.DownloadRuleAction_FailedLocalDiretoryIsNotDirectory, localPath.toString()));
return;
}
/*
* Determine list of remote paths. Make them absolute.
*/
IPath remotePaths [] = rule.getRemoteFilesAsPathArray();
IPath remoteWorkingPath = configuration.getRemoteDirectoryPath();
for (int i = 0; i < remotePaths.length; i++) {
IPath remotePath = remotePaths[i];
if (! remotePath.isAbsolute()) {
remotePath = remoteWorkingPath.append(remotePath);
}
remotePath = remotePath.removeTrailingSeparator();
Assert.isTrue(remotePath.isAbsolute(), "remotePath.isAbsolute()"); //$NON-NLS-1$
remotePaths[i] = remotePath;
}
/*
* Process paths.
*/
IRemoteFileTools fileTools = manager.getRemoteFileTools();
for (int i = 0; i < remotePaths.length; i++) {
IPath remotePath = remotePaths[i];
String remotePathAsString = LinuxPath.toString(remotePath);
IRemoteItem item = null;
try {
item = fileTools.getItem(remotePathAsString);
} catch (RemoteOperationException e) {
errorWriter.println(NLS.bind(Messages.DownloadRuleAction_FailedFetchAttributes, remotePathAsString));
continue;
}
if (!item.exists()) {
errorWriter.println(NLS.bind(Messages.DownloadRuleAction_FailedRemotePathDoesNotExit, remotePathAsString));
continue;
} else if (item.isDirectory()) {
downloadDirectory(item, localDir);
} else {
downloadFile(item, localDir);
}
}
}
private void downloadFile(IRemoteItem remoteFile, File localDir) throws RemoteConnectionException, CancelException {
Assert.isTrue(localDir.isAbsolute(), "localDir.isAbsolute()"); //$NON-NLS-1$
IPath remoteFilePath = LinuxPath.fromString(remoteFile.getPath());
File localFile = new File(localDir, remoteFilePath.lastSegment());
outputWriter.println(NLS.bind(Messages.DownloadRuleAction_NotifyFileDownload1, remoteFile.getPath()));
outputWriter.println(NLS.bind(Messages.DownloadRuleAction_NotifyFileDownload2, localFile.getAbsolutePath()));
doFileDownload(remoteFile, localFile);
}
private void downloadDirectory(IRemoteItem remoteDirectory, File localDir) throws RemoteConnectionException, CancelException {
Assert.isTrue(localDir.isAbsolute(), "localDir.isAbsolute()"); //$NON-NLS-1$
outputWriter.println(NLS.bind(Messages.DownloadRuleAction_NotifyDirectoryDownload1, remoteDirectory.getPath()));
outputWriter.println(NLS.bind(Messages.DownloadRuleAction_NotifyDirectoryDownload2, localDir.getAbsolutePath()));
IRemoteFileTools fileTools = manager.getRemoteFileTools();
IRemoteFileEnumeration enumeration = null;
try {
enumeration = fileTools.createRecursiveFileEnumeration(remoteDirectory.getPath());
} catch (RemoteOperationException e) {
errorWriter.println(NLS.bind(Messages.DownloadRuleAction_FailedFetchRemoteAttributes, e.getMessage()));
return;
}
IPath remoteRootPath = LinuxPath.fromString(remoteDirectory.getPath());
IPath localRootPath = new Path(localDir.getAbsolutePath());
int remoteRootPathLength = remoteRootPath.segmentCount();
while (enumeration.hasMoreElements()) {
while (enumeration.hasMoreExceptions()) {
errorWriter.println(NLS.bind(Messages.DownloadRuleAction_FailedFetchRemoteAttributes, enumeration.nextException()));
}
/*
* Calculate path relative to the remote root.
* Generate path relative to the local root.
*/
IRemoteItem remoteItem = enumeration.nextElementAsItem();
IPath remotePath = LinuxPath.fromString(remoteItem.getPath());
IPath relativePath = remotePath.removeFirstSegments(remoteRootPathLength);
IPath localFilePath = localRootPath.append(relativePath);
File localFile = localFilePath.toFile();
if (remoteItem.isDirectory()) {
doDirectoryDownload(remoteItem, localFile);
} else {
doFileDownload(remoteItem, localFile);
}
}
while (enumeration.hasMoreExceptions()) {
errorWriter.println(NLS.bind(Messages.DownloadRuleAction_FailedFetchRemoteAttributes, enumeration.nextException()));
}
}
private void doFileDownload(IRemoteItem remoteFile, File localFile) throws RemoteConnectionException, CancelException {
Assert.isTrue(localFile.isAbsolute(), "localFile.isAbsolute()"); //$NON-NLS-1$
String remoteFileAsString = remoteFile.getPath();
IRemoteCopyTools copyTools = manager.getRemoteCopyTools();
/*
* Check if file exists and if file is newer, depending on overwrite policy.
*/
if (rule.getOverwritePolicy() == OverwritePolicies.ALWAYS) {
/*
* File is always copied, no policy.
*/
} else {
/*
* Policy needs to check remote file.
*/
if (rule.getOverwritePolicy() == OverwritePolicies.SKIP) {
if (localFile.exists()) {
outputWriter.println(NLS.bind(Messages.DownloadRuleAction_NotiftFileExistsLocally, localFile.getAbsolutePath()));
return;
}
} else if (rule.getOverwritePolicy() == OverwritePolicies.NEWER) {
long difference = remoteFile.getModificationTime() - localFile.lastModified();
if (difference < 1000) {
outputWriter.println(NLS.bind(Messages.DownloadRuleAction_NotiftNewerFileExistsLocally, localFile.getAbsolutePath()));
return;
}
}
}
/*
* Upload the file.
*/
try {
copyTools.downloadFileToFile(remoteFileAsString, localFile);
} catch (RemoteOperationException e) {
errorWriter.println(NLS.bind(Messages.DownloadRuleAction_FailedSetDownloadFile, e.getMessage()));
return;
}
/*
* Set file permissions. We need help of EFS, since the File class from
* Java does not providel all information.
*/
// boolean read = remoteFile.isReadable();
boolean write = remoteFile.isWritable();
boolean execute = remoteFile.isExecutable();
if (rule.isAsReadOnly()) {
write = false;
}
if (rule.isAsExecutable()) {
execute = true;
}
IFileSystem localFileSystem = EFS.getLocalFileSystem();
IFileStore fileStore = localFileSystem.getStore(new Path(localFile.getPath()));
IFileInfo fileInfo = fileStore.fetchInfo();
fileInfo.setAttribute(EFS.ATTRIBUTE_EXECUTABLE, execute);
fileInfo.setAttribute(EFS.ATTRIBUTE_READ_ONLY, ! write);
/*
* Set date/time, if required
*/
if (rule.isPreserveTimeStamp()) {
long timestamp = remoteFile.getModificationTime();
fileInfo.setLastModified(timestamp);
}
/*
* Commit changes
*/
try {
fileStore.putInfo(fileInfo, EFS.SET_LAST_MODIFIED | EFS.SET_ATTRIBUTES, null);
} catch (CoreException e) {
errorWriter.println(NLS.bind(Messages.DownloadRuleAction_FailedSetLocalFileAttributes, localFile.getAbsolutePath()));
return;
}
}
private void doDirectoryDownload(IRemoteItem remoteDir, File localDir) throws RemoteConnectionException, CancelException {
Assert.isTrue(localDir.isAbsolute(), "localFile.isAbsolute()"); //$NON-NLS-1$
/*
* Create local directory, if not already exists.
*/
if (! localDir.exists()) {
if (! localDir.mkdirs()) {
errorWriter.println(NLS.bind(Messages.DownloadRuleAction_FailedCreateLocalDirectory, localDir.getAbsolutePath()));
return;
}
}
/*
* Set file permissions. We need help of EFS, since the File class from
* Java does not providel all information.
*/
// boolean read = remoteDir.isReadable();
boolean write = remoteDir.isWritable();
boolean execute = true;
if (rule.isAsReadOnly()) {
write = false;
}
IFileSystem localFileSystem = EFS.getLocalFileSystem();
IFileStore fileStore = localFileSystem.getStore(new Path(localDir.getPath()));
IFileInfo fileInfo = fileStore.fetchInfo();
fileInfo.setAttribute(EFS.ATTRIBUTE_EXECUTABLE, execute);
fileInfo.setAttribute(EFS.ATTRIBUTE_READ_ONLY, ! write);
/*
* Set date/time, if required
*/
if (rule.isPreserveTimeStamp()) {
long timestamp = remoteDir.getModificationTime();
fileInfo.setLastModified(timestamp);
}
/*
* Commit changes
*/
try {
fileStore.putInfo(fileInfo, EFS.SET_LAST_MODIFIED | EFS.SET_ATTRIBUTES, null);
} catch (CoreException e) {
errorWriter.println(NLS.bind(Messages.DownloadRuleAction_FailedSetLocalDirectoryAttributes, localDir.getAbsolutePath()));
return;
}
}
}