View Javadoc

1   /* $HeadURL$
2    * $Id$
3    *
4    * Copyright (c) 2009-2010 DuraSpace
5    * http://duraspace.org
6    *
7    * In collaboration with Topaz Inc.
8    * http://www.topazproject.org
9    *
10   * Licensed under the Apache License, Version 2.0 (the "License");
11   * you may not use this file except in compliance with the License.
12   * You may obtain a copy of the License at
13   *
14   *     http://www.apache.org/licenses/LICENSE-2.0
15   *
16   * Unless required by applicable law or agreed to in writing, software
17   * distributed under the License is distributed on an "AS IS" BASIS,
18   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19   * See the License for the specific language governing permissions and
20   * limitations under the License.
21   */
22  package org.akubraproject.fs;
23  
24  import com.google.common.collect.AbstractIterator;
25  import org.slf4j.Logger;
26  import org.slf4j.LoggerFactory;
27  
28  import java.io.File;
29  import java.net.URI;
30  import java.net.URISyntaxException;
31  
32  /**
33   * Iterates over all files in baseDir (respecting filterPrefix if provided).
34   *
35   * @author Chris Wilper
36   */
37  class FSBlobIdIterator extends AbstractIterator<URI> {
38    private final Logger log = LoggerFactory.getLogger(FSBlobIdIterator.class);
39    private final File baseDir;
40    private final String filterPrefix;
41    private DirectoryNode currentDir;
42  
43    FSBlobIdIterator(File baseDir, String filterPrefix) {
44      this.baseDir = baseDir;
45      this.filterPrefix = filterPrefix;
46      currentDir = new DirectoryNode(null, "");
47    }
48  
49    @Override
50    protected URI computeNext() {
51      while (currentDir != null) {
52        DirectoryNode child = currentDir.nextChild();
53        if (child == null) {
54          // no more children; move up
55          currentDir = currentDir.parent;
56        } else if (child.isDirectory()) {
57          // child is dir; move down
58          currentDir = child;
59        } else {
60          // child is file
61          try {
62            URI uri = new URI(FSBlob.scheme + ":" + child.path);
63            if (filterPrefix == null || uri.toString().startsWith(filterPrefix)) {
64              return uri;
65            }
66          } catch (URISyntaxException e) {
67            log.warn("Skipping non-URI-safe file: {}", child.path);
68          }
69        }
70      }
71  
72      return endOfData(); // exhausted
73    }
74  
75    private class DirectoryNode {
76  
77      final DirectoryNode parent;
78  
79      final String path;
80  
81      private String[] childPaths;
82  
83      private int childNum;
84  
85      DirectoryNode(DirectoryNode parent,  // null if root
86                    String path) {         // "" if root, "name/" if subdir, "name" if file
87        this.parent = parent;
88        this.path = path;
89        if (isDirectory()) {
90          setChildPaths();
91        }
92      }
93  
94      private void setChildPaths() {
95        File dir;
96        if (path.length() == 0) {
97          dir = baseDir;
98        } else {
99          dir = new File(baseDir, path);
100       }
101       File[] childFiles = dir.listFiles();
102       childPaths = new String[childFiles.length];
103       for (int i = 0; i < childFiles.length; i++) {
104         StringBuilder childPath = new StringBuilder(path);
105         childPath.append(childFiles[i].getName());
106         if (childFiles[i].isDirectory()) {
107           childPath.append("/");
108         }
109         childPaths[i] = childPath.toString();
110       }
111     }
112 
113     boolean isDirectory() {
114       return path.length() == 0 || path.endsWith("/");
115     }
116 
117     DirectoryNode nextChild() {
118       if (isDirectory()) {
119         if (childNum == childPaths.length) {
120           return null;  // no more children
121         } else {
122           return new DirectoryNode(this, childPaths[childNum++]);
123         }
124       } else {
125         return null;   // not a directory
126       }
127     }
128   }
129 }