Jackrabbit 1 has not changes in this release master
authorGary Gregory <garydgregory@users.noreply.github.com>
Fri, 12 Aug 2022 16:33:36 +0000 (12:33 -0400)
committerGitHub <noreply@github.com>
Fri, 12 Aug 2022 16:33:36 +0000 (12:33 -0400)
149 files changed:
.github/workflows/coverage.yml [new file with mode: 0644]
.github/workflows/maven.yml
RELEASE-NOTES.txt
checkstyle.xml
commons-vfs2-examples/README.md
commons-vfs2-examples/pom.xml
commons-vfs2-jackrabbit2/src/main/java/org/apache/commons/vfs2/provider/webdav4/Webdav4FileObject.java
commons-vfs2-sandbox/src/site/xdoc/index.xml
commons-vfs2/pom.xml
commons-vfs2/src/main/java/org/apache/commons/vfs2/FileContent.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/FileContentInfoFactory.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/FileExtensionSelector.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/FileSelectInfo.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/FileSelector.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/FileSystem.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/FileSystemManager.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/InvertIncludeFileSelector.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/VfsLog.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/cache/LRUFilesCache.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/cache/WeakRefFilesCache.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/AgeFileFilter.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/AndFileFilter.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/CanExecuteFileFilter.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/CanReadFileFilter.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/CanWriteFileFilter.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/ConditionalFileFilter.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/DirectoryFileFilter.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/EmptyFileFilter.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/FalseFileFilter.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/FileFileFilter.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/HiddenFileFilter.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/IOCase.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/NameFileFilter.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/NotFileFilter.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/OrFileFilter.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/PrefixFileFilter.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/RegexFileFilter.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/SizeFileFilter.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/SuffixFileFilter.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/SymbolicLinkFileFilter.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/TrueFileFilter.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/WildcardFileFilter.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/impl/DefaultFileMonitor.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/impl/DefaultFileReplicator.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/impl/DefaultFileSystemConfigBuilder.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/impl/DefaultFileSystemManager.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/impl/ProviderConfiguration.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/impl/StandardFileSystemManager.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/impl/SynchronizedFileObject.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/impl/URLStreamHandlerProxy.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/impl/VFSClassLoader.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/impl/VirtualFileSystem.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/operations/AbstractFileOperation.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/operations/AbstractFileOperationProvider.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/operations/FileOperationProvider.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/operations/FileOperations.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/operations/vcs/VcsCheckout.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/AbstractFileName.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/AbstractFileObject.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/AbstractFileProvider.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/AbstractFileSystem.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/AbstractVfsContainer.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/DefaultFileContent.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/DelegateFileObject.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/FileProvider.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/GenericURLFileNameParser.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/LayeredFileNameParser.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/UriParser.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/bzip2/Bzip2FileSystem.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/compressed/CompressedFileFileObject.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/ftp/FTPClientWrapper.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/ftp/FtpClient.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/ftp/FtpFileObject.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/ftp/FtpFileSystem.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/ftp/FtpFileSystemConfigBuilder.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/ftps/FtpsDataChannelProtectionLevel.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/ftps/FtpsFileSystemConfigBuilder.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/ftps/FtpsMode.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/hdfs/HdfsFileContentInfoFactory.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/hdfs/HdfsFileObject.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/Http4FileProvider.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http4/Http4FileSystemConfigBuilder.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http5/Http5FileProvider.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/http5/Http5FileSystemConfigBuilder.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/jar/JarFileObject.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/jar/JarFileSystem.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/local/GenericFileNameParser.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/local/WindowsFileNameParser.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/ram/RamFileObject.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/ram/RamFileRandomAccessContent.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/ram/RamFileSystem.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/res/ResourceFileNameParser.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/sftp/BytesIdentityInfo.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/sftp/IdentityInfo.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/sftp/SftpFileObject.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/sftp/SftpFileSystem.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/sftp/SftpFileSystemConfigBuilder.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/sftp/Utils.java [new file with mode: 0644]
commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/url/UrlFileObject.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/tasks/AbstractSyncTask.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/tasks/DeleteTask.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/tasks/ShowFileTask.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/util/DefaultCryptor.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/util/DelegatingFileSystemOptionsBuilder.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/util/Os.java
commons-vfs2/src/main/java/org/apache/commons/vfs2/util/URIBitSets.java
commons-vfs2/src/main/resources/org/apache/commons/vfs2/Resources.properties
commons-vfs2/src/test/java/org/apache/commons/vfs2/AbstractProviderTestCase.java
commons-vfs2/src/test/java/org/apache/commons/vfs2/ContentTests.java
commons-vfs2/src/test/java/org/apache/commons/vfs2/FileSystemOptionsTest.java
commons-vfs2/src/test/java/org/apache/commons/vfs2/LastModifiedTests.java
commons-vfs2/src/test/java/org/apache/commons/vfs2/NamingTests.java
commons-vfs2/src/test/java/org/apache/commons/vfs2/ProviderCacheStrategyTests.java
commons-vfs2/src/test/java/org/apache/commons/vfs2/ProviderReadTests.java
commons-vfs2/src/test/java/org/apache/commons/vfs2/ProviderRenameTests.java
commons-vfs2/src/test/java/org/apache/commons/vfs2/ProviderWriteAppendTests.java
commons-vfs2/src/test/java/org/apache/commons/vfs2/ProviderWriteTests.java
commons-vfs2/src/test/java/org/apache/commons/vfs2/VerifyingFileSelector.java
commons-vfs2/src/test/java/org/apache/commons/vfs2/cache/AbstractFilesCacheTestsBase.java
commons-vfs2/src/test/java/org/apache/commons/vfs2/cache/LRUFilesCacheTests.java
commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/AndFileFilterTest.java
commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/BaseFilterTest.java
commons-vfs2/src/test/java/org/apache/commons/vfs2/impl/DefaultFileMonitorTest.java
commons-vfs2/src/test/java/org/apache/commons/vfs2/operations/BasicOperationsTest.java
commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/ftp/FtpProviderMdtmOffTestCase.java
commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/ftps/FtpsProviderImplicitTestCase.java
commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/hdfs/HdfsFileProviderTest.java
commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/hdfs/HdfsFileProviderTestCase.java
commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/http/HttpProviderTestCase.java
commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/http4/Http4ProviderTestCase.java
commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/http5/Http5ProviderTestCase.java
commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/ram/CustomRamProviderTest.java
commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/sftp/SftpFileSystemGroupsTests.java [new file with mode: 0644]
commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/sftp/SftpPermissionExceptionTestCase.java
commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/tar/TarFileSystemTest.java
commons-vfs2/src/test/java/org/apache/commons/vfs2/util/DelegatingFileSystemOptionsBuilderTest.java
commons-vfs2/src/test/java/org/apache/commons/vfs2/util/NHttpFileServer.java
commons-vfs2/src/test/resources/log4j.properties
pom.xml
src/changes/changes.xml
src/changes/release-notes.vm
src/site/site.xml
src/site/xdoc/anttasks.xml
src/site/xdoc/api.xml
src/site/xdoc/build.xml
src/site/xdoc/filesystems.xml
src/site/xdoc/index.xml
src/site/xdoc/mail-lists.xml
src/site/xdoc/testing.xml

diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml
new file mode 100644 (file)
index 0000000..26c73ac
--- /dev/null
@@ -0,0 +1,50 @@
+# 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.
+
+name: Coverage
+
+on: [push, pull_request]
+
+permissions:
+  contents: read
+
+jobs:
+  build:
+
+    runs-on: ubuntu-latest
+    strategy:
+      matrix:
+        java: [ 8 ]
+
+    steps:
+    - uses: actions/checkout@v3
+    - uses: actions/cache@v3.0.7
+      with:
+        path: ~/.m2/repository
+        key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
+        restore-keys: |
+          ${{ runner.os }}-maven-
+    - name: Set up JDK ${{ matrix.java }}
+      uses: actions/setup-java@v3
+      with:
+        distribution: 'temurin'
+        java-version: ${{ matrix.java }}
+    - name: Build with Maven
+      run: mvn -V test jacoco:report --file pom.xml --no-transfer-progress
+
+    - name: Upload coverage to Codecov
+      uses: codecov/codecov-action@v3
+      with:
+        files: ./target/site/jacoco/jacoco.xml
index a8827179378c800ff660ca4fbbbf976a59b5279d..861590bdfe88494565a3e3daa55c2bd31dfeb346 100644 (file)
@@ -41,7 +41,7 @@ jobs:
 
     steps:
     - uses: actions/checkout@v3
-    - uses: actions/cache@v3.0.3
+    - uses: actions/cache@v3.0.7
       with:
         path: ~/.m2/repository
         key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
index a8ddf543045115a73b1fe4bde84750c2f1c74448..b66cbadc3f4a548f92c2835f2bdae87c420cb2df 100644 (file)
@@ -56,7 +56,7 @@ o           Bump Maven Surefire from 2.19.1 to 3.0.0-M5. Thanks to Gary Gregory.
 o           Bump net.sourceforge.pmd:pmd-* from 6.32.0 to 6.33.0.
 o           Bump checkstyle from 8.41 to 8.44 #175. Thanks to Dependabot, Gary Gregory.
 o           Bump actions/setup-java to v2 #177. Thanks to Boris Petrov.
-o           Bump mockito-core from 3.8.0 to 3.11.2 #178. Thanks to Dependabot, Gary GRegory.
+o           Bump mockito-core from 3.8.0 to 3.11.2 #178. Thanks to Dependabot, Gary Gregory.
 o           Bump commons-io from 2.8.0 to 2.10.0. Thanks to Gary Gregory.
 o           Bump actions/cache from 2.1.4 to 2.1.6 #183. Thanks to Dependabot.
 o           Bump jackrabbit2.version from 2.21.5 to 2.21.6 #180. Thanks to Dependabot.
@@ -76,14 +76,14 @@ o           Bump commons.javadoc.version from 3.2.0 to 3.3.0. Thanks to Gary Gre
 o           Update from to javax.mail:mail 1.4.7 to com.sun.mail:jakarta.mail 1.6.7. Thanks to Gary Gregory.
 
 
-Historical list of changes: http://commons.apache.org/proper/commons-vfs/changes-report.html
+Historical list of changes: https://commons.apache.org/proper/commons-vfs/changes-report.html
 
 For complete information on Apache Commons VFS Project, including instructions on how to submit bug reports,
 patches, or suggestions for improvement, see the Apache Apache Commons VFS Project website:
 
-http://commons.apache.org/proper/commons-vfs/
+https://commons.apache.org/proper/commons-vfs/
 
-Download page: http://commons.apache.org/proper/commons-vfs/download_vfs.cgi
+Download page: https://commons.apache.org/proper/commons-vfs/download_vfs.cgi
 
 -----------------------------------------------------------------------------
 
@@ -166,14 +166,14 @@ o VFS-795:  Code improvements for SoftRefFilesCache (simplify loop, use isEmpty,
 o           Update commons-lang3 3.11 -> 3.12.0. Thanks to Gary Gregory.
 
 
-Historical list of changes: http://commons.apache.org/proper/commons-vfs/changes-report.html
+Historical list of changes: https://commons.apache.org/proper/commons-vfs/changes-report.html
 
 For complete information on Apache Commons VFS Project, including instructions on how to submit bug reports,
 patches, or suggestions for improvement, see the Apache Apache Commons VFS Project website:
 
-http://commons.apache.org/proper/commons-vfs/
+https://commons.apache.org/proper/commons-vfs/
 
-Download page: http://commons.apache.org/proper/commons-vfs/download_vfs.cgi
+Download page: https://commons.apache.org/proper/commons-vfs/download_vfs.cgi
 
 -----------------------------------------------------------------------------
 
@@ -239,14 +239,14 @@ o           Update Apache Commons Net from 3.6 to 3.7.2. Thanks to Gary Gregory.
 o           Update JUnit from 4.13 to 4.13.1. Thanks to Gary Gregory.
 
 
-Historical list of changes: http://commons.apache.org/proper/commons-vfs/changes-report.html
+Historical list of changes: https://commons.apache.org/proper/commons-vfs/changes-report.html
 
 For complete information on Apache Commons VFS Project, including instructions on how to submit bug reports,
 patches, or suggestions for improvement, see the Apache Apache Commons VFS Project website:
 
-http://commons.apache.org/proper/commons-vfs/
+https://commons.apache.org/proper/commons-vfs/
 
-Download page: http://commons.apache.org/proper/commons-vfs/download_vfs.cgi
+Download page: https://commons.apache.org/proper/commons-vfs/download_vfs.cgi
 
 -----------------------------------------------------------------------------
 
@@ -271,14 +271,14 @@ Changes:
 o           Update JUnit from 4.12 to 4.13. Thanks to Gary Gregory.
 
 
-Historical list of changes: http://commons.apache.org/proper/commons-vfs/changes-report.html
+Historical list of changes: https://commons.apache.org/proper/commons-vfs/changes-report.html
 
 For complete information on Apache Commons VFS Project, including instructions on how to submit bug reports,
 patches, or suggestions for improvement, see the Apache Apache Commons VFS Project website:
 
-http://commons.apache.org/proper/commons-vfs/
+https://commons.apache.org/proper/commons-vfs/
 
-Download page: http://commons.apache.org/proper/commons-vfs/download_vfs.cgi
+Download page: https://commons.apache.org/proper/commons-vfs/download_vfs.cgi
 
 -----------------------------------------------------------------------------
 
@@ -326,14 +326,14 @@ o           Update tests using org.mockito:mockito-core from 3.0.0 to 3.1.0. Tha
 o VFS-749:  Update Apache Commons Parent from 48 to 50. Thanks to Gary Gregory.
 
 
-Historical list of changes: http://commons.apache.org/proper/commons-vfs/changes-report.html
+Historical list of changes: https://commons.apache.org/proper/commons-vfs/changes-report.html
 
 For complete information on Apache Commons VFS, including instructions on how to submit bug reports,
 patches, or suggestions for improvement, see the Apache Apache Commons VFS website:
 
-http://commons.apache.org/proper/commons-vfs/
+https://commons.apache.org/proper/commons-vfs/
 
-Download it from http://commons.apache.org/proper/commons-vfs/download_vfs.cgi
+Download it from https://commons.apache.org/proper/commons-vfs/download_vfs.cgi
 
 -----------------------------------------------------------------------------
 
@@ -355,14 +355,14 @@ o VFS-724:  FileContent#getByteArray() throws IllegalArgumentException: Buffer s
 o           Javadoc fixes. Thanks to Gary Gregory.
 
 
-Historical list of changes: http://commons.apache.org/proper/commons-vfs/changes-report.html
+Historical list of changes: https://commons.apache.org/proper/commons-vfs/changes-report.html
 
 For complete information on Apache Commons VFS, including instructions on how to submit bug reports,
 patches, or suggestions for improvement, see the Apache Apache Commons VFS website:
 
-Visit http://commons.apache.org/proper/commons-vfs/
+Visit https://commons.apache.org/proper/commons-vfs/
 
-Download it from http://commons.apache.org/proper/commons-vfs/download_vfs.cgi
+Download it from https://commons.apache.org/proper/commons-vfs/download_vfs.cgi
 
 -----------------------------------------------------------------------------
 
@@ -419,14 +419,14 @@ o           Public API note: The overridden method org.apache.commons.vfs2.provi
 o           Public API note: The overridden method org.apache.commons.vfs2.provider.sftp.SftpFileProvider#init() was removed but is implemented in a superclass.
 
 
-Historical list of changes: http://commons.apache.org/proper/commons-vfs/changes-report.html
+Historical list of changes: https://commons.apache.org/proper/commons-vfs/changes-report.html
 
 For complete information on Apache Commons VFS, including instructions on how to submit bug reports,
 patches, or suggestions for improvement, see the Apache Apache Commons VFS website:
 
-Visit http://commons.apache.org/proper/commons-vfs/
+Visit https://commons.apache.org/proper/commons-vfs/
 
-Download it from http://commons.apache.org/proper/commons-vfs/download_vfs.cgi
+Download it from https://commons.apache.org/proper/commons-vfs/download_vfs.cgi
 
 -----------------------------------------------------------------------------
 
@@ -478,14 +478,14 @@ o VFS-682:  Throw a org.apache.commons.vfs2.FileSystemException instead of a Nul
 o VFS-688:  [SFTP] Update jsch from 0.1.54 to 0.1.55.
 
 
-Historical list of changes: http://commons.apache.org/proper/commons-vfs/changes-report.html
+Historical list of changes: https://commons.apache.org/proper/commons-vfs/changes-report.html
 
 For complete information on Apache Commons VFS, including instructions on how to submit bug reports,
 patches, or suggestions for improvement, see the Apache Apache Commons VFS website:
 
-Visit http://commons.apache.org/proper/commons-vfs/
+Visit https://commons.apache.org/proper/commons-vfs/
 
-Download it from http://commons.apache.org/proper/commons-vfs/download_vfs.cgi
+Download it from https://commons.apache.org/proper/commons-vfs/download_vfs.cgi
 
 -----------------------------------------------------------------------------
 
@@ -524,14 +524,14 @@ Known Problems:
 o VFS-645:  VfsClassLoaderTests fails on Java 9.
 
 
-Historical list of changes: http://commons.apache.org/proper/commons-vfs/changes-report.html
+Historical list of changes: https://commons.apache.org/proper/commons-vfs/changes-report.html
 
 For complete information on Apache Commons VFS, including instructions on how to submit bug reports,
 patches, or suggestions for improvement, see the Apache Apache Commons VFS website:
 
-Visit http://commons.apache.org/proper/commons-vfs/
+Visit https://commons.apache.org/proper/commons-vfs/
 
-Download it from http://commons.apache.org/proper/commons-vfs/download_vfs.cgi
+Download it from https://commons.apache.org/proper/commons-vfs/download_vfs.cgi
 
 -----------------------------------------------------------------------------
 
@@ -586,7 +586,7 @@ o VFS-252:  [SMB] SmbFileObject does not support setLastModifiedTime while jcifs
 o VFS-313:  [FTP] Configuration does not include option for setting socket timeout. Thanks to bdavis@saintandreas.org.
 o VFS-414:  [FTP] Add config API to set the file type.
 o VFS-182:  [FTP] Usage of FTP with heterogeneous FTP server (possibility of using Ascii file type).
-o VFS-381:  Iterate over a FileObject using the Java "foreach" statement, to provide all descendents of a FileObject.
+o VFS-381:  Iterate over a FileObject using the Java "foreach" statement, to provide all descendants of a FileObject.
 o VFS-373:  Add FileContent write APIs.
 o VFS-372:  Add constructors FileDepthSelector() and FileDepthSelector(int).
 o VFS-371:  Add FileObject API deleteAll().
@@ -598,10 +598,10 @@ o VFS-424:  Fix StandardFileSystemManager class loading so it works in a OSGi en
 o VFS-490:  [vfsclassloader] Do not open folders with .jar extension. Adds tests.
 o VFS-582:  [tests] revert rename of getTestDirectoryFile to make test classes more compatible for external providers.
 o VFS-480:  Make startup of SoftRefsFileCache cleaner thread work and less racy to avoid leaks.
-o VFS-549:  Use File.seperator instead of getProperty("file.separator").
+o VFS-549:  Use File.separator instead of getProperty("file.separator").
 o VFS-567:  [ftp] Ignore exceptions while QUIT/disconnect. Thanks to Antonio Petrelli.
 o VFS-572:  [sftp] better documentation for knownhosts file option. Thanks to Sandra Parsick.
-o VFS-574:  Ensure FileOpertionProviders are closed. Adds some testcases.
+o VFS-574:  Ensure FileOperationProviders are closed. Adds some testcases.
             The error code for missing operations exceptions corrected: vfs.operation/operation-not-supported.error
 o VFS-279:  [local] Avoid ClassCastException when replicating local files while OnCall caching is active. Thanks to Didier Earith, Simon Legner.
 o VFS-297:  [sftp] VSF fails to reuse FileSystem instances if FileSystemOptions contain
@@ -707,13 +707,13 @@ o VFS-283:  [SFTP] SFTP provider did not support passphrase-protected keys nor t
             keys only, a new structure EntityInfo has been created. SftpFileSystemConfigBuilder has now the new
             getter and setter methods getIdentityInfo and setIdentity info which replace the now deprecated methods
             getIdentities and setIdentities.
-o VFS-463:  FileSytemConfigBuilder supports system properties for the value of enum-based configuration entries.
+o VFS-463:  FileSystemConfigBuilder supports system properties for the value of enum-based configuration entries.
 o VFS-462:  [FTPS] Deprecate FtpsFileSystemConfigBuilder.setFtpsType and FtpsFileSystemConfigBuilder.getFtpsType
             in favor of FtpsFileSystemConfigBuilder.setFtpsMode and FtpsFileSystemConfigBuilder.getFtpsMode which
             use new enum FtpsMode instead.
 o VFS-459:  [FTP/FTPS] Sent commands and the received answer is logged at debug level.
 o VFS-457:  Update test dependencies: sshd-core version 0.7.0 to 0.8.0; mina-core 2.0.4 to 2.0.7; junit 4.11 to 4.12; slf4j-* 1.5.5 to 1.5.11
-o VFS-456:  Use org.bouncycastel:bcprov-jdk16 instead of org.bouncycastle:bcprof-jdk15on since Java 1.6 is required.
+o VFS-456:  Use org.bouncycastle:bcprov-jdk16 instead of org.bouncycastle:bcprof-jdk15on since Java 1.6 is required.
 o VFS-415:  Update VFS requirement to Java 1.6.
 o VFS-418:  Update to Apache Commons Compress 1.4.1.
 o VFS-321:  AbstractFileObject sometimes uses getFileSystem() and sometimes references "fs" field directly. Thanks to sebb.
@@ -745,13 +745,13 @@ o VFS-361:  Upgrade commons collections version to 3.2.1.
 Removed:
 o VFS-469:  Remove unused dependency to javax.jcr:jcr.
 
-Historical list of changes: http://commons.apache.org/proper/commons-vfs/changes-report.html
+Historical list of changes: https://commons.apache.org/proper/commons-vfs/changes-report.html
 
 For complete information on Apache Commons VFS, including instructions on how to submit bug reports,
 patches, or suggestions for improvement, see the Apache Apache Commons VFS website:
 
-Visit http://commons.apache.org/proper/commons-vfs/
+Visit https://commons.apache.org/proper/commons-vfs/
 
-Download it from http://commons.apache.org/proper/commons-vfs/download_vfs.cgi
+Download it from https://commons.apache.org/proper/commons-vfs/download_vfs.cgi
 
------------------------------------------------------------------------------
\ No newline at end of file
+-----------------------------------------------------------------------------
index bbbb47f7ab40c04363cc47701c2939cf4606db3c..830cd757a13b5aeb88fddf8a7a38794f5ef9a69a 100644 (file)
   <property name="localeLanguage" value="en" />
 
   <!-- Checks that a package-info.java file exists for each package. -->
-  <!-- See http://checkstyle.sourceforge.net/config_javadoc.html -->
+  <!-- See https://checkstyle.org/config_javadoc.html#JavadocPackage -->
   <module name="JavadocPackage" />
 
   <!-- Checks whether files end with a new line. -->
-  <!-- See http://checkstyle.sf.net/config_misc.html#NewlineAtEndOfFile -->
+  <!-- See https://checkstyle.org/config_misc.html#NewlineAtEndOfFile -->
   <module name="NewlineAtEndOfFile" />
 
   <!-- Checks that property files contain the same keys. -->
-  <!-- See http://checkstyle.sf.net/config_misc.html#Translation -->
+  <!-- See https://checkstyle.org/config_misc.html#Translation -->
   <module name="Translation" />
 
   <!-- Checks for Tab characters -->
-  <!-- See http://checkstyle.sourceforge.net/config_whitespace.html#FileTabCharacter -->
+  <!-- See https://checkstyle.org/config_whitespace.html#FileTabCharacter -->
   <module name="FileTabCharacter">
     <property name="fileExtensions" value="java" />
   </module>
 
   <!-- Checks for white space at the end of the line -->
-  <!-- See http://checkstyle.sourceforge.net/config_regexp.html -->
+  <!-- See https://checkstyle.org/config_regexp.html#RegexpSingleline -->
   <module name="RegexpSingleline">
     <property name="format" value="\s+$" />
     <property name="message" value="Line has trailing spaces." />
@@ -68,7 +68,7 @@
   </module>
 
   <!-- Checks for Size Violations. -->
-  <!-- See http://checkstyle.sf.net/config_sizes.html -->
+  <!-- See https://checkstyle.org/config_sizes.html#LineLength -->
   <module name="LineLength">
     <property name="max" value="160" />
   </module>
   <module name="TreeWalker">
 
     <!-- Checks for Javadoc comments. -->
-    <!-- See http://checkstyle.sf.net/config_javadoc.html -->
+    <!-- See https://checkstyle.org/config_javadoc.html -->
     <module name="JavadocMethod">
       <property name="accessModifiers" value="public" />
     </module>
     <module name="MissingJavadocMethod"/>
 
-    <!-- http://checkstyle.sourceforge.net/config_javadoc.html#JavadocType -->
+    <!-- https://checkstyle.org/config_javadoc.html#JavadocType -->
     <module name="JavadocType">
       <!-- It is unfortunate to have to do this but checkstyle doesn't allow custom tags -->
       <property name="allowUnknownTags" value="true" />
     </module>
 
     <!-- Checks for Naming Conventions. -->
-    <!-- See http://checkstyle.sf.net/config_naming.html -->
+    <!-- See https://checkstyle.org/config_naming.html -->
     <module name="ConstantName">
       <property name="format" value="^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$|^capabilities$|^log$" />
     </module>
     <!-- <module name="RegexpHeader"/> -->
 
     <!-- Checks for imports -->
-    <!-- See http://checkstyle.sf.net/config_import.html -->
+    <!-- See https://checkstyle.org/config_imports.html -->
     <module name="AvoidStarImport" />
     <module name="IllegalImport" /> <!-- defaults to sun.* packages -->
     <module name="RedundantImport" />
     <module name="UnusedImports" />
 
     <!-- Checks for Size Violations. -->
-    <!-- See http://checkstyle.sf.net/config_sizes.html -->
+    <!-- See https://checkstyle.org/config_sizes.html -->
     <!--<module name="FileLength"/> -->
     <module name="MethodLength" />
     <module name="ParameterNumber">
     </module>
 
     <!-- Checks for whitespace -->
-    <!-- See http://checkstyle.sf.net/config_whitespace.html -->
+    <!-- See https://checkstyle.org/config_whitespace.html -->
     <module name="EmptyForIteratorPad" />
     <module name="NoWhitespaceAfter" />
     <module name="NoWhitespaceBefore" />
     <module name="GenericWhitespace" />
 
     <!-- Modifier Checks -->
-    <!-- See http://checkstyle.sf.net/config_modifiers.html -->
+    <!-- See https://checkstyle.org/config_modifier.html -->
     <module name="ModifierOrder" />
     <module name="RedundantModifier" />
 
     <!-- Checks for blocks. You know, those {}'s -->
-    <!-- See http://checkstyle.sf.net/config_blocks.html -->
+    <!-- See https://checkstyle.org/config_blocks.html -->
     <module name="AvoidNestedBlocks" />
     <!-- Require empty catch blocks to have at least a comment -->
     <module name="EmptyBlock">
     </module>
 
     <!-- Checks for common coding problems -->
-    <!-- See http://checkstyle.sf.net/config_coding.html -->
+    <!-- See https://checkstyle.org/config_coding.html -->
     <module name="CovariantEquals" />
     <module name="EqualsHashCode" />
     <module name="IllegalInstantiation" />
     <!-- <module name="UnnecessaryParentheses"/> -->
 
     <!-- Checks for class design -->
-    <!-- See http://checkstyle.sf.net/config_design.html -->
+    <!-- See https://checkstyle.org/config_design.html -->
     <module name="FinalClass" />
     <module name="HideUtilityClassConstructor" />
     <module name="InterfaceIsType" />
     </module>
 
     <!-- Miscellaneous other checks. -->
-    <!-- See http://checkstyle.sf.net/config_misc.html -->
+    <!-- See https://checkstyle.org/config_misc.html -->
     <module name="ArrayTypeStyle" />
     <module name="TodoComment">
       <property name="severity" value="info" />
index 60377db75a9edd64e52c7affad85b449b21285b3..371f276a2dd02f84b81f70e9e769988a7fcb5e7e 100644 (file)
@@ -54,7 +54,7 @@ Documentation
 -------------
 
 More information can be found on the [Apache Commons VFS Examples homepage](https://commons.apache.org/proper/commons-vfs).
-The [Javadoc](https://commons.apache.org/proper/commons-vfs/apidocs) can be browsed.
+The [Javadoc](https://commons.apache.org/proper/commons-vfs/commons-vfs2/apidocs/index.html) can be browsed.
 Questions related to the usage of Apache Commons VFS Examples should be posted to the [user mailing list][ml].
 
 Where can I get the latest release?
index 28450d596da9ed509e0333a1d628cee83c773e03..a1d4f483ee19f9c34ac026cc6438803e44e39ce5 100644 (file)
@@ -89,7 +89,7 @@
           <plugin>
             <groupId>org.codehaus.mojo</groupId>
             <artifactId>exec-maven-plugin</artifactId>
-            <version>3.0.0</version>
+            <version>3.1.0</version>
             <executions>
               <execution>
                 <phase>validate</phase>
index acc33516f4b2b0b827cb446588bc5b47c19406b1..094d07562d00e79e3cd488b6396995d428ddef54 100644 (file)
-/*
- * 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.webdav4;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.net.HttpURLConnection;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.commons.vfs2.FileContentInfoFactory;
-import org.apache.commons.vfs2.FileNotFolderException;
-import org.apache.commons.vfs2.FileNotFoundException;
-import org.apache.commons.vfs2.FileObject;
-import org.apache.commons.vfs2.FileSystemException;
-import org.apache.commons.vfs2.FileType;
-import org.apache.commons.vfs2.NameScope;
-import org.apache.commons.vfs2.provider.AbstractFileName;
-import org.apache.commons.vfs2.provider.DefaultFileContent;
-import org.apache.commons.vfs2.provider.GenericURLFileName;
-import org.apache.commons.vfs2.provider.http4.Http4FileObject;
-import org.apache.commons.vfs2.util.FileObjectUtils;
-import org.apache.commons.vfs2.util.MonitorOutputStream;
-import org.apache.commons.vfs2.util.URIUtils;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpResponse;
-import org.apache.http.HttpStatus;
-import org.apache.http.client.methods.HttpPut;
-import org.apache.http.client.methods.HttpRequestBase;
-import org.apache.http.client.methods.HttpUriRequest;
-import org.apache.http.client.utils.DateUtils;
-import org.apache.http.entity.ByteArrayEntity;
-import org.apache.http.entity.ContentType;
-import org.apache.jackrabbit.webdav.DavConstants;
-import org.apache.jackrabbit.webdav.DavException;
-import org.apache.jackrabbit.webdav.MultiStatus;
-import org.apache.jackrabbit.webdav.MultiStatusResponse;
-import org.apache.jackrabbit.webdav.client.methods.BaseDavRequest;
-import org.apache.jackrabbit.webdav.client.methods.HttpCheckin;
-import org.apache.jackrabbit.webdav.client.methods.HttpCheckout;
-import org.apache.jackrabbit.webdav.client.methods.HttpDelete;
-import org.apache.jackrabbit.webdav.client.methods.HttpMkcol;
-import org.apache.jackrabbit.webdav.client.methods.HttpMove;
-import org.apache.jackrabbit.webdav.client.methods.HttpPropfind;
-import org.apache.jackrabbit.webdav.client.methods.HttpProppatch;
-import org.apache.jackrabbit.webdav.client.methods.HttpVersionControl;
-import org.apache.jackrabbit.webdav.property.DavProperty;
-import org.apache.jackrabbit.webdav.property.DavPropertyIterator;
-import org.apache.jackrabbit.webdav.property.DavPropertyName;
-import org.apache.jackrabbit.webdav.property.DavPropertyNameSet;
-import org.apache.jackrabbit.webdav.property.DavPropertySet;
-import org.apache.jackrabbit.webdav.property.DefaultDavProperty;
-import org.apache.jackrabbit.webdav.version.DeltaVConstants;
-import org.apache.jackrabbit.webdav.version.VersionControlledResource;
-import org.apache.jackrabbit.webdav.xml.Namespace;
-import org.w3c.dom.Node;
-
-/**
- * A WebDAV file.
- *
- * @since 2.5.0
- */
-public class Webdav4FileObject extends Http4FileObject<Webdav4FileSystem> {
-
-    /**
-     * An OutputStream that writes to a Webdav resource.
-     * <p>
-     * TODO - Use piped stream to avoid temporary file.
-     */
-    private class WebdavOutputStream extends MonitorOutputStream {
-        private final Webdav4FileObject file;
-
-        WebdavOutputStream(final Webdav4FileObject file) {
-            super(new ByteArrayOutputStream());
-            this.file = file;
-        }
-
-        private boolean createVersion(final String urlStr) {
-            try {
-                final HttpVersionControl request = new HttpVersionControl(urlStr);
-                setupRequest(request);
-                executeRequest(request);
-                return true;
-            } catch (final Exception ex) {
-                return false;
-            }
-        }
-
-        /**
-         * Called after this stream is closed.
-         */
-        @Override
-        protected void onClose() throws IOException {
-            final HttpEntity entity = new ByteArrayEntity(((ByteArrayOutputStream) out).toByteArray());
-            final GenericURLFileName fileName = (GenericURLFileName) getName();
-            final String urlStr = toUrlString(fileName);
-            if (builder.isVersioning(getFileSystem().getFileSystemOptions())) {
-                DavPropertySet set = null;
-                boolean fileExists = true;
-                boolean isCheckedIn = true;
-                try {
-                    set = getPropertyNames(fileName);
-                } catch (final FileNotFoundException fnfe) {
-                    fileExists = false;
-                }
-                if (fileExists && set != null) {
-                    if (set.contains(VersionControlledResource.CHECKED_OUT)) {
-                        isCheckedIn = false;
-                    } else if (!set.contains(VersionControlledResource.CHECKED_IN)) {
-                        DavProperty<?> prop = set.get(VersionControlledResource.AUTO_VERSION);
-                        if (prop != null) {
-                            prop = getProperty(fileName, VersionControlledResource.AUTO_VERSION);
-                            if (DeltaVConstants.XML_CHECKOUT_CHECKIN.equals(prop.getValue())) {
-                                createVersion(urlStr);
-                            }
-                        }
-                    }
-                }
-                if (fileExists && isCheckedIn) {
-                    try {
-                        final HttpCheckout request = new HttpCheckout(urlStr);
-                        setupRequest(request);
-                        executeRequest(request);
-                        isCheckedIn = false;
-                    } catch (final FileSystemException ex) {
-                        log(ex);
-                    }
-                }
-
-                try {
-                    final HttpPut request = new HttpPut(urlStr);
-                    request.setEntity(entity);
-                    setupRequest(request);
-                    executeRequest(request);
-                    setUserName(fileName, urlStr);
-                } catch (final FileSystemException ex) {
-                    if (!isCheckedIn) {
-                        try {
-                            final HttpCheckin request = new HttpCheckin(urlStr);
-                            setupRequest(request);
-                            executeRequest(request);
-                            isCheckedIn = true;
-                        } catch (final Exception e) {
-                            // Going to throw original.
-                            log(e);
-                        }
-                        throw ex;
-                    }
-                }
-                if (!fileExists) {
-                    createVersion(urlStr);
-                    try {
-                        final DavPropertySet props = getPropertyNames(fileName);
-                        isCheckedIn = !props.contains(VersionControlledResource.CHECKED_OUT);
-                    } catch (final FileNotFoundException fnfe) {
-                        log(fnfe);
-                    }
-                }
-                if (!isCheckedIn) {
-                    final HttpCheckin request = new HttpCheckin(urlStr);
-                    setupRequest(request);
-                    executeRequest(request);
-                }
-            } else {
-                final HttpPut request = new HttpPut(urlStr);
-                request.setEntity(entity);
-                setupRequest(request);
-                executeRequest(request);
-                try {
-                    setUserName(fileName, urlStr);
-                } catch (final IOException e) {
-                    // Unable to set the user name.
-                    log(e);
-                }
-            }
-            ((DefaultFileContent) this.file.getContent()).resetAttributes();
-        }
-
-        private void setUserName(final GenericURLFileName fileName, final String urlStr) throws IOException {
-            final DavPropertySet setProperties = new DavPropertySet();
-            final DavPropertyNameSet removeProperties = new DavPropertyNameSet();
-            String name = builder.getCreatorName(getFileSystem().getFileSystemOptions());
-            final String userName = fileName.getUserName();
-            if (name == null) {
-                name = userName;
-            } else if (userName != null) {
-                final String comment = "Modified by user " + userName;
-                setProperties.add(new DefaultDavProperty<>(DeltaVConstants.COMMENT, comment));
-            }
-            setProperties.add(new DefaultDavProperty<>(DeltaVConstants.CREATOR_DISPLAYNAME, name));
-            final HttpProppatch request = new HttpProppatch(urlStr, setProperties, removeProperties);
-            setupRequest(request);
-            executeRequest(request);
-        }
-    }
-
-    /** The character set property name. */
-    public static final DavPropertyName RESPONSE_CHARSET = DavPropertyName.create("response-charset");
-
-    /**
-     * An empty immutable {@code Webdav4FileObject} array.
-     */
-    private static final Webdav4FileObject[] EMPTY_ARRAY = {};
-
-    /** The FileSystemConfigBuilder */
-    private final Webdav4FileSystemConfigBuilder builder;
-
-
-    protected Webdav4FileObject(final AbstractFileName name, final Webdav4FileSystem fileSystem)
-            throws FileSystemException {
-        this(name, fileSystem, Webdav4FileSystemConfigBuilder.getInstance());
-    }
-
-    protected Webdav4FileObject(final AbstractFileName name, final Webdav4FileSystem fileSystem,
-            final Webdav4FileSystemConfigBuilder builder) throws FileSystemException {
-        super(name, fileSystem, builder);
-        this.builder = builder;
-    }
-
-    /**
-     * Creates this file as a folder.
-     */
-    @Override
-    protected void doCreateFolder() throws Exception {
-        final HttpMkcol request = new HttpMkcol(toUrlString((GenericURLFileName) getName()));
-        setupRequest(request);
-        try {
-            executeRequest(request);
-        } catch (final FileSystemException fse) {
-            throw new FileSystemException("vfs.provider.webdav/create-collection.error", getName(), fse);
-        }
-    }
-
-    /**
-     * Deletes the file.
-     */
-    @Override
-    protected void doDelete() throws Exception {
-        final HttpDelete request = new HttpDelete(toUrlString((GenericURLFileName) getName()));
-        setupRequest(request);
-        executeRequest(request);
-    }
-
-    /**
-     * Returns the properties of the Webdav resource.
-     */
-    @Override
-    protected Map<String, Object> doGetAttributes() throws Exception {
-        final Map<String, Object> attributes = new HashMap<>();
-        try {
-            final GenericURLFileName fileName = (GenericURLFileName) getName();
-            DavPropertySet properties = getProperties(fileName, DavConstants.PROPFIND_ALL_PROP,
-                    new DavPropertyNameSet(), false);
-            final DavPropertyIterator iter = properties.iterator();
-            while (iter.hasNext()) {
-                final DavProperty<?> property = iter.nextProperty();
-                attributes.put(property.getName().toString(), property.getValue());
-            }
-            properties = getPropertyNames(fileName);
-            final DavPropertyIterator iter2 = properties.iterator();
-            while (iter2.hasNext()) {
-                DavProperty<?> property = iter2.nextProperty();
-                if (!attributes.containsKey(property.getName().getName())) {
-                    property = getProperty(fileName, property.getName());
-                    if (property != null) {
-                        final Object name = property.getName();
-                        final Object value = property.getValue();
-                        if (name != null && value != null) {
-                            attributes.put(name.toString(), value);
-                        }
-                    }
-                }
-            }
-            return attributes;
-        } catch (final Exception e) {
-            throw new FileSystemException("vfs.provider.webdav/get-attributes.error", getName(), e);
-        }
-    }
-
-    /**
-     * Returns the size of the file content (in bytes).
-     */
-    @Override
-    protected long doGetContentSize() throws Exception {
-        final DavProperty<?> property = getProperty((GenericURLFileName) getName(), DavConstants.PROPERTY_GETCONTENTLENGTH);
-        if (property != null) {
-            final String value = (String) property.getValue();
-            return Long.parseLong(value);
-        }
-        return 0;
-    }
-
-    /**
-     * Returns the last modified time of this file. Is only called if {@link #doGetType} does not return
-     * {@link FileType#IMAGINARY}.
-     */
-    @Override
-    protected long doGetLastModifiedTime() throws Exception {
-        final DavProperty<?> property = getProperty((GenericURLFileName) getName(), DavConstants.PROPERTY_GETLASTMODIFIED);
-        if (property != null) {
-            final String value = (String) property.getValue();
-            return DateUtils.parseDate(value).getTime();
-        }
-        return 0;
-    }
-
-    @Override
-    protected OutputStream doGetOutputStream(final boolean bAppend) throws Exception {
-        return new WebdavOutputStream(this);
-    }
-
-    /**
-     * Determines the type of this file. Must not return null. The return value of this method is cached, so the
-     * implementation can be expensive.
-     */
-    @Override
-    protected FileType doGetType() throws Exception {
-        try {
-            return isDirectory((GenericURLFileName) getName()) ? FileType.FOLDER : FileType.FILE;
-        } catch (final FileNotFolderException | FileNotFoundException fnfe) {
-            return FileType.IMAGINARY;
-        }
-
-    }
-
-    /**
-     * Determines if this file can be written to. Is only called if {@link #doGetType} does not return
-     * {@link FileType#IMAGINARY}.
-     * <p>
-     * This implementation always returns true.
-     *
-     * @return true if the file is writable.
-     * @throws Exception if an error occurs.
-     */
-    @Override
-    protected boolean doIsWriteable() throws Exception {
-        return true;
-    }
-
-    /**
-     * Lists the children of the file.
-     */
-    @Override
-    protected String[] doListChildren() throws Exception {
-        // use doListChildrenResolved for performance
-        return null;
-    }
-
-    /**
-     * Lists the children of the file.
-     */
-    @Override
-    protected FileObject[] doListChildrenResolved() throws Exception {
-        HttpPropfind request = null;
-        try {
-            final GenericURLFileName name = (GenericURLFileName) getName();
-            if (isDirectory(name)) {
-                final DavPropertyNameSet nameSet = new DavPropertyNameSet();
-                nameSet.add(DavPropertyName.create(DavConstants.PROPERTY_DISPLAYNAME));
-
-                request = new HttpPropfind(toUrlString(name), nameSet, DavConstants.DEPTH_1);
-
-                final HttpResponse res = executeRequest(request);
-                final List<Webdav4FileObject> vfs = new ArrayList<>();
-                if (request.succeeded(res)) {
-                    final MultiStatusResponse[] responses = request.getResponseBodyAsMultiStatus(res).getResponses();
-
-                    for (final MultiStatusResponse response : responses) {
-                        if (isCurrentFile(response.getHref(), name)) {
-                            continue;
-                        }
-                        final String resourceName = resourceName(response.getHref());
-                        if (!resourceName.isEmpty()) {
-                            final Webdav4FileObject fo = (Webdav4FileObject) FileObjectUtils.getAbstractFileObject(
-                                    getFileSystem().resolveFile(getFileSystem().getFileSystemManager()
-                                            .resolveName(getName(), resourceName, NameScope.CHILD)));
-                            vfs.add(fo);
-                        }
-                    }
-                }
-                return vfs.toArray(EMPTY_ARRAY);
-            }
-            throw new FileNotFolderException(getName());
-        } catch (final FileNotFolderException fnfe) {
-            throw fnfe;
-        } catch (final DavException | IOException e) {
-            throw new FileSystemException(e.getMessage(), e);
-        } finally {
-            if (request != null) {
-                request.releaseConnection();
-            }
-        }
-    }
-
-    /**
-     * Rename the file.
-     */
-    @Override
-    protected void doRename(final FileObject newFile) throws Exception {
-        final String url = URIUtils.encodePath(toUrlString((GenericURLFileName) getName()));
-        final String dest = toUrlString((GenericURLFileName) newFile.getName(), false);
-        final HttpMove request = new HttpMove(url, dest, false);
-        setupRequest(request);
-        executeRequest(request);
-    }
-
-    /**
-     * Sets an attribute of this file. Is only called if {@link #doGetType} does not return {@link FileType#IMAGINARY}.
-     */
-    @Override
-    protected void doSetAttribute(final String attrName, final Object value) throws Exception {
-        try {
-            final GenericURLFileName fileName = (GenericURLFileName) getName();
-            final String urlStr = toUrlString(fileName);
-            final DavPropertySet properties = new DavPropertySet();
-            final DavPropertyNameSet propertyNameSet = new DavPropertyNameSet();
-            final DavProperty<Object> property = new DefaultDavProperty<>(attrName, value, Namespace.EMPTY_NAMESPACE);
-            if (value != null) {
-                properties.add(property);
-            } else {
-                propertyNameSet.add(property.getName()); // remove property
-            }
-
-            final HttpProppatch request = new HttpProppatch(urlStr, properties, propertyNameSet);
-            setupRequest(request);
-            final HttpResponse response = executeRequest(request);
-            if (!request.succeeded(response)) {
-                throw new FileSystemException("Property '" + attrName + "' could not be set.");
-            }
-        } catch (final FileSystemException fse) {
-            throw fse;
-        } catch (final Exception e) {
-            throw new FileSystemException("vfs.provider.webdav/set-attributes", e, getName(), attrName);
-        }
-    }
-
-    private HttpResponse executeRequest(final HttpUriRequest request) throws FileSystemException {
-        final HttpResponse response;
-
-        try {
-            response = executeHttpUriRequest(request);
-            final int status = response.getStatusLine().getStatusCode();
-            if (status == HttpURLConnection.HTTP_NOT_FOUND || status == HttpURLConnection.HTTP_GONE) {
-                throw new FileNotFoundException(request.getURI());
-            }
-
-            if (request instanceof BaseDavRequest) {
-                ((BaseDavRequest) request).checkSuccess(response);
-            }
-
-            return response;
-        } catch (final FileSystemException fse) {
-            throw fse;
-        } catch (final IOException e) {
-            throw new FileSystemException(e);
-        } catch (final DavException e) {
-            throw ExceptionConverter.generate(e);
-        } finally {
-            if (request instanceof HttpRequestBase) {
-                ((HttpRequestBase) request).releaseConnection();
-            }
-        }
-    }
-
-    @Override
-    protected FileContentInfoFactory getFileContentInfoFactory() {
-        return new Webdav4FileContentInfoFactory();
-    }
-
-    DavPropertySet getProperties(final GenericURLFileName name) throws FileSystemException {
-        return getProperties(name, DavConstants.PROPFIND_ALL_PROP, new DavPropertyNameSet(), false);
-    }
-
-    DavPropertySet getProperties(final GenericURLFileName name, final DavPropertyNameSet nameSet, final boolean addEncoding)
-            throws FileSystemException {
-        return getProperties(name, DavConstants.PROPFIND_BY_PROPERTY, nameSet, addEncoding);
-    }
-
-    DavPropertySet getProperties(final GenericURLFileName name, final int type, final DavPropertyNameSet nameSet,
-            final boolean addEncoding) throws FileSystemException {
-        try {
-            final String urlStr = toUrlString(name);
-            final HttpPropfind request = new HttpPropfind(urlStr, type, nameSet, DavConstants.DEPTH_0);
-            setupRequest(request);
-            final HttpResponse res = executeRequest(request);
-            if (request.succeeded(res)) {
-                final MultiStatus multiStatus = request.getResponseBodyAsMultiStatus(res);
-                final MultiStatusResponse response = multiStatus.getResponses()[0];
-                final DavPropertySet props = response.getProperties(HttpStatus.SC_OK);
-                if (addEncoding) {
-                    final ContentType resContentType = ContentType.getOrDefault(res.getEntity());
-                    final DavProperty<String> prop = new DefaultDavProperty<>(RESPONSE_CHARSET,
-                            resContentType.getCharset().name());
-                    props.add(prop);
-                }
-                return props;
-            }
-            return new DavPropertySet();
-        } catch (final FileSystemException fse) {
-            throw fse;
-        } catch (final Exception e) {
-            throw new FileSystemException("vfs.provider.webdav/get-property.error", e, getName(), name, type,
-                    nameSet.getContent(), addEncoding);
-        }
-    }
-
-    DavProperty<?> getProperty(final GenericURLFileName fileName, final DavPropertyName name) throws FileSystemException {
-        final DavPropertyNameSet nameSet = new DavPropertyNameSet();
-        nameSet.add(name);
-        final DavPropertySet propertySet = getProperties(fileName, nameSet, false);
-        return propertySet.get(name);
-    }
-
-    DavProperty<?> getProperty(final GenericURLFileName fileName, final String property) throws FileSystemException {
-        return getProperty(fileName, DavPropertyName.create(property));
-    }
-
-    DavPropertySet getPropertyNames(final GenericURLFileName name) throws FileSystemException {
-        return getProperties(name, DavConstants.PROPFIND_PROPERTY_NAMES, new DavPropertyNameSet(), false);
-    }
-
-    /**
-     * Convert the FileName to an encoded url String.
-     *
-     * @param name The FileName.
-     * @return The encoded URL String.
-     */
-    private String hrefString(final GenericURLFileName name) {
-        try {
-            final GenericURLFileName newFile = new GenericURLFileName(getInternalURI().getScheme(), name.getHostName(), name.getPort(), name.getDefaultPort(),
-                    null, null, name.getPath(), name.getType(), name.getQueryString());
-            return newFile.getURIEncoded(this.getUrlCharset());
-        } catch (final Exception e) {
-            return name.getURI();
-        }
-    }
-
-    private boolean isCurrentFile(final String href, final GenericURLFileName fileName) {
-        String name = hrefString(fileName);
-        if (href.endsWith("/") && !name.endsWith("/")) {
-            name += "/";
-        }
-        return href.equals(name) || href.equals(fileName.getPath());
-    }
-
-    private boolean isDirectory(final GenericURLFileName name) throws IOException {
-        try {
-            final DavProperty<?> property = getProperty(name, DavConstants.PROPERTY_RESOURCETYPE);
-            final Node node;
-            if (property != null && (node = (Node) property.getValue()) != null) {
-                return node.getLocalName().equals(DavConstants.XML_COLLECTION);
-            }
-            return false;
-        } catch (final FileNotFoundException fse) {
-            throw new FileNotFolderException(name);
-        }
-    }
-
-    void log(final Exception ex) {
-        // TODO Consider logging
-    }
-
-    /**
-     * Returns the resource name from the path.
-     *
-     * @param path the path to the file.
-     * @return The resource name
-     */
-    private String resourceName(String path) {
-        if (path.endsWith("/")) {
-            path = path.substring(0, path.length() - 1);
-        }
-        final int i = path.lastIndexOf("/");
-        return i >= 0 ? path.substring(i + 1) : path;
-    }
-
-    private void setupRequest(final HttpUriRequest request) {
-        // NOTE: *FileSystemConfigBuilder takes care of redirect option and user agent.
-        request.addHeader("Cache-control", "no-cache");
-        request.addHeader("Cache-store", "no-store");
-        request.addHeader("Pragma", "no-cache");
-        request.addHeader("Expires", "0");
-    }
-
-    /**
-     * Converts the given URLFileName to an encoded URL String to internally use in real DAV operations.
-     *
-     * @param name The FileName.
-     * @return The encoded URL String.
-     */
-    String toUrlString(final GenericURLFileName name) {
-        return toUrlString(name, true);
-    }
-
-    /**
-     * Converts the given URLFileName to an encoded URL String to internally use in real DAV operations.
-     *
-     * @param name The FileName.
-     * @param includeUserInfo true if user information should be included.
-     * @return The encoded URL String.
-     */
-    private String toUrlString(final GenericURLFileName name, final boolean includeUserInfo) {
-        String user = null;
-        String password = null;
-        if (includeUserInfo) {
-            user = name.getUserName();
-            password = name.getPassword();
-        }
-        try {
-            final GenericURLFileName newFile = new GenericURLFileName(getInternalURI().getScheme(), name.getHostName(), name.getPort(), name.getDefaultPort(),
-                    user, password, name.getPath(), name.getType(), name.getQueryString());
-            return newFile.getURIEncoded(this.getUrlCharset());
-        } catch (final Exception e) {
-            return name.getURI();
-        }
-    }
-}
+/*\r
+ * Licensed to the Apache Software Foundation (ASF) under one or more\r
+ * contributor license agreements.  See the NOTICE file distributed with\r
+ * this work for additional information regarding copyright ownership.\r
+ * The ASF licenses this file to You under the Apache License, Version 2.0\r
+ * (the "License"); you may not use this file except in compliance with\r
+ * the License.  You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.apache.commons.vfs2.provider.webdav4;\r
+\r
+import java.io.ByteArrayOutputStream;\r
+import java.io.IOException;\r
+import java.io.OutputStream;\r
+import java.net.HttpURLConnection;\r
+import java.util.ArrayList;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+import org.apache.commons.vfs2.FileContentInfoFactory;\r
+import org.apache.commons.vfs2.FileNotFolderException;\r
+import org.apache.commons.vfs2.FileNotFoundException;\r
+import org.apache.commons.vfs2.FileObject;\r
+import org.apache.commons.vfs2.FileSystemException;\r
+import org.apache.commons.vfs2.FileType;\r
+import org.apache.commons.vfs2.NameScope;\r
+import org.apache.commons.vfs2.provider.AbstractFileName;\r
+import org.apache.commons.vfs2.provider.DefaultFileContent;\r
+import org.apache.commons.vfs2.provider.GenericURLFileName;\r
+import org.apache.commons.vfs2.provider.http4.Http4FileObject;\r
+import org.apache.commons.vfs2.util.FileObjectUtils;\r
+import org.apache.commons.vfs2.util.MonitorOutputStream;\r
+import org.apache.commons.vfs2.util.URIUtils;\r
+import org.apache.http.HttpEntity;\r
+import org.apache.http.HttpResponse;\r
+import org.apache.http.HttpStatus;\r
+import org.apache.http.client.methods.HttpPut;\r
+import org.apache.http.client.methods.HttpRequestBase;\r
+import org.apache.http.client.methods.HttpUriRequest;\r
+import org.apache.http.client.utils.DateUtils;\r
+import org.apache.http.entity.ByteArrayEntity;\r
+import org.apache.http.entity.ContentType;\r
+import org.apache.jackrabbit.webdav.DavConstants;\r
+import org.apache.jackrabbit.webdav.DavException;\r
+import org.apache.jackrabbit.webdav.MultiStatus;\r
+import org.apache.jackrabbit.webdav.MultiStatusResponse;\r
+import org.apache.jackrabbit.webdav.client.methods.BaseDavRequest;\r
+import org.apache.jackrabbit.webdav.client.methods.HttpCheckin;\r
+import org.apache.jackrabbit.webdav.client.methods.HttpCheckout;\r
+import org.apache.jackrabbit.webdav.client.methods.HttpDelete;\r
+import org.apache.jackrabbit.webdav.client.methods.HttpMkcol;\r
+import org.apache.jackrabbit.webdav.client.methods.HttpMove;\r
+import org.apache.jackrabbit.webdav.client.methods.HttpPropfind;\r
+import org.apache.jackrabbit.webdav.client.methods.HttpProppatch;\r
+import org.apache.jackrabbit.webdav.client.methods.HttpVersionControl;\r
+import org.apache.jackrabbit.webdav.property.DavProperty;\r
+import org.apache.jackrabbit.webdav.property.DavPropertyName;\r
+import org.apache.jackrabbit.webdav.property.DavPropertyNameSet;\r
+import org.apache.jackrabbit.webdav.property.DavPropertySet;\r
+import org.apache.jackrabbit.webdav.property.DefaultDavProperty;\r
+import org.apache.jackrabbit.webdav.version.DeltaVConstants;\r
+import org.apache.jackrabbit.webdav.version.VersionControlledResource;\r
+import org.apache.jackrabbit.webdav.xml.Namespace;\r
+import org.w3c.dom.Node;\r
+\r
+/**\r
+ * A WebDAV file.\r
+ *\r
+ * @since 2.5.0\r
+ */\r
+public class Webdav4FileObject extends Http4FileObject<Webdav4FileSystem> {\r
+\r
+    /**\r
+     * An OutputStream that writes to a Webdav resource.\r
+     * <p>\r
+     * TODO - Use piped stream to avoid temporary file.\r
+     */\r
+    private class WebdavOutputStream extends MonitorOutputStream {\r
+        private final Webdav4FileObject file;\r
+\r
+        WebdavOutputStream(final Webdav4FileObject file) {\r
+            super(new ByteArrayOutputStream());\r
+            this.file = file;\r
+        }\r
+\r
+        private boolean createVersion(final String urlStr) {\r
+            try {\r
+                final HttpVersionControl request = new HttpVersionControl(urlStr);\r
+                setupRequest(request);\r
+                executeRequest(request);\r
+                return true;\r
+            } catch (final Exception ex) {\r
+                return false;\r
+            }\r
+        }\r
+\r
+        /**\r
+         * Called after this stream is closed.\r
+         */\r
+        @Override\r
+        protected void onClose() throws IOException {\r
+            final HttpEntity entity = new ByteArrayEntity(((ByteArrayOutputStream) out).toByteArray());\r
+            final GenericURLFileName fileName = (GenericURLFileName) getName();\r
+            final String urlStr = toUrlString(fileName);\r
+            if (builder.isVersioning(getFileSystem().getFileSystemOptions())) {\r
+                DavPropertySet set = null;\r
+                boolean fileExists = true;\r
+                boolean isCheckedIn = true;\r
+                try {\r
+                    set = getPropertyNames(fileName);\r
+                } catch (final FileNotFoundException fnfe) {\r
+                    fileExists = false;\r
+                }\r
+                if (fileExists && set != null) {\r
+                    if (set.contains(VersionControlledResource.CHECKED_OUT)) {\r
+                        isCheckedIn = false;\r
+                    } else if (!set.contains(VersionControlledResource.CHECKED_IN)) {\r
+                        DavProperty<?> prop = set.get(VersionControlledResource.AUTO_VERSION);\r
+                        if (prop != null) {\r
+                            prop = getProperty(fileName, VersionControlledResource.AUTO_VERSION);\r
+                            if (DeltaVConstants.XML_CHECKOUT_CHECKIN.equals(prop.getValue())) {\r
+                                createVersion(urlStr);\r
+                            }\r
+                        }\r
+                    }\r
+                }\r
+                if (fileExists && isCheckedIn) {\r
+                    try {\r
+                        final HttpCheckout request = new HttpCheckout(urlStr);\r
+                        setupRequest(request);\r
+                        executeRequest(request);\r
+                        isCheckedIn = false;\r
+                    } catch (final FileSystemException ex) {\r
+                        log(ex);\r
+                    }\r
+                }\r
+\r
+                try {\r
+                    final HttpPut request = new HttpPut(urlStr);\r
+                    request.setEntity(entity);\r
+                    setupRequest(request);\r
+                    executeRequest(request);\r
+                    setUserName(fileName, urlStr);\r
+                } catch (final FileSystemException ex) {\r
+                    if (!isCheckedIn) {\r
+                        try {\r
+                            final HttpCheckin request = new HttpCheckin(urlStr);\r
+                            setupRequest(request);\r
+                            executeRequest(request);\r
+                            isCheckedIn = true;\r
+                        } catch (final Exception e) {\r
+                            // Going to throw original.\r
+                            log(e);\r
+                        }\r
+                        throw ex;\r
+                    }\r
+                }\r
+                if (!fileExists) {\r
+                    createVersion(urlStr);\r
+                    try {\r
+                        final DavPropertySet props = getPropertyNames(fileName);\r
+                        isCheckedIn = !props.contains(VersionControlledResource.CHECKED_OUT);\r
+                    } catch (final FileNotFoundException fnfe) {\r
+                        log(fnfe);\r
+                    }\r
+                }\r
+                if (!isCheckedIn) {\r
+                    final HttpCheckin request = new HttpCheckin(urlStr);\r
+                    setupRequest(request);\r
+                    executeRequest(request);\r
+                }\r
+            } else {\r
+                final HttpPut request = new HttpPut(urlStr);\r
+                request.setEntity(entity);\r
+                setupRequest(request);\r
+                executeRequest(request);\r
+                try {\r
+                    setUserName(fileName, urlStr);\r
+                } catch (final IOException e) {\r
+                    // Unable to set the user name.\r
+                    log(e);\r
+                }\r
+            }\r
+            ((DefaultFileContent) this.file.getContent()).resetAttributes();\r
+        }\r
+\r
+        private void setUserName(final GenericURLFileName fileName, final String urlStr) throws IOException {\r
+            final DavPropertySet setProperties = new DavPropertySet();\r
+            final DavPropertyNameSet removeProperties = new DavPropertyNameSet();\r
+            String name = builder.getCreatorName(getFileSystem().getFileSystemOptions());\r
+            final String userName = fileName.getUserName();\r
+            if (name == null) {\r
+                name = userName;\r
+            } else if (userName != null) {\r
+                final String comment = "Modified by user " + userName;\r
+                setProperties.add(new DefaultDavProperty<>(DeltaVConstants.COMMENT, comment));\r
+            }\r
+            setProperties.add(new DefaultDavProperty<>(DeltaVConstants.CREATOR_DISPLAYNAME, name));\r
+            final HttpProppatch request = new HttpProppatch(urlStr, setProperties, removeProperties);\r
+            setupRequest(request);\r
+            executeRequest(request);\r
+        }\r
+    }\r
+\r
+    /** The character set property name. */\r
+    public static final DavPropertyName RESPONSE_CHARSET = DavPropertyName.create("response-charset");\r
+\r
+    /**\r
+     * An empty immutable {@code Webdav4FileObject} array.\r
+     */\r
+    private static final Webdav4FileObject[] EMPTY_ARRAY = {};\r
+\r
+    /** The FileSystemConfigBuilder */\r
+    private final Webdav4FileSystemConfigBuilder builder;\r
+\r
+\r
+    protected Webdav4FileObject(final AbstractFileName name, final Webdav4FileSystem fileSystem)\r
+            throws FileSystemException {\r
+        this(name, fileSystem, Webdav4FileSystemConfigBuilder.getInstance());\r
+    }\r
+\r
+    protected Webdav4FileObject(final AbstractFileName name, final Webdav4FileSystem fileSystem,\r
+            final Webdav4FileSystemConfigBuilder builder) throws FileSystemException {\r
+        super(name, fileSystem, builder);\r
+        this.builder = builder;\r
+    }\r
+\r
+    /**\r
+     * Creates this file as a folder.\r
+     */\r
+    @Override\r
+    protected void doCreateFolder() throws Exception {\r
+        final HttpMkcol request = new HttpMkcol(toUrlString((GenericURLFileName) getName()));\r
+        setupRequest(request);\r
+        try {\r
+            executeRequest(request);\r
+        } catch (final FileSystemException fse) {\r
+            throw new FileSystemException("vfs.provider.webdav/create-collection.error", getName(), fse);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Deletes the file.\r
+     */\r
+    @Override\r
+    protected void doDelete() throws Exception {\r
+        final HttpDelete request = new HttpDelete(toUrlString((GenericURLFileName) getName()));\r
+        setupRequest(request);\r
+        executeRequest(request);\r
+    }\r
+\r
+    /**\r
+     * Returns the properties of the Webdav resource.\r
+     */\r
+    @Override\r
+    protected Map<String, Object> doGetAttributes() throws Exception {\r
+        final Map<String, Object> attributes = new HashMap<>();\r
+        try {\r
+            final GenericURLFileName fileName = (GenericURLFileName) getName();\r
+            DavPropertySet properties = getProperties(fileName, DavConstants.PROPFIND_ALL_PROP,\r
+                    new DavPropertyNameSet(), false);\r
+            for (final DavProperty<?> property : properties) {\r
+                attributes.put(property.getName().toString(), property.getValue());\r
+            }\r
+            properties = getPropertyNames(fileName);\r
+            for (DavProperty<?> property : properties) {\r
+                if (!attributes.containsKey(property.getName().getName())) {\r
+                    property = getProperty(fileName, property.getName());\r
+                    if (property != null) {\r
+                        final Object name = property.getName();\r
+                        final Object value = property.getValue();\r
+                        if (name != null && value != null) {\r
+                            attributes.put(name.toString(), value);\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+            return attributes;\r
+        } catch (final Exception e) {\r
+            throw new FileSystemException("vfs.provider.webdav/get-attributes.error", getName(), e);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Returns the size of the file content (in bytes).\r
+     */\r
+    @Override\r
+    protected long doGetContentSize() throws Exception {\r
+        final DavProperty<?> property = getProperty((GenericURLFileName) getName(), DavConstants.PROPERTY_GETCONTENTLENGTH);\r
+        if (property != null) {\r
+            final String value = (String) property.getValue();\r
+            return Long.parseLong(value);\r
+        }\r
+        return 0;\r
+    }\r
+\r
+    /**\r
+     * Returns the last modified time of this file. Is only called if {@link #doGetType} does not return\r
+     * {@link FileType#IMAGINARY}.\r
+     */\r
+    @Override\r
+    protected long doGetLastModifiedTime() throws Exception {\r
+        final DavProperty<?> property = getProperty((GenericURLFileName) getName(), DavConstants.PROPERTY_GETLASTMODIFIED);\r
+        if (property != null) {\r
+            final String value = (String) property.getValue();\r
+            return DateUtils.parseDate(value).getTime();\r
+        }\r
+        return 0;\r
+    }\r
+\r
+    @Override\r
+    protected OutputStream doGetOutputStream(final boolean bAppend) throws Exception {\r
+        return new WebdavOutputStream(this);\r
+    }\r
+\r
+    /**\r
+     * Determines the type of this file. Must not return null. The return value of this method is cached, so the\r
+     * implementation can be expensive.\r
+     */\r
+    @Override\r
+    protected FileType doGetType() throws Exception {\r
+        try {\r
+            return isDirectory((GenericURLFileName) getName()) ? FileType.FOLDER : FileType.FILE;\r
+        } catch (final FileNotFolderException | FileNotFoundException fnfe) {\r
+            return FileType.IMAGINARY;\r
+        }\r
+\r
+    }\r
+\r
+    /**\r
+     * Determines if this file can be written to. Is only called if {@link #doGetType} does not return\r
+     * {@link FileType#IMAGINARY}.\r
+     * <p>\r
+     * This implementation always returns true.\r
+     *\r
+     * @return true if the file is writable.\r
+     * @throws Exception if an error occurs.\r
+     */\r
+    @Override\r
+    protected boolean doIsWriteable() throws Exception {\r
+        return true;\r
+    }\r
+\r
+    /**\r
+     * Lists the children of the file.\r
+     */\r
+    @Override\r
+    protected String[] doListChildren() throws Exception {\r
+        // use doListChildrenResolved for performance\r
+        return null;\r
+    }\r
+\r
+    /**\r
+     * Lists the children of the file.\r
+     */\r
+    @Override\r
+    protected FileObject[] doListChildrenResolved() throws Exception {\r
+        HttpPropfind request = null;\r
+        try {\r
+            final GenericURLFileName name = (GenericURLFileName) getName();\r
+            if (isDirectory(name)) {\r
+                final DavPropertyNameSet nameSet = new DavPropertyNameSet();\r
+                nameSet.add(DavPropertyName.create(DavConstants.PROPERTY_DISPLAYNAME));\r
+\r
+                request = new HttpPropfind(toUrlString(name), nameSet, DavConstants.DEPTH_1);\r
+\r
+                final HttpResponse res = executeRequest(request);\r
+                final List<Webdav4FileObject> vfs = new ArrayList<>();\r
+                if (request.succeeded(res)) {\r
+                    final MultiStatusResponse[] responses = request.getResponseBodyAsMultiStatus(res).getResponses();\r
+\r
+                    for (final MultiStatusResponse response : responses) {\r
+                        if (isCurrentFile(response.getHref(), name)) {\r
+                            continue;\r
+                        }\r
+                        final String resourceName = resourceName(response.getHref());\r
+                        if (!resourceName.isEmpty()) {\r
+                            final Webdav4FileObject fo = (Webdav4FileObject) FileObjectUtils.getAbstractFileObject(\r
+                                    getFileSystem().resolveFile(getFileSystem().getFileSystemManager()\r
+                                            .resolveName(getName(), resourceName, NameScope.CHILD)));\r
+                            vfs.add(fo);\r
+                        }\r
+                    }\r
+                }\r
+                return vfs.toArray(EMPTY_ARRAY);\r
+            }\r
+            throw new FileNotFolderException(getName());\r
+        } catch (final FileNotFolderException fnfe) {\r
+            throw fnfe;\r
+        } catch (final DavException | IOException e) {\r
+            throw new FileSystemException(e.getMessage(), e);\r
+        } finally {\r
+            if (request != null) {\r
+                request.releaseConnection();\r
+            }\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Rename the file.\r
+     */\r
+    @Override\r
+    protected void doRename(final FileObject newFile) throws Exception {\r
+        final String url = URIUtils.encodePath(toUrlString((GenericURLFileName) getName()));\r
+        final String dest = toUrlString((GenericURLFileName) newFile.getName(), false);\r
+        final HttpMove request = new HttpMove(url, dest, false);\r
+        setupRequest(request);\r
+        executeRequest(request);\r
+    }\r
+\r
+    /**\r
+     * Sets an attribute of this file. Is only called if {@link #doGetType} does not return {@link FileType#IMAGINARY}.\r
+     */\r
+    @Override\r
+    protected void doSetAttribute(final String attrName, final Object value) throws Exception {\r
+        try {\r
+            final GenericURLFileName fileName = (GenericURLFileName) getName();\r
+            final String urlStr = toUrlString(fileName);\r
+            final DavPropertySet properties = new DavPropertySet();\r
+            final DavPropertyNameSet propertyNameSet = new DavPropertyNameSet();\r
+            final DavProperty<Object> property = new DefaultDavProperty<>(attrName, value, Namespace.EMPTY_NAMESPACE);\r
+            if (value != null) {\r
+                properties.add(property);\r
+            } else {\r
+                propertyNameSet.add(property.getName()); // remove property\r
+            }\r
+\r
+            final HttpProppatch request = new HttpProppatch(urlStr, properties, propertyNameSet);\r
+            setupRequest(request);\r
+            final HttpResponse response = executeRequest(request);\r
+            if (!request.succeeded(response)) {\r
+                throw new FileSystemException("Property '" + attrName + "' could not be set.");\r
+            }\r
+        } catch (final FileSystemException fse) {\r
+            throw fse;\r
+        } catch (final Exception e) {\r
+            throw new FileSystemException("vfs.provider.webdav/set-attributes", e, getName(), attrName);\r
+        }\r
+    }\r
+\r
+    private HttpResponse executeRequest(final HttpUriRequest request) throws FileSystemException {\r
+        final HttpResponse response;\r
+\r
+        try {\r
+            response = executeHttpUriRequest(request);\r
+            final int status = response.getStatusLine().getStatusCode();\r
+            if (status == HttpURLConnection.HTTP_NOT_FOUND || status == HttpURLConnection.HTTP_GONE) {\r
+                throw new FileNotFoundException(request.getURI());\r
+            }\r
+\r
+            if (request instanceof BaseDavRequest) {\r
+                ((BaseDavRequest) request).checkSuccess(response);\r
+            }\r
+\r
+            return response;\r
+        } catch (final FileSystemException fse) {\r
+            throw fse;\r
+        } catch (final IOException e) {\r
+            throw new FileSystemException(e);\r
+        } catch (final DavException e) {\r
+            throw ExceptionConverter.generate(e);\r
+        } finally {\r
+            if (request instanceof HttpRequestBase) {\r
+                ((HttpRequestBase) request).releaseConnection();\r
+            }\r
+        }\r
+    }\r
+\r
+    @Override\r
+    protected FileContentInfoFactory getFileContentInfoFactory() {\r
+        return new Webdav4FileContentInfoFactory();\r
+    }\r
+\r
+    DavPropertySet getProperties(final GenericURLFileName name) throws FileSystemException {\r
+        return getProperties(name, DavConstants.PROPFIND_ALL_PROP, new DavPropertyNameSet(), false);\r
+    }\r
+\r
+    DavPropertySet getProperties(final GenericURLFileName name, final DavPropertyNameSet nameSet, final boolean addEncoding)\r
+            throws FileSystemException {\r
+        return getProperties(name, DavConstants.PROPFIND_BY_PROPERTY, nameSet, addEncoding);\r
+    }\r
+\r
+    DavPropertySet getProperties(final GenericURLFileName name, final int type, final DavPropertyNameSet nameSet,\r
+            final boolean addEncoding) throws FileSystemException {\r
+        try {\r
+            final String urlStr = toUrlString(name);\r
+            final HttpPropfind request = new HttpPropfind(urlStr, type, nameSet, DavConstants.DEPTH_0);\r
+            setupRequest(request);\r
+            final HttpResponse res = executeRequest(request);\r
+            if (request.succeeded(res)) {\r
+                final MultiStatus multiStatus = request.getResponseBodyAsMultiStatus(res);\r
+                final MultiStatusResponse response = multiStatus.getResponses()[0];\r
+                final DavPropertySet props = response.getProperties(HttpStatus.SC_OK);\r
+                if (addEncoding) {\r
+                    final ContentType resContentType = ContentType.getOrDefault(res.getEntity());\r
+                    final DavProperty<String> prop = new DefaultDavProperty<>(RESPONSE_CHARSET,\r
+                            resContentType.getCharset().name());\r
+                    props.add(prop);\r
+                }\r
+                return props;\r
+            }\r
+            return new DavPropertySet();\r
+        } catch (final FileSystemException fse) {\r
+            throw fse;\r
+        } catch (final Exception e) {\r
+            throw new FileSystemException("vfs.provider.webdav/get-property.error", e, getName(), name, type,\r
+                    nameSet.getContent(), addEncoding);\r
+        }\r
+    }\r
+\r
+    DavProperty<?> getProperty(final GenericURLFileName fileName, final DavPropertyName name) throws FileSystemException {\r
+        final DavPropertyNameSet nameSet = new DavPropertyNameSet();\r
+        nameSet.add(name);\r
+        final DavPropertySet propertySet = getProperties(fileName, nameSet, false);\r
+        return propertySet.get(name);\r
+    }\r
+\r
+    DavProperty<?> getProperty(final GenericURLFileName fileName, final String property) throws FileSystemException {\r
+        return getProperty(fileName, DavPropertyName.create(property));\r
+    }\r
+\r
+    DavPropertySet getPropertyNames(final GenericURLFileName name) throws FileSystemException {\r
+        return getProperties(name, DavConstants.PROPFIND_PROPERTY_NAMES, new DavPropertyNameSet(), false);\r
+    }\r
+\r
+    /**\r
+     * Convert the FileName to an encoded url String.\r
+     *\r
+     * @param name The FileName.\r
+     * @return The encoded URL String.\r
+     */\r
+    private String hrefString(final GenericURLFileName name) {\r
+        try {\r
+            final GenericURLFileName newFile = new GenericURLFileName(getInternalURI().getScheme(), name.getHostName(), name.getPort(), name.getDefaultPort(),\r
+                    null, null, name.getPath(), name.getType(), name.getQueryString());\r
+            return newFile.getURIEncoded(this.getUrlCharset());\r
+        } catch (final Exception e) {\r
+            return name.getURI();\r
+        }\r
+    }\r
+\r
+    private boolean isCurrentFile(final String href, final GenericURLFileName fileName) {\r
+        String name = hrefString(fileName);\r
+        if (href.endsWith("/") && !name.endsWith("/")) {\r
+            name += "/";\r
+        }\r
+        return href.equals(name) || href.equals(fileName.getPath());\r
+    }\r
+\r
+    private boolean isDirectory(final GenericURLFileName name) throws IOException {\r
+        try {\r
+            final DavProperty<?> property = getProperty(name, DavConstants.PROPERTY_RESOURCETYPE);\r
+            final Node node;\r
+            if (property != null && (node = (Node) property.getValue()) != null) {\r
+                return node.getLocalName().equals(DavConstants.XML_COLLECTION);\r
+            }\r
+            return false;\r
+        } catch (final FileNotFoundException fse) {\r
+            throw new FileNotFolderException(name);\r
+        }\r
+    }\r
+\r
+    void log(final Exception ex) {\r
+        // TODO Consider logging\r
+    }\r
+\r
+    /**\r
+     * Returns the resource name from the path.\r
+     *\r
+     * @param path the path to the file.\r
+     * @return The resource name\r
+     */\r
+    private String resourceName(String path) {\r
+        if (path.endsWith("/")) {\r
+            path = path.substring(0, path.length() - 1);\r
+        }\r
+        final int i = path.lastIndexOf("/");\r
+        return i >= 0 ? path.substring(i + 1) : path;\r
+    }\r
+\r
+    private void setupRequest(final HttpUriRequest request) {\r
+        // NOTE: *FileSystemConfigBuilder takes care of redirect option and user agent.\r
+        request.addHeader("Cache-control", "no-cache");\r
+        request.addHeader("Cache-store", "no-store");\r
+        request.addHeader("Pragma", "no-cache");\r
+        request.addHeader("Expires", "0");\r
+    }\r
+\r
+    /**\r
+     * Converts the given URLFileName to an encoded URL String to internally use in real DAV operations.\r
+     *\r
+     * @param name The FileName.\r
+     * @return The encoded URL String.\r
+     */\r
+    String toUrlString(final GenericURLFileName name) {\r
+        return toUrlString(name, true);\r
+    }\r
+\r
+    /**\r
+     * Converts the given URLFileName to an encoded URL String to internally use in real DAV operations.\r
+     *\r
+     * @param name The FileName.\r
+     * @param includeUserInfo true if user information should be included.\r
+     * @return The encoded URL String.\r
+     */\r
+    private String toUrlString(final GenericURLFileName name, final boolean includeUserInfo) {\r
+        String user = null;\r
+        String password = null;\r
+        if (includeUserInfo) {\r
+            user = name.getUserName();\r
+            password = name.getPassword();\r
+        }\r
+        try {\r
+            final GenericURLFileName newFile = new GenericURLFileName(getInternalURI().getScheme(), name.getHostName(), name.getPort(), name.getDefaultPort(),\r
+                    user, password, name.getPath(), name.getType(), name.getQueryString());\r
+            return newFile.getURIEncoded(this.getUrlCharset());\r
+        } catch (final Exception e) {\r
+            return name.getURI();\r
+        }\r
+    }\r
+}\r
index 62bd0feb2572b7c43cbeff64b8f1b530c8278108..c0d12b9d816d9ada72539dcf76a9e0932229b88e 100644 (file)
@@ -30,7 +30,7 @@
           providers</a>) which cannot be shipped with the official Apache release.\r
           This includes experimental code as well as components which have \r
           <a href="dependencies.html">dependencies</a> not compatible with the \r
-          <a href="http://www.apache.org/legal/resolved.html#category-x">ASF redistribution policy\r
+          <a href="https://www.apache.org/legal/resolved.html#category-x">ASF redistribution policy\r
           (especially LGPL)</a>.\r
         </p><p>\r
           To build the sandbox binaries, see the <a href="../download.html">download and build\r
index a1a2d61ea7433ff038312b6c7b2449415e52aea6..1fb4b8181b95cee1c3955e4d90863969077672c8 100644 (file)
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
-   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.
-  -->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-
-  <modelVersion>4.0.0</modelVersion>
-
-  <name>Apache Commons VFS</name>
-  <artifactId>commons-vfs2</artifactId>
-  <description>Apache Commons VFS is a Virtual File System library.</description>
-  <url>http://commons.apache.org/proper/commons-vfs/</url>
-
-  <parent>
-    <groupId>org.apache.commons</groupId>
-    <artifactId>commons-vfs2-project</artifactId>
-    <version>2.10.0-SNAPSHOT</version>
-    <relativePath>../</relativePath>
-  </parent>
-
-  <dependencies>
-    <dependency>
-      <groupId>commons-logging</groupId>
-      <artifactId>commons-logging</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>ant</groupId>
-      <artifactId>ant</artifactId>
-      <optional>true</optional>
-    </dependency>
-    <dependency>
-      <groupId>commons-net</groupId>
-      <artifactId>commons-net</artifactId>
-      <optional>true</optional>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.commons</groupId>
-      <artifactId>commons-compress</artifactId>
-      <optional>true</optional>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.commons</groupId>
-      <artifactId>commons-collections4</artifactId>
-      <optional>true</optional>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.hadoop</groupId>
-      <artifactId>hadoop-hdfs-client</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.hadoop</groupId>
-      <artifactId>hadoop-common</artifactId>
-      <optional>true</optional>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.hadoop</groupId>
-      <artifactId>hadoop-hdfs</artifactId>
-      <optional>true</optional>
-    </dependency>
-    <dependency>
-      <groupId>commons-httpclient</groupId>
-      <artifactId>commons-httpclient</artifactId>
-      <optional>true</optional>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.httpcomponents</groupId>
-      <artifactId>httpclient</artifactId>
-      <optional>true</optional>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.httpcomponents.client5</groupId>
-      <artifactId>httpclient5</artifactId>
-      <optional>true</optional>
-    </dependency>
-    <dependency>
-      <groupId>com.jcraft</groupId>
-      <artifactId>jsch</artifactId>
-      <optional>true</optional>
-    </dependency>
-
-    <dependency>
-      <groupId>org.junit.jupiter</groupId>
-      <artifactId>junit-jupiter-engine</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.junit.vintage</groupId>
-      <artifactId>junit-vintage-engine</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.mockito</groupId>
-      <artifactId>mockito-core</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.commons</groupId>
-      <artifactId>commons-lang3</artifactId>
-    </dependency>
-    <!-- Test FTP with Apache FTP Server (MINA) -->
-    <dependency>
-      <groupId>org.apache.ftpserver</groupId>
-      <artifactId>ftpserver-core</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-api</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-slf4j-impl</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.logging.log4j</groupId>
-      <artifactId>log4j-core</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <!-- Test SFTP with Apache SHHd Server (MINA) -->
-    <dependency>
-      <groupId>org.apache.sshd</groupId>
-      <artifactId>sshd-core</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.bouncycastle</groupId>
-      <artifactId>bcprov-jdk16</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>commons-io</groupId>
-      <artifactId>commons-io</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <!-- Test HTTP with Apache HttpComponent Core -->
-    <dependency>
-      <groupId>org.apache.httpcomponents</groupId>
-      <artifactId>httpcore-nio</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <!-- Test HDFS with Apache Hadoop -->
-    <dependency>
-      <groupId>org.apache.hadoop</groupId>
-      <artifactId>hadoop-common</artifactId>
-      <type>test-jar</type>
-      <scope>test</scope>
-      <exclusions>
-        <exclusion>
-         <!-- VFS-606 - tools.jar not available in Java 9
-              This exclusion can be removed after upgrading Hadoop
-              to 2.7.1 or later  
-          -->
-          <groupId>jdk.tools</groupId>
-          <artifactId>jdk.tools</artifactId>
-        </exclusion>
-      </exclusions>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.hadoop</groupId>
-      <artifactId>hadoop-hdfs</artifactId>
-      <type>test-jar</type>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>javax.ws.rs</groupId>
-      <artifactId>jsr311-api</artifactId>
-      <scope>test</scope>
-    </dependency>
-  </dependencies>
-
-  <properties>
-    <vfs.parent.dir>${basedir}/..</vfs.parent.dir>
-    <commons.osgi.import>
-        org.apache.hadoop.*;resolution:=optional,
-        org.apache.tools.ant.*;resolution:=optional,
-        org.apache.commons.httpclient.*;resolution:=optional,
-        *
-    </commons.osgi.import>
-  </properties>
-
-  <build>
-    <resources>
-      <resource>
-        <directory>${basedir}/src/main/resources</directory>
-      </resource>
-      <!-- include NOTICE/LICENSE in generated jar -->
-      <resource>
-        <directory>${vfs.parent.dir}</directory>
-        <targetPath>META-INF</targetPath>
-        <includes>
-          <include>NOTICE.txt</include>
-          <include>LICENSE.txt</include>
-        </includes>
-      </resource>
-    </resources>
-
-    <testResources>
-      <testResource>
-        <directory>src/test/resources</directory>
-      </testResource>
-      <!-- include NOTICE/LICENSE in generated test jar -->
-      <testResource>
-        <directory>${vfs.parent.dir}</directory>
-        <targetPath>META-INF</targetPath>
-        <includes>
-          <include>NOTICE.txt</include>
-          <include>LICENSE.txt</include>
-        </includes>
-      </testResource>
-    </testResources>
-
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-jar-plugin</artifactId>
-        <executions>
-          <execution>
-            <goals>
-              <goal>test-jar</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-antrun-plugin</artifactId>
-        <executions>
-          <execution>
-            <phase>process-test-classes</phase>
-            <configuration>
-              <target>
-                <move todir="${project.build.testOutputDirectory}/test-data/code" failonerror="false">
-                  <fileset dir="${project.build.testOutputDirectory}/code" />
-                </move>
-              </target>
-            </configuration>
-            <goals>
-              <goal>run</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <trimStackTrace>false</trimStackTrace>
-          <systemPropertyVariables>
-            <test.basedir>target/test-classes/test-data</test.basedir>
-            <test.basedir.res>test-data</test.basedir.res>
-            <derby.stream.error.file>target/derby.log</derby.stream.error.file>
-          </systemPropertyVariables>
-          <excludes>
-            <!-- Main class -->
-            <exclude>**/RunTest.java</exclude>
-            <!-- inner classes -->
-            <exclude>**/*$*</exclude>
-            <!-- Need to port fully to JUnit 4 or 5. -->
-            <!-- *Tests.java files with @Test methods should not be run since these classes are in fact JUnit 3 classes used in custom JUnit 3 test suites. -->
-            <exclude>**/*Tests.java</exclude>
-          </excludes>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
-
-  <profiles>
-    <profile>
-      <id>webdav</id>
-      <activation>
-        <activeByDefault>false</activeByDefault>
-      </activation>
-      <build>
-        <plugins>
-          <plugin>
-            <groupId>org.apache.maven.plugins</groupId>
-            <artifactId>maven-surefire-plugin</artifactId>
-            <configuration>
-              <systemPropertyVariables>
-                <test.webdav.uri>${test.webdav.uri}</test.webdav.uri>
-              </systemPropertyVariables>
-            </configuration>
-          </plugin>
-        </plugins>
-      </build>
-    </profile>
-
-    <profile>
-      <id>ftp</id>
-      <activation>
-        <activeByDefault>false</activeByDefault>
-      </activation>
-      <build>
-        <plugins>
-          <plugin>
-            <groupId>org.apache.maven.plugins</groupId>
-            <artifactId>maven-surefire-plugin</artifactId>
-            <configuration>
-              <systemPropertyVariables>
-                <test.ftp.uri>${test.ftp.uri}</test.ftp.uri>
-              </systemPropertyVariables>
-            </configuration>
-          </plugin>
-        </plugins>
-      </build>
-    </profile>
-
-    <profile>
-      <id>sftp</id>
-      <activation>
-        <activeByDefault>false</activeByDefault>
-      </activation>
-      <build>
-        <plugins>
-          <plugin>
-            <groupId>org.apache.maven.plugins</groupId>
-            <artifactId>maven-surefire-plugin</artifactId>
-            <configuration>
-              <systemPropertyVariables>
-                <test.sftp.uri>${test.sftp.uri}</test.sftp.uri>
-              </systemPropertyVariables>
-            </configuration>
-          </plugin>
-        </plugins>
-      </build>
-    </profile>
-
-    <profile>
-      <id>http</id>
-      <activation>
-        <activeByDefault>false</activeByDefault>
-      </activation>
-      <build>
-        <plugins>
-          <plugin>
-            <groupId>org.apache.maven.plugins</groupId>
-            <artifactId>maven-surefire-plugin</artifactId>
-            <configuration>
-              <systemPropertyVariables>
-                <test.http.uri>${test.http.uri}</test.http.uri>
-              </systemPropertyVariables>
-            </configuration>
-          </plugin>
-        </plugins>
-      </build>
-    </profile>
-
-    <!-- On Windows we disable hdfs tests by default. -->
-    <profile>
-      <id>no-test-hdfs</id>
-      <activation>
-        <activeByDefault>false</activeByDefault>
-        <os>
-          <family>Windows</family>
-        </os>
-      </activation>
-      <build>
-        <plugins>
-          <plugin>
-            <groupId>org.apache.maven.plugins</groupId>
-            <artifactId>maven-surefire-plugin</artifactId>
-            <configuration>
-              <excludes>
-                <exclude>**/HdfsFileProviderTest.java</exclude>
-                <exclude>**/HdfsFileProviderTestCase.java</exclude>
-                <!-- Need to port fully to JUnit 4 or 5. -->
-                <!-- *Tests.java files with @Test methods should not be run since these classes are in fact JUnit 3 classes used in custom JUnit 3 test suites. -->
-                <exclude>**/*Tests.java</exclude>
-              </excludes>
-            </configuration>
-          </plugin>
-        </plugins>
-      </build>
-    </profile>
-  </profiles>
-
-</project>
+<?xml version="1.0" encoding="UTF-8"?>\r
+\r
+<!--\r
+   Licensed to the Apache Software Foundation (ASF) under one or more\r
+   contributor license agreements.  See the NOTICE file distributed with\r
+   this work for additional information regarding copyright ownership.\r
+   The ASF licenses this file to You under the Apache License, Version 2.0\r
+   (the "License"); you may not use this file except in compliance with\r
+   the License.  You may obtain a copy of the License at\r
+\r
+        http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+  -->\r
+\r
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">\r
+\r
+  <modelVersion>4.0.0</modelVersion>\r
+\r
+  <name>Apache Commons VFS</name>\r
+  <artifactId>commons-vfs2</artifactId>\r
+  <description>Apache Commons VFS is a Virtual File System library.</description>\r
+  <url>https://commons.apache.org/proper/commons-vfs/</url>\r
+\r
+  <parent>\r
+    <groupId>org.apache.commons</groupId>\r
+    <artifactId>commons-vfs2-project</artifactId>\r
+    <version>2.10.0-SNAPSHOT</version>\r
+    <relativePath>../</relativePath>\r
+  </parent>\r
+\r
+  <dependencies>\r
+    <dependency>\r
+      <groupId>commons-logging</groupId>\r
+      <artifactId>commons-logging</artifactId>\r
+    </dependency>\r
+    <dependency>\r
+      <groupId>ant</groupId>\r
+      <artifactId>ant</artifactId>\r
+      <optional>true</optional>\r
+    </dependency>\r
+    <dependency>\r
+      <groupId>commons-net</groupId>\r
+      <artifactId>commons-net</artifactId>\r
+      <optional>true</optional>\r
+    </dependency>\r
+    <dependency>\r
+      <groupId>org.apache.commons</groupId>\r
+      <artifactId>commons-compress</artifactId>\r
+      <optional>true</optional>\r
+    </dependency>\r
+    <dependency>\r
+      <groupId>org.apache.commons</groupId>\r
+      <artifactId>commons-collections4</artifactId>\r
+      <optional>true</optional>\r
+    </dependency>\r
+    <dependency>\r
+      <groupId>org.apache.hadoop</groupId>\r
+      <artifactId>hadoop-hdfs-client</artifactId>\r
+    </dependency>\r
+    <dependency>\r
+      <groupId>org.apache.hadoop</groupId>\r
+      <artifactId>hadoop-common</artifactId>\r
+      <optional>true</optional>\r
+    </dependency>\r
+    <dependency>\r
+      <groupId>org.apache.hadoop</groupId>\r
+      <artifactId>hadoop-hdfs</artifactId>\r
+      <optional>true</optional>\r
+    </dependency>\r
+    <dependency>\r
+      <groupId>commons-httpclient</groupId>\r
+      <artifactId>commons-httpclient</artifactId>\r
+      <optional>true</optional>\r
+    </dependency>\r
+    <dependency>\r
+      <groupId>org.apache.httpcomponents</groupId>\r
+      <artifactId>httpclient</artifactId>\r
+      <optional>true</optional>\r
+    </dependency>\r
+    <dependency>\r
+      <groupId>org.apache.httpcomponents.client5</groupId>\r
+      <artifactId>httpclient5</artifactId>\r
+      <optional>true</optional>\r
+    </dependency>\r
+    <dependency>\r
+      <groupId>com.jcraft</groupId>\r
+      <artifactId>jsch</artifactId>\r
+      <optional>true</optional>\r
+    </dependency>\r
+    <!-- Tests -->\r
+    <dependency>\r
+      <groupId>org.junit.jupiter</groupId>\r
+      <artifactId>junit-jupiter-engine</artifactId>\r
+      <scope>test</scope>\r
+    </dependency>\r
+    <dependency>\r
+      <groupId>org.junit.vintage</groupId>\r
+      <artifactId>junit-vintage-engine</artifactId>\r
+      <scope>test</scope>\r
+    </dependency>\r
+    <dependency>\r
+      <groupId>org.mockito</groupId>\r
+      <artifactId>mockito-core</artifactId>\r
+      <scope>test</scope>\r
+    </dependency>\r
+    <dependency>\r
+      <groupId>org.apache.commons</groupId>\r
+      <artifactId>commons-lang3</artifactId>\r
+    </dependency>\r
+    <!-- Test FTP with Apache FTP Server (MINA) -->\r
+    <dependency>\r
+      <groupId>org.apache.ftpserver</groupId>\r
+      <artifactId>ftpserver-core</artifactId>\r
+      <scope>test</scope>\r
+    </dependency>\r
+    <dependency>\r
+      <groupId>org.slf4j</groupId>\r
+      <artifactId>slf4j-api</artifactId>\r
+      <scope>test</scope>\r
+    </dependency>\r
+    <dependency>\r
+      <groupId>org.apache.logging.log4j</groupId>\r
+      <artifactId>log4j-slf4j-impl</artifactId>\r
+      <scope>test</scope>\r
+    </dependency>\r
+    <dependency>\r
+      <groupId>org.apache.logging.log4j</groupId>\r
+      <artifactId>log4j-core</artifactId>\r
+      <scope>test</scope>\r
+    </dependency>\r
+    <!-- Test SFTP with Apache SHHd Server (MINA) -->\r
+    <dependency>\r
+      <groupId>org.apache.sshd</groupId>\r
+      <artifactId>sshd-core</artifactId>\r
+      <scope>test</scope>\r
+    </dependency>\r
+    <dependency>\r
+      <groupId>org.bouncycastle</groupId>\r
+      <artifactId>bcprov-jdk16</artifactId>\r
+      <scope>test</scope>\r
+    </dependency>\r
+    <dependency>\r
+      <groupId>commons-io</groupId>\r
+      <artifactId>commons-io</artifactId>\r
+      <scope>test</scope>\r
+    </dependency>\r
+    <!-- Test HTTP with Apache HttpComponent Core -->\r
+    <dependency>\r
+      <groupId>org.apache.httpcomponents</groupId>\r
+      <artifactId>httpcore-nio</artifactId>\r
+      <scope>test</scope>\r
+    </dependency>\r
+    <!-- Test HDFS with Apache Hadoop -->\r
+    <dependency>\r
+      <groupId>org.apache.hadoop</groupId>\r
+      <artifactId>hadoop-common</artifactId>\r
+      <type>test-jar</type>\r
+      <scope>test</scope>\r
+      <exclusions>\r
+        <exclusion>\r
+         <!-- VFS-606 - tools.jar not available in Java 9\r
+              This exclusion can be removed after upgrading Hadoop\r
+              to 2.7.1 or later  \r
+          -->\r
+          <groupId>jdk.tools</groupId>\r
+          <artifactId>jdk.tools</artifactId>\r
+        </exclusion>\r
+      </exclusions>\r
+    </dependency>\r
+    <dependency>\r
+      <groupId>org.apache.hadoop</groupId>\r
+      <artifactId>hadoop-hdfs</artifactId>\r
+      <type>test-jar</type>\r
+      <scope>test</scope>\r
+    </dependency>\r
+    <dependency>\r
+      <groupId>javax.ws.rs</groupId>\r
+      <artifactId>jsr311-api</artifactId>\r
+      <scope>test</scope>\r
+    </dependency>\r
+  </dependencies>\r
+\r
+  <properties>\r
+    <vfs.parent.dir>${basedir}/..</vfs.parent.dir>\r
+    <commons.osgi.import>\r
+        org.apache.hadoop.*;resolution:=optional,\r
+        org.apache.tools.ant.*;resolution:=optional,\r
+        org.apache.commons.httpclient.*;resolution:=optional,\r
+        *\r
+    </commons.osgi.import>\r
+  </properties>\r
+\r
+  <build>\r
+    <resources>\r
+      <resource>\r
+        <directory>${basedir}/src/main/resources</directory>\r
+      </resource>\r
+      <!-- include NOTICE/LICENSE in generated jar -->\r
+      <resource>\r
+        <directory>${vfs.parent.dir}</directory>\r
+        <targetPath>META-INF</targetPath>\r
+        <includes>\r
+          <include>NOTICE.txt</include>\r
+          <include>LICENSE.txt</include>\r
+        </includes>\r
+      </resource>\r
+    </resources>\r
+\r
+    <testResources>\r
+      <testResource>\r
+        <directory>src/test/resources</directory>\r
+      </testResource>\r
+      <!-- include NOTICE/LICENSE in generated test jar -->\r
+      <testResource>\r
+        <directory>${vfs.parent.dir}</directory>\r
+        <targetPath>META-INF</targetPath>\r
+        <includes>\r
+          <include>NOTICE.txt</include>\r
+          <include>LICENSE.txt</include>\r
+        </includes>\r
+      </testResource>\r
+    </testResources>\r
+\r
+    <plugins>\r
+      <plugin>\r
+        <groupId>org.apache.maven.plugins</groupId>\r
+        <artifactId>maven-jar-plugin</artifactId>\r
+        <executions>\r
+          <execution>\r
+            <goals>\r
+              <goal>test-jar</goal>\r
+            </goals>\r
+          </execution>\r
+        </executions>\r
+      </plugin>\r
+\r
+      <plugin>\r
+        <groupId>org.apache.maven.plugins</groupId>\r
+        <artifactId>maven-antrun-plugin</artifactId>\r
+        <executions>\r
+          <execution>\r
+            <phase>process-test-classes</phase>\r
+            <configuration>\r
+              <target>\r
+                <move todir="${project.build.testOutputDirectory}/test-data/code" failonerror="false">\r
+                  <fileset dir="${project.build.testOutputDirectory}/code" />\r
+                </move>\r
+              </target>\r
+            </configuration>\r
+            <goals>\r
+              <goal>run</goal>\r
+            </goals>\r
+          </execution>\r
+        </executions>\r
+      </plugin>\r
+\r
+      <plugin>\r
+        <groupId>org.apache.maven.plugins</groupId>\r
+        <artifactId>maven-surefire-plugin</artifactId>\r
+        <configuration>\r
+          <trimStackTrace>false</trimStackTrace>\r
+          <systemPropertyVariables>\r
+            <test.basedir>target/test-classes/test-data</test.basedir>\r
+            <test.basedir.res>test-data</test.basedir.res>\r
+            <derby.stream.error.file>target/derby.log</derby.stream.error.file>\r
+          </systemPropertyVariables>\r
+          <excludes>\r
+            <!-- Main class -->\r
+            <exclude>**/RunTest.java</exclude>\r
+            <!-- inner classes -->\r
+            <exclude>**/*$*</exclude>\r
+            <!-- Need to port fully to JUnit 4 or 5. -->\r
+            <!-- *Tests.java files with @Test methods should not be run since these classes are in fact JUnit 3 classes used in custom JUnit 3 test suites. -->\r
+            <exclude>**/*Tests.java</exclude>\r
+          </excludes>\r
+        </configuration>\r
+      </plugin>\r
+    </plugins>\r
+  </build>\r
+\r
+  <profiles>\r
+    <profile>\r
+      <id>webdav</id>\r
+      <activation>\r
+        <activeByDefault>false</activeByDefault>\r
+      </activation>\r
+      <build>\r
+        <plugins>\r
+          <plugin>\r
+            <groupId>org.apache.maven.plugins</groupId>\r
+            <artifactId>maven-surefire-plugin</artifactId>\r
+            <configuration>\r
+              <systemPropertyVariables>\r
+                <test.webdav.uri>${test.webdav.uri}</test.webdav.uri>\r
+              </systemPropertyVariables>\r
+            </configuration>\r
+          </plugin>\r
+        </plugins>\r
+      </build>\r
+    </profile>\r
+\r
+    <profile>\r
+      <id>ftp</id>\r
+      <activation>\r
+        <activeByDefault>false</activeByDefault>\r
+      </activation>\r
+      <build>\r
+        <plugins>\r
+          <plugin>\r
+            <groupId>org.apache.maven.plugins</groupId>\r
+            <artifactId>maven-surefire-plugin</artifactId>\r
+            <configuration>\r
+              <systemPropertyVariables>\r
+                <test.ftp.uri>${test.ftp.uri}</test.ftp.uri>\r
+              </systemPropertyVariables>\r
+            </configuration>\r
+          </plugin>\r
+        </plugins>\r
+      </build>\r
+    </profile>\r
+\r
+    <profile>\r
+      <id>sftp</id>\r
+      <activation>\r
+        <activeByDefault>false</activeByDefault>\r
+      </activation>\r
+      <build>\r
+        <plugins>\r
+          <plugin>\r
+            <groupId>org.apache.maven.plugins</groupId>\r
+            <artifactId>maven-surefire-plugin</artifactId>\r
+            <configuration>\r
+              <systemPropertyVariables>\r
+                <test.sftp.uri>${test.sftp.uri}</test.sftp.uri>\r
+              </systemPropertyVariables>\r
+            </configuration>\r
+          </plugin>\r
+        </plugins>\r
+      </build>\r
+    </profile>\r
+\r
+    <profile>\r
+      <id>http</id>\r
+      <activation>\r
+        <activeByDefault>false</activeByDefault>\r
+      </activation>\r
+      <build>\r
+        <plugins>\r
+          <plugin>\r
+            <groupId>org.apache.maven.plugins</groupId>\r
+            <artifactId>maven-surefire-plugin</artifactId>\r
+            <configuration>\r
+              <systemPropertyVariables>\r
+                <test.http.uri>${test.http.uri}</test.http.uri>\r
+              </systemPropertyVariables>\r
+            </configuration>\r
+          </plugin>\r
+        </plugins>\r
+      </build>\r
+    </profile>\r
+\r
+    <!-- On Windows we disable hdfs tests by default. -->\r
+    <profile>\r
+      <id>no-test-hdfs</id>\r
+      <activation>\r
+        <activeByDefault>false</activeByDefault>\r
+        <os>\r
+          <family>Windows</family>\r
+        </os>\r
+      </activation>\r
+      <build>\r
+        <plugins>\r
+          <plugin>\r
+            <groupId>org.apache.maven.plugins</groupId>\r
+            <artifactId>maven-surefire-plugin</artifactId>\r
+            <configuration>\r
+              <excludes>\r
+                <exclude>**/HdfsFileProviderTest.java</exclude>\r
+                <exclude>**/HdfsFileProviderTestCase.java</exclude>\r
+                <!-- Need to port fully to JUnit 4 or 5. -->\r
+                <!-- *Tests.java files with @Test methods should not be run since these classes are in fact JUnit 3 classes used in custom JUnit 3 test suites. -->\r
+                <exclude>**/*Tests.java</exclude>\r
+              </excludes>\r
+            </configuration>\r
+          </plugin>\r
+        </plugins>\r
+      </build>\r
+    </profile>\r
+  </profiles>\r
+\r
+</project>\r
index 27a6b2073496b2b8b7a03a5c4469b1f84bfb171e..6b7b7f807eef772ba71c46d109b6aa3cd2fb2a4c 100644 (file)
@@ -60,7 +60,7 @@ public interface FileContent extends Closeable {
     /**
      * Gets the value of an attribute of the file's content.
      *
-     * @param attrName The name of the attribute. Attribute names are case insensitive.
+     * @param attrName The name of the attribute. Attribute names are case-insensitive.
      * @return The value of the attribute, or null if the attribute value is unknown.
      * @throws FileSystemException If the file does not exist, or does not support attributes.
      */
@@ -248,7 +248,7 @@ public interface FileContent extends Closeable {
     }
 
     /**
-     * Gets an stream for reading/writing the file's content.
+     * Gets a stream for reading/writing the file's content.
      * <p>
      * If the file does not exist, and you use one of the write* methods, this method creates it, and the parent folder,
      * if necessary. If the file does exist, parts of the file are replaced with whatever is written at a given
index 714379aeb3932f7715592497481b9f6b3d756af6..96a00e1381fc36d7089e271a34679c471289066d 100644 (file)
@@ -22,7 +22,7 @@ package org.apache.commons.vfs2;
 public interface FileContentInfoFactory {
 
     /**
-     * Creates a FileContentInfo for the given FileContent.
+     * Creates a FileContentInfo for the given FileContent.
      *
      * @param fileContent Use this FileContent to create a matching FileContentInfo
      * @return a FileContentInfo for the given FileContent.
index 863e35b68618bd1a29efc77af6ada6df6df1ddc3..618d037da951d46a07b5f6c7df8f20a66a2a901f 100644 (file)
@@ -70,19 +70,14 @@ public class FileExtensionSelector implements FileSelector {
      */
     @Override
     public boolean includeFile(final FileSelectInfo fileInfo) throws Exception {
-        for (final String extension : this.extensions) {
-            if (fileInfo.getFile().getName().getExtension().equalsIgnoreCase(extension)) {
-                return true;
-            }
-        }
-        return false;
+        return extensions.stream().anyMatch(extension -> fileInfo.getFile().getName().getExtension().equalsIgnoreCase(extension));
     }
 
     /**
      * Determines whether a folder should be traversed.
      *
      * @param fileInfo The file selection information.
-     * @return true if descendants should be traversed, fase otherwise.
+     * @return true if descendants should be traversed, false otherwise.
      */
     @Override
     public boolean traverseDescendents(final FileSelectInfo fileInfo) throws Exception {
index fac53489c71cf82ad166617ea1b4328e826b0141..42cc86d5ac51e8f5e174cd9219d49582f326eb0b 100644 (file)
@@ -17,7 +17,7 @@
 package org.apache.commons.vfs2;
 
 /**
- * Information about a file, that is used to select files during the traversal of a hierarchy.
+ * Gets information about a file, used to select files during the traversal of a hierarchy.
  * <p>
  * TODO - Rename this interface, as it is used by both FileSelector and FileVisitor.
  * </p>
@@ -25,21 +25,21 @@ package org.apache.commons.vfs2;
 public interface FileSelectInfo {
 
     /**
-     * Returns the base folder of the traversal.
+     * Gets the base folder of the traversal.
      *
      * @return FileObject representing the base folder.
      */
     FileObject getBaseFolder();
 
     /**
-     * Returns the depth of the file relative to the base folder.
+     * Gets the depth of the file relative to the base folder.
      *
      * @return The depth of the file relative to the base folder.
      */
     int getDepth();
 
     /**
-     * Returns the file (or folder) to be considered.
+     * Gets the file (or folder) to be considered.
      *
      * @return The FileObject.
      */
index b386ce0afefce591c18d2620b7312da2bba85436..944e96ab8c7b58ba25dcdbeeca94bd2acd22be1b 100644 (file)
 package org.apache.commons.vfs2;
 
 /**
- * This interface is used to select files when traversing a file hierarchy.
+ * Selects what to traverse a file hierarchy.
  *
  * @see Selectors
  */
 public interface FileSelector {
 
     /**
-     * Determines if a file or folder should be selected. This method is called in depthwise order (that is, it is
+     * Tests if a file or folder should be selected. This method is called in depthwise order (that is, it is
      * called for the children of a folder before it is called for the folder itself).
      *
      * @param fileInfo the file or folder to select.
@@ -34,7 +34,7 @@ public interface FileSelector {
     boolean includeFile(FileSelectInfo fileInfo) throws Exception;
 
     /**
-     * Determines whether a folder should be traversed. If this method returns true, {@link #includeFile} is called for
+     * Tests whether a folder should be traversed. If this method returns true, {@link #includeFile} is called for
      * each of the children of the folder, and each of the child folders is recursively traversed.
      * <p>
      * This method is called on a folder before {@link #includeFile} is called.
@@ -43,6 +43,24 @@ public interface FileSelector {
      * @param fileInfo the file or folder to select.
      * @return true if the folder should be traversed.
      * @throws Exception if an error occurs.
+     * @since 2.10.0
      */
+    default boolean traverseDescendants(FileSelectInfo fileInfo) throws Exception {
+        return traverseDescendents(fileInfo);
+    }
+
+    /**
+     * Tests whether a folder should be traversed. If this method returns true, {@link #includeFile} is called for
+     * each of the children of the folder, and each of the child folders is recursively traversed.
+     * <p>
+     * This method is called on a folder before {@link #includeFile} is called.
+     * </p>
+     *
+     * @param fileInfo the file or folder to select.
+     * @return true if the folder should be traversed.
+     * @throws Exception if an error occurs.
+     * @deprecated Use {@link #traverseDescendants(FileSelectInfo)}.
+     */
+    @Deprecated
     boolean traverseDescendents(FileSelectInfo fileInfo) throws Exception;
 }
index cb839f7b79dbe4c7743904651b29ae67cf5996dd..e7179fa3cd0d8494b8fa094e29940e7fffb7d2ac 100644 (file)
@@ -60,7 +60,7 @@ public interface FileSystem {
     Object getAttribute(String attrName) throws FileSystemException;
 
     /**
-     * Returns a reference to the FileSytemManager.
+     * Returns a reference to the FileSystemManager.
      *
      * @return The FileSystemManager.
      */
@@ -148,7 +148,7 @@ public interface FileSystem {
      * Creates a temporary local copy of a file and its descendants. If this file is already a local file, a copy is not
      * made.
      * <p>
-     * Note that the local copy may include additonal files, that were not selected by the given selector.
+     * Note that the local copy may include additional files, that were not selected by the given selector.
      * </p>
      * <p>
      * TODO - Add options to indicate whether the caller is happy to deal with extra files being present locally (eg if
index bfadd594224f052dce720ba6eb8f234e35111ae5..13de93a6a7a0c4c8dddad8611fca71fa6cd50a19 100644 (file)
@@ -59,7 +59,7 @@ public interface FileSystemManager extends AutoCloseable {
      * we can register {@code SvnWsOperationProvider} and {@code CvsOperationProvider.}
      * </p>
      *
-     * @param scheme The scheme assoicated with this provider.
+     * @param scheme The scheme associated with this provider.
      * @param operationProvider The FileOperationProvider to add.
      * @throws FileSystemException if an error occurs.
      */
@@ -189,16 +189,16 @@ public interface FileSystemManager extends AutoCloseable {
     /**
      * Gets the configuration builder for the given scheme.
      *
-     * @param scheme The schem to use to obtain the FileSystemConfigBuidler.
+     * @param scheme The scheme to use to obtain the FileSystemConfigBuilder.
      * @return A FileSystemConfigBuilder appropriate for the given scheme.
-     * @throws FileSystemException if the given scheme is not konwn.
+     * @throws FileSystemException if the given scheme is not known.
      */
     FileSystemConfigBuilder getFileSystemConfigBuilder(String scheme) throws FileSystemException;
 
     /**
      * Gets Providers for file operations.
      *
-     * @param scheme the scheme for wich we want to get the list af registered providers.
+     * @param scheme the scheme for which we want to get the list af registered providers.
      *
      * @return the registered FileOperationProviders for the specified scheme. If there were no providers registered for
      *         the scheme, it returns null.
@@ -212,7 +212,7 @@ public interface FileSystemManager extends AutoCloseable {
      *
      * @param scheme The scheme to use to locate the provider's capabilities.
      * @return A Collection of the various capabilities.
-     * @throws FileSystemException if the given scheme is not konwn.
+     * @throws FileSystemException if the given scheme is not known.
      */
     Collection<Capability> getProviderCapabilities(String scheme) throws FileSystemException;
 
index 30f4acd3f017897d9fcde3ba3d0798c5275cf801..59054e4748d251f355bb55fc863a5ad200e393d3 100644 (file)
@@ -49,7 +49,7 @@ public class InvertIncludeFileSelector implements FileSelector {
      */
     @Override
     public boolean traverseDescendents(final FileSelectInfo fileInfo) throws Exception {
-        return delegateFileSelector.traverseDescendents(fileInfo);
+        return delegateFileSelector.traverseDescendants(fileInfo);
     }
 
 }
index c4a5018ef70c49d7c1f858a38766da29c6ebca26..7a11a5c3c591c33ce506d6efbc2f1ba4a8f1c514 100644 (file)
@@ -20,7 +20,7 @@ import org.apache.commons.logging.Log;
 
 /**
  * This class is to keep the old logging behavior (for ant-task) and to be able to correctly use commons-logging.
- * I hope i could remove it sometimes.
+ * I hope I could remove it sometimes.
  */
 public final class VfsLog {
 
index aacf64f12de1cb53c550e587da4948f972f6aabb..c6bf7ac2d3c112553997fcdbf9d445e08d350c23 100644 (file)
@@ -114,7 +114,7 @@ public class LRUFilesCache extends AbstractFilesCache {
     private final Lock writeLock = rwLock.writeLock();
 
     /**
-     * Default constructor. Uses a LRU size of 100 per file system.
+     * Default constructor. Uses an LRU size of 100 per file system.
      */
     public LRUFilesCache() {
         this(DEFAULT_LRU_SIZE);
index f8a90e5e27fa1c6abfe2572d3054eadf11a42fe7..aee099f38e18a0363b871bd61b100ef36d76a679 100644 (file)
@@ -25,7 +25,7 @@ import org.apache.commons.vfs2.FileObject;
 /**
  * This implementation caches every file as long as it is strongly reachable by the java vm. As soon as the object is no
  * longer reachable it will be discarded. In contrast to the SoftRefFilesCache this implementation might free resources
- * faster as it don't wait until a memory limitation.
+ * faster as it doesn't wait until a memory limitation.
  *
  * @see java.lang.ref.WeakReference
  */
index 04c02a01006c0150cb971f51097276aabb4697bd..a469a7b4f1af817ccf969e8acc0c655b8caa3630 100644 (file)
@@ -47,7 +47,7 @@ import org.apache.commons.vfs2.FileSystemException;
  * </pre>
  *
  * @author This code was originally ported from Apache Commons IO File Filter
- * @see "http://commons.apache.org/proper/commons-io/"
+ * @see "https://commons.apache.org/proper/commons-io/"
  * @since 2.4
  */
 public class AgeFileFilter implements FileFilter, Serializable {
@@ -86,7 +86,7 @@ public class AgeFileFilter implements FileFilter, Serializable {
      * Constructs a new age file filter for files older than (at or before) a
      * certain File (whose last modification time will be used as reference).
      *
-     * @param cutoffReference the file whose last modification time is usesd as the
+     * @param cutoffReference the file whose last modification time is used as the
      *                        threshold age of the files
      *
      * @throws FileSystemException Error reading the last modification time from the
@@ -100,7 +100,7 @@ public class AgeFileFilter implements FileFilter, Serializable {
      * Constructs a new age file filter for files on any one side of a certain File
      * (whose last modification time will be used as reference).
      *
-     * @param cutoffReference the file whose last modification time is usesd as the
+     * @param cutoffReference the file whose last modification time is used as the
      *                        threshold age of the files
      * @param acceptOlder     if true, older files (at or before the cutoff) are
      *                        accepted, else newer ones (after the cutoff).
@@ -177,9 +177,9 @@ public class AgeFileFilter implements FileFilter, Serializable {
     }
 
     /**
-     * Provide a String representaion of this file filter.
+     * Provide a String representation of this file filter.
      *
-     * @return a String representaion
+     * @return a String representation
      */
     @Override
     public String toString() {
index b0fd2b0e0d35432ad0c010e84ed460b78d299395..2b1a2d683aada411c870e3b05698109f3ee24a78 100644 (file)
@@ -34,7 +34,7 @@ import org.apache.commons.vfs2.FileSystemException;
  * when the first filter returns {@code false}.
  *
  * @author This code was originally ported from Apache Commons IO File Filter
- * @see "http://commons.apache.org/proper/commons-io/"
+ * @see "https://commons.apache.org/proper/commons-io/"
  * @since 2.4
  */
 public class AndFileFilter implements FileFilter, ConditionalFileFilter, Serializable {
index 5aab917b5e2f1e695a2e56c1c75b109cf442076e..e8ec551b64703ddbd60e83e29dbed8493363fb7a 100644 (file)
@@ -52,7 +52,7 @@ import org.apache.commons.vfs2.FileSystemException;
  * }
  * </pre>
  *
- * @see "http://commons.apache.org/proper/commons-io/"
+ * @see "https://commons.apache.org/proper/commons-io/"
  * @since 2.4
  */
 public class CanExecuteFileFilter implements FileFilter, Serializable {
index d1151377c5761acbc79e3818e9827ef1b752c0e8..f3e6248730a21bc68918a2bed065a003b8251d3f 100644 (file)
@@ -67,7 +67,7 @@ import org.apache.commons.vfs2.FileSystemException;
  * </pre>
  *
  * @author This code was originally ported from Apache Commons IO File Filter
- * @see "http://commons.apache.org/proper/commons-io/"
+ * @see "https://commons.apache.org/proper/commons-io/"
  * @since 2.4
  */
 public class CanReadFileFilter implements FileFilter, Serializable {
index 689e110016f5aa09baa19f55a24f13702e7dd05c..9e3cc800c82393f21df4a4338d8ef53d9a740262 100644 (file)
@@ -61,7 +61,7 @@ import org.apache.commons.vfs2.FileSystemException;
  * </p>
  *
  * @author This code was originally ported from Apache Commons IO File Filter
- * @see "http://commons.apache.org/proper/commons-io/"
+ * @see "https://commons.apache.org/proper/commons-io/"
  * @since 2.4
  */
 public class CanWriteFileFilter implements FileFilter, Serializable {
index c839011cacf78af7ab2f6c21a5deebb986b0f958..caedbe9d7c8c11b4470d01930d1a96689b369072 100644 (file)
@@ -24,7 +24,7 @@ import org.apache.commons.vfs2.FileFilter;
  * Defines operations for conditional file filters.
  *
  * @author This code was originally ported from Apache Commons IO File Filter
- * @see "http://commons.apache.org/proper/commons-io/"
+ * @see "https://commons.apache.org/proper/commons-io/"
  * @since 2.4
  */
 public interface ConditionalFileFilter {
index fce90f47e95a01d3617619a3bf4e3247543e2405..820a6b8c3b38d7f24708d36a706609c2917d94a3 100644 (file)
@@ -40,7 +40,7 @@ import org.apache.commons.vfs2.FileType;
  * </pre>
  *
  * @author This code was originally ported from Apache Commons IO File Filter
- * @see "http://commons.apache.org/proper/commons-io/"
+ * @see "https://commons.apache.org/proper/commons-io/"
  * @since 2.4
  */
 public class DirectoryFileFilter implements FileFilter, Serializable {
index f53b941c7973e29a4c56ccb1e4bf823ef64ccb68..6ab9fa8f1f65b0d2534218b38f3ed360d165f2d1 100644 (file)
@@ -57,7 +57,7 @@ import org.apache.commons.vfs2.FileType;
  * </pre>
  *
  * @author This code was originally ported from Apache Commons IO File Filter
- * @see "http://commons.apache.org/proper/commons-io/"
+ * @see "https://commons.apache.org/proper/commons-io/"
  * @since 2.4
  */
 public class EmptyFileFilter implements FileFilter, Serializable {
index 21dd2d8c8d0eaa1209894e3606720a07f5abcdfd..15e752f58af19ff427822fcc7ca11c39fb61c749 100644 (file)
@@ -25,7 +25,7 @@ import org.apache.commons.vfs2.FileSelectInfo;
  * A file filter that always returns false.
  *
  * @author This code was originally ported from Apache Commons IO File Filter
- * @see "http://commons.apache.org/proper/commons-io/"
+ * @see "https://commons.apache.org/proper/commons-io/"
  * @since 2.4
  */
 public class FalseFileFilter implements FileFilter, Serializable {
index ebfba5fa59f5f7ad1c18b0116d30defa6d4a77b1..d5fa865294670ddedf010a2756641e534e015473 100644 (file)
@@ -40,7 +40,7 @@ import org.apache.commons.vfs2.FileType;
  * </pre>
  *
  * @author This code was originally ported from Apache Commons IO File Filter
- * @see "http://commons.apache.org/proper/commons-io/"
+ * @see "https://commons.apache.org/proper/commons-io/"
  * @since 2.4
  */
 public class FileFileFilter implements FileFilter, Serializable {
index 01360545b48d87b6803ef31defc2db464119454f..18da0c9fa709d31765d4badd95699125c3c2694e 100644 (file)
@@ -53,7 +53,7 @@ import org.apache.commons.vfs2.FileSystemException;
  * </pre>
  *
  * @author This code was originally ported from Apache Commons IO File Filter
- * @see "http://commons.apache.org/proper/commons-io/"
+ * @see "https://commons.apache.org/proper/commons-io/"
  * @since 2.4
  */
 public class HiddenFileFilter implements FileFilter, Serializable {
@@ -73,7 +73,7 @@ public class HiddenFileFilter implements FileFilter, Serializable {
     }
 
     /**
-     * Checks to see if the file is hidden. Non existing files won't be accepted.
+     * Checks to see if the file is hidden. Non-existing files won't be accepted.
      *
      * @param fileSelectInfo the File to check
      *
index 06e5b5531bc1569defe48f0598fd086ffc26189e..af6df87c46a4ab80502455f894e9e41067f35f76 100644 (file)
@@ -35,18 +35,18 @@ import java.io.File;
  * </p>
  *
  * @author This code was originally ported from Apache Commons IO File Filter
- * @see "http://commons.apache.org/proper/commons-io/"
+ * @see "https://commons.apache.org/proper/commons-io/"
  * @since 2.4
  */
 public enum IOCase {
 
     /**
-     * The constant for case sensitive regardless of operating system.
+     * The constant for case-sensitive regardless of operating system.
      */
     SENSITIVE("Sensitive", true),
 
     /**
-     * The constant for case insensitive regardless of operating system.
+     * The constant for case-insensitive regardless of operating system.
      */
     INSENSITIVE("Insensitive", false),
 
@@ -55,7 +55,7 @@ public enum IOCase {
      * Windows is case-insensitive when comparing file names, Unix is case-sensitive.
      * <p>
      * <strong>Note:</strong> This only caters for Windows and Unix. Other operating
-     * systems (e.g. OSX and OpenVMS) are treated as case sensitive if they use the
+     * systems (e.g. OSX and OpenVMS) are treated as case-sensitive if they use the
      * Unix file separator and case-insensitive if they use the Windows file
      * separator (see {@link java.io.File#separatorChar}).
      * <p>
@@ -222,9 +222,9 @@ public enum IOCase {
     }
 
     /**
-     * Does the object represent case sensitive comparison.
+     * Does the object represent case-sensitive comparison.
      *
-     * @return true if case sensitive
+     * @return true if case-sensitive
      */
     public boolean isCaseSensitive() {
         return sensitive;
index e86a5753f36107773906efaa2c3e3280160f08db..047eb464f3ab17b92466d321d66901157ef1bdd9 100644 (file)
@@ -41,14 +41,14 @@ import org.apache.commons.vfs2.FileSelectInfo;
  * </pre>
  *
  * @author This code was originally ported from Apache Commons IO File Filter
- * @see "http://commons.apache.org/proper/commons-io/"
+ * @see "https://commons.apache.org/proper/commons-io/"
  * @since 2.4
  */
 public class NameFileFilter implements FileFilter, Serializable {
 
     private static final long serialVersionUID = 1L;
 
-    /** Whether the comparison is case sensitive. */
+    /** Whether the comparison is case-sensitive. */
     private final IOCase caseSensitivity;
 
     /** The file names to search for. */
@@ -118,12 +118,7 @@ public class NameFileFilter implements FileFilter, Serializable {
     @Override
     public boolean accept(final FileSelectInfo fileSelectInfo) {
         final String name = fileSelectInfo.getFile().getName().getBaseName();
-        for (final String name2 : this.names) {
-            if (caseSensitivity.checkEquals(name, name2)) {
-                return true;
-            }
-        }
-        return false;
+        return names.stream().anyMatch(name2 -> caseSensitivity.checkEquals(name, name2));
     }
 
     /**
@@ -137,12 +132,7 @@ public class NameFileFilter implements FileFilter, Serializable {
         buffer.append(super.toString());
         buffer.append("(");
         if (names != null) {
-            for (int i = 0; i < names.size(); i++) {
-                if (i > 0) {
-                    buffer.append(",");
-                }
-                buffer.append(names.get(i));
-            }
+            buffer.append(String.join(",", names));
         }
         buffer.append(")");
         return buffer.toString();
index 2ca9bfdc4ce329e134558ed54acb4395ebf1d68c..2ad1afe640d0f29b706679d0c006063a721be048 100644 (file)
@@ -26,7 +26,7 @@ import org.apache.commons.vfs2.FileSystemException;
  * This filter produces a logical NOT of the filters specified.
  *
  * @author This code was originally ported from Apache Commons IO File Filter
- * @see "http://commons.apache.org/proper/commons-io/"
+ * @see "https://commons.apache.org/proper/commons-io/"
  * @since 2.4
  */
 public class NotFileFilter implements FileFilter, Serializable {
index 5ec14db0547f365de21598ec777afa81b654fb47..227b899e7fbedbf157f7eb5a282507e42adad394 100644 (file)
@@ -33,7 +33,7 @@ import org.apache.commons.vfs2.FileSystemException;
  * file filter list stops when the first filter returns {@code true}.
  *
  * @author This code was originally ported from Apache Commons IO File Filter
- * @see "http://commons.apache.org/proper/commons-io/"
+ * @see "https://commons.apache.org/proper/commons-io/"
  * @since 2.4
  */
 public class OrFileFilter implements FileFilter, ConditionalFileFilter, Serializable {
index 4c17d0b5936d72bc3be3530d6199aaf806bfb1a1..c805ac1da36145e1b2ed3e05640ce48262ed67a8 100644 (file)
@@ -41,14 +41,14 @@ import org.apache.commons.vfs2.FileSelectInfo;
  * </pre>
  *
  * @author This code was originally ported from Apache Commons IO File Filter
- * @see "http://commons.apache.org/proper/commons-io/"
+ * @see "https://commons.apache.org/proper/commons-io/"
  * @since 2.4
  */
 public class PrefixFileFilter implements FileFilter, Serializable {
 
     private static final long serialVersionUID = 1L;
 
-    /** Whether the comparison is case sensitive. */
+    /** Whether the comparison is case-sensitive. */
     private final IOCase caseSensitivity;
 
     /** The file name prefixes to search for. */
@@ -117,12 +117,7 @@ public class PrefixFileFilter implements FileFilter, Serializable {
     @Override
     public boolean accept(final FileSelectInfo fileSelectInfo) {
         final String name = fileSelectInfo.getFile().getName().getBaseName();
-        for (final String prefix : this.prefixes) {
-            if (caseSensitivity.checkStartsWith(name, prefix)) {
-                return true;
-            }
-        }
-        return false;
+        return prefixes.stream().anyMatch(prefix -> caseSensitivity.checkStartsWith(name, prefix));
     }
 
     /**
@@ -136,12 +131,7 @@ public class PrefixFileFilter implements FileFilter, Serializable {
         buffer.append(super.toString());
         buffer.append("(");
         if (prefixes != null) {
-            for (int i = 0; i < prefixes.size(); i++) {
-                if (i > 0) {
-                    buffer.append(",");
-                }
-                buffer.append(prefixes.get(i));
-            }
+            buffer.append(String.join(",", prefixes));
         }
         buffer.append(")");
         return buffer.toString();
index f0ca89d9e9783a73bbee801c814cbd43e21c78a1..8a80c57f91398fc1b107f04e01f0e1f3ffd6deae 100644 (file)
@@ -43,7 +43,7 @@ import org.apache.commons.vfs2.FileSelectInfo;
  * </pre>
  *
  * @author This code was originally ported from Apache Commons IO File Filter
- * @see "http://commons.apache.org/proper/commons-io/"
+ * @see "https://commons.apache.org/proper/commons-io/"
  * @since 2.4
  */
 public class RegexFileFilter implements FileFilter, Serializable {
index acbc9d0878a4fce75d0f71cfe03e377483043b08..abb70d643fe57306c85a1ed8378e7f0819def09f 100644 (file)
@@ -43,7 +43,7 @@ import org.apache.commons.vfs2.FileSystemException;
  * </pre>
  *
  * @author This code was originally ported from Apache Commons IO File Filter
- * @see "http://commons.apache.org/proper/commons-io/"
+ * @see "https://commons.apache.org/proper/commons-io/"
  * @since 2.4
  */
 public class SizeFileFilter implements FileFilter, Serializable {
index a1095c4289ad5292cc97507d00bae8b105879920..d86a9085548ca9d49947e442eb98326be38b8731 100644 (file)
@@ -42,14 +42,14 @@ import org.apache.commons.vfs2.FileSelectInfo;
  * </pre>
  *
  * @author This code was originally ported from Apache Commons IO File Filter
- * @see "http://commons.apache.org/proper/commons-io/"
+ * @see "https://commons.apache.org/proper/commons-io/"
  * @since 2.4
  */
 public class SuffixFileFilter implements FileFilter, Serializable {
 
     private static final long serialVersionUID = 1L;
 
-    /** Whether the comparison is case sensitive. */
+    /** Whether the comparison is case-sensitive. */
     private final IOCase caseSensitivity;
 
     /** The file name suffixes to search for. */
@@ -72,7 +72,7 @@ public class SuffixFileFilter implements FileFilter, Serializable {
     }
 
     /**
-     * Constructs a new Suffix file filter for an array of suffixs specifying
+     * Constructs a new Suffix file filter for an array of suffixes specifying
      * case-sensitivity.
      *
      * @param suffixes        the suffixes to allow, must not be null
@@ -115,12 +115,7 @@ public class SuffixFileFilter implements FileFilter, Serializable {
     @Override
     public boolean accept(final FileSelectInfo fileSelectInfo) {
         final String name = fileSelectInfo.getFile().getName().getBaseName();
-        for (final String suffix : this.suffixes) {
-            if (caseSensitivity.checkEndsWith(name, suffix)) {
-                return true;
-            }
-        }
-        return false;
+        return suffixes.stream().anyMatch(suffix -> caseSensitivity.checkEndsWith(name, suffix));
     }
 
     /**
@@ -134,12 +129,7 @@ public class SuffixFileFilter implements FileFilter, Serializable {
         buffer.append(super.toString());
         buffer.append("(");
         if (suffixes != null) {
-            for (int i = 0; i < suffixes.size(); i++) {
-                if (i > 0) {
-                    buffer.append(",");
-                }
-                buffer.append(suffixes.get(i));
-            }
+            buffer.append(String.join(",", suffixes));
         }
         buffer.append(")");
         return buffer.toString();
index e524148c00d7ae095842d488f07896aff9f70f61..925e4215fc214c795baa2c63bc161859624081d9 100644 (file)
@@ -71,7 +71,7 @@ public class SymbolicLinkFileFilter implements FileFilter, Serializable {
     }
 
     /**
-     * Checks to see if the file is a symbolic link. Non existing files won't be accepted.
+     * Checks to see if the file is a symbolic link. Non-existing files won't be accepted.
      *
      * @param fileSelectInfo the file to check
      *
index 377b6d3c62130df12068c6c105ae4fbb426f34c9..947026e2bcf647b839f0357169db334d2b98cb17 100644 (file)
@@ -25,7 +25,7 @@ import org.apache.commons.vfs2.FileSelectInfo;
  * A file filter that always returns true.
  *
  * @author This code was originally ported from Apache Commons IO File Filter
- * @see "http://commons.apache.org/proper/commons-io/"
+ * @see "https://commons.apache.org/proper/commons-io/"
  * @since 2.4
  */
 public class TrueFileFilter implements FileFilter, Serializable {
index 65690bb7ef11f4f0e45a04bc2c2470abdf88f19c..97c135e064ce940a1e8f6f12230b69cad0fc0c33 100644 (file)
@@ -54,14 +54,14 @@ import org.apache.commons.vfs2.FileSelectInfo;
  * </pre>
  *
  * @author This code was originally ported from Apache Commons IO File Filter
- * @see "http://commons.apache.org/proper/commons-io/"
+ * @see "https://commons.apache.org/proper/commons-io/"
  * @since 2.4
  */
 public class WildcardFileFilter implements FileFilter, Serializable {
 
     private static final long serialVersionUID = 1L;
 
-    /** Whether the comparison is case sensitive. */
+    /** Whether the comparison is case-sensitive. */
     private final IOCase caseSensitivity;
 
     /** The wildcards that will be used to match file names. */
@@ -175,7 +175,7 @@ public class WildcardFileFilter implements FileFilter, Serializable {
      * @param caseSensitivity what case sensitivity rule to use, null means
      *                        case-sensitive
      *
-     * @return true if the file name matches the wilcard string
+     * @return true if the file name matches the wildcard string
      */
     // CHECKSTYLE:OFF TODO xxx Cyclomatic complexity of 19 should be refactored
     static boolean wildcardMatch(final String fileName, final String wildcardMatcher, IOCase caseSensitivity) {
@@ -236,7 +236,7 @@ public class WildcardFileFilter implements FileFilter, Serializable {
                         }
                     } else if (!caseSensitivity.checkRegionMatches(fileName, textIdx, wcs[wcsIdx])) {
                         // matching from current position
-                        // couldnt match token
+                        // couldn't match token
                         break;
                     }
 
@@ -270,12 +270,7 @@ public class WildcardFileFilter implements FileFilter, Serializable {
     @Override
     public boolean accept(final FileSelectInfo fileSelectInfo) {
         final String name = fileSelectInfo.getFile().getName().getBaseName();
-        for (final String wildcard : wildcards) {
-            if (wildcardMatch(name, wildcard, caseSensitivity)) {
-                return true;
-            }
-        }
-        return false;
+        return wildcards.stream().anyMatch(wildcard -> wildcardMatch(name, wildcard, caseSensitivity));
     }
 
     // CHECKSTYLE:ON
@@ -291,12 +286,7 @@ public class WildcardFileFilter implements FileFilter, Serializable {
         buffer.append(super.toString());
         buffer.append("(");
         if (wildcards != null) {
-            for (int i = 0; i < wildcards.size(); i++) {
-                if (i > 0) {
-                    buffer.append(",");
-                }
-                buffer.append(wildcards.get(i));
-            }
+            buffer.append(String.join(",", wildcards));
         }
         buffer.append(")");
         return buffer.toString();
index a7b04f6cd5426fabe799bda122f151c5e4f6026a..211f6d2ed0dcad59a1e4f97b79d97c01cf2c2ed1 100644 (file)
@@ -20,6 +20,7 @@ import java.time.Duration;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Stack;
+import java.util.stream.Stream;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -228,10 +229,7 @@ public class DefaultFileMonitor implements Runnable, FileMonitor, AutoCloseable
 
             try {
                 if (this.defaultFileMonitor.isRecursive() && child.getType().hasChildren()) {
-                    final FileObject[] newChildren = child.getChildren();
-                    for (final FileObject element : newChildren) {
-                        fireAllCreate(element);
-                    }
+                    Stream.of(child.getChildren()).forEach(this::fireAllCreate);
                 }
             } catch (final FileSystemException fse) {
                 LOG.error(fse.getLocalizedMessage(), fse);
@@ -253,8 +251,7 @@ public class DefaultFileMonitor implements Runnable, FileMonitor, AutoCloseable
             try {
                 if (this.fileObject.getType().hasChildren()) {
                     this.children = new HashMap<>();
-                    final FileObject[] childrenList = this.fileObject.getChildren();
-                    for (final FileObject element : childrenList) {
+                    for (final FileObject element : this.fileObject.getChildren()) {
                         this.children.put(element.getName(), new Object()); // null?
                     }
                 }
@@ -343,10 +340,8 @@ public class DefaultFileMonitor implements Runnable, FileMonitor, AutoCloseable
 
                     if (file.getType().hasChildren() && this.recursive) {
                         // Traverse the children
-                        final FileObject[] children = file.getChildren();
-                        for (final FileObject element : children) {
-                            this.addFile(element); // Add depth first
-                        }
+                        // Add depth first
+                        Stream.of(file.getChildren()).forEach(this::addFile);
                     }
 
                 } catch (final FileSystemException fse) {
@@ -518,7 +513,7 @@ public class DefaultFileMonitor implements Runnable, FileMonitor, AutoCloseable
     }
 
     /**
-     * Sets the number of files to check per run. a additional delay will be added if there are more files to check
+     * Sets the number of files to check per run. An additional delay will be added if there are more files to check.
      *
      * @param checksPerRun a value less than 1 will disable this feature
      */
index 01a668e631b82a88266d0f8f9eb5fac1e7168296..4b0bb655e234b0571e0f24b52daf9807fe5a4076 100644 (file)
@@ -202,7 +202,7 @@ public class DefaultFileReplicator extends AbstractVfsComponent implements FileR
     }
 
     /**
-     * Removes a instance from the list of copies.
+     * Removes an instance from the list of copies.
      *
      * @param file The File to remove.
      */
index edc9051e77c1548dd6d7f0ebae32f83aa49f27a5..c3374ac7caaa692241d7cecf4ec2fe869bc29aee 100644 (file)
@@ -58,7 +58,7 @@ public class DefaultFileSystemConfigBuilder extends FileSystemConfigBuilder {
     }
 
     /**
-     * Sets the user authenticator to get authentication informations.
+     * Sets the user authenticator to get authentication information.
      *
      * @param opts The FileSystemOptions.
      * @param userAuthenticator The UserAuthenticator.
index b5036d22b23c5690553c3d9d34db44fdba7444b3..800588cc4e5268b1f0d569e2d665a303dc7d999a 100644 (file)
@@ -193,7 +193,7 @@ public class DefaultFileSystemManager implements FileSystemManager {
     }
 
     /**
-     * Adds an file name extension mapping.
+     * Adds a file name extension mapping.
      *
      * @param extension The file name extension.
      * @param scheme The scheme to use for files with this extension.
@@ -419,7 +419,7 @@ public class DefaultFileSystemManager implements FileSystemManager {
         // inform the cache ...
         getFilesCache().clear(fileSystem);
 
-        // just in case the cache didnt call _closeFileSystem
+        // just in case the cache didn't call _closeFileSystem
         _closeFileSystem(fileSystem);
     }
 
@@ -489,11 +489,11 @@ public class DefaultFileSystemManager implements FileSystemManager {
         }
 
         // Close the providers.
-        for (final FileProvider fileProvider : providers.values()) {
+        providers.values().forEach(fileProvider -> {
             if (fileProvider instanceof AbstractFileProvider) {
                 ((AbstractFileProvider) fileProvider).freeUnusedResources();
             }
-        }
+        });
         // vfsProvider does not need to free resources
     }
 
@@ -563,7 +563,7 @@ public class DefaultFileSystemManager implements FileSystemManager {
      *
      * @param scheme The scheme to locate.
      * @return The FileSystemConfigBuilder for the scheme.
-     * @throws FileSystemException if the given scheme is not konwn
+     * @throws FileSystemException if the given scheme is not known
      */
     @Override
     public FileSystemConfigBuilder getFileSystemConfigBuilder(final String scheme) throws FileSystemException {
@@ -596,7 +596,7 @@ public class DefaultFileSystemManager implements FileSystemManager {
     }
 
     /**
-     * @param scheme the scheme for wich we want to get the list af registered providers.
+     * @param scheme the scheme for which we want to get the list af registered providers.
      *
      * @return the registered FileOperationProviders for the specified scheme. If there were no providers registered for
      *         the scheme, it returns null.
@@ -616,9 +616,9 @@ public class DefaultFileSystemManager implements FileSystemManager {
     /**
      * Get the capabilities for a given scheme.
      *
-     * @param scheme The scheme to located.
+     * @param scheme The scheme to locate.
      * @return A Collection of capabilities.
-     * @throws FileSystemException if the given scheme is not konwn
+     * @throws FileSystemException if the given scheme is not known
      */
     @Override
     public Collection<Capability> getProviderCapabilities(final String scheme) throws FileSystemException {
@@ -745,7 +745,7 @@ public class DefaultFileSystemManager implements FileSystemManager {
     /**
      * Resolves a URI, relative to a base file.
      *
-     * @param baseFile The base FileOjbect to use to locate the file.
+     * @param baseFile The base FileObject to use to locate the file.
      * @param uri The URI of the file to locate.
      * @return The FileObject for the located file.
      * @throws FileSystemException if the file cannot be located or an error occurs.
@@ -759,7 +759,7 @@ public class DefaultFileSystemManager implements FileSystemManager {
      * Resolves a URI, relative to a base file with specified FileSystem configuration.
      *
      * @param baseFile The base file.
-     * @param uri The file name. May be a fully qualified or relative path or a url.
+     * @param uri The file name. May be a fully qualified or relative path or an url.
      * @param fileSystemOptions Options to pass to the file system.
      * @return A FileObject representing the target file.
      * @throws FileSystemException if an error occurs accessing the file.
@@ -1076,7 +1076,7 @@ public class DefaultFileSystemManager implements FileSystemManager {
      * Can only be set before the FileSystemManager is initialized.
      * </p>
      *
-     * @param fileObjectDecorator must be inherted from {@link DecoratedFileObject} a has to provide a constructor with
+     * @param fileObjectDecorator must be inherited from {@link DecoratedFileObject} a has to provide a constructor with
      *            a single {@link FileObject} as argument
      * @throws FileSystemException if an error occurs setting the decorator.
      */
@@ -1107,7 +1107,7 @@ public class DefaultFileSystemManager implements FileSystemManager {
      * </p>
      *
      * @param filesCache The FilesCache.
-     * @throws FileSystemException if an error occurs setting the cache..
+     * @throws FileSystemException if an error occurs setting the cache.
      */
     public void setFilesCache(final FilesCache filesCache) throws FileSystemException {
         if (init) {
@@ -1162,7 +1162,7 @@ public class DefaultFileSystemManager implements FileSystemManager {
     /**
      * Initializes a component, if it has not already been initialized.
      *
-     * @param component The component to setup.
+     * @param component The component to set up.
      * @throws FileSystemException if an error occurs.
      */
     private void setupComponent(final Object component) throws FileSystemException {
@@ -1181,7 +1181,7 @@ public class DefaultFileSystemManager implements FileSystemManager {
      * Converts a local file into a {@link FileObject}.
      *
      * @param file The input File.
-     * @return the create FileObject
+     * @return the created FileObject
      * @throws FileSystemException if an error occurs creating the file.
      */
     @Override
index b772af30afa281617453cdc4ab3e2d089d11fcf5..d0c0632d33a9b4dbd6b0c645f5cb6da24f490c3e 100644 (file)
@@ -29,7 +29,7 @@ public class ProviderConfiguration {
 
     private String className;
     private final List<String> schemes = new ArrayList<>(10);
-    private final List<String> dependenies = new ArrayList<>(10);
+    private final List<String> dependencies = new ArrayList<>(10);
 
     /**
      * Constructs a new instance.
@@ -52,7 +52,7 @@ public class ProviderConfiguration {
      * @return the dependency.
      */
     public List<String> getDependencies() {
-        return dependenies;
+        return dependencies;
     }
 
     /**
@@ -88,7 +88,7 @@ public class ProviderConfiguration {
      * @param dependency the dependency.
      */
     public void setDependency(final String dependency) {
-        dependenies.add(dependency);
+        dependencies.add(dependency);
     }
 
     /**
index e62eac9b2886fc2d010c4fe7d142c8cde64cee5d..9c59ade743b46ff36162c91b392668d3818bf3fc 100644 (file)
-/*
- * 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.impl;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.Objects;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.apache.commons.lang3.ArrayUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.vfs2.FileSystemException;
-import org.apache.commons.vfs2.VfsLog;
-import org.apache.commons.vfs2.operations.FileOperationProvider;
-import org.apache.commons.vfs2.provider.FileProvider;
-import org.apache.commons.vfs2.util.Messages;
-import org.w3c.dom.Element;
-import org.w3c.dom.NodeList;
-
-/**
- * A {@link org.apache.commons.vfs2.FileSystemManager} that configures itself from an XML (Default: providers.xml)
- * configuration file.
- * <p>
- * Certain providers are only loaded and available if the dependent library is in your classpath. You have to configure
- * your debugging facility to log "debug" messages to see if a provider was skipped due to "unresolved externals".
- * </p>
- */
-public class StandardFileSystemManager extends DefaultFileSystemManager {
-    private static final String CONFIG_RESOURCE = "providers.xml";
-    private static final String PLUGIN_CONFIG_RESOURCE = "META-INF/vfs-providers.xml";
-
-    private URL configUri;
-    private ClassLoader classLoader;
-
-    /**
-     * Adds an extension map.
-     *
-     * @param map containing the Elements.
-     */
-    private void addExtensionMap(final Element map) {
-        final String extension = map.getAttribute("extension");
-        final String scheme = map.getAttribute("scheme");
-        if (!StringUtils.isEmpty(scheme)) {
-            addExtensionMap(extension, scheme);
-        }
-    }
-
-    /**
-     * Adds a mime-type map.
-     *
-     * @param map containing the Elements.
-     */
-    private void addMimeTypeMap(final Element map) {
-        final String mimeType = map.getAttribute("mime-type");
-        final String scheme = map.getAttribute("scheme");
-        addMimeTypeMap(mimeType, scheme);
-    }
-
-    /**
-     * Adds a operationProvider from a operationProvider definition.
-     */
-    private void addOperationProvider(final Element providerDef) throws FileSystemException {
-        final String classname = providerDef.getAttribute("class-name");
-
-        // Attach only to available schemas
-        final String[] schemas = getSchemas(providerDef);
-        for (final String schema : schemas) {
-            if (hasProvider(schema)) {
-                final FileOperationProvider operationProvider = (FileOperationProvider) createInstance(classname);
-                addOperationProvider(schema, operationProvider);
-            }
-        }
-    }
-
-    /**
-     * Adds a provider from a provider definition.
-     *
-     * @param providerDef the provider definition
-     * @param isDefault true if the default should be used.
-     * @throws FileSystemException if an error occurs.
-     */
-    private void addProvider(final Element providerDef, final boolean isDefault) throws FileSystemException {
-        final String classname = providerDef.getAttribute("class-name");
-
-        // Make sure all required schemes are available
-        final String[] requiredSchemes = getRequiredSchemes(providerDef);
-        for (final String requiredScheme : requiredSchemes) {
-            if (!hasProvider(requiredScheme)) {
-                final String msg = Messages.getString("vfs.impl/skipping-provider-scheme.debug", classname,
-                        requiredScheme);
-                VfsLog.debug(getLogger(), getLogger(), msg);
-                return;
-            }
-        }
-
-        // Make sure all required classes are in classpath
-        final String[] requiredClasses = getRequiredClasses(providerDef);
-        for (final String requiredClass : requiredClasses) {
-            if (!findClass(requiredClass)) {
-                final String msg = Messages.getString("vfs.impl/skipping-provider.debug", classname, requiredClass);
-                VfsLog.debug(getLogger(), getLogger(), msg);
-                return;
-            }
-        }
-
-        // Create and register the provider
-        final FileProvider provider = (FileProvider) createInstance(classname);
-        final String[] schemas = getSchemas(providerDef);
-        if (schemas.length > 0) {
-            addProvider(schemas, provider);
-        }
-
-        // Set as default, if required
-        if (isDefault) {
-            setDefaultProvider(provider);
-        }
-    }
-
-    /**
-     * Configures this manager from an parsed XML configuration file
-     *
-     * @param config The configuration Element.
-     * @throws FileSystemException if an error occurs.
-     */
-    private void configure(final Element config) throws FileSystemException {
-        // Add the providers
-        final NodeList providers = config.getElementsByTagName("provider");
-        final int count = providers.getLength();
-        for (int i = 0; i < count; i++) {
-            final Element provider = (Element) providers.item(i);
-            addProvider(provider, false);
-        }
-
-        // Add the operation providers
-        final NodeList operationProviders = config.getElementsByTagName("operationProvider");
-        for (int i = 0; i < operationProviders.getLength(); i++) {
-            final Element operationProvider = (Element) operationProviders.item(i);
-            addOperationProvider(operationProvider);
-        }
-
-        // Add the default provider
-        final NodeList defProviders = config.getElementsByTagName("default-provider");
-        if (defProviders.getLength() > 0) {
-            final Element provider = (Element) defProviders.item(0);
-            addProvider(provider, true);
-        }
-
-        // Add the mime-type maps
-        final NodeList mimeTypes = config.getElementsByTagName("mime-type-map");
-        for (int i = 0; i < mimeTypes.getLength(); i++) {
-            final Element map = (Element) mimeTypes.item(i);
-            addMimeTypeMap(map);
-        }
-
-        // Add the extension maps
-        final NodeList extensions = config.getElementsByTagName("extension-map");
-        for (int i = 0; i < extensions.getLength(); i++) {
-            final Element map = (Element) extensions.item(i);
-            addExtensionMap(map);
-        }
-    }
-
-    /**
-     * Configures this manager from an XML configuration file.
-     *
-     * @param configUri The URI of the configuration.
-     * @param configStream An InputStream containing the configuration.
-     * @throws FileSystemException if an error occurs.
-     */
-    @SuppressWarnings("unused")
-    private void configure(final String configUri, final InputStream configStream) throws FileSystemException {
-        try {
-            // Load up the config
-            // TODO - validate
-            configure(createDocumentBuilder().parse(configStream).getDocumentElement());
-
-        } catch (final Exception e) {
-            throw new FileSystemException("vfs.impl/load-config.error", configUri, e);
-        }
-    }
-
-    /**
-     * Configures this manager from an XML configuration file.
-     *
-     * @param configUri The URI of the configuration.
-     * @throws FileSystemException if an error occus.
-     */
-    private void configure(final URL configUri) throws FileSystemException {
-        InputStream configStream = null;
-        try {
-            // Load up the config
-            // TODO - validate
-            final DocumentBuilder builder = createDocumentBuilder();
-            configStream = configUri.openStream();
-            final Element config = builder.parse(configStream).getDocumentElement();
-
-            configure(config);
-        } catch (final Exception e) {
-            throw new FileSystemException("vfs.impl/load-config.error", configUri.toString(), e);
-        } finally {
-            if (configStream != null) {
-                try {
-                    configStream.close();
-                } catch (final IOException e) {
-                    getLogger().warn(e.getLocalizedMessage(), e);
-                }
-            }
-        }
-    }
-
-    /**
-     * Scans the classpath to find any droped plugin.
-     * <p>
-     * The plugin-description has to be in {@code /META-INF/vfs-providers.xml}.
-     * </p>
-     *
-     * @throws FileSystemException if an error occurs.
-     */
-    protected void configurePlugins() throws FileSystemException {
-        final Enumeration<URL> enumResources;
-        try {
-            enumResources = enumerateResources(PLUGIN_CONFIG_RESOURCE);
-        } catch (final IOException e) {
-            throw new FileSystemException(e);
-        }
-
-        while (enumResources.hasMoreElements()) {
-            configure(enumResources.nextElement());
-        }
-    }
-
-    protected DefaultFileReplicator createDefaultFileReplicator() {
-        return new DefaultFileReplicator();
-    }
-
-    /**
-     * Configure and create a DocumentBuilder
-     *
-     * @return A DocumentBuilder for the configuration.
-     * @throws ParserConfigurationException if an error occurs.
-     */
-    private DocumentBuilder createDocumentBuilder() throws ParserConfigurationException {
-        final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-        factory.setIgnoringElementContentWhitespace(true);
-        factory.setIgnoringComments(true);
-        factory.setExpandEntityReferences(true);
-        return factory.newDocumentBuilder();
-    }
-
-    /**
-     * Creates a provider.
-     */
-    private Object createInstance(final String className) throws FileSystemException {
-        try {
-            return loadClass(className).newInstance();
-        } catch (final Exception e) {
-            throw new FileSystemException("vfs.impl/create-provider.error", className, e);
-        }
-    }
-
-    /**
-     * Enumerates resources from different class loaders.
-     *
-     * @throws IOException if {@code getResource} failed.
-     * @see #findClassLoader()
-     */
-    private Enumeration<URL> enumerateResources(final String name) throws IOException {
-        Enumeration<URL> enumeration = findClassLoader().getResources(name);
-        if (enumeration == null || !enumeration.hasMoreElements()) {
-            enumeration = getValidClassLoader(getClass()).getResources(name);
-        }
-        return enumeration;
-    }
-
-    /**
-     * Tests if a class is available.
-     */
-    private boolean findClass(final String className) {
-        try {
-            loadClass(className);
-            return true;
-        } catch (final ClassNotFoundException e) {
-            return false;
-        }
-    }
-
-    /**
-     * Returns a class loader or null since some Java implementation is null for the bootstrap class loader.
-     *
-     * @return A class loader or null since some Java implementation is null for the bootstrap class loader.
-     */
-    private ClassLoader findClassLoader() {
-        if (classLoader != null) {
-            return classLoader;
-        }
-        final ClassLoader cl = Thread.currentThread().getContextClassLoader();
-        if (cl != null) {
-            return cl;
-        }
-        return getValidClassLoader(getClass());
-    }
-
-    /**
-     * Extracts the required classes from a provider definition.
-     */
-    private String[] getRequiredClasses(final Element providerDef) {
-        final ArrayList<String> classes = new ArrayList<>();
-        final NodeList deps = providerDef.getElementsByTagName("if-available");
-        final int count = deps.getLength();
-        for (int i = 0; i < count; i++) {
-            final Element dep = (Element) deps.item(i);
-            final String className = dep.getAttribute("class-name");
-            if (!StringUtils.isEmpty(className)) {
-                classes.add(className);
-            }
-        }
-        return classes.toArray(ArrayUtils.EMPTY_STRING_ARRAY);
-    }
-
-    /**
-     * Extracts the required schemes from a provider definition.
-     */
-    private String[] getRequiredSchemes(final Element providerDef) {
-        final ArrayList<String> schemes = new ArrayList<>();
-        final NodeList deps = providerDef.getElementsByTagName("if-available");
-        final int count = deps.getLength();
-        for (int i = 0; i < count; i++) {
-            final Element dep = (Element) deps.item(i);
-            final String scheme = dep.getAttribute("scheme");
-            if (!StringUtils.isEmpty(scheme)) {
-                schemes.add(scheme);
-            }
-        }
-        return schemes.toArray(ArrayUtils.EMPTY_STRING_ARRAY);
-    }
-
-    /**
-     * Extracts the schema names from a provider definition.
-     */
-    private String[] getSchemas(final Element provider) {
-        final ArrayList<String> schemas = new ArrayList<>();
-        final NodeList schemaElements = provider.getElementsByTagName("scheme");
-        final int count = schemaElements.getLength();
-        for (int i = 0; i < count; i++) {
-            final Element scheme = (Element) schemaElements.item(i);
-            schemas.add(scheme.getAttribute("name"));
-        }
-        return schemas.toArray(ArrayUtils.EMPTY_STRING_ARRAY);
-    }
-
-    private ClassLoader getValidClassLoader(final Class<?> clazz) {
-        return validateClassLoader(clazz.getClassLoader(), clazz);
-    }
-
-    /**
-     * Initializes this manager. Adds the providers and replicator.
-     *
-     * @throws FileSystemException if an error occurs.
-     */
-    @Override
-    public void init() throws FileSystemException {
-        // Set the replicator and temporary file store (use the same component)
-        final DefaultFileReplicator replicator = createDefaultFileReplicator();
-        setReplicator(new PrivilegedFileReplicator(replicator));
-        setTemporaryFileStore(replicator);
-
-        if (configUri == null) {
-            // Use default config
-            final URL url = getClass().getResource(CONFIG_RESOURCE);
-            FileSystemException.requireNonNull(url, "vfs.impl/find-config-file.error", CONFIG_RESOURCE);
-            configUri = url;
-        }
-
-        configure(configUri);
-        configurePlugins();
-
-        // Initialize super-class
-        super.init();
-    }
-
-    /**
-     * Load a class from different class loaders.
-     *
-     * @throws ClassNotFoundException if last {@code loadClass} failed.
-     * @see #findClassLoader()
-     */
-    private Class<?> loadClass(final String className) throws ClassNotFoundException {
-        try {
-            return findClassLoader().loadClass(className);
-        } catch (final ClassNotFoundException e) {
-            return getValidClassLoader(getClass()).loadClass(className);
-        }
-    }
-
-    /**
-     * Sets the ClassLoader to use to load the providers. Default is to use the ClassLoader that loaded this class.
-     *
-     * @param classLoader The ClassLoader.
-     */
-    public void setClassLoader(final ClassLoader classLoader) {
-        this.classLoader = classLoader;
-    }
-
-    /**
-     * Sets the configuration file for this manager.
-     *
-     * @param configUri The URI for this manager.
-     */
-    public void setConfiguration(final String configUri) {
-        try {
-            setConfiguration(new URL(configUri));
-        } catch (final MalformedURLException e) {
-            getLogger().warn(e.getLocalizedMessage(), e);
-        }
-    }
-
-    /**
-     * Sets the configuration file for this manager.
-     *
-     * @param configUri The URI forthis manager.
-     */
-    public void setConfiguration(final URL configUri) {
-        this.configUri = configUri;
-    }
-
-    private ClassLoader validateClassLoader(final ClassLoader clazzLoader, final Class<?> clazz) {
-        return Objects.requireNonNull(clazzLoader, "The class loader for " + clazz
-                + " is null; some Java implementions use null for the bootstrap class loader.");
-    }
-
-}
+/*\r
+ * Licensed to the Apache Software Foundation (ASF) under one or more\r
+ * contributor license agreements.  See the NOTICE file distributed with\r
+ * this work for additional information regarding copyright ownership.\r
+ * The ASF licenses this file to You under the Apache License, Version 2.0\r
+ * (the "License"); you may not use this file except in compliance with\r
+ * the License.  You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.apache.commons.vfs2.impl;\r
+\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+import java.net.MalformedURLException;\r
+import java.net.URL;\r
+import java.util.ArrayList;\r
+import java.util.Enumeration;\r
+import java.util.Objects;\r
+\r
+import javax.xml.parsers.DocumentBuilder;\r
+import javax.xml.parsers.DocumentBuilderFactory;\r
+import javax.xml.parsers.ParserConfigurationException;\r
+\r
+import org.apache.commons.lang3.ArrayUtils;\r
+import org.apache.commons.lang3.StringUtils;\r
+import org.apache.commons.vfs2.FileSystemException;\r
+import org.apache.commons.vfs2.VfsLog;\r
+import org.apache.commons.vfs2.operations.FileOperationProvider;\r
+import org.apache.commons.vfs2.provider.FileProvider;\r
+import org.apache.commons.vfs2.util.Messages;\r
+import org.w3c.dom.Element;\r
+import org.w3c.dom.NodeList;\r
+\r
+/**\r
+ * A {@link org.apache.commons.vfs2.FileSystemManager} that configures itself from an XML (Default: providers.xml)\r
+ * configuration file.\r
+ * <p>\r
+ * Certain providers are only loaded and available if the dependent library is in your classpath. You have to configure\r
+ * your debugging facility to log "debug" messages to see if a provider was skipped due to "unresolved externals".\r
+ * </p>\r
+ */\r
+public class StandardFileSystemManager extends DefaultFileSystemManager {\r
+    private static final String CONFIG_RESOURCE = "providers.xml";\r
+    private static final String PLUGIN_CONFIG_RESOURCE = "META-INF/vfs-providers.xml";\r
+\r
+    private URL configUri;\r
+    private ClassLoader classLoader;\r
+\r
+    /**\r
+     * Adds an extension map.\r
+     *\r
+     * @param map containing the Elements.\r
+     */\r
+    private void addExtensionMap(final Element map) {\r
+        final String extension = map.getAttribute("extension");\r
+        final String scheme = map.getAttribute("scheme");\r
+        if (!StringUtils.isEmpty(scheme)) {\r
+            addExtensionMap(extension, scheme);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Adds a mime-type map.\r
+     *\r
+     * @param map containing the Elements.\r
+     */\r
+    private void addMimeTypeMap(final Element map) {\r
+        final String mimeType = map.getAttribute("mime-type");\r
+        final String scheme = map.getAttribute("scheme");\r
+        addMimeTypeMap(mimeType, scheme);\r
+    }\r
+\r
+    /**\r
+     * Adds a operationProvider from a operationProvider definition.\r
+     */\r
+    private void addOperationProvider(final Element providerDef) throws FileSystemException {\r
+        final String classname = providerDef.getAttribute("class-name");\r
+\r
+        // Attach only to available schemas\r
+        final String[] schemas = getSchemas(providerDef);\r
+        for (final String schema : schemas) {\r
+            if (hasProvider(schema)) {\r
+                final FileOperationProvider operationProvider = (FileOperationProvider) createInstance(classname);\r
+                addOperationProvider(schema, operationProvider);\r
+            }\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Adds a provider from a provider definition.\r
+     *\r
+     * @param providerDef the provider definition\r
+     * @param isDefault true if the default should be used.\r
+     * @throws FileSystemException if an error occurs.\r
+     */\r
+    private void addProvider(final Element providerDef, final boolean isDefault) throws FileSystemException {\r
+        final String classname = providerDef.getAttribute("class-name");\r
+\r
+        // Make sure all required schemes are available\r
+        final String[] requiredSchemes = getRequiredSchemes(providerDef);\r
+        for (final String requiredScheme : requiredSchemes) {\r
+            if (!hasProvider(requiredScheme)) {\r
+                final String msg = Messages.getString("vfs.impl/skipping-provider-scheme.debug", classname,\r
+                        requiredScheme);\r
+                VfsLog.debug(getLogger(), getLogger(), msg);\r
+                return;\r
+            }\r
+        }\r
+\r
+        // Make sure all required classes are in classpath\r
+        final String[] requiredClasses = getRequiredClasses(providerDef);\r
+        for (final String requiredClass : requiredClasses) {\r
+            if (!findClass(requiredClass)) {\r
+                final String msg = Messages.getString("vfs.impl/skipping-provider.debug", classname, requiredClass);\r
+                VfsLog.debug(getLogger(), getLogger(), msg);\r
+                return;\r
+            }\r
+        }\r
+\r
+        // Create and register the provider\r
+        final FileProvider provider = (FileProvider) createInstance(classname);\r
+        final String[] schemas = getSchemas(providerDef);\r
+        if (schemas.length > 0) {\r
+            addProvider(schemas, provider);\r
+        }\r
+\r
+        // Set as default, if required\r
+        if (isDefault) {\r
+            setDefaultProvider(provider);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Configures this manager from a parsed XML configuration file\r
+     *\r
+     * @param config The configuration Element.\r
+     * @throws FileSystemException if an error occurs.\r
+     */\r
+    private void configure(final Element config) throws FileSystemException {\r
+        // Add the providers\r
+        final NodeList providers = config.getElementsByTagName("provider");\r
+        final int count = providers.getLength();\r
+        for (int i = 0; i < count; i++) {\r
+            final Element provider = (Element) providers.item(i);\r
+            addProvider(provider, false);\r
+        }\r
+\r
+        // Add the operation providers\r
+        final NodeList operationProviders = config.getElementsByTagName("operationProvider");\r
+        for (int i = 0; i < operationProviders.getLength(); i++) {\r
+            final Element operationProvider = (Element) operationProviders.item(i);\r
+            addOperationProvider(operationProvider);\r
+        }\r
+\r
+        // Add the default provider\r
+        final NodeList defProviders = config.getElementsByTagName("default-provider");\r
+        if (defProviders.getLength() > 0) {\r
+            final Element provider = (Element) defProviders.item(0);\r
+            addProvider(provider, true);\r
+        }\r
+\r
+        // Add the mime-type maps\r
+        final NodeList mimeTypes = config.getElementsByTagName("mime-type-map");\r
+        for (int i = 0; i < mimeTypes.getLength(); i++) {\r
+            final Element map = (Element) mimeTypes.item(i);\r
+            addMimeTypeMap(map);\r
+        }\r
+\r
+        // Add the extension maps\r
+        final NodeList extensions = config.getElementsByTagName("extension-map");\r
+        for (int i = 0; i < extensions.getLength(); i++) {\r
+            final Element map = (Element) extensions.item(i);\r
+            addExtensionMap(map);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Configures this manager from an XML configuration file.\r
+     *\r
+     * @param configUri The URI of the configuration.\r
+     * @throws FileSystemException if an error occurs.\r
+     */\r
+    private void configure(final URL configUri) throws FileSystemException {\r
+        InputStream configStream = null;\r
+        try {\r
+            // Load up the config\r
+            // TODO - validate\r
+            final DocumentBuilder builder = createDocumentBuilder();\r
+            configStream = configUri.openStream();\r
+            final Element config = builder.parse(configStream).getDocumentElement();\r
+\r
+            configure(config);\r
+        } catch (final Exception e) {\r
+            throw new FileSystemException("vfs.impl/load-config.error", configUri.toString(), e);\r
+        } finally {\r
+            if (configStream != null) {\r
+                try {\r
+                    configStream.close();\r
+                } catch (final IOException e) {\r
+                    getLogger().warn(e.getLocalizedMessage(), e);\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Scans the classpath to find any dropped plugin.\r
+     * <p>\r
+     * The plugin-description has to be in {@code /META-INF/vfs-providers.xml}.\r
+     * </p>\r
+     *\r
+     * @throws FileSystemException if an error occurs.\r
+     */\r
+    protected void configurePlugins() throws FileSystemException {\r
+        final Enumeration<URL> enumResources;\r
+        try {\r
+            enumResources = enumerateResources(PLUGIN_CONFIG_RESOURCE);\r
+        } catch (final IOException e) {\r
+            throw new FileSystemException(e);\r
+        }\r
+\r
+        while (enumResources.hasMoreElements()) {\r
+            configure(enumResources.nextElement());\r
+        }\r
+    }\r
+\r
+    protected DefaultFileReplicator createDefaultFileReplicator() {\r
+        return new DefaultFileReplicator();\r
+    }\r
+\r
+    /**\r
+     * Configure and create a DocumentBuilder\r
+     *\r
+     * @return A DocumentBuilder for the configuration.\r
+     * @throws ParserConfigurationException if an error occurs.\r
+     */\r
+    private DocumentBuilder createDocumentBuilder() throws ParserConfigurationException {\r
+        final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();\r
+        factory.setIgnoringElementContentWhitespace(true);\r
+        factory.setIgnoringComments(true);\r
+        factory.setExpandEntityReferences(true);\r
+        return factory.newDocumentBuilder();\r
+    }\r
+\r
+    /**\r
+     * Creates a provider.\r
+     */\r
+    private Object createInstance(final String className) throws FileSystemException {\r
+        try {\r
+            return loadClass(className).newInstance();\r
+        } catch (final Exception e) {\r
+            throw new FileSystemException("vfs.impl/create-provider.error", className, e);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Enumerates resources from different class loaders.\r
+     *\r
+     * @throws IOException if {@code getResource} failed.\r
+     * @see #findClassLoader()\r
+     */\r
+    private Enumeration<URL> enumerateResources(final String name) throws IOException {\r
+        Enumeration<URL> enumeration = findClassLoader().getResources(name);\r
+        if (enumeration == null || !enumeration.hasMoreElements()) {\r
+            enumeration = getValidClassLoader(getClass()).getResources(name);\r
+        }\r
+        return enumeration;\r
+    }\r
+\r
+    /**\r
+     * Tests if a class is available.\r
+     */\r
+    private boolean findClass(final String className) {\r
+        try {\r
+            loadClass(className);\r
+            return true;\r
+        } catch (final ClassNotFoundException e) {\r
+            return false;\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Returns a class loader or null since some Java implementation is null for the bootstrap class loader.\r
+     *\r
+     * @return A class loader or null since some Java implementation is null for the bootstrap class loader.\r
+     */\r
+    private ClassLoader findClassLoader() {\r
+        if (classLoader != null) {\r
+            return classLoader;\r
+        }\r
+        final ClassLoader cl = Thread.currentThread().getContextClassLoader();\r
+        if (cl != null) {\r
+            return cl;\r
+        }\r
+        return getValidClassLoader(getClass());\r
+    }\r
+\r
+    /**\r
+     * Extracts the required classes from a provider definition.\r
+     */\r
+    private String[] getRequiredClasses(final Element providerDef) {\r
+        final ArrayList<String> classes = new ArrayList<>();\r
+        final NodeList deps = providerDef.getElementsByTagName("if-available");\r
+        final int count = deps.getLength();\r
+        for (int i = 0; i < count; i++) {\r
+            final Element dep = (Element) deps.item(i);\r
+            final String className = dep.getAttribute("class-name");\r
+            if (!StringUtils.isEmpty(className)) {\r
+                classes.add(className);\r
+            }\r
+        }\r
+        return classes.toArray(ArrayUtils.EMPTY_STRING_ARRAY);\r
+    }\r
+\r
+    /**\r
+     * Extracts the required schemes from a provider definition.\r
+     */\r
+    private String[] getRequiredSchemes(final Element providerDef) {\r
+        final ArrayList<String> schemes = new ArrayList<>();\r
+        final NodeList deps = providerDef.getElementsByTagName("if-available");\r
+        final int count = deps.getLength();\r
+        for (int i = 0; i < count; i++) {\r
+            final Element dep = (Element) deps.item(i);\r
+            final String scheme = dep.getAttribute("scheme");\r
+            if (!StringUtils.isEmpty(scheme)) {\r
+                schemes.add(scheme);\r
+            }\r
+        }\r
+        return schemes.toArray(ArrayUtils.EMPTY_STRING_ARRAY);\r
+    }\r
+\r
+    /**\r
+     * Extracts the schema names from a provider definition.\r
+     */\r
+    private String[] getSchemas(final Element provider) {\r
+        final ArrayList<String> schemas = new ArrayList<>();\r
+        final NodeList schemaElements = provider.getElementsByTagName("scheme");\r
+        final int count = schemaElements.getLength();\r
+        for (int i = 0; i < count; i++) {\r
+            final Element scheme = (Element) schemaElements.item(i);\r
+            schemas.add(scheme.getAttribute("name"));\r
+        }\r
+        return schemas.toArray(ArrayUtils.EMPTY_STRING_ARRAY);\r
+    }\r
+\r
+    private ClassLoader getValidClassLoader(final Class<?> clazz) {\r
+        return validateClassLoader(clazz.getClassLoader(), clazz);\r
+    }\r
+\r
+    /**\r
+     * Initializes this manager. Adds the providers and replicator.\r
+     *\r
+     * @throws FileSystemException if an error occurs.\r
+     */\r
+    @Override\r
+    public void init() throws FileSystemException {\r
+        // Set the replicator and temporary file store (use the same component)\r
+        final DefaultFileReplicator replicator = createDefaultFileReplicator();\r
+        setReplicator(new PrivilegedFileReplicator(replicator));\r
+        setTemporaryFileStore(replicator);\r
+\r
+        if (configUri == null) {\r
+            // Use default config\r
+            final URL url = getClass().getResource(CONFIG_RESOURCE);\r
+            FileSystemException.requireNonNull(url, "vfs.impl/find-config-file.error", CONFIG_RESOURCE);\r
+            configUri = url;\r
+        }\r
+\r
+        configure(configUri);\r
+        configurePlugins();\r
+\r
+        // Initialize super-class\r
+        super.init();\r
+    }\r
+\r
+    /**\r
+     * Load a class from different class loaders.\r
+     *\r
+     * @throws ClassNotFoundException if last {@code loadClass} failed.\r
+     * @see #findClassLoader()\r
+     */\r
+    private Class<?> loadClass(final String className) throws ClassNotFoundException {\r
+        try {\r
+            return findClassLoader().loadClass(className);\r
+        } catch (final ClassNotFoundException e) {\r
+            return getValidClassLoader(getClass()).loadClass(className);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Sets the ClassLoader to use to load the providers. Default is to use the ClassLoader that loaded this class.\r
+     *\r
+     * @param classLoader The ClassLoader.\r
+     */\r
+    public void setClassLoader(final ClassLoader classLoader) {\r
+        this.classLoader = classLoader;\r
+    }\r
+\r
+    /**\r
+     * Sets the configuration file for this manager.\r
+     *\r
+     * @param configUri The URI for this manager.\r
+     */\r
+    public void setConfiguration(final String configUri) {\r
+        try {\r
+            setConfiguration(new URL(configUri));\r
+        } catch (final MalformedURLException e) {\r
+            getLogger().warn(e.getLocalizedMessage(), e);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Sets the configuration file for this manager.\r
+     *\r
+     * @param configUri The URI for this manager.\r
+     */\r
+    public void setConfiguration(final URL configUri) {\r
+        this.configUri = configUri;\r
+    }\r
+\r
+    private ClassLoader validateClassLoader(final ClassLoader clazzLoader, final Class<?> clazz) {\r
+        return Objects.requireNonNull(clazzLoader, "The class loader for " + clazz\r
+                + " is null; some Java implementations use null for the bootstrap class loader.");\r
+    }\r
+\r
+}\r
index 27df9ad355799d3a24cde8551400897a96f15473..fdb015bd56ae0e741030ba58b11c54988ba4207e 100644 (file)
@@ -26,7 +26,7 @@ import org.apache.commons.vfs2.FileType;
 import org.apache.commons.vfs2.NameScope;
 
 /**
- * This decorator synchronize all access to the FileObject.
+ * This decorator synchronizes all access to the FileObject.
  */
 public class SynchronizedFileObject extends DecoratedFileObject {
 
index c547bc278b9d8756b8f5fe93f4426a7cdd90fc6e..acde392c709d83282dc4b4c3b0981952a66bb586 100644 (file)
@@ -39,8 +39,8 @@ final class URLStreamHandlerProxy extends URLStreamHandler {
             setURL(u, url.getProtocol(), url.getHost(), url.getPort(), url.getAuthority(), url.getUserInfo(),
                     url.getFile(), url.getQuery(), url.getRef());
         } catch (final MalformedURLException mue) {
-            // We retrow this as a simple runtime exception.
-            // It is retrown in URL as a MalformedURLException anyway.
+            // We rethrow this as a simple runtime exception.
+            // It is rethrown in URL as a MalformedURLException anyway.
             throw new RuntimeException(mue.getMessage());
         }
     }
index 39faa397e29db5c0d183afb72bfb308a49dbe52b..a6c79ce7cb7499eb3e800aa3aa2dcb975bedafbd 100644 (file)
@@ -56,7 +56,7 @@ public class VFSClassLoader extends SecureClassLoader {
      * Constructors a new VFSClassLoader for the given file.
      *
      * @param file the file to load the classes and resources from.
-     * @param manager the FileManager to use when trying create a layered Jar file system.
+     * @param manager the FileManager to use when trying to create a layered Jar file system.
      * @throws FileSystemException if an error occurs.
      */
     public VFSClassLoader(final FileObject file, final FileSystemManager manager) throws FileSystemException {
@@ -67,7 +67,7 @@ public class VFSClassLoader extends SecureClassLoader {
      * Constructors a new VFSClassLoader for the given file.
      *
      * @param file the file to load the classes and resources from.
-     * @param manager the FileManager to use when trying create a layered Jar file system.
+     * @param manager the FileManager to use when trying to create a layered Jar file system.
      * @param parent the parent class loader for delegation.
      * @throws FileSystemException if an error occurs.
      */
@@ -80,7 +80,7 @@ public class VFSClassLoader extends SecureClassLoader {
      * Constructors a new VFSClassLoader for the given files. The files will be searched in the order specified.
      *
      * @param files the files to load the classes and resources from.
-     * @param manager the FileManager to use when trying create a layered Jar file system.
+     * @param manager the FileManager to use when trying to create a layered Jar file system.
      * @throws FileSystemException if an error occurs.
      */
     public VFSClassLoader(final FileObject[] files, final FileSystemManager manager) throws FileSystemException {
@@ -92,7 +92,7 @@ public class VFSClassLoader extends SecureClassLoader {
      * specified.
      *
      * @param files the FileObjects to load the classes and resources from.
-     * @param manager the FileManager to use when trying create a layered Jar file system.
+     * @param manager the FileManager to use when trying to create a layered Jar file system.
      * @param parent the parent class loader for delegation.
      * @throws FileSystemException if an error occurs.
      */
@@ -134,8 +134,7 @@ public class VFSClassLoader extends SecureClassLoader {
      */
     protected void copyPermissions(final PermissionCollection src, final PermissionCollection dest) {
         for (final Enumeration<Permission> elem = src.elements(); elem.hasMoreElements();) {
-            final Permission permission = elem.nextElement();
-            dest.add(permission);
+            dest.add(elem.nextElement());
         }
     }
 
@@ -297,7 +296,7 @@ public class VFSClassLoader extends SecureClassLoader {
     }
 
     /**
-     * Returns true if the we should seal the package where res resides.
+     * Returns true if we should seal the package where res resides.
      */
     private boolean isSealed(final Resource res) throws FileSystemException {
         final String sealed = res.getPackageAttribute(Attributes.Name.SEALED);
index 59e2afe842214dfb85781a943bcca49f2fe41683..28b3f69f2cca72b5d9250540b58f8667c3d7b587 100644 (file)
@@ -159,16 +159,8 @@ public class VirtualFileSystem extends AbstractFileSystem {
             // The name points to the junction point directly
             return name;
         }
-
         // Find matching junction
-        for (final FileName junctionPoint : junctions.keySet()) {
-            if (junctionPoint.isDescendent(name)) {
-                return junctionPoint;
-            }
-        }
-
-        // None
-        return null;
+        return junctions.keySet().stream().filter(fileName -> fileName.isDescendent(name)).findFirst().orElse(null);
     }
 
     /**
index b7b93e68592ed967552ba5b2fc761fcae67463db..1b6649d9ea3a7504aa3cfe6e61932ba16e067f3b 100644 (file)
@@ -25,7 +25,7 @@ import org.apache.commons.vfs2.FileObject;
 public abstract class AbstractFileOperation implements FileOperation {
 
     /**
-     * FileObject which the FileOperation is operate on.
+     * FileObject which the FileOperation is operated on.
      */
     private final FileObject fileObject;
 
@@ -37,7 +37,7 @@ public abstract class AbstractFileOperation implements FileOperation {
     }
 
     /**
-     * @return an instance of FileObject which this FileOperation is operate on.
+     * @return an instance of FileObject which this FileOperation is operated on.
      */
     protected FileObject getFileObject() {
         return fileObject;
index c88b5106958696f8194e0843d2bf64a07a1cdddf..312359b6b856f90db5f3e7237bf5cc42d0e7346e 100644 (file)
@@ -78,7 +78,7 @@ public abstract class AbstractFileOperationProvider implements FileOperationProv
         Collection<Class<? extends FileOperation>> resultList, FileObject file) throws FileSystemException;
 
     /**
-     * @param file the FileObject for which we need a operation.
+     * @param file the FileObject for which we need an operation.
      * @param operationClass the Class which instance we are needed.
      * @return the required operation instance.
      * @throws FileSystemException if operation cannot be retrieved.
@@ -93,7 +93,7 @@ public abstract class AbstractFileOperationProvider implements FileOperationProv
      * Get operation instance for specified FileOperation subclass.
      *
      * @param file the file this operation should act on.
-     * @param operationClass the class of an file operation interface to instantiate.
+     * @param operationClass the class of a file operation interface to instantiate.
      * @return a new file operation
      * @throws FileSystemException if operation cannot be instantiated.
      */
index 9c30dd785ca2d01c7b49434274b13a450b20776f..19afbf6e5f94c6bea600dbfbea0e150e4c72f2a4 100644 (file)
@@ -49,7 +49,7 @@ public interface FileOperationProvider {
     /**
      * Get implementation for a given FileObject and FileOperation interface.
      *
-     * @param file the FileObject for which we need a operation.
+     * @param file the FileObject for which we need an operation.
      * @param operationClass the Class which instance we are needed.
      * @return the required operation instance.
      *
index ede79482e499b4f121b5bb9b7b4ea67cb933863b..6e8c989d3222ada640d5e203293cd045175da768 100644 (file)
@@ -21,15 +21,15 @@ import org.apache.commons.vfs2.FileSystemException;
 /**
  * FileOperations interface provides API to work with operations.
  *
- * @see FileOperation on what a operation in the context of VFS is.
+ * @see FileOperation on what an operation in the context of VFS is.
  *
  * @since 0.1
  */
 public interface FileOperations {
     /**
      * @param operationClass the operation Class.
-     * @return a operation implementing the given {@code operationClass}
-     * @throws FileSystemException if an error occus.
+     * @return an operation implementing the given {@code operationClass}
+     * @throws FileSystemException if an error occurs.
      */
     FileOperation getOperation(Class<? extends FileOperation> operationClass) throws FileSystemException;
 
@@ -41,8 +41,8 @@ public interface FileOperations {
 
     /**
      * @param operationClass the operation Class.
-     * @return if a operation {@code operationClass} is available
-     * @throws FileSystemException if an error ocurs.
+     * @return if an operation {@code operationClass} is available
+     * @throws FileSystemException if an error occurs.
      */
     boolean hasOperation(Class<? extends FileOperation> operationClass) throws FileSystemException;
 }
index e14cc12caff72e9495b87f230959933e10456b9e..bd69e315990834fe29eaad65f05bdee3f5315ca1 100644 (file)
@@ -26,7 +26,7 @@ import org.apache.commons.vfs2.operations.FileOperation;
 public interface VcsCheckout extends FileOperation {
 
     /**
-     * @param export if true, administrative .svn directoies will not be created on the retrieved tree. The checkout
+     * @param export if true, administrative .svn directories will not be created on the retrieved tree. The checkout
      *        operation in this case is equivalent to export function.
      */
     void setExport(boolean export);
index ccff027489268ab145f7148b1eb4276a7472dfae..a4a9222dba3a4858d2755205743855c8bde7e3c4 100644 (file)
-/*
- * 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;
-
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.vfs2.FileName;
-import org.apache.commons.vfs2.FileSystemException;
-import org.apache.commons.vfs2.FileType;
-import org.apache.commons.vfs2.NameScope;
-import org.apache.commons.vfs2.VFS;
-
-/**
- * A default file name implementation.
- */
-public abstract class AbstractFileName implements FileName {
-
-    // URI Characters that are possible in local file names, but must be escaped
-    // for proper URI handling.
-    //
-    // How reserved URI chars were selected:
-    //
-    // URIs can contain :, /, ?, #, @
-    // See https://docs.oracle.com/javase/8/docs/api/java/net/URI.html
-    // http://tools.ietf.org/html/rfc3986#section-2.2
-    //
-    // Since : and / occur before the path, only chars after path are escaped (i.e., # and ?)
-    // ? is a reserved filesystem character for Windows and Unix, so can't be part of a file name.
-    // Therefore only # is a reserved char in a URI as part of the path that can be in the file name.
-    private static final char[] RESERVED_URI_CHARS = {'#', ' '};
-
-    private final String scheme;
-    private final String absPath;
-    private FileType type;
-
-    // Cached attributes
-    private String uriString;
-    private String baseName;
-    private String rootUri;
-    private String extension;
-    private String decodedAbsPath;
-
-    private String key;
-
-    /**
-     * Constructs a new instance.
-     *
-     * @param scheme The scheme.
-     * @param absolutePath the absolute path, maybe empty or null.
-     * @param type the file type.
-     */
-    public AbstractFileName(final String scheme, final String absolutePath, final FileType type) {
-        this.rootUri = null;
-        this.scheme = scheme;
-        this.type = type;
-        if (StringUtils.isEmpty(absolutePath)) {
-            this.absPath = ROOT_PATH;
-        } else if (absolutePath.length() > 1 && absolutePath.endsWith("/")) {
-            this.absPath = absolutePath.substring(0, absolutePath.length() - 1);
-        } else {
-            this.absPath = absolutePath;
-        }
-    }
-
-    /**
-     * Checks whether a path fits in a particular scope of another path.
-     *
-     * @param basePath An absolute, normalised path.
-     * @param path An absolute, normalised path.
-     * @param scope The NameScope.
-     * @return true if the path fits in the scope, false otherwise.
-     */
-    public static boolean checkName(final String basePath, final String path, final NameScope scope) {
-        if (scope == NameScope.FILE_SYSTEM) {
-            // All good
-            return true;
-        }
-
-        if (!path.startsWith(basePath)) {
-            return false;
-        }
-
-        int baseLen = basePath.length();
-        if (VFS.isUriStyle()) {
-            // strip the trailing "/"
-            baseLen--;
-        }
-
-        if (scope == NameScope.CHILD) {
-            return path.length() != baseLen && (baseLen <= 1 || path.charAt(baseLen) == SEPARATOR_CHAR)
-                    && path.indexOf(SEPARATOR_CHAR, baseLen + 1) == -1;
-        }
-        if (scope == NameScope.DESCENDENT) {
-            return path.length() != baseLen && (baseLen <= 1 || path.charAt(baseLen) == SEPARATOR_CHAR);
-        }
-        if (scope == NameScope.DESCENDENT_OR_SELF) {
-            return baseLen <= 1 || path.length() <= baseLen || path.charAt(baseLen) == SEPARATOR_CHAR;
-        }
-        throw new IllegalArgumentException();
-    }
-
-    /**
-     * Builds the root URI for this file name. Note that the root URI must not end with a separator character.
-     *
-     * @param buffer A StringBuilder to use to construct the URI.
-     * @param addPassword true if the password should be added, false otherwise.
-     */
-    protected abstract void appendRootUri(StringBuilder buffer, boolean addPassword);
-
-    /**
-     * Implement Comparable.
-     *
-     * @param obj another abstract file name
-     * @return negative number if less than, 0 if equal, positive if greater than.
-     */
-    @Override
-    public int compareTo(final FileName obj) {
-        final AbstractFileName name = (AbstractFileName) obj;
-        return getKey().compareTo(name.getKey());
-    }
-
-    /**
-     * Factory method for creating name instances.
-     *
-     * @param absolutePath The absolute path.
-     * @param fileType The FileType.
-     * @return The FileName.
-     */
-    public abstract FileName createName(String absolutePath, FileType fileType);
-
-    protected String createURI() {
-        return createURI(false, true);
-    }
-
-    private String createURI(final boolean useAbsolutePath, final boolean usePassword) {
-        final StringBuilder buffer = new StringBuilder();
-        appendRootUri(buffer, usePassword);
-        buffer.append(handleURISpecialCharacters(useAbsolutePath ? absPath : getPath()));
-        return buffer.toString();
-    }
-
-    @Override
-    public boolean equals(final Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (o == null || getClass() != o.getClass()) {
-            return false;
-        }
-
-        final AbstractFileName that = (AbstractFileName) o;
-
-        return getKey().equals(that.getKey());
-    }
-
-    /**
-     * Returns the base name of the file.
-     *
-     * @return The base name of the file.
-     */
-    @Override
-    public String getBaseName() {
-        if (baseName == null) {
-            final int idx = getPath().lastIndexOf(SEPARATOR_CHAR);
-            if (idx == -1) {
-                baseName = getPath();
-            } else {
-                baseName = getPath().substring(idx + 1);
-            }
-        }
-
-        return baseName;
-    }
-
-    /**
-     * Returns the depth of this file name, within its file system.
-     *
-     * @return The depth of the file name.
-     */
-    @Override
-    public int getDepth() {
-        final int len = getPath().length();
-        if (len == 0 || len == 1 && getPath().charAt(0) == SEPARATOR_CHAR) {
-            return 0;
-        }
-        int depth = 1;
-        for (int pos = 0; pos > -1 && pos < len; depth++) {
-            pos = getPath().indexOf(SEPARATOR_CHAR, pos + 1);
-        }
-        return depth;
-    }
-
-    /**
-     * Returns the extension of this file name.
-     *
-     * @return The file extension.
-     */
-    @Override
-    public String getExtension() {
-        if (extension == null) {
-            getBaseName();
-            final int pos = baseName.lastIndexOf('.');
-            // if ((pos == -1) || (pos == baseName.length() - 1))
-            // imario@ops.co.at: Review of patch from adagoubard@chello.nl
-            // do not treat file names like
-            // .bashrc c:\windows\.java c:\windows\.javaws c:\windows\.jedit c:\windows\.appletviewer
-            // as extension
-            if (pos < 1 || pos == baseName.length() - 1) {
-                // No extension
-                extension = "";
-            } else {
-                extension = baseName.substring(pos + 1).intern();
-            }
-        }
-        return extension;
-    }
-
-    /**
-     * Returns the URI without a password.
-     *
-     * @return Returns the URI without a password.
-     */
-    @Override
-    public String getFriendlyURI() {
-        return createURI(false, false);
-    }
-
-    /**
-     * Create a path that does not use the FileType since that field is not immutable.
-     *
-     * @return The key.
-     */
-    private String getKey() {
-        if (key == null) {
-            key = getURI();
-        }
-        return key;
-    }
-
-    /**
-     * Returns the name of the parent of the file.
-     *
-     * @return the FileName of the parent.
-     */
-    @Override
-    public FileName getParent() {
-        final String parentPath;
-        final int idx = getPath().lastIndexOf(SEPARATOR_CHAR);
-        if (idx == -1 || idx == getPath().length() - 1) {
-            // No parent
-            return null;
-        }
-        if (idx == 0) {
-            // Root is the parent
-            parentPath = SEPARATOR;
-        } else {
-            parentPath = getPath().substring(0, idx);
-        }
-        return createName(parentPath, FileType.FOLDER);
-    }
-
-    /**
-     * Returns the absolute path of the file, relative to the root of the file system that the file belongs to.
-     *
-     * @return The path String.
-     */
-    @Override
-    public String getPath() {
-        if (VFS.isUriStyle()) {
-            return absPath + getUriTrailer();
-        }
-        return absPath;
-    }
-
-    /**
-     * Returns the decoded path.
-     *
-     * @return The decoded path String.
-     * @throws FileSystemException If an error occurs.
-     */
-    @Override
-    public String getPathDecoded() throws FileSystemException {
-        if (decodedAbsPath == null) {
-            decodedAbsPath = UriParser.decode(getPath());
-        }
-
-        return decodedAbsPath;
-    }
-
-    /**
-     * Converts a file name to a relative name, relative to this file name.
-     *
-     * @param name The FileName.
-     * @return The relative path to the file.
-     * @throws FileSystemException if an error occurs.
-     */
-    @Override
-    public String getRelativeName(final FileName name) throws FileSystemException {
-        final String path = name.getPath();
-
-        // Calculate the common prefix
-        final int basePathLen = getPath().length();
-        final int pathLen = path.length();
-
-        // Deal with root
-        if (basePathLen == 1 && pathLen == 1) {
-            return ".";
-        }
-        if (basePathLen == 1) {
-            return path.substring(1);
-        }
-
-        final int maxlen = Math.min(basePathLen, pathLen);
-        int pos = 0;
-        for (; pos < maxlen && getPath().charAt(pos) == path.charAt(pos); pos++) {
-            // empty
-        }
-
-        if (pos == basePathLen && pos == pathLen) {
-            // Same names
-            return ".";
-        }
-        if (pos == basePathLen && pos < pathLen && path.charAt(pos) == SEPARATOR_CHAR) {
-            // A descendent of the base path
-            return path.substring(pos + 1);
-        }
-
-        // Strip the common prefix off the path
-        final StringBuilder buffer = new StringBuilder();
-        if (pathLen > 1 && (pos < pathLen || getPath().charAt(pos) != SEPARATOR_CHAR)) {
-            // Not a direct ancestor, need to back up
-            pos = getPath().lastIndexOf(SEPARATOR_CHAR, pos);
-            buffer.append(path.substring(pos));
-        }
-
-        // Prepend a '../' for each element in the base path past the common
-        // prefix
-        buffer.insert(0, "..");
-        pos = getPath().indexOf(SEPARATOR_CHAR, pos + 1);
-        while (pos != -1) {
-            buffer.insert(0, "../");
-            pos = getPath().indexOf(SEPARATOR_CHAR, pos + 1);
-        }
-
-        return buffer.toString();
-    }
-
-    /**
-     * find the root of the file system.
-     *
-     * @return The root FileName.
-     */
-    @Override
-    public FileName getRoot() {
-        FileName root = this;
-        while (root.getParent() != null) {
-            root = root.getParent();
-        }
-
-        return root;
-    }
-
-    /**
-     * Returns the root URI of the file system this file belongs to.
-     *
-     * @return The URI of the root.
-     */
-    @Override
-    public String getRootURI() {
-        if (rootUri == null) {
-            final StringBuilder buffer = new StringBuilder();
-            appendRootUri(buffer, true);
-            buffer.append(SEPARATOR_CHAR);
-            rootUri = buffer.toString().intern();
-        }
-        return rootUri;
-    }
-
-    /**
-     * Returns the URI scheme of this file.
-     *
-     * @return The protocol used to access the file.
-     */
-    @Override
-    public String getScheme() {
-        return scheme;
-    }
-
-    /**
-     * Returns the requested or current type of this name.
-     * <p>
-     * The "requested" type is the one determined during resolving the name. n this case the name is a
-     * {@link FileType#FOLDER} if it ends with an "/" else it will be a {@link FileType#FILE}.
-     * </p>
-     * <p>
-     * Once attached it will be changed to reflect the real type of this resource.
-     * </p>
-     *
-     * @return {@link FileType#FOLDER} or {@link FileType#FILE}
-     */
-    @Override
-    public FileType getType() {
-        return type;
-    }
-
-    /**
-     * Returns the absolute URI of the file.
-     *
-     * @return The absolute URI of the file.
-     */
-    @Override
-    public String getURI() {
-        if (uriString == null) {
-            uriString = createURI();
-        }
-        return uriString;
-    }
-
-    protected String getUriTrailer() {
-        return getType().hasChildren() ? "/" : "";
-    }
-
-    private String handleURISpecialCharacters(String uri) {
-        if (!StringUtils.isEmpty(uri)) {
-            try {
-                // VFS-325: Handle URI special characters in file name
-                // Decode the base URI and re-encode with URI special characters
-                uri = UriParser.decode(uri);
-
-                return UriParser.encode(uri, RESERVED_URI_CHARS);
-            } catch (final FileSystemException e) {
-                // Default to base URI value?
-                return uri;
-            }
-        }
-
-        return uri;
-    }
-
-    @Override
-    public int hashCode() {
-        return getKey().hashCode();
-    }
-
-    /**
-     * Determines if another file name is an ancestor of this file name.
-     *
-     * @param ancestor The FileName to check.
-     * @return true if the FileName is an ancestor, false otherwise.
-     */
-    @Override
-    public boolean isAncestor(final FileName ancestor) {
-        if (!ancestor.getRootURI().equals(getRootURI())) {
-            return false;
-        }
-        return checkName(ancestor.getPath(), getPath(), NameScope.DESCENDENT);
-    }
-
-    /**
-     * Determines if another file name is a descendent of this file name.
-     *
-     * @param descendent The FileName to check.
-     * @return true if the FileName is a descendent, false otherwise.
-     */
-    @Override
-    public boolean isDescendent(final FileName descendent) {
-        return isDescendent(descendent, NameScope.DESCENDENT);
-    }
-
-    /**
-     * Determines if another file name is a descendent of this file name.
-     *
-     * @param descendent The FileName to check.
-     * @param scope The NameScope.
-     * @return true if the FileName is a descendent, false otherwise.
-     */
-    @Override
-    public boolean isDescendent(final FileName descendent, final NameScope scope) {
-        if (!descendent.getRootURI().equals(getRootURI())) {
-            return false;
-        }
-        return checkName(getPath(), descendent.getPath(), scope);
-    }
-
-    /**
-     * Checks if this file name is a name for a regular file by using its type.
-     *
-     * @return true if this file is a regular file.
-     * @throws FileSystemException may be thrown by subclasses.
-     * @see #getType()
-     * @see FileType#FILE
-     */
-    @Override
-    public boolean isFile() throws FileSystemException {
-        // Use equals instead of == to avoid any class loader worries.
-        return FileType.FILE.equals(this.getType());
-    }
-
-    /**
-     * Sets the type of this file e.g. when it will be attached.
-     *
-     * @param type {@link FileType#FOLDER} or {@link FileType#FILE}
-     * @throws FileSystemException if an error occurs.
-     */
-    void setType(final FileType type) throws FileSystemException {
-        if (type != FileType.FOLDER && type != FileType.FILE && type != FileType.FILE_OR_FOLDER) {
-            throw new FileSystemException("vfs.provider/filename-type.error");
-        }
-
-        this.type = type;
-    }
-
-    /**
-     * Returns the URI of the file.
-     *
-     * @return the FileName as a URI.
-     */
-    @Override
-    public String toString() {
-        return getURI();
-    }
-}
+/*\r
+ * Licensed to the Apache Software Foundation (ASF) under one or more\r
+ * contributor license agreements.  See the NOTICE file distributed with\r
+ * this work for additional information regarding copyright ownership.\r
+ * The ASF licenses this file to You under the Apache License, Version 2.0\r
+ * (the "License"); you may not use this file except in compliance with\r
+ * the License.  You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.apache.commons.vfs2.provider;\r
+\r
+import org.apache.commons.lang3.StringUtils;\r
+import org.apache.commons.vfs2.FileName;\r
+import org.apache.commons.vfs2.FileSystemException;\r
+import org.apache.commons.vfs2.FileType;\r
+import org.apache.commons.vfs2.NameScope;\r
+import org.apache.commons.vfs2.VFS;\r
+\r
+/**\r
+ * A default file name implementation.\r
+ */\r
+public abstract class AbstractFileName implements FileName {\r
+\r
+    // URI Characters that are possible in local file names, but must be escaped\r
+    // for proper URI handling.\r
+    //\r
+    // How reserved URI chars were selected:\r
+    //\r
+    // URIs can contain :, /, ?, #, @\r
+    // See https://docs.oracle.com/javase/8/docs/api/java/net/URI.html\r
+    // https://datatracker.ietf.org/doc/html/rfc3986#section-2.2\r
+    //\r
+    // Since : and / occur before the path, only chars after path are escaped (i.e., # and ?)\r
+    // ? is a reserved filesystem character for Windows and Unix, so can't be part of a file name.\r
+    // Therefore only # is a reserved char in a URI as part of the path that can be in the file name.\r
+    private static final char[] RESERVED_URI_CHARS = {'#', ' '};\r
+\r
+    private final String scheme;\r
+    private final String absPath;\r
+    private FileType type;\r
+\r
+    // Cached attributes\r
+    private String uriString;\r
+    private String baseName;\r
+    private String rootUri;\r
+    private String extension;\r
+    private String decodedAbsPath;\r
+\r
+    private String key;\r
+\r
+    /**\r
+     * Constructs a new instance.\r
+     *\r
+     * @param scheme The scheme.\r
+     * @param absolutePath the absolute path, maybe empty or null.\r
+     * @param type the file type.\r
+     */\r
+    public AbstractFileName(final String scheme, final String absolutePath, final FileType type) {\r
+        this.rootUri = null;\r
+        this.scheme = scheme;\r
+        this.type = type;\r
+        if (StringUtils.isEmpty(absolutePath)) {\r
+            this.absPath = ROOT_PATH;\r
+        } else if (absolutePath.length() > 1 && absolutePath.endsWith("/")) {\r
+            this.absPath = absolutePath.substring(0, absolutePath.length() - 1);\r
+        } else {\r
+            this.absPath = absolutePath;\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Checks whether a path fits in a particular scope of another path.\r
+     *\r
+     * @param basePath An absolute, normalised path.\r
+     * @param path An absolute, normalised path.\r
+     * @param scope The NameScope.\r
+     * @return true if the path fits in the scope, false otherwise.\r
+     */\r
+    public static boolean checkName(final String basePath, final String path, final NameScope scope) {\r
+        if (scope == NameScope.FILE_SYSTEM) {\r
+            // All good\r
+            return true;\r
+        }\r
+\r
+        if (!path.startsWith(basePath)) {\r
+            return false;\r
+        }\r
+\r
+        int baseLen = basePath.length();\r
+        if (VFS.isUriStyle()) {\r
+            // strip the trailing "/"\r
+            baseLen--;\r
+        }\r
+\r
+        if (scope == NameScope.CHILD) {\r
+            return path.length() != baseLen && (baseLen <= 1 || path.charAt(baseLen) == SEPARATOR_CHAR)\r
+                    && path.indexOf(SEPARATOR_CHAR, baseLen + 1) == -1;\r
+        }\r
+        if (scope == NameScope.DESCENDENT) {\r
+            return path.length() != baseLen && (baseLen <= 1 || path.charAt(baseLen) == SEPARATOR_CHAR);\r
+        }\r
+        if (scope == NameScope.DESCENDENT_OR_SELF) {\r
+            return baseLen <= 1 || path.length() <= baseLen || path.charAt(baseLen) == SEPARATOR_CHAR;\r
+        }\r
+        throw new IllegalArgumentException();\r
+    }\r
+\r
+    /**\r
+     * Builds the root URI for this file name. Note that the root URI must not end with a separator character.\r
+     *\r
+     * @param buffer A StringBuilder to use to construct the URI.\r
+     * @param addPassword true if the password should be added, false otherwise.\r
+     */\r
+    protected abstract void appendRootUri(StringBuilder buffer, boolean addPassword);\r
+\r
+    /**\r
+     * Implement Comparable.\r
+     *\r
+     * @param obj another abstract file name\r
+     * @return negative number if less than, 0 if equal, positive if greater than.\r
+     */\r
+    @Override\r
+    public int compareTo(final FileName obj) {\r
+        final AbstractFileName name = (AbstractFileName) obj;\r
+        return getKey().compareTo(name.getKey());\r
+    }\r
+\r
+    /**\r
+     * Factory method for creating name instances.\r
+     *\r
+     * @param absolutePath The absolute path.\r
+     * @param fileType The FileType.\r
+     * @return The FileName.\r
+     */\r
+    public abstract FileName createName(String absolutePath, FileType fileType);\r
+\r
+    protected String createURI() {\r
+        return createURI(false, true);\r
+    }\r
+\r
+    private String createURI(final boolean useAbsolutePath, final boolean usePassword) {\r
+        final StringBuilder buffer = new StringBuilder();\r
+        appendRootUri(buffer, usePassword);\r
+        buffer.append(handleURISpecialCharacters(useAbsolutePath ? absPath : getPath()));\r
+        return buffer.toString();\r
+    }\r
+\r
+    @Override\r
+    public boolean equals(final Object o) {\r
+        if (this == o) {\r
+            return true;\r
+        }\r
+        if (o == null || getClass() != o.getClass()) {\r
+            return false;\r
+        }\r
+\r
+        final AbstractFileName that = (AbstractFileName) o;\r
+\r
+        return getKey().equals(that.getKey());\r
+    }\r
+\r
+    /**\r
+     * Returns the base name of the file.\r
+     *\r
+     * @return The base name of the file.\r
+     */\r
+    @Override\r
+    public String getBaseName() {\r
+        if (baseName == null) {\r
+            final int idx = getPath().lastIndexOf(SEPARATOR_CHAR);\r
+            if (idx == -1) {\r
+                baseName = getPath();\r
+            } else {\r
+                baseName = getPath().substring(idx + 1);\r
+            }\r
+        }\r
+\r
+        return baseName;\r
+    }\r
+\r
+    /**\r
+     * Returns the depth of this file name, within its file system.\r
+     *\r
+     * @return The depth of the file name.\r
+     */\r
+    @Override\r
+    public int getDepth() {\r
+        final int len = getPath().length();\r
+        if (len == 0 || len == 1 && getPath().charAt(0) == SEPARATOR_CHAR) {\r
+            return 0;\r
+        }\r
+        int depth = 1;\r
+        for (int pos = 0; pos > -1 && pos < len; depth++) {\r
+            pos = getPath().indexOf(SEPARATOR_CHAR, pos + 1);\r
+        }\r
+        return depth;\r
+    }\r
+\r
+    /**\r
+     * Returns the extension of this file name.\r
+     *\r
+     * @return The file extension.\r
+     */\r
+    @Override\r
+    public String getExtension() {\r
+        if (extension == null) {\r
+            getBaseName();\r
+            final int pos = baseName.lastIndexOf('.');\r
+            // if ((pos == -1) || (pos == baseName.length() - 1))\r
+            // imario@ops.co.at: Review of patch from adagoubard@chello.nl\r
+            // do not treat file names like\r
+            // .bashrc c:\windows\.java c:\windows\.javaws c:\windows\.jedit c:\windows\.appletviewer\r
+            // as extension\r
+            if (pos < 1 || pos == baseName.length() - 1) {\r
+                // No extension\r
+                extension = "";\r
+            } else {\r
+                extension = baseName.substring(pos + 1).intern();\r
+            }\r
+        }\r
+        return extension;\r
+    }\r
+\r
+    /**\r
+     * Returns the URI without a password.\r
+     *\r
+     * @return Returns the URI without a password.\r
+     */\r
+    @Override\r
+    public String getFriendlyURI() {\r
+        return createURI(false, false);\r
+    }\r
+\r
+    /**\r
+     * Create a path that does not use the FileType since that field is not immutable.\r
+     *\r
+     * @return The key.\r
+     */\r
+    private String getKey() {\r
+        if (key == null) {\r
+            key = getURI();\r
+        }\r
+        return key;\r
+    }\r
+\r
+    /**\r
+     * Returns the name of the parent of the file.\r
+     *\r
+     * @return the FileName of the parent.\r
+     */\r
+    @Override\r
+    public FileName getParent() {\r
+        final String parentPath;\r
+        final int idx = getPath().lastIndexOf(SEPARATOR_CHAR);\r
+        if (idx == -1 || idx == getPath().length() - 1) {\r
+            // No parent\r
+            return null;\r
+        }\r
+        if (idx == 0) {\r
+            // Root is the parent\r
+            parentPath = SEPARATOR;\r
+        } else {\r
+            parentPath = getPath().substring(0, idx);\r
+        }\r
+        return createName(parentPath, FileType.FOLDER);\r
+    }\r
+\r
+    /**\r
+     * Returns the absolute path of the file, relative to the root of the file system that the file belongs to.\r
+     *\r
+     * @return The path String.\r
+     */\r
+    @Override\r
+    public String getPath() {\r
+        if (VFS.isUriStyle()) {\r
+            return absPath + getUriTrailer();\r
+        }\r
+        return absPath;\r
+    }\r
+\r
+    /**\r
+     * Returns the decoded path.\r
+     *\r
+     * @return The decoded path String.\r
+     * @throws FileSystemException If an error occurs.\r
+     */\r
+    @Override\r
+    public String getPathDecoded() throws FileSystemException {\r
+        if (decodedAbsPath == null) {\r
+            decodedAbsPath = UriParser.decode(getPath());\r
+        }\r
+\r
+        return decodedAbsPath;\r
+    }\r
+\r
+    /**\r
+     * Converts a file name to a relative name, relative to this file name.\r
+     *\r
+     * @param name The FileName.\r
+     * @return The relative path to the file.\r
+     * @throws FileSystemException if an error occurs.\r
+     */\r
+    @Override\r
+    public String getRelativeName(final FileName name) throws FileSystemException {\r
+        final String path = name.getPath();\r
+\r
+        // Calculate the common prefix\r
+        final int basePathLen = getPath().length();\r
+        final int pathLen = path.length();\r
+\r
+        // Deal with root\r
+        if (basePathLen == 1 && pathLen == 1) {\r
+            return ".";\r
+        }\r
+        if (basePathLen == 1) {\r
+            return path.substring(1);\r
+        }\r
+\r
+        final int maxlen = Math.min(basePathLen, pathLen);\r
+        int pos = 0;\r
+        while (pos < maxlen && getPath().charAt(pos) == path.charAt(pos)) {\r
+            pos++;\r
+        }\r
+\r
+        if (pos == basePathLen && pos == pathLen) {\r
+            // Same names\r
+            return ".";\r
+        }\r
+        if (pos == basePathLen && pos < pathLen && path.charAt(pos) == SEPARATOR_CHAR) {\r
+            // A descendent of the base path\r
+            return path.substring(pos + 1);\r
+        }\r
+\r
+        // Strip the common prefix off the path\r
+        final StringBuilder buffer = new StringBuilder();\r
+        if (pathLen > 1 && (pos < pathLen || getPath().charAt(pos) != SEPARATOR_CHAR)) {\r
+            // Not a direct ancestor, need to back up\r
+            pos = getPath().lastIndexOf(SEPARATOR_CHAR, pos);\r
+            buffer.append(path.substring(pos));\r
+        }\r
+\r
+        // Prepend a '../' for each element in the base path past the common\r
+        // prefix\r
+        buffer.insert(0, "..");\r
+        pos = getPath().indexOf(SEPARATOR_CHAR, pos + 1);\r
+        while (pos != -1) {\r
+            buffer.insert(0, "../");\r
+            pos = getPath().indexOf(SEPARATOR_CHAR, pos + 1);\r
+        }\r
+\r
+        return buffer.toString();\r
+    }\r
+\r
+    /**\r
+     * find the root of the file system.\r
+     *\r
+     * @return The root FileName.\r
+     */\r
+    @Override\r
+    public FileName getRoot() {\r
+        FileName root = this;\r
+        while (root.getParent() != null) {\r
+            root = root.getParent();\r
+        }\r
+\r
+        return root;\r
+    }\r
+\r
+    /**\r
+     * Returns the root URI of the file system this file belongs to.\r
+     *\r
+     * @return The URI of the root.\r
+     */\r
+    @Override\r
+    public String getRootURI() {\r
+        if (rootUri == null) {\r
+            final StringBuilder buffer = new StringBuilder();\r
+            appendRootUri(buffer, true);\r
+            buffer.append(SEPARATOR_CHAR);\r
+            rootUri = buffer.toString().intern();\r
+        }\r
+        return rootUri;\r
+    }\r
+\r
+    /**\r
+     * Returns the URI scheme of this file.\r
+     *\r
+     * @return The protocol used to access the file.\r
+     */\r
+    @Override\r
+    public String getScheme() {\r
+        return scheme;\r
+    }\r
+\r
+    /**\r
+     * Returns the requested or current type of this name.\r
+     * <p>\r
+     * The "requested" type is the one determined during resolving the name. n this case the name is a\r
+     * {@link FileType#FOLDER} if it ends with an "/" else it will be a {@link FileType#FILE}.\r
+     * </p>\r
+     * <p>\r
+     * Once attached it will be changed to reflect the real type of this resource.\r
+     * </p>\r
+     *\r
+     * @return {@link FileType#FOLDER} or {@link FileType#FILE}\r
+     */\r
+    @Override\r
+    public FileType getType() {\r
+        return type;\r
+    }\r
+\r
+    /**\r
+     * Returns the absolute URI of the file.\r
+     *\r
+     * @return The absolute URI of the file.\r
+     */\r
+    @Override\r
+    public String getURI() {\r
+        if (uriString == null) {\r
+            uriString = createURI();\r
+        }\r
+        return uriString;\r
+    }\r
+\r
+    protected String getUriTrailer() {\r
+        return getType().hasChildren() ? "/" : "";\r
+    }\r
+\r
+    private String handleURISpecialCharacters(String uri) {\r
+        if (!StringUtils.isEmpty(uri)) {\r
+            try {\r
+                // VFS-325: Handle URI special characters in file name\r
+                // Decode the base URI and re-encode with URI special characters\r
+                uri = UriParser.decode(uri);\r
+\r
+                return UriParser.encode(uri, RESERVED_URI_CHARS);\r
+            } catch (final FileSystemException e) {\r
+                // Default to base URI value?\r
+                return uri;\r
+            }\r
+        }\r
+\r
+        return uri;\r
+    }\r
+\r
+    @Override\r
+    public int hashCode() {\r
+        return getKey().hashCode();\r
+    }\r
+\r
+    /**\r
+     * Determines if another file name is an ancestor of this file name.\r
+     *\r
+     * @param ancestor The FileName to check.\r
+     * @return true if the FileName is an ancestor, false otherwise.\r
+     */\r
+    @Override\r
+    public boolean isAncestor(final FileName ancestor) {\r
+        if (!ancestor.getRootURI().equals(getRootURI())) {\r
+            return false;\r
+        }\r
+        return checkName(ancestor.getPath(), getPath(), NameScope.DESCENDENT);\r
+    }\r
+\r
+    /**\r
+     * Determines if another file name is a descendent of this file name.\r
+     *\r
+     * @param descendent The FileName to check.\r
+     * @return true if the FileName is a descendent, false otherwise.\r
+     */\r
+    @Override\r
+    public boolean isDescendent(final FileName descendent) {\r
+        return isDescendent(descendent, NameScope.DESCENDENT);\r
+    }\r
+\r
+    /**\r
+     * Determines if another file name is a descendent of this file name.\r
+     *\r
+     * @param descendent The FileName to check.\r
+     * @param scope The NameScope.\r
+     * @return true if the FileName is a descendent, false otherwise.\r
+     */\r
+    @Override\r
+    public boolean isDescendent(final FileName descendent, final NameScope scope) {\r
+        if (!descendent.getRootURI().equals(getRootURI())) {\r
+            return false;\r
+        }\r
+        return checkName(getPath(), descendent.getPath(), scope);\r
+    }\r
+\r
+    /**\r
+     * Checks if this file name is a name for a regular file by using its type.\r
+     *\r
+     * @return true if this file is a regular file.\r
+     * @throws FileSystemException may be thrown by subclasses.\r
+     * @see #getType()\r
+     * @see FileType#FILE\r
+     */\r
+    @Override\r
+    public boolean isFile() throws FileSystemException {\r
+        // Use equals instead of == to avoid any class loader worries.\r
+        return FileType.FILE.equals(this.getType());\r
+    }\r
+\r
+    /**\r
+     * Sets the type of this file e.g. when it will be attached.\r
+     *\r
+     * @param type {@link FileType#FOLDER} or {@link FileType#FILE}\r
+     * @throws FileSystemException if an error occurs.\r
+     */\r
+    void setType(final FileType type) throws FileSystemException {\r
+        if (type != FileType.FOLDER && type != FileType.FILE && type != FileType.FILE_OR_FOLDER) {\r
+            throw new FileSystemException("vfs.provider/filename-type.error");\r
+        }\r
+\r
+        this.type = type;\r
+    }\r
+\r
+    /**\r
+     * Returns the URI of the file.\r
+     *\r
+     * @return the FileName as a URI.\r
+     */\r
+    @Override\r
+    public String toString() {\r
+        return getURI();\r
+    }\r
+}\r
index 497acd22372f7f0efc35cd8e9d9f95a527642c6b..380055031da288982901b9e870ff1068bee2aad4 100644 (file)
-/*
- * 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;
-
-import java.io.BufferedInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.URL;
-import java.security.AccessController;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-import java.security.cert.Certificate;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Stream;
-
-import org.apache.commons.vfs2.Capability;
-import org.apache.commons.vfs2.FileContent;
-import org.apache.commons.vfs2.FileContentInfoFactory;
-import org.apache.commons.vfs2.FileName;
-import org.apache.commons.vfs2.FileNotFolderException;
-import org.apache.commons.vfs2.FileObject;
-import org.apache.commons.vfs2.FileSelector;
-import org.apache.commons.vfs2.FileSystem;
-import org.apache.commons.vfs2.FileSystemException;
-import org.apache.commons.vfs2.FileType;
-import org.apache.commons.vfs2.NameScope;
-import org.apache.commons.vfs2.RandomAccessContent;
-import org.apache.commons.vfs2.Selectors;
-import org.apache.commons.vfs2.operations.DefaultFileOperations;
-import org.apache.commons.vfs2.operations.FileOperations;
-import org.apache.commons.vfs2.util.FileObjectUtils;
-import org.apache.commons.vfs2.util.RandomAccessMode;
-
-/**
- * A partial file object implementation.
- *
- * TODO - Chop this class up - move all the protected methods to several interfaces, so that structure and content can
- * be separately overridden.
- *
- * <p>
- * TODO - Check caps in methods like getChildren(), etc, and give better error messages (eg 'this file type does not
- * support listing children', vs 'this is not a folder')
- * </p>
- *
- * @param <AFS> An AbstractFileSystem subclass
- */
-public abstract class AbstractFileObject<AFS extends AbstractFileSystem> implements FileObject {
-
-    /**
-     * Same as {@link BufferedInputStream}.
-     */
-    public static final int DEFAULT_BUFFER_SIZE = 8192;
-
-    private static final int INITIAL_LIST_SIZE = 5;
-
-    private static final String DO_GET_INPUT_STREAM_INT = "doGetInputStream(int)";
-
-    private final AbstractFileName fileName;
-    private final AFS fileSystem;
-
-    private FileContent content;
-    // Cached info
-    private boolean attached;
-    private FileType type;
-
-    private FileObject parent;
-    // Changed to hold only the name of the children and let the object
-    // go into the global files cache
-    // private FileObject[] children;
-    private FileName[] children;
-
-    private List<Object> objects;
-
-    /**
-     * FileServices instance.
-     */
-    private FileOperations operations;
-
-    /**
-     * Constructs a new instance.
-     *
-     * @param fileName the file name.
-     * @param fileSystem the file system.
-     */
-    protected AbstractFileObject(final AbstractFileName fileName, final AFS fileSystem) {
-        this.fileName = fileName;
-        this.fileSystem = fileSystem;
-        fileSystem.fileObjectHanded(this);
-    }
-
-    /**
-     * Traverses a file.
-     */
-    private static void traverse(final DefaultFileSelectorInfo fileInfo, final FileSelector selector,
-            final boolean depthwise, final List<FileObject> selected) throws Exception {
-        // Check the file itself
-        final FileObject file = fileInfo.getFile();
-        final int index = selected.size();
-
-        // If the file is a folder, traverse it
-        if (file.getType().hasChildren() && selector.traverseDescendents(fileInfo)) {
-            final int curDepth = fileInfo.getDepth();
-            fileInfo.setDepth(curDepth + 1);
-
-            // Traverse the children
-            final FileObject[] children = file.getChildren();
-            for (final FileObject child : children) {
-                fileInfo.setFile(child);
-                traverse(fileInfo, selector, depthwise, selected);
-            }
-
-            fileInfo.setFile(file);
-            fileInfo.setDepth(curDepth);
-        }
-
-        // Add the file if doing depthwise traversal
-        if (selector.includeFile(fileInfo)) {
-            if (depthwise) {
-                // Add this file after its descendants
-                selected.add(file);
-            } else {
-                // Add this file before its descendants
-                selected.add(index, file);
-            }
-        }
-    }
-
-    /**
-     * Attaches to the file.
-     *
-     * @throws FileSystemException if an error occurs.
-     */
-    private void attach() throws FileSystemException {
-        synchronized (fileSystem) {
-            if (attached) {
-                return;
-            }
-
-            try {
-                // Attach and determine the file type
-                doAttach();
-                attached = true;
-                // now the type could already be injected by doAttach (e.g from parent to child)
-
-                /*
-                 * VFS-210: determine the type when really asked fore if (type == null) { setFileType(doGetType()); } if
-                 * (type == null) { setFileType(FileType.IMAGINARY); }
-                 */
-            } catch (final Exception exc) {
-                throw new FileSystemException("vfs.provider/get-type.error", exc, fileName);
-            }
-
-            // fs.fileAttached(this);
-        }
-    }
-
-    /**
-     * Queries the object if a simple rename to the file name of {@code newfile} is possible.
-     *
-     * @param newfile the new file name
-     * @return true if rename is possible
-     */
-    @Override
-    public boolean canRenameTo(final FileObject newfile) {
-        return fileSystem == newfile.getFileSystem();
-    }
-
-    /**
-     * Notifies the file that its children have changed.
-     *
-     * @param childName The name of the child.
-     * @param newType The type of the child.
-     * @throws Exception if an error occurs.
-     */
-    protected void childrenChanged(final FileName childName, final FileType newType) throws Exception {
-        // TODO - this may be called when not attached
-
-        if (children != null && childName != null && newType != null) {
-            // TODO - figure out if children[] can be replaced by list
-            final ArrayList<FileName> list = new ArrayList<>(Arrays.asList(children));
-            if (newType.equals(FileType.IMAGINARY)) {
-                list.remove(childName);
-            } else {
-                list.add(childName);
-            }
-            children = list.toArray(FileName.EMPTY_ARRAY);
-        }
-
-        // removeChildrenCache();
-        onChildrenChanged(childName, newType);
-    }
-
-    /**
-     * Closes this file, and its content.
-     *
-     * @throws FileSystemException if an error occurs.
-     */
-    @Override
-    public void close() throws FileSystemException {
-        FileSystemException exc = null;
-
-        synchronized (fileSystem) {
-            // Close the content
-            if (content != null) {
-                try {
-                    content.close();
-                    content = null;
-                } catch (final FileSystemException e) {
-                    exc = e;
-                }
-            }
-
-            // Detach from the file
-            try {
-                detach();
-            } catch (final Exception e) {
-                exc = new FileSystemException("vfs.provider/close.error", fileName, e);
-            }
-
-            if (exc != null) {
-                throw exc;
-            }
-        }
-    }
-
-    /**
-     * Compares two FileObjects (ignores case).
-     *
-     * @param file the object to compare.
-     * @return a negative integer, zero, or a positive integer when this object is less than, equal to, or greater than
-     *         the given object.
-     */
-    @Override
-    public int compareTo(final FileObject file) {
-        if (file == null) {
-            return 1;
-        }
-        return this.toString().compareToIgnoreCase(file.toString());
-    }
-
-    /**
-     * Copies another file to this file.
-     *
-     * @param file The FileObject to copy.
-     * @param selector The FileSelector.
-     * @throws FileSystemException if an error occurs.
-     */
-    @Override
-    public void copyFrom(final FileObject file, final FileSelector selector) throws FileSystemException {
-        if (!FileObjectUtils.exists(file)) {
-            throw new FileSystemException("vfs.provider/copy-missing-file.error", file);
-        }
-
-        // Locate the files to copy across
-        final ArrayList<FileObject> files = new ArrayList<>();
-        file.findFiles(selector, false, files);
-
-        // Copy everything across
-        for (final FileObject srcFile : files) {
-            // Determine the destination file
-            final String relPath = file.getName().getRelativeName(srcFile.getName());
-            final FileObject destFile = resolveFile(relPath, NameScope.DESCENDENT_OR_SELF);
-
-            // Clean up the destination file, if necessary
-            if (FileObjectUtils.exists(destFile) && destFile.getType() != srcFile.getType()) {
-                // The destination file exists, and is not of the same type,
-                // so delete it
-                // TODO - add a pluggable policy for deleting and overwriting existing files
-                destFile.deleteAll();
-            }
-
-            // Copy across
-            try {
-                if (srcFile.getType().hasContent()) {
-                    FileObjectUtils.writeContent(srcFile, destFile);
-                } else if (srcFile.getType().hasChildren()) {
-                    destFile.createFolder();
-                }
-            } catch (final IOException e) {
-                throw new FileSystemException("vfs.provider/copy-file.error", e, srcFile, destFile);
-            }
-        }
-    }
-
-    /**
-     * Creates this file, if it does not exist.
-     *
-     * @throws FileSystemException if an error occurs.
-     */
-    @Override
-    public void createFile() throws FileSystemException {
-        synchronized (fileSystem) {
-            try {
-                // VFS-210: We do not want to trunc any existing file, checking for its existence is
-                // still required
-                if (exists() && !isFile()) {
-                    throw new FileSystemException("vfs.provider/create-file.error", fileName);
-                }
-
-                if (!exists()) {
-                    try (FileContent content = getContent()) {
-                        if (content != null) {
-                            try (OutputStream outputStream = content.getOutputStream()) {
-                                // Avoids NPE on OutputStream#close()
-                            }
-                        }
-                    }
-                }
-            } catch (final RuntimeException re) {
-                throw re;
-            } catch (final Exception e) {
-                throw new FileSystemException("vfs.provider/create-file.error", fileName, e);
-            }
-        }
-    }
-
-    /**
-     * Creates this folder, if it does not exist. Also creates any ancestor files which do not exist.
-     *
-     * @throws FileSystemException if an error occurs.
-     */
-    @Override
-    public void createFolder() throws FileSystemException {
-        synchronized (fileSystem) {
-            // VFS-210: we create a folder only if it does not already exist. So this check should be safe.
-            if (getType().hasChildren()) {
-                // Already exists as correct type
-                return;
-            }
-            if (getType() != FileType.IMAGINARY) {
-                throw new FileSystemException("vfs.provider/create-folder-mismatched-type.error", fileName);
-            }
-            /*
-             * VFS-210: checking for writable is not always possible as the security constraint might be more complex
-             * if (!isWriteable()) { throw new FileSystemException("vfs.provider/create-folder-read-only.error", name);
-             * }
-             */
-
-            // Traverse up the hierarchy and make sure everything is a folder
-            final FileObject parent = getParent();
-            if (parent != null) {
-                parent.createFolder();
-            }
-
-            try {
-                // Create the folder
-                doCreateFolder();
-
-                // Update cached info
-                handleCreate(FileType.FOLDER);
-            } catch (final RuntimeException re) {
-                throw re;
-            } catch (final Exception exc) {
-                throw new FileSystemException("vfs.provider/create-folder.error", fileName, exc);
-            }
-        }
-    }
-
-    /**
-     * Deletes this file.
-     * <p>
-     * TODO - This will not fail if this is a non-empty folder.
-     * </p>
-     *
-     * @return true if this object has been deleted
-     * @throws FileSystemException if an error occurs.
-     */
-    @Override
-    public boolean delete() throws FileSystemException {
-        return delete(Selectors.SELECT_SELF) > 0;
-    }
-
-    /**
-     * Deletes this file, and all children matching the {@code selector}.
-     *
-     * @param selector The FileSelector.
-     * @return the number of deleted files.
-     * @throws FileSystemException if an error occurs.
-     */
-    @Override
-    public int delete(final FileSelector selector) throws FileSystemException {
-        int nuofDeleted = 0;
-
-        /*
-         * VFS-210 if (getType() == FileType.IMAGINARY) { // File does not exist return nuofDeleted; }
-         */
-
-        // Locate all the files to delete
-        final ArrayList<FileObject> files = new ArrayList<>();
-        findFiles(selector, true, files);
-
-        // Delete 'em
-        for (final FileObject fileObject : files) {
-            final AbstractFileObject file = FileObjectUtils.getAbstractFileObject(fileObject);
-            // file.attach();
-
-            // VFS-210: It seems impossible to me that findFiles will return a list with hidden files/directories
-            // in it, else it would not be hidden. Checking for the file-type seems ok in this case
-            // If the file is a folder, make sure all its children have been deleted
-            if (file.getType().hasChildren() && file.getChildren().length != 0) {
-                // Skip - as the selector forced us not to delete all files
-                continue;
-            }
-
-            // Delete the file
-            if (file.deleteSelf()) {
-                nuofDeleted++;
-            }
-        }
-
-        return nuofDeleted;
-    }
-
-    /**
-     * Deletes this file and all children. Shorthand for {@code delete(Selectors.SELECT_ALL)}
-     *
-     * @return the number of deleted files.
-     * @throws FileSystemException if an error occurs.
-     * @see #delete(FileSelector)
-     * @see Selectors#SELECT_ALL
-     */
-    @Override
-    public int deleteAll() throws FileSystemException {
-        return this.delete(Selectors.SELECT_ALL);
-    }
-
-    /**
-     * Deletes this file, once all its children have been deleted
-     *
-     * @return true if this file has been deleted
-     * @throws FileSystemException if an error occurs.
-     */
-    private boolean deleteSelf() throws FileSystemException {
-        synchronized (fileSystem) {
-            // Its possible to delete a read-only file if you have write-execute access to the directory
-
-            /*
-             * VFS-210 if (getType() == FileType.IMAGINARY) { // File does not exist return false; }
-             */
-
-            try {
-                // Delete the file
-                doDelete();
-
-                // Update cached info
-                handleDelete();
-            } catch (final RuntimeException re) {
-                throw re;
-            } catch (final Exception exc) {
-                throw new FileSystemException("vfs.provider/delete.error", exc, fileName);
-            }
-
-            return true;
-        }
-    }
-
-    /**
-     * Detaches this file, invalidating all cached info. This will force a call to {@link #doAttach} next time this file
-     * is used.
-     *
-     * @throws Exception if an error occurs.
-     */
-    private void detach() throws Exception {
-        synchronized (fileSystem) {
-            if (attached) {
-                try {
-                    doDetach();
-                } finally {
-                    attached = false;
-                    setFileType(null);
-                    parent = null;
-
-                    // fs.fileDetached(this);
-
-                    removeChildrenCache();
-                    // children = null;
-                }
-            }
-        }
-    }
-
-    /**
-     * Attaches this file object to its file resource.
-     * <p>
-     * This method is called before any of the doBlah() or onBlah() methods. Sub-classes can use this method to perform
-     * lazy initialization.
-     * </p>
-     * <p>
-     * This implementation does nothing.
-     * </p>
-     *
-     * @throws Exception if an error occurs.
-     */
-    protected void doAttach() throws Exception {
-        // noop
-    }
-
-    /**
-     * Create a FileContent implementation.
-     *
-     * @return The FileContent.
-     * @throws FileSystemException if an error occurs.
-   &n