Resolved some TODOs.
This commit is contained in:
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Copyright 2006-2007 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 org.springframework.batch.execution.bootstrap;
|
||||
|
||||
import org.springframework.batch.repeat.interceptor.RepeatOperationsApplicationEvent;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
/**
|
||||
* {@link ApplicationEvent} that encodes a request from the execution layer to a
|
||||
* running job.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class BatchExecutionRequestEvent extends ApplicationEvent {
|
||||
|
||||
/**
|
||||
* Constructor for {@link BatchExecutionRequestEvent}. The source is the
|
||||
* execution layer service implementation that is sending the signal.<br/>
|
||||
*
|
||||
* TODO: the source should be Serializable so really it should be just a
|
||||
* message about the request?
|
||||
*
|
||||
* Currently encodes a request to publish back a
|
||||
* {@link RepeatOperationsApplicationEvent}. Could be extended in the
|
||||
* future to narrow the request to ask for specific information to be
|
||||
* published back.
|
||||
*/
|
||||
public BatchExecutionRequestEvent(Object source) {
|
||||
super(source);
|
||||
}
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* Copyright 2006-2007 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 org.springframework.batch.execution.bootstrap.support;
|
||||
|
||||
import java.beans.PropertyEditor;
|
||||
import java.beans.PropertyEditorSupport;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.springframework.batch.core.domain.JobParameters;
|
||||
import org.springframework.batch.core.runtime.JobParametersFactory;
|
||||
import org.springframework.batch.support.PropertiesConverter;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* A {@link PropertyEditor} that delegates to a {@link JobParametersFactory}.
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class JobParametersPropertyEditor extends PropertyEditorSupport {
|
||||
|
||||
private JobParametersFactory factory = new DefaultJobParametersFactory();
|
||||
|
||||
/**
|
||||
* Accept properties in the form of name=value pairs, delimited by either
|
||||
* comma or new line (or both) and create {@link JobParameters}.
|
||||
*
|
||||
* @see java.beans.PropertyEditorSupport#setAsText(java.lang.String)
|
||||
*/
|
||||
public void setAsText(String text) throws IllegalArgumentException {
|
||||
Properties properties = StringUtils.splitArrayElementsIntoProperties(StringUtils.tokenizeToStringArray(text,
|
||||
",\n"), "=");
|
||||
setValue(factory.getJobParameters(properties));
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the name from the {@link JobIdentifier}.
|
||||
*
|
||||
* @see java.beans.PropertyEditorSupport#getAsText()
|
||||
*/
|
||||
public String getAsText() {
|
||||
JobParameters params = (JobParameters) getValue();
|
||||
if (params == null) {
|
||||
return null;
|
||||
}
|
||||
Properties properties = factory.getProperties(params);
|
||||
return PropertiesConverter.propertiesToString(properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* Public setter for the {@link JobParametersFactory}.
|
||||
* @param factory the factory to set
|
||||
*/
|
||||
public void setFactory(JobParametersFactory factory) {
|
||||
this.factory = factory;
|
||||
}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
* Copyright 2006-2007 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 org.springframework.batch.execution.bootstrap.support;
|
||||
|
||||
import java.beans.PropertyEditor;
|
||||
import java.beans.PropertyEditorSupport;
|
||||
|
||||
import org.springframework.batch.core.domain.Job;
|
||||
import org.springframework.batch.core.domain.JobLocator;
|
||||
import org.springframework.batch.core.domain.NoSuchJobException;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* A {@link PropertyEditor} that delegates to a {@link JobLocator}.
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class JobPropertyEditor extends PropertyEditorSupport implements InitializingBean {
|
||||
|
||||
private JobLocator jobLocator;
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
|
||||
*/
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.notNull(jobLocator, "JobLocator is required");
|
||||
}
|
||||
|
||||
/**
|
||||
* Accept job name and convert to {@link Job} through the injected {@link JobLocator}.
|
||||
*
|
||||
* @see java.beans.PropertyEditorSupport#setAsText(java.lang.String)
|
||||
*/
|
||||
public void setAsText(String text) throws IllegalArgumentException {
|
||||
try {
|
||||
setValue(jobLocator.getJob(text));
|
||||
}
|
||||
catch (NoSuchJobException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the name from the {@link JobIdentifier}.
|
||||
*
|
||||
* @see java.beans.PropertyEditorSupport#getAsText()
|
||||
*/
|
||||
public String getAsText() {
|
||||
Job job = (Job) getValue();
|
||||
if (job == null) {
|
||||
return null;
|
||||
}
|
||||
return job.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Public setter for the {@link JobLocator}.
|
||||
* @param jobLocator the jobLocator to set
|
||||
*/
|
||||
public void setJobLocator(JobLocator jobLocator) {
|
||||
this.jobLocator = jobLocator;
|
||||
}
|
||||
}
|
||||
@@ -1,187 +0,0 @@
|
||||
/*
|
||||
* Copyright 2006-2007 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 org.springframework.batch.execution.bootstrap.support;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.springframework.batch.support.DefaultPropertyEditorRegistrar;
|
||||
import org.springframework.beans.PropertyEditorRegistry;
|
||||
import org.springframework.beans.SimpleTypeConverter;
|
||||
import org.springframework.beans.TypeConverter;
|
||||
import org.springframework.beans.TypeMismatchException;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* A {@link MethodInterceptor} that can mask a mismatch between the target and
|
||||
* proxy interfaces by converting the returned value to the correct type.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class TypeConverterMethodInterceptor extends DefaultPropertyEditorRegistrar implements MethodInterceptor,
|
||||
InitializingBean {
|
||||
|
||||
// Get the default PropertyEditorRegistry free.
|
||||
private TypeConverter typeConverter;
|
||||
|
||||
private boolean convertException = false;
|
||||
|
||||
/**
|
||||
* Ensure that the {@link TypeConverter} is set up, creating one if
|
||||
* necessary, and if it is a {@link PropertyEditorRegistry}, register the
|
||||
* custom editors. (If it is not a {@link PropertyEditorRegistry} then the
|
||||
* custom editors are ignored).
|
||||
*
|
||||
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
|
||||
*/
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
if (typeConverter == null) {
|
||||
SimpleTypeConverter converter = new SimpleTypeConverter();
|
||||
typeConverter = converter;
|
||||
}
|
||||
if (typeConverter instanceof PropertyEditorRegistry) {
|
||||
registerCustomEditors((PropertyEditorRegistry) typeConverter);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a flag that will cause exceptions during method invocation to be
|
||||
* caught and treated as a result. This can be useful if used over JConsole,
|
||||
* where exception reporting is a little weak (and in addition the class of
|
||||
* the exception might not be available remotely).
|
||||
*
|
||||
* @param convertException the flag to set (default false)
|
||||
*/
|
||||
public void setConvertException(boolean convertException) {
|
||||
this.convertException = convertException;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public setter for the {@link TypeConverter} property. Defaults to a
|
||||
* {@link SimpleTypeConverter}.
|
||||
*
|
||||
* @param typeConverter the typeConverter to set
|
||||
*/
|
||||
public void setTypeConverter(TypeConverter typeConverter) {
|
||||
this.typeConverter = typeConverter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke the method with the same name and arguments on the target, but
|
||||
* possibly with a different return type. If the return type doesn't match
|
||||
* attempt to convert it.
|
||||
*
|
||||
* @return an object that satisfies the signature of the proxy method.
|
||||
*
|
||||
* @throws TypeMismatchException if the target method returns an object that
|
||||
* cannot be converted to the desired type.
|
||||
*
|
||||
* @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)
|
||||
*/
|
||||
public Object invoke(MethodInvocation invocation) throws Throwable {
|
||||
|
||||
// The method called on the proxy
|
||||
final Method invoked = invocation.getMethod();
|
||||
|
||||
// The corresponding method on the target if there is one...
|
||||
Method method = ReflectionUtils.findMethod(invocation.getThis().getClass(), invoked.getName(), invoked
|
||||
.getParameterTypes());
|
||||
|
||||
Object[] arguments = invocation.getArguments();
|
||||
|
||||
// If there was no such method look for one with String args
|
||||
if (method == null) {
|
||||
final List methods = new ArrayList();
|
||||
ReflectionUtils.doWithMethods(invocation.getThis().getClass(), new ReflectionUtils.MethodCallback() {
|
||||
public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
|
||||
methods.add(method);
|
||||
}
|
||||
|
||||
}, new ReflectionUtils.MethodFilter() {
|
||||
public boolean matches(Method method) {
|
||||
if (method.getName().equals(invoked.getName())
|
||||
&& method.getParameterTypes().length == invoked.getParameterTypes().length) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
});
|
||||
if (methods.size() == 1) {
|
||||
method = (Method) methods.get(0);
|
||||
for (int i = 0; i < arguments.length; i++) {
|
||||
Object arg = arguments[i];
|
||||
arguments[i] = convert(arg, method.getParameterTypes()[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If there was no such method do nothing... TODO: throw Exception?
|
||||
if (method == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Invoke the target method
|
||||
Object result = null;
|
||||
|
||||
try {
|
||||
result = ReflectionUtils.invokeMethod(method, invocation.getThis(), arguments);
|
||||
}
|
||||
catch (Throwable e) {
|
||||
if (convertException) {
|
||||
result = e;
|
||||
}
|
||||
else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
if (result == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// If the return type doesn't match, try and convert it
|
||||
if (!ClassUtils.isAssignableValue(invoked.getReturnType(), result)) {
|
||||
result = convert(result, invoked.getReturnType());
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
private Object convert(Object result, Class returnType) {
|
||||
// Provide some simple conversion algorithms natively for String results
|
||||
if (returnType.isAssignableFrom(String.class)) {
|
||||
if (result instanceof Throwable) {
|
||||
Throwable e = (Throwable) result;
|
||||
e.fillInStackTrace();
|
||||
StringWriter writer = new StringWriter();
|
||||
e.printStackTrace(new PrintWriter(writer));
|
||||
result = writer.toString();
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
return typeConverter.convertIfNecessary(result, returnType);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -44,18 +44,17 @@ import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Sql implementation of {@link StepDao}. Uses Sequences (via Spring's
|
||||
* Jdbc implementation of {@link StepDao}.<br/>
|
||||
*
|
||||
* @link DataFieldMaxValueIncrementer abstraction) to create all Step and
|
||||
* StepExecution primary keys before inserting a new row. All objects are
|
||||
* checked to ensure all fields to be stored are not null. If any are found to
|
||||
* be null, an IllegalArgumentException will be thrown. This could be left to
|
||||
* JdbcTemplate, however, the exception will be fairly vague, and fails to
|
||||
* highlight which field caused the exception.
|
||||
* Allows customisation of the tables names used by Spring Batch for step meta
|
||||
* data via a prefix property.<br/>
|
||||
*
|
||||
* TODO: JavaDoc should be geared more towards usability, the comments above are
|
||||
* useful information, and should be there, but needs usability stuff. Depends
|
||||
* on the step dao java docs as well.
|
||||
* Uses sequences or tables (via Spring's {@link DataFieldMaxValueIncrementer}
|
||||
* abstraction) to create all primary keys before inserting a new row. All
|
||||
* objects are checked to ensure all fields to be stored are not null. If any
|
||||
* are found to be null, an IllegalArgumentException will be thrown. This could
|
||||
* be left to JdbcTemplate, however, the exception will be fairly vague, and
|
||||
* fails to highlight which field caused the exception.<br/>
|
||||
*
|
||||
* @author Lucas Ward
|
||||
* @author Dave Syer
|
||||
@@ -310,10 +309,10 @@ public class JdbcStepDao implements StepDao, InitializingBean {
|
||||
|
||||
stepExecution.setId(new Long(stepExecutionIncrementer.nextLongValue()));
|
||||
stepExecution.incrementVersion(); // should be 0 now
|
||||
Object[] parameters = new Object[] { stepExecution.getId(), stepExecution.getVersion(), stepExecution.getStepId(),
|
||||
stepExecution.getJobExecutionId(), stepExecution.getStartTime(), stepExecution.getEndTime(),
|
||||
stepExecution.getStatus().toString(), stepExecution.getCommitCount(), stepExecution.getTaskCount(),
|
||||
PropertiesConverter.propertiesToString(stepExecution.getStatistics()),
|
||||
Object[] parameters = new Object[] { stepExecution.getId(), stepExecution.getVersion(),
|
||||
stepExecution.getStepId(), stepExecution.getJobExecutionId(), stepExecution.getStartTime(),
|
||||
stepExecution.getEndTime(), stepExecution.getStatus().toString(), stepExecution.getCommitCount(),
|
||||
stepExecution.getTaskCount(), PropertiesConverter.propertiesToString(stepExecution.getStatistics()),
|
||||
stepExecution.getExitStatus().isContinuable() ? "Y" : "N", stepExecution.getExitStatus().getExitCode(),
|
||||
stepExecution.getExitStatus().getExitDescription() };
|
||||
jdbcTemplate.update(getSaveStepExecutionQuery(), parameters, new int[] { Types.INTEGER, Types.INTEGER,
|
||||
@@ -377,13 +376,8 @@ public class JdbcStepDao implements StepDao, InitializingBean {
|
||||
Assert.notNull(stepExecution.getId(), "StepExecution Id cannot be null. StepExecution must saved"
|
||||
+ " before it can be updated.");
|
||||
|
||||
// TODO: Not sure if this is a good idea on step execution considering
|
||||
// it is saved at every commit
|
||||
// point.
|
||||
// if (jdbcTemplate.queryForInt(CHECK_STEP_EXECUTION_EXISTS, new
|
||||
// Object[] { stepExecution.getId() }) != 1) {
|
||||
// return; // throw exception?
|
||||
// }
|
||||
// Do not check for existence of step execution considering
|
||||
// it is saved at every commit point.
|
||||
|
||||
String exitDescription = stepExecution.getExitStatus().getExitDescription();
|
||||
if (exitDescription != null && exitDescription.length() > EXIT_MESSAGE_LENGTH) {
|
||||
|
||||
@@ -221,9 +221,9 @@ public class SimpleStepExecutor implements StepExecutor {
|
||||
|
||||
result = processChunk(step, contribution);
|
||||
|
||||
// TODO: Statistics are not thread safe
|
||||
// - we cannot guarantee that they are
|
||||
// up to date. (Maybe we never can?)
|
||||
// TODO: check that stepExecution can
|
||||
// aggregate these contributions if they
|
||||
// come in asnchronously.
|
||||
Properties statistics = stepScopeContext.getStatistics();
|
||||
contribution.setStatistics(statistics);
|
||||
contribution.incrementCommitCount();
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright 2006-2007 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 org.springframework.batch.execution.bootstrap;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class BatchExecutionRequestEventTests extends TestCase {
|
||||
|
||||
/**
|
||||
* Test method for {@link org.springframework.batch.execution.bootstrap.BatchExecutionRequestEvent#BatchContainerRequestEvent(java.lang.Object)}.
|
||||
*/
|
||||
public void testBatchContainerRequestEvent() {
|
||||
ApplicationEvent event = new BatchExecutionRequestEvent(this);
|
||||
assertEquals(this, event.getSource());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright 2006-2007 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 org.springframework.batch.execution.bootstrap.support;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.core.domain.JobParameters;
|
||||
import org.springframework.batch.support.PropertiesConverter;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class JobParametersPropertyEditorTests extends TestCase {
|
||||
|
||||
private JobParametersPropertyEditor editor = new JobParametersPropertyEditor();
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.execution.bootstrap.support.JobParametersPropertyEditor#setAsText(java.lang.String)}.
|
||||
*/
|
||||
public void testSetAsTextString() {
|
||||
editor.setAsText("foo=bar");
|
||||
JobParameters identifier = (JobParameters) editor.getValue();
|
||||
assertEquals("bar", identifier.getString("foo"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.execution.bootstrap.support.JobParametersPropertyEditor#getAsText()}.
|
||||
*/
|
||||
public void testGetAsText() {
|
||||
editor.setAsText("foo=bar,spam=bucket");
|
||||
Properties properties = PropertiesConverter.stringToProperties(editor.getAsText());
|
||||
assertEquals("bar", properties.getProperty("foo"));
|
||||
assertEquals("bucket", properties.getProperty("spam"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
* Copyright 2006-2007 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 org.springframework.batch.execution.bootstrap.support;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.core.domain.Job;
|
||||
import org.springframework.batch.core.domain.JobLocator;
|
||||
import org.springframework.batch.core.domain.NoSuchJobException;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class JobPropertyEditorTests extends TestCase {
|
||||
|
||||
private JobPropertyEditor editor = new JobPropertyEditor();
|
||||
private Job job = new Job();
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see junit.framework.TestCase#setUp()
|
||||
*/
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
editor.setJobLocator(new JobLocator() {
|
||||
public Job getJob(String name) throws NoSuchJobException {
|
||||
job.setName(name);
|
||||
return job;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void testMandatoryProperties() throws Exception {
|
||||
editor = new JobPropertyEditor();
|
||||
try {
|
||||
editor.afterPropertiesSet();
|
||||
fail("Expected IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.execution.bootstrap.support.JobParametersPropertyEditor#setAsText(java.lang.String)}.
|
||||
*/
|
||||
public void testSetAsTextString() {
|
||||
editor.setAsText("foo");
|
||||
Job job = (Job) editor.getValue();
|
||||
assertEquals(job, job);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for
|
||||
* {@link org.springframework.batch.execution.bootstrap.support.JobParametersPropertyEditor#getAsText()}.
|
||||
*/
|
||||
public void testGetAsText() {
|
||||
editor.setAsText("foo");
|
||||
assertEquals("foo", editor.getAsText());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,246 +0,0 @@
|
||||
package org.springframework.batch.execution.bootstrap.support;
|
||||
|
||||
import java.beans.PropertyEditorSupport;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.beans.SimpleTypeConverter;
|
||||
import org.springframework.beans.TypeMismatchException;
|
||||
|
||||
public class TypeConverterMethodInterceptorTests extends TestCase {
|
||||
|
||||
TypeConverterMethodInterceptor interceptor = new TypeConverterMethodInterceptor();
|
||||
|
||||
private List list = new ArrayList();
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see junit.framework.TestCase#setUp()
|
||||
*/
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
interceptor.afterPropertiesSet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Even though TestBean does not implement Test, the proxy will invoke a
|
||||
* method is called with the same signature.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testInvokeWithNull() {
|
||||
ProxyFactory factory = new ProxyFactory(Test.class, interceptor);
|
||||
factory.setTarget(new TestBean(true));
|
||||
Test proxy = (Test) factory.getProxy();
|
||||
assertEquals(0, list.size());
|
||||
proxy.operate();
|
||||
assertEquals(1, list.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Even though TestBean does not implement Test, the proxy will return
|
||||
* something if a method is called with the same signature.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testInvokeWithBoolean() {
|
||||
ProxyFactory factory = new ProxyFactory(Test.class, interceptor);
|
||||
factory.setTarget(new TestBean(true));
|
||||
Test proxy = (Test) factory.getProxy();
|
||||
assertEquals(true, proxy.isTest());
|
||||
}
|
||||
|
||||
/**
|
||||
* Even though TestBean does not implement Test, the proxy will return
|
||||
* something if a method is called with the same signature.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testInvokeWithConversionToInt() {
|
||||
ProxyFactory factory = new ProxyFactory(Test.class, interceptor);
|
||||
factory.setTarget(new TestBean(true));
|
||||
Test proxy = (Test) factory.getProxy();
|
||||
assertEquals(123, proxy.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Even though TestBean does not implement Test, the proxy will return a
|
||||
* converted value if a method is called with the same name and arguments,
|
||||
* but different return type.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testInvokeWithComplex() throws Exception {
|
||||
ProxyFactory factory = new ProxyFactory(Test.class, interceptor);
|
||||
factory.setTarget(new TestBean(true));
|
||||
Test proxy = (Test) factory.getProxy();
|
||||
assertEquals("FOO:true", proxy.getBean());
|
||||
}
|
||||
|
||||
public void testInvokeWithNoMethodMatch() throws Exception {
|
||||
ProxyFactory factory = new ProxyFactory(Test.class, interceptor);
|
||||
factory.setTarget(this);
|
||||
Test proxy = (Test) factory.getProxy();
|
||||
assertNull(proxy.getBean());
|
||||
}
|
||||
|
||||
public void testInvokeWithError() throws Exception {
|
||||
ProxyFactory factory = new ProxyFactory(Test.class, interceptor);
|
||||
factory.setTarget(new TestBean(true));
|
||||
Test proxy = (Test) factory.getProxy();
|
||||
try {
|
||||
assertNull(proxy.error());
|
||||
fail("Expected RuntimeException");
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
// expected
|
||||
assertEquals("Foo", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testInvokeWithErrorAndConvert() throws Exception {
|
||||
ProxyFactory factory = new ProxyFactory(Test.class, interceptor);
|
||||
factory.setTarget(new TestBean(true));
|
||||
Test proxy = (Test) factory.getProxy();
|
||||
interceptor.setConvertException(true);
|
||||
String msg = proxy.error();
|
||||
assertTrue("Message is not a stacktrace: "+msg, msg.indexOf("RuntimeException: Foo")>=0);
|
||||
}
|
||||
|
||||
public void testInvokeWithMethodParameterConversionToBoolean() throws Exception {
|
||||
ProxyFactory factory = new ProxyFactory(Test.class, interceptor);
|
||||
factory.setTarget(new TestBean(true));
|
||||
Test proxy = (Test) factory.getProxy();
|
||||
assertEquals("flag:true", proxy.grab("true"));
|
||||
}
|
||||
|
||||
public void testInvokeWithMethodParameterConversionToPattern() throws Exception {
|
||||
ProxyFactory factory = new ProxyFactory(Test.class, interceptor);
|
||||
factory.setTarget(new TestBean(true));
|
||||
Test proxy = (Test) factory.getProxy();
|
||||
Pattern pattern = Pattern.compile("[a-z]*");
|
||||
assertEquals(pattern.toString(), proxy.relayPattern("[a-z]*"));
|
||||
}
|
||||
|
||||
public void testInvalidConversion() throws Exception {
|
||||
ProxyFactory factory = new ProxyFactory(Test.class, interceptor);
|
||||
factory.setTarget(new TestBean(true));
|
||||
Test proxy = (Test) factory.getProxy();
|
||||
try {
|
||||
proxy.getInvalid();
|
||||
fail("Expected TypeMismatchException");
|
||||
}
|
||||
catch (TypeMismatchException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
public void testTypeConverter() throws Exception {
|
||||
final TestCase testCase = this;
|
||||
interceptor.setTypeConverter(new SimpleTypeConverter() {
|
||||
public Object convertIfNecessary(Object value, Class requiredType) {
|
||||
return testCase;
|
||||
}
|
||||
});
|
||||
ProxyFactory factory = new ProxyFactory(Test.class, interceptor);
|
||||
factory.setTarget(new TestBean(true));
|
||||
Test proxy = (Test) factory.getProxy();
|
||||
assertEquals(testCase, proxy.getInvalid());
|
||||
}
|
||||
|
||||
public void testTypeConverterAfterPropertiesSet() throws Exception {
|
||||
testTypeConverter();
|
||||
interceptor.afterPropertiesSet();
|
||||
testTypeConverter();
|
||||
}
|
||||
|
||||
public void testInvokeWithMethodParameterConversionWithPropertyEditor() throws Exception {
|
||||
final TestBean bean = new TestBean(false);
|
||||
SimpleTypeConverter converter = new SimpleTypeConverter();
|
||||
converter.registerCustomEditor(TestBean.class, new PropertyEditorSupport() {
|
||||
public void setAsText(String text) throws IllegalArgumentException {
|
||||
setValue(bean);
|
||||
}
|
||||
});
|
||||
interceptor.setTypeConverter(converter);
|
||||
ProxyFactory factory = new ProxyFactory(Test.class, interceptor);
|
||||
factory.setTarget(new TestBean(true));
|
||||
Test proxy = (Test) factory.getProxy();
|
||||
assertEquals(bean.toString(), proxy.relayBean("foo"));
|
||||
}
|
||||
|
||||
public interface Test {
|
||||
boolean isTest();
|
||||
|
||||
String getBean();
|
||||
|
||||
String relayPattern(String pattern);
|
||||
|
||||
TestCase getInvalid();
|
||||
|
||||
int getValue();
|
||||
|
||||
void operate();
|
||||
|
||||
String grab(String value);
|
||||
|
||||
String relayBean(String value);
|
||||
|
||||
String error();
|
||||
}
|
||||
|
||||
// N.B. TestBean intentionally does not implement Test!
|
||||
public class TestBean {
|
||||
private boolean test;
|
||||
|
||||
public TestBean(boolean test) {
|
||||
super();
|
||||
this.test = test;
|
||||
}
|
||||
|
||||
public boolean isTest() {
|
||||
return test;
|
||||
}
|
||||
|
||||
public TestBean getBean() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public TestBean relayBean(TestBean bean) {
|
||||
return bean;
|
||||
}
|
||||
|
||||
public Pattern relayPattern(Pattern pattern) {
|
||||
return pattern;
|
||||
}
|
||||
|
||||
public TestBean getInvalid() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return "123";
|
||||
}
|
||||
|
||||
public void operate() {
|
||||
list.add("FOO");
|
||||
}
|
||||
|
||||
public String grab(boolean flag) {
|
||||
return "flag:" + flag;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "FOO:" + test;
|
||||
}
|
||||
|
||||
public String error() {
|
||||
throw new RuntimeException("Foo");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -370,13 +370,12 @@ public class SimpleJobRepositoryTests extends TestCase {
|
||||
stepDaoControl.verify();
|
||||
}
|
||||
|
||||
public void testSaveStepExecution(){
|
||||
StepExecution stepExecution = new StepExecution(new StepInstance(new Long(10L)), null, new Long(2));
|
||||
//TODO: Not sure why, but calling save on the EasyMock stepDao causes a NullPointerException
|
||||
// stepDao.save(stepExecution);
|
||||
// stepDaoControl.replay();
|
||||
public void testSaveExistingStepExecution(){
|
||||
StepExecution stepExecution = new StepExecution(new StepInstance(new Long(10L)), null, null);
|
||||
stepDao.save(stepExecution);
|
||||
stepDaoControl.replay();
|
||||
jobRepository.saveOrUpdate(stepExecution);
|
||||
// stepDaoControl.verify();
|
||||
stepDaoControl.verify();
|
||||
}
|
||||
|
||||
public void testSaveOrUpdateStepExecutionException() {
|
||||
|
||||
@@ -128,10 +128,10 @@ public class ItemOrientedTaskletTests extends TestCase {
|
||||
// call read
|
||||
try {
|
||||
module.execute();
|
||||
// TODO: should we expect Batch exception?
|
||||
fail("RuntimeException was expected");
|
||||
} catch (RuntimeException bce) {
|
||||
// expected
|
||||
assertEquals("foo", bce.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -60,8 +60,6 @@ public class ApplicationEventPublisherRepeatInterceptor implements ApplicationEv
|
||||
*/
|
||||
public void close(RepeatContext context) {
|
||||
publish(context, "Closed repeat context with batch complete", RepeatOperationsApplicationEvent.CLOSE);
|
||||
//TODO: why is this returning continuable?
|
||||
//return ExitStatus.CONTINUABLE;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -64,7 +64,8 @@ public class BatchTransactionSynchronizationManager {
|
||||
/**
|
||||
* The key in the context attributes for the list of synchronizations.
|
||||
*/
|
||||
private static final String SYNCHS_ATTR_KEY = BatchTransactionSynchronizationManager.class.getName() + ".SYNCHRONIZATIONS";
|
||||
private static final String SYNCHS_ATTR_KEY = BatchTransactionSynchronizationManager.class.getName()
|
||||
+ ".SYNCHRONIZATIONS";
|
||||
|
||||
/**
|
||||
* Static method to register synchronizations. A TransactionSyncrhonization
|
||||
@@ -144,8 +145,9 @@ public class BatchTransactionSynchronizationManager {
|
||||
|
||||
AttributeAccessor context = getContext();
|
||||
if (context == null) {
|
||||
// TODO: this should return null or unmodifiable - there is no
|
||||
// context for it
|
||||
// N.B. this returns a modifiable list on purpose - it is used
|
||||
// internally to set up the list if there is no context available
|
||||
// (useful in testing).
|
||||
return new ArrayList();
|
||||
}
|
||||
List synchs = (List) context.getAttribute(SYNCHS_ATTR_KEY);
|
||||
|
||||
@@ -52,7 +52,7 @@ public class RetryOperationsInterceptor implements MethodInterceptor {
|
||||
}
|
||||
|
||||
public Object invoke(final MethodInvocation invocation) throws Throwable {
|
||||
// TODO: use the method name to initialise a statistics context
|
||||
|
||||
return this.retryOperations.execute(new RetryCallback() {
|
||||
|
||||
public Object doWithRetry(RetryContext context) throws Throwable {
|
||||
|
||||
@@ -70,8 +70,8 @@ public class SynchronizedAttributeAccessorTests extends TestCase {
|
||||
public void testEqualsWrongType() {
|
||||
accessor.setAttribute("foo", "bar");
|
||||
Map another = Collections.singletonMap("foo", "bar");
|
||||
|
||||
//TODO accessor and another are instances of unrelated classes, they can never be equal
|
||||
// Accessor and another are instances of unrelated classes, they should
|
||||
// never be equal...
|
||||
assertFalse(accessor.equals(another));
|
||||
}
|
||||
|
||||
|
||||
@@ -120,8 +120,10 @@ public class BatchMessageListenerContainer extends DefaultMessageListenerContain
|
||||
|
||||
/**
|
||||
* Used to provide a recovery path - delegates to
|
||||
* {@link #recover(Session, Message, Throwable)}. TODO: Could be merged
|
||||
* into base class?
|
||||
* {@link #recover(Session, Message, Throwable)}.
|
||||
*
|
||||
* TODO: Could be merged into base class?
|
||||
*
|
||||
* @param session the JMS session
|
||||
* @param message the last message
|
||||
* @param ex the exception thrown by listener
|
||||
|
||||
@@ -40,16 +40,12 @@ public class IbatisCustomerCreditWriter extends SqlMapClientDaoSupport
|
||||
* @see org.springframework.batch.item.ResourceLifecycle#close()
|
||||
*/
|
||||
public void close() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.batch.item.ResourceLifecycle#open()
|
||||
*/
|
||||
public void open() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -92,28 +92,6 @@
|
||||
<bean id="notificationPublisher"
|
||||
class="org.springframework.batch.execution.bootstrap.JobExecutionNotificationPublisher" />
|
||||
|
||||
<bean id="convertingMethodInterceptor"
|
||||
class="org.springframework.batch.execution.bootstrap.support.TypeConverterMethodInterceptor">
|
||||
<property name="convertException" value="true" />
|
||||
<property name="customEditors">
|
||||
<map>
|
||||
<entry
|
||||
key="org.springframework.batch.core.domain.JobParameters">
|
||||
<bean
|
||||
class="org.springframework.batch.execution.bootstrap.support.JobParametersPropertyEditor" />
|
||||
</entry>
|
||||
<entry
|
||||
key="org.springframework.batch.core.domain.Job">
|
||||
<bean
|
||||
class="org.springframework.batch.execution.bootstrap.support.JobPropertyEditor">
|
||||
<property name="jobLocator"
|
||||
ref="jobConfigurationRegistry" />
|
||||
</bean>
|
||||
</entry>
|
||||
</map>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="logAdvice"
|
||||
class="org.springframework.batch.sample.advice.MethodExecutionLogAdvice" />
|
||||
|
||||
|
||||
@@ -68,16 +68,6 @@ public class HibernateFailureJobFunctionalTests extends
|
||||
assertEquals(before, after);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.batch.sample.AbstractCustomerCreditIncreaseTests#validatePostConditions()
|
||||
*/
|
||||
protected void validatePostConditions() throws Exception {
|
||||
// TODO: fix so that the postconditions in super class are true
|
||||
super.validatePostConditions();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
|
||||
@@ -21,12 +21,10 @@ public class JdbcPlayerDaoIntegrationTests extends AbstractTransactionalDataSour
|
||||
private static final String GET_PLAYER = "SELECT * from PLAYERS";
|
||||
|
||||
protected String[] getConfigLocations() {
|
||||
// TODO Auto-generated method stub
|
||||
return new String[] {"data-source-context.xml"};
|
||||
}
|
||||
|
||||
protected void onSetUpBeforeTransaction() throws Exception {
|
||||
// TODO Auto-generated method stub
|
||||
super.onSetUpBeforeTransaction();
|
||||
|
||||
playerDao = new JdbcPlayerDao();
|
||||
|
||||
Reference in New Issue
Block a user