From 63a1fb2c42b2aa1938936e7654b2789c22a416b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Hauenstein?= Date: Sun, 5 Nov 2017 21:29:53 +0100 Subject: [PATCH 01/21] Adding classes for smb2 / 3 implementation using SMBJ --- commons-vfs2/pom.xml | 698 +++++----- .../apache/commons/vfs2/impl/providers.xml | 257 ++-- .../commons/vfs2/provider/smb3/.gitignore | 1 + .../vfs2/provider/smb3/SMB3ClientWrapper.java | 158 +++ .../vfs2/provider/smb3/SMB3FileObject.java | 237 ++++ .../vfs2/provider/smb3/SMB3FileProvider.java | 71 ++ .../vfs2/provider/smb3/SMB3FileSystem.java | 58 + pom.xml | 1119 ++++++++--------- 8 files changed, 1552 insertions(+), 1047 deletions(-) create mode 100644 commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/.gitignore create mode 100644 commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3ClientWrapper.java create mode 100644 commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileObject.java create mode 100644 commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileProvider.java create mode 100644 commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileSystem.java diff --git a/commons-vfs2/pom.xml b/commons-vfs2/pom.xml index 31173bdb6f..45daca1741 100644 --- a/commons-vfs2/pom.xml +++ b/commons-vfs2/pom.xml @@ -1,369 +1,371 @@ - - http://www.apache.org/licenses/LICENSE-2.0 + - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - --> + 4.0.0 - + Apache Commons VFS + org.apache.commons + commons-vfs2 + 2.2.1-SNAPSHOT + Apache Commons VFS is a Virtual File System library. + http://commons.apache.org/proper/commons-vfs/ - 4.0.0 + + org.apache.commons + commons-vfs2-project + 2.2.1-SNAPSHOT + ../ + - Apache Commons VFS - org.apache.commons - commons-vfs2 - 2.2.1-SNAPSHOT - Apache Commons VFS is a Virtual File System library. - http://commons.apache.org/proper/commons-vfs/ + + + commons-logging + commons-logging + + + ant + ant + true + + + commons-net + commons-net + true + + + org.apache.commons + commons-compress + true + + + org.apache.commons + commons-collections4 + true + + + org.apache.hadoop + hadoop-common + true + + + org.apache.hadoop + hadoop-hdfs + true + + + commons-httpclient + commons-httpclient + true + + + org.apache.jackrabbit + jackrabbit-webdav + true + + + com.jcraft + jsch + true + + + + com.hierynomus + smbj + + + + org.slf4j + slf4j-simple + + + junit + junit + test + + + org.apache.commons + commons-lang3 + test + + + + org.apache.ftpserver + ftpserver-core + test + + + org.slf4j + slf4j-api + + + + org.apache.sshd + sshd-core + test + + + org.bouncycastle + bcprov-jdk16 + test + + + commons-io + commons-io + test + + + + org.apache.httpcomponents + httpcore-nio + test + + + + org.apache.jackrabbit + jackrabbit-standalone + test + + + + org.apache.hadoop + hadoop-common + test-jar + test + + + + jdk.tools + jdk.tools + + + + + org.apache.hadoop + hadoop-hdfs + test-jar + test + + + javax.ws.rs + jsr311-api + test + + - - org.apache.commons - commons-vfs2-project - 2.2.1-SNAPSHOT - ../ - + + ${basedir}/.. + - - - commons-logging - commons-logging - - - ant - ant - true - - - commons-net - commons-net - true - - - org.apache.commons - commons-compress - true - - - org.apache.commons - commons-collections4 - true - - - org.apache.hadoop - hadoop-common - true - - - org.apache.hadoop - hadoop-hdfs - true - - - commons-httpclient - commons-httpclient - true - - - org.apache.jackrabbit - jackrabbit-webdav - true - - - com.jcraft - jsch - true - + + + + src/main/java + + **/*.html + **/*.java + + + + + ${vfs.parent.dir} + META-INF + + NOTICE.txt + LICENSE.txt + + + - - junit - junit - test - - - org.apache.commons - commons-lang3 - test - - - - org.apache.ftpserver - ftpserver-core - test - - - org.slf4j - slf4j-api - test - - - - org.apache.sshd - sshd-core - test - - - org.bouncycastle - bcprov-jdk16 - test - - - commons-io - commons-io - test - - - - org.apache.httpcomponents - httpcore-nio - test - - - - org.apache.jackrabbit - jackrabbit-standalone - test - - - - org.apache.hadoop - hadoop-common - test-jar - test - - - - jdk.tools - jdk.tools - - - - - org.apache.hadoop - hadoop-hdfs - test-jar - test - - - javax.ws.rs - jsr311-api - test - - - - ${basedir}/.. - + + + src/test/resources + + + + ${vfs.parent.dir} + META-INF + + NOTICE.txt + LICENSE.txt + + + - - - - src/main/java - - **/*.html - **/*.java - - - - - ${vfs.parent.dir} - META-INF - - NOTICE.txt - LICENSE.txt - - - + + + org.apache.maven.plugins + maven-jar-plugin + + + + test-jar + + + + + + org.apache.maven.plugins + maven-antrun-plugin + + + process-test-classes + + + + + + + + + run + + + + - - - src/test/resources - - - - ${vfs.parent.dir} - META-INF - - NOTICE.txt - LICENSE.txt - - - + + org.apache.maven.plugins + maven-surefire-plugin + + false + + target/test-classes/test-data + test-data + target/derby.log + + + + **/RunTest.java + + **/*$* + + + + + - - - org.apache.maven.plugins - maven-jar-plugin - - - - test-jar - - - - + + + webdav + + false + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + ${test.webdav.uri} + + + + + + - - org.apache.maven.plugins - maven-antrun-plugin - - - process-test-classes - - - - - - - - - run - - - - + + ftp + + false + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + ${test.ftp.uri} + + + + + + - - org.apache.maven.plugins - maven-surefire-plugin - - false - - target/test-classes/test-data - test-data - target/derby.log - - - - **/RunTest.java - - **/*$* - - - - - + + sftp + + false + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + ${test.sftp.uri} + + + + + + - - - webdav - - false - - - - - org.apache.maven.plugins - maven-surefire-plugin - - - ${test.webdav.uri} - - - - - - + + http + + false + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + ${test.http.uri} + + + + + + - - ftp - - false - - - - - org.apache.maven.plugins - maven-surefire-plugin - - - ${test.ftp.uri} - - - - - - - - - sftp - - false - - - - - org.apache.maven.plugins - maven-surefire-plugin - - - ${test.sftp.uri} - - - - - - - - - http - - false - - - - - org.apache.maven.plugins - maven-surefire-plugin - - - ${test.http.uri} - - - - - - - - - - no-test-hdfs - - false - - Windows - - - - - - org.apache.maven.plugins - maven-surefire-plugin - - - **/HdfsFileProviderTest.java - **/HdfsFileProviderTestCase.java - - - - - - - + + + no-test-hdfs + + false + + Windows + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + **/HdfsFileProviderTest.java + **/HdfsFileProviderTestCase.java + + + + + + + diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/impl/providers.xml b/commons-vfs2/src/main/java/org/apache/commons/vfs2/impl/providers.xml index f8d571c848..8d7fab6051 100644 --- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/impl/providers.xml +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/impl/providers.xml @@ -1,144 +1,125 @@ - + - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - - - - - - - - - - - - + + + + + + + + + + + + - + diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/.gitignore b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/.gitignore new file mode 100644 index 0000000000..6dd38fcbc2 --- /dev/null +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/.gitignore @@ -0,0 +1 @@ +/SMB3FileNameParser.java diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3ClientWrapper.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3ClientWrapper.java new file mode 100644 index 0000000000..580f47e088 --- /dev/null +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3ClientWrapper.java @@ -0,0 +1,158 @@ +package org.apache.commons.vfs2.provider.smb3; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; + +import org.apache.commons.vfs2.FileSystemException; +import org.apache.commons.vfs2.FileSystemOptions; +import org.apache.commons.vfs2.provider.GenericFileName; + +import com.hierynomus.msdtyp.AccessMask; +import com.hierynomus.msfscc.FileAttributes; +import com.hierynomus.msfscc.fileinformation.FileAllInformation; +import com.hierynomus.msfscc.fileinformation.FileIdBothDirectoryInformation; +import com.hierynomus.mssmb2.SMB2CreateDisposition; +import com.hierynomus.mssmb2.SMB2CreateOptions; +import com.hierynomus.mssmb2.SMB2ShareAccess; +import com.hierynomus.smbj.SMBClient; +import com.hierynomus.smbj.auth.AuthenticationContext; +import com.hierynomus.smbj.connection.Connection; +import com.hierynomus.smbj.session.Session; +import com.hierynomus.smbj.share.DiskEntry; +import com.hierynomus.smbj.share.DiskShare; + +public class SMB3ClientWrapper extends SMBClient +{ + protected final FileSystemOptions fileSystemOptions; + private final GenericFileName root; + private SMBClient smbClient; + private Connection connection; + private Session session; + private DiskShare diskShare; + + protected SMB3ClientWrapper(final GenericFileName root, final FileSystemOptions fileSystemOptions) throws FileSystemException + { + this.root = root; + this.fileSystemOptions = fileSystemOptions; + smbClient = new SMBClient(); + setupClient(); + } + + private void setupClient() + { + final GenericFileName rootName = getRoot(); + + String userName = (rootName.getUserName().equals("") || rootName.getUserName() == null) ? "" : ((rootName.getUserName().contains(";") ? rootName.getUserName().substring(rootName.getUserName().indexOf(";")+1, rootName.getUserName().length()) : rootName.getUserName())); + String password = rootName.getPassword(); + String authDomain = (rootName.getUserName().contains(";") ? rootName.getUserName().substring(0, rootName.getUserName().indexOf(";")) : null); + AuthenticationContext authContext = new AuthenticationContext(userName, password.toCharArray(), authDomain); + setupClient(rootName, authContext); + + } + + protected void setupClient(final GenericFileName rootName, final AuthenticationContext authContext) + { + smbClient = new SMBClient(); + try + { + connection = smbClient.connect(rootName.getHostName()); + } catch (IOException e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } + session = connection.authenticate(authContext); + + String share = extractShare(rootName); + + diskShare = (DiskShare) session.connectShare(share); + } + + private String extractShare(final GenericFileName rootName) + { + if(rootName.getPath().equals("") || rootName.getPath().equals("/")) + { + return null; + } + String[] pathParts = (rootName.getPath().startsWith("/")) ? rootName.getPath().substring(1).split("/") : rootName.getPath().split("/"); + + return pathParts[0]; + } + + public GenericFileName getRoot() + { + return root; + } + + public FileAllInformation getFileInfo(String relPath) + { + try + { + return diskShare.getFileInformation(relPath); + } + catch(Exception e) + { + return null; + } + } + + public DiskEntry getDiskEntryWrite(String path) + { + DiskEntry diskEntryWrite = diskShare.open(path, + EnumSet.of(AccessMask.GENERIC_ALL), + EnumSet.of(FileAttributes.FILE_ATTRIBUTE_NORMAL), + EnumSet.of(SMB2ShareAccess.FILE_SHARE_WRITE), + SMB2CreateDisposition.FILE_OPEN_IF, + EnumSet.of(SMB2CreateOptions.FILE_NO_COMPRESSION)); + + return diskEntryWrite; + } + + public void createFolder(String path) + { + DiskEntry de = diskShare.openDirectory(path, + EnumSet.of(AccessMask.GENERIC_WRITE), + EnumSet.of(FileAttributes.FILE_ATTRIBUTE_NORMAL), + EnumSet.of(SMB2ShareAccess.FILE_SHARE_READ), + SMB2CreateDisposition.FILE_CREATE, + EnumSet.of(SMB2CreateOptions.FILE_DIRECTORY_FILE)); + + de.close(); + } + + public DiskEntry getDiskEntryRead(String path) + { + DiskEntry diskEntryRead = diskShare.open(path, + EnumSet.of(AccessMask.GENERIC_READ), + EnumSet.of(FileAttributes.FILE_ATTRIBUTE_NORMAL), + EnumSet.of(SMB2ShareAccess.FILE_SHARE_READ), + SMB2CreateDisposition.FILE_OPEN, + EnumSet.of(SMB2CreateOptions.FILE_NO_COMPRESSION)); + + return diskEntryRead; + } + + public String[] getChildren(String path) + { + List children = new ArrayList(); + + for(FileIdBothDirectoryInformation file : diskShare.list(path)) + { + String name = file.getFileName(); + if (name.equals(".") || name.equals("..") || name.equals("./") || name.equals("../")) + { + continue; + } + children.add(file.getFileName()); + } + return children.toArray(new String[children.size()]); + } + + public void delete(String path) + { + + diskShare.rm(path); + } +} diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileObject.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileObject.java new file mode 100644 index 0000000000..5738e3f82d --- /dev/null +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileObject.java @@ -0,0 +1,237 @@ +package org.apache.commons.vfs2.provider.smb3; + +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.vfs2.FileName; +import org.apache.commons.vfs2.FileObject; +import org.apache.commons.vfs2.FileSystemException; +import org.apache.commons.vfs2.FileType; +import org.apache.commons.vfs2.provider.AbstractFileName; +import org.apache.commons.vfs2.provider.AbstractFileObject; + +import com.hierynomus.msfscc.fileinformation.FileAllInformation; +import com.hierynomus.smbj.share.DiskEntry; +import com.hierynomus.smbj.share.File; + +public class SMB3FileObject extends AbstractFileObject +{ + private final String relPathToShare; + private FileAllInformation fileInfo; + private FileName rootName; + private DiskEntry diskEntryWrite; + private DiskEntry diskEntryRead; + + protected SMB3FileObject(AbstractFileName name, final SMB3FileSystem fs, final FileName rootName) + { + super(name, fs); + String relPath = name.getURI().substring(rootName.getURI().length()); + relPathToShare = relPath.startsWith("/") ? relPath.substring(1).replace("/", "\\") : relPath.replace("/", "\\"); + this.rootName = rootName; + } + + @Override + protected long doGetContentSize() throws Exception + { + // TODO Auto-generated method stub + return 0; + } + + @Override + protected InputStream doGetInputStream() throws Exception + { + if (diskEntryRead == null) + { + getDiskEntryRead(); + } + return ((File) diskEntryRead).getInputStream(); + } + + @Override + protected FileType doGetType() throws Exception + { + synchronized (getFileSystem()) + { + if (this.fileInfo == null) + { + getFileInfo(); + } + if (fileInfo == null) + { + return FileType.IMAGINARY; + } else + { + return (fileInfo.getStandardInformation().isDirectory()) ? FileType.FOLDER : FileType.FILE; + } + } + } + + private void getFileInfo() + { + synchronized (getFileSystem()) + { + SMB3FileSystem fileSystem = (SMB3FileSystem) getFileSystem(); + SMB3ClientWrapper client = (SMB3ClientWrapper) fileSystem.getClient(); + fileInfo = client.getFileInfo(relPathToShare); + } + } + + @Override + protected String[] doListChildren() throws Exception + { + // TODO Auto-generated method stub + return null; + } + + // make sure to return null if child is in share - root + @Override + public FileObject getParent() throws FileSystemException + { + if (getName().getBaseName().equals(relPathToShare)) + { + // return null; + + // test + synchronized (getFileSystem()) + { + AbstractFileName name = (AbstractFileName) getName().getParent(); + return new SMB3FileObject(name, (SMB3FileSystem) getFileSystem(), rootName); + } + + } + + synchronized (getFileSystem()) + { + AbstractFileName name = (AbstractFileName) getName().getParent(); + return new SMB3FileObject(name, (SMB3FileSystem) getFileSystem(), rootName); + } + } + + @Override + protected OutputStream doGetOutputStream(final boolean bAppend) throws Exception + { + if (diskEntryWrite == null) + { + getDiskEntryWrite(); + } + return ((File) diskEntryWrite).getOutputStream(); + } + + @Override + protected void doCreateFolder() throws Exception + { + try + { + synchronized (getFileSystem()) + { + SMB3FileSystem fileSystem = (SMB3FileSystem) getFileSystem(); + SMB3ClientWrapper client = (SMB3ClientWrapper) fileSystem.getClient(); + client.createFolder(relPathToShare); + } + } catch (Exception e) + { + throw new FileSystemException("Exception thrown creating folder: " + e.getCause()); + } + } + + @Override + protected void endOutput() throws Exception + { + super.endOutput(); + if (diskEntryWrite != null) + { + diskEntryWrite.close(); + } + } + + private void getDiskEntryWrite() throws Exception + { + try + { + synchronized (getFileSystem()) + { + SMB3FileSystem fileSystem = (SMB3FileSystem) getFileSystem(); + diskEntryWrite = fileSystem.getDiskEntryWrite(relPathToShare); + } + } catch (Exception e) + { + throw new FileSystemException("Exception thrown getting DiskEntry: " + e.getCause()); + } + } + + private void getDiskEntryRead() throws Exception + { + try + { + synchronized (getFileSystem()) + { + SMB3FileSystem fileSystem = (SMB3FileSystem) getFileSystem(); + diskEntryRead = fileSystem.getDiskEntryRead(relPathToShare); + // TODO check SmbPath to conversion / --> \\ + } + } catch (Exception e) + { + throw new FileSystemException("Exception thrown getting DiskEntry: " + e.getCause()); + } + } + + public String getRelPathToShare() + { + return relPathToShare; + } + + @Override + protected void doRename(final FileObject newFile) throws Exception + { + if (diskEntryWrite == null) + { + getDiskEntryWrite(); + } + SMB3FileObject fo = (SMB3FileObject) newFile; + diskEntryWrite.rename(fo.getRelPathToShare()); + + //TODO maybo obsoloete + endOutput(); + } + + @Override + protected FileObject[] doListChildrenResolved() throws Exception { + + synchronized (getFileSystem()) + { + List children = new ArrayList(); + + SMB3FileSystem fileSystem = (SMB3FileSystem) getFileSystem(); + SMB3ClientWrapper client = (SMB3ClientWrapper) fileSystem.getClient(); + String[] childrenNames = client.getChildren(relPathToShare); + + for(int i = 0; i < childrenNames.length; i++) + { + //String currentFolderURI = getName().getURI().endsWith("/") ? getName().getURI() : getName().getURI() + "/"; + //String childPath = currentFolderURI + childrenNames[i]; + children.add(fileSystem.getFileSystemManager().resolveFile(this, childrenNames[i])); + } + return children.toArray(new FileObject[children.size()]); + } + } + + @Override + protected void doDelete() throws Exception + { + synchronized (getFileSystem()) + { + if(diskEntryRead != null) + { + diskEntryRead.close(); + } + endOutput(); + + SMB3FileSystem fileSystem = (SMB3FileSystem) getFileSystem(); + SMB3ClientWrapper client = (SMB3ClientWrapper) fileSystem.getClient(); + client.delete(relPathToShare); + } + } + +} diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileProvider.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileProvider.java new file mode 100644 index 0000000000..fca4af4710 --- /dev/null +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileProvider.java @@ -0,0 +1,71 @@ +package org.apache.commons.vfs2.provider.smb3; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; + +import org.apache.commons.vfs2.Capability; +import org.apache.commons.vfs2.FileName; +import org.apache.commons.vfs2.FileSystem; +import org.apache.commons.vfs2.FileSystemException; +import org.apache.commons.vfs2.FileSystemOptions; +import org.apache.commons.vfs2.UserAuthenticationData; +import org.apache.commons.vfs2.provider.AbstractOriginatingFileProvider; +import org.apache.commons.vfs2.provider.GenericFileName; + +public class SMB3FileProvider extends AbstractOriginatingFileProvider +{ + + /** + * Authenticator types. + */ + public static final UserAuthenticationData.Type[] AUTHENTICATOR_TYPES = new UserAuthenticationData.Type[] { + UserAuthenticationData.USERNAME, UserAuthenticationData.PASSWORD }; + + static final Collection capabilities = Collections.unmodifiableCollection(Arrays + .asList(new Capability[] { Capability.CREATE, Capability.DELETE, Capability.RENAME, Capability.GET_TYPE, + Capability.LIST_CHILDREN, Capability.READ_CONTENT, Capability.GET_LAST_MODIFIED, Capability.URI, + Capability.WRITE_CONTENT, Capability.APPEND_CONTENT, Capability.RANDOM_ACCESS_READ, })); + + public SMB3FileProvider() + { + super(); + setFileNameParser(SMB3FileNameParser.getInstance()); + } + + + + @Override + public Collection getCapabilities() + { + // TODO Auto-generated method stub + return null; + } + + @Override + protected FileSystem doCreateFileSystem(FileName name, FileSystemOptions fileSystemOptions) + throws FileSystemException + { + final GenericFileName rootName = (GenericFileName) name; + + final SMB3ClientWrapper smbClient = new SMB3ClientWrapper(rootName, fileSystemOptions); + + return new SMB3FileSystem(rootName, fileSystemOptions, smbClient); + } + + @Override + public FileName parseUri(final FileName base, final String uri) throws FileSystemException { + if (getFileNameParser() != null) { + + if(uri.endsWith("//")) //TODO really parse if share is not in uri + { + return ((SMB3FileNameParser) getFileNameParser()).parseShareRoot(getContext(), base, uri); + } + + return getFileNameParser().parseUri(getContext(), base, uri); + } + + throw new FileSystemException("vfs.provider/filename-parser-missing.error"); + } + +} diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileSystem.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileSystem.java new file mode 100644 index 0000000000..52c205b878 --- /dev/null +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileSystem.java @@ -0,0 +1,58 @@ +package org.apache.commons.vfs2.provider.smb3; + +import java.util.Collection; +import java.util.concurrent.atomic.AtomicReference; + +import org.apache.commons.vfs2.Capability; +import org.apache.commons.vfs2.FileName; +import org.apache.commons.vfs2.FileObject; +import org.apache.commons.vfs2.FileSystemOptions; +import org.apache.commons.vfs2.provider.AbstractFileName; +import org.apache.commons.vfs2.provider.AbstractFileSystem; + +import com.hierynomus.smbj.SMBClient; +import com.hierynomus.smbj.share.DiskEntry; + +public class SMB3FileSystem extends AbstractFileSystem +{ + + //private SMBClient smbClient; + + private final AtomicReference client = new AtomicReference(); + + protected SMB3FileSystem(FileName rootName, FileSystemOptions fileSystemOptions, SMBClient smbClient) + { + super(rootName, null, fileSystemOptions); + //this.smbClient = smbClient; + client.set(smbClient); + } + + @Override + protected FileObject createFile(AbstractFileName name) throws Exception + { + return new SMB3FileObject(name, this, getRootName()); + } + + @Override + protected void addCapabilities(Collection caps) + { + caps.addAll(SMB3FileProvider.capabilities); + } + + public SMBClient getClient() + { + return (SMB3ClientWrapper) client.get(); + //return smbClient; + } + + public DiskEntry getDiskEntryWrite(String path) + { + return ((SMB3ClientWrapper) client.get()).getDiskEntryWrite(path); + } + + public DiskEntry getDiskEntryRead(String path) + { + return ((SMB3ClientWrapper) client.get()).getDiskEntryRead(path); + } + +} diff --git a/pom.xml b/pom.xml index 3f888518cd..83278ab8c1 100644 --- a/pom.xml +++ b/pom.xml @@ -1,589 +1,586 @@ - - http://www.apache.org/licenses/LICENSE-2.0 + + + org.apache.commons + commons-parent + 42 + - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - --> + 4.0.0 + commons-vfs2-project + Apache Commons VFS Project + Apache Commons VFS is a Virtual File System library. + pom + 2.2.1-SNAPSHOT - - - org.apache.commons - commons-parent - 42 - + http://commons.apache.org/proper/commons-vfs/ + 2002 - 4.0.0 - commons-vfs2-project - Apache Commons VFS Project - Apache Commons VFS is a Virtual File System library. - pom - 2.2.1-SNAPSHOT + + commons-vfs2 + commons-vfs2-examples + commons-vfs2-distribution + - http://commons.apache.org/proper/commons-vfs/ - 2002 + + jira + https://issues.apache.org/jira/browse/VFS + - - commons-vfs2 - commons-vfs2-examples - commons-vfs2-distribution - + + scm:svn:http://svn.apache.org/repos/asf/commons/proper/vfs/tags/commons-vfs2-project-2.2 + scm:svn:https://svn.apache.org/repos/asf/commons/proper/vfs/tags/commons-vfs2-project-2.2 + http://svn.apache.org/viewvc/commons/proper/vfs/tags/commons-vfs2-project-2.2 + - - jira - https://issues.apache.org/jira/browse/VFS - + + + Adam Murdoch + adammurdoch + adammurdoch -at- apache.org + + + + James Strachan + jstrachan + jstrachan -at- apache.org + SpiritSoft, Inc. + + + Mario Ivankovits + imario + imario -at- apache.org + OPS EDV Gmbh + + + Rahul Akolkar + rahul + rahul -at- apache.org + The Apache Software Foundation + + + James Carman + jcarman + jcarman -at- apache.org + The Apache Software Foundation + + + Ralph Goers + rgoers + rgoers -at- apache.org + Intuit + + + Joerg Schaible + joehni + joehni -at- apache.org + + + Gary D. Gregory + ggregory + ggregory -at- apache.org + http://www.garygregory.com + -5 + + + Bernd Eckenfels + ecki + ecki -at- apache.org + http://bernd.eckenfels.net + +1 + + - - scm:svn:http://svn.apache.org/repos/asf/commons/proper/vfs/tags/commons-vfs2-project-2.2 - scm:svn:https://svn.apache.org/repos/asf/commons/proper/vfs/tags/commons-vfs2-project-2.2 - http://svn.apache.org/viewvc/commons/proper/vfs/tags/commons-vfs2-project-2.2 - + + + Rami Ojares + rami.ojares -at- elisa.fi + + + Anthony Goubard + adagoubard -at- chello.nl + + + Christopher Ottley + xknight -at- users.sourceforge.net + + + Dave Marion + dlmarion -at- apache.org + + + Scott Bjerstedt + jcottbjer -at- gmail.com + + + Jose Juan Montiel + josejuan.montiel -at- gmail.com + + - - - Adam Murdoch - adammurdoch - adammurdoch -at- apache.org - - - - James Strachan - jstrachan - jstrachan -at- apache.org - SpiritSoft, Inc. - - - Mario Ivankovits - imario - imario -at- apache.org - OPS EDV Gmbh - - - Rahul Akolkar - rahul - rahul -at- apache.org - The Apache Software Foundation - - - James Carman - jcarman - jcarman -at- apache.org - The Apache Software Foundation - - - Ralph Goers - rgoers - rgoers -at- apache.org - Intuit - - - Joerg Schaible - joehni - joehni -at- apache.org - - - Gary D. Gregory - ggregory - ggregory -at- apache.org - http://www.garygregory.com - -5 - - - Bernd Eckenfels - ecki - ecki -at- apache.org - http://bernd.eckenfels.net - +1 - - + + UTF-8 - - - Rami Ojares - rami.ojares -at- elisa.fi - - - Anthony Goubard - adagoubard -at- chello.nl - - - Christopher Ottley - xknight -at- users.sourceforge.net - - - Dave Marion - dlmarion -at- apache.org - - - Scott Bjerstedt - jcottbjer -at- gmail.com - - - Jose Juan Montiel - josejuan.montiel -at- gmail.com - - + 1.7 + 1.7 - - UTF-8 + + vfs2 + org.apache.commons.vfs2 + VFS + 12310495 + https://svn.apache.org/repos/infra/websites/production/commons/content/proper/commons-vfs - 1.7 - 1.7 + 2.2 + + commons-vfs-${commons.release.version} + (requires Java 1.7+) + - - vfs2 - org.apache.commons.vfs2 - VFS - 12310495 - https://svn.apache.org/repos/infra/websites/production/commons/content/proper/commons-vfs + - 2.2 - - commons-vfs-${commons.release.version} - (requires Java 1.7+) - + ${basedir} + 2.17 + + + + 2.6 + + false + 2.6.0 + - + + + + ${basedir}/osgi + osgi + + MANIFEST.MF + + + - ${basedir} - 2.17 - - - - 2.6 - - false - 2.6.0 - + + + org.apache.maven.plugins + maven-antrun-plugin + + + vfs-jar-manifest + generate-sources + + run + + + + + + + + + + javadoc.resources + generate-sources + + run + + + + + + + + + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + -Xmx64m + + + + org.apache.maven.plugins + maven-checkstyle-plugin + ${version.checkstyle} + + + com.puppycrawl.tools + checkstyle + + 6.19 + + + + + + ${vfs.parent.dir}/checkstyle.xml + ${vfs.parent.dir}/checkstyle-suppressions.xml + false + basedir=${basedir} + + + + org.apache.rat + apache-rat-plugin + ${commons.rat.version} + + + + + src/test/resources/test-data/**/*.txt + src/test/resources/test-data/test.mf + + sandbox/** + + + + + - - - - ${basedir}/osgi - osgi - - MANIFEST.MF - - - + + + + org.apache.rat + apache-rat-plugin + ${commons.rat.version} + + + + + src/test/resources/test-data/**/*.txt + src/test/resources/test-data/test.mf + + sandbox/** + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + ${version.checkstyle} + + + + ${vfs.parent.dir}/checkstyle.xml + ${vfs.parent.dir}/checkstyle-suppressions.xml + false + basedir=${basedir} + + + + org.apache.maven.plugins + maven-javadoc-plugin + ${commons.javadoc.version} + + + + todo + + a + To Do: + + + true + + + + org.codehaus.mojo + findbugs-maven-plugin + + ${commons.findbugs.version} + + Normal + Default + ${vfs.parent.dir}/findbugs-exclude-filter.xml + + + + org.apache.maven.plugins + maven-pmd-plugin + 3.8 + + ${maven.compiler.target} + true + + + + + + + + - - - org.apache.maven.plugins - maven-antrun-plugin - - - vfs-jar-manifest - generate-sources - - run - - - - - - - - - - javadoc.resources - generate-sources - - run - - - - - - - - - - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - - - -Xmx64m - - - - org.apache.maven.plugins - maven-checkstyle-plugin - ${version.checkstyle} - - - com.puppycrawl.tools - checkstyle - - 6.19 - - - - - - ${vfs.parent.dir}/checkstyle.xml - ${vfs.parent.dir}/checkstyle-suppressions.xml - false - basedir=${basedir} - - - - org.apache.rat - apache-rat-plugin - ${commons.rat.version} - - - - - src/test/resources/test-data/**/*.txt - src/test/resources/test-data/test.mf - - sandbox/** - - - - - + + + + + org.apache.commons + commons-vfs2 + ${project.version} + + + org.apache.commons + commons-vfs2 + ${project.version} + test-jar + test + + + org.apache.commons + commons-vfs2-sandbox + ${project.version} + + + org.apache.commons + commons-vfs2-examples + ${project.version} + - - - - org.apache.rat - apache-rat-plugin - ${commons.rat.version} - - - - - src/test/resources/test-data/**/*.txt - src/test/resources/test-data/test.mf - - sandbox/** - - - - - org.apache.maven.plugins - maven-checkstyle-plugin - ${version.checkstyle} - - - - ${vfs.parent.dir}/checkstyle.xml - ${vfs.parent.dir}/checkstyle-suppressions.xml - false - basedir=${basedir} - - - - org.apache.maven.plugins - maven-javadoc-plugin - ${commons.javadoc.version} - - - - todo - - a - To Do: - - - true - - - - org.codehaus.mojo - findbugs-maven-plugin - - ${commons.findbugs.version} - - Normal - Default - ${vfs.parent.dir}/findbugs-exclude-filter.xml - - - - org.apache.maven.plugins - maven-pmd-plugin - 3.8 - - ${maven.compiler.target} - true - - - - - - - - + + + commons-logging + commons-logging + 1.2 + + + commons-net + commons-net + 3.6 + + + org.apache.commons + commons-collections4 + 4.1 + + + commons-httpclient + commons-httpclient + 3.1 + + + org.apache.commons + commons-compress + 1.15 + + + org.apache.jackrabbit + jackrabbit-webdav + 1.6.5 + + + ant + ant + 1.6.5 + + + com.jcraft + jsch + 0.1.54 + + + jcifs + jcifs + 1.3.17 + + + javax.mail + mail + 1.4.7 + + + org.apache.hadoop + hadoop-common + ${hadoop.version} + + + * + * + + + + + org.apache.hadoop + hadoop-hdfs + ${hadoop.version} + + + * + * + + + - - - - - org.apache.commons - commons-vfs2 - ${project.version} - - - org.apache.commons - commons-vfs2 - ${project.version} - test-jar - test - - - org.apache.commons - commons-vfs2-sandbox - ${project.version} - - - org.apache.commons - commons-vfs2-examples - ${project.version} - + + + com.hierynomus + smbj + 0.5.0 + - - - commons-logging - commons-logging - 1.2 - - - commons-net - commons-net - 3.6 - - - org.apache.commons - commons-collections4 - 4.1 - - - commons-httpclient - commons-httpclient - 3.1 - - - org.apache.commons - commons-compress - 1.15 - - - org.apache.jackrabbit - jackrabbit-webdav - 1.6.5 - - - ant - ant - 1.6.5 - - - com.jcraft - jsch - 0.1.54 - - - jcifs - jcifs - 1.3.17 - - - javax.mail - mail - 1.4.7 - - - org.apache.hadoop - hadoop-common - ${hadoop.version} - - - * - * - - - - - org.apache.hadoop - hadoop-hdfs - ${hadoop.version} - - - * - * - - - - - - junit - junit - 4.12 - - - org.apache.commons - commons-lang3 - 3.6 - - - - org.apache.ftpserver - ftpserver-core - 1.1.1 - - - org.slf4j - slf4j-api - 1.5.11 - - - org.slf4j - jcl-over-slf4j - 1.5.11 - - - - org.apache.sshd - sshd-core - 0.8.0 - - - org.apache.mina - mina-core - 2.0.7 - - - org.bouncycastle - bcprov-jdk16 - 1.46 - - - commons-io - commons-io - 2.6 - - - - org.apache.httpcomponents - httpcore-nio - 4.4.7 - - - - org.apache.jackrabbit - jackrabbit-standalone - 1.6.5 - - - - * - * - - - - - - org.apache.hadoop - hadoop-common - ${hadoop.version} - test-jar - - - - org.slf4j - slf4j-log4j12 - - - - - org.apache.hadoop - hadoop-hdfs - ${hadoop.version} - test-jar - - - javax.ws.rs - jsr311-api - 1.1.1 - - - + + + junit + junit + 4.12 + + + org.apache.commons + commons-lang3 + 3.6 + + + + org.apache.ftpserver + ftpserver-core + 1.1.1 + + + org.slf4j + slf4j-api + 1.5.11 + + + org.slf4j + slf4j-simple + 1.5.11 + + + org.slf4j + jcl-over-slf4j + 1.5.11 + + + + org.apache.sshd + sshd-core + 0.8.0 + + + org.apache.mina + mina-core + 2.0.7 + + + org.bouncycastle + bcprov-jdk16 + 1.46 + + + commons-io + commons-io + 2.6 + + + + org.apache.httpcomponents + httpcore-nio + 4.4.7 + + + + org.apache.jackrabbit + jackrabbit-standalone + 1.6.5 + + + + * + * + + + + + + org.apache.hadoop + hadoop-common + ${hadoop.version} + test-jar + + + + org.slf4j + slf4j-log4j12 + + + + + org.apache.hadoop + hadoop-hdfs + ${hadoop.version} + test-jar + + + javax.ws.rs + jsr311-api + 1.1.1 + + + - - - commons.site - Apache Commons Site - scm:svn:${commons.scmPubUrl} - - + + + commons.site + Apache Commons Site + scm:svn:${commons.scmPubUrl} + + - - - - include-sandbox - - sandbox - - - - release - - - - maven-assembly-plugin - - - - - true - - - - - - - + + + + include-sandbox + + sandbox + + + + release + + + + maven-assembly-plugin + + + + + true + + + + + + + - + - + \ No newline at end of file From 831deed6723a8fb69795c875f91385e6dee8fc30 Mon Sep 17 00:00:00 2001 From: hauensteina Date: Sun, 5 Nov 2017 21:40:34 +0100 Subject: [PATCH 02/21] FileNameParser somehow made it to the gitignore --- .../provider/smb3/SMB3FileNameParser.java | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileNameParser.java diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileNameParser.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileNameParser.java new file mode 100644 index 0000000000..cf3647688d --- /dev/null +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileNameParser.java @@ -0,0 +1,63 @@ +package org.apache.commons.vfs2.provider.smb3; + +import java.net.URI; +import java.net.URISyntaxException; + +import org.apache.commons.vfs2.FileName; +import org.apache.commons.vfs2.FileSystemException; +import org.apache.commons.vfs2.provider.HostFileNameParser; +import org.apache.commons.vfs2.provider.VfsComponentContext; + +public class SMB3FileNameParser extends HostFileNameParser { + + private static final SMB3FileNameParser INSTANCE = new SMB3FileNameParser(); + + private static final int PORT = 443; + + public SMB3FileNameParser() + { + super(PORT); + } + + public static SMB3FileNameParser getInstance() + { + return INSTANCE; + } + + public FileName parseShareRoot(VfsComponentContext ctx, FileName name, String path) throws FileSystemException + { + URI uri = null; + try + { + uri = new URI(name.getPath()); + } catch (URISyntaxException e) + { + //TODO logger write whats wrong... + e.printStackTrace(); + } + if(uri.toString().equals("/")) + { + //TODO logger no share submitted + return null; + } + String share = extractShareName(uri); + + while(path.endsWith("/") && path.length() > 0) + { + path = path.substring(0, path.length()-1); + } + + String rootPathShare = path + "/" + share + "/"; //add '/' to the end so the share gets parsed as folder by the HostFileNameParser + + return parseUri(ctx, name, rootPathShare); + } + + protected String extractShareName(URI uri) + { + String s = uri.getPath().startsWith("/") ? uri.getPath().substring(1) : uri.getPath(); + String[] pathParts = s.split("/"); + + return pathParts[0]; + } + +} \ No newline at end of file From e1db1f10efde9f90d346d22d3c31fd75b84b03b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Hauenstein?= Date: Mon, 6 Nov 2017 15:30:49 +0100 Subject: [PATCH 03/21] Wrap InputStream to close File Handle as well --- .../vfs2/provider/smb3/SMB3FileObject.java | 41 +++++++++++++++---- .../provider/smb3/SMB3InputStreamWrapper.java | 31 ++++++++++++++ 2 files changed, 64 insertions(+), 8 deletions(-) create mode 100644 commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3InputStreamWrapper.java diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileObject.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileObject.java index 5738e3f82d..244f00195c 100644 --- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileObject.java +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileObject.java @@ -35,18 +35,26 @@ protected SMB3FileObject(AbstractFileName name, final SMB3FileSystem fs, final F @Override protected long doGetContentSize() throws Exception { - // TODO Auto-generated method stub - return 0; + if(fileInfo == null) + { + getFileInfo(); + } + return fileInfo.getStandardInformation().getEndOfFile(); } @Override protected InputStream doGetInputStream() throws Exception { + if (!getType().hasContent()) { + throw new FileSystemException("vfs.provider/read-not-file.error", getName()); + } if (diskEntryRead == null) { getDiskEntryRead(); } - return ((File) diskEntryRead).getInputStream(); + InputStream is = ((File) diskEntryRead).getInputStream(); + SMB3InputStreamWrapper inputStream = new SMB3InputStreamWrapper(is, this); + return inputStream; } @Override @@ -140,14 +148,12 @@ protected void doCreateFolder() throws Exception protected void endOutput() throws Exception { super.endOutput(); - if (diskEntryWrite != null) - { - diskEntryWrite.close(); - } + closeAllHandles(); //force resolve } private void getDiskEntryWrite() throws Exception { + closeAllHandles(); try { synchronized (getFileSystem()) @@ -193,7 +199,7 @@ protected void doRename(final FileObject newFile) throws Exception diskEntryWrite.rename(fo.getRelPathToShare()); //TODO maybo obsoloete - endOutput(); + closeAllHandles(); } @Override @@ -234,4 +240,23 @@ protected void doDelete() throws Exception } } + @Override + public void close() throws FileSystemException + { + super.close(); + closeAllHandles(); + } + + private void closeAllHandles() + { + if(diskEntryRead != null) + { + diskEntryRead.close(); + } + if(diskEntryWrite != null) + { + diskEntryWrite.close(); + } + } + } diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3InputStreamWrapper.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3InputStreamWrapper.java new file mode 100644 index 0000000000..9e649a6bb7 --- /dev/null +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3InputStreamWrapper.java @@ -0,0 +1,31 @@ +package org.apache.commons.vfs2.provider.smb3; + +import java.io.IOException; +import java.io.InputStream; + +import org.apache.commons.vfs2.FileObject; + +public class SMB3InputStreamWrapper extends InputStream +{ + private InputStream is; + private final FileObject fo; + + public SMB3InputStreamWrapper(InputStream is, final FileObject fo) + { + this.is = is; + this.fo = fo; + } + + @Override + public int read() throws IOException + { + return is.read(); + } + + @Override + public void close() throws IOException + { + is.close(); + fo.close(); + } +} From 3010dcb406a2da87be625736feafe1d65d5fbe85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Hauenstein?= Date: Mon, 6 Nov 2017 15:49:20 +0100 Subject: [PATCH 04/21] FileObject closeAllHandles method set handles null after closing --- .../org/apache/commons/vfs2/provider/smb3/SMB3FileObject.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileObject.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileObject.java index 244f00195c..97c147394e 100644 --- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileObject.java +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileObject.java @@ -252,10 +252,12 @@ private void closeAllHandles() if(diskEntryRead != null) { diskEntryRead.close(); + diskEntryRead = null; } if(diskEntryWrite != null) { diskEntryWrite.close(); + diskEntryWrite = null; } } From 5725ed8e6ce46e0d834ebb4aa60f459b5416c3a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Hauenstein?= Date: Mon, 6 Nov 2017 16:06:57 +0100 Subject: [PATCH 05/21] Test m2e git plugin --- .../org/apache/commons/vfs2/provider/smb3/SMB3FileObject.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileObject.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileObject.java index 97c147394e..6fb5e427de 100644 --- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileObject.java +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileObject.java @@ -93,7 +93,7 @@ protected String[] doListChildren() throws Exception return null; } - // make sure to return null if child is in share - root + // make sure to return null if child is in share - root. @Override public FileObject getParent() throws FileSystemException { From 2d641d0a1ed8d70adc2aeef0565253c88d655d13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Hauenstein?= Date: Mon, 6 Nov 2017 16:54:56 +0100 Subject: [PATCH 06/21] Code cleanup & add comments where needed --- .../vfs2/provider/smb3/SMB3ClientWrapper.java | 51 ++++++++---- .../provider/smb3/SMB3FileNameParser.java | 22 ++++- .../vfs2/provider/smb3/SMB3FileObject.java | 48 +++++++---- .../vfs2/provider/smb3/SMB3FileProvider.java | 82 +++++++++++-------- .../vfs2/provider/smb3/SMB3FileSystem.java | 21 +++-- .../provider/smb3/SMB3InputStreamWrapper.java | 17 ++++ 6 files changed, 164 insertions(+), 77 deletions(-) diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3ClientWrapper.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3ClientWrapper.java index 580f47e088..7c1a07ac42 100644 --- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3ClientWrapper.java +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3ClientWrapper.java @@ -1,6 +1,21 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.apache.commons.vfs2.provider.smb3; -import java.io.IOException; import java.util.ArrayList; import java.util.EnumSet; import java.util.List; @@ -23,6 +38,11 @@ import com.hierynomus.smbj.share.DiskEntry; import com.hierynomus.smbj.share.DiskShare; +/** + * A wrapper to the SMBClient for bundling the related client & connection instances. + *

+ * The SMBClient ALWAYS needs a share. The share is part of the rootURI provided by the FileNameParser + */ public class SMB3ClientWrapper extends SMBClient { protected final FileSystemOptions fileSystemOptions; @@ -40,36 +60,34 @@ protected SMB3ClientWrapper(final GenericFileName root, final FileSystemOptions setupClient(); } - private void setupClient() + private void setupClient() throws FileSystemException { final GenericFileName rootName = getRoot(); + //the relevant data to authenticate a connection String userName = (rootName.getUserName().equals("") || rootName.getUserName() == null) ? "" : ((rootName.getUserName().contains(";") ? rootName.getUserName().substring(rootName.getUserName().indexOf(";")+1, rootName.getUserName().length()) : rootName.getUserName())); String password = rootName.getPassword(); String authDomain = (rootName.getUserName().contains(";") ? rootName.getUserName().substring(0, rootName.getUserName().indexOf(";")) : null); + + //if username == "" the client tries to authenticate "anonymously". It's also possible to summit "guets" as username AuthenticationContext authContext = new AuthenticationContext(userName, password.toCharArray(), authDomain); - setupClient(rootName, authContext); - } - - protected void setupClient(final GenericFileName rootName, final AuthenticationContext authContext) - { + //a connection stack is: SMBClient > Connection > Session > DiskShare smbClient = new SMBClient(); try { connection = smbClient.connect(rootName.getHostName()); - } catch (IOException e) + session = connection.authenticate(authContext); + String share = extractShare(rootName); + diskShare = (DiskShare) session.connectShare(share); + } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + throw new FileSystemException("Error while creation a connection: " + e.getCause()); } - session = connection.authenticate(authContext); - String share = extractShare(rootName); - - diskShare = (DiskShare) session.connectShare(share); } + //a share name MUST be provided, otherwise the client cannot connect to its base private String extractShare(final GenericFileName rootName) { if(rootName.getPath().equals("") || rootName.getPath().equals("/")) @@ -98,6 +116,7 @@ public FileAllInformation getFileInfo(String relPath) } } + //create a WRITE handle on the file public DiskEntry getDiskEntryWrite(String path) { DiskEntry diskEntryWrite = diskShare.open(path, @@ -110,6 +129,7 @@ public DiskEntry getDiskEntryWrite(String path) return diskEntryWrite; } + //creates a folder and immediately closes the handle public void createFolder(String path) { DiskEntry de = diskShare.openDirectory(path, @@ -122,6 +142,7 @@ public void createFolder(String path) de.close(); } + //creates a READ handle for the file public DiskEntry getDiskEntryRead(String path) { DiskEntry diskEntryRead = diskShare.open(path, @@ -134,6 +155,7 @@ public DiskEntry getDiskEntryRead(String path) return diskEntryRead; } + public String[] getChildren(String path) { List children = new ArrayList(); @@ -152,7 +174,6 @@ public String[] getChildren(String path) public void delete(String path) { - diskShare.rm(path); } } diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileNameParser.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileNameParser.java index cf3647688d..832df9f8c0 100644 --- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileNameParser.java +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileNameParser.java @@ -1,3 +1,19 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.apache.commons.vfs2.provider.smb3; import java.net.URI; @@ -32,16 +48,16 @@ public FileName parseShareRoot(VfsComponentContext ctx, FileName name, String pa uri = new URI(name.getPath()); } catch (URISyntaxException e) { - //TODO logger write whats wrong... - e.printStackTrace(); + throw new FileSystemException("URI invalid: FileSystem depends on it! " + e.getCause()); } if(uri.toString().equals("/")) { - //TODO logger no share submitted + //no share submitted, can not determine root return null; } String share = extractShareName(uri); + //dunno why sometimes the path ends up with two "/" at the end while(path.endsWith("/") && path.length() > 0) { path = path.substring(0, path.length()-1); diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileObject.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileObject.java index 6fb5e427de..b3f18caef0 100644 --- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileObject.java +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileObject.java @@ -1,3 +1,19 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.apache.commons.vfs2.provider.smb3; import java.io.InputStream; @@ -16,6 +32,13 @@ import com.hierynomus.smbj.share.DiskEntry; import com.hierynomus.smbj.share.File; +/** + * Class containing all its handles from the current Instance but NOT all possible handles to the same file!! + *

+ * Closing a stream (Input || Output) does not release the handle for the current file. The handle itself must be closed! Otherwise the file got locked up. + *

+ * All methos accessing the FileSystem are declared a synchronized for thread-safetyness + */ public class SMB3FileObject extends AbstractFileObject { private final String relPathToShare; @@ -28,6 +51,7 @@ protected SMB3FileObject(AbstractFileName name, final SMB3FileSystem fs, final F { super(name, fs); String relPath = name.getURI().substring(rootName.getURI().length()); + //smb shares do not accept "/" --> it needs a "\" which is represented by "\\" relPathToShare = relPath.startsWith("/") ? relPath.substring(1).replace("/", "\\") : relPath.replace("/", "\\"); this.rootName = rootName; } @@ -53,6 +77,8 @@ protected InputStream doGetInputStream() throws Exception getDiskEntryRead(); } InputStream is = ((File) diskEntryRead).getInputStream(); + + //wrapped to override the close method. For further details see SMB3InputStreamWrapper.class SMB3InputStreamWrapper inputStream = new SMB3InputStreamWrapper(is, this); return inputStream; } @@ -64,6 +90,7 @@ protected FileType doGetType() throws Exception { if (this.fileInfo == null) { + //returns null if the diskShare cannot the file info's. Therefore : imaginary getFileInfo(); } if (fileInfo == null) @@ -93,23 +120,9 @@ protected String[] doListChildren() throws Exception return null; } - // make sure to return null if child is in share - root. @Override public FileObject getParent() throws FileSystemException { - if (getName().getBaseName().equals(relPathToShare)) - { - // return null; - - // test - synchronized (getFileSystem()) - { - AbstractFileName name = (AbstractFileName) getName().getParent(); - return new SMB3FileObject(name, (SMB3FileSystem) getFileSystem(), rootName); - } - - } - synchronized (getFileSystem()) { AbstractFileName name = (AbstractFileName) getName().getParent(); @@ -148,7 +161,7 @@ protected void doCreateFolder() throws Exception protected void endOutput() throws Exception { super.endOutput(); - closeAllHandles(); //force resolve + closeAllHandles(); // also close the handles } private void getDiskEntryWrite() throws Exception @@ -175,7 +188,6 @@ private void getDiskEntryRead() throws Exception { SMB3FileSystem fileSystem = (SMB3FileSystem) getFileSystem(); diskEntryRead = fileSystem.getDiskEntryRead(relPathToShare); - // TODO check SmbPath to conversion / --> \\ } } catch (Exception e) { @@ -215,8 +227,7 @@ protected FileObject[] doListChildrenResolved() throws Exception { for(int i = 0; i < childrenNames.length; i++) { - //String currentFolderURI = getName().getURI().endsWith("/") ? getName().getURI() : getName().getURI() + "/"; - //String childPath = currentFolderURI + childrenNames[i]; + //resolve chil dusing resolve Fileobject and child name (just the baseName) children.add(fileSystem.getFileSystemManager().resolveFile(this, childrenNames[i])); } return children.toArray(new FileObject[children.size()]); @@ -240,6 +251,7 @@ protected void doDelete() throws Exception } } + //needs to be overridden to also close the file Handles when the FileObject is closed. Otherwise files got locked up @Override public void close() throws FileSystemException { diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileProvider.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileProvider.java index fca4af4710..604bccc5e4 100644 --- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileProvider.java +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileProvider.java @@ -1,3 +1,19 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.apache.commons.vfs2.provider.smb3; import java.util.Arrays; @@ -15,31 +31,28 @@ public class SMB3FileProvider extends AbstractOriginatingFileProvider { - + /** - * Authenticator types. - */ - public static final UserAuthenticationData.Type[] AUTHENTICATOR_TYPES = new UserAuthenticationData.Type[] { - UserAuthenticationData.USERNAME, UserAuthenticationData.PASSWORD }; - - static final Collection capabilities = Collections.unmodifiableCollection(Arrays - .asList(new Capability[] { Capability.CREATE, Capability.DELETE, Capability.RENAME, Capability.GET_TYPE, - Capability.LIST_CHILDREN, Capability.READ_CONTENT, Capability.GET_LAST_MODIFIED, Capability.URI, - Capability.WRITE_CONTENT, Capability.APPEND_CONTENT, Capability.RANDOM_ACCESS_READ, })); - - public SMB3FileProvider() - { - super(); - setFileNameParser(SMB3FileNameParser.getInstance()); - } - - + * Authenticator types. + */ + public static final UserAuthenticationData.Type[] AUTHENTICATOR_TYPES = new UserAuthenticationData.Type[] + { UserAuthenticationData.USERNAME, UserAuthenticationData.PASSWORD }; + + static final Collection capabilities = Collections.unmodifiableCollection(Arrays.asList(new Capability[] + { Capability.CREATE, Capability.DELETE, Capability.RENAME, Capability.GET_TYPE, Capability.LIST_CHILDREN, + Capability.READ_CONTENT, Capability.GET_LAST_MODIFIED, Capability.URI, Capability.WRITE_CONTENT, + Capability.APPEND_CONTENT, Capability.RANDOM_ACCESS_READ, })); + + public SMB3FileProvider() + { + super(); + setFileNameParser(SMB3FileNameParser.getInstance()); + } @Override public Collection getCapabilities() { - // TODO Auto-generated method stub - return null; + return capabilities; } @Override @@ -47,25 +60,22 @@ protected FileSystem doCreateFileSystem(FileName name, FileSystemOptions fileSys throws FileSystemException { final GenericFileName rootName = (GenericFileName) name; - final SMB3ClientWrapper smbClient = new SMB3ClientWrapper(rootName, fileSystemOptions); - return new SMB3FileSystem(rootName, fileSystemOptions, smbClient); } - - @Override - public FileName parseUri(final FileName base, final String uri) throws FileSystemException { - if (getFileNameParser() != null) { - - if(uri.endsWith("//")) //TODO really parse if share is not in uri - { - return ((SMB3FileNameParser) getFileNameParser()).parseShareRoot(getContext(), base, uri); - } - - return getFileNameParser().parseUri(getContext(), base, uri); - } - throw new FileSystemException("vfs.provider/filename-parser-missing.error"); - } + @Override + public FileName parseUri(final FileName base, final String uri) throws FileSystemException + { + if (getFileNameParser() != null) + { + if (uri.endsWith("//")) // TODO really parse if share is not in uri + { + return ((SMB3FileNameParser) getFileNameParser()).parseShareRoot(getContext(), base, uri); + } + return getFileNameParser().parseUri(getContext(), base, uri); + } + throw new FileSystemException("vfs.provider/filename-parser-missing.error"); + } } diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileSystem.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileSystem.java index 52c205b878..ceb87acb17 100644 --- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileSystem.java +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileSystem.java @@ -1,3 +1,19 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.apache.commons.vfs2.provider.smb3; import java.util.Collection; @@ -15,15 +31,11 @@ public class SMB3FileSystem extends AbstractFileSystem { - - //private SMBClient smbClient; - private final AtomicReference client = new AtomicReference(); protected SMB3FileSystem(FileName rootName, FileSystemOptions fileSystemOptions, SMBClient smbClient) { super(rootName, null, fileSystemOptions); - //this.smbClient = smbClient; client.set(smbClient); } @@ -42,7 +54,6 @@ protected void addCapabilities(Collection caps) public SMBClient getClient() { return (SMB3ClientWrapper) client.get(); - //return smbClient; } public DiskEntry getDiskEntryWrite(String path) diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3InputStreamWrapper.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3InputStreamWrapper.java index 9e649a6bb7..5fbc6732e1 100644 --- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3InputStreamWrapper.java +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3InputStreamWrapper.java @@ -1,3 +1,19 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.apache.commons.vfs2.provider.smb3; import java.io.IOException; @@ -22,6 +38,7 @@ public int read() throws IOException return is.read(); } + //the only reason this class exists @Override public void close() throws IOException { From 6e9b10eb7b9b777001cbc51f3e5615bae9523509 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Hauenstein?= Date: Mon, 6 Nov 2017 17:29:30 +0100 Subject: [PATCH 07/21] Folder move & rename fixed --- .../vfs2/provider/smb3/SMB3ClientWrapper.java | 14 ++++-- .../vfs2/provider/smb3/SMB3FileObject.java | 43 ++++++++++++++++--- .../vfs2/provider/smb3/SMB3FileSystem.java | 5 +++ 3 files changed, 52 insertions(+), 10 deletions(-) diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3ClientWrapper.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3ClientWrapper.java index 7c1a07ac42..5cdf37d3d6 100644 --- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3ClientWrapper.java +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3ClientWrapper.java @@ -131,17 +131,25 @@ public DiskEntry getDiskEntryWrite(String path) //creates a folder and immediately closes the handle public void createFolder(String path) + { + DiskEntry de = getDiskEntryFolderWrite(path); + de.close(); + } + + public DiskEntry getDiskEntryFolderWrite(String path) { DiskEntry de = diskShare.openDirectory(path, - EnumSet.of(AccessMask.GENERIC_WRITE), + EnumSet.of(AccessMask.GENERIC_ALL), EnumSet.of(FileAttributes.FILE_ATTRIBUTE_NORMAL), EnumSet.of(SMB2ShareAccess.FILE_SHARE_READ), - SMB2CreateDisposition.FILE_CREATE, + SMB2CreateDisposition.FILE_OPEN_IF, EnumSet.of(SMB2CreateOptions.FILE_DIRECTORY_FILE)); - de.close(); + return de; } + + //creates a READ handle for the file public DiskEntry getDiskEntryRead(String path) { diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileObject.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileObject.java index b3f18caef0..a6c3f01f46 100644 --- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileObject.java +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileObject.java @@ -46,6 +46,7 @@ public class SMB3FileObject extends AbstractFileObject private FileName rootName; private DiskEntry diskEntryWrite; private DiskEntry diskEntryRead; + private DiskEntry diskEntryFolderWrite; protected SMB3FileObject(AbstractFileName name, final SMB3FileSystem fs, final FileName rootName) { @@ -195,6 +196,22 @@ private void getDiskEntryRead() throws Exception } } + private void getDiskEntryFolderWrite() throws Exception + { + try + { + synchronized (getFileSystem()) + { + SMB3FileSystem fileSystem = (SMB3FileSystem) getFileSystem(); + diskEntryFolderWrite = fileSystem.getDiskEntryFolderWrite(relPathToShare); + } + } + catch(Exception e) + { + throw new FileSystemException("Exception thrown getting DiskEntry: " + e.getCause()); + } + } + public String getRelPathToShare() { return relPathToShare; @@ -203,15 +220,27 @@ public String getRelPathToShare() @Override protected void doRename(final FileObject newFile) throws Exception { - if (diskEntryWrite == null) + if(doGetType() == FileType.FOLDER) { - getDiskEntryWrite(); + if(diskEntryFolderWrite == null) + { + getDiskEntryFolderWrite(); + } + SMB3FileObject fo = (SMB3FileObject) newFile; + diskEntryFolderWrite.rename(fo.getRelPathToShare()); + } + else + { + if (diskEntryWrite == null) + { + getDiskEntryWrite(); + } + SMB3FileObject fo = (SMB3FileObject) newFile; + diskEntryWrite.rename(fo.getRelPathToShare()); + + //TODO maybo obsoloete + closeAllHandles(); } - SMB3FileObject fo = (SMB3FileObject) newFile; - diskEntryWrite.rename(fo.getRelPathToShare()); - - //TODO maybo obsoloete - closeAllHandles(); } @Override diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileSystem.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileSystem.java index ceb87acb17..f94c95eca6 100644 --- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileSystem.java +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileSystem.java @@ -65,5 +65,10 @@ public DiskEntry getDiskEntryRead(String path) { return ((SMB3ClientWrapper) client.get()).getDiskEntryRead(path); } + + public DiskEntry getDiskEntryFolderWrite(String path) + { + return ((SMB3ClientWrapper) client.get()).getDiskEntryFolderWrite(path); + } } From d48237c68b200aae6509183bffa7870e43095a40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Hauenstein?= Date: Mon, 6 Nov 2017 17:45:36 +0100 Subject: [PATCH 08/21] Rename SMB 3 -> 2 (used while prototyping) --- .../apache/commons/vfs2/impl/providers.xml | 4 +-- .../vfs2/provider/{smb3 => smb2}/.gitignore | 0 .../SMB2ClientWrapper.java} | 6 ++-- .../SMB2FileNameParser.java} | 10 +++--- .../SMB2FileObject.java} | 36 +++++++++---------- .../SMB2FileProvider.java} | 14 ++++---- .../SMB2FileSystem.java} | 18 +++++----- .../SMB2InputStreamWrapper.java} | 6 ++-- 8 files changed, 47 insertions(+), 47 deletions(-) rename commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/{smb3 => smb2}/.gitignore (100%) rename commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/{smb3/SMB3ClientWrapper.java => smb2/SMB2ClientWrapper.java} (97%) rename commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/{smb3/SMB3FileNameParser.java => smb2/SMB2FileNameParser.java} (89%) rename commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/{smb3/SMB3FileObject.java => smb2/SMB2FileObject.java} (86%) rename commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/{smb3/SMB3FileProvider.java => smb2/SMB2FileProvider.java} (87%) rename commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/{smb3/SMB3FileSystem.java => smb2/SMB2FileSystem.java} (78%) rename commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/{smb3/SMB3InputStreamWrapper.java => smb2/SMB2InputStreamWrapper.java} (87%) diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/impl/providers.xml b/commons-vfs2/src/main/java/org/apache/commons/vfs2/impl/providers.xml index 8d7fab6051..69fb4ab8e9 100644 --- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/impl/providers.xml +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/impl/providers.xml @@ -99,8 +99,8 @@ - - + + diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/.gitignore b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/.gitignore similarity index 100% rename from commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/.gitignore rename to commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/.gitignore diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3ClientWrapper.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2ClientWrapper.java similarity index 97% rename from commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3ClientWrapper.java rename to commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2ClientWrapper.java index 5cdf37d3d6..cef2f890a9 100644 --- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3ClientWrapper.java +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2ClientWrapper.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.vfs2.provider.smb3; +package org.apache.commons.vfs2.provider.smb2; import java.util.ArrayList; import java.util.EnumSet; @@ -43,7 +43,7 @@ *

* The SMBClient ALWAYS needs a share. The share is part of the rootURI provided by the FileNameParser */ -public class SMB3ClientWrapper extends SMBClient +public class SMB2ClientWrapper extends SMBClient { protected final FileSystemOptions fileSystemOptions; private final GenericFileName root; @@ -52,7 +52,7 @@ public class SMB3ClientWrapper extends SMBClient private Session session; private DiskShare diskShare; - protected SMB3ClientWrapper(final GenericFileName root, final FileSystemOptions fileSystemOptions) throws FileSystemException + protected SMB2ClientWrapper(final GenericFileName root, final FileSystemOptions fileSystemOptions) throws FileSystemException { this.root = root; this.fileSystemOptions = fileSystemOptions; diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileNameParser.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileNameParser.java similarity index 89% rename from commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileNameParser.java rename to commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileNameParser.java index 832df9f8c0..c4688395db 100644 --- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileNameParser.java +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileNameParser.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.vfs2.provider.smb3; +package org.apache.commons.vfs2.provider.smb2; import java.net.URI; import java.net.URISyntaxException; @@ -24,18 +24,18 @@ import org.apache.commons.vfs2.provider.HostFileNameParser; import org.apache.commons.vfs2.provider.VfsComponentContext; -public class SMB3FileNameParser extends HostFileNameParser { +public class SMB2FileNameParser extends HostFileNameParser { - private static final SMB3FileNameParser INSTANCE = new SMB3FileNameParser(); + private static final SMB2FileNameParser INSTANCE = new SMB2FileNameParser(); private static final int PORT = 443; - public SMB3FileNameParser() + public SMB2FileNameParser() { super(PORT); } - public static SMB3FileNameParser getInstance() + public static SMB2FileNameParser getInstance() { return INSTANCE; } diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileObject.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileObject.java similarity index 86% rename from commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileObject.java rename to commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileObject.java index a6c3f01f46..e7601b08f8 100644 --- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileObject.java +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileObject.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.vfs2.provider.smb3; +package org.apache.commons.vfs2.provider.smb2; import java.io.InputStream; import java.io.OutputStream; @@ -39,7 +39,7 @@ *

* All methos accessing the FileSystem are declared a synchronized for thread-safetyness */ -public class SMB3FileObject extends AbstractFileObject +public class SMB2FileObject extends AbstractFileObject { private final String relPathToShare; private FileAllInformation fileInfo; @@ -48,7 +48,7 @@ public class SMB3FileObject extends AbstractFileObject private DiskEntry diskEntryRead; private DiskEntry diskEntryFolderWrite; - protected SMB3FileObject(AbstractFileName name, final SMB3FileSystem fs, final FileName rootName) + protected SMB2FileObject(AbstractFileName name, final SMB2FileSystem fs, final FileName rootName) { super(name, fs); String relPath = name.getURI().substring(rootName.getURI().length()); @@ -80,7 +80,7 @@ protected InputStream doGetInputStream() throws Exception InputStream is = ((File) diskEntryRead).getInputStream(); //wrapped to override the close method. For further details see SMB3InputStreamWrapper.class - SMB3InputStreamWrapper inputStream = new SMB3InputStreamWrapper(is, this); + SMB2InputStreamWrapper inputStream = new SMB2InputStreamWrapper(is, this); return inputStream; } @@ -108,8 +108,8 @@ private void getFileInfo() { synchronized (getFileSystem()) { - SMB3FileSystem fileSystem = (SMB3FileSystem) getFileSystem(); - SMB3ClientWrapper client = (SMB3ClientWrapper) fileSystem.getClient(); + SMB2FileSystem fileSystem = (SMB2FileSystem) getFileSystem(); + SMB2ClientWrapper client = (SMB2ClientWrapper) fileSystem.getClient(); fileInfo = client.getFileInfo(relPathToShare); } } @@ -127,7 +127,7 @@ public FileObject getParent() throws FileSystemException synchronized (getFileSystem()) { AbstractFileName name = (AbstractFileName) getName().getParent(); - return new SMB3FileObject(name, (SMB3FileSystem) getFileSystem(), rootName); + return new SMB2FileObject(name, (SMB2FileSystem) getFileSystem(), rootName); } } @@ -148,8 +148,8 @@ protected void doCreateFolder() throws Exception { synchronized (getFileSystem()) { - SMB3FileSystem fileSystem = (SMB3FileSystem) getFileSystem(); - SMB3ClientWrapper client = (SMB3ClientWrapper) fileSystem.getClient(); + SMB2FileSystem fileSystem = (SMB2FileSystem) getFileSystem(); + SMB2ClientWrapper client = (SMB2ClientWrapper) fileSystem.getClient(); client.createFolder(relPathToShare); } } catch (Exception e) @@ -172,7 +172,7 @@ private void getDiskEntryWrite() throws Exception { synchronized (getFileSystem()) { - SMB3FileSystem fileSystem = (SMB3FileSystem) getFileSystem(); + SMB2FileSystem fileSystem = (SMB2FileSystem) getFileSystem(); diskEntryWrite = fileSystem.getDiskEntryWrite(relPathToShare); } } catch (Exception e) @@ -187,7 +187,7 @@ private void getDiskEntryRead() throws Exception { synchronized (getFileSystem()) { - SMB3FileSystem fileSystem = (SMB3FileSystem) getFileSystem(); + SMB2FileSystem fileSystem = (SMB2FileSystem) getFileSystem(); diskEntryRead = fileSystem.getDiskEntryRead(relPathToShare); } } catch (Exception e) @@ -202,7 +202,7 @@ private void getDiskEntryFolderWrite() throws Exception { synchronized (getFileSystem()) { - SMB3FileSystem fileSystem = (SMB3FileSystem) getFileSystem(); + SMB2FileSystem fileSystem = (SMB2FileSystem) getFileSystem(); diskEntryFolderWrite = fileSystem.getDiskEntryFolderWrite(relPathToShare); } } @@ -226,7 +226,7 @@ protected void doRename(final FileObject newFile) throws Exception { getDiskEntryFolderWrite(); } - SMB3FileObject fo = (SMB3FileObject) newFile; + SMB2FileObject fo = (SMB2FileObject) newFile; diskEntryFolderWrite.rename(fo.getRelPathToShare()); } else @@ -235,7 +235,7 @@ protected void doRename(final FileObject newFile) throws Exception { getDiskEntryWrite(); } - SMB3FileObject fo = (SMB3FileObject) newFile; + SMB2FileObject fo = (SMB2FileObject) newFile; diskEntryWrite.rename(fo.getRelPathToShare()); //TODO maybo obsoloete @@ -250,8 +250,8 @@ protected FileObject[] doListChildrenResolved() throws Exception { { List children = new ArrayList(); - SMB3FileSystem fileSystem = (SMB3FileSystem) getFileSystem(); - SMB3ClientWrapper client = (SMB3ClientWrapper) fileSystem.getClient(); + SMB2FileSystem fileSystem = (SMB2FileSystem) getFileSystem(); + SMB2ClientWrapper client = (SMB2ClientWrapper) fileSystem.getClient(); String[] childrenNames = client.getChildren(relPathToShare); for(int i = 0; i < childrenNames.length; i++) @@ -274,8 +274,8 @@ protected void doDelete() throws Exception } endOutput(); - SMB3FileSystem fileSystem = (SMB3FileSystem) getFileSystem(); - SMB3ClientWrapper client = (SMB3ClientWrapper) fileSystem.getClient(); + SMB2FileSystem fileSystem = (SMB2FileSystem) getFileSystem(); + SMB2ClientWrapper client = (SMB2ClientWrapper) fileSystem.getClient(); client.delete(relPathToShare); } } diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileProvider.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileProvider.java similarity index 87% rename from commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileProvider.java rename to commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileProvider.java index 604bccc5e4..25dcc6804c 100644 --- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileProvider.java +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileProvider.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.vfs2.provider.smb3; +package org.apache.commons.vfs2.provider.smb2; import java.util.Arrays; import java.util.Collection; @@ -29,7 +29,7 @@ import org.apache.commons.vfs2.provider.AbstractOriginatingFileProvider; import org.apache.commons.vfs2.provider.GenericFileName; -public class SMB3FileProvider extends AbstractOriginatingFileProvider +public class SMB2FileProvider extends AbstractOriginatingFileProvider { /** @@ -43,10 +43,10 @@ public class SMB3FileProvider extends AbstractOriginatingFileProvider Capability.READ_CONTENT, Capability.GET_LAST_MODIFIED, Capability.URI, Capability.WRITE_CONTENT, Capability.APPEND_CONTENT, Capability.RANDOM_ACCESS_READ, })); - public SMB3FileProvider() + public SMB2FileProvider() { super(); - setFileNameParser(SMB3FileNameParser.getInstance()); + setFileNameParser(SMB2FileNameParser.getInstance()); } @Override @@ -60,8 +60,8 @@ protected FileSystem doCreateFileSystem(FileName name, FileSystemOptions fileSys throws FileSystemException { final GenericFileName rootName = (GenericFileName) name; - final SMB3ClientWrapper smbClient = new SMB3ClientWrapper(rootName, fileSystemOptions); - return new SMB3FileSystem(rootName, fileSystemOptions, smbClient); + final SMB2ClientWrapper smbClient = new SMB2ClientWrapper(rootName, fileSystemOptions); + return new SMB2FileSystem(rootName, fileSystemOptions, smbClient); } @Override @@ -71,7 +71,7 @@ public FileName parseUri(final FileName base, final String uri) throws FileSyste { if (uri.endsWith("//")) // TODO really parse if share is not in uri { - return ((SMB3FileNameParser) getFileNameParser()).parseShareRoot(getContext(), base, uri); + return ((SMB2FileNameParser) getFileNameParser()).parseShareRoot(getContext(), base, uri); } return getFileNameParser().parseUri(getContext(), base, uri); } diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileSystem.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileSystem.java similarity index 78% rename from commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileSystem.java rename to commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileSystem.java index f94c95eca6..7ad918dec4 100644 --- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3FileSystem.java +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileSystem.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.vfs2.provider.smb3; +package org.apache.commons.vfs2.provider.smb2; import java.util.Collection; import java.util.concurrent.atomic.AtomicReference; @@ -29,11 +29,11 @@ import com.hierynomus.smbj.SMBClient; import com.hierynomus.smbj.share.DiskEntry; -public class SMB3FileSystem extends AbstractFileSystem +public class SMB2FileSystem extends AbstractFileSystem { private final AtomicReference client = new AtomicReference(); - protected SMB3FileSystem(FileName rootName, FileSystemOptions fileSystemOptions, SMBClient smbClient) + protected SMB2FileSystem(FileName rootName, FileSystemOptions fileSystemOptions, SMBClient smbClient) { super(rootName, null, fileSystemOptions); client.set(smbClient); @@ -42,33 +42,33 @@ protected SMB3FileSystem(FileName rootName, FileSystemOptions fileSystemOptions, @Override protected FileObject createFile(AbstractFileName name) throws Exception { - return new SMB3FileObject(name, this, getRootName()); + return new SMB2FileObject(name, this, getRootName()); } @Override protected void addCapabilities(Collection caps) { - caps.addAll(SMB3FileProvider.capabilities); + caps.addAll(SMB2FileProvider.capabilities); } public SMBClient getClient() { - return (SMB3ClientWrapper) client.get(); + return (SMB2ClientWrapper) client.get(); } public DiskEntry getDiskEntryWrite(String path) { - return ((SMB3ClientWrapper) client.get()).getDiskEntryWrite(path); + return ((SMB2ClientWrapper) client.get()).getDiskEntryWrite(path); } public DiskEntry getDiskEntryRead(String path) { - return ((SMB3ClientWrapper) client.get()).getDiskEntryRead(path); + return ((SMB2ClientWrapper) client.get()).getDiskEntryRead(path); } public DiskEntry getDiskEntryFolderWrite(String path) { - return ((SMB3ClientWrapper) client.get()).getDiskEntryFolderWrite(path); + return ((SMB2ClientWrapper) client.get()).getDiskEntryFolderWrite(path); } } diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3InputStreamWrapper.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2InputStreamWrapper.java similarity index 87% rename from commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3InputStreamWrapper.java rename to commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2InputStreamWrapper.java index 5fbc6732e1..9b396becfd 100644 --- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb3/SMB3InputStreamWrapper.java +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2InputStreamWrapper.java @@ -14,19 +14,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.vfs2.provider.smb3; +package org.apache.commons.vfs2.provider.smb2; import java.io.IOException; import java.io.InputStream; import org.apache.commons.vfs2.FileObject; -public class SMB3InputStreamWrapper extends InputStream +public class SMB2InputStreamWrapper extends InputStream { private InputStream is; private final FileObject fo; - public SMB3InputStreamWrapper(InputStream is, final FileObject fo) + public SMB2InputStreamWrapper(InputStream is, final FileObject fo) { this.is = is; this.fo = fo; From ac7639c95eef797d1cc65e848f09a8adf94bc131 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Hauenstein?= Date: Wed, 8 Nov 2017 17:38:44 +0100 Subject: [PATCH 09/21] Added SMB Config default: DFS enabled, Multiprotocol-Negotiation --- .../commons/vfs2/provider/smb2/SMB2ClientWrapper.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2ClientWrapper.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2ClientWrapper.java index cef2f890a9..e642f68b2f 100644 --- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2ClientWrapper.java +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2ClientWrapper.java @@ -32,6 +32,7 @@ import com.hierynomus.mssmb2.SMB2CreateOptions; import com.hierynomus.mssmb2.SMB2ShareAccess; import com.hierynomus.smbj.SMBClient; +import com.hierynomus.smbj.SmbConfig; import com.hierynomus.smbj.auth.AuthenticationContext; import com.hierynomus.smbj.connection.Connection; import com.hierynomus.smbj.session.Session; @@ -45,6 +46,11 @@ */ public class SMB2ClientWrapper extends SMBClient { + private static final SmbConfig CONFIG = SmbConfig.builder() + .withDfsEnabled(true) + .withMultiProtocolNegotiate(true) + .build(); + protected final FileSystemOptions fileSystemOptions; private final GenericFileName root; private SMBClient smbClient; @@ -56,7 +62,7 @@ protected SMB2ClientWrapper(final GenericFileName root, final FileSystemOptions { this.root = root; this.fileSystemOptions = fileSystemOptions; - smbClient = new SMBClient(); + smbClient = new SMBClient(CONFIG); setupClient(); } From a737d585c270622b57886116ba2773e823f006c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Hauenstein?= Date: Thu, 9 Nov 2017 15:36:17 +0100 Subject: [PATCH 10/21] Adding separate method to delete a folder --- .../vfs2/provider/smb2/SMB2ClientWrapper.java | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2ClientWrapper.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2ClientWrapper.java index e642f68b2f..182904f5bf 100644 --- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2ClientWrapper.java +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2ClientWrapper.java @@ -188,6 +188,25 @@ public String[] getChildren(String path) public void delete(String path) { - diskShare.rm(path); + FileAllInformation info = null; + try + { + info = diskShare.getFileInformation(path); + } + catch(Exception e) + { + //file or folder does not exist + return; + } + if(info.getStandardInformation().isDirectory()) + { + diskShare.rmdir(path, true); + } + else + { + diskShare.rm(path); + } } + + } From 0a58ac2a2c234aa98c5fc05e6aea66eb0ab506f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Hauenstein?= Date: Thu, 9 Nov 2017 16:03:44 +0100 Subject: [PATCH 11/21] Added ProviderTestCase --- .../smb2/test/SMB2ProviderTestCase.java | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/smb2/test/SMB2ProviderTestCase.java diff --git a/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/smb2/test/SMB2ProviderTestCase.java b/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/smb2/test/SMB2ProviderTestCase.java new file mode 100644 index 0000000000..3c481589cb --- /dev/null +++ b/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/smb2/test/SMB2ProviderTestCase.java @@ -0,0 +1,47 @@ +package org.apache.commons.vfs2.provider.smb2.test; + +import java.net.URI; +import java.net.URISyntaxException; + +import org.apache.commons.vfs2.FileObject; +import org.apache.commons.vfs2.FileSystemException; +import org.apache.commons.vfs2.FileSystemManager; +import org.apache.commons.vfs2.impl.DefaultFileSystemManager; +import org.apache.commons.vfs2.provider.smb2.SMB2FileProvider; +import org.apache.commons.vfs2.test.AbstractProviderTestConfig; +import org.apache.commons.vfs2.test.ProviderTestConfig; +import org.apache.commons.vfs2.test.ProviderTestSuite; + +import junit.framework.Test; +import junit.framework.TestSuite; + +public class SMB2ProviderTestCase extends AbstractProviderTestConfig implements ProviderTestConfig +{ + private final static String HOSTNAME = "localhost"; + private final static String USERINFO = "DOMAIN;test:test"; + private final static String SHARENAME = "share"; + private final static int PORT = 443; + + final TestSuite suite = new TestSuite(); + + public static Test suite() throws Exception + { + return new ProviderTestSuite(new SMB2ProviderTestCase()); + } + + public void prepare(final DefaultFileSystemManager manager) throws FileSystemException + { + manager.addProvider("smb2", new SMB2FileProvider()); + } + + public FileObject getBaseTestFolder(final FileSystemManager manager) throws Exception + { + return manager.resolveFile(buildURI().toString()); + } + + private URI buildURI() throws URISyntaxException + { + return new URI("smb2", USERINFO, HOSTNAME, PORT, ("/" + SHARENAME), null, null); + } + +} From 0e74e8a6080d88f3fdcc6bf2ffce2c282e9f4b3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Hauenstein?= Date: Fri, 10 Nov 2017 16:35:10 +0100 Subject: [PATCH 12/21] SMB2FileName added to keep the share - name in the root(uri). Fixed: getParent() when share root is reached --- .../vfs2/provider/smb2/SMB2ClientWrapper.java | 2 +- .../vfs2/provider/smb2/SMB2FileName.java | 74 +++++++++++++++ .../provider/smb2/SMB2FileNameParser.java | 94 +++++++++++++++---- .../vfs2/provider/smb2/SMB2FileObject.java | 5 + .../vfs2/provider/smb2/SMB2FileProvider.java | 11 ++- .../smb2/test/SMB2ProviderTestCase.java | 4 +- 6 files changed, 162 insertions(+), 28 deletions(-) create mode 100644 commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileName.java diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2ClientWrapper.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2ClientWrapper.java index 182904f5bf..744feab6d6 100644 --- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2ClientWrapper.java +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2ClientWrapper.java @@ -84,7 +84,7 @@ private void setupClient() throws FileSystemException { connection = smbClient.connect(rootName.getHostName()); session = connection.authenticate(authContext); - String share = extractShare(rootName); + String share = ((SMB2FileName) rootName).getShareName(); diskShare = (DiskShare) session.connectShare(share); } catch (Exception e) { diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileName.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileName.java new file mode 100644 index 0000000000..4cf60ca8e4 --- /dev/null +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileName.java @@ -0,0 +1,74 @@ +package org.apache.commons.vfs2.provider.smb2; + +import org.apache.commons.vfs2.FileName; +import org.apache.commons.vfs2.FileType; +import org.apache.commons.vfs2.provider.GenericFileName; + +public class SMB2FileName extends GenericFileName +{ + private final String shareName; + private String rootUri; + + + protected SMB2FileName(String scheme, String hostName, int port, int defaultPort, String userName, String password, + String path, FileType type, String shareName) + { + super(scheme, hostName, port, defaultPort, userName, password, path, type); + this.shareName = shareName; + } + + public String getShareName() + { + return shareName; + } + + @Override + public String getRootURI() { + if(this.rootUri == null) + { + String uri = super.getRootURI(); + this.rootUri = uri + shareName; + } + return this.rootUri; + } + + @Override + public FileName getParent() { + + if(this.rootUri == null) + { + getRootURI(); + } + + if(getPath().replaceAll("/", "").equals(shareName)) + { + return null; + } + else + { + SMB2FileName name = new SMB2FileName(this.getScheme(), this.getHostName(), this.getPort(), this.getDefaultPort(), this.getUserName(), this.getPassword(), getPath().substring(0, getPath().lastIndexOf("/")), this.getType(), shareName); + return name; + } + } + @Override + public String toString() + { + StringBuilder sb = new StringBuilder(); + sb.append(getScheme()); + sb.append("://"); + sb.append(getUserName()); + sb.append(':'); + sb.append(getPassword()); + sb.append('@'); + sb.append(getHostName()); + sb.append("/"); + sb.append(shareName); + if(!getPath().startsWith("/")) + { + sb.append('/'); + } + sb.append(getPath()); + return sb.toString(); + } + +} diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileNameParser.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileNameParser.java index c4688395db..e33def9022 100644 --- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileNameParser.java +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileNameParser.java @@ -17,7 +17,6 @@ package org.apache.commons.vfs2.provider.smb2; import java.net.URI; -import java.net.URISyntaxException; import org.apache.commons.vfs2.FileName; import org.apache.commons.vfs2.FileSystemException; @@ -40,40 +39,95 @@ public static SMB2FileNameParser getInstance() return INSTANCE; } - public FileName parseShareRoot(VfsComponentContext ctx, FileName name, String path) throws FileSystemException + protected String extractShareName(URI uri) { - URI uri = null; - try + String s = uri.getPath().startsWith("/") ? uri.getPath().substring(1) : uri.getPath(); + String[] pathParts = s.split("/"); + + return pathParts[0]; //TODO check share given by uri + } + + @Override + public FileName parseUri(final VfsComponentContext context, final FileName base, final String uri) throws FileSystemException + { + FileName parsedFileName = super.parseUri(context, base, uri); + String share; + if(base == null) { - uri = new URI(name.getPath()); - } catch (URISyntaxException e) + share = extractShareName(parseURIString(parsedFileName.toString())); + } + else + { + share = extractShareName(parseURIString(base.toString())); + } + + StringBuilder sb = new StringBuilder(); + Authority auth = extractToPath(parsedFileName.toString(), sb); + + String path; + + if(sb.length() == 0 || (sb.length() == 1 && sb.charAt(0) == '/')) { - throw new FileSystemException("URI invalid: FileSystem depends on it! " + e.getCause()); + //this must point to the share root + path = "/" + share; } - if(uri.toString().equals("/")) + else { - //no share submitted, can not determine root - return null; + path = parsedFileName.getPath(); } - String share = extractShareName(uri); - //dunno why sometimes the path ends up with two "/" at the end - while(path.endsWith("/") && path.length() > 0) + String relPathFromShare; + try + { + relPathFromShare = removeShareFromAbsPath(path, share); + } + catch(Exception e) { - path = path.substring(0, path.length()-1); + throw new FileSystemException("Share could not be remove from the absPath: " + e.getCause()); } - String rootPathShare = path + "/" + share + "/"; //add '/' to the end so the share gets parsed as folder by the HostFileNameParser + SMB2FileName fileName = new SMB2FileName(auth.getScheme(), auth.getHostName(), auth.getPort(), PORT, auth.getUserName(), auth.getPassword(), relPathFromShare, parsedFileName.getType(), share); + - return parseUri(ctx, name, rootPathShare); + return fileName; + } + + public URI parseURIString(String uriString) throws FileSystemException + { + try + { + return new URI(uriString); + } + catch (Exception e) + { + throw new FileSystemException("FileSystem needs a well formed URI: " + e.getCause()); + } } - protected String extractShareName(URI uri) + public String removeShareFromAbsPath(String path, String shareName) throws Exception { - String s = uri.getPath().startsWith("/") ? uri.getPath().substring(1) : uri.getPath(); - String[] pathParts = s.split("/"); + if(shareName == null || shareName.length() == 0) + { + throw new Exception("No path provided!"); + } + + String tmp = path.startsWith("/") ? path.substring(1) : path; - return pathParts[0]; + if(!tmp.substring(0, shareName.length()).equals(shareName)) { + throw new Exception("Share does not match the provided path!"); + } + + tmp = tmp.substring(shareName.length()); + + if(tmp.equals("") || tmp.equals("/")) + { + return ""; + } + return tmp; } + + + + } \ No newline at end of file diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileObject.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileObject.java index e7601b08f8..d7d6691715 100644 --- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileObject.java +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileObject.java @@ -302,4 +302,9 @@ private void closeAllHandles() } } + public String toString() + { + return getName().toString(); + } + } diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileProvider.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileProvider.java index 25dcc6804c..bddb6ec322 100644 --- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileProvider.java +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileProvider.java @@ -69,11 +69,12 @@ public FileName parseUri(final FileName base, final String uri) throws FileSyste { if (getFileNameParser() != null) { - if (uri.endsWith("//")) // TODO really parse if share is not in uri - { - return ((SMB2FileNameParser) getFileNameParser()).parseShareRoot(getContext(), base, uri); - } - return getFileNameParser().parseUri(getContext(), base, uri); + //if (uri.endsWith("//")) // TODO really parse if share is not in uri + //{ + //return ((SMB2FileNameParser) getFileNameParser()).parseShareRoot(getContext(), base, uri); + return getFileNameParser().parseUri(getContext(), base, uri); + //} + //return getFileNameParser().parseUri(getContext(), base, uri); } throw new FileSystemException("vfs.provider/filename-parser-missing.error"); } diff --git a/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/smb2/test/SMB2ProviderTestCase.java b/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/smb2/test/SMB2ProviderTestCase.java index 3c481589cb..961314d528 100644 --- a/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/smb2/test/SMB2ProviderTestCase.java +++ b/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/smb2/test/SMB2ProviderTestCase.java @@ -17,8 +17,8 @@ public class SMB2ProviderTestCase extends AbstractProviderTestConfig implements ProviderTestConfig { - private final static String HOSTNAME = "localhost"; - private final static String USERINFO = "DOMAIN;test:test"; + private final static String HOSTNAME = "192.168.2.35"; + private final static String USERINFO = "Administrator:2Ha17qnp3y"; private final static String SHARENAME = "share"; private final static int PORT = 443; From eb0e61ecd110a2e3bb7d0504354ef9df3b6cd13e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Hauenstein?= Date: Mon, 13 Nov 2017 07:51:33 +0100 Subject: [PATCH 13/21] doDetach sets fileInfo to null --- .../apache/commons/vfs2/provider/smb2/SMB2FileObject.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileObject.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileObject.java index d7d6691715..8414297590 100644 --- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileObject.java +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileObject.java @@ -302,6 +302,12 @@ private void closeAllHandles() } } + @Override + protected void doDetach() + { + this.fileInfo = null; + } + public String toString() { return getName().toString(); From 14b3cc68334a3bc8d0b81f27f6f97dd4c2cd4b1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Hauenstein?= Date: Mon, 13 Nov 2017 09:00:01 +0100 Subject: [PATCH 14/21] Override getURI to get correct URI including share go through cached files to check whether parent is already resolved --- .../vfs2/provider/smb2/SMB2FileName.java | 82 +++++++++++++++---- .../vfs2/provider/smb2/SMB2FileObject.java | 10 ++- 2 files changed, 74 insertions(+), 18 deletions(-) diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileName.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileName.java index 4cf60ca8e4..d78d1d5d86 100644 --- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileName.java +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileName.java @@ -8,48 +8,96 @@ public class SMB2FileName extends GenericFileName { private final String shareName; private String rootUri; - - + private String uri; + protected SMB2FileName(String scheme, String hostName, int port, int defaultPort, String userName, String password, String path, FileType type, String shareName) { super(scheme, hostName, port, defaultPort, userName, password, path, type); this.shareName = shareName; + createURI(); } - + public String getShareName() { return shareName; } - + + @Override + public String getFriendlyURI() + { + return createURI(false, false); + } + @Override - public String getRootURI() { - if(this.rootUri == null) + public String getURI() + { + if (uri == null) + { + uri = createURI(); + } + return uri; + } + + protected String createURI() + { + return createURI(false, true); + } + + private String createURI(final boolean useAbsolutePath, final boolean usePassword) + { + StringBuilder sb = new StringBuilder(); + appendRootUri(sb, usePassword); + if(sb.charAt(sb.length() -1 ) != '/') + { + sb.append('/'); + } + sb.append(shareName); + + if(!(getPath() == null || getPath().equals("/"))) + { + if(!getPath().startsWith("/")) + { + sb.append('/'); + } + sb.append(getPath()); + } + + return sb.toString(); + } + + @Override + public String getRootURI() + { + if (this.rootUri == null) { String uri = super.getRootURI(); this.rootUri = uri + shareName; } return this.rootUri; } - + @Override - public FileName getParent() { - - if(this.rootUri == null) + public FileName getParent() + { + + if (this.rootUri == null) { getRootURI(); } - - if(getPath().replaceAll("/", "").equals(shareName)) + + if (getPath().replaceAll("/", "").equals(shareName)) { return null; - } - else + } else { - SMB2FileName name = new SMB2FileName(this.getScheme(), this.getHostName(), this.getPort(), this.getDefaultPort(), this.getUserName(), this.getPassword(), getPath().substring(0, getPath().lastIndexOf("/")), this.getType(), shareName); + SMB2FileName name = new SMB2FileName(this.getScheme(), this.getHostName(), this.getPort(), + this.getDefaultPort(), this.getUserName(), this.getPassword(), + getPath().substring(0, getPath().lastIndexOf("/")), this.getType(), shareName); return name; } - } + } + @Override public String toString() { @@ -63,7 +111,7 @@ public String toString() sb.append(getHostName()); sb.append("/"); sb.append(shareName); - if(!getPath().startsWith("/")) + if (!getPath().startsWith("/")) { sb.append('/'); } diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileObject.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileObject.java index 8414297590..fe36d869c0 100644 --- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileObject.java +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileObject.java @@ -127,7 +127,15 @@ public FileObject getParent() throws FileSystemException synchronized (getFileSystem()) { AbstractFileName name = (AbstractFileName) getName().getParent(); - return new SMB2FileObject(name, (SMB2FileSystem) getFileSystem(), rootName); + FileObject cachedFile = getFileSystem().getFileSystemManager().getFilesCache().getFile(getFileSystem(), name); + if(cachedFile != null) + { + return cachedFile; + } + else + { + return new SMB2FileObject(name, (SMB2FileSystem) getFileSystem(), rootName); + } } } From 9638d9ced73121469dc84e0f163c136cf7a94ce8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Hauenstein?= Date: Mon, 13 Nov 2017 13:20:29 +0100 Subject: [PATCH 15/21] Using URIParse instead of URLEncoder/URLDecoder Removed RandomAccess from capabilities Added getLastModifiedTime Tests: testLoadClass & testSealing are not working on linux (it seems to be an known issue) --- .../vfs2/provider/smb2/SMB2FileName.java | 2 +- .../vfs2/provider/smb2/SMB2FileObject.java | 167 +++++++++++------- .../vfs2/provider/smb2/SMB2FileProvider.java | 3 +- 3 files changed, 108 insertions(+), 64 deletions(-) diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileName.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileName.java index d78d1d5d86..19e14686ac 100644 --- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileName.java +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileName.java @@ -86,7 +86,7 @@ public FileName getParent() getRootURI(); } - if (getPath().replaceAll("/", "").equals(shareName)) + if (getPath().replaceAll("/", "").equals(shareName) || getPath().equals("/") || getPath().equals("")) { return null; } else diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileObject.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileObject.java index fe36d869c0..e904522b53 100644 --- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileObject.java +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileObject.java @@ -18,6 +18,9 @@ import java.io.InputStream; import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.net.URLEncoder; import java.util.ArrayList; import java.util.List; @@ -27,17 +30,22 @@ import org.apache.commons.vfs2.FileType; import org.apache.commons.vfs2.provider.AbstractFileName; import org.apache.commons.vfs2.provider.AbstractFileObject; +import org.apache.commons.vfs2.provider.UriParser; import com.hierynomus.msfscc.fileinformation.FileAllInformation; import com.hierynomus.smbj.share.DiskEntry; import com.hierynomus.smbj.share.File; /** - * Class containing all its handles from the current Instance but NOT all possible handles to the same file!! + * Class containing all its handles from the current Instance but NOT all + * possible handles to the same file!! *

- * Closing a stream (Input || Output) does not release the handle for the current file. The handle itself must be closed! Otherwise the file got locked up. + * Closing a stream (Input || Output) does not release the handle for the + * current file. The handle itself must be closed! Otherwise the file got locked + * up. *

- * All methos accessing the FileSystem are declared a synchronized for thread-safetyness + * All methos accessing the FileSystem are declared a synchronized for + * thread-safetyness */ public class SMB2FileObject extends AbstractFileObject { @@ -52,7 +60,7 @@ protected SMB2FileObject(AbstractFileName name, final SMB2FileSystem fs, final F { super(name, fs); String relPath = name.getURI().substring(rootName.getURI().length()); - //smb shares do not accept "/" --> it needs a "\" which is represented by "\\" + // smb shares do not accept "/" --> it needs a "\" which is represented by "\\" relPathToShare = relPath.startsWith("/") ? relPath.substring(1).replace("/", "\\") : relPath.replace("/", "\\"); this.rootName = rootName; } @@ -60,26 +68,25 @@ protected SMB2FileObject(AbstractFileName name, final SMB2FileSystem fs, final F @Override protected long doGetContentSize() throws Exception { - if(fileInfo == null) - { - getFileInfo(); - } + getFileInfo(); return fileInfo.getStandardInformation().getEndOfFile(); } @Override protected InputStream doGetInputStream() throws Exception { - if (!getType().hasContent()) { - throw new FileSystemException("vfs.provider/read-not-file.error", getName()); - } + if (!getType().hasContent()) + { + throw new FileSystemException("vfs.provider/read-not-file.error", getName()); + } if (diskEntryRead == null) { getDiskEntryRead(); } InputStream is = ((File) diskEntryRead).getInputStream(); - - //wrapped to override the close method. For further details see SMB3InputStreamWrapper.class + + // wrapped to override the close method. For further details see + // SMB3InputStreamWrapper.class SMB2InputStreamWrapper inputStream = new SMB2InputStreamWrapper(is, this); return inputStream; } @@ -91,7 +98,7 @@ protected FileType doGetType() throws Exception { if (this.fileInfo == null) { - //returns null if the diskShare cannot the file info's. Therefore : imaginary + // returns null if the diskShare cannot the file info's. Therefore : imaginary getFileInfo(); } if (fileInfo == null) @@ -106,18 +113,22 @@ protected FileType doGetType() throws Exception private void getFileInfo() { - synchronized (getFileSystem()) + if (fileInfo == null) { - SMB2FileSystem fileSystem = (SMB2FileSystem) getFileSystem(); - SMB2ClientWrapper client = (SMB2ClientWrapper) fileSystem.getClient(); - fileInfo = client.getFileInfo(relPathToShare); + synchronized (getFileSystem()) + { + SMB2FileSystem fileSystem = (SMB2FileSystem) getFileSystem(); + SMB2ClientWrapper client = (SMB2ClientWrapper) fileSystem.getClient(); + fileInfo = client.getFileInfo(getRelPathToShare()); + } + } } @Override protected String[] doListChildren() throws Exception { - // TODO Auto-generated method stub + // not using this method return null; } @@ -127,12 +138,18 @@ public FileObject getParent() throws FileSystemException synchronized (getFileSystem()) { AbstractFileName name = (AbstractFileName) getName().getParent(); - FileObject cachedFile = getFileSystem().getFileSystemManager().getFilesCache().getFile(getFileSystem(), name); - if(cachedFile != null) + + // root folder has no parent + if (name == null) { - return cachedFile; + return null; } - else + FileObject cachedFile = getFileSystem().getFileSystemManager().getFilesCache().getFile(getFileSystem(), + name); + if (cachedFile != null) + { + return cachedFile; + } else { return new SMB2FileObject(name, (SMB2FileSystem) getFileSystem(), rootName); } @@ -146,6 +163,7 @@ protected OutputStream doGetOutputStream(final boolean bAppend) throws Exception { getDiskEntryWrite(); } + return ((File) diskEntryWrite).getOutputStream(); } @@ -158,7 +176,7 @@ protected void doCreateFolder() throws Exception { SMB2FileSystem fileSystem = (SMB2FileSystem) getFileSystem(); SMB2ClientWrapper client = (SMB2ClientWrapper) fileSystem.getClient(); - client.createFolder(relPathToShare); + client.createFolder(getRelPathToShare()); } } catch (Exception e) { @@ -181,7 +199,7 @@ private void getDiskEntryWrite() throws Exception synchronized (getFileSystem()) { SMB2FileSystem fileSystem = (SMB2FileSystem) getFileSystem(); - diskEntryWrite = fileSystem.getDiskEntryWrite(relPathToShare); + diskEntryWrite = fileSystem.getDiskEntryWrite(getRelPathToShare()); } } catch (Exception e) { @@ -196,14 +214,14 @@ private void getDiskEntryRead() throws Exception synchronized (getFileSystem()) { SMB2FileSystem fileSystem = (SMB2FileSystem) getFileSystem(); - diskEntryRead = fileSystem.getDiskEntryRead(relPathToShare); + diskEntryRead = fileSystem.getDiskEntryRead(getRelPathToShare()); } } catch (Exception e) { throw new FileSystemException("Exception thrown getting DiskEntry: " + e.getCause()); } } - + private void getDiskEntryFolderWrite() throws Exception { try @@ -211,33 +229,47 @@ private void getDiskEntryFolderWrite() throws Exception synchronized (getFileSystem()) { SMB2FileSystem fileSystem = (SMB2FileSystem) getFileSystem(); - diskEntryFolderWrite = fileSystem.getDiskEntryFolderWrite(relPathToShare); + diskEntryFolderWrite = fileSystem.getDiskEntryFolderWrite(getRelPathToShare()); } - } - catch(Exception e) + } catch (Exception e) { throw new FileSystemException("Exception thrown getting DiskEntry: " + e.getCause()); } } - + public String getRelPathToShare() { - return relPathToShare; + return decodeOrGet(relPathToShare); + } + + public String decodeOrGet(String s) + { + try + { + return UriParser.decode(s); + } catch (FileSystemException e) + { + return s; + } + } + + public String encodeOrGet(String s) + { + return UriParser.encode(s); } @Override protected void doRename(final FileObject newFile) throws Exception { - if(doGetType() == FileType.FOLDER) + if (doGetType() == FileType.FOLDER) { - if(diskEntryFolderWrite == null) + if (diskEntryFolderWrite == null) { getDiskEntryFolderWrite(); } SMB2FileObject fo = (SMB2FileObject) newFile; diskEntryFolderWrite.rename(fo.getRelPathToShare()); - } - else + } else { if (diskEntryWrite == null) { @@ -245,80 +277,93 @@ protected void doRename(final FileObject newFile) throws Exception } SMB2FileObject fo = (SMB2FileObject) newFile; diskEntryWrite.rename(fo.getRelPathToShare()); - - //TODO maybo obsoloete + + // TODO maybo obsoloete closeAllHandles(); } } @Override - protected FileObject[] doListChildrenResolved() throws Exception { - + protected FileObject[] doListChildrenResolved() throws Exception + { + synchronized (getFileSystem()) { + if (getType() != FileType.FOLDER) + { + throw new FileSystemException("vfs.provider/list-children-not-folder.error", this); + } + List children = new ArrayList(); - + SMB2FileSystem fileSystem = (SMB2FileSystem) getFileSystem(); SMB2ClientWrapper client = (SMB2ClientWrapper) fileSystem.getClient(); - String[] childrenNames = client.getChildren(relPathToShare); - - for(int i = 0; i < childrenNames.length; i++) + String[] childrenNames = client.getChildren(getRelPathToShare()); + + for (int i = 0; i < childrenNames.length; i++) { - //resolve chil dusing resolve Fileobject and child name (just the baseName) - children.add(fileSystem.getFileSystemManager().resolveFile(this, childrenNames[i])); + children.add(fileSystem.getFileSystemManager().resolveFile(this, encodeOrGet(childrenNames[i]))); } return children.toArray(new FileObject[children.size()]); } - } - + } + @Override - protected void doDelete() throws Exception + protected void doDelete() throws Exception { synchronized (getFileSystem()) { - if(diskEntryRead != null) + if (diskEntryRead != null) { diskEntryRead.close(); } endOutput(); - + SMB2FileSystem fileSystem = (SMB2FileSystem) getFileSystem(); SMB2ClientWrapper client = (SMB2ClientWrapper) fileSystem.getClient(); - client.delete(relPathToShare); + client.delete(getRelPathToShare()); } - } - - //needs to be overridden to also close the file Handles when the FileObject is closed. Otherwise files got locked up + } + + @Override + protected long doGetLastModifiedTime() throws Exception + { + getFileInfo(); + return fileInfo.getBasicInformation().getChangeTime().getWindowsTimeStamp(); + } + + // needs to be overridden to also close the file Handles when the FileObject is + // closed. Otherwise files got locked up @Override public void close() throws FileSystemException { super.close(); closeAllHandles(); } - + private void closeAllHandles() { - if(diskEntryRead != null) + if (diskEntryRead != null) { diskEntryRead.close(); diskEntryRead = null; } - if(diskEntryWrite != null) + if (diskEntryWrite != null) { diskEntryWrite.close(); diskEntryWrite = null; } } - + @Override protected void doDetach() { this.fileInfo = null; } - + public String toString() { return getName().toString(); } - + } diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileProvider.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileProvider.java index bddb6ec322..c9069ffc68 100644 --- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileProvider.java +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileProvider.java @@ -40,8 +40,7 @@ public class SMB2FileProvider extends AbstractOriginatingFileProvider static final Collection capabilities = Collections.unmodifiableCollection(Arrays.asList(new Capability[] { Capability.CREATE, Capability.DELETE, Capability.RENAME, Capability.GET_TYPE, Capability.LIST_CHILDREN, - Capability.READ_CONTENT, Capability.GET_LAST_MODIFIED, Capability.URI, Capability.WRITE_CONTENT, - Capability.APPEND_CONTENT, Capability.RANDOM_ACCESS_READ, })); + Capability.READ_CONTENT, Capability.GET_LAST_MODIFIED, Capability.URI, Capability.WRITE_CONTENT })); public SMB2FileProvider() { From b15551c8b3ab0ca4ada9a64ecb1dec90392ca81b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Hauenstein?= Date: Mon, 13 Nov 2017 13:29:22 +0100 Subject: [PATCH 16/21] clean --- .../vfs2/provider/smb2/SMB2ClientWrapper.java | 12 -------- .../vfs2/provider/smb2/SMB2FileName.java | 28 +++++++++++++++++-- .../vfs2/provider/smb2/SMB2FileObject.java | 3 -- 3 files changed, 26 insertions(+), 17 deletions(-) diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2ClientWrapper.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2ClientWrapper.java index 744feab6d6..2f641c66c1 100644 --- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2ClientWrapper.java +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2ClientWrapper.java @@ -93,18 +93,6 @@ private void setupClient() throws FileSystemException } - //a share name MUST be provided, otherwise the client cannot connect to its base - private String extractShare(final GenericFileName rootName) - { - if(rootName.getPath().equals("") || rootName.getPath().equals("/")) - { - return null; - } - String[] pathParts = (rootName.getPath().startsWith("/")) ? rootName.getPath().substring(1).split("/") : rootName.getPath().split("/"); - - return pathParts[0]; - } - public GenericFileName getRoot() { return root; diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileName.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileName.java index 19e14686ac..0f8904c9ed 100644 --- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileName.java +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileName.java @@ -1,9 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.apache.commons.vfs2.provider.smb2; import org.apache.commons.vfs2.FileName; import org.apache.commons.vfs2.FileType; import org.apache.commons.vfs2.provider.GenericFileName; +/** + * Using an explicit fileName for SMB2 since the uri must contain a share name. + *

+ * The share name belongs to the rootURI, whereas the AbsPath must not contain the share + */ public class SMB2FileName extends GenericFileName { private final String shareName; @@ -44,6 +65,7 @@ protected String createURI() return createURI(false, true); } + //the share needs to be inserted since it has been extracted from absPath (getPath()) private String createURI(final boolean useAbsolutePath, final boolean usePassword) { StringBuilder sb = new StringBuilder(); @@ -88,8 +110,9 @@ public FileName getParent() if (getPath().replaceAll("/", "").equals(shareName) || getPath().equals("/") || getPath().equals("")) { - return null; - } else + return null; //if this method is called from the root name, return null because there is no parent + } + else { SMB2FileName name = new SMB2FileName(this.getScheme(), this.getHostName(), this.getPort(), this.getDefaultPort(), this.getUserName(), this.getPassword(), @@ -98,6 +121,7 @@ public FileName getParent() } } + //inserting the share name since it has been extracted from the absPath @Override public String toString() { diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileObject.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileObject.java index e904522b53..12cbafd2af 100644 --- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileObject.java +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileObject.java @@ -18,9 +18,6 @@ import java.io.InputStream; import java.io.OutputStream; -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import java.net.URLEncoder; import java.util.ArrayList; import java.util.List; From 7b511b03399633d8c678aaaf32d4b0d8c55a82cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Hauenstein?= Date: Thu, 16 Nov 2017 11:56:35 +0100 Subject: [PATCH 17/21] Restored original pom.xml and removed smb2 test class --- commons-vfs2/pom.xml | 704 +++++------ .../smb2/test/SMB2ProviderTestCase.java | 47 - pom.xml | 1119 +++++++++-------- 3 files changed, 915 insertions(+), 955 deletions(-) delete mode 100644 commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/smb2/test/SMB2ProviderTestCase.java diff --git a/commons-vfs2/pom.xml b/commons-vfs2/pom.xml index 45daca1741..833cd34db3 100644 --- a/commons-vfs2/pom.xml +++ b/commons-vfs2/pom.xml @@ -1,371 +1,375 @@ - + - Apache Commons VFS - org.apache.commons - commons-vfs2 - 2.2.1-SNAPSHOT - Apache Commons VFS is a Virtual File System library. - http://commons.apache.org/proper/commons-vfs/ + - - org.apache.commons - commons-vfs2-project - 2.2.1-SNAPSHOT - ../ - + 4.0.0 - - - commons-logging - commons-logging - - - ant - ant - true - - - commons-net - commons-net - true - - - org.apache.commons - commons-compress - true - - - org.apache.commons - commons-collections4 - true - - - org.apache.hadoop - hadoop-common - true - - - org.apache.hadoop - hadoop-hdfs - true - - - commons-httpclient - commons-httpclient - true - - - org.apache.jackrabbit - jackrabbit-webdav - true - - - com.jcraft - jsch - true - - - - com.hierynomus - smbj - - - - org.slf4j - slf4j-simple - - - junit - junit - test - - - org.apache.commons - commons-lang3 - test - - - - org.apache.ftpserver - ftpserver-core - test - - - org.slf4j - slf4j-api - - - - org.apache.sshd - sshd-core - test - - - org.bouncycastle - bcprov-jdk16 - test - - - commons-io - commons-io - test - - - - org.apache.httpcomponents - httpcore-nio - test - - - - org.apache.jackrabbit - jackrabbit-standalone - test - - - - org.apache.hadoop - hadoop-common - test-jar - test - - - - jdk.tools - jdk.tools - - - - - org.apache.hadoop - hadoop-hdfs - test-jar - test - - - javax.ws.rs - jsr311-api - test - - + Apache Commons VFS + org.apache.commons + commons-vfs2 + 2.2.1-SNAPSHOT + Apache Commons VFS is a Virtual File System library. + http://commons.apache.org/proper/commons-vfs/ - - ${basedir}/.. - + + org.apache.commons + commons-vfs2-project + 2.2.1-SNAPSHOT + ../ + - - - - src/main/java - - **/*.html - **/*.java - - - - - ${vfs.parent.dir} - META-INF - - NOTICE.txt - LICENSE.txt - - - + + + commons-logging + commons-logging + + + ant + ant + true + + + commons-net + commons-net + true + + + org.apache.commons + commons-compress + true + + + org.apache.commons + commons-collections4 + true + + + org.apache.hadoop + hadoop-common + true + + + org.apache.hadoop + hadoop-hdfs + true + + + commons-httpclient + commons-httpclient + true + + + org.apache.jackrabbit + jackrabbit-webdav + true + + + com.jcraft + jsch + true + + + junit + junit + test + + + org.apache.commons + commons-lang3 + test + + + + org.apache.ftpserver + ftpserver-core + test + + + org.slf4j + slf4j-api + test + + + + org.apache.sshd + sshd-core + test + + + org.bouncycastle + bcprov-jdk16 + test + + + commons-io + commons-io + test + + + + org.apache.httpcomponents + httpcore-nio + test + + + + org.apache.jackrabbit + jackrabbit-standalone + test + + + + com.hierynomus + smbj + 0.5.1 + + + + org.apache.hadoop + hadoop-common + test-jar + test + + + + jdk.tools + jdk.tools + + + + + org.apache.hadoop + hadoop-hdfs + test-jar + test + + + javax.ws.rs + jsr311-api + test + + - - - src/test/resources - - - - ${vfs.parent.dir} - META-INF - - NOTICE.txt - LICENSE.txt - - - + + ${basedir}/.. + - - - org.apache.maven.plugins - maven-jar-plugin - - - - test-jar - - - - + + + + src/main/java + + **/*.html + **/*.java + + + + + ${vfs.parent.dir} + META-INF + + NOTICE.txt + LICENSE.txt + + + - - org.apache.maven.plugins - maven-antrun-plugin - - - process-test-classes - - - - - - - - - run - - - - - - org.apache.maven.plugins - maven-surefire-plugin - - false - - target/test-classes/test-data - test-data - target/derby.log - - - - **/RunTest.java - - **/*$* - - - - - + + + src/test/resources + + + + ${vfs.parent.dir} + META-INF + + NOTICE.txt + LICENSE.txt + + + - - - webdav - - false - - - - - org.apache.maven.plugins - maven-surefire-plugin - - - ${test.webdav.uri} - - - - - - + + + org.apache.maven.plugins + maven-jar-plugin + + + + test-jar + + + + - - ftp - - false - - - - - org.apache.maven.plugins - maven-surefire-plugin - - - ${test.ftp.uri} - - - - - - + + org.apache.maven.plugins + maven-antrun-plugin + + + process-test-classes + + + + + + + + + run + + + + - - sftp - - false - - - - - org.apache.maven.plugins - maven-surefire-plugin - - - ${test.sftp.uri} - - - - - - + + org.apache.maven.plugins + maven-surefire-plugin + + false + + target/test-classes/test-data + test-data + target/derby.log + + + + **/RunTest.java + + **/*$* + + + + + - - http - - false - - - - - org.apache.maven.plugins - maven-surefire-plugin - - - ${test.http.uri} - - - - - - + + + webdav + + false + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + ${test.webdav.uri} + + + + + + - - - no-test-hdfs - - false - - Windows - - - - - - org.apache.maven.plugins - maven-surefire-plugin - - - **/HdfsFileProviderTest.java - **/HdfsFileProviderTestCase.java - - - - - - - + + ftp + + false + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + ${test.ftp.uri} + + + + + + + + + sftp + + false + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + ${test.sftp.uri} + + + + + + + + + http + + false + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + ${test.http.uri} + + + + + + + + + + no-test-hdfs + + false + + Windows + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + **/HdfsFileProviderTest.java + **/HdfsFileProviderTestCase.java + + + + + + + diff --git a/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/smb2/test/SMB2ProviderTestCase.java b/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/smb2/test/SMB2ProviderTestCase.java deleted file mode 100644 index 961314d528..0000000000 --- a/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/smb2/test/SMB2ProviderTestCase.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.apache.commons.vfs2.provider.smb2.test; - -import java.net.URI; -import java.net.URISyntaxException; - -import org.apache.commons.vfs2.FileObject; -import org.apache.commons.vfs2.FileSystemException; -import org.apache.commons.vfs2.FileSystemManager; -import org.apache.commons.vfs2.impl.DefaultFileSystemManager; -import org.apache.commons.vfs2.provider.smb2.SMB2FileProvider; -import org.apache.commons.vfs2.test.AbstractProviderTestConfig; -import org.apache.commons.vfs2.test.ProviderTestConfig; -import org.apache.commons.vfs2.test.ProviderTestSuite; - -import junit.framework.Test; -import junit.framework.TestSuite; - -public class SMB2ProviderTestCase extends AbstractProviderTestConfig implements ProviderTestConfig -{ - private final static String HOSTNAME = "192.168.2.35"; - private final static String USERINFO = "Administrator:2Ha17qnp3y"; - private final static String SHARENAME = "share"; - private final static int PORT = 443; - - final TestSuite suite = new TestSuite(); - - public static Test suite() throws Exception - { - return new ProviderTestSuite(new SMB2ProviderTestCase()); - } - - public void prepare(final DefaultFileSystemManager manager) throws FileSystemException - { - manager.addProvider("smb2", new SMB2FileProvider()); - } - - public FileObject getBaseTestFolder(final FileSystemManager manager) throws Exception - { - return manager.resolveFile(buildURI().toString()); - } - - private URI buildURI() throws URISyntaxException - { - return new URI("smb2", USERINFO, HOSTNAME, PORT, ("/" + SHARENAME), null, null); - } - -} diff --git a/pom.xml b/pom.xml index 83278ab8c1..3f888518cd 100644 --- a/pom.xml +++ b/pom.xml @@ -1,586 +1,589 @@ - + - http://commons.apache.org/proper/commons-vfs/ - 2002 + + + org.apache.commons + commons-parent + 42 + - - commons-vfs2 - commons-vfs2-examples - commons-vfs2-distribution - + 4.0.0 + commons-vfs2-project + Apache Commons VFS Project + Apache Commons VFS is a Virtual File System library. + pom + 2.2.1-SNAPSHOT - - jira - https://issues.apache.org/jira/browse/VFS - + http://commons.apache.org/proper/commons-vfs/ + 2002 - - scm:svn:http://svn.apache.org/repos/asf/commons/proper/vfs/tags/commons-vfs2-project-2.2 - scm:svn:https://svn.apache.org/repos/asf/commons/proper/vfs/tags/commons-vfs2-project-2.2 - http://svn.apache.org/viewvc/commons/proper/vfs/tags/commons-vfs2-project-2.2 - + + commons-vfs2 + commons-vfs2-examples + commons-vfs2-distribution + - - - Adam Murdoch - adammurdoch - adammurdoch -at- apache.org - - - - James Strachan - jstrachan - jstrachan -at- apache.org - SpiritSoft, Inc. - - - Mario Ivankovits - imario - imario -at- apache.org - OPS EDV Gmbh - - - Rahul Akolkar - rahul - rahul -at- apache.org - The Apache Software Foundation - - - James Carman - jcarman - jcarman -at- apache.org - The Apache Software Foundation - - - Ralph Goers - rgoers - rgoers -at- apache.org - Intuit - - - Joerg Schaible - joehni - joehni -at- apache.org - - - Gary D. Gregory - ggregory - ggregory -at- apache.org - http://www.garygregory.com - -5 - - - Bernd Eckenfels - ecki - ecki -at- apache.org - http://bernd.eckenfels.net - +1 - - + + jira + https://issues.apache.org/jira/browse/VFS + - - - Rami Ojares - rami.ojares -at- elisa.fi - - - Anthony Goubard - adagoubard -at- chello.nl - - - Christopher Ottley - xknight -at- users.sourceforge.net - - - Dave Marion - dlmarion -at- apache.org - - - Scott Bjerstedt - jcottbjer -at- gmail.com - - - Jose Juan Montiel - josejuan.montiel -at- gmail.com - - + + scm:svn:http://svn.apache.org/repos/asf/commons/proper/vfs/tags/commons-vfs2-project-2.2 + scm:svn:https://svn.apache.org/repos/asf/commons/proper/vfs/tags/commons-vfs2-project-2.2 + http://svn.apache.org/viewvc/commons/proper/vfs/tags/commons-vfs2-project-2.2 + - - UTF-8 + + + Adam Murdoch + adammurdoch + adammurdoch -at- apache.org + + + + James Strachan + jstrachan + jstrachan -at- apache.org + SpiritSoft, Inc. + + + Mario Ivankovits + imario + imario -at- apache.org + OPS EDV Gmbh + + + Rahul Akolkar + rahul + rahul -at- apache.org + The Apache Software Foundation + + + James Carman + jcarman + jcarman -at- apache.org + The Apache Software Foundation + + + Ralph Goers + rgoers + rgoers -at- apache.org + Intuit + + + Joerg Schaible + joehni + joehni -at- apache.org + + + Gary D. Gregory + ggregory + ggregory -at- apache.org + http://www.garygregory.com + -5 + + + Bernd Eckenfels + ecki + ecki -at- apache.org + http://bernd.eckenfels.net + +1 + + - 1.7 - 1.7 + + + Rami Ojares + rami.ojares -at- elisa.fi + + + Anthony Goubard + adagoubard -at- chello.nl + + + Christopher Ottley + xknight -at- users.sourceforge.net + + + Dave Marion + dlmarion -at- apache.org + + + Scott Bjerstedt + jcottbjer -at- gmail.com + + + Jose Juan Montiel + josejuan.montiel -at- gmail.com + + - - vfs2 - org.apache.commons.vfs2 - VFS - 12310495 - https://svn.apache.org/repos/infra/websites/production/commons/content/proper/commons-vfs + + UTF-8 - 2.2 - - commons-vfs-${commons.release.version} - (requires Java 1.7+) - + 1.7 + 1.7 - + + vfs2 + org.apache.commons.vfs2 + VFS + 12310495 + https://svn.apache.org/repos/infra/websites/production/commons/content/proper/commons-vfs - ${basedir} - 2.17 - - - - 2.6 - - false - 2.6.0 - + 2.2 + + commons-vfs-${commons.release.version} + (requires Java 1.7+) + - - - - ${basedir}/osgi - osgi - - MANIFEST.MF - - - + - - - org.apache.maven.plugins - maven-antrun-plugin - - - vfs-jar-manifest - generate-sources - - run - - - - - - - - - - javadoc.resources - generate-sources - - run - - - - - - - - - - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - - - -Xmx64m - - - - org.apache.maven.plugins - maven-checkstyle-plugin - ${version.checkstyle} - - - com.puppycrawl.tools - checkstyle - - 6.19 - - - - - - ${vfs.parent.dir}/checkstyle.xml - ${vfs.parent.dir}/checkstyle-suppressions.xml - false - basedir=${basedir} - - - - org.apache.rat - apache-rat-plugin - ${commons.rat.version} - - - - - src/test/resources/test-data/**/*.txt - src/test/resources/test-data/test.mf - - sandbox/** - - - - - + ${basedir} + 2.17 + + + + 2.6 + + false + 2.6.0 + - - - - org.apache.rat - apache-rat-plugin - ${commons.rat.version} - - - - - src/test/resources/test-data/**/*.txt - src/test/resources/test-data/test.mf - - sandbox/** - - - - - org.apache.maven.plugins - maven-checkstyle-plugin - ${version.checkstyle} - - - - ${vfs.parent.dir}/checkstyle.xml - ${vfs.parent.dir}/checkstyle-suppressions.xml - false - basedir=${basedir} - - - - org.apache.maven.plugins - maven-javadoc-plugin - ${commons.javadoc.version} - - - - todo - - a - To Do: - - - true - - - - org.codehaus.mojo - findbugs-maven-plugin - - ${commons.findbugs.version} - - Normal - Default - ${vfs.parent.dir}/findbugs-exclude-filter.xml - - - - org.apache.maven.plugins - maven-pmd-plugin - 3.8 - - ${maven.compiler.target} - true - - - - - - - - + + + + ${basedir}/osgi + osgi + + MANIFEST.MF + + + - - - - - org.apache.commons - commons-vfs2 - ${project.version} - - - org.apache.commons - commons-vfs2 - ${project.version} - test-jar - test - - - org.apache.commons - commons-vfs2-sandbox - ${project.version} - - - org.apache.commons - commons-vfs2-examples - ${project.version} - + + + org.apache.maven.plugins + maven-antrun-plugin + + + vfs-jar-manifest + generate-sources + + run + + + + + + + + + + javadoc.resources + generate-sources + + run + + + + + + + + + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + -Xmx64m + + + + org.apache.maven.plugins + maven-checkstyle-plugin + ${version.checkstyle} + + + com.puppycrawl.tools + checkstyle + + 6.19 + + + + + + ${vfs.parent.dir}/checkstyle.xml + ${vfs.parent.dir}/checkstyle-suppressions.xml + false + basedir=${basedir} + + + + org.apache.rat + apache-rat-plugin + ${commons.rat.version} + + + + + src/test/resources/test-data/**/*.txt + src/test/resources/test-data/test.mf + + sandbox/** + + + + + - - - commons-logging - commons-logging - 1.2 - - - commons-net - commons-net - 3.6 - - - org.apache.commons - commons-collections4 - 4.1 - - - commons-httpclient - commons-httpclient - 3.1 - - - org.apache.commons - commons-compress - 1.15 - - - org.apache.jackrabbit - jackrabbit-webdav - 1.6.5 - - - ant - ant - 1.6.5 - - - com.jcraft - jsch - 0.1.54 - - - jcifs - jcifs - 1.3.17 - - - javax.mail - mail - 1.4.7 - - - org.apache.hadoop - hadoop-common - ${hadoop.version} - - - * - * - - - - - org.apache.hadoop - hadoop-hdfs - ${hadoop.version} - - - * - * - - - + + + + org.apache.rat + apache-rat-plugin + ${commons.rat.version} + + + + + src/test/resources/test-data/**/*.txt + src/test/resources/test-data/test.mf + + sandbox/** + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + ${version.checkstyle} + + + + ${vfs.parent.dir}/checkstyle.xml + ${vfs.parent.dir}/checkstyle-suppressions.xml + false + basedir=${basedir} + + + + org.apache.maven.plugins + maven-javadoc-plugin + ${commons.javadoc.version} + + + + todo + + a + To Do: + + + true + + + + org.codehaus.mojo + findbugs-maven-plugin + + ${commons.findbugs.version} + + Normal + Default + ${vfs.parent.dir}/findbugs-exclude-filter.xml + + + + org.apache.maven.plugins + maven-pmd-plugin + 3.8 + + ${maven.compiler.target} + true + + + + + + + + - - - com.hierynomus - smbj - 0.5.0 - + + + + + org.apache.commons + commons-vfs2 + ${project.version} + + + org.apache.commons + commons-vfs2 + ${project.version} + test-jar + test + + + org.apache.commons + commons-vfs2-sandbox + ${project.version} + + + org.apache.commons + commons-vfs2-examples + ${project.version} + + + + commons-logging + commons-logging + 1.2 + + + commons-net + commons-net + 3.6 + + + org.apache.commons + commons-collections4 + 4.1 + + + commons-httpclient + commons-httpclient + 3.1 + + + org.apache.commons + commons-compress + 1.15 + + + org.apache.jackrabbit + jackrabbit-webdav + 1.6.5 + + + ant + ant + 1.6.5 + + + com.jcraft + jsch + 0.1.54 + + + jcifs + jcifs + 1.3.17 + + + javax.mail + mail + 1.4.7 + + + org.apache.hadoop + hadoop-common + ${hadoop.version} + + + * + * + + + + + org.apache.hadoop + hadoop-hdfs + ${hadoop.version} + + + * + * + + + - - - junit - junit - 4.12 - - - org.apache.commons - commons-lang3 - 3.6 - - - - org.apache.ftpserver - ftpserver-core - 1.1.1 - - - org.slf4j - slf4j-api - 1.5.11 - - - org.slf4j - slf4j-simple - 1.5.11 - - - org.slf4j - jcl-over-slf4j - 1.5.11 - - - - org.apache.sshd - sshd-core - 0.8.0 - - - org.apache.mina - mina-core - 2.0.7 - - - org.bouncycastle - bcprov-jdk16 - 1.46 - - - commons-io - commons-io - 2.6 - - - - org.apache.httpcomponents - httpcore-nio - 4.4.7 - - - - org.apache.jackrabbit - jackrabbit-standalone - 1.6.5 - - - - * - * - - - - - - org.apache.hadoop - hadoop-common - ${hadoop.version} - test-jar - - - - org.slf4j - slf4j-log4j12 - - - - - org.apache.hadoop - hadoop-hdfs - ${hadoop.version} - test-jar - - - javax.ws.rs - jsr311-api - 1.1.1 - - - + + + junit + junit + 4.12 + + + org.apache.commons + commons-lang3 + 3.6 + + + + org.apache.ftpserver + ftpserver-core + 1.1.1 + + + org.slf4j + slf4j-api + 1.5.11 + + + org.slf4j + jcl-over-slf4j + 1.5.11 + + + + org.apache.sshd + sshd-core + 0.8.0 + + + org.apache.mina + mina-core + 2.0.7 + + + org.bouncycastle + bcprov-jdk16 + 1.46 + + + commons-io + commons-io + 2.6 + + + + org.apache.httpcomponents + httpcore-nio + 4.4.7 + + + + org.apache.jackrabbit + jackrabbit-standalone + 1.6.5 + + + + * + * + + + + + + org.apache.hadoop + hadoop-common + ${hadoop.version} + test-jar + + + + org.slf4j + slf4j-log4j12 + + + + + org.apache.hadoop + hadoop-hdfs + ${hadoop.version} + test-jar + + + javax.ws.rs + jsr311-api + 1.1.1 + + + - - - commons.site - Apache Commons Site - scm:svn:${commons.scmPubUrl} - - + + + commons.site + Apache Commons Site + scm:svn:${commons.scmPubUrl} + + - - - - include-sandbox - - sandbox - - - - release - - - - maven-assembly-plugin - - - - - true - - - - - - - + + + + include-sandbox + + sandbox + + + + release + + + + maven-assembly-plugin + + + + + true + + + + + + + - + - \ No newline at end of file + From d13d982f3db7552eddcdb82a79609ee0f1210f41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Hauenstein?= Date: Mon, 20 Nov 2017 15:38:29 +0100 Subject: [PATCH 18/21] Fix: SmbConfig accidentally overwritten --- .../org/apache/commons/vfs2/provider/smb2/SMB2ClientWrapper.java | 1 - 1 file changed, 1 deletion(-) diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2ClientWrapper.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2ClientWrapper.java index 2f641c66c1..2cd1c66899 100644 --- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2ClientWrapper.java +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2ClientWrapper.java @@ -79,7 +79,6 @@ private void setupClient() throws FileSystemException AuthenticationContext authContext = new AuthenticationContext(userName, password.toCharArray(), authDomain); //a connection stack is: SMBClient > Connection > Session > DiskShare - smbClient = new SMBClient(); try { connection = smbClient.connect(rootName.getHostName()); From 688a290a034fa3e55fdeed7f85aa88bb4435fb90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Hauenstein?= Date: Tue, 21 Nov 2017 13:48:50 +0100 Subject: [PATCH 19/21] Changed Write-Access from GENERIC_ALL to MAXIMUM_ALLOWED. GENERIC_ALL needs FullControl --- .../apache/commons/vfs2/provider/smb2/SMB2ClientWrapper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2ClientWrapper.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2ClientWrapper.java index 2cd1c66899..cfb803acd1 100644 --- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2ClientWrapper.java +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2ClientWrapper.java @@ -113,7 +113,7 @@ public FileAllInformation getFileInfo(String relPath) public DiskEntry getDiskEntryWrite(String path) { DiskEntry diskEntryWrite = diskShare.open(path, - EnumSet.of(AccessMask.GENERIC_ALL), + EnumSet.of(AccessMask.MAXIMUM_ALLOWED), EnumSet.of(FileAttributes.FILE_ATTRIBUTE_NORMAL), EnumSet.of(SMB2ShareAccess.FILE_SHARE_WRITE), SMB2CreateDisposition.FILE_OPEN_IF, From d0c5244dbbdd3f2ccbca4d3b77c48cb318d34b35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Hauenstein?= Date: Wed, 22 Nov 2017 09:58:09 +0100 Subject: [PATCH 20/21] Fix: Atomar reference Added Exceptions in Resources.properties and replaced all exceptions with the correct ressource --- .../apache/commons/vfs2/Resources.properties | 7 +++ .../vfs2/provider/smb2/SMB2ClientWrapper.java | 4 +- .../provider/smb2/SMB2FileNameParser.java | 11 +++-- .../vfs2/provider/smb2/SMB2FileObject.java | 45 +++++++++++++++---- .../vfs2/provider/smb2/SMB2FileSystem.java | 7 ++- 5 files changed, 60 insertions(+), 14 deletions(-) diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/Resources.properties b/commons-vfs2/src/main/java/org/apache/commons/vfs2/Resources.properties index 768c12bc39..3d9d68ad9b 100644 --- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/Resources.properties +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/Resources.properties @@ -203,6 +203,13 @@ vfs.provider.temp/missing-share-name.error=Share name missing from UNC file name vfs.provider.smb/missing-share-name.error=The share name is missing from URI "{0}". vfs.provider.smb/get-type.error=Could not detemine the type of "{0}". +# SMB2 Provider +vfs.provider.smb2/missing-share-name.error=The share name is missing from URI "{0}". +vfs.provider.smb2/share-path-extraction.error=Share name extraction failed for path "{0}". +vfs.provider.smb2/connect.error=Could not establish connection to "{0}". +vfs.provider.smb2/folder-create.error=Could not create folder "{0}". +vfs.provider.smb2/diskentry-create.error=Could not create a handle for file "{0}". + # Zip Provider vfs.provider.zip/open-zip-file.error=Could not open Zip file "{0}". vfs.provider.zip/close-zip-file.error=Could not close Zip file "{0}". diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2ClientWrapper.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2ClientWrapper.java index cfb803acd1..c40e461623 100644 --- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2ClientWrapper.java +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2ClientWrapper.java @@ -75,7 +75,7 @@ private void setupClient() throws FileSystemException String password = rootName.getPassword(); String authDomain = (rootName.getUserName().contains(";") ? rootName.getUserName().substring(0, rootName.getUserName().indexOf(";")) : null); - //if username == "" the client tries to authenticate "anonymously". It's also possible to summit "guets" as username + //if username == "" the client tries to authenticate "anonymously". It's also possible to submit "guets" as username AuthenticationContext authContext = new AuthenticationContext(userName, password.toCharArray(), authDomain); //a connection stack is: SMBClient > Connection > Session > DiskShare @@ -87,7 +87,7 @@ private void setupClient() throws FileSystemException diskShare = (DiskShare) session.connectShare(share); } catch (Exception e) { - throw new FileSystemException("Error while creation a connection: " + e.getCause()); + throw new FileSystemException("vfs.provider.smb2/connect.error", rootName.getHostName(), e.getCause()); } } diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileNameParser.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileNameParser.java index e33def9022..f33950e076 100644 --- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileNameParser.java +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileNameParser.java @@ -39,10 +39,15 @@ public static SMB2FileNameParser getInstance() return INSTANCE; } - protected String extractShareName(URI uri) + protected String extractShareName(URI uri) throws FileSystemException { String s = uri.getPath().startsWith("/") ? uri.getPath().substring(1) : uri.getPath(); String[] pathParts = s.split("/"); + String share = pathParts[0]; + if(share == null || share.equals("")) + { + throw new FileSystemException("vfs.provider.smb2/missing-share-name.error", uri.toString()); + } return pathParts[0]; //TODO check share given by uri } @@ -83,7 +88,7 @@ public FileName parseUri(final VfsComponentContext context, final FileName base, } catch(Exception e) { - throw new FileSystemException("Share could not be remove from the absPath: " + e.getCause()); + throw new FileSystemException("vfs.provider.smb2/share-path-extraction.error", path, e.getCause()); } SMB2FileName fileName = new SMB2FileName(auth.getScheme(), auth.getHostName(), auth.getPort(), PORT, auth.getUserName(), auth.getPassword(), relPathFromShare, parsedFileName.getType(), share); @@ -100,7 +105,7 @@ public URI parseURIString(String uriString) throws FileSystemException } catch (Exception e) { - throw new FileSystemException("FileSystem needs a well formed URI: " + e.getCause()); + throw new FileSystemException("vfs.provider.url/badly-formed-uri.error", uriString, e.getCause()); } } diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileObject.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileObject.java index 12cbafd2af..32f8dd07db 100644 --- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileObject.java +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileObject.java @@ -116,7 +116,14 @@ private void getFileInfo() { SMB2FileSystem fileSystem = (SMB2FileSystem) getFileSystem(); SMB2ClientWrapper client = (SMB2ClientWrapper) fileSystem.getClient(); - fileInfo = client.getFileInfo(getRelPathToShare()); + try + { + fileInfo = client.getFileInfo(getRelPathToShare()); + } + finally + { + fileSystem.putClient(client); + } } } @@ -173,11 +180,18 @@ protected void doCreateFolder() throws Exception { SMB2FileSystem fileSystem = (SMB2FileSystem) getFileSystem(); SMB2ClientWrapper client = (SMB2ClientWrapper) fileSystem.getClient(); - client.createFolder(getRelPathToShare()); + try + { + client.createFolder(getRelPathToShare()); + } + finally + { + fileSystem.putClient(client); + } } } catch (Exception e) { - throw new FileSystemException("Exception thrown creating folder: " + e.getCause()); + throw new FileSystemException("vfs.provider.smb2/folder-create.error", getName(), e.getCause()); } } @@ -200,7 +214,7 @@ private void getDiskEntryWrite() throws Exception } } catch (Exception e) { - throw new FileSystemException("Exception thrown getting DiskEntry: " + e.getCause()); + throw new FileSystemException("vfs.provider.smb2/diskentry-create.error", getName(), e.getCause()); } } @@ -215,7 +229,7 @@ private void getDiskEntryRead() throws Exception } } catch (Exception e) { - throw new FileSystemException("Exception thrown getting DiskEntry: " + e.getCause()); + throw new FileSystemException("vfs.provider.smb2/diskentry-create.error", getName(), e.getCause()); } } @@ -230,7 +244,7 @@ private void getDiskEntryFolderWrite() throws Exception } } catch (Exception e) { - throw new FileSystemException("Exception thrown getting DiskEntry: " + e.getCause()); + throw new FileSystemException("vfs.provider.smb2/diskentry-create.error", getName(), e.getCause()); } } @@ -295,7 +309,15 @@ protected FileObject[] doListChildrenResolved() throws Exception SMB2FileSystem fileSystem = (SMB2FileSystem) getFileSystem(); SMB2ClientWrapper client = (SMB2ClientWrapper) fileSystem.getClient(); - String[] childrenNames = client.getChildren(getRelPathToShare()); + String[] childrenNames; + try + { + childrenNames = client.getChildren(getRelPathToShare()); + } + finally + { + fileSystem.putClient(client); + } for (int i = 0; i < childrenNames.length; i++) { @@ -318,7 +340,14 @@ protected void doDelete() throws Exception SMB2FileSystem fileSystem = (SMB2FileSystem) getFileSystem(); SMB2ClientWrapper client = (SMB2ClientWrapper) fileSystem.getClient(); - client.delete(getRelPathToShare()); + try + { + client.delete(getRelPathToShare()); + } + finally + { + fileSystem.putClient(client); + } } } diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileSystem.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileSystem.java index 7ad918dec4..3cdac6f618 100644 --- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileSystem.java +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/smb2/SMB2FileSystem.java @@ -53,7 +53,12 @@ protected void addCapabilities(Collection caps) public SMBClient getClient() { - return (SMB2ClientWrapper) client.get(); + return (SMB2ClientWrapper) client.getAndSet(null); + } + + public void putClient(SMBClient smbClient) + { + client.set(smbClient); } public DiskEntry getDiskEntryWrite(String path) From db27fbe48de937c028ba5f026b11ca2c7cd93e82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Hauenstein?= Date: Wed, 22 Nov 2017 12:10:19 +0100 Subject: [PATCH 21/21] Added TestCase but as excluded --- commons-vfs2/pom.xml | 16 ++++++- .../smb2/test/SMB2ProviderTestCase.java | 47 +++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/smb2/test/SMB2ProviderTestCase.java diff --git a/commons-vfs2/pom.xml b/commons-vfs2/pom.xml index 833cd34db3..56364c179c 100644 --- a/commons-vfs2/pom.xml +++ b/commons-vfs2/pom.xml @@ -105,7 +105,6 @@ org.slf4j slf4j-api - test @@ -141,6 +140,12 @@ smbj 0.5.1 + + + org.slf4j + slf4j-simple + 1.5.11 + org.apache.hadoop @@ -262,6 +267,15 @@ + + org.apache.maven.plugins + maven-surefire-plugin + + + **/SMB2ProviderTestCase.java + + + diff --git a/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/smb2/test/SMB2ProviderTestCase.java b/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/smb2/test/SMB2ProviderTestCase.java new file mode 100644 index 0000000000..8ace331d07 --- /dev/null +++ b/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/smb2/test/SMB2ProviderTestCase.java @@ -0,0 +1,47 @@ +package org.apache.commons.vfs2.provider.smb2.test; + +import java.net.URI; +import java.net.URISyntaxException; + +import org.apache.commons.vfs2.FileObject; +import org.apache.commons.vfs2.FileSystemManager; +import org.apache.commons.vfs2.impl.DefaultFileSystemManager; +import org.apache.commons.vfs2.provider.smb2.SMB2FileProvider; +import org.apache.commons.vfs2.test.AbstractProviderTestConfig; +import org.apache.commons.vfs2.test.ProviderTestConfig; +import org.apache.commons.vfs2.test.ProviderTestSuite; + +import junit.framework.Test; +import junit.framework.TestSuite; + +public class SMB2ProviderTestCase extends AbstractProviderTestConfig implements ProviderTestConfig +{ + + private final static String HOSTNAME = "127.0.0.1"; + private final static String USERINFO = "testuser:password"; + private final static String SHARENAME = "share"; + private final static int PORT = 443; + + final TestSuite suite = new TestSuite(); + + public static Test suite() throws Exception + { + return (Test) new ProviderTestSuite(new SMB2ProviderTestCase()); + } + + @Override + public void prepare(final DefaultFileSystemManager manager) throws Exception + { + manager.addProvider("smb2", new SMB2FileProvider()); + } + + public FileObject getBaseTestFolder(final FileSystemManager manager) throws Exception + { + return manager.resolveFile(buildURI().toString()); + } + + private URI buildURI() throws URISyntaxException + { + return new URI("smb2", USERINFO, HOSTNAME, PORT, ("/" + SHARENAME), null, null); + } +} \ No newline at end of file