/*
* Copyright 2004-2012 the Seasar Foundation and the Others.
*
* Licensed 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.seasar.mayaa.impl.util;
import java.io.File;
import java.io.FilenameFilter;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* @author Taro Kato (Gluegent, Inc.)
*/
public class FileSearchIterator implements Iterator, Runnable {
private File _root;
private FilenameFilter _filenameFilter;
private boolean _done = false;
private File _current;
private Thread _stepFindThread;
private boolean _gotNext = false;
private volatile boolean _doFindNext;
private volatile boolean _doFindNextDone;
public FileSearchIterator(File rootDir) {
this(rootDir, null);
}
public FileSearchIterator(File rootDir, FilenameFilter filenameFilter) {
_root = rootDir;
_filenameFilter = filenameFilter;
}
public File getRoot() {
return _root;
}
public FilenameFilter getFilenameFilter() {
return _filenameFilter;
}
protected void startThread() {
if (_stepFindThread == null) {
_done = false;
_doFindNext = false;
_stepFindThread = new Thread(this);
_stepFindThread.setName("fileSearch:root=" + _root + ":filter=" + _filenameFilter);
_stepFindThread.setDaemon(true);
_stepFindThread.start();
}
}
protected void stopThread() {
_stepFindThread = null;
}
public boolean hasNext() {
if (_done && _current == null) {
return false;
}
startThread();
_doFindNext = true;
while (_done == false && _doFindNextDone == false) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
break;
}
}
boolean found = _doFindNextDone;
_doFindNext = false;
while (_done == false && _doFindNextDone == true) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
break;
}
}
if (_done && found == false) {
return false;
}
_gotNext = found;
return found;
}
public Object next() {
if (_gotNext == false) {
if (hasNext() == false) {
throw new NoSuchElementException();
}
}
_gotNext = false;
return _current;
}
private Thread _internalCurrentThread;
public void run() {
try {
_done = false;
_current = null;
_internalCurrentThread = Thread.currentThread();
findFile(_root, _root);
} catch(InterruptedException e) {
// no operation
}
_done = true;
}
protected void findFile(File root, File dir)
throws InterruptedException {
File[] files;
if (_filenameFilter == null) {
files = dir.listFiles();
} else {
files = dir.listFiles(_filenameFilter);
}
for (int i = 0; i < files.length; i++) {
File file = files[i];
if (file.isFile() && file.isHidden() == false) {
while (_doFindNext == false
&& _internalCurrentThread == _stepFindThread) {
Thread.sleep(1);
}
if (_internalCurrentThread != _stepFindThread) {
return;
}
_current = file;
_doFindNextDone = true;
while (_doFindNext &&
_internalCurrentThread == _stepFindThread) {
Thread.sleep(1);
}
_doFindNextDone = false;
if (_internalCurrentThread != _stepFindThread) {
return;
}
}
}
for (int i = 0; i < files.length; i++) {
File file = files[i];
if (file.isDirectory()) {
findFile(root, file);
if (_internalCurrentThread != _stepFindThread) {
return;
}
}
}
}
public void remove() {
throw new UnsupportedOperationException();
}
protected void finalize() throws Throwable {
stopThread();
super.finalize();
}
}