Skip to content

Commit

Permalink
#18 start splitting the path
Browse files Browse the repository at this point in the history
  • Loading branch information
maddingo committed Jan 4, 2017
1 parent 165d989 commit 376fd45
Show file tree
Hide file tree
Showing 8 changed files with 150 additions and 562 deletions.
5 changes: 5 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,11 @@
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-library</artifactId>
<version>1.3</version>
</dependency>
</dependencies>
</dependencyManagement>

Expand Down
5 changes: 5 additions & 0 deletions sftp/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-library</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,12 +121,14 @@ public void createDirectory(Path dir, FileAttribute<?>... attrs) throws IOExcept

sftp.connect();

SFTPPath sftpPath = (SFTPPath)dir;
String dirString = sftpPath.getPathString();
try {
sftp.mkdir(dirString);
} catch(SftpException e) {
throw new IOException(dirString, e);
// Implementation might not support recursive creation of directories
for (String subPath : ((SFTPPath) dir).getParts()) {
try {
sftp.mkdir(subPath);
} catch(SftpException e) {
throw new IOException(subPath, e);
}

}

sftp.quit();
Expand Down
64 changes: 40 additions & 24 deletions sftp/src/main/java/no/maddin/niofs/sftp/SFTPPath.java
Original file line number Diff line number Diff line change
@@ -1,42 +1,46 @@
package no.maddin.niofs.sftp;

import sun.nio.fs.UnixFileSystemProvider;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.*;
import java.nio.file.WatchEvent.Kind;
import java.nio.file.WatchEvent.Modifier;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
import java.util.*;

/**
* A Path implementation for SFTP.
*/
public class SFTPPath implements Path {

private static final String HOME_PREFIX = "/~/";
private static final int HOME_PREFIX_LEN = HOME_PREFIX.length();
private static final String DEFAULT_ROOT_PATH = "";
private static final String PATH_SEP = "/";
private final String path;
private final SFTPHost host;
private final java.util.List<String> parts;

SFTPPath(SFTPHost sftpHost, String path) {
this.host = sftpHost;
this.path = path;
parts = splitParts(path);
}

private List<String> splitParts(String path) {
String[] parts = path.split(PATH_SEP, -1);
return Arrays.asList(parts);
}

// TODO split the path in ist components
if (path == null || path.trim().isEmpty()) {
this.path = DEFAULT_ROOT_PATH;
} else {
if (path.startsWith(HOME_PREFIX)) {
this.path = path.substring(HOME_PREFIX_LEN);
} else {
this.path = path;
private String combineParts(int startIdx, int endIdx) {
StringBuilder sb = new StringBuilder();
for (String part : parts.subList(startIdx, endIdx)) {
if (sb.length() > 0) {
sb.append(PATH_SEP);
}
sb.append(part);
}
return sb.toString();
}

@Override
Expand All @@ -51,10 +55,10 @@ public boolean isAbsolute() {

@Override
public Path getRoot() {
if (path.equals(DEFAULT_ROOT_PATH)) {
if (path == null) {
return this;
}
return new SFTPPath(this.host, DEFAULT_ROOT_PATH);
return new SFTPPath(this.host, null);
}

@Override
Expand All @@ -64,12 +68,17 @@ public Path getFileName() {

@Override
public Path getParent() {
throw new UnsupportedOperationException("Not Implemented");

if (path == null) {
return null;
}
return new SFTPPath(this.host, combineParts(0, getNameCount() - 1));
}

@Override
public int getNameCount() {
throw new UnsupportedOperationException("Not Implemented");

return parts.size();
}

@Override
Expand All @@ -79,7 +88,7 @@ public Path getName(int index) {

@Override
public Path subpath(int beginIndex, int endIndex) {
throw new UnsupportedOperationException("Not Implemented");
return new SFTPPath(beginIndex == 0 ? host : null, combineParts(0, endIndex));
}

@Override
Expand Down Expand Up @@ -141,11 +150,14 @@ public Path relativize(Path other) {
public URI toUri() {

try {
String userInfo;
String userInfo = null;
if (host.getUserName() != null) {
userInfo = host.getUserName() + ':' + host.getPassword();
} else {
userInfo = null;
StringBuilder uinfoSb = new StringBuilder();
uinfoSb.append(host.getUserName());
if (host.getPassword() != null) {
uinfoSb.append(':').append(host.getPassword());
}
userInfo = uinfoSb.toString();
}
return new URI("sftp", userInfo, host.getHost(), host.getPort(), this.path, null, null);
} catch (URISyntaxException e) {
Expand Down Expand Up @@ -191,4 +203,8 @@ public int compareTo(Path other) {
String getPathString() {
return this.path;
}

List<String> getParts() {
return Collections.unmodifiableList(parts);
}
}
56 changes: 56 additions & 0 deletions sftp/src/test/java/no/maddin/niofs/sftp/PartsTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package no.maddin.niofs.sftp;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import static org.hamcrest.Matchers.*;
import static org.junit.Assert.assertThat;

/**
* Tests splitting Path parts.
*/
@RunWith(Parameterized.class)
public class PartsTest {

private final String input;
private final List<String> result;

@Parameterized.Parameters(name = "{index}: {0} {1}")
public static List<Object[]> data() {

return Arrays.asList(
new Object[] {".", Arrays.asList(".")},
new Object[] {"", Arrays.asList("")},
new Object[] {"/", Arrays.asList("", "")},
new Object[] {"./", Arrays.asList(".", "")},
new Object[] {"/~", Arrays.asList("", "~")},
new Object[] {"aa", Arrays.asList("aa")},
new Object[] {"/aa/bb", Arrays.asList("", "aa", "bb")},
new Object[] {"/aa/../bb", Arrays.asList("", "aa", "..", "bb")},
new Object[] {"../", Arrays.asList("..", "")}
);
}

public PartsTest(String input, List<String> result) {
this.input = input;
this.result = result;
}

@Test
public void splitDot() {
SFTPPath path = new SFTPPath(null, input);

List<String> parts = path.getParts();

assertThat(parts, is(equalTo(this.result)));
// assertThat(parts, hasSize(1));
// assertThat(parts, hasItem(equalTo(".")));
}


}
26 changes: 24 additions & 2 deletions sftp/src/test/java/no/maddin/niofs/sftp/SFTPServerTest.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
package no.maddin.niofs.sftp;

import org.apache.sshd.common.NamedFactory;
import org.apache.sshd.common.file.virtualfs.VirtualFileSystemFactory;
import org.apache.sshd.server.Command;
import org.apache.sshd.server.SshServer;
import org.apache.sshd.server.auth.password.PasswordAuthenticator;
import org.apache.sshd.server.auth.password.PasswordChangeRequiredException;
import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
import org.apache.sshd.server.scp.ScpCommandFactory;
import org.apache.sshd.server.session.ServerSession;
import org.apache.sshd.server.shell.ProcessShellFactory;
import org.apache.sshd.server.subsystem.sftp.SftpSubsystem;
import org.apache.sshd.server.subsystem.sftp.SftpSubsystemFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
Expand All @@ -14,6 +22,9 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
Expand All @@ -27,6 +38,8 @@ public class SFTPServerTest {

private SshServer sshd;
private int port;
private String sftpUserame = "username";
private String sftpPassword = "password";

/**
* https://mina.apache.org/sshd-project/embedding_ssh.html
Expand All @@ -39,8 +52,17 @@ public void setupSftpServer() throws Exception {
serverSocket.close();
sshd.setPort(this.port);
sshd.setKeyPairProvider(new SimpleGeneratorHostKeyProvider(new File("target", "hostkey.ser")));
sshd.setPasswordAuthenticator(new PasswordAuthenticator() {
@Override
public boolean authenticate(String username, String password, ServerSession session) throws PasswordChangeRequiredException {
return sftpUserame.equals(username) && sftpPassword.equals(password);
}
});

sshd.setShellFactory(new ProcessShellFactory("/bin/sh", "-i", "-l"));
sshd.setSubsystemFactories(Collections.<NamedFactory<Command>>singletonList(new SftpSubsystemFactory()));
sshd.setFileSystemFactory(new VirtualFileSystemFactory(Paths.get(System.getProperty("user.dir"), "target")));

sshd.setShellFactory(new ProcessShellFactory(new String[]{"/bin/sh", "-i", "-l"}));
sshd.setCommandFactory(new ScpCommandFactory());
sshd.start();
}
Expand All @@ -53,7 +75,7 @@ public void stopServer() throws Exception {

@Test
public void createDirectories() throws Exception {
URI uri = new URI("sftp", "test", "localhost", port, "/a/b/", null, null);
URI uri = new URI("sftp", sftpUserame + ':' + sftpPassword, "localhost", port, "/~/a/b/", null, null);
Path path = Paths.get(uri);
Path newPath = Files.createDirectories(path);
assertThat(newPath, is(notNullValue()));
Expand Down
Loading

0 comments on commit 376fd45

Please sign in to comment.