/* * Geotoolkit - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2009, Geomatys * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotoolkit.data.session; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; import org.geotoolkit.data.FeatureStore; import org.apache.sis.storage.DataStoreException; import org.apache.sis.internal.util.UnmodifiableArrayList; /** * Contain a list of all modification, ensure concurrency when accesing * deltas and lock when commiting or reverting changes. * * @author Johann Sorel (Geomatys) * @module */ public class DefaultSessionDiff{ private final List<Delta> deltas = new ArrayList<Delta>(); private List<Delta> readCopy = null; private final ReadWriteLock rwlock = new ReentrantReadWriteLock(); private final Lock readLock = rwlock.readLock(); private final Lock writeLock = rwlock.writeLock(); public DefaultSessionDiff(){ } /** * {@inheritDoc } */ public List<Delta> getDeltas() { readLock.lock(); try{ List<Delta> cp = readCopy; if(cp != null){ return cp; } }finally{ readLock.unlock(); } /* * Double-check: was a deprecated practice before Java 5. * Is okay since Java 5 provided that the readCopy field * is protected by the readlock. */ writeLock.lock(); try{ List<Delta> cp = readCopy; if(cp == null){ cp = UnmodifiableArrayList.wrap(deltas.toArray(new Delta[deltas.size()])); readCopy = cp; } return cp; }finally{ writeLock.unlock(); } } public void add(final Delta alt){ writeLock.lock(); try{ deltas.add(alt); readCopy = null; }finally{ writeLock.unlock(); } } public void commit(final FeatureStore store) throws DataStoreException{ writeLock.lock(); try{ for(int i=0,n=deltas.size();i<n;i++){ final Delta alt = deltas.get(i); final Map<String,String> updates = alt.commit(store); alt.dispose(); //update next deltas if(updates != null){ for(int j=i+1;j<n;j++){ final Delta next = deltas.get(j); next.update(updates); } } } deltas.clear(); readCopy = null; }finally{ writeLock.unlock(); } } public void rollback(){ writeLock.lock(); try{ deltas.clear(); readCopy = null; }finally{ writeLock.unlock(); } } }