1 /* 2 * Copyright (C) 2018, Thomas Wolf <thomas.wolf@paranor.ch> and others 3 * 4 * This program and the accompanying materials are made available under the 5 * terms of the Eclipse Distribution License v. 1.0 which is available at 6 * https://www.eclipse.org/org/documents/edl-v10.php. 7 * 8 * SPDX-License-Identifier: BSD-3-Clause 9 */ 10 package org.eclipse.jgit.transport; 11 12 import java.io.FileNotFoundException; 13 import java.io.IOException; 14 import java.io.InputStream; 15 import java.io.OutputStream; 16 import java.util.Collection; 17 import java.util.concurrent.TimeUnit; 18 19 /** 20 * An interface providing FTP operations over a {@link RemoteSession}. All 21 * operations are supposed to throw {@link FtpException} for remote file system 22 * errors and other IOExceptions on connection errors. 23 * 24 * @since 5.2 25 */ 26 public interface FtpChannel { 27 28 /** 29 * An {@link Exception} for reporting SFTP errors. 30 */ 31 static class FtpException extends IOException { 32 33 private static final long serialVersionUID = 7176525179280330876L; 34 35 public static final int OK = 0; 36 37 public static final int EOF = 1; 38 39 public static final int NO_SUCH_FILE = 2; 40 41 public static final int NO_PERMISSION = 3; 42 43 public static final int UNSPECIFIED_FAILURE = 4; 44 45 public static final int PROTOCOL_ERROR = 5; 46 47 public static final int UNSUPPORTED = 8; 48 49 private final int status; 50 FtpException(String message, int status)51 public FtpException(String message, int status) { 52 super(message); 53 this.status = status; 54 } 55 FtpException(String message, int status, Throwable cause)56 public FtpException(String message, int status, Throwable cause) { 57 super(message, cause); 58 this.status = status; 59 } 60 getStatus()61 public int getStatus() { 62 return status; 63 } 64 } 65 66 /** 67 * Connects the {@link FtpChannel} to the remote end. 68 * 69 * @param timeout 70 * for establishing the FTP connection 71 * @param unit 72 * of the {@code timeout} 73 * @throws IOException 74 */ connect(int timeout, TimeUnit unit)75 void connect(int timeout, TimeUnit unit) throws IOException; 76 77 /** 78 * Disconnects and {@link FtpChannel}. 79 */ disconnect()80 void disconnect(); 81 82 /** 83 * @return whether the {@link FtpChannel} is connected 84 */ isConnected()85 boolean isConnected(); 86 87 /** 88 * Changes the current remote directory. 89 * 90 * @param path 91 * target directory 92 * @throws IOException 93 * if the operation could not be performed remotely 94 */ cd(String path)95 void cd(String path) throws IOException; 96 97 /** 98 * @return the current remote directory path 99 * @throws IOException 100 */ pwd()101 String pwd() throws IOException; 102 103 /** 104 * Simplified remote directory entry. 105 */ 106 interface DirEntry { getFilename()107 String getFilename(); 108 getModifiedTime()109 long getModifiedTime(); 110 isDirectory()111 boolean isDirectory(); 112 } 113 114 /** 115 * Lists contents of a remote directory 116 * 117 * @param path 118 * of the directory to list 119 * @return the directory entries 120 * @throws IOException 121 */ ls(String path)122 Collection<DirEntry> ls(String path) throws IOException; 123 124 /** 125 * Deletes a directory on the remote file system. The directory must be 126 * empty. 127 * 128 * @param path 129 * to delete 130 * @throws IOException 131 */ rmdir(String path)132 void rmdir(String path) throws IOException; 133 134 /** 135 * Creates a directory on the remote file system. 136 * 137 * @param path 138 * to create 139 * @throws IOException 140 */ mkdir(String path)141 void mkdir(String path) throws IOException; 142 143 /** 144 * Obtain an {@link InputStream} to read the contents of a remote file. 145 * 146 * @param path 147 * of the file to read 148 * 149 * @return the stream to read from 150 * @throws IOException 151 */ get(String path)152 InputStream get(String path) throws IOException; 153 154 /** 155 * Obtain an {@link OutputStream} to write to a remote file. If the file 156 * exists already, it will be overwritten. 157 * 158 * @param path 159 * of the file to read 160 * 161 * @return the stream to read from 162 * @throws IOException 163 */ put(String path)164 OutputStream put(String path) throws IOException; 165 166 /** 167 * Deletes a file on the remote file system. 168 * 169 * @param path 170 * to delete 171 * @throws IOException 172 * if the file does not exist or could otherwise not be deleted 173 */ rm(String path)174 void rm(String path) throws IOException; 175 176 /** 177 * Deletes a file on the remote file system. If the file does not exist, no 178 * exception is thrown. 179 * 180 * @param path 181 * to delete 182 * @throws IOException 183 * if the file exist but could not be deleted 184 */ delete(String path)185 default void delete(String path) throws IOException { 186 try { 187 rm(path); 188 } catch (FileNotFoundException e) { 189 // Ignore; it's OK if the file doesn't exist 190 } catch (FtpException f) { 191 if (f.getStatus() == FtpException.NO_SUCH_FILE) { 192 return; 193 } 194 throw f; 195 } 196 } 197 198 /** 199 * Renames a file on the remote file system. If {@code to} exists, it is 200 * replaced by {@code from}. (POSIX rename() semantics) 201 * 202 * @param from 203 * original name of the file 204 * @param to 205 * new name of the file 206 * @throws IOException 207 * @see <a href= 208 * "http://pubs.opengroup.org/onlinepubs/9699919799/functions/rename.html">stdio.h: 209 * rename()</a> 210 */ rename(String from, String to)211 void rename(String from, String to) throws IOException; 212 213 } 214