/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2004-2008, Open Source Geospatial Foundation (OSGeo) * * 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.geotools.data.wfs.v1_0_0; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.NoSuchElementException; import org.geotools.factory.CommonFactoryFinder; import org.geotools.feature.LenientBuilder; import org.geotools.filter.visitor.DuplicatingFilterVisitor; import org.opengis.feature.IllegalAttributeException; import org.opengis.feature.simple.SimpleFeature; import org.opengis.filter.Filter; import org.opengis.filter.FilterFactory2; import org.opengis.filter.identity.FeatureId; /** * This interface represents pending actions within a transaction. * * @author dzwiers * * * @source $URL$ */ public interface Action { /** * Action mask for an Insert Action */ public static final int INSERT = 1; /** * Action mask for an Update Action */ public static final int UPDATE = 2; /** * Action mask for a Delete Action */ public static final int DELETE = 4; /** * @return The Type of Action ... one of the three Constants */ public int getType(); /** * @return The Filter on which to inflict the Action */ public Filter getFilter(); /** * @return The FeatureType name for which this Action is intended */ public String getTypeName(); /** * Represents an Update Action * * @author dzwiers */ public static class UpdateAction implements Action { private final Filter filter; private final Map<String,Object> properties; private final String typeName; /** * Makes an UpdateAction Filter is copied so any further changes will not be included in filter of action. * * @param typeName The TypeName * @param f Filter which this update affects * @param properties The properties to update. Entries must be <String, Object> where String is an attribute to * update and Object is the new Value. */ public UpdateAction(String typeName, Filter f, Map<String,Object> properties) { //DuplicatingFilterVisitor duplicator = new DuplicatingFilterVisitor(); DuplicatingFilterVisitor visitor=new DuplicatingFilterVisitor(); filter = (Filter) f.accept(visitor, null ); this.properties = new HashMap<String,Object>(properties); this.typeName = typeName; } /** * @return @see Action#UPDATE */ public int getType() { return UPDATE; } /** * Returns the property if found ... this method will not create a * NullPointerException if properties is null. * * @param name String the property key * @return Object The property if found, null other wise. */ public Object getProperty(String name) { return (properties == null) ? null : properties.get(name); } /** * Returns the property names if they exist ... this method will not create a * NullPointerException if properties is null. * * @return A list of the keys. */ public String[] getPropertyNames() { return properties==null?new String[0]:(String[]) properties.keySet().toArray(new String[properties.keySet() .size()]); } /** * @return a clone of the properties map, null if it does not exist. */ public Map<String,Object> getProperties() { return properties==null?null:new HashMap<String,Object>(properties); } /** * @return Filter the Filter */ public Filter getFilter() { return filter; } /** * @return String the TypeName */ public String getTypeName() { return typeName; } public void update(SimpleFeature feature) { if( !filter.evaluate(feature) ) throw new IllegalArgumentException(feature+"is not affected by this update, only call update on features that" + "the Action applies to!"); String[] propNames = getPropertyNames(); for (int j = 0; j < propNames.length; j++) { try { feature.setAttribute(propNames[j], getProperty(propNames[j])); } catch (IllegalAttributeException e) { NoSuchElementException ee = new NoSuchElementException(e.getMessage()); ee.initCause(e); throw ee; } } } public String toString() { return "UPDATE "+filter+" "+properties; } } /** * Represents a Delete Action for a Transaction * * @author dzwiers */ public static class DeleteAction implements Action { private final Filter filter; private final String typeName; /** * Represents a Delete Action. * Filter is copied so any further changes will not be included in filter of action. * * @param typeName TypeName * @param f Filter of Features to Delete */ public DeleteAction(String typeName, Filter f) { DuplicatingFilterVisitor visitor = new DuplicatingFilterVisitor(); filter = (Filter) f.accept(visitor, null); this.typeName = typeName; } /** * @return @see Action#DELETE */ public int getType() { return DELETE; } /** * @return the TypeName */ public String getTypeName() { return typeName; } /** * @return the Filter */ public Filter getFilter() { return filter; } public String toString() { return "REMOVE "+filter; } } /** * Represents an Insert Action * * @author dzwiers */ public static class InsertAction implements Action { private final SimpleFeature feature; /** * Creates an insert action for the Feature specified. The feature is copied to * prevent inadvertant side effect of modifing the feature after an insert. * * @param f Feature to add */ public InsertAction(SimpleFeature f) { SimpleFeature feature; try { // WARNNING: deep copy feature = LenientBuilder.copy( f ); } catch (IllegalAttributeException e) { org.geotools.util.logging.Logging.getLogger("org.geotools.data.wfs").warning("Failed to duplicate feature:"+f); feature=f; } this.feature=feature; } /** * @return @see Action#INSERT */ public int getType() { return INSERT; } /** * @return The Feature to add */ public SimpleFeature getFeature() { return feature; } /** * @see org.geotools.wfs.v_1_0_0.data.Action#getTypeName() */ public String getTypeName() { return (feature == null) ? null : feature.getType().getName().getLocalPart(); } /** * @see org.geotools.wfs.v_1_0_0.data.Action#getFilter() */ public Filter getFilter() { if( feature == null ) { return Filter.EXCLUDE; } String fid = feature.getID(); if( fid != null ){ FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2(null); FeatureId identifier = ff.featureId( fid ); HashSet<FeatureId> fids = new HashSet<FeatureId>(); fids.add( identifier ); Filter filter = ff.id( fids ); return filter; } else { return Filter.EXCLUDE; } } public String toString() { return "INSERT "+feature; } } }