/* * Geotoolkit - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2009-2015, 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.memory; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.sis.feature.FeatureExt; import org.apache.sis.storage.DataStoreException; import org.geotoolkit.data.FeatureReader; import org.geotoolkit.data.FeatureStore; import org.geotoolkit.data.FeatureStoreRuntimeException; import org.geotoolkit.data.FeatureWriter; import org.geotoolkit.data.query.QueryBuilder; import org.geotoolkit.factory.FactoryFinder; import org.apache.sis.util.Classes; import org.opengis.feature.AttributeType; import org.opengis.feature.Feature; import org.opengis.feature.FeatureType; import org.opengis.feature.PropertyType; import org.opengis.util.GenericName; import org.opengis.filter.Filter; import org.opengis.filter.FilterFactory; import org.opengis.filter.identity.FeatureId; import org.apache.sis.internal.feature.AttributeConvention; /** * Basic support for a FeatureWriter that redicts it's calls to * the more casual methods : addFeatures, removeFeatures and updateFeatures * of the feature store. * * @author Johann Sorel (Geomatys) * @module */ public class GenericFeatureWriter implements FeatureWriter { private static final FilterFactory FF = FactoryFinder.getFilterFactory(null); protected final FeatureStore store; protected final String typeName; protected final FeatureReader reader; protected final FeatureType type; protected Feature currentFeature = null; protected Feature modified = null; private boolean remove = false; private GenericFeatureWriter(final FeatureStore store, final String typeName, final Filter filter) throws DataStoreException { this.store = store; this.typeName = typeName; reader = store.getFeatureReader(QueryBuilder.filtered(typeName, filter)); type = store.getFeatureType(typeName); } @Override public FeatureType getFeatureType() throws FeatureStoreRuntimeException{ return type; } /** * {@inheritDoc } */ @Override public Feature next() throws FeatureStoreRuntimeException { remove = false; if(hasNext()){ currentFeature = reader.next(); modified = FeatureExt.copy(currentFeature); }else{ currentFeature = null; modified = type.newInstance(); } return modified; } /** * {@inheritDoc } */ @Override public void close() throws FeatureStoreRuntimeException { reader.close(); write(); } /** * {@inheritDoc } */ @Override public boolean hasNext() throws FeatureStoreRuntimeException { return reader.hasNext(); } /** * {@inheritDoc } */ @Override public void remove() { remove = true; write(); } /** * {@inheritDoc } */ @Override public void write() throws FeatureStoreRuntimeException { if(currentFeature != null){ final Filter filter = FF.id(Collections.singleton(FeatureExt.getId(currentFeature))); if(remove){ //it's a remove operation try { store.removeFeatures(typeName, filter); } catch (DataStoreException ex) { throw new FeatureStoreRuntimeException(ex); } }else{ //it's a modify operation final Map<String,Object> values = new HashMap<>(); for(PropertyType desc : type.getProperties(true)){ if(desc instanceof AttributeType){ final String propName = desc.getName().toString(); final Object original = currentFeature.getPropertyValue(propName); final Object mod = modified.getProperty(propName).getValue(); //check if the values was modified if(!safeEqual(original, mod)){ //value has changed values.put(propName, mod); } } } if(!values.isEmpty()){ try { store.updateFeatures(typeName.toString(), filter, values); } catch (DataStoreException ex) { throw new FeatureStoreRuntimeException(ex); } } } }else{ if(modified != null){ //it's an add operation try { final List<FeatureId> res = store.addFeatures(typeName.toString(), Collections.singleton(modified)); if (!res.isEmpty()) { modified.setPropertyValue(AttributeConvention.IDENTIFIER_PROPERTY.toString(), res.get(0).getID()); } } catch (DataStoreException ex) { throw new FeatureStoreRuntimeException(ex); } modified = null; } } remove = false; } private boolean safeEqual(final Object o1, final Object o2){ if(o1 == null && o2 == null){ return true; }else if(o1 != null){ return o1.equals(o2); }else{ return o2.equals(o1); } } @Override public String toString() { final StringBuilder sb = new StringBuilder(Classes.getShortClassName(this)); sb.append('\n'); String subIterator = "\u2514\u2500\u2500" + reader.toString(); //move text to the right subIterator = subIterator.replaceAll("\n", "\n\u00A0\u00A0\u00A0"); //move text to the right sb.append(subIterator); return sb.toString(); } public static FeatureWriter wrap(final FeatureStore store, final String typeName, final Filter filter) throws DataStoreException{ return new GenericFeatureWriter(store, typeName, filter); } public static FeatureWriter wrapAppend(final FeatureStore store, final String typeName) throws DataStoreException{ return wrap(store,typeName,Filter.EXCLUDE); } }