]>
git.argeo.org Git - gpl/argeo-slc.git/blob - runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/jsch/ScpTo.java
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
.IOUtils
;
12 import org
.apache
.commons
.logging
.Log
;
13 import org
.apache
.commons
.logging
.LogFactory
;
14 import org
.argeo
.slc
.SlcException
;
15 import org
.springframework
.core
.io
.Resource
;
16 import org
.springframework
.util
.AntPathMatcher
;
17 import org
.springframework
.util
.PathMatcher
;
18 import org
.springframework
.util
.StringUtils
;
20 import com
.jcraft
.jsch
.Channel
;
21 import com
.jcraft
.jsch
.ChannelExec
;
22 import com
.jcraft
.jsch
.Session
;
24 public class ScpTo
extends AbstractJschTask
{
25 private final static Log log
= LogFactory
.getLog(ScpTo
.class);
27 private Resource localResource
;
28 private String remotePath
;
31 private String remoteDir
;
32 private List
<String
> includes
= new ArrayList
<String
>();
34 private List
<String
> excludes
= new ArrayList
<String
>();
36 private PathMatcher pathMatcher
;
38 public void run(Session session
) {
39 if (StringUtils
.hasText(dir
)) {
40 if (!StringUtils
.hasText(remoteDir
))
41 throw new SlcException("Remote dir has to be specified.");
43 String dirOs
= dir
.replace('/', File
.separatorChar
);
44 if (dirOs
.charAt(dir
.length() - 1) != File
.separatorChar
) {
45 dirOs
= dirOs
+ File
.separator
;
48 if (pathMatcher
== null)
49 pathMatcher
= new AntPathMatcher();
51 log
.info("Start multiple scp based on "+dirOs
);
52 scanDir(session
, dirOs
, "", includes
, excludes
);
55 if (localResource
!= null) {
58 lFile
= localResource
.getFile();
59 } catch (IOException e
) {
60 throw new SlcException("Cannot interpret resource "
61 + localResource
+ " as file.", e
);
63 uploadFile(session
, lFile
, remotePath
);
67 protected void scanDir(Session session
, String dir
, String currentRelPath
,
68 List
<String
> includes
, List
<String
> excludes
) {
69 File
[] files
= new File(dir
).listFiles();
70 for (File file
: files
) {
71 if (!file
.isDirectory()) {
72 String relPath
= currentRelPath
.concat(file
.getName());
73 if (match(relPath
, includes
, excludes
, false)) {
74 uploadFile(session
, file
, remoteDir
+ '/' + relPath
);
77 String relPath
= currentRelPath
.concat(file
.getName()).concat(
79 if (match(relPath
, includes
, excludes
, true)) {
80 String nextDir
= dir
.concat(file
.getName()).concat(
82 scanDir(session
, nextDir
, relPath
, includes
, excludes
);
88 protected Boolean
match(String path
, List
<String
> includes
,
89 List
<String
> excludes
, boolean matchStart
) {
90 for (String patternIn
: includes
) {
91 boolean matchIn
= matchStart ? pathMatcher
.matchStart(patternIn
,
92 path
) : pathMatcher
.match(patternIn
, path
);
94 // Could be included, check excludes
95 boolean excluded
= false;
96 ex
: for (String patternEx
: excludes
) {
97 boolean matchEx
= matchStart ? pathMatcher
.matchStart(
98 patternEx
, path
) : pathMatcher
.match(patternEx
,
113 protected void uploadFile(Session session
, File localFile
, String remoteFile
) {
114 InputStream in
= null;
115 OutputStream channelOut
;
116 InputStream channelIn
;
119 // exec 'scp -t rfile' remotely
120 String command
= "scp -p -t " + remoteFile
;
121 Channel channel
= session
.openChannel("exec");
122 ((ChannelExec
) channel
).setCommand(command
);
124 // get I/O streams for remote scp
125 channelOut
= channel
.getOutputStream();
126 channelIn
= channel
.getInputStream();
131 // send "C0644 filesize filename", where filename should not include
133 long filesize
= localFile
.length();
134 command
= "C0644 " + filesize
+ " ";
135 int index
= localFile
.getPath().lastIndexOf('/');
137 command
+= localFile
.getPath().substring(index
+ 1);
139 command
+= localFile
.getPath();
143 channelOut
.write(command
.getBytes());
147 if (log
.isDebugEnabled())
148 log
.debug("Start copy of " + localFile
+ " to " + remoteFile
149 + " on " + getSshTarget() + "...");
151 final long oneMB
= 1024l;// in KB
152 final long tenMB
= 10 * oneMB
;// in KB
154 // send a content of lfile
155 in
= new FileInputStream(localFile
);
156 byte[] buf
= new byte[1024];
159 int len
= in
.read(buf
, 0, buf
.length
);
162 channelOut
.write(buf
, 0, len
); // out.flush();
163 if ((cycleCount
% oneMB
) == 0)// each 1 MB
164 System
.out
.print('#');
165 if ((cycleCount
% (tenMB
)) == 0)// each 10 MB
166 System
.out
.print(" - " + cycleCount
/ tenMB
+ "0 MB\n");
171 channelOut
.write(buf
, 0, 1);
175 log
.info("\n" + (cycleCount
) + " KB sent to server. ("
176 + (cycleCount
/ oneMB
+ " MB)"));
178 if (log
.isDebugEnabled())
179 log
.debug("Finished copy of " + localFile
+ " to " + remoteFile
180 + " on " + getSshTarget() + "...");
182 IOUtils
.closeQuietly(channelOut
);
184 channel
.disconnect();
185 } catch (Exception e
) {
186 throw new SlcException("Cannot copy " + localFile
+ " to "
189 IOUtils
.closeQuietly(in
);
193 public void setLocalResource(Resource localFile
) {
194 this.localResource
= localFile
;
197 public void setRemotePath(String remoteFile
) {
198 this.remotePath
= remoteFile
;
201 public void setDir(String dir
) {
205 public void setRemoteDir(String remoteDir
) {
206 this.remoteDir
= remoteDir
;
209 public void setIncludes(List
<String
> includes
) {
210 this.includes
= includes
;
213 public void setExcludes(List
<String
> excludes
) {
214 this.excludes
= excludes
;
217 public void setPathMatcher(PathMatcher pathMatcher
) {
218 this.pathMatcher
= pathMatcher
;