package org.jboss.seam.deployment;
import groovy.lang.GroovyRuntimeException;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashSet;
import java.util.Set;
import org.codehaus.groovy.control.CompilationFailedException;
import org.jboss.seam.annotations.Install;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.log.LogProvider;
import org.jboss.seam.log.Logging;
/**
* A deployment handler for (uncompiled) Groovy Seam components
*
* @author Pete Muir
*
*/
public class GroovyDeploymentHandler extends AbstractDeploymentHandler
{
private class GroovyDeploymentHandlerMetadata implements DeploymentMetadata
{
private String groovyExtension;
public GroovyDeploymentHandlerMetadata(String groovyExtension)
{
this.groovyExtension = groovyExtension;
}
public String getFileNameSuffix()
{
return groovyExtension;
}
}
private DeploymentMetadata metadata;
private static final LogProvider log = Logging.getLogProvider(GroovyDeploymentHandler.class);
public static final String NAME = "org.jboss.seam.deployment.GroovyDeploymentHandler";
private final String groovyFileExtension;
private Set<ClassDescriptor> classes;
/**
*
* @param groovyFileExtension The extension to use for the groovy file
*/
public GroovyDeploymentHandler(String groovyFileExtension)
{
this.groovyFileExtension = groovyFileExtension;
this.classes = new HashSet<ClassDescriptor>();
this.metadata = new GroovyDeploymentHandlerMetadata(groovyFileExtension);
}
/**
* Get all the Groovy Seam Components this handler has handled
*/
public Set<ClassDescriptor> getClasses()
{
return classes;
}
@Override
public void postProcess(ClassLoader classLoader)
{
for (FileDescriptor fileDescriptor : getResources())
{
log.debug("Found a groovy file: " + fileDescriptor.getName());
String classname = filenameToGroovyname(fileDescriptor.getName());
String filename = groovyComponentFilename(fileDescriptor.getName());
BufferedReader buffReader = null;
try
{
InputStream stream = classLoader.getResourceAsStream(fileDescriptor.getName());
//TODO is BufferedInputStream necessary?
buffReader = new BufferedReader(new InputStreamReader(stream));
String line = buffReader.readLine();
while (line != null)
{
if (line.indexOf("@Name") != -1 || line.indexOf("@" + Name.class.getName()) != -1)
{
//possibly a Seam component
log.debug("Groovy file possibly a Seam component: " + fileDescriptor.getName());
Class<Object> groovyClass = (Class<Object>) classLoader.loadClass(classname);
Install install = groovyClass.getAnnotation(Install.class);
boolean installable = ( install == null || install.value() )
&& ( groovyClass.isAnnotationPresent(Name.class)
|| classLoader.getResources(filename).hasMoreElements() );
if (installable)
{
log.debug("found groovy component class: " + fileDescriptor.getName());
classes.add(new ClassDescriptor(fileDescriptor.getName(), fileDescriptor.getUrl(), groovyClass));
}
break;
}
line = buffReader.readLine();
}
}
catch (ClassNotFoundException cnfe)
{
log.debug("could not load groovy class: " + classname, cnfe);
}
catch (NoClassDefFoundError ncdfe)
{
log.debug("could not load groovy class (missing dependency): " + classname, ncdfe);
}
catch (IOException ioe)
{
log.debug("could not load groovy file: " + classname, ioe);
}
catch( CompilationFailedException e) {
log.debug("Compilation error in Groovy file:" + classname, e);
}
catch(GroovyRuntimeException e) {
log.debug("Unknown error reading Groovy file:" + classname, e);
}
finally
{
if (buffReader != null) {
try
{
buffReader.close();
}
catch (IOException e)
{
log.trace("Could not close stream");
}
}
}
}
}
private String filenameToGroovyname(String filename)
{
return filename.substring(0, filename.lastIndexOf(groovyFileExtension))
.replace('/', '.').replace('\\', '.');
}
private String groovyComponentFilename(String name)
{
return name.substring(0, name.lastIndexOf(groovyFileExtension)) + ".component.xml";
}
public String getName()
{
return NAME;
}
public DeploymentMetadata getMetadata()
{
return metadata;
}
}