package org.sakaiproject.util;
import java.io.File;
/**
* A utility for generating (and cleaning up) {@link Component}s. Please
* note that the tear-down is highly aggressive: it deletes the entire
* root components directory that it generates.
*
*
* @author dmccallum
*
*/
public class ComponentBuilder {
private File componentsRootDir;
private Compiler compiler;
public ComponentBuilder() {
compiler = new Compiler();
}
/**
* Verifies that this builder has a reasonable chance at performing
* its work, i.e. can at least attempt to compile generated source code.
*
* @return
*/
public boolean isUseable() {
return compiler.isUseable();
}
public Component buildComponent() {
if ( !(isUseable()) ) {
throw new IllegalStateException("ComponentBuilder not currently useable, probably because the JDK compiler is unavailable.");
}
initComponentsRootDir();
Component component = new Component(nextComponentId(),
componentsRootDir.getAbsolutePath(), compiler);
component.generate();
return component;
}
protected String nextComponentId() {
return Long.toString((long)(Math.random() * 2821109907456L), 36);
}
protected void initComponentsRootDir() {
if ( componentsRootDir != null && componentsRootDir.exists() ) {
return;
}
doInitComponentsRootDir();
}
protected void doInitComponentsRootDir() {
File tmpDir = new File(System.getProperty("java.io.tmpdir"));
if ( !(tmpDir.exists()) || !(tmpDir.isDirectory()) || !(tmpDir.canWrite()) ) {
throw new IllegalStateException("Unable to create components root dir in [" + tmpDir + "]");
}
File newRoot = null;
for ( int i = 0; i < 1000; i++ ) {
newRoot = new File(tmpDir.getAbsolutePath() + File.separator + "components" + (i == 0 ? "" : "-" + i));
if ( newRoot.mkdir() ) {
componentsRootDir = newRoot;
break;
}
}
if ( componentsRootDir == null ) {
throw new IllegalStateException("Unable to create new components root dir below " + tmpDir);
}
}
public File getComponentsRootDir() {
return componentsRootDir;
}
public void tearDown() {
if ( componentsRootDir == null || !(componentsRootDir.exists()) ) {
return;
}
deleteDir(componentsRootDir);
}
protected void deleteDir(File dir) {
if (!(dir.exists())) {
return;
}
if(dir.isDirectory()) {
File[] files = dir.listFiles();
for ( File file : files ) {
deleteDir(file);
}
dir.delete();
} else {
dir.delete();
}
}
@Override
protected void finalize() {
tearDown();
}
}