Browse Source

Merge pull request #153 from gid79/SPR-9812

* SPR-9812:
  Allow 'arg-type' matches against element body
  Polish whitespace
pull/165/merge
Phillip Webb 14 years ago
parent
commit
e4158f91a4
  1. 6
      spring-beans/src/main/java/org/springframework/beans/factory/xml/BeanDefinitionParserDelegate.java
  2. 61
      spring-context/src/test/java/org/springframework/beans/factory/xml/XmlBeanFactoryTestTypes.java
  3. 48
      spring-context/src/test/java/org/springframework/beans/factory/xml/XmlBeanFactoryTests-delegationOverrides.xml
  4. 26
      spring-context/src/test/java/org/springframework/beans/factory/xml/XmlBeanFactoryTests.java

6
spring-beans/src/main/java/org/springframework/beans/factory/xml/BeanDefinitionParserDelegate.java

@ -827,7 +827,11 @@ public class BeanDefinitionParserDelegate {
// Look for arg-type match elements. // Look for arg-type match elements.
List<Element> argTypeEles = DomUtils.getChildElementsByTagName(replacedMethodEle, ARG_TYPE_ELEMENT); List<Element> argTypeEles = DomUtils.getChildElementsByTagName(replacedMethodEle, ARG_TYPE_ELEMENT);
for (Element argTypeEle : argTypeEles) { for (Element argTypeEle : argTypeEles) {
replaceOverride.addTypeIdentifier(argTypeEle.getAttribute(ARG_TYPE_MATCH_ATTRIBUTE)); String match = argTypeEle.getAttribute(ARG_TYPE_MATCH_ATTRIBUTE);
match = (StringUtils.hasText(match) ? match : DomUtils.getTextValue(argTypeEle));
if (StringUtils.hasText(match)) {
replaceOverride.addTypeIdentifier(match);
}
} }
replaceOverride.setSource(extractSource(replacedMethodEle)); replaceOverride.setSource(extractSource(replacedMethodEle));
overrides.addOverride(replaceOverride); overrides.addOverride(replaceOverride);

61
spring-context/src/test/java/org/springframework/beans/factory/xml/XmlBeanFactoryTestTypes.java

@ -1,12 +1,12 @@
/* /*
* Copyright 2002-2009 the original author or authors. * Copyright 2002-2012 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -41,7 +41,7 @@ import org.springframework.beans.factory.support.MethodReplacer;
/** /**
* Types used by {@link XmlBeanFactoryTests} and its attendant XML config files. * Types used by {@link XmlBeanFactoryTests} and its attendant XML config files.
* *
* @author Chris Beams * @author Chris Beams
*/ */
final class XmlBeanFactoryTestTypes { } final class XmlBeanFactoryTestTypes { }
@ -161,20 +161,20 @@ class SimpleConstructorArgBean {
* @author Rod Johnson * @author Rod Johnson
*/ */
abstract class ConstructorInjectedOverrides { abstract class ConstructorInjectedOverrides {
private ITestBean tb; private ITestBean tb;
private String setterString; private String setterString;
public ConstructorInjectedOverrides(ITestBean tb) { public ConstructorInjectedOverrides(ITestBean tb) {
this.tb = tb; this.tb = tb;
} }
public ITestBean getTestBean() { public ITestBean getTestBean() {
return this.tb; return this.tb;
} }
protected abstract FactoryMethods createFactoryMethods(); protected abstract FactoryMethods createFactoryMethods();
/** /**
@ -234,7 +234,7 @@ class DerivedConstructorDependenciesBean extends ConstructorDependenciesBean {
/** /**
* *
* @author Rod Johnson * @author Rod Johnson
*/ */
interface DummyBo { interface DummyBo {
@ -245,19 +245,19 @@ interface DummyBo {
/** /**
* *
* @author Rod Johnson * @author Rod Johnson
*/ */
class DummyBoImpl implements DummyBo { class DummyBoImpl implements DummyBo {
DummyDao dao; DummyDao dao;
public DummyBoImpl(DummyDao dao) { public DummyBoImpl(DummyDao dao) {
this.dao = dao; this.dao = dao;
} }
public void something() { public void something() {
} }
} }
@ -267,7 +267,7 @@ class DummyBoImpl implements DummyBo {
* @author Rod Johnson * @author Rod Johnson
*/ */
class DummyDao { class DummyDao {
DataSource ds; DataSource ds;
public DummyDao(DataSource ds) { public DummyDao(DataSource ds) {
@ -332,7 +332,7 @@ class DummyReferencer {
* @author Juergen Hoeller * @author Juergen Hoeller
*/ */
class FactoryMethods { class FactoryMethods {
public static FactoryMethods nullInstance() { public static FactoryMethods nullInstance() {
return null; return null;
} }
@ -342,21 +342,21 @@ class FactoryMethods {
tb.setName("defaultInstance"); tb.setName("defaultInstance");
return new FactoryMethods(tb, "default", 0); return new FactoryMethods(tb, "default", 0);
} }
/** /**
* Note that overloaded methods are supported. * Note that overloaded methods are supported.
*/ */
public static FactoryMethods newInstance(TestBean tb) { public static FactoryMethods newInstance(TestBean tb) {
return new FactoryMethods(tb, "default", 0); return new FactoryMethods(tb, "default", 0);
} }
protected static FactoryMethods newInstance(TestBean tb, int num, String name) { protected static FactoryMethods newInstance(TestBean tb, int num, String name) {
if (name == null) { if (name == null) {
throw new IllegalStateException("Should never be called with null value"); throw new IllegalStateException("Should never be called with null value");
} }
return new FactoryMethods(tb, name, num); return new FactoryMethods(tb, name, num);
} }
static FactoryMethods newInstance(TestBean tb, int num, Integer something) { static FactoryMethods newInstance(TestBean tb, int num, Integer something) {
if (something != null) { if (something != null) {
throw new IllegalStateException("Should never be called with non-null value"); throw new IllegalStateException("Should never be called with non-null value");
@ -384,35 +384,35 @@ class FactoryMethods {
this.name = name; this.name = name;
this.num = num; this.num = num;
} }
public void setStringValue(String stringValue) { public void setStringValue(String stringValue) {
this.stringValue = stringValue; this.stringValue = stringValue;
} }
public String getStringValue() { public String getStringValue() {
return this.stringValue; return this.stringValue;
} }
public TestBean getTestBean() { public TestBean getTestBean() {
return this.tb; return this.tb;
} }
protected TestBean protectedGetTestBean() { protected TestBean protectedGetTestBean() {
return this.tb; return this.tb;
} }
private TestBean privateGetTestBean() { private TestBean privateGetTestBean() {
return this.tb; return this.tb;
} }
public int getNum() { public int getNum() {
return num; return num;
} }
public String getName() { public String getName() {
return name; return name;
} }
/** /**
* Set via Setter Injection once instance is created. * Set via Setter Injection once instance is created.
*/ */
@ -540,6 +540,9 @@ abstract class OverrideOneMethod extends MethodReplaceCandidate implements Overr
return "replaceMe:" + someParam; return "replaceMe:" + someParam;
} }
public String replaceMe(String someParam) {
return "replaceMe:" + someParam;
}
} }
@ -550,7 +553,7 @@ abstract class OverrideOneMethod extends MethodReplaceCandidate implements Overr
* @author Rod Johnson * @author Rod Johnson
*/ */
abstract class OverrideOneMethodSubclass extends OverrideOneMethod { abstract class OverrideOneMethodSubclass extends OverrideOneMethod {
protected void doSomething(String arg) { protected void doSomething(String arg) {
// This implementation does nothing! // This implementation does nothing!
// It's not overloaded // It's not overloaded

48
spring-context/src/test/java/org/springframework/beans/factory/xml/XmlBeanFactoryTests-delegationOverrides.xml

@ -1,22 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd"> <beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<beans> <!--
<!--
Not yet in use: illustration of possible approach Not yet in use: illustration of possible approach
--> -->
<bean id="overrideOneMethod" class="org.springframework.beans.factory.xml.OverrideOneMethod"> <bean id="overrideOneMethod" class="org.springframework.beans.factory.xml.OverrideOneMethod">
<lookup-method name="getPrototypeDependency" bean="jenny"/> <lookup-method name="getPrototypeDependency" bean="jenny"/>
<lookup-method name="protectedOverrideSingleton" bean="david"/> <lookup-method name="protectedOverrideSingleton" bean="david"/>
<!-- Arbitrary method replacer --> <!-- Arbitrary method replacer -->
<replaced-method name="replaceMe" replacer="reverseReplacer"> <replaced-method name="replaceMe" replacer="reverseReplacer">
<arg-type>String</arg-type> <arg-type>String</arg-type>
</replaced-method> </replaced-method>
<replaced-method name="replaceMe" replacer="fixedReplacer"/> <replaced-method name="replaceMe" replacer="fixedReplacer"/>
</bean> </bean>
@ -39,25 +39,25 @@
</bean> </bean>
<bean id="reverseReplacer" <bean id="reverseReplacer"
class="org.springframework.beans.factory.xml.ReverseMethodReplacer"/> class="org.springframework.beans.factory.xml.ReverseMethodReplacer"/>
<bean id="fixedReplacer" <bean id="fixedReplacer"
class="org.springframework.beans.factory.xml.FixedMethodReplacer"/> class="org.springframework.beans.factory.xml.FixedMethodReplacer"/>
<bean id="doSomethingReplacer" <bean id="doSomethingReplacer"
class="org.springframework.beans.factory.xml.XmlBeanFactoryTests$DoSomethingReplacer"/> class="org.springframework.beans.factory.xml.XmlBeanFactoryTests$DoSomethingReplacer"/>
<bean id="serializableReplacer" <bean id="serializableReplacer"
class="org.springframework.beans.factory.xml.SerializableMethodReplacerCandidate"> class="org.springframework.beans.factory.xml.SerializableMethodReplacerCandidate">
<!-- Arbitrary method replacer --> <!-- Arbitrary method replacer -->
<replaced-method name="replaceMe" replacer="reverseReplacer"> <replaced-method name="replaceMe" replacer="reverseReplacer">
<arg-type>String</arg-type> <arg-type>String</arg-type>
</replaced-method> </replaced-method>
</bean> </bean>
<bean id="jenny" class="org.springframework.beans.TestBean" <bean id="jenny" class="org.springframework.beans.TestBean"
scope="prototype"> scope="prototype">
<property name="name"><value>Jenny</value></property> <property name="name"><value>Jenny</value></property>
@ -67,7 +67,7 @@
<ref local="david"/> <ref local="david"/>
</property> </property>
</bean> </bean>
<bean id="david" class="org.springframework.beans.TestBean" <bean id="david" class="org.springframework.beans.TestBean"
scope="singleton"> scope="singleton">
<description> <description>
@ -80,4 +80,16 @@
<property name="age"><value>27</value></property> <property name="age"><value>27</value></property>
</bean> </bean>
<bean id="overrideOneMethodByAttribute" class="org.springframework.beans.factory.xml.OverrideOneMethod">
<replaced-method name="replaceMe" replacer="reverseReplacer">
<arg-type match="String"/>
</replaced-method>
</bean>
<bean id="overrideOneMethodByElement" class="org.springframework.beans.factory.xml.OverrideOneMethod">
<replaced-method name="replaceMe" replacer="reverseReplacer">
<arg-type>String</arg-type>
</replaced-method>
</bean>
</beans> </beans>

26
spring-context/src/test/java/org/springframework/beans/factory/xml/XmlBeanFactoryTests.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2009 the original author or authors. * Copyright 2002-2012 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -83,10 +83,10 @@ import org.xml.sax.InputSource;
* @author Chris Beams * @author Chris Beams
*/ */
public final class XmlBeanFactoryTests { public final class XmlBeanFactoryTests {
private static final Class<?> CLASS = XmlBeanFactoryTests.class; private static final Class<?> CLASS = XmlBeanFactoryTests.class;
private static final String CLASSNAME = CLASS.getSimpleName(); private static final String CLASSNAME = CLASS.getSimpleName();
private static final ClassPathResource AUTOWIRE_CONTEXT = classPathResource("-autowire.xml"); private static final ClassPathResource AUTOWIRE_CONTEXT = classPathResource("-autowire.xml");
private static final ClassPathResource CHILD_CONTEXT = classPathResource("-child.xml"); private static final ClassPathResource CHILD_CONTEXT = classPathResource("-child.xml");
private static final ClassPathResource CLASS_NOT_FOUND_CONTEXT = classPathResource("-classNotFound.xml"); private static final ClassPathResource CLASS_NOT_FOUND_CONTEXT = classPathResource("-classNotFound.xml");
@ -128,7 +128,7 @@ public final class XmlBeanFactoryTests {
private static final ClassPathResource REFTYPES_CONTEXT = classPathResource("-reftypes.xml"); private static final ClassPathResource REFTYPES_CONTEXT = classPathResource("-reftypes.xml");
private static final ClassPathResource DEFAULT_LAZY_CONTEXT = classPathResource("-defaultLazyInit.xml"); private static final ClassPathResource DEFAULT_LAZY_CONTEXT = classPathResource("-defaultLazyInit.xml");
private static final ClassPathResource DEFAULT_AUTOWIRE_CONTEXT = classPathResource("-defaultAutowire.xml"); private static final ClassPathResource DEFAULT_AUTOWIRE_CONTEXT = classPathResource("-defaultAutowire.xml");
private static ClassPathResource classPathResource(String suffix) { private static ClassPathResource classPathResource(String suffix) {
return new ClassPathResource(CLASSNAME + suffix, CLASS); return new ClassPathResource(CLASSNAME + suffix, CLASS);
} }
@ -1489,6 +1489,24 @@ public final class XmlBeanFactoryTests {
} }
} }
public @Test void testOverrideMethodByArgTypeAttribute() {
DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(xbf);
reader.loadBeanDefinitions(DELEGATION_OVERRIDES_CONTEXT);
OverrideOneMethod oom = (OverrideOneMethod) xbf.getBean("overrideOneMethodByAttribute");
assertEquals("should not replace", "replaceMe:1", oom.replaceMe(1));
assertEquals("should replace", "cba", oom.replaceMe("abc"));
}
public @Test void testOverrideMethodByArgTypeElement() {
DefaultListableBeanFactory xbf = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(xbf);
reader.loadBeanDefinitions(DELEGATION_OVERRIDES_CONTEXT);
OverrideOneMethod oom = (OverrideOneMethod) xbf.getBean("overrideOneMethodByElement");
assertEquals("should not replace", "replaceMe:1", oom.replaceMe(1));
assertEquals("should replace", "cba", oom.replaceMe("abc"));
}
public static class DoSomethingReplacer implements MethodReplacer { public static class DoSomethingReplacer implements MethodReplacer {
public Object lastArg; public Object lastArg;

Loading…
Cancel
Save