public void write() throws IOException { if (live == null) { throw new IOException("No current feature to write"); } if (live.equals(origional)) { writeImplementation(origional); } else { writeImplementation(live); if (origional != null) { ReferencedEnvelope bounds = new ReferencedEnvelope(); bounds.include(live.getBounds()); bounds.include(origional.getBounds()); store.listenerManager.fireFeaturesChanged( live.getFeatureType().getTypeName(), Transaction.AUTO_COMMIT, bounds, false); } else { store.listenerManager.fireFeaturesAdded( live.getFeatureType().getTypeName(), Transaction.AUTO_COMMIT, ReferencedEnvelope.reference(live.getBounds()), false); } } origional = null; live = null; }
/** * Creates the resultant features. * * @param splitGeometries List with the new geometries. * @param feature The old feature. * @throws OperationNotFoundException * @throws TransformException */ private List<SimpleFeature> createSplitFeatures( final List<Geometry> splitGeometries, final SimpleFeature feature) throws OperationNotFoundException, TransformException { final SimpleFeatureType featureType = feature.getFeatureType(); final CoordinateReferenceSystem featureCrs = featureType.getCoordinateReferenceSystem(); Class<? extends Geometry> geometryType = (Class<? extends Geometry>) featureType.getGeometryDescriptor().getType().getBinding(); List<SimpleFeature> splitFeatureList = new LinkedList<SimpleFeature>(); for (Geometry splittedPart : splitGeometries) { splittedPart = GeoToolsUtils.reproject(splittedPart, desiredCRS, featureCrs); splittedPart = GeometryUtil.adapt(splittedPart, geometryType); SimpleFeature newFeature = DataUtilities.template(featureType); GeoToolsUtils.copyAttributes(feature, newFeature); newFeature.setDefaultGeometry(splittedPart); splitFeatureList.add(newFeature); } return splitFeatureList; }
/** @see org.geotools.data.FeatureStore#setFeatures(org.geotools.data.FeatureReader) */ 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(); } }
@Test public void testGetFeaturesFeatureSource() throws Exception { // check the schemas in feature source and feature collection SimpleFeatureSource fs = rts.getFeatureSource(RENAMED); assertEquals(primitive, fs.getSchema()); SimpleFeatureCollection fc = fs.getFeatures(); assertEquals(primitive, fc.getSchema()); assertTrue(fc.size() > 0); // make sure the feature schema is good as well FeatureIterator<SimpleFeature> it = fc.features(); SimpleFeature sf = it.next(); it.close(); assertEquals(primitive, sf.getFeatureType()); // check the feature ids have been renamed as well assertTrue( "Feature id has not been renamed, it's still " + sf.getID(), sf.getID().startsWith(RENAMED)); // check mappings occurred assertEquals("description-f001", sf.getAttribute("description")); assertTrue( new WKTReader() .read("MULTIPOINT(39.73245 2.00342)") .equalsExact((Geometry) sf.getAttribute("pointProperty"))); assertEquals(new Long(155), sf.getAttribute("intProperty")); assertNull(sf.getAttribute("newProperty")); }
/** * Analyze the feature list, and for those features that can suffer split operation, they'll be * split. * * @return The builder instance. * @throws SplitFeatureBuilderFailException if the operation fail * @throws CannotSplitException if the split line cannot divide the feature's geometry */ public SplitFeatureBuilder buildSplit() throws SplitFeatureBuilderFailException, CannotSplitException { try { this.splitResultList = new LinkedList<SimpleFeature>(); boolean existSplit = false; for (SimpleFeature feature : this.featureList) { Geometry geomToSplit = (Geometry) feature.getDefaultGeometry(); assert geomToSplit.isValid() : "No Valid Geometry: " + geomToSplit.toText(); // $NON-NLS-1$ CoordinateReferenceSystem featureCrs = feature.getFeatureType().getCoordinateReferenceSystem(); geomToSplit = GeoToolsUtils.reproject(geomToSplit, featureCrs, this.desiredCRS); if (canSplit(geomToSplit)) { existSplit = true; this.featuresThatSufferedSplit.add(feature); List<Geometry> splitGeometriesResult = split(geomToSplit); this.splitResultList.addAll(createSplitFeatures(splitGeometriesResult, feature)); } } if (!existSplit) { throw new CannotSplitException("The split line cannot split any features"); // $NON-NLS-1$ } } catch (OperationNotFoundException e) { throw makeFailException(e); } catch (TransformException e) { throw makeFailException(e); } return this; }
/** * Analyzes the feature list, take the features that are neighbour and if they meet the * requirements, add a vertex to them. * * @return The builder instance. * @throws SplitFeatureBuilderFailException */ public SplitFeatureBuilder buildNeighbours() throws SplitFeatureBuilderFailException { this.neighbourResultList = new ArrayList<SimpleFeature>(); try { for (SimpleFeature feature : featureList) { Geometry geom = (Geometry) feature.getDefaultGeometry(); CoordinateReferenceSystem featureCRS = feature.getFeatureType().getCoordinateReferenceSystem(); geom = GeoToolsUtils.reproject(geom, featureCRS, desiredCRS); if (!canSplit(geom) && (requireVertex(geom))) { Geometry geomWithAddedVertex = addVertexToNeighbour(geom); geomWithAddedVertex = GeoToolsUtils.reproject(geomWithAddedVertex, desiredCRS, featureCRS); feature.setDefaultGeometry(geomWithAddedVertex); this.neighbourResultList.add(feature); } } } catch (Exception e) { throw makeFailException(e); } return this; }
@SuppressWarnings("unchecked") public void XtestGetSelection() throws Exception { SimpleFeatureType featureType = feature1.getFeatureType(); List<SimpleFeature> newFeatures = new ArrayList<SimpleFeature>(); for (int i = 5; i < 50; i++) { SimpleFeature f = SimpleFeatureBuilder.build( featureType, new Object[] {"feature" + i, i}, "feature" + i); // $NON-NLS-1$ //$NON-NLS-2$ newFeatures.add(f); } features.addAll(newFeatures); while (Display.getCurrent().readAndDispatch()) ; assertSelected(35, false); assertSelected(0, false); assertSelected(48, false); Table table2 = table.getViewer().getTable(); table2.setTopIndex(0); // now test without reveal selectFeature(40, false); assertEquals(0, table2.getTopIndex()); // test with reveal selectFeature(30, true); assertEquals(30, table2.getTopIndex()); }
@Override public SimpleFeature next() { SimpleFeature next = super.next(); String fid = ((SimpleFeature) next).getID(); if (fid.startsWith(fidPrefix)) { fid = fid.substring(fidPrefix.length()); } return new FidAndFtOverrideFeature(next, fid, next.getFeatureType()); }
static SimpleFeature retype(SimpleFeature source, SimpleFeatureBuilder builder) throws IllegalAttributeException { SimpleFeatureType target = builder.getFeatureType(); for (int i = 0; i < target.getAttributeCount(); i++) { AttributeDescriptor attributeType = target.getDescriptor(i); Object value = null; if (source.getFeatureType().getDescriptor(attributeType.getName()) != null) { value = source.getAttribute(attributeType.getName()); } builder.add(value); } FeatureId id = reTypeId(source.getIdentifier(), source.getFeatureType(), target); SimpleFeature retyped = builder.buildFeature(id.getID()); retyped.getUserData().putAll(source.getUserData()); return retyped; }
/** * Handles the feature creation/update/deletion strategy. You may want to override this in a * subclass to handle workflow. * * @param feature the feature that is about to be split * @param geoms new geometries that are the result of splitting * @param filter filter to get at feature * @param localStore the store we're working against * @param localStrategy the strategy in use * @return A list of FeatureIds is returned, one for each feature in the order created. However, * these might not be assigned until after a commit has been performed. * @throws Exception if an error occurs modifying the data source, converting the geometry or an * illegal argument was given */ protected List<FeatureId> handleStrategy( SimpleFeature feature, List<? extends Geometry> geoms, Filter filter, SimpleFeatureStore localStore, String localStrategy) throws Exception { List<SimpleFeature> newFeats = new ArrayList(); GeometryTypeConverterFactory cf = new GeometryTypeConverterFactory(); Converter c = cf.createConverter( Geometry.class, localStore.getSchema().getGeometryDescriptor().getType().getBinding(), null); GeometryType type = localStore.getSchema().getGeometryDescriptor().getType(); String geomAttribute = localStore.getSchema().getGeometryDescriptor().getLocalName(); boolean firstFeature = true; for (Geometry newGeom : geoms) { if (firstFeature) { if (localStrategy.equalsIgnoreCase("replace")) { // use first/largest geom to update existing feature geom feature.setAttribute(geomAttribute, c.convert(newGeom, type.getBinding())); feature = this.handleExtraData(feature); Object[] attributevalues = feature.getAttributes().toArray(new Object[feature.getAttributeCount()]); AttributeDescriptor[] attributes = feature .getFeatureType() .getAttributeDescriptors() .toArray(new AttributeDescriptor[feature.getAttributeCount()]); localStore.modifyFeatures(attributes, attributevalues, filter); firstFeature = false; continue; } else if (localStrategy.equalsIgnoreCase("add")) { // delete the source feature, new ones will be created localStore.removeFeatures(filter); firstFeature = false; } else { throw new IllegalArgumentException( "Unknown strategy '" + localStrategy + "', cannot split"); } } // create + add new features SimpleFeature newFeat = DataUtilities.createFeature( feature.getType(), DataUtilities.encodeFeature(feature, false)); newFeat.setAttribute(geomAttribute, c.convert(newGeom, type.getBinding())); newFeats.add(newFeat); } newFeats = this.handleExtraData(newFeats); return localStore.addFeatures(DataUtilities.collection(newFeats)); }
/** * Returns 0 if the features are the same. 1 if the attributes are the same but have different * featureIDs and -1 if attributes are different or are of different featureTypes. * * @param feature1 * @param feature2 * @return */ public static int same(SimpleFeature feature1, SimpleFeature feature2) { if (DataUtilities.compare(feature1.getFeatureType(), feature2.getFeatureType()) != 0) { return -1; } for (int i = 0; i < feature1.getAttributeCount(); i++) { if (feature1.getAttribute(i) == null) { if (feature2.getAttribute(i) != null) return -1; else continue; } if (feature1.getAttribute(i) instanceof Geometry) { Geometry geom1 = (Geometry) feature1.getAttribute(i); if (feature2.getAttribute(i) instanceof Geometry) { Geometry geom2 = (Geometry) feature2.getAttribute(i); if (geom1.equalsExact(geom2)) continue; else return -1; } else return -1; } if (!feature1.getAttribute(i).equals(feature2.getAttribute(i))) return -1; } return feature1.getID().equals(feature2.getID()) ? 0 : 1; }
@Test public void testModify() throws Exception { final Query queryAll = new Query(RENAMED); SimpleFeatureStore store; store = (SimpleFeatureStore) rts.getFeatureSource(RENAMED); SimpleFeature original = store.getFeatures(fidFilter).features().next(); // test a non mapped attribute String newDescription = ((String) original.getAttribute("description")) + " xxx"; store.modifyFeatures( original.getFeatureType().getDescriptor("description"), newDescription, fidFilter); SimpleFeature modified = store.getFeatures(fidFilter).features().next(); assertEquals(newDescription, modified.getAttribute("description")); // test a mapped attribute MultiPoint mpo = (MultiPoint) original.getAttribute("pointProperty"); MultiPoint mpm = mpo.getFactory().createMultiPoint(new Coordinate[] {new Coordinate(10, 12)}); store.modifyFeatures(original.getFeatureType().getDescriptor("pointProperty"), mpm, fidFilter); modified = store.getFeatures(fidFilter).features().next(); assertTrue(mpm.equalsExact((Geometry) modified.getAttribute("pointProperty"))); }
@Test public void testGetFeaturesReader() throws Exception { FeatureReader<SimpleFeatureType, SimpleFeature> fr; fr = rts.getFeatureReader(new Query(RENAMED), Transaction.AUTO_COMMIT); SimpleFeature sf = fr.next(); fr.close(); assertEquals(primitive, sf.getFeatureType()); // check the feature ids have been renamed as well assertTrue( "Feature id has not been renamed, it's still " + sf.getID(), sf.getID().startsWith(RENAMED)); }
public void remove() throws IOException { if (live == null) { throw new IOException("No current feature to remove"); } if (origional != null) { store.listenerManager.fireFeaturesRemoved( live.getFeatureType().getTypeName(), Transaction.AUTO_COMMIT, ReferencedEnvelope.reference(origional.getBounds()), false); } origional = null; live = null; // prevent live and remove from being written out }
public List<FeatureId> addFeatures(FeatureCollection<SimpleFeatureType, SimpleFeature> collection) throws IOException { List<FeatureId> addedFids = new LinkedList<FeatureId>(); String typeName = getSchema().getTypeName(); SimpleFeature feature = null; SimpleFeature newFeature; FeatureWriter<SimpleFeatureType, SimpleFeature> writer = getDataStore().getFeatureWriterAppend(typeName, getTransaction()); Iterator iterator = collection.iterator(); try { while (iterator.hasNext()) { try { feature = (SimpleFeature) iterator.next(); } catch (Exception e) { throw new DataSourceException("Could not add Features, problem with provided reader", e); } newFeature = (SimpleFeature) writer.next(); try { // JD: we may have a case that the source feature type does not // match exactly the target feature type, so build attributes // based oin target // newFeature.setAttributes(feature.getAttributes(null)); Object[] attributes = new Object[newFeature.getAttributeCount()]; for (int i = 0; i < attributes.length; i++) { AttributeDescriptor type = newFeature.getFeatureType().getDescriptor(i); attributes[i] = feature.getAttribute(type.getLocalName()); } newFeature.setAttributes(attributes); } catch (IllegalAttributeException writeProblem) { throw new DataSourceException( "Could not create " + typeName + " out of provided feature: " + feature.getID(), writeProblem); } writer.write(); addedFids.add(newFeature.getIdentifier()); } } finally { collection.close(iterator); writer.close(); } return addedFids; }
private boolean intersects(SimpleFeature feature) { GeometryDescriptor geomDescriptor = getGeometryAttDescriptor(feature.getFeatureType()); Geometry bboxGeom = new GeometryFactory().toGeometry(bbox); Geometry geom = (Geometry) feature.getAttribute(geomDescriptor.getName()); try { return geom.intersects(bboxGeom); } catch (Exception e) { // ok so exception happened during intersection. This usually means geometry is a little // crazy // what to do?... EditPlugin.log("Can't do intersection so I'm assuming they intersect", e); // $NON-NLS-1$ return false; } }
public static WritableGeometry convertToGeometry(SimpleFeature feature) { // Translate the SimpleFeature geometry to JTS geometry com.vividsolutions.jts.geom.Geometry jtsGeometry = (com.vividsolutions.jts.geom.Geometry) feature.getDefaultGeometry(); // Then generate a MrGeo WritableGeometry from the JTS geometry WritableGeometry geom = GeometryFactory.fromJTS(jtsGeometry); // Now copy over the attributes to the MrGeo WritableGeometry List<AttributeDescriptor> descriptors = feature.getFeatureType().getAttributeDescriptors(); for (AttributeDescriptor desc : descriptors) { String localName = desc.getLocalName(); Object attrValue = feature.getAttribute(localName); if (attrValue != null) { String strValue = attrValue.toString(); geom.setAttribute(localName, strValue); } } return geom; }
/** * A new feature type using the attribute names of all joined feature type. * * @return a new feature type * @throws IllegalAttributeException * @throws SchemaException */ public SimpleFeature getFeature() throws IllegalAttributeException, SchemaException { SimpleFeatureType unionFeatureType = getFeatureType(); // adds the attributes values Object[] attrList = new Object[unionFeatureType.getAttributeCount()]; for (SimpleFeature feature : this.unionFeatures) { SimpleFeatureType featureType = feature.getFeatureType(); for (int j = 0; j < featureType.getAttributeCount(); j++) { // gets the attribute value AttributeDescriptor attrType = featureType.getDescriptor(j); if (!(attrType instanceof GeometryDescriptor)) { Object attrValue = feature.getAttribute(j); // gets the position in the union String unionAttrName = findAttributeName(featureType.getTypeName(), attrType.getLocalName()); int unionAttrPosition = unionFeatureType.indexOf(unionAttrName); // set the value in union attrList[unionAttrPosition] = attrValue; } } } // creates the new feature SimpleFeatureBuilder builder = new SimpleFeatureBuilder(unionFeatureType); builder.addAll(attrList); // SimpleFeature product = unionFeatureType.create(attrList); SimpleFeature product = builder.buildFeature(null); product.setDefaultGeometry(this.geometry); return product; }
/** * Executes the export operation using the parameters that have been specified. * * @return a FeatureCollection with the specified features */ @Override protected SimpleFeatureStore _call() { final ObjectDatabase database = objectDatabase(); if (filterFeatureTypeId != null) { RevObject filterType = database.getIfPresent(filterFeatureTypeId); checkArgument( filterType instanceof RevFeatureType, "Provided filter feature type is does not exist"); } final SimpleFeatureStore targetStore = getTargetStore(); final String refspec = resolveRefSpec(); final String treePath = refspec.substring(refspec.indexOf(':') + 1); final RevTree rootTree = resolveRootTree(refspec); final NodeRef typeTreeRef = resolTypeTreeRef(refspec, treePath, rootTree); final ObjectId defaultMetadataId = typeTreeRef.getMetadataId(); final RevTree typeTree = database.getTree(typeTreeRef.getObjectId()); final ProgressListener progressListener = getProgressListener(); progressListener.started(); progressListener.setDescription( "Exporting from " + path + " to " + targetStore.getName().getLocalPart() + "... "); final Iterator<SimpleFeature> filtered; { final Iterator<SimpleFeature> plainFeatures = getFeatures(typeTree, database, defaultMetadataId, progressListener); Iterator<SimpleFeature> adaptedFeatures = adaptToArguments(plainFeatures, defaultMetadataId); Iterator<Optional<Feature>> transformed = Iterators.transform(adaptedFeatures, ExportOp.this.function); Iterator<SimpleFeature> result = Iterators.filter( Iterators.transform( transformed, new Function<Optional<Feature>, SimpleFeature>() { @Override public SimpleFeature apply(Optional<Feature> input) { return (SimpleFeature) input.orNull(); } }), Predicates.notNull()); // check the resulting schema has something to contribute PeekingIterator<SimpleFeature> peekingIt = Iterators.peekingIterator(result); if (peekingIt.hasNext()) { Function<AttributeDescriptor, String> toString = new Function<AttributeDescriptor, String>() { @Override public String apply(AttributeDescriptor input) { return input.getLocalName(); } }; SimpleFeature peek = peekingIt.peek(); Set<String> sourceAtts = new HashSet<String>( Lists.transform(peek.getFeatureType().getAttributeDescriptors(), toString)); Set<String> targetAtts = new HashSet<String>( Lists.transform(targetStore.getSchema().getAttributeDescriptors(), toString)); if (Sets.intersection(sourceAtts, targetAtts).isEmpty()) { throw new GeoToolsOpException( StatusCode.UNABLE_TO_ADD, "No common attributes between source and target feature types"); } } filtered = peekingIt; } FeatureCollection<SimpleFeatureType, SimpleFeature> asFeatureCollection = new BaseFeatureCollection<SimpleFeatureType, SimpleFeature>() { @Override public FeatureIterator<SimpleFeature> features() { return new DelegateFeatureIterator<SimpleFeature>(filtered); } }; // add the feature collection to the feature store final Transaction transaction; if (transactional) { transaction = new DefaultTransaction("create"); } else { transaction = Transaction.AUTO_COMMIT; } try { targetStore.setTransaction(transaction); try { targetStore.addFeatures(asFeatureCollection); transaction.commit(); } catch (final Exception e) { if (transactional) { transaction.rollback(); } Throwables.propagateIfInstanceOf(e, GeoToolsOpException.class); throw new GeoToolsOpException(e, StatusCode.UNABLE_TO_ADD); } finally { transaction.close(); } } catch (IOException e) { throw new GeoToolsOpException(e, StatusCode.UNABLE_TO_ADD); } progressListener.complete(); return targetStore; }
public void rollback(String toVersion, Filter filter, String[] userIds) throws IOException { // TODO: build an optimized version of this that can do the same work with a couple // of queries assuming the filter is fully encodable Transaction t = getTransaction(); boolean autoCommit = false; if (Transaction.AUTO_COMMIT.equals(t)) { t = new DefaultTransaction(); autoCommit = true; } // Gather feature modified after toVersion ModifiedFeatureIds mfids = store.getModifiedFeatureFIDs(schema.getTypeName(), toVersion, null, filter, userIds, t); FilterFactory ff = CommonFactoryFinder.getFilterFactory(null); // grab the state, we need to mark as dirty all the features we are going to modify/re-insert VersionedJdbcTransactionState state = store.wrapped.getVersionedJdbcTransactionState(t); // remove all features that have been created and not deleted Set fidsToRemove = new HashSet(mfids.getCreated()); fidsToRemove.removeAll(mfids.getDeleted()); if (!fidsToRemove.isEmpty()) { removeFeatures(store.buildFidFilter(fidsToRemove)); state.setTypeNameDirty(getSchema().getTypeName()); } // reinstate all features that were there before toVersion and that // have been deleted after it. Notice this is an insertion, so to preserve // the fids I have to use low level writers where I can set all attributes manually // (we work on the assumption the wrapped data store maps all attributes of the primary // key in the feature itself) Set fidsToRecreate = new HashSet(mfids.getDeleted()); fidsToRecreate.removeAll(mfids.getCreated()); if (!fidsToRecreate.isEmpty()) { state.setTypeNameDirty(getSchema().getTypeName()); state.setFidsDirty(getSchema().getTypeName(), fidsToRecreate); long revision = store.wrapped.getVersionedJdbcTransactionState(t).getRevision(); Filter recreateFilter = store.buildVersionedFilter( schema.getTypeName(), store.buildFidFilter(fidsToRecreate), mfids.fromRevision); FeatureReader<SimpleFeatureType, SimpleFeature> fr = null; FeatureWriter<SimpleFeatureType, SimpleFeature> fw = null; try { DefaultQuery q = new DefaultQuery(schema.getTypeName(), recreateFilter); fr = store.wrapped.getFeatureReader(q, t); fw = store.wrapped.getFeatureWriterAppend(schema.getTypeName(), t); while (fr.hasNext()) { SimpleFeature original = fr.next(); SimpleFeature restored = fw.next(); for (int i = 0; i < original.getFeatureType().getAttributeCount(); i++) { restored.setAttribute(i, original.getAttribute(i)); } restored.setAttribute("revision", new Long(revision)); restored.setAttribute("expired", new Long(Long.MAX_VALUE)); fw.write(); } } catch (IllegalAttributeException iae) { throw new DataSourceException( "Unexpected error occurred while " + "restoring deleted featues", iae); } finally { if (fr != null) fr.close(); if (fw != null) fw.close(); } } // Now onto the modified features, that were there, and still are there. // Since we cannot get a sorted writer we have to do a kind of inner loop scan // (note, a parellel scan of similarly sorted reader and writer would be more // efficient, but writer sorting is not there...) // Here it's possible to work against the external API, thought it would be more // efficient (but more complex) to work against the wrapped one. if (!mfids.getModified().isEmpty()) { state.setTypeNameDirty(getSchema().getTypeName()); state.setFidsDirty(getSchema().getTypeName(), mfids.getModified()); Filter modifiedIdFilter = store.buildFidFilter(mfids.getModified()); Filter mifCurrent = store.buildVersionedFilter(schema.getTypeName(), modifiedIdFilter, new RevisionInfo()); FeatureReader<SimpleFeatureType, SimpleFeature> fr = null; FeatureWriter<SimpleFeatureType, SimpleFeature> fw = null; try { fw = store.getFeatureWriter(schema.getTypeName(), mifCurrent, t); while (fw.hasNext()) { SimpleFeature current = fw.next(); Filter currIdFilter = ff.id(Collections.singleton(ff.featureId(current.getID()))); Filter cidToVersion = store.buildVersionedFilter(schema.getTypeName(), currIdFilter, mfids.fromRevision); DefaultQuery q = new DefaultQuery(schema.getTypeName(), cidToVersion); q.setVersion(mfids.fromRevision.toString()); fr = store.getFeatureReader(q, t); SimpleFeature original = fr.next(); for (int i = 0; i < original.getFeatureType().getAttributeCount(); i++) { current.setAttribute(i, original.getAttribute(i)); } fr.close(); fw.write(); } } catch (IllegalAttributeException iae) { throw new DataSourceException( "Unexpected error occurred while " + "restoring deleted featues", iae); } finally { if (fr != null) fr.close(); if (fw != null) fw.close(); } } // if it's auto commit, don't forget to actually commit if (autoCommit) { t.commit(); t.close(); } }