Package org.geotools.data.wfs.v1_0_0

Source Code of org.geotools.data.wfs.v1_0_0.WFSFeatureStore

/*
*    GeoTools - The Open Source Java GIS Toolkit
*    http://geotools.org
*
*    (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
*    (C) 2005-2006, David Zwiers
*
*    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.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;

import org.geotools.data.DataUtilities;
import org.geotools.data.FeatureReader;
import org.geotools.data.Transaction;
import org.geotools.data.simple.SimpleFeatureStore;
import org.geotools.data.wfs.feature.LenientBuilder;
import org.geotools.data.wfs.feature.LenientFeatureFactory;
import org.geotools.data.wfs.v1_0_0.Action.DeleteAction;
import org.geotools.data.wfs.v1_0_0.Action.InsertAction;
import org.geotools.data.wfs.v1_0_0.Action.UpdateAction;
import org.geotools.feature.FeatureCollection;
import org.geotools.feature.FeatureIterator;
import org.geotools.feature.NameImpl;
import org.geotools.filter.identity.FeatureIdImpl;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.opengis.feature.IllegalAttributeException;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.AttributeDescriptor;
import org.opengis.feature.type.GeometryDescriptor;
import org.opengis.feature.type.Name;
import org.opengis.filter.Filter;
import org.opengis.filter.identity.FeatureId;
import org.opengis.referencing.crs.CoordinateReferenceSystem;

import com.vividsolutions.jts.geom.Geometry;


/**
* FeatureStore used to assemble a Transaction Request (issued during commit).
* <p>
* Please note this FeatureStore does not support working on Transaction.AUTO_COMMIT.
* Instead it builds up the Transaction request in a WFSTransactionState; each call
* to addFeatures, removeFeatures etc results in a series of "Actions" being recorded.
* These actions are used to both modify the contents you are looking at prior to commit
* being called; and to construct the Transaction Request when commit() is called.
*
* @author dzwiers
*
*
*
* @source $URL$
*/
public class WFSFeatureStore extends WFSFeatureSource implements SimpleFeatureStore {
    protected Transaction trans = Transaction.AUTO_COMMIT;
   
    /**
     *
     * @param ds
     * @param typeName
     */
    public WFSFeatureStore(WFS_1_0_0_DataStore ds, String typeName) {
        super(ds, typeName);
    }
    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Override
    public Set getSupportedHints() {
        return super.getSupportedHints();
    }
    @Override
    public Transaction getTransaction() {
        return trans;
    }

    public List<FeatureId> addFeatures(final  FeatureReader<SimpleFeatureType, SimpleFeature> reader) throws IOException {
        List<SimpleFeature> features=new ArrayList<SimpleFeature>();
        while(reader.hasNext()){
            try {
                SimpleFeature next = reader.next();
                features.add(next);
            } catch (Exception e) {
                throw (IOException) new IOException( ).initCause( e );
            }
        }
        return addFeatures(DataUtilities.collection((SimpleFeature[]) features.toArray(new SimpleFeature[0])));
    }

  public List<FeatureId> addFeatures(FeatureCollection<SimpleFeatureType,SimpleFeature> collection) throws IOException {
        WFSTransactionState ts = null;

        if (trans == Transaction.AUTO_COMMIT) {
            ts = new WFSTransactionState(ds);
        } else {
            ts = (WFSTransactionState) trans.getState(ds);
        }
        List<FeatureId> r = new LinkedList<FeatureId>();
       
        SimpleFeatureType schema = getSchema();
       
        LenientBuilder build = new LenientBuilder( schema );
       
        boolean isLenient = true;
        if( schema.getUserData().containsKey("lenient")){
            isLenient = (Boolean) schema.getUserData().get("lenient");
        }
       
        if( isLenient ){
            build.setFeatureFactory( new LenientFeatureFactory());
        }
       
        List<AttributeDescriptor> atrs = schema.getAttributeDescriptors();
        FeatureIterator<SimpleFeature> iter=collection.features();
        try{
            ReferencedEnvelope bounds=null;
           
        while (iter.hasNext()){
            try {
                SimpleFeature newFeature;
                try {
                    SimpleFeature f = iter.next();
                   
                    String nextFid = ts.nextFid(schema.getTypeName());
                    Object[] values = f.getAttributes().toArray();
                   
                    build.addAll( values );
                    newFeature = build.buildFeature( nextFid );
                   
                    r.add(newFeature.getIdentifier());
                } catch (IllegalAttributeException e) {
                    throw (IOException) new IOException( e.getLocalizedMessage() );
                }

                for(int i=0;i<atrs.size();i++){
                    AttributeDescriptor att = atrs.get(i);
                    if(att instanceof GeometryDescriptor){
                      Object geom = newFeature.getAttribute(i);
                      if(geom instanceof Geometry){
                          Geometry g = (Geometry) geom;
                          CoordinateReferenceSystem cs = ((GeometryDescriptor)att).getCoordinateReferenceSystem();
//                          if( g==null ){
//                              continue;
//                          }
                          if( cs!=null && !cs.getIdentifiers().isEmpty() )
                              g.setUserData(cs.getIdentifiers().iterator().next().toString());
                          if( bounds==null ){
                              bounds=new ReferencedEnvelope(g.getEnvelopeInternal(), schema.getCoordinateReferenceSystem() );
                          }else{
                              bounds.expandToInclude(g.getEnvelopeInternal());
                          }
                      }
                    }
                }
                ts.addAction(schema.getTypeName(), new InsertAction(newFeature));

            } catch (NoSuchElementException e) {
                WFS_1_0_0_DataStore.LOGGER.warning(e.toString());
                throw new IOException(e.toString());
            }
        }

        // Fire a notification.
        // JE
        if( bounds==null){
            // if bounds are null then send an envelope to say that features were added but
            // at an unknown location.
            bounds = new ReferencedEnvelope( getSchema().getCoordinateReferenceSystem() );
            ((WFS_1_0_0_DataStore)getDataStore()).listenerManager.fireFeaturesRemoved(schema.getTypeName(),
                    getTransaction(), bounds, false);
        }else{
            ((WFS_1_0_0_DataStore)getDataStore()).listenerManager.fireFeaturesRemoved(schema.getTypeName(),
                    getTransaction(), bounds, false);                  
        }

        }finally{
            iter.close();
        }
        if (trans == Transaction.AUTO_COMMIT) {
            ts.commit();

            String[] fids = ts.getFids(schema.getTypeName());
            int i=0;
            for( String fid : fids ){
              FeatureId identifier = r.get(i);
              if( identifier instanceof FeatureIdImpl){
                ((FeatureIdImpl)identifier).setID( fid );
              }
              i++;
            }
            return r;
        }
        return r;
  }

    @Override
    public void removeFeatures(Filter filter2) throws IOException {
      Filter filter=ds.processFilter(filter2);
        WFSTransactionState ts = null;

        if (trans == Transaction.AUTO_COMMIT) {
            ts = new WFSTransactionState(ds);
        } else {
            ts = (WFSTransactionState) trans.getState(ds);
        }

        ts.addAction(getSchema().getTypeName(), new DeleteAction(getSchema().getTypeName(), filter));
       
        // Fire a notification.  I don't know a way of quickly getting the bounds of
        // an arbitrary filter so I'm sending a NULL envelope to say "some features were removed but I don't
        // know what."  Can't be null because the convention states that null is sent on commits only.
        // JE
        ((WFS_1_0_0_DataStore)getDataStore()).listenerManager.fireFeaturesRemoved(getSchema().getTypeName(),
            getTransaction(), null, false);

        if (trans == Transaction.AUTO_COMMIT) {
            ts.commit();
        }
    }

    @Override
    public void modifyFeatures(Name[] names, Object[] value,
        Filter filter2) throws IOException {
      Filter filter=ds.processFilter(filter2);
        WFSTransactionState ts = null;

        if (trans == Transaction.AUTO_COMMIT) {
            ts = new WFSTransactionState(ds);
        } else {
            ts = (WFSTransactionState) trans.getState(ds);
        }

        Map<String,Object> props = new HashMap<String,Object>();
       
        ReferencedEnvelope bounds=null;
        for (int i = 0; i < names.length; i++) {
          if(names[i] instanceof GeometryDescriptor){
            Geometry g = (Geometry)value[i];
            CoordinateReferenceSystem cs = ((GeometryDescriptor)names[i]).getCoordinateReferenceSystem();

                if( cs!=null && !cs.getIdentifiers().isEmpty() )
                    g.setUserData(cs.getIdentifiers().iterator().next().toString());
            g.setUserData(cs.getIdentifiers().iterator().next().toString());
                if( cs!=null && !cs.getIdentifiers().isEmpty() )
                    g.setUserData(cs.getIdentifiers().iterator().next().toString());
                // set/expand the bounds that are being changed.
//                if( g==null ){
//                    continue;
//                }
                if( bounds==null ){
                    bounds=new ReferencedEnvelope(g.getEnvelopeInternal(),cs);
                }else{
                    bounds.expandToInclude(g.getEnvelopeInternal());
                }
          }
            props.put(names[i].getLocalPart(), value[i]);
        }

        ts.addAction(getSchema().getTypeName(), new UpdateAction(getSchema().getTypeName(), filter, props));

        // Fire a notification.
        // JE
        if( bounds==null ){
            // if bounds are null then send an envelope to say that features were modified but
            // at an unknown location.
            bounds = new ReferencedEnvelope(getSchema().getCoordinateReferenceSystem());
            ((WFS_1_0_0_DataStore)getDataStore()).listenerManager.fireFeaturesRemoved(getSchema().getTypeName(),
                    getTransaction(), bounds, false);
        }else{
            ((WFS_1_0_0_DataStore)getDataStore()).listenerManager.fireFeaturesRemoved(getSchema().getTypeName(),
                    getTransaction(), bounds, false);                  
        }   
       
        if (trans == Transaction.AUTO_COMMIT) {
            ts.commit();
        }
    }

    public final void modifyFeatures(AttributeDescriptor type, Object value, Filter filter)
            throws IOException {
        Name attributeName = type.getName();
        modifyFeatures(attributeName, value, filter);
    }
   
    @Override
    public void modifyFeatures(Name type, Object value, Filter filter)
        throws IOException {
        modifyFeatures(new Name[] { type, }, new Object[] { value, },
            filter);
    }

    public final void modifyFeatures(AttributeDescriptor[] type, Object[] value, Filter filter)
            throws IOException {

        Name attributeNames[] = new Name[type.length];
        for (int i = 0; i < type.length; i++) {
            attributeNames[i] = type[i].getName();
        }
        modifyFeatures(attributeNames, value, filter);
    }

    public void modifyFeatures(String name, Object attributeValue, Filter filter)
            throws IOException {
        modifyFeatures(new Name[] { new NameImpl(name), }, new Object[] { attributeValue, }, filter);
    }

    public void modifyFeatures(String[] names, Object[] values, Filter filter) throws IOException {
        Name attributeNames[] = new Name[names.length];
        for (int i = 0; i < names.length; i++) {
            attributeNames[i] = new NameImpl(names[i]);
        }
        modifyFeatures(attributeNames, values, filter);
    }
    @Override
    public void setFeatures(FeatureReader <SimpleFeatureType, SimpleFeature> reader) throws IOException {
        WFSTransactionState ts = null;

        if (trans == Transaction.AUTO_COMMIT) {
            ts = new WFSTransactionState(ds);
        } else {
            ts = (WFSTransactionState) trans.getState(ds);
        }

        ts.addAction(getSchema().getTypeName(), new DeleteAction(getSchema().getTypeName(), Filter.INCLUDE));
       
        ReferencedEnvelope bounds=null;
        while (reader.hasNext()){

            try {
              SimpleFeature f = reader.next();
              List<AttributeDescriptor> atrs = f.getFeatureType().getAttributeDescriptors();
              for(int i=0;i<atrs.size();i++){
                if(atrs.get(i) instanceof GeometryDescriptor){
                  Geometry g = (Geometry)f.getAttribute(i);
                    CoordinateReferenceSystem cs = ((GeometryDescriptor)atrs.get(i)).getCoordinateReferenceSystem();
                        if( cs!=null && !cs.getIdentifiers().isEmpty() )
                            g.setUserData(cs.getIdentifiers().iterator().next().toString());
                        if( g==null )
                          continue;
                        if( bounds==null ){
                            bounds=new ReferencedEnvelope(g.getEnvelopeInternal(),cs);
                        }else{
                            bounds.expandToInclude(g.getEnvelopeInternal());
                        }
                }
              }
                ts.addAction(getSchema().getTypeName(), new InsertAction(f));
            } catch (NoSuchElementException e) {
                WFS_1_0_0_DataStore.LOGGER.warning(e.toString());
            } catch (IllegalAttributeException e) {
                WFS_1_0_0_DataStore.LOGGER.warning(e.toString());
            }
        }
           
        // Fire a notification.
        // JE
        if( bounds==null){
            // if bounds are null then send an envelope to say that features were added but
            // at an unknown location.
            bounds = new ReferencedEnvelope( getSchema().getCoordinateReferenceSystem() );
            ((WFS_1_0_0_DataStore)getDataStore()).listenerManager.fireFeaturesRemoved(getSchema().getTypeName(),
                    getTransaction(), bounds, false);
        }else{
            ((WFS_1_0_0_DataStore)getDataStore()).listenerManager.fireFeaturesRemoved(getSchema().getTypeName(),
                    getTransaction(), bounds, false);                  
        }   
        if (trans == Transaction.AUTO_COMMIT) {
            ts.commit();
        }
    }

    @Override
    public void setTransaction(Transaction transaction) {
        if(transaction == null)
            throw new NullPointerException("Should this not be Transaction.AutoCommit?");
        trans = transaction;
        if(trans != Transaction.AUTO_COMMIT){
          WFSTransactionState ts = (WFSTransactionState) trans.getState(ds);
          if(ts == null){
            trans.putState(ds,new WFSTransactionState(ds));
          }
        }
    }
}
TOP

Related Classes of org.geotools.data.wfs.v1_0_0.WFSFeatureStore

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.