JavaDataTransaction.java
package eu.javaexperience.datastorage.javaImpl;
import java.io.IOException;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import eu.javaexperience.collection.map.TransactionMap;
import eu.javaexperience.datastorage.DataTransaction;
import eu.javaexperience.datastorage.TransactionException;
import eu.javaexperience.interfaces.simple.SimpleGet;
import eu.javaexperience.interfaces.simple.SimpleGetFactory;
import eu.javaexperience.reflect.Mirror;
public class JavaDataTransaction implements DataTransaction
{
protected TransactionMap<String, Object> transactionMap;
public JavaDataTransaction(Map<String, Object> origin)
{
this(origin, (SimpleGet) SimpleGetFactory.getSmallMapFactory());
}
public JavaDataTransaction(Map<String, Object> origin, SimpleGet<Map> backendMapCreator)
{
transactionMap = new TransactionMap<String, Object>(origin, backendMapCreator);
}
protected boolean closed = false;
protected void assertOpen()
{
if(closed)
{
throw new RuntimeException("DataStorage is already closed");
}
}
@Override
public int size()
{
assertOpen();
return transactionMap.size();
}
@Override
public boolean isEmpty()
{
assertOpen();
return transactionMap.isEmpty();
}
@Override
public boolean containsKey(Object key)
{
assertOpen();
return transactionMap.containsKey(key);
}
@Override
public boolean containsValue(Object value)
{
assertOpen();
return transactionMap.containsValue(value);
}
@Override
public Object get(Object key)
{
assertOpen();
return transactionMap.get(key);
}
@Override
public Object put(String key, Object value)
{
assertOpen();
return transactionMap.put(key, value);
}
@Override
public Object remove(Object key)
{
assertOpen();
return transactionMap.remove(key);
}
@Override
public void putAll(Map<? extends String, ? extends Object> m)
{
assertOpen();
transactionMap.putAll(m);
}
@Override
public void clear()
{
assertOpen();
transactionMap.clear();
}
@Override
public Set<String> keySet()
{
assertOpen();
return transactionMap.keySet();
}
@Override
public Collection<Object> values()
{
assertOpen();
return transactionMap.values();
}
@Override
public Set<Entry<String, Object>> entrySet()
{
assertOpen();
return transactionMap.entrySet();
}
@Override
public void rollback()
{
closed = true;
}
@Override
public void close() throws IOException
{
closed = true;
}
@Override
public void commit() throws TransactionException
{
Map<String, Object> origin = transactionMap.getOriginalMap();
synchronized(origin)
{
Map<String, Object> access = transactionMap.getAccessMap();
for(Entry<String, Object> kv:access.entrySet())
{
String k = kv.getKey();
Object o = origin.get(k);
Object a = transactionMap.getAccessTimeValue(k);
if(!Mirror.equals(o, a))
{
throw new TransactionException("Data under key `"+k+"` modified by another thread since transaction started. Try again.");
}
}
origin.putAll(transactionMap.getDiffMap());
}
}
}