You should define a new ClasspathContainer by implementing the org.eclipse.jdt.core.classpath.ContainerInitializerextension point. For example the org.eclipse.jdt.junit plugin defines the following in its plugin.xml
<extension
point="org.eclipse.jdt.core.classpathContainerInitializer">
<classpathContainerInitializer
class="org.eclipse.jdt.internal.junit.buildpath.JUnitContainerInitializer"
id="org.eclipse.jdt.junit.JUNIT_CONTAINER">
</classpathContainerInitializer>
</extension>
The referenced JUnitContainerInitializer creates and initialises the two JUnit classpath containers.
Following this approach you can implement a "folder container". There is a DeveloperWorks article that shows how to do this (you'll need to register to view the article).
Update: It is possible to define a container without registering the extension point, but you have to be aware that you'll not have access to lifecycle methods to refresh the container if the contents of the folder change. It is much better to do it via the extension point.
The example below will add the "lib" folder of a project as a custom container, and add any jar files found in the folder as entries within the container. It does not manage source associations .
final String description = "My container";
IProject project = ResourcesPlugin.getWorkspace().getRoot()
.getProject("foo");
//get the lib folder, TODO check if it exists!
final IFolder folder = project.getFolder("lib");
//define a unique path for the custom container
final IPath containerPath = new Path(
"my.custom.CLASSPATH_CONTAINER").append(project
.getFullPath());
IJavaProject javaProject = JavaCore.create(project);
//create a container that lists all jars in the lib folder
IClasspathContainer customContainer = new IClasspathContainer() {
public IClasspathEntry[] getClasspathEntries() {
List<IClasspathEntry> entryList = new ArrayList<IClasspathEntry>();
try {
// add any members that are files with the jar extension
IResource[] members = folder.members();
for (IResource resource : members) {
if (IFile.class.isAssignableFrom(resource
.getClass())) {
if (resource.getName().endsWith(".jar")) {
entryList.add(JavaCore.newLibraryEntry(
new Path(resource.getFullPath()
.toOSString()), null,
new Path("/")));
}
}
}
} catch (CoreException e) {
// TODO handle the exception
e.printStackTrace();
}
// convert the list to an array and return it
IClasspathEntry[] entryArray = new IClasspathEntry[entryList
.size()];
return entryList.toArray(entryArray);
}
public String getDescription() {
return description;
}
public int getKind() {
return IClasspathEntry.CPE_CONTAINER;
}
public IPath getPath() {
return containerPath;
}
@Override
public String toString() {
return getDescription();
}
};
//register the custom container so when we add its path it is discovered
JavaCore.setClasspathContainer(containerPath,
new IJavaProject[] { javaProject },
new IClasspathContainer[] { customContainer }, null);
IClasspathEntry[] entries = javaProject.getRawClasspath();
//check if the container is already on the path
boolean hasCustomContainer = false;
for (int i = 0; i < entries.length; i++) {
if (entries[i].getEntryKind() == IClasspathEntry.CPE_CONTAINER
&& entries[i].getPath().equals(containerPath)) {
hasCustomContainer = true;
}
}
if (!hasCustomContainer) {
IClasspathEntry[] newEntries = new IClasspathEntry[entries.length + 1];
System.arraycopy(entries, 0, newEntries, 0, entries.length);
// add a new entry using the path to the container
newEntries[entries.length] = JavaCore
.newContainerEntry(customContainer.getPath());
javaProject.setRawClasspath(newEntries,
new NullProgressMonitor());
}