/*
* 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.builder.library.scanner;
import java.io.File;
import java.io.FileFilter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Set;
import org.seasar.mayaa.builder.library.scanner.SourceScanner;
import org.seasar.mayaa.cycle.scope.ApplicationScope;
import org.seasar.mayaa.impl.IllegalParameterValueException;
import org.seasar.mayaa.impl.ParameterAwareImpl;
import org.seasar.mayaa.impl.source.ApplicationFileSourceDescriptor;
import org.seasar.mayaa.impl.source.FileSourceDescriptor;
import org.seasar.mayaa.impl.util.StringUtil;
import org.seasar.mayaa.impl.util.collection.NullIterator;
/**
* @author Masataka Kurihara (Gluegent, Inc.)
* @author Koji Suga (Gluegent, Inc.)
*/
public class FolderSourceScanner extends ParameterAwareImpl
implements SourceScanner {
private static final long serialVersionUID = 2888604805693825909L;
private FileSourceDescriptor _source;
private String _folder;
private boolean _recursive = false;
private boolean _absolute = false;
private Set _extensions = new HashSet();
private Set _unmodifiableExtensions =
Collections.unmodifiableSet(_extensions);
public String getFolder() {
if (StringUtil.isEmpty(_folder)) {
throw new IllegalStateException();
}
return _folder;
}
public boolean isRecursive() {
return _recursive;
}
public Set getExtensions() {
return _unmodifiableExtensions;
}
protected String[] getExtensionArray() {
return (String[]) _extensions.toArray(new String[_extensions.size()]);
}
public Iterator scan() {
ApplicationScope appScope = null;
if (_source == null) {
if (_absolute) {
_source = new FileSourceDescriptor();
} else {
ApplicationFileSourceDescriptor appSource =
new ApplicationFileSourceDescriptor();
appScope = appSource.getApplicationScope();
_source = appSource;
}
_source.setRoot(getFolder());
}
if (_source.exists() && _source.isDirectory()) {
return new FileToSourceIterator(appScope,
_source.getRoot(), iterateFiles(_source.getFile()));
}
return NullIterator.getInstance();
}
protected Iterator iterateFiles(File dir) {
if (dir.exists()) {
File[] files;
if (dir.isDirectory()) {
files = listFiles(dir);
} else {
files = new File[] { dir };
}
return new FileArrayIterator(files);
}
return NullIterator.getInstance();
}
protected FileFilter createExtensionFilter() {
return new FileFilter() {
private final String[] _acceptableExtensions = getExtensionArray();
public boolean accept(File pathName) {
if (pathName.isDirectory()) {
return true;
}
if (_acceptableExtensions.length == 0) {
return true;
}
for (int i = 0; i < _acceptableExtensions.length; i++) {
if (pathName.getName().endsWith(_acceptableExtensions[i])) {
return true;
}
}
return false;
}
};
}
protected File[] listFiles(File dir) {
List sources = new ArrayList();
FileFilter filter = createExtensionFilter();
if (_recursive) {
listFilesRecursive(sources, dir, filter);
} else {
listFilesNonRecursive(sources, dir, filter);
}
return (File[]) sources.toArray(new File[sources.size()]);
}
protected void listFilesNonRecursive(List list, File dir, FileFilter filter) {
if (dir.isDirectory()) {
File[] files = dir.listFiles(filter);
for (int i = 0; i < files.length; i++) {
if (files[i].isFile()) {
list.add(files[i]);
}
}
}
}
protected void listFilesRecursive(List list, File dir, FileFilter filter) {
if (dir.isDirectory()) {
File[] files = dir.listFiles(filter);
for (int i = 0; i < files.length; i++) {
if (files[i].isDirectory()) {
listFilesRecursive(list, files[i], filter);
} else {
list.add(files[i]);
}
}
}
}
// Parameterizable implements ------------------------------------
public void setParameter(String name, String value) {
if ("folder".equals(name)) {
if (StringUtil.isEmpty(value)) {
throw new IllegalParameterValueException(getClass(), name);
}
_folder = value;
} else if ("recursive".equals(name)) {
_recursive = Boolean.valueOf(value).booleanValue();
} else if ("absolute".equals(name)) {
_absolute = Boolean.valueOf(value).booleanValue();
} else if ("extension".equals(name)) {
if (StringUtil.isEmpty(value)) {
throw new IllegalParameterValueException(getClass(), name);
}
if (value.charAt(0) != '.') {
_extensions.add('.' + value);
} else {
_extensions.add(value);
}
}
super.setParameter(name, value);
}
// support class ------------------------------------------------
protected static class FileArrayIterator implements Iterator {
private File[] _files;
private int _index;
public FileArrayIterator(File[] files) {
if (files == null) {
throw new IllegalArgumentException();
}
_files = files;
}
public boolean hasNext() {
return _index < _files.length;
}
public Object next() {
if (hasNext() == false) {
throw new NoSuchElementException();
}
return _files[_index++];
}
public void remove() {
throw new UnsupportedOperationException();
}
}
protected static class FileToSourceIterator implements Iterator {
private ApplicationScope _applicationScope;
private String _root;
private Iterator _iterator;
public FileToSourceIterator(ApplicationScope applicationScope,
String root, Iterator iterator) {
if (iterator == null) {
throw new IllegalArgumentException();
}
_applicationScope = applicationScope;
_root = root;
_iterator = iterator;
}
public boolean hasNext() {
return _iterator.hasNext();
}
private String getSystemID(File file) {
String sourceRoot = _root;
if (StringUtil.isEmpty(sourceRoot)) {
sourceRoot = "/";
}
String root;
if (_applicationScope != null) {
root = _applicationScope.getRealPath(sourceRoot);
} else {
root = "";
}
String absolutePath = file.getAbsolutePath();
String path = absolutePath.substring(root.length());
return StringUtil.preparePath(path);
}
public Object next() {
Object ret = _iterator.next();
if (ret instanceof File) {
File file = (File) ret;
String systemID = getSystemID(file);
ApplicationFileSourceDescriptor source =
new ApplicationFileSourceDescriptor();
source.setRoot(_root);
source.setSystemID(systemID);
source.setFile(file);
return source;
}
throw new IllegalStateException();
}
public void remove() {
_iterator.remove();
}
}
}