Select Git revision
-
Al Massati Bilal authoredAl Massati Bilal authored
FTPService.java 9.93 KiB
package fil.sr2.flopbox;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class FTPService {
public FtpNode getResourceTree(String alias, String path, String user, String pass)
throws IOException, FTPException {
FTPClient ftpClient = FTPClientFactory.createClient(alias);
try {
if (!ftpClient.login(user, pass)) {
throw new FTPException("Authentification FTP échouée", 401);
}
ftpClient.enterLocalPassiveMode();
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
// Normaliser le chemin : retirer le slash final s'il y en a un
if (path.endsWith("/")) {
path = path.substring(0, path.length() - 1);
}
// Vérifier si c'est un dossier
boolean isDir = ftpClient.changeWorkingDirectory(path);
if (isDir) {
// Même si le dossier est vide, c'est valide
return buildFtpTree(ftpClient, path);
} else {
// Sinon, tenter de récupérer un flux de fichier
InputStream is = ftpClient.retrieveFileStream(path);
if (is != null) {
is.close();
ftpClient.completePendingCommand();
return new FtpNode(getFileName(path), false);
} else {
throw new FTPException("Ressource non trouvée : " + path, 404);
}
}
} finally {
FTPClientFactory.disconnect(ftpClient);
}
}
// Méthode récursive pour construire l'arborescence
private FtpNode buildFtpTree(FTPClient ftpClient, String path) throws IOException {
FTPFile[] files = ftpClient.listFiles(path);
FtpNode node = new FtpNode(getFileName(path), true);
if (files != null) {
for (FTPFile file : files) {
String fullPath = path + "/" + file.getName();
if (file.isDirectory()) {
node.children.add(buildFtpTree(ftpClient, fullPath));
} else {
node.children.add(new FtpNode(file.getName(), false));
}
}
}
return node;
}
public byte[] downloadFile(String alias, String path, String user, String pass)
throws IOException, FTPException {
FTPClient ftp = FTPClientFactory.createClient(alias);
try {
if (!ftp.login(user, pass)) {
throw new FTPException("Authentification FTP échouée", 401);
}
ftp.enterLocalPassiveMode();
ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
InputStream is = ftp.retrieveFileStream(path);
if (is == null) {
throw new FTPException("Ressource non trouvée : " + path, 404);
}
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = is.read(buffer)) != -1) {
baos.write(buffer, 0, bytesRead);
}
is.close();
ftp.completePendingCommand();
return baos.toByteArray();
} finally {
FTPClientFactory.disconnect(ftp);
}
}
public byte[] downloadDirectoryAsZip(String alias, String path, String user, String pass)
throws IOException, FTPException {
FTPClient ftp = FTPClientFactory.createClient(alias);
try {
if (!ftp.login(user, pass)) {
throw new FTPException("Authentification FTP échouée", 401);
}
ftp.enterLocalPassiveMode();
ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ZipOutputStream zos = new ZipOutputStream(baos);
addDirectoryToZip(ftp, path, "", zos);
zos.close();
return baos.toByteArray();
} finally {
FTPClientFactory.disconnect(ftp);
}
}
private void addDirectoryToZip(FTPClient ftp, String remotePath, String basePath, ZipOutputStream zos)
throws IOException {
FTPFile[] files = ftp.listFiles(remotePath);
if (files == null || files.length == 0) {
return;
}
for (FTPFile file : files) {
String filePath = remotePath + "/" + file.getName();
String zipEntryPath = basePath.isEmpty() ? file.getName() : basePath + "/" + file.getName();
if (file.isDirectory()) {
zos.putNextEntry(new ZipEntry(zipEntryPath + "/"));
zos.closeEntry();
addDirectoryToZip(ftp, filePath, zipEntryPath, zos);
} else {
zos.putNextEntry(new ZipEntry(zipEntryPath));
InputStream is = ftp.retrieveFileStream(filePath);
if (is != null) {
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = is.read(buffer)) != -1) {
zos.write(buffer, 0, bytesRead);
}
is.close();
ftp.completePendingCommand();
}
zos.closeEntry();
}
}
}
public void uploadFile(String alias, String path, String user, String pass, InputStream fileStream)
throws IOException, FTPException {
FTPClient ftp = FTPClientFactory.createClient(alias);
try {
if (!ftp.login(user, pass)) {
throw new FTPException("Authentification FTP échouée", 401);
}
ftp.enterLocalPassiveMode();
ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
boolean success = ftp.storeFile(path, fileStream);
if (!success) {
throw new FTPException("Erreur lors de l'upload", 500);
}
} finally {
FTPClientFactory.disconnect(ftp);
}
}
public void createResource(String alias, String path, String user, String pass, String resourceType,
InputStream inputStream) throws IOException, FTPException {
FTPClient ftp = FTPClientFactory.createClient(alias);
try {
if (!ftp.login(user, pass)) {
throw new FTPException("Authentification FTP échouée", 401);
}
ftp.enterLocalPassiveMode();
if ("directory".equalsIgnoreCase(resourceType)) {
boolean created = ftp.makeDirectory(path);
if (!created) {
throw new FTPException("Erreur création répertoire", 400);
}
} else {
boolean created = ftp.storeFile(path, inputStream);
if (!created) {
throw new FTPException("Erreur création fichier", 400);
}
}
} finally {
FTPClientFactory.disconnect(ftp);
}
}
public void deleteResource(String alias, String path, String user, String pass)
throws IOException, FTPException {
FTPClient ftp = FTPClientFactory.createClient(alias);
try {
if (!ftp.login(user, pass)) {
throw new FTPException("Authentification FTP échouée", 401);
}
ftp.enterLocalPassiveMode();
boolean deleted = deleteRecursive(ftp, path);
if (!deleted) {
throw new FTPException("Ressource non trouvée", 404);
}
} finally {
FTPClientFactory.disconnect(ftp);
}
}
private boolean deleteRecursive(FTPClient ftp, String path) throws IOException {
if (ftp.deleteFile(path)) {
return true;
}
FTPFile[] files = ftp.listFiles(path);
if (files == null) {
return false;
}
for (FTPFile file : files) {
String fullPath = path + "/" + file.getName();
if (file.isDirectory()) {
if (!deleteRecursive(ftp, fullPath)) {
return false;
}
} else {
if (!ftp.deleteFile(fullPath)) {
return false;
}
}
}
return ftp.removeDirectory(path);
}
public void renameResource(String alias, String oldPath, String newPath, String user, String pass)
throws IOException, FTPException {
FTPClient ftp = FTPClientFactory.createClient(alias);
try {
if (!ftp.login(user, pass)) {
throw new FTPException("Authentification FTP échouée", 401);
}
ftp.enterLocalPassiveMode();
boolean success = ftp.rename(oldPath, newPath);
if (!success) {
throw new FTPException("Échec du renommage", 400);
}
} finally {
FTPClientFactory.disconnect(ftp);
}
}
private String getFileName(String path) {
return path.substring(path.lastIndexOf('/') + 1);
}
// Classe représentant un nœud de l'arborescence FTP
public static class FtpNode {
public String name;
public boolean isDirectory;
public List<FtpNode> children;
public FtpNode(String name, boolean isDirectory) {
this.name = name;
this.isDirectory = isDirectory;
if (isDirectory) {
this.children = new ArrayList<>();
}
}
}
}