diff --git a/spring-batch-core/pom.xml b/spring-batch-core/pom.xml
index f0cef18cb..cb201d82e 100644
--- a/spring-batch-core/pom.xml
+++ b/spring-batch-core/pom.xml
@@ -310,6 +310,7 @@
org.codehaus.mojo
emma-maven-plugin
+ 1.0-alpha-1
diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/scope/util/PlaceholderTargetSource.java b/spring-batch-core/src/main/java/org/springframework/batch/core/scope/util/PlaceholderTargetSource.java
index 7373d58bb..28092993d 100644
--- a/spring-batch-core/src/main/java/org/springframework/batch/core/scope/util/PlaceholderTargetSource.java
+++ b/spring-batch-core/src/main/java/org/springframework/batch/core/scope/util/PlaceholderTargetSource.java
@@ -15,11 +15,15 @@
*/
package org.springframework.batch.core.scope.util;
+import java.beans.PropertyEditor;
+import java.util.Date;
+
import org.springframework.aop.TargetSource;
import org.springframework.aop.target.SimpleBeanTargetSource;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.beans.BeansException;
+import org.springframework.beans.PropertyEditorRegistrySupport;
import org.springframework.beans.TypeConverter;
import org.springframework.beans.TypeMismatchException;
import org.springframework.beans.factory.InitializingBean;
@@ -93,7 +97,7 @@ public class PlaceholderTargetSource extends SimpleBeanTargetSource implements I
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(listableBeanFactory);
beanFactory.copyConfigurationFrom(listableBeanFactory);
- beanFactory.setTypeConverter(new TypeConverter() {
+ final TypeConverter contextTypeConverter = new TypeConverter() {
@SuppressWarnings("unchecked")
public Object convertIfNecessary(Object value, Class requiredType, MethodParameter methodParam)
throws TypeMismatchException {
@@ -105,6 +109,39 @@ public class PlaceholderTargetSource extends SimpleBeanTargetSource implements I
result = convertFromContext(key, requiredType);
}
}
+ else if (requiredType.isAssignableFrom(value.getClass())) {
+ result = value;
+ }
+ else if (requiredType.isAssignableFrom(String.class)) {
+ if (typeConverter instanceof PropertyEditorRegistrySupport) {
+ /*
+ * PropertyEditorRegistrySupport is de rigeur with
+ * TypeConverter instances used internally by Spring. If
+ * we have one of those then we can convert to String
+ * but the TypeConverter doesn't know how to.
+ */
+ PropertyEditorRegistrySupport registry = (PropertyEditorRegistrySupport) typeConverter;
+ PropertyEditor editor = registry.findCustomEditor(value.getClass(), null);
+ if (editor != null) {
+ if (registry.isSharedEditor(editor)) {
+ // Synchronized access to shared editor
+ // instance.
+ synchronized (editor) {
+ editor.setValue(value);
+ result = editor.getAsText();
+ }
+ }
+ else {
+ editor.setValue(value);
+ result = editor.getAsText();
+ }
+ }
+ }
+ if (result == null) {
+ logger.debug("Falling back on toString for conversion of : [" + value.getClass() + "]");
+ result = value.toString();
+ }
+ }
return result != null ? result : typeConverter.convertIfNecessary(value, requiredType, methodParam);
}
@@ -112,7 +149,8 @@ public class PlaceholderTargetSource extends SimpleBeanTargetSource implements I
public Object convertIfNecessary(Object value, Class requiredType) throws TypeMismatchException {
return convertIfNecessary(value, requiredType, null);
}
- });
+ };
+ beanFactory.setTypeConverter(contextTypeConverter);
String beanName = getTargetBeanName() + "#" + contextFactory.getContextId();
@@ -133,7 +171,16 @@ public class PlaceholderTargetSource extends SimpleBeanTargetSource implements I
if (!strVal.contains(PLACEHOLDER_PREFIX)) {
return strVal;
}
- return replacePlaceholders(strVal, typeConverter);
+ if (strVal.startsWith(PLACEHOLDER_PREFIX) && strVal.endsWith(PLACEHOLDER_SUFFIX)) {
+ // If the whole value is a placeholder it might be
+ // possible to replace it all in one go as a String
+ // (e.g. if it's a ref=#{})
+ StringBuilder result = new StringBuilder(strVal);
+ String key = extractKey(strVal);
+ replaceIfTypeMatches(result, 0, strVal.length() - 1, key, String.class, typeConverter);
+ return result.toString();
+ }
+ return replacePlaceholders(strVal, contextTypeConverter);
}
}) {
protected Object resolveValue(Object value) {
@@ -216,10 +263,9 @@ public class PlaceholderTargetSource extends SimpleBeanTargetSource implements I
replaceIfTypeMatches(result, first, next, key, Integer.class, typeConverter);
// Spring cannot convert from String to Date, so there is an error
// here.
- // replaceIfTypeMatches(result, first, next, key, Date.class,
- // typeConverter);
- first = result.indexOf(PLACEHOLDER_PREFIX, first + 1);;
- next = result.indexOf(PLACEHOLDER_SUFFIX, first + 1);;
+ replaceIfTypeMatches(result, first, next, key, Date.class, typeConverter);
+ first = result.indexOf(PLACEHOLDER_PREFIX, first + 1);
+ next = result.indexOf(PLACEHOLDER_SUFFIX, first + 1);
}
diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/scope/util/PlaceholderTargetSourceTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/scope/util/PlaceholderTargetSourceTests.java
index 84702280b..afcd8389e 100644
--- a/spring-batch-core/src/test/java/org/springframework/batch/core/scope/util/PlaceholderTargetSourceTests.java
+++ b/spring-batch-core/src/test/java/org/springframework/batch/core/scope/util/PlaceholderTargetSourceTests.java
@@ -38,6 +38,10 @@ public class PlaceholderTargetSourceTests extends ContextFactorySupport {
@Qualifier("withMultiple")
private PlaceholderTargetSource withMultiple;
+ @Autowired
+ @Qualifier("withEmbeddedDate")
+ private PlaceholderTargetSource withEmbeddedDate;
+
@Autowired
@Qualifier("withDate")
private PlaceholderTargetSource withDate;
@@ -60,7 +64,7 @@ public class PlaceholderTargetSourceTests extends ContextFactorySupport {
private Map map = Collections.singletonMap("foo.foo", (Object) "bar");
- private Date date = new Date();
+ private Date date = new Date(0L);
public Object getContext() {
return this;
@@ -154,11 +158,16 @@ public class PlaceholderTargetSourceTests extends ContextFactorySupport {
assertEquals("bar-4321-4321", target.getName());
}
+ @Test
+ public void testGetEmbeddedDate() {
+ Node target = (Node) withEmbeddedDate.getTarget();
+ assertEquals("bar-1970/01/01", target.getName());
+ }
+
@Test
public void testGetDate() {
Node target = (Node) withDate.getTarget();
- // Remains unconverted because Spring cannot convert from Date to String
- assertEquals("bar-#{date}", target.getName());
+ assertEquals(0L, target.getDate().getTime());
}
@Test
@@ -171,6 +180,8 @@ public class PlaceholderTargetSourceTests extends ContextFactorySupport {
public static interface Node {
String getName();
+ Date getDate();
+
Node getParent();
}
@@ -178,6 +189,8 @@ public class PlaceholderTargetSourceTests extends ContextFactorySupport {
private String name;
+ private Date date;
+
private Node parent;
public Foo() {
@@ -191,6 +204,14 @@ public class PlaceholderTargetSourceTests extends ContextFactorySupport {
return name;
}
+ public Date getDate() {
+ return date;
+ }
+
+ public void setDate(Date date) {
+ this.date = date;
+ }
+
public void setName(String name) {
this.name = name;
}
diff --git a/spring-batch-core/src/test/resources/org/springframework/batch/core/scope/util/PlaceholderTargetSourceTests-context.xml b/spring-batch-core/src/test/resources/org/springframework/batch/core/scope/util/PlaceholderTargetSourceTests-context.xml
index 2423d4e35..6e4089230 100644
--- a/spring-batch-core/src/test/resources/org/springframework/batch/core/scope/util/PlaceholderTargetSourceTests-context.xml
+++ b/spring-batch-core/src/test/resources/org/springframework/batch/core/scope/util/PlaceholderTargetSourceTests-context.xml
@@ -60,6 +60,12 @@
+
+
+
+
+
@@ -110,12 +116,18 @@
-
+
+
+
+
diff --git a/spring-batch-infrastructure/pom.xml b/spring-batch-infrastructure/pom.xml
index 0d24a521d..998afcc4a 100644
--- a/spring-batch-infrastructure/pom.xml
+++ b/spring-batch-infrastructure/pom.xml
@@ -167,6 +167,7 @@
org.codehaus.mojo
emma-maven-plugin
+ 1.0-alpha-1
diff --git a/spring-batch-test/pom.xml b/spring-batch-test/pom.xml
index 0cad6a466..22370f3bc 100755
--- a/spring-batch-test/pom.xml
+++ b/spring-batch-test/pom.xml
@@ -78,8 +78,9 @@
org.codehaus.mojo
emma-maven-plugin
+ 1.0-alpha-1
-
\ No newline at end of file
+