package mil.nga.giat.geowave.core.ingest.local; import java.io.File; import java.io.IOException; import java.nio.file.FileVisitResult; import java.nio.file.FileVisitor; import java.nio.file.Path; import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Map.Entry; import java.util.regex.Pattern; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang3.ArrayUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * This class is used by any local file driver to recurse a directory of files. * It will provide the plugin with any supported file with the appropriate * extension within a directory structure. * * @param <P> * the type of the plugin * @param <R> * the type for intermediate data that can be used throughout the * life of the file recursion */ public class LocalPluginFileVisitor<P extends LocalPluginBase, R> implements FileVisitor<Path> { private final static Logger LOGGER = LoggerFactory.getLogger(LocalPluginFileVisitor.class); private class PluginVisitor { private final Pattern pattern; private final String typeName; private final P localPluginBase; public PluginVisitor( final P localPluginBase, final String typeName, final String[] userExtensions ) { final String[] combinedExtensions = ArrayUtils.addAll( localPluginBase.getFileExtensionFilters(), userExtensions); if ((combinedExtensions != null) && (combinedExtensions.length > 0)) { final String[] lowerCaseExtensions = new String[combinedExtensions.length]; for (int i = 0; i < combinedExtensions.length; i++) { lowerCaseExtensions[i] = combinedExtensions[i].toLowerCase(Locale.ENGLISH); } final String extStr = String.format( "([^\\s]+(\\.(?i)(%s))$)", StringUtils.join( lowerCaseExtensions, "|")); pattern = Pattern.compile(extStr); } else { pattern = null; } this.localPluginBase = localPluginBase; this.typeName = typeName; } public boolean supportsFile( final File file ) { if ((pattern != null) && !pattern.matcher( file.getName().toLowerCase( Locale.ENGLISH)).matches()) { return false; } else if (!localPluginBase.supportsFile(file)) { return false; } return true; } } private final AbstractLocalFileDriver<P, R> driver; private final List<PluginVisitor> pluginVisitors; private final R runData; public LocalPluginFileVisitor( final Map<String, P> localPlugins, final AbstractLocalFileDriver<P, R> driver, final R runData, final String[] userExtensions ) { pluginVisitors = new ArrayList<PluginVisitor>( localPlugins.size()); for (final Entry<String, P> localPluginBase : localPlugins.entrySet()) { pluginVisitors.add(new PluginVisitor( localPluginBase.getValue(), localPluginBase.getKey(), userExtensions)); } this.driver = driver; this.runData = runData; } @Override public FileVisitResult postVisitDirectory( final Path path, final IOException e ) throws IOException { return FileVisitResult.CONTINUE; } @Override public FileVisitResult preVisitDirectory( final Path path, final BasicFileAttributes bfa ) throws IOException { return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFile( final Path path, final BasicFileAttributes bfa ) throws IOException { final File file = path.toFile(); for (final PluginVisitor visitor : pluginVisitors) { if (visitor.supportsFile(file)) { driver.processFile( file, visitor.typeName, visitor.localPluginBase, runData); } } return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFileFailed( final Path path, final IOException bfa ) throws IOException { LOGGER.error("Cannot visit path: " + path); return FileVisitResult.CONTINUE; } }