tikhomirov@58: /* tikhomirov@58: * Copyright (c) 2011 Artem Tikhomirov tikhomirov@58: */ tikhomirov@58: package com.tmate.hgkit.fs; tikhomirov@58: tikhomirov@58: import java.io.File; tikhomirov@58: import java.util.LinkedList; tikhomirov@58: import java.util.NoSuchElementException; tikhomirov@58: tikhomirov@58: /** tikhomirov@58: * tikhomirov@58: * @author artem tikhomirov@58: */ tikhomirov@58: public class FileWalker { tikhomirov@58: tikhomirov@58: private final File startDir; tikhomirov@58: private final LinkedList dirQueue; tikhomirov@58: private final LinkedList fileQueue; tikhomirov@58: private File nextFile; tikhomirov@58: private String nextPath; tikhomirov@58: tikhomirov@58: // FilenameFilter is used in a non-standard way - first argument, dir, is always startDir, tikhomirov@58: // while second arg, name, is startDir-relative path to the file in question tikhomirov@58: public FileWalker(File startDir) { tikhomirov@58: this.startDir = startDir; tikhomirov@58: dirQueue = new LinkedList(); tikhomirov@58: fileQueue = new LinkedList(); tikhomirov@58: reset(); tikhomirov@58: } tikhomirov@58: tikhomirov@58: public void reset() { tikhomirov@58: fileQueue.clear(); tikhomirov@58: dirQueue.clear(); tikhomirov@58: dirQueue.add(startDir); tikhomirov@58: nextFile = null; tikhomirov@58: nextPath = null; tikhomirov@58: } tikhomirov@58: tikhomirov@58: public boolean hasNext() { tikhomirov@58: return fill(); tikhomirov@58: } tikhomirov@58: tikhomirov@58: public void next() { tikhomirov@58: if (!fill()) { tikhomirov@58: throw new NoSuchElementException(); tikhomirov@58: } tikhomirov@58: nextFile = fileQueue.removeFirst(); tikhomirov@58: nextPath = path(nextFile); tikhomirov@58: } tikhomirov@58: tikhomirov@58: public String name() { tikhomirov@58: return nextPath; tikhomirov@58: } tikhomirov@58: tikhomirov@58: public File file() { tikhomirov@58: return nextFile; tikhomirov@58: } tikhomirov@58: tikhomirov@58: private String path(File f) { tikhomirov@58: // XXX LocalHgRepo#normalize tikhomirov@58: String p = f.getPath().substring(startDir.getPath().length() + 1); tikhomirov@58: return p.replace('\\', '/').replace("//", "/"); tikhomirov@58: } tikhomirov@58: tikhomirov@58: private File[] listFiles(File f) { tikhomirov@58: // in case we need to solve os-related file issues (mac with some encodings?) tikhomirov@58: return f.listFiles(); tikhomirov@58: } tikhomirov@58: tikhomirov@58: // return true when fill added any elements to fileQueue. tikhomirov@58: private boolean fill() { tikhomirov@58: while (fileQueue.isEmpty()) { tikhomirov@58: if (dirQueue.isEmpty()) { tikhomirov@58: return false; tikhomirov@58: } tikhomirov@58: while (!dirQueue.isEmpty()) { tikhomirov@58: File dir = dirQueue.removeFirst(); tikhomirov@58: for (File f : listFiles(dir)) { tikhomirov@58: if (f.isDirectory()) { tikhomirov@58: if (!".hg".equals(f.getName())) { tikhomirov@58: dirQueue.addLast(f); tikhomirov@58: } tikhomirov@58: } else { tikhomirov@58: fileQueue.addLast(f); tikhomirov@58: } tikhomirov@58: } tikhomirov@58: break; tikhomirov@58: } tikhomirov@58: } tikhomirov@58: return !fileQueue.isEmpty(); tikhomirov@58: } tikhomirov@58: }