Javaによるtreeコマンド実装

ちょっと前に会社の後輩に出した課題。
自分でもやってみた。

import java.io.*;
import java.util.*;

public class Tree {

	private static final String ONE_NODE = "├─";

	private static final String END_NODE = "└─";

	private static final String CONTINUE = "│  ";

	private static final String BLANK = "    ";

	private File rootDir = null;

	private PrintStream out = null;

	/*
	 * 出力に含めるファイル/ディレクトリを判定するフィルタ
	 * デフォルトではディレクトリのみ。
	 */
	private FileFilter filter = new FileFilter() {
		public boolean accept(File file) {
			return file.isDirectory();
		}
	};
	
	/*
	 * ファイルソート順を決定する比較オブジェクト
	 * デフォルトでは、ファイルを先に、ディレクトリを後に、
	 * Ascii順
	 */
	private Comparator<File> comparator = new Comparator<File>() {
		public int compare(File f1,File f2) {
			if (f1.isDirectory() && f2.isDirectory()) {
				return f1.compareTo(f2);
			} else if (f1.isDirectory() && f2.isFile()) {
				return 1;
			} else if (f1.isFile() && f2.isDirectory()) {
				return -1;
			} else if (f1.isFile() && f2.isFile()) {
				return f1.compareTo(f2);
			}
			return 0;
		}
	};

	private List<String> hierarchyStrings = new ArrayList<String>();

	private boolean isDirectoryContain = false;
	
	public Tree(File rootDir,PrintStream out) {
		this.rootDir = rootDir;
		this.out = out;
	}
	
	public void setFilter(FileFilter filter) {
		this.filter = filter;
	}

	public void outputTree() {
		this.out.println(rootDir.getName());
		this.outputTreeFiles(rootDir.listFiles(this.filter));
	}
	
	private void outputTreeFiles(File[] files) {
		for (File file:files) {
			if (file.isDirectory()) {
				this.isDirectoryContain = true;
				break;
			} else {
				this.isDirectoryContain = false;
			}
		}
		
		Arrays.sort(files,this.comparator);
		
		for(int i = 0; i < files.length; i++) {
			this.out.println(formatRowString(files[i],i,files.length));
			if (files[i].isDirectory()) {
				hierarchyStrings.add(formatHierarchyStrings(i,files.length));
				outputTreeFiles(files[i].listFiles(this.filter));
			}
		}

		if (hierarchyStrings.size() != 0) {
			hierarchyStrings.remove(hierarchyStrings.size()-1);
		}
	}

	private String formatRowString(File file,int rowIndex,int fileCount) {
		StringBuilder prefix = new StringBuilder();
		for (String hierarchyString : hierarchyStrings) {
			prefix.append(hierarchyString);
		}
		if (file.isFile()) {
			if (this.isDirectoryContain) {
				prefix.append(CONTINUE).append(file.getName());
			} else {
				prefix.append(BLANK).append(file.getName());
			}
		} else if (rowIndex < (fileCount-1)) {
			prefix.append(ONE_NODE).append(file.getName());
		} else if (rowIndex == (fileCount-1)) {
			prefix.append(END_NODE).append(file.getName());
		}

		return prefix.toString();
	}

	private String formatHierarchyStrings(int rowIndex,int fileCount) {

		if (rowIndex < (fileCount - 1)) {
			return CONTINUE;
		}

		if (rowIndex == (fileCount - 1)) {
			return BLANK;
		}

		return null;
	}
	
	
	public static void main(String[] args) {
		File rootDir = new File(System.getProperty("user.dir"));
		
		Tree tree = new Tree(rootDir,System.out);
		
		if (args.length > 0 && args[0].toUpperCase().equals("/F")) {
			tree.setFilter(null);
		}
		
		tree.outputTree();
	}
}

うーん。なんかJavaはこういう実装に向いてないなぁー。
すっきりいかない。
次は、PythonRubyでも書いてみよう。