Simplify SshdFtpChannel

Apache MINA sshd has simpler API for reading directories, and it has a
functional interface suitable for us. So no need to use our own
interface, or to deal with low-level abstractions like CloseableHandle.

Change-Id: Ic125c587535670504983f157a696b41ed6a76bb7
Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
This commit is contained in:
Thomas Wolf 2021-10-31 17:29:04 +01:00
parent c6d48ab2f8
commit 3a7db8b782
2 changed files with 30 additions and 55 deletions

View File

@ -73,6 +73,7 @@ Import-Package: net.i2p.crypto.eddsa;version="[0.3.0,0.4.0)",
org.apache.sshd.common.util.buffer;version="[2.7.0,2.8.0)", org.apache.sshd.common.util.buffer;version="[2.7.0,2.8.0)",
org.apache.sshd.common.util.closeable;version="[2.7.0,2.8.0)", org.apache.sshd.common.util.closeable;version="[2.7.0,2.8.0)",
org.apache.sshd.common.util.io;version="[2.7.0,2.8.0)", org.apache.sshd.common.util.io;version="[2.7.0,2.8.0)",
org.apache.sshd.common.util.io.functors;version="[2.7.0,2.8.0)",
org.apache.sshd.common.util.io.resource;version="[2.7.0,2.8.0)", org.apache.sshd.common.util.io.resource;version="[2.7.0,2.8.0)",
org.apache.sshd.common.util.logging;version="[2.7.0,2.8.0)", org.apache.sshd.common.util.logging;version="[2.7.0,2.8.0)",
org.apache.sshd.common.util.net;version="[2.7.0,2.8.0)", org.apache.sshd.common.util.net;version="[2.7.0,2.8.0)",

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2018, 2020 Thomas Wolf <thomas.wolf@paranor.ch> and others * Copyright (C) 2018, 2021 Thomas Wolf <thomas.wolf@paranor.ch> and others
* *
* This program and the accompanying materials are made available under the * This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0 which is available at * terms of the Eclipse Distribution License v. 1.0 which is available at
@ -28,7 +28,6 @@
import java.util.Map; import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -44,9 +43,9 @@
import org.apache.sshd.common.future.CloseFuture; import org.apache.sshd.common.future.CloseFuture;
import org.apache.sshd.common.future.SshFutureListener; import org.apache.sshd.common.future.SshFutureListener;
import org.apache.sshd.common.util.io.IoUtils; import org.apache.sshd.common.util.io.IoUtils;
import org.apache.sshd.common.util.io.functors.IOFunction;
import org.apache.sshd.common.util.net.SshdSocketAddress; import org.apache.sshd.common.util.net.SshdSocketAddress;
import org.apache.sshd.sftp.client.SftpClient; import org.apache.sshd.sftp.client.SftpClient;
import org.apache.sshd.sftp.client.SftpClient.CloseableHandle;
import org.apache.sshd.sftp.client.SftpClient.CopyMode; import org.apache.sshd.sftp.client.SftpClient.CopyMode;
import org.apache.sshd.sftp.client.SftpClientFactory; import org.apache.sshd.sftp.client.SftpClientFactory;
import org.apache.sshd.sftp.common.SftpException; import org.apache.sshd.sftp.common.SftpException;
@ -416,20 +415,6 @@ public void destroy() {
} }
} }
/**
* Helper interface like {@link Supplier}, but possibly raising an
* {@link IOException}.
*
* @param <T>
* return type
*/
@FunctionalInterface
private interface FtpOperation<T> {
T call() throws IOException;
}
private class SshdFtpChannel implements FtpChannel { private class SshdFtpChannel implements FtpChannel {
private SftpClient ftp; private SftpClient ftp;
@ -485,9 +470,9 @@ private String absolute(String path) {
return path; return path;
} }
private <T> T map(FtpOperation<T> op) throws IOException { private <T> T map(IOFunction<Void, T> op) throws IOException {
try { try {
return op.call(); return op.apply(null);
} catch (IOException e) { } catch (IOException e) {
if (e instanceof SftpException) { if (e instanceof SftpException) {
throw new FtpChannel.FtpException(e.getLocalizedMessage(), throw new FtpChannel.FtpException(e.getLocalizedMessage(),
@ -499,7 +484,7 @@ private <T> T map(FtpOperation<T> op) throws IOException {
@Override @Override
public void cd(String path) throws IOException { public void cd(String path) throws IOException {
cwd = map(() -> ftp.canonicalPath(absolute(path))); cwd = map(x -> ftp.canonicalPath(absolute(path)));
if (cwd.isEmpty()) { if (cwd.isEmpty()) {
cwd += '/'; cwd += '/';
} }
@ -512,39 +497,28 @@ public String pwd() throws IOException {
@Override @Override
public Collection<DirEntry> ls(String path) throws IOException { public Collection<DirEntry> ls(String path) throws IOException {
return map(() -> { return map(x -> {
List<DirEntry> result = new ArrayList<>(); List<DirEntry> result = new ArrayList<>();
try (CloseableHandle handle = ftp.openDir(absolute(path))) { for (SftpClient.DirEntry remote : ftp.readDir(absolute(path))) {
AtomicReference<Boolean> atEnd = new AtomicReference<>( result.add(new DirEntry() {
Boolean.FALSE);
while (!atEnd.get().booleanValue()) { @Override
List<SftpClient.DirEntry> chunk = ftp.readDir(handle, public String getFilename() {
atEnd); return remote.getFilename();
if (chunk == null) {
break;
} }
for (SftpClient.DirEntry remote : chunk) {
result.add(new DirEntry() {
@Override @Override
public String getFilename() { public long getModifiedTime() {
return remote.getFilename(); return remote.getAttributes().getModifyTime()
} .toMillis();
@Override
public long getModifiedTime() {
return remote.getAttributes()
.getModifyTime().toMillis();
}
@Override
public boolean isDirectory() {
return remote.getAttributes().isDirectory();
}
});
} }
}
@Override
public boolean isDirectory() {
return remote.getAttributes().isDirectory();
}
});
} }
return result; return result;
}); });
@ -552,7 +526,7 @@ public boolean isDirectory() {
@Override @Override
public void rmdir(String path) throws IOException { public void rmdir(String path) throws IOException {
map(() -> { map(x -> {
ftp.rmdir(absolute(path)); ftp.rmdir(absolute(path));
return null; return null;
}); });
@ -561,7 +535,7 @@ public void rmdir(String path) throws IOException {
@Override @Override
public void mkdir(String path) throws IOException { public void mkdir(String path) throws IOException {
map(() -> { map(x -> {
ftp.mkdir(absolute(path)); ftp.mkdir(absolute(path));
return null; return null;
}); });
@ -569,17 +543,17 @@ public void mkdir(String path) throws IOException {
@Override @Override
public InputStream get(String path) throws IOException { public InputStream get(String path) throws IOException {
return map(() -> ftp.read(absolute(path))); return map(x -> ftp.read(absolute(path)));
} }
@Override @Override
public OutputStream put(String path) throws IOException { public OutputStream put(String path) throws IOException {
return map(() -> ftp.write(absolute(path))); return map(x -> ftp.write(absolute(path)));
} }
@Override @Override
public void rm(String path) throws IOException { public void rm(String path) throws IOException {
map(() -> { map(x -> {
ftp.remove(absolute(path)); ftp.remove(absolute(path));
return null; return null;
}); });
@ -587,7 +561,7 @@ public void rm(String path) throws IOException {
@Override @Override
public void rename(String from, String to) throws IOException { public void rename(String from, String to) throws IOException {
map(() -> { map(x -> {
String src = absolute(from); String src = absolute(from);
String dest = absolute(to); String dest = absolute(to);
try { try {