BATCH-1208: Modified PlaceholderTargetSource to remove the path from resolveStringValue() that handles values that start with "#{" and end with "}". This was causing problems for values like "#{run.id}" or "#{integer}-#{integer}" where replacements were expected. The special path was added to handle references, where a replacement should not take place. Since a replacement is not expected, removing the path caused an exception to be thrown to indicate that no replacement had occurred. This exception was changed to a logging statement to allow this case.
This commit is contained in:
@@ -170,15 +170,6 @@ public class PlaceholderTargetSource extends SimpleBeanTargetSource implements I
|
||||
if (!strVal.contains(PLACEHOLDER_PREFIX)) {
|
||||
return strVal;
|
||||
}
|
||||
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);
|
||||
}
|
||||
}) {
|
||||
@@ -327,7 +318,7 @@ public class PlaceholderTargetSource extends SimpleBeanTargetSource implements I
|
||||
replaced |= replaceIfTypeMatches(result, first, next, key, Integer.class, typeConverter);
|
||||
replaced |= replaceIfTypeMatches(result, first, next, key, Date.class, typeConverter);
|
||||
if (!replaced) {
|
||||
throw new IllegalStateException("Cannot bind to placeholder: "+key);
|
||||
logger.debug("Cannot bind to placeholder: " + key);
|
||||
}
|
||||
first = result.indexOf(PLACEHOLDER_PREFIX, first + 1);
|
||||
next = result.indexOf(PLACEHOLDER_SUFFIX, first + 1);
|
||||
|
||||
@@ -29,7 +29,6 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.batch.core.BatchStatus;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.JobParametersBuilder;
|
||||
import org.springframework.batch.core.StepExecution;
|
||||
import org.springframework.batch.core.job.AbstractJob;
|
||||
@@ -113,9 +112,10 @@ public class ListPreparedStatementSetterTests {
|
||||
this.simpleJdbcTemplate.update("insert into FOO values (?,?,?)", 0, "zero", 0);
|
||||
this.simpleJdbcTemplate.update("insert into FOO values (?,?,?)", 1, "one", 1);
|
||||
this.simpleJdbcTemplate.update("insert into FOO values (?,?,?)", 2, "two", 2);
|
||||
this.simpleJdbcTemplate.update("insert into FOO values (?,?,?)", 3, "three", 3);
|
||||
|
||||
JobParameters params = new JobParametersBuilder().addLong("start.id", 1L).toJobParameters();
|
||||
JobExecution jobExecution = this.jobLauncher.run(this.job, params);
|
||||
JobParametersBuilder builder = new JobParametersBuilder().addLong("min.id", 1L).addLong("max.id", 2L);
|
||||
JobExecution jobExecution = this.jobLauncher.run(this.job, builder.toJobParameters());
|
||||
assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus());
|
||||
|
||||
List<Foo> foos = fooStoringItemWriter.getFoos();
|
||||
|
||||
@@ -74,15 +74,8 @@ public class PlaceholderTargetSourceErrorTests extends ContextFactorySupport {
|
||||
|
||||
@Test
|
||||
public void testPartialReplaceMissingProperty() throws Exception {
|
||||
try {
|
||||
Node target = (Node) createValue("name", "#{garbage}-bar").getTarget();
|
||||
assertEquals("bar", target.getName());
|
||||
fail("Expected IllegalStateException");
|
||||
}
|
||||
catch (Exception e) {
|
||||
String message = e.getMessage();
|
||||
assertTrue("Wrong message: " + message, message.toLowerCase().contains("cannot bind"));
|
||||
}
|
||||
Node target = (Node) createValue("name", "#{garbage}-bar").getTarget();
|
||||
assertEquals("#{garbage}-bar", target.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -39,6 +39,10 @@ public class PlaceholderTargetSourceTests extends ContextFactorySupport {
|
||||
@Qualifier("withMultiple")
|
||||
private PlaceholderTargetSource withMultiple;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("withMultipleStartAndEnd")
|
||||
private PlaceholderTargetSource withMultipleStartAndEnd;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("withEmbeddedDate")
|
||||
private PlaceholderTargetSource withEmbeddedDate;
|
||||
@@ -155,6 +159,12 @@ public class PlaceholderTargetSourceTests extends ContextFactorySupport {
|
||||
assertEquals("bar-4321-4321", target.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMultipleStartAndEnd() {
|
||||
Node target = (Node) withMultipleStartAndEnd.getTarget();
|
||||
assertEquals("4321-4321", target.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetEmbeddedDate() {
|
||||
Node target = (Node) withEmbeddedDate.getTarget();
|
||||
@@ -165,7 +175,9 @@ public class PlaceholderTargetSourceTests extends ContextFactorySupport {
|
||||
@Test
|
||||
public void testGetDate() {
|
||||
Node target = (Node) withDate.getTarget();
|
||||
assertEquals(1L, target.getDate().getTime());
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
|
||||
String date = sdf.format(new Date(1L));
|
||||
assertEquals(date, sdf.format(target.getDate()));
|
||||
}
|
||||
|
||||
public static interface Node {
|
||||
|
||||
@@ -22,9 +22,9 @@
|
||||
</beans:bean>
|
||||
|
||||
<beans:bean id="reader" class="org.springframework.batch.item.database.JdbcCursorItemReader">
|
||||
<beans:property name="dataSource" ref="dataSource"/>
|
||||
<beans:property name="sql" value="select ID, NAME, VALUE from FOO where ID >= ?"/>
|
||||
<beans:property name="sql" value="select ID, NAME, VALUE from FOO where ID >= ? and ID <= ?"/>
|
||||
<beans:property name="preparedStatementSetter" ref="pss"/>
|
||||
<beans:property name="dataSource" ref="dataSource"/>
|
||||
<beans:property name="rowMapper">
|
||||
<beans:bean class="org.springframework.batch.core.resource.FooRowMapper"/>
|
||||
</beans:property>
|
||||
@@ -32,7 +32,10 @@
|
||||
|
||||
<beans:bean id="pss" class="org.springframework.batch.core.resource.ListPreparedStatementSetter" scope="step">
|
||||
<beans:property name="parameters">
|
||||
<beans:value>#{jobParameters[start.id]}</beans:value>
|
||||
<beans:list>
|
||||
<beans:value>#{jobParameters[min.id]}</beans:value>
|
||||
<beans:value>#{jobParameters[max.id]}</beans:value>
|
||||
</beans:list>
|
||||
</beans:property>
|
||||
</beans:bean>
|
||||
|
||||
|
||||
@@ -58,6 +58,12 @@
|
||||
<property name="targetBeanName" value="withMultipleTarget" />
|
||||
</bean>
|
||||
|
||||
<bean id="withMultipleStartAndEnd"
|
||||
class="org.springframework.batch.core.scope.util.PlaceholderTargetSource">
|
||||
<property name="contextFactory" ref="context" />
|
||||
<property name="targetBeanName" value="withMultipleStartAndEndTarget" />
|
||||
</bean>
|
||||
|
||||
<bean id="withDate"
|
||||
class="org.springframework.batch.core.scope.util.PlaceholderTargetSource">
|
||||
<property name="contextFactory" ref="context" />
|
||||
@@ -117,6 +123,12 @@
|
||||
<property name="name" value="bar-#{integer}-#{integer}" />
|
||||
</bean>
|
||||
|
||||
<bean id="withMultipleStartAndEndTarget"
|
||||
class="org.springframework.batch.core.scope.util.PlaceholderTargetSourceTests$Foo"
|
||||
lazy-init="true">
|
||||
<property name="name" value="#{integer}-#{integer}" />
|
||||
</bean>
|
||||
|
||||
<bean id="withEmbeddedDateTarget"
|
||||
class="org.springframework.batch.core.scope.util.PlaceholderTargetSourceTests$Foo"
|
||||
lazy-init="true">
|
||||
|
||||
Reference in New Issue
Block a user