Packager SPI
aslak Feb 19, 2010 9:31 AMAs a follow up from yesterdays Community meeting
New packaging related SPIs:
{code:java}
package org.jboss.arquillian.spi; import org.jboss.shrinkwrap.api.Archive; /** * DeploymentAppender * * SPI used for modules who need to add classes/resources to the deployed archive. * * @author <a href="mailto:aslak@conduct.no">Aslak Knutsen</a> * @version $Revision: $ */ public interface DeploymentAppender { /** * Create a archive containing the needed resources for this extension * to run in-container. * * @return A Archive of any type */ Archive<?> createArchive(); }
{code}
{code:java}
package org.jboss.arquillian.spi; import org.jboss.shrinkwrap.api.Archive; /** * Extension point for client side deployment enhancements. * * Example: * - Annotations to help define meta data for the deployment * * @author <a href="mailto:aslak@conduct.no">Aslak Knutsen</a> * @version $Revision: $ */ public interface UserArchiveProcessor { /** * * * @param userArchive The user defined deployment archive * @param testClass The users test class */ void process(Archive<?> userArchive, Class<?> testClass); }
{code}
{code:java}
package org.jboss.arquillian.spi; import org.jboss.shrinkwrap.api.Archive; /** * Extension point to alter system defined deployments. * * Example: * - Add beans.xml to EE modules * * @author <a href="mailto:aslak@conduct.no">Aslak Knutsen</a> * @version $Revision: $ */ public interface SystemArchiveProcessor { /** * Called once for each found ArchiveAppender * * @param rchive The system defined deployment archive */ void process(Archive<?> archive); }
{code}
{code:java}
package org.jboss.arquillian.spi; import java.util.Collection; import org.jboss.shrinkwrap.api.Archive; /** * Extension point for the DeployableContainer to prepare the Archives for deployment. * * Example: * - Create a EAR, WAR * * @author <a href="mailto:aslak@conduct.no">Aslak Knutsen</a> * @version $Revision: $ */ public interface DeploymentPackager { /** * @param userArchive The user defined deployment archive * @param systemArchives All found system defined deployment archives * @return A archive to deploy */ Archive<?> generate(Archive<?> userArchive, Collection<Archive<?>> systemArchives); }
{code}
And this is the current DeploymentGenerator impl that mix them all.
{code:java}
package org.jboss.arquillian.impl; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.jboss.arquillian.spi.DeploymentAppender; import org.jboss.arquillian.spi.DeploymentPackager; import org.jboss.arquillian.spi.ServiceLoader; import org.jboss.arquillian.spi.SystemArchiveProcessor; import org.jboss.arquillian.spi.UserArchiveProcessor; import org.jboss.shrinkwrap.api.Archive; /** * DeploymentAppenderArchiveGenerator * * @author <a href="mailto:aslak@conduct.no">Aslak Knutsen</a> * @version $Revision: $ */ public class ClientDeploymentGenerator implements DeploymentGenerator { private ServiceLoader serviceLoader; public ClientDeploymentGenerator(ServiceLoader serviceLoader) { Validate.notNull(serviceLoader, "ServiceLoader must be specified"); this.serviceLoader = serviceLoader; } /* (non-Javadoc) * @see org.jboss.arquillian.impl.DeploymentGenerator#generate(java.lang.Class) */ @Override public Archive<?> generate(Class<?> testCase) { Validate.notNull(testCase, "TestCase must be specified"); DeploymentPackager packager = serviceLoader.onlyOne(DeploymentPackager.class); Archive<?> userArchive = UserArchiveGenerator.generateArchive(testCase); applyUserProcessors(userArchive, testCase); List<Archive<?>> systemArchives = loadSystemArchives(); applySystemProcessors(systemArchives); return packager.generate(userArchive, systemArchives); } private List<Archive<?>> loadSystemArchives() { List<Archive<?>> archives = new ArrayList<Archive<?>>(); Collection<DeploymentAppender> deploymentAppenders = serviceLoader.all(DeploymentAppender.class); for(DeploymentAppender deploymentAppender : deploymentAppenders) { archives.add(deploymentAppender.createArchive()); } return archives; } private void applyUserProcessors(Archive<?> userArchive, Class<?> testClass) { Collection<UserArchiveProcessor> processors = serviceLoader.all(UserArchiveProcessor.class); for(UserArchiveProcessor processor : processors) { processor.process(userArchive, testClass); } } private void applySystemProcessors(List<Archive<?>> systemArchives) { Collection<SystemArchiveProcessor> processors = serviceLoader.all(SystemArchiveProcessor.class); for(SystemArchiveProcessor processor : processors) { for(Archive<?> systemArchive : systemArchives) { processor.process(systemArchive); } } } }{code}
The names are just the last names Pete suggested... (without the rename of DeploymentAppender to ArchiveAppender)