commit eb866cd48c1f3fa513b12acddba4421cd66cd362 Author: trisberg Date: Thu Jun 10 16:50:23 2010 -0400 the beginning of the Sping Data Common sub-project diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/pom.xml b/pom.xml new file mode 100644 index 000000000..8c6115d75 --- /dev/null +++ b/pom.xml @@ -0,0 +1,211 @@ + + + 4.0.0 + org.springframework.data + common + jar + 1.0.0.SNAPSHOT + Spring Data Common Interfaces and Implementations + + 3.0.2.RELEASE + 1.6.0 + + + + spring-maven-snapshot + + true + + Springframework Maven SNAPSHOT Repository + http://maven.springframework.org/snapshot + + + spring-maven-milestone + + true + + Springframework Maven MILESTONE Repository + http://maven.springframework.org/milestone + + + + + + junit + junit + 4.8.1 + test + + + log4j + log4j + 1.2.15 + + + + javax.mail + mail + + + javax.jms + jms + + + com.sun.jdmk + jmxtools + + + com.sun.jmx + jmxri + + + + + org.slf4j + slf4j-api + ${slf4j.version} + + + org.slf4j + jcl-over-slf4j + ${slf4j.version} + + + org.slf4j + slf4j-log4j12 + ${slf4j.version} + + + + org.springframework + spring-core + ${spring.version} + + + commons-logging + commons-logging + + + + + org.springframework + spring-test + ${spring.version} + test + + + commons-logging + commons-logging + + + + + org.springframework + spring-context + ${spring.version} + + + org.springframework + spring-aop + ${spring.version} + + + org.springframework + spring-aspects + ${spring.version} + + + org.springframework + spring-tx + ${spring.version} + + + + org.mockito + mockito-core + 1.8.0 + test + + + org.mockito + mockito-all + 1.8.0 + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.1 + + 1.6 + 1.6 + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.5 + + + **/*_Roo_* + + + + + org.apache.maven.plugins + maven-assembly-plugin + 2.2-beta-5 + + + jar-with-dependencies + + + + + org.apache.maven.plugins + maven-deploy-plugin + 2.5 + + + + org.apache.maven.plugins + maven-eclipse-plugin + 2.7 + + true + false + 2.0 + + + org.eclipse.ajdt.core.ajbuilder + + org.springframework.aspects + + + + org.springframework.ide.eclipse.core.springbuilder + + + + org.eclipse.ajdt.ui.ajnature + com.springsource.sts.roo.core.nature + org.springframework.ide.eclipse.core.springnature + + + + + org.apache.maven.plugins + maven-idea-plugin + 2.2 + + true + true + + + + + diff --git a/src/main/java/org/springframework/data/serialization/SerializationStore.java b/src/main/java/org/springframework/data/serialization/SerializationStore.java new file mode 100644 index 000000000..dd4bd317c --- /dev/null +++ b/src/main/java/org/springframework/data/serialization/SerializationStore.java @@ -0,0 +1,13 @@ +package org.springframework.data.serialization; + +import java.lang.annotation.ElementType; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import java.lang.annotation.Retention; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface SerializationStore { + +} diff --git a/src/main/java/org/springframework/data/support/ChangeSet.java b/src/main/java/org/springframework/data/support/ChangeSet.java new file mode 100644 index 000000000..37ae15a0b --- /dev/null +++ b/src/main/java/org/springframework/data/support/ChangeSet.java @@ -0,0 +1,24 @@ +package org.springframework.data.support; + +import java.util.Map; + +import org.springframework.core.convert.ConversionService; + +/** + * Interface representing the set of changes in an entity. + * + * @author Rod Johnson + * @author Thomas Risberg + * + */ +public interface ChangeSet { + + T get(String key, Class requiredClass, ConversionService cs); + + void set(String key, Object o); + + Map getValues(); + + Object removeProperty(String k); + +} diff --git a/src/main/java/org/springframework/data/support/ChangeSetBacked.java b/src/main/java/org/springframework/data/support/ChangeSetBacked.java new file mode 100644 index 000000000..c291c4e6c --- /dev/null +++ b/src/main/java/org/springframework/data/support/ChangeSetBacked.java @@ -0,0 +1,13 @@ +package org.springframework.data.support; + + +/** + * Interface introduced to objects exposing ChangeSet information + * @author Rod Johnson + * @author Thomas Risberg + */ +public interface ChangeSetBacked { + + ChangeSet getChangeSet(); + +} diff --git a/src/main/java/org/springframework/data/support/ChangeSetPersister.java b/src/main/java/org/springframework/data/support/ChangeSetPersister.java new file mode 100644 index 000000000..b4a7d3465 --- /dev/null +++ b/src/main/java/org/springframework/data/support/ChangeSetPersister.java @@ -0,0 +1,47 @@ +package org.springframework.data.support; + +import org.springframework.dao.DataAccessException; + +/** + * Interface to be implemented by classes that can synchronize + * between data stores and ChangeSets. + * @author Rod Johnson + * + * @param entity key + */ +public interface ChangeSetPersister { + + String ID_KEY = "_id"; + + String CLASS_KEY = "_class"; + + /** + * TODO how to tell when not found? throw exception? + */ + void getPersistentState(Class entityClass, K key, ChangeSet changeSet) throws DataAccessException, NotFoundException; + + /** + * Return id + * @param cs + * @return + * @throws DataAccessException + */ + K getPersistentId(Class entityClass, ChangeSet cs) throws DataAccessException; + + /** + * Return key + * @param cs Key may be null if not persistent + * @return + * @throws DataAccessException + */ + K persistState(Class entityClass, ChangeSet cs) throws DataAccessException; + + /** + * Exception thrown in alternate control flow if getPersistentState + * finds no entity data. + */ + class NotFoundException extends Exception { + + } + +} diff --git a/src/main/java/org/springframework/data/support/ChangeSetSynchronizer.java b/src/main/java/org/springframework/data/support/ChangeSetSynchronizer.java new file mode 100644 index 000000000..6609052e1 --- /dev/null +++ b/src/main/java/org/springframework/data/support/ChangeSetSynchronizer.java @@ -0,0 +1,28 @@ +package org.springframework.data.support; + +import java.util.Map; + +import org.springframework.dao.DataAccessException; + +/** + * Interface to be implemented by classes that can synchronize + * between entities and ChangeSets. + * @author Rod Johnson + * + * @param + */ +public interface ChangeSetSynchronizer { + + Map> persistentFields(Class entityClassClass); + + /** + * Take all entity fields into a changeSet. + * @param entity + * @return + * @throws DataAccessException + */ + void populateChangeSet(ChangeSet changeSet, E entity) throws DataAccessException; + + void populateEntity(ChangeSet changeSet, E entity) throws DataAccessException; + +} diff --git a/src/main/java/org/springframework/data/support/HashMapChangeSet.java b/src/main/java/org/springframework/data/support/HashMapChangeSet.java new file mode 100644 index 000000000..a1a034bf3 --- /dev/null +++ b/src/main/java/org/springframework/data/support/HashMapChangeSet.java @@ -0,0 +1,51 @@ +package org.springframework.data.support; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.springframework.core.convert.ConversionService; + +/** + * Simple ChangeSet implementation backed by a HashMap. + * @author Thomas Risberg + * @author Rod Johnson + */ +public class HashMapChangeSet implements ChangeSet { + + private Map values; + + public HashMapChangeSet(Map values) { + this.values = values; + } + + public HashMapChangeSet() { + this(new HashMap()); + } + + @Override + public void set(String key, Object o) { + values.put(key, o); + } + + @Override + public String toString() { + return "HashMapChangeSet: values=[" + values + "]"; + } + + @Override + public Map getValues() { + return Collections.unmodifiableMap(values); + } + + @Override + public Object removeProperty(String k) { + return this.values.remove(k); + } + + @Override + public T get(String key, Class requiredClass, ConversionService conversionService) { + return conversionService.convert(values.get(key), requiredClass); + } + +} diff --git a/src/main/java/org/springframework/data/transaction/ChangedSetBackedTransactionSynchronization.java b/src/main/java/org/springframework/data/transaction/ChangedSetBackedTransactionSynchronization.java new file mode 100644 index 000000000..125970117 --- /dev/null +++ b/src/main/java/org/springframework/data/transaction/ChangedSetBackedTransactionSynchronization.java @@ -0,0 +1,69 @@ +package org.springframework.data.transaction; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.springframework.data.support.ChangeSetBacked; +import org.springframework.data.support.ChangeSetPersister; +import org.springframework.transaction.support.TransactionSynchronization; + +public class ChangedSetBackedTransactionSynchronization implements TransactionSynchronization { + + protected final Log log = LogFactory.getLog(getClass()); + + private ChangeSetPersister changeSetPersister; + + private ChangeSetBacked entity; + + private int changeSetTxStatus = -1; + + public ChangedSetBackedTransactionSynchronization(ChangeSetPersister changeSetPersister, ChangeSetBacked entity) { + this.changeSetPersister = changeSetPersister; + this.entity = entity; + } + + @Override + public void afterCommit() { + log.debug("After Commit called for " + entity); + changeSetPersister.persistState(entity.getClass(), entity.getChangeSet()); + changeSetTxStatus = 0; + } + + @Override + public void afterCompletion(int status) { + log.debug("After Completion called with status = " + status); + if (changeSetTxStatus == 0) { + if (status == STATUS_COMMITTED) { + // this is good + log.debug("ChangedSetBackedTransactionSynchronization completed successfully for " + this.entity); + } + else { + // this could be bad - TODO: compensate + log.error("ChangedSetBackedTransactionSynchronization failed for " + this.entity); + } + } + } + + @Override + public void beforeCommit(boolean readOnly) { + } + + @Override + public void beforeCompletion() { + } + + @Override + public void flush() { + } + + @Override + public void resume() { + throw new IllegalStateException("ChangedSetBackedTransactionSynchronization does not support transaction suspension currently."); + } + + @Override + public void suspend() { + throw new IllegalStateException("ChangedSetBackedTransactionSynchronization does not support transaction suspension currently."); + } + +}