* Copyright (C) 2010 Robert Futrell
* robert_futrell at users.sourceforge.net
* http://fifesoft.com/rsyntaxtextarea
* This library is distributed under a modified BSD license. See the included
* RSTALanguageSupport.License.txt file for details.
package org.fife.rsta.ac.java.buildpath;
import java.io.IOException;
import java.util.TreeMap;
import org.fife.rsta.ac.java.Util;
import org.fife.rsta.ac.java.classreader.ClassFile;
* Information about a folder containing a set of classes to add to the "build
* path." This type of library info could be used, for example, to add sibling
* projects in a workspace, not yet built into jars, to another project's build
* @see ClasspathLibraryInfo
public class DirLibraryInfo extends LibraryInfo {
public DirLibraryInfo(File dir) {
public DirLibraryInfo(String dir) {
public DirLibraryInfo(File dir, SourceLocation sourceLoc) {
setSourceLocation(sourceLoc);
public DirLibraryInfo(String dir, SourceLocation sourceLoc) {
this(new File(dir), sourceLoc);
* Compares this <code>LibraryInfo</code> to another one. Two instances of
* this class are only considered equal if they represent the same class
* file location. Source attachment is irrelevant.
* @return The sort order of these two library infos.
public int compareTo(Object o) {
if (o instanceof DirLibraryInfo) {
return dir.compareTo(((DirLibraryInfo)o).dir);
public ClassFile createClassFile(String entryName) throws IOException {
File file = new File(dir, entryName);
System.err.println("ERROR: Invalid class file: " + file.getAbsolutePath());
return new ClassFile(file);
public TreeMap createPackageMap() throws IOException {
TreeMap map = new TreeMap();
getPackageMapImpl(dir, null, map);
public long getLastModified() {
return dir.lastModified();
public String getLocationAsString() {
return dir.getAbsolutePath();
* Does the dirty-work of finding all class files in a directory tree.
* @param dir The directory to scan.
* @param pkg The package name scanned so far, in the form
* "<code>com/company/pkgname</code>"...
* @throws IOException If an IO error occurs.
private void getPackageMapImpl(File dir, String pkg, TreeMap retVal)
File[] children = dir.listFiles();
boolean firstTimeThrough = true;
for (int i=0; i<children.length; i++) {
File child = children[i];
if (child.isFile() && child.getName().endsWith(".class")) {
if (pkg!=null) { // will be null the first time through
if (firstTimeThrough) { // Lazily drill down to pkg map node
firstTimeThrough = false;
String[] items = Util.splitOnChar(pkg, '/');
for (int j=0; j<items.length; j++) {
Object temp = m.get(items[j]);
if (temp instanceof TreeMap) {
TreeMap submap = new TreeMap();
else { // e.g. a ClassFile
// A class with the same name as a package
// name - very unlikely, but could happen. In
// this case, all peer classes/directories will
// share this package/class name conflict, so
// might as well bail now.
String className = child.getName().
substring(0, child.getName().length()-6);
else if (child.isDirectory()) {
String subpkg = pkg==null ? child.getName() :
(pkg + "/" + child.getName());
getPackageMapImpl(child, subpkg, retVal);
* Sets the directory containing the classes.
* @param dir The directory. This cannot be <code>null</code>.
private void setDirectory(File dir) {
if (dir==null || !dir.isDirectory()) {
String name = dir==null ? "null" : dir.getAbsolutePath();
throw new IllegalArgumentException("Directory does not exist: " + name);
* Returns a string representation of this jar information. Useful for
* @return A string representation of this object.
public String toString() {
return "[DirLibraryInfo: " +
"jar=" + dir.getAbsolutePath() +
"; source=" + getSourceLocation() +