KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tools > ant > taskdefs > optional > ssh > ScpToMessage


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */

18
19 package org.apache.tools.ant.taskdefs.optional.ssh;
20
21 import com.jcraft.jsch.Channel;
22 import com.jcraft.jsch.Session;
23 import com.jcraft.jsch.JSchException;
24 import java.io.File JavaDoc;
25 import java.io.IOException JavaDoc;
26 import java.io.InputStream JavaDoc;
27 import java.io.FileInputStream JavaDoc;
28 import java.io.OutputStream JavaDoc;
29 import java.util.List JavaDoc;
30 import java.util.Iterator JavaDoc;
31
32 /**
33  * Utility class to carry out an upload scp transfer.
34  */

35 public class ScpToMessage extends AbstractSshMessage {
36
37     private static final int BUFFER_SIZE = 1024;
38
39     private File JavaDoc localFile;
40     private String JavaDoc remotePath;
41     private List JavaDoc directoryList;
42
43     /**
44      * Constructor for ScpToMessage
45      * @param session the ssh session to use
46      */

47     public ScpToMessage(Session session) {
48         super(session);
49     }
50
51     /**
52      * Constructor for ScpToMessage
53      * @param verbose if true do verbose logging
54      * @param session the ssh session to use
55      * @since Ant 1.7
56      */

57     public ScpToMessage(boolean verbose, Session session) {
58         super(verbose, session);
59     }
60
61     /**
62      * Constructor for a local file to remote.
63      * @param verbose if true do verbose logging
64      * @param session the scp session to use
65      * @param aLocalFile the local file
66      * @param aRemotePath the remote path
67      * @since Ant 1.6.2
68      */

69     public ScpToMessage(boolean verbose,
70                         Session session,
71                         File JavaDoc aLocalFile,
72                         String JavaDoc aRemotePath) {
73         this(verbose, session, aRemotePath);
74
75         this.localFile = aLocalFile;
76     }
77
78     /**
79      * Constructor for a local directories to remote.
80      * @param verbose if true do verbose logging
81      * @param session the scp session to use
82      * @param aDirectoryList a list of directories
83      * @param aRemotePath the remote path
84      * @since Ant 1.6.2
85      */

86     public ScpToMessage(boolean verbose,
87                         Session session,
88                         List JavaDoc aDirectoryList,
89                         String JavaDoc aRemotePath) {
90         this(verbose, session, aRemotePath);
91
92         this.directoryList = aDirectoryList;
93     }
94
95     /**
96      * Constructor for ScpToMessage.
97      * @param verbose if true do verbose logging
98      * @param session the scp session to use
99      * @param aRemotePath the remote path
100      * @since Ant 1.6.2
101      */

102     private ScpToMessage(boolean verbose,
103                          Session session,
104                          String JavaDoc aRemotePath) {
105         super(verbose, session);
106         this.remotePath = aRemotePath;
107     }
108
109     /**
110      * Constructor for ScpToMessage.
111      * @param session the scp session to use
112      * @param aLocalFile the local file
113      * @param aRemotePath the remote path
114      */

115     public ScpToMessage(Session session,
116                         File JavaDoc aLocalFile,
117                         String JavaDoc aRemotePath) {
118         this(false, session, aLocalFile, aRemotePath);
119     }
120
121     /**
122      * Constructor for ScpToMessage.
123      * @param session the scp session to use
124      * @param aDirectoryList a list of directories
125      * @param aRemotePath the remote path
126      */

127     public ScpToMessage(Session session,
128                          List JavaDoc aDirectoryList,
129                          String JavaDoc aRemotePath) {
130         this(false, session, aDirectoryList, aRemotePath);
131     }
132
133     /**
134      * Carry out the transfer.
135      * @throws IOException on i/o errors
136      * @throws JSchException on errors detected by scp
137      */

138     public void execute() throws IOException JavaDoc, JSchException {
139         if (directoryList != null) {
140             doMultipleTransfer();
141         }
142         if (localFile != null) {
143             doSingleTransfer();
144         }
145         log("done.\n");
146     }
147
148     private void doSingleTransfer() throws IOException JavaDoc, JSchException {
149         String JavaDoc cmd = "scp -t " + remotePath;
150         Channel channel = openExecChannel(cmd);
151         try {
152
153             OutputStream JavaDoc out = channel.getOutputStream();
154             InputStream JavaDoc in = channel.getInputStream();
155
156             channel.connect();
157
158             waitForAck(in);
159             sendFileToRemote(localFile, in, out);
160         } finally {
161             if (channel != null) {
162                 channel.disconnect();
163             }
164         }
165     }
166
167     private void doMultipleTransfer() throws IOException JavaDoc, JSchException {
168         Channel channel = openExecChannel("scp -r -d -t " + remotePath);
169         try {
170             OutputStream JavaDoc out = channel.getOutputStream();
171             InputStream JavaDoc in = channel.getInputStream();
172
173             channel.connect();
174
175             waitForAck(in);
176             for (Iterator JavaDoc i = directoryList.iterator(); i.hasNext();) {
177                 Directory current = (Directory) i.next();
178                 sendDirectory(current, in, out);
179             }
180         } finally {
181             if (channel != null) {
182                 channel.disconnect();
183             }
184         }
185     }
186
187     private void sendDirectory(Directory current,
188                                InputStream JavaDoc in,
189                                OutputStream JavaDoc out) throws IOException JavaDoc {
190         for (Iterator JavaDoc fileIt = current.filesIterator(); fileIt.hasNext();) {
191             sendFileToRemote((File JavaDoc) fileIt.next(), in, out);
192         }
193         for (Iterator JavaDoc dirIt = current.directoryIterator(); dirIt.hasNext();) {
194             Directory dir = (Directory) dirIt.next();
195             sendDirectoryToRemote(dir, in, out);
196         }
197     }
198
199     private void sendDirectoryToRemote(Directory directory,
200                                         InputStream JavaDoc in,
201                                         OutputStream JavaDoc out) throws IOException JavaDoc {
202         String JavaDoc command = "D0755 0 ";
203         command += directory.getDirectory().getName();
204         command += "\n";
205
206         out.write(command.getBytes());
207         out.flush();
208
209         waitForAck(in);
210         sendDirectory(directory, in, out);
211         out.write("E\n".getBytes());
212         waitForAck(in);
213     }
214
215     private void sendFileToRemote(File JavaDoc localFile,
216                                    InputStream JavaDoc in,
217                                    OutputStream JavaDoc out) throws IOException JavaDoc {
218         // send "C0644 filesize filename", where filename should not include '/'
219
long filesize = localFile.length();
220         String JavaDoc command = "C0644 " + filesize + " ";
221         command += localFile.getName();
222         command += "\n";
223
224         out.write(command.getBytes());
225         out.flush();
226
227         waitForAck(in);
228
229         // send a content of lfile
230
FileInputStream JavaDoc fis = new FileInputStream JavaDoc(localFile);
231         byte[] buf = new byte[BUFFER_SIZE];
232         long startTime = System.currentTimeMillis();
233         long totalLength = 0;
234
235         // only track progress for files larger than 100kb in verbose mode
236
boolean trackProgress = getVerbose() && filesize > 102400;
237         // since filesize keeps on decreasing we have to store the
238
// initial filesize
239
long initFilesize = filesize;
240         int percentTransmitted = 0;
241
242         try {
243             if (this.getVerbose()) {
244                 log("Sending: " + localFile.getName() + " : " + localFile.length());
245             }
246             while (true) {
247                 int len = fis.read(buf, 0, buf.length);
248                 if (len <= 0) {
249                     break;
250                 }
251                 out.write(buf, 0, len);
252                 totalLength += len;
253
254                 if (trackProgress) {
255                     percentTransmitted = trackProgress(initFilesize,
256                                                        totalLength,
257                                                        percentTransmitted);
258                 }
259             }
260             out.flush();
261             sendAck(out);
262             waitForAck(in);
263         } finally {
264             if (this.getVerbose()) {
265                 long endTime = System.currentTimeMillis();
266                 logStats(startTime, endTime, totalLength);
267             }
268             fis.close();
269         }
270     }
271
272     /**
273      * Get the local file
274      * @return the local file
275      */

276     public File JavaDoc getLocalFile() {
277         return localFile;
278     }
279
280     /**
281      * Get the remote path
282      * @return the remote path
283      */

284     public String JavaDoc getRemotePath() {
285         return remotePath;
286     }
287 }
288
Popular Tags