Add spring-batch- to module directory names (so folks can use mvn eclipse:eclipse if they want to).

BATCH-238: Remove hibernate support for the Daos.
This commit is contained in:
dsyer
2007-12-10 21:23:48 +00:00
parent 17705f27ab
commit 8ea331bfc7
884 changed files with 956 additions and 2352 deletions

View File

@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src/main/java"/>
<classpathentry kind="src" output="bin/test-classes" path="src/test/java"/>
<classpathentry kind="src" path="src/main/resources"/>
<classpathentry kind="src" output="bin/test-classes" path="src/test/resources"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>

View File

@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src/main/java"/>
<classpathentry kind="src" output="bin/test-classes" path="src/test/java"/>
<classpathentry kind="src" output="bin/test-classes" path="src/test/resources"/>
<classpathentry kind="src" path="src/main/resources"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>

View File

@@ -1,115 +0,0 @@
package org.springframework.batch.execution.repository.dao;
import java.io.Serializable;
import org.hibernate.EmptyInterceptor;
import org.hibernate.type.Type;
import org.springframework.batch.core.domain.JobExecution;
import org.springframework.batch.core.domain.JobIdentifier;
import org.springframework.batch.core.domain.JobInstance;
import org.springframework.batch.core.domain.StepExecution;
import org.springframework.batch.repeat.ExitStatus;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;
/**
* Hibernate interceptor for batch meta data. It can distinguish between the
* various {@link JobIdentifier} strategies in a {@link JobInstance}, and can
* truncate the exit descriptions. Its main task is to return the correct entity
* name for a {@link JobInstance} based on the type of {@link JobIdentifier}
* used. There is necessarily some tight coupling between this and the Hibernate
* mappings for {@link JobInstance} because the map from {@link JobIdentifier}
* type to entity name is in both places.
*
* @author Dave Syer
*
*/
public class BatchHibernateInterceptor extends EmptyInterceptor implements
InitializingBean {
/**
*
*/
private static final int EXIT_MESSAGE_LENGTH = 250;
private EntityNameLocator entityNameLocator;
/**
* Public setter for the {@link EntityNameLocator} property.
*
* @param entityNameLocator
* the entityNameLocator to set
*/
public void setEntityNameLocator(EntityNameLocator entityNameLocator) {
this.entityNameLocator = entityNameLocator;
}
/**
* Check mandatory properties ({@link #entityNameLocator}).
*
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/
public void afterPropertiesSet() throws Exception {
Assert
.notNull(entityNameLocator,
"EntityNameLocator must be provided.");
}
/**
* If the object is a {@link JobInstance} search the identifier types for an
* entity name based on the {@link JobIdentifier} type. Fall back to
* SimpleJobIdentifier if the value is not found.
*
* @see org.hibernate.EmptyInterceptor#getEntityName(java.lang.Object)
*/
public String getEntityName(Object object) {
if (object instanceof JobInstance) {
JobInstance instance = (JobInstance) object;
return entityNameLocator
.locate(instance.getIdentifier().getClass());
}
return super.getEntityName(object);
}
/**
* Ensure that {@link JobExecution} and {@link StepExecution} have exit
* status with legal description (not too long).
*
* @see org.hibernate.EmptyInterceptor#onFlushDirty(java.lang.Object,
* java.io.Serializable, java.lang.Object[], java.lang.Object[],
* java.lang.String[], org.hibernate.type.Type[])
*/
public boolean onFlushDirty(Object entity, Serializable id,
Object[] currentState, Object[] previousState,
String[] propertyNames, Type[] types) {
if (entity instanceof StepExecution || entity instanceof JobExecution) {
int index = findExitStatus(propertyNames);
ExitStatus status = (ExitStatus) currentState[index];
String description = status == null ? "" : status
.getExitDescription();
if (description.length() > EXIT_MESSAGE_LENGTH) {
status = status.addExitDescription(description.substring(0,
EXIT_MESSAGE_LENGTH));
currentState[index] = status;
// state was modified...
return true;
}
}
return false;
}
/**
* @param propertyNames
* @return
*/
private int findExitStatus(String[] propertyNames) {
for (int i = 0; i < propertyNames.length; i++) {
if ("exitStatus".equals(propertyNames[i])) {
return i;
}
}
return -1;
}
}

View File

@@ -1,71 +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.repository.dao;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import org.hibernate.HibernateException;
import org.springframework.batch.core.domain.BatchStatus;
/**
* User type object to help Hibernate to persist {@link BatchStatus} objects
* (just plonking it a String).
*
* @author Dave Syer
*
*/
public class BatchStatusUserType extends ImmutableValueUserType {
/* (non-Javadoc)
* @see org.springframework.batch.execution.repository.dao.ImmutableValueUserType#sqlTypes()
*/
public int[] sqlTypes() {
return new int[] { Types.VARCHAR };
}
/**
* Get the
* @see org.springframework.batch.execution.repository.dao.ImmutableValueUserType#nullSafeGet(java.sql.ResultSet, java.lang.String[], java.lang.Object)
*/
public Object nullSafeGet(ResultSet rs, String[] names, Object owner)
throws HibernateException, SQLException {
return BatchStatus.getStatus(rs.getString(names[0]));
}
/**
* Plonk a String representation of the status in the prepared statement.
*
* @see org.springframework.batch.execution.repository.dao.ImmutableValueUserType#nullSafeSet(java.sql.PreparedStatement, java.lang.Object, int)
*/
public void nullSafeSet(PreparedStatement st, Object value, int index)
throws HibernateException, SQLException {
st.setString(index, value!=null ? value.toString() : null);
}
/* (non-Javadoc)
* @see org.springframework.batch.execution.repository.dao.ImmutableValueUserType#returnedClass()
*/
public Class returnedClass() {
return BatchStatus.class;
}
}

View File

@@ -1,34 +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.repository.dao;
/**
* Locator strategy for entity names based on class.
*
* @author Dave Syer
*
*/
public interface EntityNameLocator {
/**
* Translate a concrete class into an entity name.
*
* @param clz the Class of the object to locate
* @return an entity name
*/
String locate(Class clz);
}

View File

@@ -1,72 +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.repository.dao;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import org.hibernate.HibernateException;
import org.springframework.batch.repeat.ExitStatus;
/**
* User type object to help Hibernate persist (@link {@link ExitStatus})
* objects. The continuable flag is mapped to a String with value Y/N.
*
* @author Dave Syer
*
*/
public class ExitStatusUserType extends ImmutableValueUserType {
/**
* Convert a result set to an {@link ExitStatus}.
*
* @see org.springframework.batch.execution.repository.dao.ImmutableValueUserType#nullSafeGet(java.sql.ResultSet, java.lang.String[], java.lang.Object)
*/
public Object nullSafeGet(ResultSet rs, String[] names, Object owner)
throws HibernateException, SQLException {
boolean continuable = "Y".equals(rs.getString(names[0]));
String code = rs.getString(names[1]);
String message = rs.getString(names[2]);
return new ExitStatus(continuable, code, message);
}
/**
* Convert the value (as an {@link ExitStatus}) to the columns in the
* prepared statement.
*
* @see org.springframework.batch.execution.repository.dao.ImmutableValueUserType#nullSafeSet(java.sql.PreparedStatement,
* java.lang.Object, int)
*/
public void nullSafeSet(PreparedStatement st, Object value, int index)
throws HibernateException, SQLException {
ExitStatus status = (ExitStatus) value;
st.setString(index, status.isContinuable() ? "Y" : "N");
st.setString(index + 1, status.getExitCode());
st.setString(index + 2, status.getExitDescription());
}
public Class returnedClass() {
return ExitStatus.class;
}
public int[] sqlTypes() {
return new int[] { Types.CHAR, Types.VARCHAR, Types.VARCHAR };
}
}

View File

@@ -1,241 +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.repository.dao;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Expression;
import org.springframework.batch.core.domain.JobExecution;
import org.springframework.batch.core.domain.JobIdentifier;
import org.springframework.batch.core.domain.JobInstance;
import org.springframework.batch.core.repository.NoSuchBatchDomainObjectException;
import org.springframework.batch.execution.runtime.ScheduledJobIdentifier;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.util.Assert;
/**
* Implementation of {@link JobDao} functionality based on the Hibernate ORM
* framework. Its advantage is the independence of implementation on the
* underlying database.
*
* @author Tomas Slanina
* @author Dave Syer
*/
public class HibernateJobDao extends HibernateDaoSupport implements JobDao, InitializingBean {
private EntityNameLocator entityNameLocator;
/**
* Public setter for the {@link EntityNameLocator} property.
*
* @param entityNameLocator the entityNameLocator to set
*/
public void setEntityNameLocator(EntityNameLocator entityNameLocator) {
this.entityNameLocator = entityNameLocator;
}
/**
* Check mandatory properties ({@link #entityNameLocator}).
* @see org.springframework.dao.support.DaoSupport#initDao()
*/
protected void initDao() throws Exception {
Assert.notNull(entityNameLocator, "An EntityNameLocator must be provided.");
super.initDao();
}
/**
* @see JobDao#createJob(JobIdentifier)
*
* In this Hibernate implementation a job is stored into the database. Id is
* obtained from Hibernate.
*/
public JobInstance createJob(JobIdentifier jobIdentifier) {
validateJobIdentifier(jobIdentifier);
JobInstance job = new JobInstance(jobIdentifier);
Long jobId = (Long) getHibernateTemplate().save(job);
job.setId(jobId);
return job;
}
/**
* @see JobDao#findJobs(JobIdentifier)
*
* Hibernate is asked to get all jobs that matches criteria. Afterwards,
* result is mapped into domain objects.
*/
public List findJobs(JobIdentifier jobIdentifier) {
final JobIdentifier jobRuntimeInformation = jobIdentifier;
validateJobIdentifier(jobRuntimeInformation);
List list = this.getHibernateTemplate().executeFind(
new HibernateCallback() {
public Object doInHibernate(Session session) {
String entityName = entityNameLocator.locate(jobRuntimeInformation.getClass());
Criteria criteria = session
.createCriteria(entityName);
criteria.add(Expression.eq("identifier",
jobRuntimeInformation));
return criteria.list();
}
});
return list;
}
/**
* @see JobDao#getJobExecutionCount(Long)
*/
public int getJobExecutionCount(final Long jobId) {
Assert.notNull(jobId, "JobId cannot be null");
Long result = (Long) this.getHibernateTemplate().execute(
new HibernateCallback() {
public Object doInHibernate(Session session) {
return session
.createQuery(
"select count(id) from JobExecution where job.id = :jobId")
.setLong("jobId", jobId.longValue())
.uniqueResult();
}
});
return (result == null) ? 0 : result.intValue();
}
/**
* @see JobDao#save(JobExecution)
*
* Hibernate implementation persists JobExecution instance. Id is obtained
* from Hibernate.
*/
public void save(JobExecution jobExecution) {
validateJobExecution(jobExecution);
Long id = (Long) getHibernateTemplate().save(jobExecution);
jobExecution.setId(id);
}
/**
* @see JobDao#update(JobInstance)
*/
public void update(JobInstance job) {
Assert.notNull(job, "Job Cannot be Null");
Assert.notNull(job.getStatus(), "Job Status cannot be Null");
Assert.notNull(job.getId(), "Job ID cannot be null");
getHibernateTemplate().update(job);
}
/**
* @see JobDao#update(JobExecution)
*/
public void update(final JobExecution jobExecution) {
validateJobExecution(jobExecution);
if (jobExecution.getId() == null) {
throw new IllegalArgumentException(
"JobExecution ID cannot be null. JobExecution must be saved "
+ "before it can be updated.");
}
JobExecution other = (JobExecution) getHibernateTemplate()
.get(JobExecution.class, jobExecution.getId());
if (other == null) {
throw new NoSuchBatchDomainObjectException(
"Invalid JobExecution, ID " + jobExecution.getId()
+ " not found.");
}
getHibernateTemplate().evict(other);
getHibernateTemplate().update(jobExecution);
}
public List findJobExecutions(JobInstance job) {
Assert.notNull(job, "Job cannot be null.");
Assert.notNull(job.getId(), "Job ID cannot be null.");
final Long jobId = job.getId();
List list = this.getHibernateTemplate().executeFind(
new HibernateCallback() {
public Object doInHibernate(Session session) {
Criteria criteria = session
.createCriteria(JobExecution.class);
criteria.add(Expression.eq("job.id", jobId));
return criteria.list();
}
});
return list;
}
/*
* Validate JobExecution. At a minimum, JobId, StartTime, EndTime, and
* Status cannot be null.
*
* @param jobExecution @throws IllegalArgumentException
*/
private void validateJobExecution(JobExecution jobExecution) {
Assert.notNull(jobExecution);
Assert.notNull(jobExecution.getJobId(),
"JobExecution Job-Id cannot be null.");
Assert.notNull(jobExecution.getStartTime(),
"JobExecution start time cannot be null.");
Assert.notNull(jobExecution.getStatus(),
"JobExecution status cannot be null.");
}
/*
* Validate JobRuntimeInformation. Due to differing requirements, it is
* acceptable for any field to be blank, however null fields may cause odd
* and vague exception reports from the database driver.
*/
private void validateJobIdentifier(JobIdentifier jobIdentifier) {
Assert.notNull(jobIdentifier, "JobIdentifier cannot be null.");
Assert.hasText(jobIdentifier.getName(),
"JobIdentifier name cannot be null or empty.");
if (jobIdentifier instanceof ScheduledJobIdentifier) {
ScheduledJobIdentifier jobRuntimeInformation = (ScheduledJobIdentifier) jobIdentifier;
Assert.notNull(jobRuntimeInformation.getJobKey(),
"ScheduledJobIdentifier JobKey cannot be null.");
Assert.notNull(jobRuntimeInformation.getScheduleDate(),
"ScheduledJobIdentifier ScheduleDate cannot be null.");
}
}
}

View File

@@ -1,184 +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.repository.dao;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Expression;
import org.springframework.batch.core.domain.JobInstance;
import org.springframework.batch.core.domain.StepExecution;
import org.springframework.batch.core.domain.StepInstance;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.util.Assert;
/**
* It represents an implementation of {@link StepDao} functionality based
* on the Hibernate ORM framework. Its advantage is the independence of implementation
* on the underlying database.
*
* @author Tomas Slanina
* @author Dave Syer
*/
public class HibernateStepDao extends HibernateDaoSupport implements StepDao {
/* (non-Javadoc)
* @see org.springframework.batch.container.repository.dao.StepDao#createStep(String, java.lang.Long)
*/
public StepInstance createStep(JobInstance job, String stepName) {
Assert.notNull(job, "Job cannot be null.");
Assert.notNull(stepName, "StepName cannot be null.");
StepInstance step = new StepInstance(job, stepName);
Long stepId = (Long)getHibernateTemplate().save(step);
step.setId(stepId);
return step;
}
/**
* @see StepDao#findStep(Long, String)
*/
public StepInstance findStep(final JobInstance job, final String stepName) {
Assert.notNull(job, "Job cannot be null.");
Assert.notNull(job.getId(), "Job ID cannot be null");
Assert.notNull(stepName, "StepName cannot be null");
return (StepInstance) this.getHibernateTemplate().execute(new HibernateCallback() {
public Object doInHibernate(Session session) {
Criteria criteria = session.createCriteria(StepInstance.class);
criteria.add(Expression.eq("name", stepName));
criteria.add(Expression.eq("job.id", job.getId()));
return criteria.uniqueResult();
}
});
}
/**
* @see StepDao#findSteps(JobInstance)
*
* Hibernate is asked to get all jobs that matches criteria. Afterwards, result is mapped into domain objects.
* It should be noted that restart data must be requested separately.
*
*/
public List findSteps(final JobInstance job) {
Assert.notNull(job, "JobId cannot be null.");
List list = this.getHibernateTemplate().executeFind(new HibernateCallback() {
public Object doInHibernate(Session session) {
Criteria criteria = session.createCriteria(StepInstance.class);
criteria.add(Expression.eq("job.id", job.getId()));
return criteria.list();
}
});
return list;
}
/**
* @see StepDao#getStepExecutionCount(Long)
*/
public int getStepExecutionCount(final Long stepId) {
Long result = (Long) this.getHibernateTemplate().execute(new HibernateCallback() {
public Object doInHibernate(Session session) {
return session.createQuery("select count(id) from StepExecution s where s.step.id = :stepId")
.setLong("stepId", stepId.longValue())
.uniqueResult();
}
});
return (result==null) ? 0 :result.intValue();
}
/**
* @see StepDao#save(StepExecution)
*
* Hibernate implementation persists StepExecution instance. Id is obtained from Hibernate.
*/
public void save(StepExecution stepExecution) {
validateStepExecution(stepExecution);
Long id = (Long)getHibernateTemplate().save(stepExecution);
stepExecution.setId(id);
}
/**
* @see StepDao#update(StepInstance)
*/
public void update(StepInstance step) {
Assert.notNull(step, "Step cannot be null.");
Assert.notNull(step.getStatus(), "Step status cannot be null.");
Assert.notNull(step.getId(), "Step Id cannot be null.");
getHibernateTemplate().update(step);
}
/**
* @see StepDao#update(StepExecution)
*/
public void update(StepExecution stepExecution) {
validateStepExecution(stepExecution);
Assert.notNull(stepExecution.getId(), "StepExecution Id cannot be null. StepExecution must saved" +
" before it can be updated.");
getHibernateTemplate().update(stepExecution);
}
public List findStepExecutions(final StepInstance step) {
Assert.notNull(step, "Step cannot be null.");
List results = this.getHibernateTemplate().executeFind(new HibernateCallback() {
public Object doInHibernate(Session session) {
Criteria criteria = session.createCriteria(StepExecution.class);
criteria.add(Expression.eq("step.id", step.getId()));
return criteria.list();
}
});
return results;
}
/*
* Validate StepExecution. At a minimum, JobId, StartTime, EndTime, and Status cannot be
* null. EndTime can be null for an unfinished job.
*
* @param jobExecution
* @throws IllegalArgumentException
*/
private void validateStepExecution(StepExecution stepExecution){
Assert.notNull(stepExecution);
Assert.notNull(stepExecution.getStepId(), "StepExecution Step-Id cannot be null.");
Assert.notNull(stepExecution.getStartTime(), "StepExecution start time cannot be null.");
Assert.notNull(stepExecution.getStatus(), "StepExecution status cannot be null.");
}
}

View File

@@ -1,68 +0,0 @@
package org.springframework.batch.execution.repository.dao;
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.hibernate.HibernateException;
import org.hibernate.usertype.UserType;
/**
* A base class for user types that map immutable values (objects that cannot be
* changed after construction and may be safely shared).
*
* @author Ben Hale
* @author Dave Syer
*/
public abstract class ImmutableValueUserType implements UserType {
public Object assemble(Serializable cached, Object owner)
throws HibernateException {
return cached;
}
public Object deepCopy(Object value) throws HibernateException {
return value;
}
public Serializable disassemble(Object value) throws HibernateException {
return (Serializable) value;
}
public boolean equals(Object x, Object y) throws HibernateException {
if (x==null && y==null) {
return true;
}
if (x==null) {
return false;
}
return x.equals(y);
}
public int hashCode(Object x) throws HibernateException {
return x.hashCode();
}
public boolean isMutable() {
return false;
}
public Object replace(Object original, Object target, Object owner)
throws HibernateException {
return original;
}
// subclasses must implement the following methods
public abstract Class returnedClass();
public abstract int[] sqlTypes();
public abstract Object nullSafeGet(ResultSet rs, String[] names,
Object owner) throws HibernateException, SQLException;
public abstract void nullSafeSet(PreparedStatement st, Object value,
int index) throws HibernateException, SQLException;
}

View File

@@ -1,131 +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.repository.dao;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import org.springframework.batch.core.domain.JobIdentifier;
import org.springframework.batch.core.domain.JobInstance;
import org.springframework.batch.execution.runtime.DefaultJobIdentifier;
import org.springframework.batch.execution.runtime.ScheduledJobIdentifier;
import org.springframework.util.ClassUtils;
/**
* An {@link EntityNameLocator} that knows about {@link JobIdentifier} class
* types and translates them into entity names that are recongnized by
* Hibernate. The implementation is actually generic, and can be used as a
* general purpose {@link EntityNameLocator} by setting the
* {@link #identifierTypes} property. By default it knows about all the entity
* types that work out of the box with Spring Batch.
*
* @author Dave Syer
*
*/
public class JobIdentifierEntityNameLocator implements EntityNameLocator {
private static final String SIMPLE_JOB_INSTANCE = "SimpleJobInstance";
private Map identifierTypes;
private Set entrySet;
public JobIdentifierEntityNameLocator() {
Map types = new HashMap();
types.put(ScheduledJobIdentifier.class, "ScheduledJobInstance");
types.put(DefaultJobIdentifier.class, "DefaultJobInstance");
setIdentifierTypes(types);
};
/**
* Public setter for the identifier types. A map from Class (the
* {@link JobIdentifier} implementation) to String (the entity name). If a
* map from String to String is provided it will be interpreted as a map
* from class name to entity name.
*
* @throws IllegalArgumentException
* if a String key is provided that is not a Class name.
*
* @param types
* the identifierTypes to set
*/
public void setIdentifierTypes(Map types) {
this.identifierTypes = new HashMap();
for (Iterator iterator = types.entrySet().iterator(); iterator
.hasNext();) {
Map.Entry entry = (Map.Entry) iterator.next();
Object key = entry.getKey();
if (key instanceof Class) {
identifierTypes.put(key, entry.getValue());
} else {
try {
Class classKey = ClassUtils.forName(key.toString());
identifierTypes.put(classKey, entry.getValue());
} catch (ClassNotFoundException e) {
throw new IllegalArgumentException(
"Could not convert key in identifierTypes to type Class: ["
+ key + "]", e);
}
}
}
this.entrySet = new TreeSet(new ClassComparator());
entrySet.addAll(identifierTypes.keySet());
}
/**
* Identify a {@link JobInstance} entity type from the given
* {@link JobIdentifier} class.
*
* @see org.springframework.batch.execution.repository.dao.EntityNameLocator#locate(java.lang.Class)
*/
public String locate(Class clz) {
for (Iterator iterator = entrySet.iterator(); iterator.hasNext();) {
Class key = (Class) iterator.next();
if (key.isAssignableFrom(clz)) {
return (String) identifierTypes.get(key);
}
}
return SIMPLE_JOB_INSTANCE;
}
/**
* Comparator for classes to order by inheritance.
*
* @author Dave Syer
*
*/
private class ClassComparator implements Comparator {
/**
* @return 1 if arg0 is assignable from arg1
* @return -1 otherwise
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
*/
public int compare(Object arg0, Object arg1) {
Class cls0 = (Class) arg0;
Class cls1 = (Class) arg1;
if (cls0.isAssignableFrom(cls1)) {
return 1;
}
return -1;
}
}
}

View File

@@ -1,65 +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.repository.dao;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
import org.springframework.batch.support.PropertiesConverter;
import org.springframework.jdbc.support.lob.LobCreator;
import org.springframework.jdbc.support.lob.LobHandler;
import org.springframework.orm.hibernate3.support.ClobStringType;
/**
* User type object to help Hibernate to persist Poperties objects
* (just plonking it a Clob).
*
* @author Dave Syer
*
*/
public class PropertiesUserType extends ClobStringType {
/**
* Get a {@link Properties} from a Clob.
*
* @return a {@link Properties} object whose string representation is the
* same as the database value.
*
* @see org.springframework.orm.hibernate3.support.ClobStringType#nullSafeGetInternal(java.sql.ResultSet,
* java.lang.String[], java.lang.Object,
* org.springframework.jdbc.support.lob.LobHandler)
*/
protected Object nullSafeGetInternal(ResultSet rs, String[] names, Object owner, LobHandler lobHandler)
throws SQLException {
final String value = (String) super.nullSafeGetInternal(rs, names, owner, lobHandler);
return PropertiesConverter.stringToProperties(value);
}
/**
* Convert a {@link Properties} object to a string and then pop it in a Clob.
*
* @see org.springframework.orm.hibernate3.support.ClobStringType#nullSafeSetInternal(java.sql.PreparedStatement, int, java.lang.Object, org.springframework.jdbc.support.lob.LobCreator)
*/
protected void nullSafeSetInternal(PreparedStatement ps, int index, Object value, LobCreator lobCreator)
throws SQLException {
String string = PropertiesConverter.propertiesToString((Properties)value);
super.nullSafeSetInternal(ps, index, string, lobCreator);
}
}

View File

@@ -1,68 +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.repository.dao;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
import org.springframework.batch.restart.GenericRestartData;
import org.springframework.batch.restart.RestartData;
import org.springframework.batch.support.PropertiesConverter;
import org.springframework.jdbc.support.lob.LobCreator;
import org.springframework.jdbc.support.lob.LobHandler;
import org.springframework.orm.hibernate3.support.ClobStringType;
/**
* User type object to help Hibernate persist (@link RestartData) objects by setting
* a string in a clob.
*
* @author Lucas Ward
*
*/
public class RestartDataUserType extends ClobStringType {
/**
* Get a {@link Properties} from a Clob.
*
* @return a {@link GenericRestartData} object whose internal properties string representation is the
* same as the database value.
*
* @see org.springframework.orm.hibernate3.support.ClobStringType#nullSafeGetInternal(java.sql.ResultSet,
* java.lang.String[], java.lang.Object,
* org.springframework.jdbc.support.lob.LobHandler)
*/
protected Object nullSafeGetInternal(ResultSet rs, String[] names, Object owner, LobHandler lobHandler)
throws SQLException {
final String value = (String) super.nullSafeGetInternal(rs, names, owner, lobHandler);
return new GenericRestartData(PropertiesConverter.stringToProperties(value));
}
/**
* Convert a {@link RestartData} object to a string and then pop it in a Clob.
*
* @see org.springframework.orm.hibernate3.support.ClobStringType#nullSafeSetInternal(java.sql.PreparedStatement, int, java.lang.Object, org.springframework.jdbc.support.lob.LobCreator)
*/
protected void nullSafeSetInternal(PreparedStatement ps, int index, Object value, LobCreator lobCreator)
throws SQLException {
final RestartData restartData = (RestartData)value;
String string = (restartData == null) ? ""
:PropertiesConverter.propertiesToString(restartData.getProperties());
super.nullSafeSetInternal(ps, index, string, lobCreator);
}
}

View File

@@ -1,26 +0,0 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" [
<!ENTITY % globals SYSTEM "classpath://org/springframework/batch/execution/repository/dao/globals.dtd">
%globals;
]>
<hibernate-mapping package="org.springframework.batch.core.domain">
<class name="JobExecution" table="BATCH_JOB_EXECUTION">
<id name="id" type="long" column="ID">
&job-execution-generator;
</id>
<version name="version" access="field"/>
<many-to-one name="job" cascade="all" update="false" column="JOB_ID" access="field"/>
<property name="startTime" column="START_TIME" />
<property name="endTime" column="END_TIME" />
<property name="status" type="org.springframework.batch.execution.repository.dao.BatchStatusUserType" column="STATUS" length="10"/>
<property name="exitStatus" type="org.springframework.batch.execution.repository.dao.ExitStatusUserType">
<column name="CONTINUABLE"/>
<column name="EXIT_CODE" length="20"/>
<column name="EXIT_MESSAGE" length="250"/>
</property>
</class>
</hibernate-mapping>

View File

@@ -1,58 +0,0 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" [
<!ENTITY % globals SYSTEM "classpath://org/springframework/batch/execution/repository/dao/globals.dtd">
%globals;
]>
<hibernate-mapping package="org.springframework.batch.core.domain">
<class name="JobInstance" table="BATCH_JOB">
<id name="id" type="long" column="ID">
&job-generator;
</id>
<discriminator
formula="case when JOB_KEY is NULL then 'Simple' when SCHEDULE_DATE is NULL then 'Default' else 'Scheduled' end"
type="string" />
<version name="version" access="field" />
<property name="status"
type="org.springframework.batch.execution.repository.dao.BatchStatusUserType"
insert="false" column="STATUS" />
<subclass entity-name="ScheduledJobInstance" name="JobInstance"
discriminator-value="Scheduled">
<component name="identifier" access="field"
class="org.springframework.batch.execution.runtime.ScheduledJobIdentifier">
<property name="name" update="false" column="JOB_NAME" />
<property name="jobKey" update="false"
column="JOB_KEY" length="250"/>
<property name="scheduleDate" update="false"
column="SCHEDULE_DATE" />
</component>
</subclass>
<subclass entity-name="DefaultJobInstance" name="JobInstance"
discriminator-value="Default">
<component name="identifier" access="field"
class="org.springframework.batch.execution.runtime.ScheduledJobIdentifier">
<property name="name" update="false" column="JOB_NAME" />
<property name="jobKey" update="false"
column="JOB_KEY" length="250"/>
</component>
</subclass>
<subclass entity-name="SimpleJobInstance" name="JobInstance"
discriminator-value="Simple">
<component name="identifier" access="field"
class="org.springframework.batch.core.runtime.SimpleJobIdentifier">
<property name="name" update="false" column="JOB_NAME" />
</component>
</subclass>
</class>
</hibernate-mapping>

View File

@@ -1,31 +0,0 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" [
<!ENTITY % globals SYSTEM "classpath://org/springframework/batch/execution/repository/dao/globals.dtd">
%globals;
]>
<hibernate-mapping package="org.springframework.batch.core.domain">
<class name="StepExecution" table="BATCH_STEP_EXECUTION">
<id name="id" type="long" column="ID">
&step-execution-generator;
</id>
<version name="version" access="field"/>
<many-to-one name="step" update="false" column="STEP_ID" access="field"/>
<many-to-one name="jobExecution" cascade="all" update="false" column="JOB_EXECUTION_ID" access="field"/>
<property name="startTime" column="START_TIME" />
<property name="endTime" column="END_TIME" />
<property name="status" type="org.springframework.batch.execution.repository.dao.BatchStatusUserType" column="STATUS" length="10"/>
<property name="commitCount" column="COMMIT_COUNT" />
<property name="taskCount" column="TASK_COUNT" />
<property name="statistics" type="org.springframework.batch.execution.repository.dao.PropertiesUserType" column="TASK_STATISTICS" length="250"/>
<property name="exitStatus" type="org.springframework.batch.execution.repository.dao.ExitStatusUserType">
<column name="CONTINUABLE"/>
<column name="EXIT_CODE" length="20"/>
<column name="EXIT_MESSAGE" length="250"/>
</property>
</class>
</hibernate-mapping>

View File

@@ -1,23 +0,0 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" [
<!ENTITY % globals SYSTEM "classpath://org/springframework/batch/execution/repository/dao/globals.dtd">
%globals;
]>
<hibernate-mapping package="org.springframework.batch.core.domain">
<class name="StepInstance" table="BATCH_STEP">
<id name="id" type="long" column="ID">
&step-generator;
</id>
<version name="version" access="field"/>
<many-to-one name="job" update="false" column="JOB_ID" access="field"/>
<property name="name" update="false" column="STEP_NAME" access="field"/>
<property name="restartData"
type="org.springframework.batch.execution.repository.dao.RestartDataUserType" insert="false"
column="RESTART_DATA" length="250"/>
<property name="status" type="org.springframework.batch.execution.repository.dao.BatchStatusUserType"
insert="false" column="STATUS" length="10"/>
</class>
</hibernate-mapping>

View File

@@ -1,20 +0,0 @@
<!-- To switch between native and sequence generators, switch the IGNORE/INCLUDE -->
<!ENTITY % native 'INCLUDE'>
<!ENTITY % sequence 'IGNORE'>
<![%native;[
<!ENTITY % native-generator '<generator class="native" />'>
<!ENTITY job-generator "%native-generator;">
<!ENTITY job-execution-generator "%native-generator;">
<!ENTITY step-generator "%native-generator;">
<!ENTITY step-execution-generator "%native-generator;">
]]>
<![%sequence;[
<!ENTITY % open '<generator class="sequence"><param name="sequence">'>
<!ENTITY % close '</param></generator>'>
<!ENTITY job-generator "%open;BATCH_JOB_SEQ%close;">
<!ENTITY job-execution-generator "%open;BATCH_JOB_EXECUTION_SEQ%close;">
<!ENTITY step-generator "%open;BATCH_STEP_SEQ%close;">
<!ENTITY step-execution-generator "%open;BATCH_STEP_EXECUTION_SEQ%close;">
]]>

View File

@@ -1,82 +0,0 @@
package org.springframework.batch.execution.repository.dao;
import junit.framework.TestCase;
import org.hibernate.type.Type;
import org.springframework.batch.core.domain.JobExecution;
import org.springframework.batch.core.domain.JobInstance;
import org.springframework.batch.execution.runtime.ScheduledJobIdentifier;
import org.springframework.batch.repeat.ExitStatus;
public class BatchHibernateInterceptorTests extends TestCase {
public static final String LONG_STRING = "A very long description: \n" +
"Nov 16 20:10:42 util.JDBCExceptionReporter 78 - Data truncation: Data too long for column 'exit_message' at row 1\n" +
"Nov 16 20:10:43 def.AbstractFlushingEventListener 301 - Could not synchronize database state with session \n" +
"org.hibernate.exception.DataException: could not update: [org.springframework.batch.core.domain.JobExecution#67]\n" +
" at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:77)\n";
private BatchHibernateInterceptor interceptor = new BatchHibernateInterceptor();
/* (non-Javadoc)
* @see junit.framework.TestCase#setUp()
*/
protected void setUp() throws Exception {
super.setUp();
interceptor.setEntityNameLocator(new EntityNameLocator() {
public String locate(Class clz) {
return "foo";
}
});
}
public void testAfterPropertiesSet() throws Exception {
interceptor = new BatchHibernateInterceptor();
try {
interceptor.afterPropertiesSet();
fail("Expected IllegalArgumentException");
} catch (IllegalArgumentException e) {
// expected
}
}
public void testGetEntityName() {
JobInstance job = new JobInstance(new ScheduledJobIdentifier("foo"));
assertEquals("foo", interceptor.getEntityName(job));
}
public void testGetEntityNameForNonJobInstance() {
Object job = new Object();
assertEquals(null, interceptor.getEntityName(job));
}
public void testOnFlushDirtyWithJobInstance() throws Exception {
JobInstance job = new JobInstance(new ScheduledJobIdentifier("foo"));
assertFalse(interceptor.onFlushDirty(job, null, new Object[1], new Object[1], new String[] {"exitStatus"}, new Type[1]));
}
public void testOnFlushDirtyWithShortDescription() throws Exception {
JobExecution execution = new JobExecution(new JobInstance(new ScheduledJobIdentifier("foo")));
execution.setExitStatus(ExitStatus.UNKNOWN.addExitDescription("bar"));
assertFalse(interceptor.onFlushDirty(execution, null, new Object[] {execution.getExitStatus()}, new Object[1], new String[] {"exitStatus"}, new Type[1]));
}
public void testOnFlushDirtyWithLongDescription() throws Exception {
JobExecution execution = new JobExecution(new JobInstance(new ScheduledJobIdentifier("foo")));
execution.setExitStatus(ExitStatus.UNKNOWN.addExitDescription(LONG_STRING));
Object[] state = new Object[] {execution.getExitStatus()};
assertTrue(interceptor.onFlushDirty(execution, null, state, new Object[1], new String[] {"exitStatus"}, new Type[1]));
assertEquals(250, ((ExitStatus) state[0]).getExitDescription().length());
}
public void testOnFlushDirtyWithMissingExitStatusProperty() throws Exception {
JobExecution execution = new JobExecution(new JobInstance(new ScheduledJobIdentifier("foo")));
execution.setExitStatus(ExitStatus.UNKNOWN.addExitDescription("bar"));
try {
interceptor.onFlushDirty(execution, null, new Object[] {execution.getExitStatus()}, new Object[1], new String[1], new Type[1]);
fail("Expected ArrayIndexOutOfBoundsException");
} catch (ArrayIndexOutOfBoundsException e) {
// expected;
}
}
}

View File

@@ -1,51 +0,0 @@
package org.springframework.batch.execution.repository.dao;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Types;
import junit.framework.TestCase;
import org.easymock.MockControl;
import org.springframework.batch.repeat.ExitStatus;
public class ExitStatusUserTypeTests extends TestCase {
ExitStatusUserType type = new ExitStatusUserType();
public void testReturnedClass() {
assertEquals(ExitStatus.class, type.returnedClass());
}
public void testSqlTypes() {
int[] types = type.sqlTypes();
assertEquals(3, types.length);
assertEquals(Types.CHAR, types[0]);
}
public void testNullSafeGet() throws Exception {
String[] names = new String[] {"a", "b", "c"};
MockControl control = MockControl.createControl(ResultSet.class);
ResultSet rs = (ResultSet) control.getMock();
control.expectAndReturn(rs.getString(names[0]), "Y");
control.expectAndReturn(rs.getString(names[1]), "foo");
control.expectAndReturn(rs.getString(names[2]), "bar");
control.replay();
Object result = type.nullSafeGet(rs, names, null);
assertNotNull(result);
assertTrue(result instanceof ExitStatus);
control.verify();
}
public void testNullSafeSet() throws Exception {
MockControl control = MockControl.createControl(PreparedStatement.class);
PreparedStatement st = (PreparedStatement) control.getMock();
st.setString(2, "Y");
st.setString(3, ExitStatus.CONTINUABLE.getExitCode());
st.setString(4, ExitStatus.CONTINUABLE.getExitDescription());
control.replay();
type.nullSafeSet(st, ExitStatus.CONTINUABLE, 2);
control.verify();
}
}

View File

@@ -1,150 +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.repository.dao;
import java.sql.Timestamp;
import java.util.List;
import java.util.Map;
import org.hibernate.SessionFactory;
import org.springframework.batch.core.domain.BatchStatus;
import org.springframework.batch.core.domain.JobIdentifier;
import org.springframework.batch.core.domain.JobInstance;
import org.springframework.batch.core.runtime.SimpleJobIdentifier;
import org.springframework.batch.execution.runtime.ScheduledJobIdentifier;
import org.springframework.batch.repeat.ExitStatus;
import org.springframework.util.ClassUtils;
public class HibernateJobDaoTests extends AbstractJobDaoTests {
private static final String LONG_STRING = BatchHibernateInterceptorTests.LONG_STRING;
private SessionFactory sessionFactory;
protected String[] getConfigLocations() {
return new String[] { ClassUtils.addResourcePathToPackagePath(
getClass(), "hibernate-dao-test.xml") };
}
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public void testUpdateJobExecution() {
jobExecution.setStatus(BatchStatus.COMPLETED);
jobExecution.setEndTime(new Timestamp(System.currentTimeMillis()));
jobDao.update(jobExecution);
sessionFactory.getCurrentSession().flush();
List executions = jdbcTemplate.queryForList(
"SELECT * FROM BATCH_JOB_EXECUTION where JOB_ID=?",
new Object[] { job.getId() });
assertEquals(1, executions.size());
assertEquals(jobExecution.getEndTime(), ((Map) executions.get(0))
.get("END_TIME"));
}
public void testUpdateDetachedJobExecution() {
sessionFactory.getCurrentSession().evict(jobExecution);
jobExecution.setStatus(BatchStatus.COMPLETED);
jobExecution.setEndTime(new Timestamp(System.currentTimeMillis()));
jobDao.update(jobExecution);
sessionFactory.getCurrentSession().flush();
List executions = jdbcTemplate.queryForList(
"SELECT * FROM BATCH_JOB_EXECUTION where JOB_ID=?",
new Object[] { job.getId() });
assertEquals(1, executions.size());
assertEquals(jobExecution.getEndTime(), ((Map) executions.get(0))
.get("END_TIME"));
}
public void testCreateSimpleJobExecution() {
JobIdentifier simpleIdentifier = new SimpleJobIdentifier("SimpleJob");
JobInstance simpleJob = jobDao.createJob(simpleIdentifier);
List jobs = jobDao.findJobs(simpleIdentifier);
assertEquals(jobs.size(), 1);
JobInstance testJob = (JobInstance) jobs.get(0);
assertEquals(simpleJob, testJob);
}
public void testUpdateJobExecutionWithLongExitCode() {
assertTrue(LONG_STRING.length()>250);
jobExecution.setExitStatus(ExitStatus.FINISHED.addExitDescription(LONG_STRING));
jobDao.update(jobExecution);
sessionFactory.getCurrentSession().flush();
List executions = jdbcTemplate.queryForList(
"SELECT * FROM BATCH_JOB_EXECUTION where JOB_ID=?",
new Object[] { job.getId() });
assertEquals(1, executions.size());
assertEquals(LONG_STRING.substring(0, 250), ((Map) executions.get(0))
.get("EXIT_MESSAGE"));
}
public void testNullIdentifierName() {
JobIdentifier simpleIdentifier = new SimpleJobIdentifier(null);
try {
jobDao.createJob(simpleIdentifier);
fail();
} catch (IllegalArgumentException ex) {
// expected
}
}
public void testEmptyIdentifierName() {
JobIdentifier simpleIdentifier = new SimpleJobIdentifier("");
try {
jobDao.createJob(simpleIdentifier);
fail();
} catch (IllegalArgumentException ex) {
// expected
}
}
public void testNullScheduleDate() {
ScheduledJobIdentifier scheduledIdentifier = new ScheduledJobIdentifier(
"ScheduledJob");
scheduledIdentifier.setJobKey(null);
try {
jobDao.createJob(scheduledIdentifier);
fail();
} catch (IllegalArgumentException ex) {
// expected
}
}
}

View File

@@ -1,100 +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.repository.dao;
import java.sql.Timestamp;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.hibernate.SessionFactory;
import org.springframework.batch.core.domain.BatchStatus;
import org.springframework.batch.core.domain.JobExecution;
import org.springframework.batch.core.domain.StepExecution;
import org.springframework.batch.core.domain.StepInstance;
import org.springframework.batch.repeat.ExitStatus;
import org.springframework.batch.support.PropertiesConverter;
import org.springframework.util.ClassUtils;
public class HibernateStepDaoTests extends AbstractStepDaoTests {
private static final String LONG_STRING = BatchHibernateInterceptorTests.LONG_STRING;
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
protected String[] getConfigLocations() {
return new String[] { ClassUtils.addResourcePathToPackagePath(getClass(), "hibernate-dao-test.xml") };
}
public void testSaveStatistics() throws Exception {
StepInstance step = stepDao.createStep(job, "foo");
StepExecution stepExecution = new StepExecution(step, new JobExecution(step.getJob()));
Properties statistics = new Properties();
statistics.setProperty("x", "y");
statistics.setProperty("a", "b");
stepExecution.setStatistics(statistics);
stepDao.save(stepExecution);
sessionFactory.getCurrentSession().flush();
String returnedStatistics = (String) jdbcTemplate.queryForObject(
"SELECT TASK_STATISTICS from BATCH_STEP_EXECUTION where ID=?", new Object[] { stepExecution.getId() },
String.class);
Properties fromDb = PropertiesConverter.stringToProperties(returnedStatistics);
//assertEquals("x=y, a=b", returnedStatistics);
assertEquals(fromDb, statistics);
}
public void testUpdateDetachedStepExecution() {
sessionFactory.getCurrentSession().evict(stepExecution);
stepExecution.setStatus(BatchStatus.COMPLETED);
stepExecution.setEndTime(new Timestamp(System.currentTimeMillis()));
stepDao.update(stepExecution);
sessionFactory.getCurrentSession().flush();
List executions = jdbcTemplate.queryForList(
"SELECT * FROM BATCH_STEP_EXECUTION where STEP_ID=?",
new Object[] { step1.getId() });
assertEquals(1, executions.size());
assertEquals(stepExecution.getEndTime(), ((Map) executions.get(0))
.get("END_TIME"));
}
public void testUpdateStepExecutionWithLongDescription() {
assertTrue(LONG_STRING.length()>250);
stepExecution.setExitStatus(ExitStatus.FINISHED.addExitDescription(LONG_STRING));
stepDao.update(stepExecution);
sessionFactory.getCurrentSession().flush();
List executions = jdbcTemplate.queryForList(
"SELECT * FROM BATCH_STEP_EXECUTION where STEP_ID=?",
new Object[] { step1.getId() });
assertEquals(1, executions.size());
assertEquals(LONG_STRING.substring(0, 250), ((Map) executions.get(0))
.get("EXIT_MESSAGE"));
}
}

View File

@@ -1,73 +0,0 @@
package org.springframework.batch.execution.repository.dao;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.hibernate.HibernateException;
import junit.framework.TestCase;
public class ImmutableValueUserTypeTests extends TestCase {
ImmutableValueUserType type = new ImmutableValueUserType() {
public Object nullSafeGet(ResultSet rs, String[] names, Object owner)
throws HibernateException, SQLException {
return null;
}
public void nullSafeSet(PreparedStatement st, Object value, int index)
throws HibernateException, SQLException {
}
public Class returnedClass() {
return null;
}
public int[] sqlTypes() {
return null;
}
};
public void testAssemble() {
assertEquals("foo", type.assemble("foo", null));
}
public void testDeepCopy() {
assertEquals("foo", type.deepCopy("foo"));
}
public void testDisassemble() {
assertEquals("foo", type.disassemble("foo"));
}
public void testEqualsWithNullObjects() {
assertTrue(type.equals(null, null));
}
public void testEqualsWithFirstNullObject() {
assertFalse(type.equals(null, "foo"));
}
public void testEqualsWithSecondNullObject() {
assertFalse(type.equals("foo", null));
}
public void testEqualsWithEqualObjects() {
assertTrue(type.equals("foo", "foo"));
}
public void testEqualsWithUnEqualObjects() {
assertFalse(type.equals("foo", "bar"));
}
public void testHashCodeObject() {
assertEquals("foo".hashCode(), type.hashCode("foo"));
}
public void testIsMutable() {
assertFalse(type.isMutable());
}
public void testReplace() {
assertEquals("foo",type.replace("foo", "bar", null));
}
}

View File

@@ -1,65 +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.repository.dao;
import java.util.Collections;
import junit.framework.TestCase;
import org.springframework.batch.core.runtime.SimpleJobIdentifier;
import org.springframework.batch.execution.runtime.DefaultJobIdentifier;
import org.springframework.batch.execution.runtime.ScheduledJobIdentifier;
/**
* @author Dave Syer
*
*/
public class JobIdentiferEntityNameLocatorTests extends TestCase {
private JobIdentifierEntityNameLocator interceptor = new JobIdentifierEntityNameLocator();
public void testGetEntityNameForScheduledJobIdentifier() {
assertEquals("ScheduledJobInstance", interceptor.locate(ScheduledJobIdentifier.class));
}
public void testGetEntityNameForDefaultJobIdentifier() {
assertEquals("DefaultJobInstance", interceptor.locate(DefaultJobIdentifier.class));
}
public void testGetEntityNameForSimpleJobIdentifier() {
assertEquals("SimpleJobInstance", interceptor.locate(SimpleJobIdentifier.class));
}
public void testSetIdentifierTypesWithString() {
interceptor.setIdentifierTypes(Collections.singletonMap(ScheduledJobIdentifier.class.getName(), "foo"));
assertEquals("foo", interceptor.locate(ScheduledJobIdentifier.class));
}
public void testSetIdentifierTypesWithClass() {
interceptor.setIdentifierTypes(Collections.singletonMap(ScheduledJobIdentifier.class, "foo"));
assertEquals("foo", interceptor.locate(ScheduledJobIdentifier.class));
}
public void testSetIdentifierTypesWithInvalidClassName() {
try {
interceptor.setIdentifierTypes(Collections.singletonMap("FooBarNotAClass", "foo"));
fail("Expected IllegalArgumentException");
} catch (IllegalArgumentException e) {
// expected
}
}
}

View File

@@ -1,43 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<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-2.0.xsd">
<import resource="data-source-context.xml"/>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="mappingLocations">
<list>
<value>classpath:/org/springframework/batch/execution/repository/dao/JobInstance.hbm.xml</value>
<value>classpath:/org/springframework/batch/execution/repository/dao/JobExecution.hbm.xml</value>
<value>classpath:/org/springframework/batch/execution/repository/dao/StepInstance.hbm.xml</value>
<value>classpath:/org/springframework/batch/execution/repository/dao/StepExecution.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<value><![CDATA[
hibernate.show_sql=true
hibernate.format_sql=true
hibernate.dialect=org.hibernate.dialect.HSQLDialect
]]></value>
</property>
<property name="dataSource" ref="dataSource" />
<property name="lobHandler">
<bean class="org.springframework.jdbc.support.lob.DefaultLobHandler"/>
</property>
<property name="entityInterceptor">
<bean
class="org.springframework.batch.execution.repository.dao.BatchHibernateInterceptor">
<property name="entityNameLocator" ref="entityNameLocator"/>
</bean>
</property>
</bean>
<bean id="entityNameLocator"
class="org.springframework.batch.execution.repository.dao.JobIdentifierEntityNameLocator" />
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
</beans>

View File

@@ -1,15 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<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-2.0.xsd">
<import resource="hibernate-context.xml" />
<bean id="jobDao" class="org.springframework.batch.execution.repository.dao.HibernateJobDao">
<property name="sessionFactory" ref="sessionFactory"/>
<property name="entityNameLocator" ref="entityNameLocator"/>
</bean>
<bean id="stepDao" class="org.springframework.batch.execution.repository.dao.HibernateStepDao">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
</beans>

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src/main/java"/>
<classpathentry kind="src" output="bin/test-classes" path="src/test/java"/>
<classpathentry kind="src" output="bin/test-classes" path="src/test/resources"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>

View File

@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src/main/java"/>
<classpathentry kind="src" output="bin/test-classes" path="src/test/java"/>
<classpathentry kind="src" output="bin/test-classes" path="src/test/resources"/>
<classpathentry kind="src" path="src/main/resources"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>

10
pom.xml
View File

@@ -13,11 +13,11 @@
<packaging>pom</packaging>
<modules>
<module>infrastructure</module>
<module>core</module>
<module>execution</module>
<module>samples</module>
<module>integration</module>
<module>spring-batch-infrastructure</module>
<module>spring-batch-core</module>
<module>spring-batch-execution</module>
<module>spring-batch-samples</module>
<module>spring-batch-integration</module>
<module>docs</module>
</modules>

View File

@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src/main/java"/>
<classpathentry kind="src" path="src/main/resources"/>
<classpathentry kind="src" output="bin/test-classes" path="src/test/java"/>
<classpathentry kind="src" output="bin/test-classes" path="src/test/resources"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>

View File

@@ -1,54 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<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-2.0.xsd">
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
lazy-init="true">
<property name="mappingLocations">
<list>
<value>
classpath:/org/springframework/batch/execution/repository/dao/JobInstance.hbm.xml
</value>
<value>
classpath:/org/springframework/batch/execution/repository/dao/JobExecution.hbm.xml
</value>
<value>
classpath:/org/springframework/batch/execution/repository/dao/StepInstance.hbm.xml
</value>
<value>
classpath:/org/springframework/batch/execution/repository/dao/StepExecution.hbm.xml
</value>
</list>
</property>
<property name="hibernateProperties">
<value><![CDATA[
hibernate.show_sql=true
hibernate.format_sql=true
hibernate.dialect=org.hibernate.dialect.HSQLDialect
]]></value>
</property>
<property name="dataSource" ref="dataSource" />
<property name="lobHandler">
<bean
class="org.springframework.jdbc.support.lob.DefaultLobHandler" />
</property>
<property name="entityInterceptor">
<bean
class="org.springframework.batch.execution.repository.dao.EntityNameInterceptor">
<property name="entityNameLocator" ref="entityNameLocator"/>
</bean>
</property>
</bean>
<bean id="entityNameLocator"
class="org.springframework.batch.execution.repository.dao.JobIdentifierEntityNameLocator" />
<bean id="hibernateTransactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager"
lazy-init="true">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
</beans>

View File

@@ -0,0 +1,25 @@
<classpath>
<classpathentry kind="src" path="src/main/java"/>
<classpathentry kind="src" path="src/main/resources" excluding="**/*.java"/>
<classpathentry kind="src" path="src/test/java" output="target/test-classes"/>
<classpathentry kind="src" path="src/test/resources" output="target/test-classes" excluding="**/*.java"/>
<classpathentry kind="output" path="target/classes"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="var" path="M2_REPO/commons-logging/commons-logging/1.1/commons-logging-1.1.jar" sourcepath="M2_REPO/commons-logging/commons-logging/1.1/commons-logging-1.1-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-beans/2.5/spring-beans-2.5.jar" sourcepath="M2_REPO/org/springframework/spring-beans/2.5/spring-beans-2.5-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/aopalliance/aopalliance/1.0/aopalliance-1.0.jar" sourcepath="M2_REPO/aopalliance/aopalliance/1.0/aopalliance-1.0-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/commons-lang/commons-lang/2.1/commons-lang-2.1.jar" sourcepath="M2_REPO/commons-lang/commons-lang/2.1/commons-lang-2.1-sources.jar"/>
<classpathentry kind="src" path="/spring-batch-infrastructure"/>
<classpathentry kind="var" path="M2_REPO/commons-pool/commons-pool/1.3/commons-pool-1.3.jar"/>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-tx/2.5/spring-tx-2.5.jar" sourcepath="M2_REPO/org/springframework/spring-tx/2.5/spring-tx-2.5-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-context-support/2.5/spring-context-support-2.5.jar" sourcepath="M2_REPO/org/springframework/spring-context-support/2.5/spring-context-support-2.5-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-jdbc/2.5/spring-jdbc-2.5.jar" sourcepath="M2_REPO/org/springframework/spring-jdbc/2.5/spring-jdbc-2.5-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-context/2.5/spring-context-2.5.jar" sourcepath="M2_REPO/org/springframework/spring-context/2.5/spring-context-2.5-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-aop/2.5/spring-aop-2.5.jar" sourcepath="M2_REPO/org/springframework/spring-aop/2.5/spring-aop-2.5-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/backport-util-concurrent/backport-util-concurrent/3.0/backport-util-concurrent-3.0.jar" sourcepath="M2_REPO/backport-util-concurrent/backport-util-concurrent/3.0/backport-util-concurrent-3.0-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/easymock/easymock/1.1/easymock-1.1.jar" sourcepath="M2_REPO/easymock/easymock/1.1/easymock-1.1-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-jms/2.5/spring-jms-2.5.jar" sourcepath="M2_REPO/org/springframework/spring-jms/2.5/spring-jms-2.5-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/junit/junit/3.8.1/junit-3.8.1.jar" sourcepath="M2_REPO/junit/junit/3.8.1/junit-3.8.1-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-core/2.5/spring-core-2.5.jar" sourcepath="M2_REPO/org/springframework/spring-core/2.5/spring-core-2.5-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-orm/2.5/spring-orm-2.5.jar" sourcepath="M2_REPO/org/springframework/spring-orm/2.5/spring-orm-2.5-sources.jar"/>
</classpath>

View File

@@ -1,8 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>batch-integration</name>
<comment></comment>
<name>spring-batch-core</name>
<comment>Core domain for batch processing, expressing a domain of Jobs, Steps, Chunks, etc.</comment>
<projects>
<project>spring-batch-infrastructure</project>
</projects>
<buildSpec>
<buildCommand>
@@ -15,15 +16,9 @@
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.maven.ide.eclipse.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.maven.ide.eclipse.maven2Nature</nature>
<nature>org.springframework.ide.eclipse.core.springnature</nature>
</natures>
</projectDescription>

View File

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

View File

@@ -0,0 +1,28 @@
<classpath>
<classpathentry kind="src" path="src/main/java"/>
<classpathentry kind="src" path="src/main/resources" excluding="**/*.java"/>
<classpathentry kind="src" path="src/test/java" output="target/test-classes"/>
<classpathentry kind="src" path="src/test/resources" output="target/test-classes" excluding="**/*.java"/>
<classpathentry kind="output" path="target/classes"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="var" path="M2_REPO/easymock/easymock/1.1/easymock-1.1.jar" sourcepath="M2_REPO/easymock/easymock/1.1/easymock-1.1-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-tx/2.5/spring-tx-2.5.jar" sourcepath="M2_REPO/org/springframework/spring-tx/2.5/spring-tx-2.5-sources.jar"/>
<classpathentry kind="src" path="/spring-batch-infrastructure"/>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-context/2.5/spring-context-2.5.jar" sourcepath="M2_REPO/org/springframework/spring-context/2.5/spring-context-2.5-sources.jar"/>
<classpathentry kind="src" path="/spring-batch-core"/>
<classpathentry kind="var" path="M2_REPO/commons-lang/commons-lang/2.1/commons-lang-2.1.jar" sourcepath="M2_REPO/commons-lang/commons-lang/2.1/commons-lang-2.1-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-core/2.5/spring-core-2.5.jar" sourcepath="M2_REPO/org/springframework/spring-core/2.5/spring-core-2.5-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-jms/2.5/spring-jms-2.5.jar" sourcepath="M2_REPO/org/springframework/spring-jms/2.5/spring-jms-2.5-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/hsqldb/hsqldb/1.8.0.7/hsqldb-1.8.0.7.jar"/>
<classpathentry kind="var" path="M2_REPO/aopalliance/aopalliance/1.0/aopalliance-1.0.jar" sourcepath="M2_REPO/aopalliance/aopalliance/1.0/aopalliance-1.0-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/commons-io/commons-io/1.2/commons-io-1.2.jar" sourcepath="M2_REPO/commons-io/commons-io/1.2/commons-io-1.2-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-jdbc/2.5/spring-jdbc-2.5.jar" sourcepath="M2_REPO/org/springframework/spring-jdbc/2.5/spring-jdbc-2.5-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/commons-pool/commons-pool/1.3/commons-pool-1.3.jar"/>
<classpathentry kind="var" path="M2_REPO/junit/junit/3.8.1/junit-3.8.1.jar" sourcepath="M2_REPO/junit/junit/3.8.1/junit-3.8.1-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-aop/2.5/spring-aop-2.5.jar" sourcepath="M2_REPO/org/springframework/spring-aop/2.5/spring-aop-2.5-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-context-support/2.5/spring-context-support-2.5.jar" sourcepath="M2_REPO/org/springframework/spring-context-support/2.5/spring-context-support-2.5-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-orm/2.5/spring-orm-2.5.jar" sourcepath="M2_REPO/org/springframework/spring-orm/2.5/spring-orm-2.5-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-beans/2.5/spring-beans-2.5.jar" sourcepath="M2_REPO/org/springframework/spring-beans/2.5/spring-beans-2.5-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-test/2.5/spring-test-2.5.jar" sourcepath="M2_REPO/org/springframework/spring-test/2.5/spring-test-2.5-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/commons-logging/commons-logging/1.1/commons-logging-1.1.jar" sourcepath="M2_REPO/commons-logging/commons-logging/1.1/commons-logging-1.1-sources.jar"/>
</classpath>

Some files were not shown because too many files have changed in this diff Show More