Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
ARQ-215, configurations for extensions
  • Loading branch information
kpiwko committed Sep 13, 2010
1 parent 60722a9 commit a6c3108
Show file tree
Hide file tree
Showing 6 changed files with 243 additions and 53 deletions.
Expand Up @@ -29,6 +29,7 @@
import org.jboss.arquillian.spi.Configuration;
import org.jboss.arquillian.spi.ConfigurationException;
import org.jboss.arquillian.spi.ContainerConfiguration;
import org.jboss.arquillian.spi.ExtensionConfiguration;
import org.jboss.arquillian.spi.ServiceLoader;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
Expand All @@ -43,6 +44,7 @@
* @author <a href="mailto:german.escobarc@gmail.com">German Escobar</a>
* @author <a href="mailto:aslak@redhat.com">Aslak Knutsen</a>
* @author Dan Allen
* @author <a href="mailto:kpiwko@redhat.com">Karel Piwko</a>
* @version $Revision: $
*/
public class XmlConfigurationBuilder implements ConfigurationBuilder
Expand Down Expand Up @@ -106,13 +108,22 @@ public Configuration build() throws ConfigurationException
{
configuration.addContainerConfig(containerConfiguration);
}

Collection<ExtensionConfiguration> extensionsConfigurations = serviceLoader.all(ExtensionConfiguration.class);
log.fine("Extension Configurations: " + containersConfigurations.size());

for(ExtensionConfiguration extensionConfiguration : extensionsConfigurations)
{
configuration.addExtensionConfig(extensionConfiguration);
}

try
{
Document arquillianConfiguration = loadArquillianConfiguration(resourcePath);
if(arquillianConfiguration != null)
{
populateConfiguration(arquillianConfiguration, containersConfigurations);
populateConfiguration(arquillianConfiguration, containersConfigurations, "container");
populateConfiguration(arquillianConfiguration, extensionsConfigurations, "extension");
populateConfiguration(arquillianConfiguration, configuration);
}
}
Expand Down Expand Up @@ -152,24 +163,34 @@ private Document loadArquillianConfiguration(String resourcePath) throws Excepti
return null;
}

private void populateConfiguration(Document xmlDocument, Collection<ContainerConfiguration> containersConfigurations) throws Exception
/**
* Populates a configuration by finding appropriate configuration for either
* a container or an extension in the XML document.
* @param <T> the type of configuration, either container or extension
* @param xmlDocument the document to be parsed
* @param subConfigurations the collection of available configuration for given type
* @param localName the local part of qualified name in of the node in the document
* which should contain configuration
* @throws Exception
*/
private <T> void populateConfiguration(Document xmlDocument, Collection<T> subConfigurations, String localName) throws Exception
{
// load all the container nodes
NodeList nodeList = xmlDocument.getDocumentElement().getElementsByTagNameNS("*", "container");
NodeList nodeList = xmlDocument.getDocumentElement().getElementsByTagNameNS("*", localName);
for (int i=0; i < nodeList.getLength(); i++)
{
Node containerNode = nodeList.item(i);
Node subConfigNode = nodeList.item(i);

// retrieve the package
String pkg = containerNode.getNamespaceURI().replaceFirst("urn:arq:", "");
String pkg = subConfigNode.getNamespaceURI().replaceFirst("urn:arq:", "");

// try to find a ContainerConfiguration that matches the package
ContainerConfiguration containerConfig = matchContainerConfiguration(containersConfigurations, pkg);
T subConfiguration = matchSubConfiguration(subConfigurations, pkg);

if (containerConfig != null)
if (subConfiguration != null)
{
// map the nodes
mapNodesToProperties(containerConfig, containerNode);
mapNodesToProperties(subConfiguration, subConfigNode);
}
}
}
Expand Down Expand Up @@ -266,34 +287,34 @@ private Map<String,String> getPropertiesFromNode(Node element) {
}

/**
* Matches a ContainerConfiguration implementation object with the pkg parameter.
* @param pkg the package prefix used to match the ContainerConfiguration.
* @return the ContainerConfiguration implementation object that matches the package,
* null otherwise.
* Matches a Configuration implementation object with the pkg parameter.
* @param subConfigurations The collection of configuration to be searched for
* @param pkg the package prefix used to match the configuration.
* @return the configuration implementation object that matches the package,
* @{code null} otherwise.
*/
private ContainerConfiguration matchContainerConfiguration(Collection<ContainerConfiguration> containerConfigurations, String pkg)
private <T> T matchSubConfiguration(Collection<T> subConfigurations, String pkg)
{
log.fine("trying to match a container configuration for package: " + pkg);
// load all the containers configurations
log.fine("trying to match a configuration for package: " + pkg);

ContainerConfiguration containerConfig = null;

// select the container configuration that matches the package
for (ContainerConfiguration cc : containerConfigurations)
T subConfiguration = null;
// select the configuration that matches the package
for (T sc : subConfigurations)
{
if (cc.getClass().getName().startsWith(pkg))
if (sc.getClass().getName().startsWith(pkg))
{
containerConfig = cc;
subConfiguration = sc;
}
}

// warn: we didn't find the class
if (containerConfig == null)
if (subConfiguration == null)
{
log.warning("No container configuration found for URI: java:urn:" + pkg);
log.warning("No configuration found for URI: java:urn:" + pkg);
}

return containerConfig;
return subConfiguration;
}

/**
Expand Down
Expand Up @@ -23,6 +23,7 @@
import org.jboss.arquillian.spi.ConfigurationException;
import org.jboss.arquillian.spi.ContainerConfiguration;
import org.jboss.arquillian.spi.ContainerProfile;
import org.jboss.arquillian.spi.ExtensionConfiguration;
import org.jboss.arquillian.spi.ServiceLoader;
import org.junit.Assert;
import org.junit.Test;
Expand All @@ -32,6 +33,7 @@
*
* @author <a href="mailto:german.escobarc@gmail.com">German Escobar</a>
* @author <a href="mailto:aslak@redhat.com">Aslak Knutsen</a>
* @author <a href="mailto:kpiwko@redhat.com">Karel Piwko</a>
* @version $Revision: $
*/
public class XmlConfigurationBuilderTestCase
Expand All @@ -58,7 +60,7 @@ public void testNonExistingConfigurationFile() throws Exception
public void testValidConfigurationFile() throws Exception
{
// create a mock ServiceLoader that returns our MockContainerConfiguration
ServiceLoader serviceLoader = new MockServiceLoader();
ServiceLoader serviceLoader = new MockServiceLoader(new MockContainerConfiguration());

// build the configuration
ConfigurationBuilder builder = new XmlConfigurationBuilder("arquillian.xml", serviceLoader);
Expand Down Expand Up @@ -105,7 +107,7 @@ public void testLoadDefaultConfigurationOnMissingFile() throws Exception
{
Configuration configuration = new XmlConfigurationBuilder(
"missing_arquillian.xml",
new MockServiceLoader()).build();
new MockServiceLoader(new MockContainerConfiguration())).build();

ContainerConfiguration containerConfiguration = configuration.getActiveContainerConfiguration();
Assert.assertNotNull(containerConfiguration);
Expand All @@ -114,25 +116,65 @@ public void testLoadDefaultConfigurationOnMissingFile() throws Exception
Assert.assertNotNull(mockContainerConfiguration);
}

@Test
public void testMockExtensionConfiguration() throws Exception
{
// create a mock ServiceLoader that returns our MockContainerConfiguration
ServiceLoader serviceLoader = new MockServiceLoader(new MockExtensionConfiguration());

// build the configuration
ConfigurationBuilder builder = new XmlConfigurationBuilder("arquillian-extension.xml", serviceLoader);
Configuration configuration = builder.build();
Assert.assertNotNull(configuration);

MockExtensionConfiguration extensionConfig = configuration.getExtensionConfig(MockExtensionConfiguration.class);
Assert.assertNotNull(extensionConfig);

// check that the properties have the correct value
Assert.assertEquals("*superbrowser /usr/local/bin/superbrowser", extensionConfig.getBrowser());
Assert.assertEquals(8888, extensionConfig.getServerPort());
Assert.assertEquals("localhost", extensionConfig.getServerHost());
}

/**
* Mocks the ServiceLoader to return our MockContainerConfiguration
* Mocks the ServiceLoader to return configuration we want to test
*
* @author <a href="mailto:german.escobarc@gmail.com">German Escobar</a>
* @author <a href="mailto:kpiwko@redhat.com">Karel Piwko</a>
*/
class MockServiceLoader implements ServiceLoader
{
@SuppressWarnings("unchecked")
private Object instance;

/**
*
* @param instance
*/
public MockServiceLoader(Object instance) {
this.instance = instance;
}


@SuppressWarnings("unchecked")
public <T> Collection<T> all(Class<T> serviceClass)
{
return (Collection<T>) Collections.singleton(new MockContainerConfiguration());
if(serviceClass.isAssignableFrom(instance.getClass()))
{
return (Collection<T>) Collections.singleton(instance);
}

return Collections.emptyList();
}

@SuppressWarnings("unchecked")

@SuppressWarnings("unchecked")
public <T> T onlyOne(Class<T> serviceClass)
{
return (T) new MockContainerConfiguration();
if(serviceClass.isAssignableFrom(instance.getClass()))
{
return (T) instance;
}

return null;
}

/* (non-Javadoc)
Expand Down Expand Up @@ -244,5 +286,63 @@ public void setC(String c)
}

}

class MockExtensionConfiguration implements ExtensionConfiguration
{
private String browser;

private int serverPort;

private String serverHost;

/**
* @return the browser
*/
public String getBrowser()
{
return browser;
}

/**
* @param browser the browser to set
*/
public void setBrowser(String browser)
{
this.browser = browser;
}

/**
* @return the serverPort
*/
public int getServerPort()
{
return serverPort;
}

/**
* @param serverPort the serverPort to set
*/
public void setServerPort(int serverPort)
{
this.serverPort = serverPort;
}

/**
* @return the serverHost
*/
public String getServerHost()
{
return serverHost;
}

/**
* @param serverHost the serverHost to set
*/
public void setServerHost(String serverHost)
{
this.serverHost = serverHost;
}

}

}
16 changes: 16 additions & 0 deletions impl-base/src/test/resources/arquillian-extension.xml
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<arquillian xmlns="http://jboss.com/arquillian"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mock="urn:arq:org.jboss.arquillian.impl">

<engine>
<deploymentExportPath>/tmp/</deploymentExportPath>
</engine>

<mock:extension>
<mock:browser>*superbrowser /usr/local/bin/superbrowser</mock:browser>
<mock:serverPort>8888</mock:serverPort>
<mock:serverHost>localhost</mock:serverHost>
</mock:extension>

</arquillian>

0 comments on commit a6c3108

Please sign in to comment.