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:
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
@@ -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 };
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
@@ -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;">
|
||||
]]>
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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"));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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
10
pom.xml
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
25
spring-batch-core/.classpath
Normal file
25
spring-batch-core/.classpath
Normal 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>
|
||||
@@ -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>
|
||||
|
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 6.8 KiB |
|
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 7.8 KiB |
28
spring-batch-execution/.classpath
Normal file
28
spring-batch-execution/.classpath
Normal 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
Reference in New Issue
Block a user