001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: */
018:
019: package org.apache.tools.ant.taskdefs.optional.ssh;
020:
021: import java.io.File;
022: import java.io.IOException;
023:
024: import com.jcraft.jsch.JSchException;
025: import com.jcraft.jsch.Session;
026: import com.jcraft.jsch.ChannelSftp;
027: import com.jcraft.jsch.SftpException;
028: import com.jcraft.jsch.SftpATTRS;
029: import com.jcraft.jsch.SftpProgressMonitor;
030:
031: /**
032: * A helper object representing an scp download.
033: */
034: public class ScpFromMessageBySftp extends ScpFromMessage {
035:
036: private String remoteFile;
037: private File localFile;
038: private boolean isRecursive = false;
039: private boolean verbose = false;
040:
041: /**
042: * Constructor for ScpFromMessageBySftp.
043: * @param verbose if true log extra information
044: * @param session the Scp session to use
045: * @param aRemoteFile the remote file name
046: * @param aLocalFile the local file
047: * @param recursive if true use recursion
048: * @since Ant 1.7
049: */
050: public ScpFromMessageBySftp(boolean verbose, Session session,
051: String aRemoteFile, File aLocalFile, boolean recursive) {
052: super (verbose, session);
053: this .verbose = verbose;
054: this .remoteFile = aRemoteFile;
055: this .localFile = aLocalFile;
056: this .isRecursive = recursive;
057: }
058:
059: /**
060: * Constructor for ScpFromMessageBySftp.
061: * @param session the Scp session to use
062: * @param aRemoteFile the remote file name
063: * @param aLocalFile the local file
064: * @param recursive if true use recursion
065: */
066: public ScpFromMessageBySftp(Session session, String aRemoteFile,
067: File aLocalFile, boolean recursive) {
068: this (false, session, aRemoteFile, aLocalFile, recursive);
069: }
070:
071: /**
072: * Carry out the transfer.
073: * @throws IOException on i/o errors
074: * @throws JSchException on errors detected by scp
075: */
076: public void execute() throws IOException, JSchException {
077: ChannelSftp channel = openSftpChannel();
078: try {
079: channel.connect();
080: try {
081: SftpATTRS attrs = channel.stat(remoteFile);
082: if (attrs.isDir() && !remoteFile.endsWith("/")) {
083: remoteFile = remoteFile + "/";
084: }
085: } catch (SftpException ee) {
086: // Ignored
087: }
088: getDir(channel, remoteFile, localFile);
089: } catch (SftpException e) {
090: throw new JSchException(e.toString());
091: } finally {
092: if (channel != null) {
093: channel.disconnect();
094: }
095: }
096: log("done\n");
097: }
098:
099: private void getDir(ChannelSftp channel, String remoteFile,
100: File localFile) throws IOException, SftpException {
101: String pwd = remoteFile;
102: if (remoteFile.lastIndexOf('/') != -1) {
103: if (remoteFile.length() > 1) {
104: pwd = remoteFile.substring(0, remoteFile
105: .lastIndexOf('/'));
106: }
107: }
108: channel.cd(pwd);
109: if (!localFile.exists()) {
110: localFile.mkdirs();
111: }
112: java.util.Vector files = channel.ls(remoteFile);
113: for (int i = 0; i < files.size(); i++) {
114: ChannelSftp.LsEntry le = (ChannelSftp.LsEntry) files
115: .elementAt(i);
116: String name = le.getFilename();
117: if (le.getAttrs().isDir()) {
118: if (name.equals(".") || name.equals("..")) {
119: continue;
120: }
121: getDir(channel, channel.pwd() + "/" + name + "/",
122: new File(localFile, le.getFilename()));
123: } else {
124: getFile(channel, le, localFile);
125: }
126: }
127: channel.cd("..");
128: }
129:
130: private void getFile(ChannelSftp channel, ChannelSftp.LsEntry le,
131: File localFile) throws IOException, SftpException {
132: String remoteFile = le.getFilename();
133: if (!localFile.exists()) {
134: String path = localFile.getAbsolutePath();
135: int i = 0;
136: if ((i = path.lastIndexOf(File.pathSeparator)) != -1) {
137: if (path.length() > File.pathSeparator.length()) {
138: new File(path.substring(0, i)).mkdirs();
139: }
140: }
141: }
142:
143: if (localFile.isDirectory()) {
144: localFile = new File(localFile, remoteFile);
145: }
146:
147: long startTime = System.currentTimeMillis();
148: long totalLength = le.getAttrs().getSize();
149:
150: SftpProgressMonitor monitor = null;
151: boolean trackProgress = getVerbose() && totalLength > 102400;
152: if (trackProgress) {
153: monitor = getProgressMonitor();
154: }
155: try {
156: log("Receiving: " + remoteFile + " : "
157: + le.getAttrs().getSize());
158: channel.get(remoteFile, localFile.getAbsolutePath(),
159: monitor);
160: } finally {
161: long endTime = System.currentTimeMillis();
162: logStats(startTime, endTime, (int) totalLength);
163: }
164: }
165: }
|