com.xebialabs.overthere.util.OverthereFileDirectoryWalker Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of overthere Show documentation
Show all versions of overthere Show documentation
Remote file manipulation and process execution framework for Java
/*
* Copyright (c) 2008-2014, XebiaLabs B.V., All rights reserved.
*
*
* Overthere is licensed under the terms of the GPLv2
* , like most XebiaLabs Libraries.
* There are special exceptions to the terms and conditions of the GPLv2 as it is applied to
* this software, see the FLOSS License Exception
* .
*
* This program is free software; you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation; version 2
* of the License.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this
* program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
package com.xebialabs.overthere.util;
import java.io.IOException;
import java.util.List;
import com.xebialabs.overthere.OverthereFile;
import com.xebialabs.overthere.RuntimeIOException;
/**
* Abstract class that walks through a directory hierarchy and provides subclasses with convenient hooks to add specific
* behaviour.
*
* This class operates with a maximum depth to limit the files and direcories visited.
*
* The following sections describe:
*
* - 1. Example Implementation - example
FileCleaner
implementation.
*
*
*
* 1. Example Implementation
*
* There are many possible extensions, for example, to delete all files and '.svn' directories
*
*
* public class FileCleaner extends OverthereFileDirectoryWalker {
* private List<OverthereFile> results = new ArrayList<OverthereFile>();
*
* public FileCleaner() {
* super();
* }
*
* public List clean(OverthereFile startDirectory) {
* results.clear();
* walk(startDirectory, results);
* return results;
* }
*
* protected boolean handleDirectory(OverthereFile directory, int depth) {
* // delete svn directories and then skip
* if (".svn".equals(directory.getName())) {
* directory.delete();
* return false;
* } else {
* return true;
* }
*
* }
*
* protected void handleFile(OverthereFile file, int depth) {
* // delete file and add to list of deleted
* file.delete();
* results.add(file);
* }
* }
*
*
* Adapted from the DirectoryWalker class in Common IO.
*
* FIXME: Move to its proper place
*/
public abstract class OverthereFileDirectoryWalker {
/**
* The directory level representing the starting directory = 0
*/
public static final int ROOT = 0;
/**
* The limit on the directory depth to walk.
*/
private final int depthLimit;
/**
* Construct an instance with unlimited depth.
*/
protected OverthereFileDirectoryWalker() {
this(-1);
}
/**
* Construct an instance with limit the depth navigated to.
*
*
* @param depthLimit controls how deep the hierarchy is navigated to (less than 0 means unlimited)
*/
protected OverthereFileDirectoryWalker(int depthLimit) {
this.depthLimit = depthLimit;
}
/**
* Internal method that walks the directory hierarchy in a depth-first manner.
*
* Users of this class do not need to call this method. This method will be called automatically by another (public)
* method on the specific subclass.
*
* Writers of subclasses should call this method to start the directory walk. Once called, this method will emit
* events as it walks the hierarchy. The event methods have the prefix handle
.
*
* @param startDirectory the directory to start from, not null
* @throws NullPointerException if the start directory is null
* @throws RuntimeIOException if an I/O Error occurs
*/
protected final void walk(OverthereFile startDirectory) throws RuntimeIOException {
try {
if (startDirectory == null) {
throw new NullPointerException("Start Directory is null");
}
handleStart(startDirectory);
walk(startDirectory, 0);
handleEnd();
} catch (IOException e) {
throw new RuntimeIOException(e);
}
}
/**
* Main recursive method to examine the directory hierarchy.
*
* @param directory the directory to examine, not null
* @param depth the directory level (starting directory = 0)
* @throws IOException if an I/O Error occurs
*/
private void walk(OverthereFile directory, int depth) throws IOException {
if (handleDirectory(directory, depth)) {
handleDirectoryStart(directory, depth);
int childDepth = depth + 1;
if (depthLimit < 0 || childDepth <= depthLimit) {
List childFiles = listFiles(directory);
if (childFiles == null) {
handleRestricted(directory, childDepth);
} else {
for (OverthereFile childFile : childFiles) {
if (childFile.isDirectory()) {
walk(childFile, childDepth);
} else {
handleFile(childFile, childDepth);
}
}
}
}
handleDirectoryEnd(directory, depth);
}
}
/**
* Lists the files in the directory.
*
* @param directory in which to list files.
* @return all the files in the directory as filtering.
*/
protected List listFiles(OverthereFile directory) {
return directory.listFiles();
}
/**
* Overridable callback method invoked at the start of processing.
*
* This implementation does nothing.
*
* @param startDirectory the directory to start from
* @throws IOException if an I/O Error occurs
*/
protected void handleStart(OverthereFile startDirectory) throws IOException {
// do nothing - overridable by subclass
}
/**
* Overridable callback method invoked to determine if a directory should be processed.
*
* This method returns a boolean to indicate if the directory should be examined or not. If you return false, the
* entire directory and any subdirectories will be skipped.
*
* This implementation does nothing and returns true.
*
* @param directory the current directory being processed
* @param depth the current directory level (starting directory = 0)
* @return true to process this directory, false to skip this directory
* @throws IOException if an I/O Error occurs
*/
protected boolean handleDirectory(OverthereFile directory, int depth) throws IOException {
// do nothing - overridable by subclass
return true; // process directory
}
/**
* Overridable callback method invoked at the start of processing each directory.
*
* This implementation does nothing.
*
* @param directory the current directory being processed
* @param depth the current directory level (starting directory = 0)
* @throws IOException if an I/O Error occurs
*/
protected void handleDirectoryStart(OverthereFile directory, int depth) throws IOException {
// do nothing - overridable by subclass
}
/**
* Overridable callback method invoked for each (non-directory) file.
*
* This implementation does nothing.
*
* @param file the current file being processed
* @param depth the current directory level (starting directory = 0)
* @throws IOException if an I/O Error occurs
*/
protected void handleFile(OverthereFile file, int depth) throws IOException {
// do nothing - overridable by subclass
}
/**
* Overridable callback method invoked for each restricted directory.
*
* This implementation does nothing.
*
* @param directory the restricted directory
* @param depth the current directory level (starting directory = 0)
* @throws IOException if an I/O Error occurs
*/
protected void handleRestricted(OverthereFile directory, int depth) throws IOException {
// do nothing - overridable by subclass
}
/**
* Overridable callback method invoked at the end of processing each directory.
*
* This implementation does nothing.
*
* @param directory the directory being processed
* @param depth the current directory level (starting directory = 0)
* @throws IOException if an I/O Error occurs
*/
protected void handleDirectoryEnd(OverthereFile directory, int depth) throws IOException {
// do nothing - overridable by subclass
}
/**
* Overridable callback method invoked at the end of processing.
*
* This implementation does nothing.
*
* @throws IOException if an I/O Error occurs
*/
protected void handleEnd() throws IOException {
// do nothing - overridable by subclass
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy