This is an automated email from the ASF dual-hosted git repository. ecki pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-vfs.git
The following commit(s) were added to refs/heads/master by this push: new d79524d [VFS-741] Allow known prefixes when listing folders. d79524d is described below commit d79524d567f4bbd9e9b8e056451ede70e89abd35 Author: Bernd Eckenfels <e...@apache.org> AuthorDate: Thu Oct 17 14:39:25 2019 +0200 [VFS-741] Allow known prefixes when listing folders. --- .../commons/vfs2/provider/AbstractFileObject.java | 2 +- .../provider/ram/test/CustomRamProviderTest.java | 124 ++++++++++++++++++++- src/changes/changes.xml | 3 + 3 files changed, 126 insertions(+), 3 deletions(-) diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/AbstractFileObject.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/AbstractFileObject.java index 2187a42..3c1e61a 100644 --- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/AbstractFileObject.java +++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/AbstractFileObject.java @@ -1119,7 +1119,7 @@ public abstract class AbstractFileObject<AFS extends AbstractFileSystem> impleme // Create file objects for the children final FileName[] cache = new FileName[files.length]; for (int i = 0; i < files.length; i++) { - final String file = files[i]; + final String file = "./" + files[i]; // VFS-741: assume scheme prefix is filename only cache[i] = fileSystem.getFileSystemManager().resolveName(fileName, file, NameScope.CHILD); } // VFS-285: only assign the children file names after all of them have been diff --git a/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/ram/test/CustomRamProviderTest.java b/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/ram/test/CustomRamProviderTest.java index ef4c4ee..7609dc7 100644 --- a/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/ram/test/CustomRamProviderTest.java +++ b/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/ram/test/CustomRamProviderTest.java @@ -18,6 +18,7 @@ package org.apache.commons.vfs2.provider.ram.test; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -29,11 +30,14 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import org.apache.commons.vfs2.AllFileSelector; import org.apache.commons.vfs2.FileContent; import org.apache.commons.vfs2.FileObject; import org.apache.commons.vfs2.FileSystemException; import org.apache.commons.vfs2.FileSystemOptions; +import org.apache.commons.vfs2.FileType; import org.apache.commons.vfs2.impl.DefaultFileSystemManager; +import org.apache.commons.vfs2.provider.UriParser; import org.apache.commons.vfs2.provider.ram.RamFileProvider; import org.apache.commons.vfs2.provider.ram.RamFileSystemConfigBuilder; import org.junit.After; @@ -42,10 +46,12 @@ import org.junit.Before; import org.junit.Test; /** - * Custom tests - * + * Custom tests for RamProvider. */ public class CustomRamProviderTest { + /** List of URL special characters encoded for AbstractFileObject#getChild */ + final char[] ENC = { /*'#',*/ '!', '?'}; + private static final byte[] NON_EMPTY_FILE_CONTENT = new byte[] { 1, 2, 3 }; private final List<Closeable> closeables = new ArrayList<>(); @@ -87,6 +93,23 @@ public class CustomRamProviderTest { return this.closeOnTearDown(content.getInputStream()); } + /** Create directory structure for {@link #testSpecialName()} and {@link #testSchemePrefix()} */ + private FileObject prepareSpecialFile(String dirname, String testFileName) throws FileSystemException + { + // set up a folder containing an filename with special characters: + final FileObject dir = manager.resolveFile("ram:" + dirname); + dir.createFolder(); + // construct the absolute name to make sure the relative name is not miss-interpreted + // ("./" + UriParser.encode(testFileName, ENC) would also work) + final String filePath = dir.getName().getPath() + "/" + UriParser.encode(testFileName, ENC); + + final FileObject specialFile = dir.resolveFile(filePath); + specialFile.createFile(); + + return dir; + } + + @Before public void setUp() throws Exception { manager = new DefaultFileSystemManager(); @@ -259,4 +282,101 @@ public class CustomRamProviderTest { Assert.assertTrue(fileSource.canRenameTo(fileDest)); fileSource.moveTo(fileDest); } + + /** + * Test some special file name symbols. + * <p> + * Use the RamProvider since it has no character limitations like + * the (Windows) LocalFileProvider. + */ + @Test + public void testSpecialName() throws FileSystemException + { + // we test with this file name + // does not work with '!' + final String testDir = "/spacialtest/"; + final String testFileName = "test:+-_ \"()<>%#.txt"; + final String expectedName = testDir + testFileName; + + final FileObject dir = prepareSpecialFile(testDir, testFileName); + + + // DO: verify you can list it: + final FileObject[] findFilesResult = dir.findFiles(new AllFileSelector()); // includes dir + final FileObject[] getChildrenResult = dir.getChildren(); + final FileObject getChildResult = dir.getChild(UriParser.encode(testFileName, ENC)); + + + // validate findFiles returns expected result + assertEquals("Unexpected result findFiles: " + Arrays.toString(findFilesResult), 2, findFilesResult.length); + String resultName = findFilesResult[0].getName().getPathDecoded(); + assertEquals("findFiles Child name does not match", expectedName, resultName); + assertEquals("Did findFiles but child was no file", FileType.FILE, findFilesResult[0].getType()); + + // validate getChildren returns expected result + assertEquals("Unexpected result getChildren: " + Arrays.toString(getChildrenResult), 1, getChildrenResult.length); + resultName = getChildrenResult[0].getName().getPathDecoded(); + assertEquals("getChildren Child name does not match", expectedName, resultName); + assertEquals("Did getChildren but child was no file", FileType.FILE, getChildrenResult[0].getType()); + + // validate getChild returns expected child + assertNotNull("Did not find direct child", getChildResult); + resultName = getChildResult.getName().getPathDecoded(); + assertEquals("getChild name does not match", expectedName, resultName); + assertEquals("getChild was no file", FileType.FILE, getChildResult.getType()); + } + + + /** + * Test if listing files with known scheme prefix works. + * <p> + * This test is not RamProvider specific but it uses it as a simple test-bed. + * Verifies VFS-741. + */ + @Test + public void testSchemePrefix() throws FileSystemException + { + // use a :-prefix with a known scheme (unknown scheme works since VFS-398) + final String KNOWN_SCHEME = manager.getSchemes()[0]; // typically "ram" + + // we test with this file name + final String testDir = "/prefixtest/"; + final String testFileName = KNOWN_SCHEME + ":test:txt"; + final String expectedName = testDir + testFileName; + + final FileObject dir = prepareSpecialFile(testDir, testFileName); + + + // verify we can list dir + + // if not it throws: + // Caused by: org.apache.commons.vfs2.FileSystemException: Invalid descendent file name "ram:data:test.txt". + // at org.apache.commons.vfs2.impl.DefaultFileSystemManager.resolveName + // at org.apache.commons.vfs2.provider.AbstractFileObject.getChildren + // at org.apache.commons.vfs2.provider.AbstractFileObject.traverse + // at org.apache.commons.vfs2.provider.AbstractFileObject.findFiles + + // test methods to get the child: + final FileObject[] findFilesResult = dir.findFiles(new AllFileSelector()); // includes dir + final FileObject[] getChildrenResult = dir.getChildren(); + final FileObject getChildResult = dir.getChild(testFileName); + + // validate findFiles returns expected result + assertEquals("Unexpected result findFiles: " + Arrays.toString(findFilesResult), 2, findFilesResult.length); + String resultName = findFilesResult[0].getName().getPathDecoded(); + assertEquals("findFiles Child name does not match", expectedName, resultName); + assertEquals("Did findFiles but child was no file", FileType.FILE, findFilesResult[0].getType()); + + // validate getChildren returns expected result + assertEquals("Unexpected result getChildren: " + Arrays.toString(getChildrenResult), 1, getChildrenResult.length); + resultName = getChildrenResult[0].getName().getPathDecoded(); + assertEquals("getChildren Child name does not match", expectedName, resultName); + assertEquals("Did getChildren but child was no file", FileType.FILE, getChildrenResult[0].getType()); + + // validate getChild returns expected child + assertNotNull("Did not find direct child", getChildResult); + resultName = getChildResult.getName().getPathDecoded(); + assertEquals("getChild name does not match", expectedName, resultName); + assertEquals("getChild was no file", FileType.FILE, getChildResult.getType()); + } } diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 8b39b81..0a48c5a 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -50,6 +50,9 @@ The <action> type attribute can be add,update,fix,remove. <!-- [Local] Need an easy way to convert from a FileObject to a File. --> <!-- </action> --> <!-- START Might need to be moved to the next version --> + <action issue="VFS-741" dev="ecki" type="fix"> + FileObject#getChildren allows listing of files with known scheme prefix (generalizes VFS-398). + </action> <action issue="VFS-726" dev="ggregory" type="fix" due-to="Cornelius Höfig, Gary Gregory"> getInputStream(int bufferSize) on SftpFileObject effectively ignores buffer size. </action>