Browse Source
+ improved example to work with multi-nested declarations + used JDK 5 syntax + added documentation code into trunk (including unit test) for easier future referencepull/23217/head
10 changed files with 266 additions and 25 deletions
@ -0,0 +1,26 @@
@@ -0,0 +1,26 @@
|
||||
package com.foo; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
public class Component { |
||||
private String name; |
||||
private List<Component> components = new ArrayList<Component>(); |
||||
|
||||
// mmm, there is no setter method for the 'components'
|
||||
public void addComponent(Component component) { |
||||
this.components.add(component); |
||||
} |
||||
|
||||
public List<Component> getComponents() { |
||||
return components; |
||||
} |
||||
|
||||
public String getName() { |
||||
return name; |
||||
} |
||||
|
||||
public void setName(String name) { |
||||
this.name = name; |
||||
} |
||||
} |
||||
@ -0,0 +1,52 @@
@@ -0,0 +1,52 @@
|
||||
package com.foo; |
||||
|
||||
import java.util.List; |
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition; |
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition; |
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder; |
||||
import org.springframework.beans.factory.support.ManagedList; |
||||
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser; |
||||
import org.springframework.beans.factory.xml.ParserContext; |
||||
import org.springframework.util.xml.DomUtils; |
||||
import org.w3c.dom.Element; |
||||
|
||||
public class ComponentBeanDefinitionParser extends AbstractBeanDefinitionParser { |
||||
|
||||
protected AbstractBeanDefinition parseInternal(Element element, |
||||
ParserContext parserContext) { |
||||
return parseComponentElement(element); |
||||
} |
||||
|
||||
private static AbstractBeanDefinition parseComponentElement(Element element) { |
||||
BeanDefinitionBuilder factory = BeanDefinitionBuilder |
||||
.rootBeanDefinition(ComponentFactoryBean.class); |
||||
|
||||
factory.addPropertyValue("parent", parseComponent(element)); |
||||
|
||||
List<Element> childElements = DomUtils.getChildElementsByTagName( |
||||
element, "component"); |
||||
if (childElements != null && childElements.size() > 0) { |
||||
parseChildComponents(childElements, factory); |
||||
} |
||||
|
||||
return factory.getBeanDefinition(); |
||||
} |
||||
|
||||
private static BeanDefinition parseComponent(Element element) { |
||||
BeanDefinitionBuilder component = BeanDefinitionBuilder |
||||
.rootBeanDefinition(Component.class); |
||||
component.addPropertyValue("name", element.getAttribute("name")); |
||||
return component.getBeanDefinition(); |
||||
} |
||||
|
||||
private static void parseChildComponents(List<Element> childElements, |
||||
BeanDefinitionBuilder factory) { |
||||
ManagedList<BeanDefinition> children = new ManagedList<BeanDefinition>( |
||||
childElements.size()); |
||||
for (Element element : childElements) { |
||||
children.add(parseComponentElement(element)); |
||||
} |
||||
factory.addPropertyValue("children", children); |
||||
} |
||||
} |
||||
@ -0,0 +1,74 @@
@@ -0,0 +1,74 @@
|
||||
/* |
||||
* Copyright 2006-2010 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package com.foo; |
||||
|
||||
import java.util.List; |
||||
|
||||
import org.junit.AfterClass; |
||||
import org.junit.BeforeClass; |
||||
import org.junit.Test; |
||||
import org.springframework.beans.factory.xml.XmlBeanFactory; |
||||
import org.springframework.core.io.ClassPathResource; |
||||
|
||||
import static org.junit.Assert.*; |
||||
import static org.hamcrest.CoreMatchers.*; |
||||
|
||||
/** |
||||
* @author Costin Leau |
||||
*/ |
||||
public class ComponentBeanDefinitionParserTest { |
||||
|
||||
private static XmlBeanFactory bf; |
||||
|
||||
@BeforeClass |
||||
public static void setUpBeforeClass() throws Exception { |
||||
bf = new XmlBeanFactory(new ClassPathResource( |
||||
"com/foo/component-config.xml")); |
||||
} |
||||
|
||||
@AfterClass |
||||
public static void tearDownAfterClass() throws Exception { |
||||
bf.destroySingletons(); |
||||
} |
||||
|
||||
private Component getBionicFamily() { |
||||
return bf.getBean("bionic-family", Component.class); |
||||
} |
||||
|
||||
@Test |
||||
public void testBionicBasic() throws Exception { |
||||
Component cp = getBionicFamily(); |
||||
assertThat("Bionic-1", equalTo(cp.getName())); |
||||
} |
||||
|
||||
@Test |
||||
public void testBionicFirstLevelChildren() throws Exception { |
||||
Component cp = getBionicFamily(); |
||||
List<Component> components = cp.getComponents(); |
||||
assertThat(2, equalTo(components.size())); |
||||
assertThat("Mother-1", equalTo(components.get(0).getName())); |
||||
assertThat("Rock-1", equalTo(components.get(1).getName())); |
||||
} |
||||
|
||||
@Test |
||||
public void testBionicSecondLevenChildren() throws Exception { |
||||
Component cp = getBionicFamily(); |
||||
List<Component> components = cp.getComponents().get(0).getComponents(); |
||||
assertThat(2, equalTo(components.size())); |
||||
assertThat("Karate-1", equalTo(components.get(0).getName())); |
||||
assertThat("Sport-1", equalTo(components.get(1).getName())); |
||||
} |
||||
} |
||||
@ -0,0 +1,35 @@
@@ -0,0 +1,35 @@
|
||||
package com.foo; |
||||
|
||||
import java.util.List; |
||||
|
||||
import org.springframework.beans.factory.FactoryBean; |
||||
|
||||
public class ComponentFactoryBean implements FactoryBean<Component> { |
||||
private Component parent; |
||||
private List<Component> children; |
||||
|
||||
public void setParent(Component parent) { |
||||
this.parent = parent; |
||||
} |
||||
|
||||
public void setChildren(List<Component> children) { |
||||
this.children = children; |
||||
} |
||||
|
||||
public Component getObject() throws Exception { |
||||
if (this.children != null && this.children.size() > 0) { |
||||
for (Component child : children) { |
||||
this.parent.addComponent(child); |
||||
} |
||||
} |
||||
return this.parent; |
||||
} |
||||
|
||||
public Class<Component> getObjectType() { |
||||
return Component.class; |
||||
} |
||||
|
||||
public boolean isSingleton() { |
||||
return true; |
||||
} |
||||
} |
||||
@ -0,0 +1,10 @@
@@ -0,0 +1,10 @@
|
||||
package com.foo; |
||||
|
||||
import org.springframework.beans.factory.xml.NamespaceHandlerSupport; |
||||
|
||||
public class ComponentNamespaceHandler extends NamespaceHandlerSupport { |
||||
public void init() { |
||||
registerBeanDefinitionParser("component", |
||||
new ComponentBeanDefinitionParser()); |
||||
} |
||||
} |
||||
@ -0,0 +1 @@
@@ -0,0 +1 @@
|
||||
http\://www.foo.com/schema/component=com.foo.ComponentNamespaceHandler |
||||
@ -0,0 +1 @@
@@ -0,0 +1 @@
|
||||
http\://www.foo.com/schema/component/component.xsd=com/foo/component.xsd |
||||
@ -0,0 +1,17 @@
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<beans xmlns="http://www.springframework.org/schema/beans" |
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
xmlns:foo="http://www.foo.com/schema/component" |
||||
xsi:schemaLocation=" |
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd |
||||
http://www.foo.com/schema/component http://www.foo.com/schema/component/component.xsd"> |
||||
|
||||
<foo:component id="bionic-family" name="Bionic-1"> |
||||
<foo:component name="Mother-1"> |
||||
<foo:component name="Karate-1"/> |
||||
<foo:component name="Sport-1"/> |
||||
</foo:component> |
||||
<foo:component name="Rock-1"/> |
||||
</foo:component> |
||||
|
||||
</beans> |
||||
@ -0,0 +1,19 @@
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?> |
||||
|
||||
<xsd:schema xmlns="http://www.foo.com/schema/component" |
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema" |
||||
targetNamespace="http://www.foo.com/schema/component" |
||||
elementFormDefault="qualified" |
||||
attributeFormDefault="unqualified"> |
||||
|
||||
<xsd:element name="component"> |
||||
<xsd:complexType> |
||||
<xsd:choice minOccurs="0" maxOccurs="unbounded"> |
||||
<xsd:element ref="component"/> |
||||
</xsd:choice> |
||||
<xsd:attribute name="id" type="xsd:ID"/> |
||||
<xsd:attribute name="name" use="required" type="xsd:string"/> |
||||
</xsd:complexType> |
||||
</xsd:element> |
||||
|
||||
</xsd:schema> |
||||
Loading…
Reference in new issue