/******************************************************************************* * Copyright (c) 2011, 2014 IBM Corporation and others. * 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 API and implementation *******************************************************************************/ package org.eclipse.orion.internal.server.servlets.xfer; import com.jcraft.jsch.*; import java.io.*; import java.util.*; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.orion.server.core.ProtocolConstants; import org.eclipse.osgi.util.NLS; /** * Implements export from workspace over SFTP. */ public class SFTPExportJob extends SFTPTransferJob { public SFTPExportJob(String userRunningTask, File localFile, String host, int port, Path remotePath, String user, String passphrase, List<String> options) { super(userRunningTask, localFile, host, port, remotePath, user, passphrase, options); } protected void doTransferFile(ChannelSftp channel, IPath remotePath, File localFile) throws IOException, SftpException { if (shouldSkip(channel, remotePath, localFile)) return; //on export, copy the local file to the remote destination channel.put(new FileInputStream(localFile), remotePath.toString()); } /** * Check if we should skip writing this file due to timestamp checks and overwrite options. * @throws IOException If the operation should abort completely */ private boolean shouldSkip(ChannelSftp channel, IPath remotePath, File localFile) throws IOException { SftpATTRS remoteAttributes; try { remoteAttributes = channel.stat(remotePath.toString()); } catch (SftpException e) { //remote file doesn't exist, so we need to traverse it. return false; } //abort the entire import if we have a collision and no-overwrite is specified if (getOptions().contains(ProtocolConstants.OPTION_NO_OVERWRITE)) { //give path relative to root in error message throw new IOException(NLS.bind("Remote file exists: {0}", remotePath.removeFirstSegments(remoteRoot.segmentCount()).toString())); } //time is expressed as seconds since the epoch int localMTime = (int) (localFile.lastModified() / 1000L); int remoteMTime = remoteAttributes.getMTime(); //check if we should skip overwrite of newer files if (getOptions().contains(ProtocolConstants.OPTION_OVERWRITE_OLDER) && remoteMTime > localMTime) return true; //skip file if unchanged if (localMTime == remoteMTime && localFile.length() == remoteAttributes.getSize()) return true; return false; } @Override protected void transferDirectory(ChannelSftp channel, IPath remotePath, File localFile) throws SftpException, IOException { try { //create the remote folder on export channel.mkdir(remotePath.toString()); } catch (SftpException e) { //mkdir failure likely means the folder already exists } //visit local children List<File> localChildren = new ArrayList<File>(); File[] localFiles = localFile.listFiles(); if (localFiles != null) localChildren.addAll(Arrays.asList(localFiles)); addTaskTotal(localFiles.length); for (File localChild : localChildren) { String childName = localChild.getName(); if (shouldSkip(childName)) { taskItemLoaded(); continue; } IPath remoteChild = remotePath.append(childName); if (localChild.isDirectory()) { transferDirectory(channel, remoteChild, localChild); } else { doTransferFile(channel, remoteChild, localChild); } taskItemLoaded(); } } }