Skip to content

Commit

Permalink
Part I of tests for WELD-319 (parsing part)
Browse files Browse the repository at this point in the history
Delegate validation to Validator
Missing parser message
Typo in test JIRA reference
  • Loading branch information
nickarls committed Dec 10, 2009
1 parent 8752a6e commit 37a7946
Show file tree
Hide file tree
Showing 20 changed files with 290 additions and 37 deletions.
31 changes: 7 additions & 24 deletions impl/src/main/java/org/jboss/weld/xml/BeansXmlElement.java
Expand Up @@ -22,8 +22,6 @@
import java.util.ArrayList;
import java.util.List;

import org.jboss.weld.DeploymentException;
import org.jboss.weld.logging.messages.XmlMessage;
import org.jboss.weld.resources.spi.ResourceLoader;
import org.jboss.weld.resources.spi.ResourceLoadingException;
import org.jboss.weld.util.dom.NodeListIterable;
Expand All @@ -40,32 +38,12 @@ public class BeansXmlElement
{
private URL file;
private Element element;
private List<String> classNames;

private BeansXmlElement(URL file, Element element)
{
super();
this.file = file;
this.element = element;
classNames = new ArrayList<String>();
}

public BeansXmlElement validateWithMessage(XmlMessage multipleViolationMessage)
{
for (Node child : new NodeListIterable(element.getChildNodes()))
{
String className = getClassNameFromNode(child);
if (className == null)
{
continue;
}
if (classNames.contains(className))
{
throw new DeploymentException(multipleViolationMessage);
}
classNames.add(className);
}
return this;
}

private String getClassNameFromNode(Node node)
Expand All @@ -89,15 +67,20 @@ public static BeansXmlElement of(URL file, Node element)
public List<Class<?>> getClasses(ResourceLoader resourceLoader)
{
List<Class<?>> classes = new ArrayList<Class<?>>();
for (String className : classNames)
for (Node child : new NodeListIterable(element.getChildNodes()))
{
String className = getClassNameFromNode(child);
if (className == null)
{
continue;
}
try
{
classes.add(resourceLoader.classForName(className));
}
catch (ResourceLoadingException e)
{
throw new DeploymentException(CANNOT_LOAD_CLASS, className, file);
throw new WeldXmlException(CANNOT_LOAD_CLASS, className, file);
}
}
return classes;
Expand Down
9 changes: 6 additions & 3 deletions impl/src/main/java/org/jboss/weld/xml/BeansXmlParser.java
Expand Up @@ -30,7 +30,6 @@
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.jboss.weld.DeploymentException;
import org.jboss.weld.resources.spi.ResourceLoader;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
Expand Down Expand Up @@ -102,11 +101,11 @@ private Document getDocument(DocumentBuilder documentBuilder, URL beansXml)
}
catch (SAXException e)
{
throw new DeploymentException(PARSING_ERROR, e, beansXml.toString());
throw new WeldXmlException(PARSING_ERROR, e, beansXml.toString());
}
catch (IOException e)
{
throw new DeploymentException(LOAD_ERROR, e, beansXml.toString());
throw new WeldXmlException(LOAD_ERROR, e, beansXml.toString());
}
finally
{
Expand All @@ -133,6 +132,10 @@ private void closeStream(InputStream in)

private boolean isBeansXmlOK(URL beansXml)
{
if (beansXml == null)
{
throw new WeldXmlException(LOAD_ERROR, "null-URL");
}
InputStream in = null;
try
{
Expand Down
3 changes: 1 addition & 2 deletions impl/src/main/java/org/jboss/weld/xml/EnabledClasses.java
Expand Up @@ -19,7 +19,6 @@
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;

import org.jboss.weld.resources.spi.ResourceLoader;
Expand Down Expand Up @@ -73,7 +72,7 @@ private void processAlternatives(List<BeansXmlElement> alternativesElements)

private Collection<Class<?>> getClassesInElements(List<BeansXmlElement> elements)
{
LinkedHashSet<Class<?>> classes = new LinkedHashSet<Class<?>>();
List<Class<?>> classes = new ArrayList<Class<?>>();
for (BeansXmlElement element : elements)
{
classes.addAll(element.getClasses(resourceLoader));
Expand Down
7 changes: 2 additions & 5 deletions impl/src/main/java/org/jboss/weld/xml/MergedElements.java
Expand Up @@ -24,7 +24,6 @@
import java.util.ArrayList;
import java.util.List;

import org.jboss.weld.DeploymentException;
import org.jboss.weld.logging.messages.XmlMessage;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
Expand All @@ -50,19 +49,17 @@ public void merge(URL url, Document beansXmlDocument)
decoratorsElements.addAll(getNamedElement(url, documentElement, "decorators", MULTIPLE_DECORATORS));
}

// TODO: look over exception message when multiple blocks or multiple
// classes. Now they're the same.
private List<BeansXmlElement> getNamedElement(URL url, Element beans, String name, XmlMessage multipleViolationMessage)
{
List<BeansXmlElement> elements = new ArrayList<BeansXmlElement>();
NodeList nodeList = beans.getElementsByTagName(name);
if (nodeList.getLength() > 1)
{
throw new DeploymentException(multipleViolationMessage);
throw new WeldXmlException(multipleViolationMessage);
}
else if (nodeList.getLength() == 1)
{
BeansXmlElement element = BeansXmlElement.of(url, nodeList.item(0)).validateWithMessage(multipleViolationMessage);
BeansXmlElement element = BeansXmlElement.of(url, nodeList.item(0));
elements.add(element);
}
return elements;
Expand Down
@@ -1,6 +1,7 @@
CONFIGURATION_ERROR=Error configuring XML parser
LOAD_ERROR=Error loading {0}
LOAD_ERROR=Error loading beans.xml {0}
CANNOT_LOAD_CLASS=Could not load class {0}
PARSING_ERROR=Error parsing {0}
MULTIPLE_ALTERNATIVES=<alternatives> can only be specified once, but appears multiple times\: {0}
MULTIPLE_DECORATORS=<decorator> can only be specified once, but is specified multiple times\: {0}
MULTIPLE_DECORATORS=<decorators> can only be specified once, but is specified multiple times\: {0}
MULTIPLE_INTERCEPTORS=<interceptor> can only be specified once, but it is specified multiple times\: {0}
Expand Up @@ -21,7 +21,7 @@ public void testSFSBWithOnlyRemoteInterfacesDeploys()

}

@Test(description="WBRI-326")
@Test(description="WELD-326")
public void testInvocationExceptionIsUnwrapped()
{
try
Expand Down
@@ -0,0 +1,9 @@
package org.jboss.weld.tests.unit.bootstrap.xml;

import javax.enterprise.inject.Alternative;

@Alternative
public class Alt
{

}
@@ -0,0 +1,169 @@
package org.jboss.weld.tests.unit.bootstrap.xml;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import org.jboss.weld.logging.messages.XmlMessage;
import org.jboss.weld.mock.MockEELifecycle;
import org.jboss.weld.mock.TestContainer;
import org.jboss.weld.xml.WeldXmlException;
import org.testng.annotations.Test;

@SuppressWarnings("unchecked")
public class BeansXmlTest
{
private class FailedDeployment
{
private List<Class<?>> beans = Collections.emptyList();
private List<URL> beansXml = Collections.emptyList();

public FailedDeployment(List<Class<?>> beans, List<URL> beansXml)
{
this.beans = beans;
this.beansXml = beansXml;
}

public void run()
{
TestContainer container = null;
try
{
container = new TestContainer(new MockEELifecycle(), beans, beansXml).startContainer().ensureRequestActive();
}
finally
{
if (container != null)
{
container.stopContainer();
}
}
}

public void runAndExpect(WeldXmlException expected)
{
String errorCode = expected.getMessage().substring(0, 12);
try
{
run();
}
catch (WeldXmlException e)
{
if (e.getMessage().startsWith(errorCode))
{
return;
}
}
assert false;
}

}

private void testWithBeansXmlAndExpectException(String beansXml, WeldXmlException e)
{
List<Class<?>> beans = Arrays.asList(Alt.class, Dec.class, Int.class, Plain.class, IntBind.class);
List<URL> beansXmls = Arrays.asList(getClass().getResource(beansXml));
new FailedDeployment(beans, beansXmls).runAndExpect(e);
}

// Multiple XML blocks

@Test
public void multipleAlternativeBlocksFail()
{
testWithBeansXmlAndExpectException("multipleAlternativeBlocks.xml", new WeldXmlException(XmlMessage.MULTIPLE_ALTERNATIVES));
}

@Test
public void multipleDecoratorBlocksFail()
{
testWithBeansXmlAndExpectException("multipleDecoratorBlocks.xml", new WeldXmlException(XmlMessage.MULTIPLE_DECORATORS));
}

@Test
public void multipleInterceptorBlocksFail()
{
testWithBeansXmlAndExpectException("multipleInterceptorsBlocks.xml", new WeldXmlException(XmlMessage.MULTIPLE_INTERCEPTORS));
}

@Test
public void alternativesEnabled()
{
List<Class<?>> beans = Arrays.asList(Alt.class, Dec.class, Int.class, IntBind.class, Plain.class);
List<URL> beansXmls = Arrays.asList(getClass().getResource("alternative.xml"));
TestContainer container = new TestContainer(new MockEELifecycle(), beans, beansXmls).startContainer().ensureRequestActive();
assert container.getBeanManager().getEnabledAlternativeClasses().size() == 1;
assert container.getBeanManager().getEnabledAlternativeClasses().iterator().next() == Alt.class;
container.stopContainer();
}

@Test
public void decoratorsEnabled()
{
List<Class<?>> beans = Arrays.asList(Alt.class, Dec.class, Int.class, IntBind.class, Plain.class);
List<URL> beansXmls = Arrays.asList(getClass().getResource("decorator.xml"));
TestContainer container = new TestContainer(new MockEELifecycle(), beans, beansXmls).startContainer().ensureRequestActive();
assert container.getBeanManager().getEnabledDecoratorClasses().size() == 1;
assert container.getBeanManager().getEnabledDecoratorClasses().iterator().next() == Dec.class;
container.stopContainer();
}

@Test
public void interceptorsEnabled()
{
List<Class<?>> beans = Arrays.asList(Alt.class, Dec.class, Int.class, IntBind.class, Plain.class);
List<URL> beansXmls = Arrays.asList(getClass().getResource("interceptor.xml"));
TestContainer container = new TestContainer(new MockEELifecycle(), beans, beansXmls).startContainer().ensureRequestActive();
assert container.getBeanManager().getEnabledInterceptorClasses().size() == 1;
assert container.getBeanManager().getEnabledInterceptorClasses().iterator().next() == Int.class;
container.stopContainer();
}

@Test
public void testMergeBeansXmls()
{
List<Class<?>> beans = Arrays.asList(Alt.class, Dec.class, Int.class, IntBind.class, Plain.class);
List<URL> beansXmls = Arrays.asList(getClass().getResource("alternative.xml"), getClass().getResource("decorator.xml"), getClass().getResource("interceptor.xml"));
TestContainer container = new TestContainer(new MockEELifecycle(), beans, beansXmls).startContainer().ensureRequestActive();
assert container.getBeanManager().getEnabledAlternativeClasses().size() == 1;
assert container.getBeanManager().getEnabledAlternativeClasses().iterator().next() == Alt.class;
assert container.getBeanManager().getEnabledInterceptorClasses().size() == 1;
assert container.getBeanManager().getEnabledInterceptorClasses().iterator().next() == Int.class;
assert container.getBeanManager().getEnabledDecoratorClasses().size() == 1;
assert container.getBeanManager().getEnabledDecoratorClasses().iterator().next() == Dec.class;
container.stopContainer();
}

@Test
public void testBeansXmlDoesntExist()
{
testWithBeansXmlAndExpectException("nope.xml", new WeldXmlException(XmlMessage.LOAD_ERROR));
}

@Test(groups="stub")
public void testCannotGetDocumentBuilder()
{
}

@Test
public void testCannotLoadFile() throws MalformedURLException
{
List<Class<?>> beans = Collections.emptyList();
new FailedDeployment(beans, Arrays.asList(new URL("http://foo.bar/beans.xml"))).runAndExpect(new WeldXmlException(XmlMessage.LOAD_ERROR));
}

@Test
public void testParsingError()
{
testWithBeansXmlAndExpectException("unparseable.xml", new WeldXmlException(XmlMessage.PARSING_ERROR));
}

@Test
public void testCannotLoadClass()
{
testWithBeansXmlAndExpectException("unloadable.xml", new WeldXmlException(XmlMessage.CANNOT_LOAD_CLASS));
}

}
@@ -0,0 +1,11 @@
package org.jboss.weld.tests.unit.bootstrap.xml;

import javax.decorator.Decorator;
import javax.decorator.Delegate;
import javax.inject.Inject;

@Decorator
public class Dec
{
@Inject @Delegate Plain plain;
}
@@ -0,0 +1,10 @@
package org.jboss.weld.tests.unit.bootstrap.xml;

import javax.interceptor.Interceptor;

@Interceptor
@IntBind
public class Int
{

}
@@ -0,0 +1,16 @@
package org.jboss.weld.tests.unit.bootstrap.xml;

import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
import javax.interceptor.InterceptorBinding;

@InterceptorBinding
@Inherited
@Target( { TYPE, METHOD })
@Retention(RUNTIME)
public @interface IntBind
{
}
@@ -0,0 +1,6 @@
package org.jboss.weld.tests.unit.bootstrap.xml;

public class Plain
{

}
@@ -0,0 +1,5 @@
<beans>
<alternatives>
<class>org.jboss.weld.tests.unit.bootstrap.xml.Alt</class>
</alternatives>
</beans>

0 comments on commit 37a7946

Please sign in to comment.