View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.vfs2;
18  
19  import java.util.ArrayList;
20  import java.util.HashSet;
21  import java.util.List;
22  import java.util.Set;
23  
24  import org.apache.commons.vfs2.provider.AbstractFileObject;
25  import org.apache.commons.vfs2.util.FileObjectUtils;
26  import org.junit.jupiter.api.Assertions;
27  
28  /**
29   * A file selector that asserts that all files are visited, in the correct order.
30   */
31  public class VerifyingFileSelector extends Assertions implements FileSelector {
32  
33      private final FileInfo rootFile;
34      private final List<FileObject> files = new ArrayList<>();
35  
36      private FileInfo currentFolderInfo;
37      private FileObject currentFolder;
38      private Set<String> children;
39      private final List<Set<String>> stack = new ArrayList<>();
40  
41      public VerifyingFileSelector(final FileInfo fileInfo) {
42          rootFile = fileInfo;
43          children = new HashSet<>();
44          children.add(rootFile.baseName);
45      }
46  
47      /**
48       * Asserts that the selector has seen all the files.
49       *
50       * @return The files in the order they were visited.
51       */
52      public List<FileObject> finish() {
53          assertEquals(0, children.size());
54          return files;
55      }
56  
57      /**
58       * Finds a child of the current folder.
59       */
60      private FileInfo getChild(final String baseName) {
61          if (currentFolderInfo == null) {
62              assertEquals(rootFile.baseName, baseName);
63              return rootFile;
64          }
65          final FileInfo child = currentFolderInfo.children.get(baseName);
66          assertNotNull(child, "Could not locate child " + baseName);
67          return child;
68      }
69  
70      /**
71       * Determines if a file or folder should be selected.
72       */
73      @Override
74      public boolean includeFile(final FileSelectInfo fileInfo) throws FileSystemException {
75          final FileObject file = fileInfo.getFile();
76          if (file == currentFolder) {
77              // Pop current folder
78              assertEquals(0, children.size());
79              currentFolder = currentFolder.getParent();
80              currentFolderInfo = currentFolderInfo.getParent();
81              children = stack.remove(0);
82          }
83  
84          final String baseName = file.getName().getBaseName();
85  
86          final FileInfo childInfo = getChild(baseName);
87          assertSame(childInfo.type, file.getType());
88  
89          final boolean isChild = children.remove(baseName);
90          assertTrue(isChild);
91  
92          files.add(file);
93          return true;
94      }
95  
96      /**
97       * Determines whether a folder should be traversed.
98       */
99      @Override
100     public boolean traverseDescendents(final FileSelectInfo fileInfo) throws FileSystemException {
101         // Check that the given file is a folder
102         final FileObject folder = FileObjectUtils.getAbstractFileObject(fileInfo.getFile());
103         assertSame(FileType.FOLDER, folder.getType());
104         assertTrue(folder.isFolder());
105 
106         // Locate the info for the folder
107         final String baseName = folder.getName().getBaseName();
108         if (currentFolder == null) {
109             assertEquals(rootFile.baseName, baseName);
110             currentFolderInfo = rootFile;
111         } else {
112             final AbstractFileObject parent = FileObjectUtils.getAbstractFileObject(folder.getParent());
113             assertSame(currentFolder, parent);
114 
115             // Locate the info for the child, and make sure it is folder
116             currentFolderInfo = getChild(baseName);
117             assertSame(FileType.FOLDER, currentFolderInfo.type);
118         }
119 
120         // Push the folder
121         stack.add(0, children);
122         children = new HashSet<>(currentFolderInfo.children.keySet());
123         currentFolder = folder;
124 
125         return true;
126     }
127 
128 }