public void rollback(IProgressMonitor monitor) throws Exception {
    editBlackboard.removeGeometries(Collections.singleton(first));

    EditGeom newGeom =
        editBlackboard.newGeom(
            oldshape.getEditGeom().getFeatureIDRef().get(), oldshape.getEditGeom().getShapeType());

    for (int i = 0; i < oldshape.getNumCoords(); i++) {
      editBlackboard.addCoordinate(oldshape.getCoord(i), newGeom.getShell());
    }

    if (currentShapeSet) setCurrentShape(newGeom.getShell());

    FeatureStore<SimpleFeatureType, SimpleFeature> store =
        layer.getResource(FeatureStore.class, new SubProgressMonitor(monitor, 1));

    FilterFactory factory = CommonFactoryFinder.getFilterFactory(GeoTools.getDefaultHints());
    Set<FeatureId> ids = new HashSet<FeatureId>();
    for (FeatureId id : newFids) {
      ids.add(id);
    }
    Id filter = factory.id(ids);

    store.removeFeatures(filter);
    Geometry oldType = (Geometry) oldFeature.getDefaultGeometry();
    GeometryDescriptor newType = store.getSchema().getGeometryDescriptor();
    store.modifyFeatures(
        newType, oldType, factory.id(FeatureUtils.stringToId(factory, oldFeature.getID())));
    oldFeature.setDefaultGeometry(oldGeometry);
    newFids.clear();
  }
 private boolean hasDirtyGeom(EditToolHandler handler) {
   if (handler.getCurrentGeom() != null && handler.getCurrentGeom().isChanged()) return true;
   List<EditGeom> geoms = handler.getEditBlackboard(handler.getEditLayer()).getGeoms();
   for (EditGeom geom : geoms) {
     if (geom.isChanged()) return true;
   }
   return false;
 }
  public void run(IProgressMonitor monitor) throws Exception {
    editBlackboard.startBatchingEvents();

    oldshape = shapeProvider.get(new SubProgressMonitor(monitor, 1));
    oldFeature = featureProvider.get(new SubProgressMonitor(monitor, 1));
    oldGeometry = (Geometry) oldFeature.getDefaultGeometry();
    layer = layerProvider.get(new SubProgressMonitor(monitor, 1));

    editBlackboard.removeGeometries(Collections.singleton(oldshape.getEditGeom()));
    ShapeType shapeType = oldshape.getEditGeom().getShapeType();
    EditGeom current =
        editBlackboard.newGeom(oldshape.getEditGeom().getFeatureIDRef().get(), shapeType);
    first = current;

    final Set<EditGeom> addedGeoms = new HashSet<EditGeom>();
    for (int i = 0; i < oldshape.getNumPoints(); i++) {
      addCoords(current.getShell(), i);
      if (current.getShell().getNumPoints() > 1
          && i < oldshape.getNumPoints() - 1
          && points.contains(oldshape.getPoint(i))) {

        current =
            editBlackboard.newGeom(
                "newFeature" + System.currentTimeMillis(), shapeType); // $NON-NLS-1$
        List<Coordinate> coords = oldshape.getCoordsAt(i);
        editBlackboard.addCoordinate(coords.get(coords.size() - 1), current.getShell());
        addedGeoms.add(current);
      }
    }

    editBlackboard.removeGeometries(addedGeoms);

    if (getCurrentShape() == oldshape) {
      currentShapeSet = true;
      setCurrentShape(first.getShell());
    }

    final FeatureStore<SimpleFeatureType, SimpleFeature> store =
        layer.getResource(FeatureStore.class, new SubProgressMonitor(monitor, 1));

    modifyOldFeature(store);

    createAndAddFeatures(addedGeoms, store);

    editBlackboard.fireBatchedEvents();
  }
 /**
  * Copies the geometry back onto the editblackboard.
  *
  * @return
  */
 private void copyFeature(EditBlackboard editBlackboard, EditGeom geom) {
   EditGeom newGeom = editBlackboard.newGeom(geom.getFeatureIDRef().get(), geom.getShapeType());
   for (PrimitiveShape shape : geom) {
     PrimitiveShape newShape;
     if (shape == geom.getShell()) {
       newShape = newGeom.getShell();
     } else {
       newShape = newGeom.newHole();
     }
     if (shape == currentShape) handler.setCurrentShape(newShape);
     for (int i = 0; i < shape.getNumCoords(); i++) {
       editBlackboard.addCoordinate(shape.getCoord(i), newShape);
     }
     newGeom.setChanged(geom.isChanged());
   }
 }
  @SuppressWarnings({"unchecked"})
  private void modifyOldFeature(final FeatureStore<SimpleFeatureType, SimpleFeature> store)
      throws IOException, IllegalAttributeException {
    FilterFactory fac = CommonFactoryFinder.getFilterFactory(GeoTools.getDefaultHints());
    Filter filter = fac.id(FeatureUtils.stringToId(fac, oldFeature.getID()));

    Geometry g = GeometryCreationUtil.createGeom(LineString.class, first.getShell(), true);
    if (store
        .getSchema()
        .getGeometryDescriptor()
        .getType()
        .getBinding()
        .isAssignableFrom(MultiLineString.class))
      g = new GeometryFactory().createMultiLineString(new LineString[] {(LineString) g});

    store.modifyFeatures(store.getSchema().getGeometryDescriptor(), g, filter);
    oldFeature.setDefaultGeometry(g);
  }
  @Test
  public void testInOtherHole() throws Exception {

    bb.addPoint(10, 10, hole);
    bb.addPoint(20, 10, hole);

    PrimitiveShape hole2 = geom.newHole();

    bb.addPoint(50, 50, hole2);
    bb.addPoint(70, 50, hole2);
    bb.addPoint(70, 70, hole2);
    bb.addPoint(50, 70, hole2);
    bb.addPoint(50, 50, hole2);

    MapMouseEvent event =
        new MapMouseEvent(
            null, 60, 60, MapMouseEvent.NONE, MapMouseEvent.NONE, MapMouseEvent.BUTTON1);
    assertEquals(
        Messages.ValidHoleValidator_holeOverlap,
        validator.isValid(handler, event, EventType.RELEASED));
  }
  @Before
  public void setUp() throws Exception {
    handler = new TestHandler();
    bb = handler.getEditBlackboard();
    geom = bb.newGeom("id", ShapeType.POLYGON); // $NON-NLS-1$
    bb.addPoint(0, 0, geom.getShell());
    bb.addPoint(100, 0, geom.getShell());
    bb.addPoint(100, 100, geom.getShell());
    bb.addPoint(0, 100, geom.getShell());
    bb.addPoint(0, 0, geom.getShell());

    validator = new ValidHoleValidator();

    hole = geom.newHole();

    handler.setCurrentShape(hole);
  }