1 7 package fr.jayasoft.ivy.repository.sftp; 8 9 import java.io.File ; 10 import java.io.IOException ; 11 import java.io.InputStream ; 12 import java.util.ArrayList ; 13 import java.util.Collection ; 14 import java.util.Iterator ; 15 import java.util.List ; 16 17 import com.jcraft.jsch.ChannelSftp; 18 import com.jcraft.jsch.JSchException; 19 import com.jcraft.jsch.Session; 20 import com.jcraft.jsch.SftpATTRS; 21 import com.jcraft.jsch.SftpException; 22 import com.jcraft.jsch.SftpProgressMonitor; 23 import com.jcraft.jsch.ChannelSftp.LsEntry; 24 25 import fr.jayasoft.ivy.repository.BasicResource; 26 import fr.jayasoft.ivy.repository.Resource; 27 import fr.jayasoft.ivy.repository.TransferEvent; 28 import fr.jayasoft.ivy.repository.ssh.AbstractSshBasedRepository; 29 import fr.jayasoft.ivy.repository.ssh.SshCache; 30 import fr.jayasoft.ivy.util.Message; 31 32 42 public class SFTPRepository extends AbstractSshBasedRepository { 43 private final class MyProgressMonitor implements SftpProgressMonitor { 44 private long _totalLength; 45 46 public void init(int op, String src, String dest, long max) { 47 _totalLength = max; 48 fireTransferStarted(max); 49 } 50 51 public void end() { 52 fireTransferCompleted(_totalLength); 53 } 54 55 public boolean count(long count) { 56 fireTransferProgress(count); 57 return true; 58 } 59 } 60 61 62 public SFTPRepository() { 63 } 64 65 66 public Resource getResource(String source) { 67 return new SFTPResource(this, source); 68 } 69 70 71 78 public Resource resolveResource(String path) { 79 try { 80 ChannelSftp c = getSftpChannel(path); 81 Collection r = c.ls(path); 82 if (r != null) { 83 for (Iterator iter = r.iterator(); iter.hasNext();) { 84 Object obj=iter.next(); 85 if(obj instanceof LsEntry){ 86 LsEntry entry = (LsEntry) obj; 87 SftpATTRS attrs = entry.getAttrs(); 88 return new BasicResource(path, true, attrs.getSize(), attrs.getMTime() * 1000, false); 89 } 90 } 91 } 92 } catch (Exception e) { 93 Message.debug("reolving resource error: "+e.getMessage()); 94 } 96 return new BasicResource(path, false, 0, 0, false); 97 } 98 99 public InputStream openStream(SFTPResource resource) throws IOException { 100 ChannelSftp c = getSftpChannel(resource.getName()); 101 try { 102 return c.get(resource.getName()); 103 } catch (SftpException e) { 104 e.printStackTrace(); 105 IOException ex = new IOException ("impossible to open stream for "+resource+" on "+getHost()+(e.getMessage() != null?": " + e.getMessage():"")); 106 ex.initCause(e); 107 throw ex; 108 } 109 } 110 111 public void get(String source, File destination) throws IOException { 112 fireTransferInitiated(getResource(source), TransferEvent.REQUEST_GET); 113 ChannelSftp c = getSftpChannel(source); 114 try { 115 c.get(source, destination.getAbsolutePath(), new MyProgressMonitor()); 116 } catch (SftpException e) { 117 e.printStackTrace(); 118 IOException ex = new IOException ("impossible to get "+source+" on "+getHost()+(e.getMessage() != null?": " + e.getMessage():"")); 119 ex.initCause(e); 120 throw ex; 121 } 122 } 123 124 public void put(File source, String destination, boolean overwrite) throws IOException { 125 fireTransferInitiated(getResource(destination), TransferEvent.REQUEST_PUT); 126 ChannelSftp c = getSftpChannel(destination); 127 try { 128 if(!overwrite && checkExistence(destination, c)) 129 throw new IOException ("destination file exists and overwrite == true"); 130 if (destination.indexOf('/') != -1) { 131 mkdirs(destination.substring(0, destination.lastIndexOf('/')),c); 132 } 133 c.put(source.getAbsolutePath(), destination, new MyProgressMonitor()); 134 } catch (SftpException e) { 135 IOException ex = new IOException (e.getMessage()); 136 ex.initCause(e); 137 throw ex; 138 } 139 } 140 141 private void mkdirs(String directory, ChannelSftp c) throws IOException , SftpException { 142 try { 143 SftpATTRS att = c.stat(directory); 144 if (att != null) { 145 if (att.isDir()) { 146 return; 147 } 148 } 149 } catch (SftpException ex) { 150 if (directory.indexOf('/') != -1) { 151 mkdirs(directory.substring(0, directory.lastIndexOf('/')),c); 152 } 153 c.mkdir(directory); 154 } 155 } 156 157 158 public List list(String parent) throws IOException { 159 try { 160 ChannelSftp c = getSftpChannel(parent); 161 Collection r = c.ls(parent); 162 if (r != null) { 163 if (!parent.endsWith("/")) { 164 parent = parent+"/"; 165 } 166 List result = new ArrayList (); 167 for (Iterator iter = r.iterator(); iter.hasNext();) { 168 Object obj=iter.next(); 169 if(obj instanceof LsEntry){ 170 LsEntry entry = (LsEntry) obj; 171 if (".".equals(entry.getFilename()) || "..".equals(entry.getFilename())) { 172 continue; 173 } 174 result.add(parent+entry.getFilename()); 175 } 176 } 177 return result; 178 } 179 } catch (Exception e) { 180 } 182 return null; 183 } 184 185 193 private boolean checkExistence(String file, ChannelSftp channel) throws IOException , SftpException { 194 try { 195 return channel.stat(file) != null; 196 } catch (SftpException ex) { 197 return false; 198 } 199 } 200 201 210 private ChannelSftp getSftpChannel(String pathOrUri) throws IOException { 211 Session session = getSession(pathOrUri); 212 String host = session.getHost(); 213 ChannelSftp channel = SshCache.getInstance().getChannelSftp(session); 214 if(channel == null) { 215 try { 216 channel = (ChannelSftp) session.openChannel("sftp"); 217 channel.connect(); 218 Message.verbose(":: SFTP :: connected to "+host+"!"); 219 SshCache.getInstance().attachChannelSftp(session,channel); 220 } catch (JSchException e) { 221 IOException ex = new IOException (e.getMessage()); 222 ex.initCause(e); 223 throw ex; 224 } 225 } 226 return channel; 227 } 228 229 protected String getRepositoryScheme() { 230 return "sftp"; 233 } 234 } 235 | Popular Tags |