]>
git.argeo.org Git - gpl/argeo-slc.git/blob - runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/jsch/ScpTo.java
07f428c4df03de90537fdf8bd5d97881fe665ee0
1 package org
.argeo
.slc
.jsch
;
4 import java
.io
.FileInputStream
;
5 import java
.io
.IOException
;
6 import java
.io
.InputStream
;
7 import java
.io
.OutputStream
;
8 import java
.util
.ArrayList
;
11 import org
.apache
.commons
.io
.FileUtils
;
12 import org
.apache
.commons
.io
.IOUtils
;
13 import org
.apache
.commons
.logging
.Log
;
14 import org
.apache
.commons
.logging
.LogFactory
;
15 import org
.argeo
.slc
.SlcException
;
16 import org
.springframework
.core
.io
.Resource
;
17 import org
.springframework
.util
.AntPathMatcher
;
18 import org
.springframework
.util
.PathMatcher
;
19 import org
.springframework
.util
.StringUtils
;
21 import com
.jcraft
.jsch
.Channel
;
22 import com
.jcraft
.jsch
.ChannelExec
;
23 import com
.jcraft
.jsch
.Session
;
25 public class ScpTo
extends AbstractJschTask
{
26 private final static Log log
= LogFactory
.getLog(ScpTo
.class);
28 private Resource localResource
;
29 private String remotePath
;
32 private String remoteDir
;
33 private List
<String
> includes
= new ArrayList
<String
>();
35 private List
<String
> excludes
= new ArrayList
<String
>();
37 private PathMatcher pathMatcher
;
39 public void run(Session session
) {
40 if (StringUtils
.hasText(dir
)) {
41 if (!StringUtils
.hasText(remoteDir
))
42 throw new SlcException("Remote dir has to be specified.");
44 String dirOs
= dir
.replace('/', File
.separatorChar
);
45 if (dirOs
.charAt(dir
.length() - 1) != File
.separatorChar
) {
46 dirOs
= dirOs
+ File
.separator
;
49 if (pathMatcher
== null)
50 pathMatcher
= new AntPathMatcher();
52 log
.info("Start multiple scp based on " + dirOs
);
53 scanDir(session
, dirOs
, "", includes
, excludes
);
56 if (localResource
!= null) {
58 File lFile
= localResource
.getFile();
59 uploadFile(session
, lFile
, remotePath
);
60 } catch (IOException e
) {
61 OutputStream out
= null;
62 InputStream in
= null;
65 tempFile
= File
.createTempFile(getClass().getSimpleName()
66 + "-" + localResource
.getFilename(), null);
67 out
= FileUtils
.openOutputStream(tempFile
);
68 in
= localResource
.getInputStream();
69 IOUtils
.copy(in
, out
);
70 uploadFile(session
, tempFile
, remotePath
);
71 } catch (IOException e1
) {
72 throw new SlcException("Can neither interpret resource "
74 + " as file, nor create a temporary file", e1
);
76 IOUtils
.closeQuietly(in
);
77 IOUtils
.closeQuietly(out
);
78 FileUtils
.deleteQuietly(tempFile
);
84 protected void scanDir(Session session
, String dir
, String currentRelPath
,
85 List
<String
> includes
, List
<String
> excludes
) {
86 File
[] files
= new File(dir
).listFiles();
87 for (File file
: files
) {
88 if (!file
.isDirectory()) {
89 String relPath
= currentRelPath
.concat(file
.getName());
90 if (match(relPath
, includes
, excludes
, false)) {
91 uploadFile(session
, file
, remoteDir
+ '/' + relPath
);
94 String relPath
= currentRelPath
.concat(file
.getName()).concat(
96 if (match(relPath
, includes
, excludes
, true)) {
97 String nextDir
= dir
.concat(file
.getName()).concat(
99 scanDir(session
, nextDir
, relPath
, includes
, excludes
);
105 protected Boolean
match(String path
, List
<String
> includes
,
106 List
<String
> excludes
, boolean matchStart
) {
107 for (String patternIn
: includes
) {
108 boolean matchIn
= matchStart ? pathMatcher
.matchStart(patternIn
,
109 path
) : pathMatcher
.match(patternIn
, path
);
111 // Could be included, check excludes
112 boolean excluded
= false;
113 ex
: for (String patternEx
: excludes
) {
114 boolean matchEx
= matchStart ? pathMatcher
.matchStart(
115 patternEx
, path
) : pathMatcher
.match(patternEx
,
130 protected void uploadFile(Session session
, File localFile
, String remoteFile
) {
131 InputStream in
= null;
132 OutputStream channelOut
;
133 InputStream channelIn
;
136 // exec 'scp -t rfile' remotely
137 String command
= "scp -p -t " + remoteFile
;
138 Channel channel
= session
.openChannel("exec");
139 ((ChannelExec
) channel
).setCommand(command
);
141 // get I/O streams for remote scp
142 channelOut
= channel
.getOutputStream();
143 channelIn
= channel
.getInputStream();
148 // send "C0644 filesize filename", where filename should not include
150 long filesize
= localFile
.length();
151 command
= "C0644 " + filesize
+ " ";
152 int index
= localFile
.getPath().lastIndexOf('/');
154 command
+= localFile
.getPath().substring(index
+ 1);
156 command
+= localFile
.getPath();
160 channelOut
.write(command
.getBytes());
164 if (log
.isTraceEnabled())
165 log
.debug("Start copy of " + localFile
+ " to " + remoteFile
166 + " on " + getSshTarget() + "...");
168 final long oneMB
= 1024l;// in KB
169 final long tenMB
= 10 * oneMB
;// in KB
171 // send a content of lfile
172 in
= new FileInputStream(localFile
);
173 byte[] buf
= new byte[1024];
176 int len
= in
.read(buf
, 0, buf
.length
);
179 channelOut
.write(buf
, 0, len
); // out.flush();
180 if (((cycleCount
% oneMB
) == 0) && cycleCount
!= 0)// each 1 MB
181 System
.out
.print('#');
182 if (((cycleCount
% (tenMB
)) == 0) && cycleCount
!= 0)// each 10
184 System
.out
.print(" - " + cycleCount
/ tenMB
+ "0 MB\n");
189 channelOut
.write(buf
, 0, 1);
193 if (log
.isTraceEnabled())
194 log
.debug((cycleCount
) + " KB sent to server. ("
195 + (cycleCount
/ oneMB
+ " MB)"));
197 if (log
.isDebugEnabled())
198 log
.debug("Finished copy to " + remoteFile
+ " on "
199 + getSshTarget() + " from " + localFile
);
201 IOUtils
.closeQuietly(channelOut
);
203 channel
.disconnect();
204 } catch (Exception e
) {
205 throw new SlcException("Cannot copy " + localFile
+ " to "
208 IOUtils
.closeQuietly(in
);
212 public void setLocalResource(Resource localFile
) {
213 this.localResource
= localFile
;
216 public void setRemotePath(String remoteFile
) {
217 this.remotePath
= remoteFile
;
220 public void setDir(String dir
) {
224 public void setRemoteDir(String remoteDir
) {
225 this.remoteDir
= remoteDir
;
228 public void setIncludes(List
<String
> includes
) {
229 this.includes
= includes
;
232 public void setExcludes(List
<String
> excludes
) {
233 this.excludes
= excludes
;
236 public void setPathMatcher(PathMatcher pathMatcher
) {
237 this.pathMatcher
= pathMatcher
;