Package org.locationtech.udig.project.internal.impl

Source Code of org.locationtech.udig.project.internal.impl.UDIGSimpleFeatureStore

/*
*    uDig - User Friendly Desktop Internet GIS client
*    http://udig.refractions.net
*    (C) 2012, Refractions Research Inc.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* (http://www.eclipse.org/legal/epl-v10.html), and the Refractions BSD
* License v1.0 (http://udig.refractions.net/files/bsd3-v10.html).
*/
package org.locationtech.udig.project.internal.impl;

import java.awt.RenderingHints.Key;
import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.locationtech.udig.project.ILayer;
import org.locationtech.udig.project.Interaction;
import org.locationtech.udig.project.LayerEvent;
import org.locationtech.udig.project.ProjectBlackboardConstants;
import org.locationtech.udig.project.internal.EditManager;
import org.locationtech.udig.project.internal.Messages;
import org.locationtech.udig.project.internal.ProjectPlugin;

import org.geotools.data.DataStore;
import org.geotools.data.DataUtilities;
import org.geotools.data.FeatureEvent;
import org.geotools.data.FeatureListener;
import org.geotools.data.FeatureReader;
import org.geotools.data.FeatureSource;
import org.geotools.data.FeatureStore;
import org.geotools.data.Query;
import org.geotools.data.QueryCapabilities;
import org.geotools.data.ResourceInfo;
import org.geotools.data.Transaction;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureStore;
import org.geotools.factory.CommonFactoryFinder;
import org.geotools.feature.FeatureCollection;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.AttributeDescriptor;
import org.opengis.feature.type.Name;
import org.opengis.filter.Filter;
import org.opengis.filter.FilterFactory2;
import org.opengis.filter.Id;
import org.opengis.filter.identity.FeatureId;

import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.io.WKTWriter;

/**
* A SimpleFeatureStore decorator that does not allow the transaction to be set more than once.
* <p>
* Only if the current transaction is "AUTO_COMMIT" can the transaction be set.
*
* @author Jody Garnett
* @since 1.2.1
* @see UDIGFeatureStore
*/
public class UDIGSimpleFeatureStore implements SimpleFeatureStore, UDIGStore {
    SimpleFeatureStore wrapped;
    ILayer layer;

    /**
     * Create a new FeatureStore decorator that does not allow the transaction to be set more than
     * once. (Only if the current transaction is "AUTO_COMMIT" can the transaction be set)
     *
     * @param store the feature store that will be decorated
     * @param layer layer providing context
     */
    public UDIGSimpleFeatureStore( SimpleFeatureStore featureStore, ILayer layer ) {
        wrapped = featureStore;
        this.layer = layer;
    }
   
    public UDIGSimpleFeatureStore( FeatureStore<?,?> featureStore, ILayer layer ) {
        wrapped = DataUtilities.simple( featureStore );
        this.layer = layer;
    }

    public Name getName() {
        return wrapped.getName();
    }

    public ResourceInfo getInfo() {
        return wrapped.getInfo();
    }

    public void removeFeatures( Filter filter ) throws IOException {
        setTransactionInternal();
        wrapped.removeFeatures(filter);
       
        fireLayerEditEvent( FeatureEvent.Type.REMOVED, null, filter );
    }

    @Deprecated
    public void modifyFeatures( AttributeDescriptor[] descriptors, Object[] values, Filter filter )
            throws IOException {
        setTransactionInternal();
        wrapped.modifyFeatures(descriptors, values, filter);
        fireLayerEditEvent( FeatureEvent.Type.CHANGED, null, filter );
    }
   
    public void modifyFeatures( Name[] names, Object[] values, Filter filter ) throws IOException {
        setTransactionInternal();
        wrapped.modifyFeatures(names, values, filter);
        fireLayerEditEvent( FeatureEvent.Type.CHANGED, null, filter );
    }
   
    public void modifyFeatures( Name name, Object value, Filter filter ) throws IOException {
        setTransactionInternal();
        wrapped.modifyFeatures(name, value, filter);
        fireLayerEditEvent( FeatureEvent.Type.CHANGED, null, filter );
    }
    public void modifyFeatures( String name, Object value, Filter filter ) throws IOException {
        setTransactionInternal();
        wrapped.modifyFeatures(name, value, filter);
        fireLayerEditEvent( FeatureEvent.Type.CHANGED, null, filter );       
    }
    public void modifyFeatures( String names[], Object values[], Filter filter ) throws IOException {
        setTransactionInternal();
        wrapped.modifyFeatures(names, values, filter);
        fireLayerEditEvent( FeatureEvent.Type.CHANGED, null, filter );       
    }
   
    @Deprecated
    public void modifyFeatures( AttributeDescriptor attribute, Object value, Filter selectFilter )
            throws IOException {
        setTransactionInternal();
        if (value instanceof Geometry) {
            Geometry geom = (Geometry) value;
            if (!geom.isValid()) {
                WKTWriter writer = new WKTWriter();
                String wkt = writer.write(geom);
                String where = selectFilter.toString();
                if (selectFilter instanceof Id) {
                    Id id = (Id) selectFilter;
                    where = id.getIDs().toString();
                }
                String msg = "Modify fetures (WHERE " + where + ") failed with invalid geometry:"
                        + wkt;
                ProjectPlugin.log(msg);
                throw new IOException(msg);
            }
        }
        wrapped.modifyFeatures(attribute, value, selectFilter);
        fireLayerEditEvent( FeatureEvent.Type.CHANGED, null, selectFilter );
    }
    /**
     * Used to force the layer to send out an LayerEditEvent (and refresh!); we are faking the correct FeatureEventType
     * we expected from the wrapped GeoTools datastore. This is defensive programming as we are not trusting
     * the implementations to provide good events.
     * @param type
     * @param bounds
     * @param filter
     */
    public void fireLayerEditEvent( FeatureEvent.Type type, ReferencedEnvelope bounds, Filter filter){
        // issue edit event for TableView and any other interested parties
        if( type == null ){
            type = FeatureEvent.Type.CHANGED;
        }
        FeatureEvent featureEvent = new FeatureEvent( this, type, bounds, filter);
        ((LayerImpl)layer).fireLayerChange(new LayerEvent(layer, LayerEvent.EventType.EDIT_EVENT, null, featureEvent));
        layer.refresh(bounds);
    }
   
    public void setFeatures( FeatureReader<SimpleFeatureType, SimpleFeature> features )
            throws IOException {
        setTransactionInternal();
        wrapped.setFeatures(features);
        fireLayerEditEvent( FeatureEvent.Type.CHANGED, null, Filter.INCLUDE );
    }

    public void setTransaction( Transaction transaction ) {
        throw new IllegalArgumentException(Messages.UDIGFeatureStore_0
                + Messages.UDIGFeatureStore_1);
       
    }
   
    /** Called when commitRollbackCompleted to restore Transaction.AUTO_COMMIT */
    public void editComplete() {
        wrapped.setTransaction(Transaction.AUTO_COMMIT);
    }
    /**
     * Called when any method that may modify feature content is used.
     * <p>
     * This method is responsible for setting the transaction prior to use.
     */
    private void setTransactionInternal() {
        if (!layer.getInteraction(Interaction.EDIT)) {
            String message = "Attempted to open a transaction on a non-editable layer (Aborted)";
            IllegalStateException illegalStateException = new IllegalStateException( message );
            ProjectPlugin.log(message, illegalStateException);
            throw illegalStateException;
        }
        // grab the current map transaction
        EditManager editManager = (EditManager) layer.getMap().getEditManager();
        Transaction transaction = editManager.getTransaction();
       
        if (wrapped.getTransaction() == Transaction.AUTO_COMMIT) {
            // change over from autocommit to transactional
            wrapped.setTransaction(transaction);
        }
        else if (wrapped.getTransaction() != transaction){
            // a transaction is already present? huh ...
            String msg = "Layer transaction already set "+wrapped.getTransaction(); //$NON-NLS-1$
            IllegalStateException illegalStateException = new IllegalStateException(msg);
            ProjectPlugin.log(msg,illegalStateException);
            throw illegalStateException;
        }
    }

    /**
     * Used to start a transaction.
     * <p>
     * Q: V(italus) Think out how to provide for developers the opportunity to use its own FeatureStore
     * wrapper, not UDIGFeatureStore.
     * <p>
     * A: (Jody) They can use the id; and grab the actual IResource from
     * the catalog; and get there own that way.
     */
    public void startTransaction() {
        if (wrapped.getTransaction() == Transaction.AUTO_COMMIT) {
            Transaction transaction = ((EditManager) layer.getMap().getEditManager())
                    .getTransaction();
            wrapped.setTransaction(transaction);
        }
    }

    public Transaction getTransaction() {
        // may need to check that this is not auto commit?
        return wrapped.getTransaction();
    }

    public DataStore getDataStore() {
        return (DataStore) wrapped.getDataStore();
    }

    public void addFeatureListener( FeatureListener listener ) {
        wrapped.addFeatureListener(listener);
    }

    public void removeFeatureListener( FeatureListener listener ) {
        wrapped.removeFeatureListener(listener);
    }

    public SimpleFeatureCollection getFeatures( Query query )
            throws IOException {
        return wrapped.getFeatures(query);
    }

    public SimpleFeatureCollection getFeatures( Filter filter )
            throws IOException {
        return wrapped.getFeatures(filter);
    }

    public SimpleFeatureCollection getFeatures() throws IOException {
        return wrapped.getFeatures();
    }

    public SimpleFeatureType getSchema() {
        return wrapped.getSchema();
    }

    public ReferencedEnvelope getBounds() throws IOException {
        return wrapped.getBounds();
    }

    public ReferencedEnvelope getBounds( Query query ) throws IOException {
        return wrapped.getBounds(query);
    }

    public int getCount( Query query ) throws IOException {
        return wrapped.getCount(query);
    }

    public List<FeatureId> addFeatures( FeatureCollection<SimpleFeatureType, SimpleFeature> features )
            throws IOException {
        setTransactionInternal();
        List<FeatureId> ids = wrapped.addFeatures(features);
       
        FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2();
        Id filter = ff.id( new HashSet<FeatureId>( ids ) );
       
        fireLayerEditEvent( FeatureEvent.Type.CHANGED, null, Filter.INCLUDE );
       
        return ids;
    }

    public boolean sameSource( Object source ) {
        return source == wrapped || source == this;
    }
   
    public SimpleFeatureStore wrapped() {
        return wrapped;
    }

    public Set<Key> getSupportedHints() {
        return wrapped.getSupportedHints();
    }

    public QueryCapabilities getQueryCapabilities() {
        return wrapped.getQueryCapabilities();
    }
}
TOP

Related Classes of org.locationtech.udig.project.internal.impl.UDIGSimpleFeatureStore

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.