/*
* Geotoolkit - An Open Source Java GIS Toolkit
* http://www.geotoolkit.org
*
* (C) 2009-2011, 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.io.Closeable;
import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import org.apache.sis.feature.FeatureExt;
import org.apache.sis.storage.DataStoreException;
import org.geotoolkit.data.FeatureStore;
import org.geotoolkit.data.FeatureStoreUtilities;
import org.geotoolkit.data.FeatureCollection;
import org.geotoolkit.data.FeatureIterator;
import org.geotoolkit.data.query.Query;
import org.geotoolkit.data.query.QueryBuilder;
import org.geotoolkit.geometry.jts.JTSEnvelope2D;
import static org.apache.sis.util.ArgumentChecks.*;
import org.apache.sis.util.logging.Logging;
import org.opengis.feature.Feature;
import org.opengis.feature.FeatureType;
import org.opengis.util.GenericName;
import org.opengis.filter.Filter;
import org.opengis.filter.identity.FeatureId;
import org.opengis.filter.sort.SortBy;
import org.opengis.geometry.Envelope;
/**
* Delta which add a collection of features.
*
* @author Johann Sorel (Geomatys)
* @module
* @todo make this concurrent
*/
public class AddDelta extends AbstractDelta{
protected final FeatureCollection features;
/**
*
* @param session
* @param typeName
* @param features : can be empty, even so it would be useless,
* We do not check the size since this collection may be relying on
* a feature store which may be slow or changing with time.
* this features from the given collection will be copied.
*/
public AddDelta(final Session session, final String typeName, final Collection<? extends Feature> features){
super(session,typeName);
ensureNonNull("type name", typeName);
ensureNonNull("features", features);
FeatureType ft;
try {
ft = session.getFeatureStore().getFeatureType(typeName);
} catch (DataStoreException ex) {
Logging.getLogger("org.geotoolkit.data.session").log(Level.WARNING, null, ex);
ft = null;
}
this.features = FeatureStoreUtilities.collection("temp", ft);
//we must copy the features since they might be changed later
final Iterator<? extends Feature> ite = features.iterator();
try{
while(ite.hasNext()){
Feature sf = ite.next();
sf = FeatureExt.deepCopy(sf);
this.features.add(sf);
}
}finally{
if(ite instanceof Closeable){
try {
((Closeable) ite).close();
} catch (IOException ex) {
Logging.getLogger("org.geotoolkit.data.session").log(Level.WARNING, "Error while closing iterator : ", ex);
}
}
}
}
/**
* {@inheritDoc }
*/
@Override
public Query modify(final Query query) {
//add doesnt modify a query
return query;
}
/**
* {@inheritDoc }
*/
@Override
public FeatureIterator modify(final Query query, final FeatureIterator reader) throws DataStoreException {
if(!query.getTypeName().equals(type)) return reader;
//remove the filter, it is handle at the end by the session
//we can not filter here since some modify operation can follow
//and change the filter result
final QueryBuilder qb = new QueryBuilder(query);
qb.setFilter(Filter.INCLUDE);
final FeatureIterator affected = features.subCollection(qb.buildQuery()).iterator();
final SortBy[] sort = query.getSortBy();
if(sort != null && sort.length > 0){
return FeatureStoreUtilities.combine(query.getSortBy(), reader, affected);
}else{
return FeatureStoreUtilities.sequence(reader, affected);
}
}
/**
* {@inheritDoc }
*/
@Override
public long modify(final Query query, final long count) throws DataStoreException{
if(!query.getTypeName().equals(type)) return count;
final int affected = features.subCollection(query).size();
return count + affected;
}
/**
* {@inheritDoc }
*/
@Override
public Envelope modify(final Query query, final Envelope env) throws DataStoreException {
if(!query.getTypeName().equals(type)) return env;
final Envelope affected = features.subCollection(query).getEnvelope();
final JTSEnvelope2D combine = new JTSEnvelope2D(env);
combine.expandToInclude(new JTSEnvelope2D(affected));
return combine;
}
/**
* {@inheritDoc }
*/
@Override
public Map<String, String> commit(final FeatureStore store) throws DataStoreException {
final List<FeatureId> createdIds = store.addFeatures(type.toString(), features);
//iterator and list should have the same size
final Map<String,String> updates = new HashMap<String, String>();
final FeatureIterator ite = features.iterator();
int i=0;
try{
if(createdIds != null && !createdIds.isEmpty()){
while(ite.hasNext()){
final Feature f = ite.next();
final String id = FeatureExt.getId(f).getID();
updates.put(id, createdIds.get(i).getID());
i++;
}
}
}finally{
ite.close();
}
features.clear();
return updates;
}
/**
* {@inheritDoc }
*/
@Override
public void dispose() {
features.clear();
}
@Override
public void update(Map<String, String> idUpdates) {
//nothing to update
}
}