the beginning of the Sping Data Common sub-project

This commit is contained in:
trisberg
2010-06-10 16:50:23 -04:00
commit eb866cd48c
9 changed files with 457 additions and 0 deletions

View File

@@ -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 {
}

View File

@@ -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> T get(String key, Class<T> requiredClass, ConversionService cs);
void set(String key, Object o);
Map<String, Object> getValues();
Object removeProperty(String k);
}

View File

@@ -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();
}

View File

@@ -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 <K> entity key
*/
public interface ChangeSetPersister<K> {
String ID_KEY = "_id";
String CLASS_KEY = "_class";
/**
* TODO how to tell when not found? throw exception?
*/
void getPersistentState(Class<? extends ChangeSetBacked> entityClass, K key, ChangeSet changeSet) throws DataAccessException, NotFoundException;
/**
* Return id
* @param cs
* @return
* @throws DataAccessException
*/
K getPersistentId(Class<? extends ChangeSetBacked> entityClass, ChangeSet cs) throws DataAccessException;
/**
* Return key
* @param cs Key may be null if not persistent
* @return
* @throws DataAccessException
*/
K persistState(Class<? extends ChangeSetBacked> entityClass, ChangeSet cs) throws DataAccessException;
/**
* Exception thrown in alternate control flow if getPersistentState
* finds no entity data.
*/
class NotFoundException extends Exception {
}
}

View File

@@ -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 <E>
*/
public interface ChangeSetSynchronizer<E extends ChangeSetBacked> {
Map<String, Class<?>> persistentFields(Class<? extends E> 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;
}

View File

@@ -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<String, Object> values;
public HashMapChangeSet(Map<String,Object> values) {
this.values = values;
}
public HashMapChangeSet() {
this(new HashMap<String, Object>());
}
@Override
public void set(String key, Object o) {
values.put(key, o);
}
@Override
public String toString() {
return "HashMapChangeSet: values=[" + values + "]";
}
@Override
public Map<String, Object> getValues() {
return Collections.unmodifiableMap(values);
}
@Override
public Object removeProperty(String k) {
return this.values.remove(k);
}
@Override
public <T> T get(String key, Class<T> requiredClass, ConversionService conversionService) {
return conversionService.convert(values.get(key), requiredClass);
}
}

View File

@@ -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<Object> changeSetPersister;
private ChangeSetBacked entity;
private int changeSetTxStatus = -1;
public ChangedSetBackedTransactionSynchronization(ChangeSetPersister<Object> 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.");
}
}