Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / extensions / extEditing / src / org / gvsig / editing / EditionManager.java @ 39578

History | View | Annotate | Download (26.1 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 */
22
package org.gvsig.editing;
23

    
24
import java.awt.BorderLayout;
25
import java.awt.Dimension;
26
import java.awt.ScrollPane;
27
import java.util.ArrayList;
28
import java.util.Iterator;
29
import java.util.List;
30

    
31
import javax.swing.JOptionPane;
32
import javax.swing.JPanel;
33
import javax.swing.SwingUtilities;
34

    
35
import org.gvsig.andami.PluginServices;
36
import org.gvsig.andami.messages.NotificationManager;
37
import org.gvsig.andami.ui.mdiManager.IWindow;
38
import org.gvsig.app.ApplicationLocator;
39
import org.gvsig.app.project.documents.view.gui.DefaultViewPanel;
40
import org.gvsig.editing.layers.FactoryLayerEdited;
41
import org.gvsig.editing.layers.ILayerEdited;
42
import org.gvsig.editing.layers.VectorialLayerEdited;
43
import org.gvsig.fmap.dal.exception.DataException;
44
import org.gvsig.fmap.dal.exception.DataRuntimeException;
45
import org.gvsig.fmap.dal.feature.AbstractFeatureRule;
46
import org.gvsig.fmap.dal.feature.EditableFeature;
47
import org.gvsig.fmap.dal.feature.Feature;
48
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
49
import org.gvsig.fmap.dal.feature.FeatureRule;
50
import org.gvsig.fmap.dal.feature.FeatureRules;
51
import org.gvsig.fmap.dal.feature.FeatureSelection;
52
import org.gvsig.fmap.dal.feature.FeatureStore;
53
import org.gvsig.fmap.dal.feature.FeatureType;
54
import org.gvsig.fmap.geom.Geometry;
55
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
56
import org.gvsig.fmap.geom.GeometryLocator;
57
import org.gvsig.fmap.geom.GeometryManager;
58
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
59
import org.gvsig.fmap.geom.primitive.Envelope;
60
import org.gvsig.fmap.mapcontext.layers.CancelationException;
61
import org.gvsig.fmap.mapcontext.layers.FLayer;
62
import org.gvsig.fmap.mapcontext.layers.LayerCollectionEvent;
63
import org.gvsig.fmap.mapcontext.layers.LayerCollectionListener;
64
import org.gvsig.fmap.mapcontext.layers.LayerEvent;
65
import org.gvsig.fmap.mapcontext.layers.LayerListener;
66
import org.gvsig.fmap.mapcontext.layers.LayerPositionEvent;
67
import org.gvsig.fmap.mapcontext.layers.SpatialCache;
68
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
69
import org.gvsig.fmap.mapcontrol.MapControl;
70
import org.gvsig.fmap.mapcontrol.MapControlLocator;
71
import org.gvsig.fmap.mapcontrol.MapControlManager;
72
import org.gvsig.gui.beans.buttonspanel.ButtonsPanel;
73
import org.gvsig.gui.beans.buttonspanel.ButtonsPanelEvent;
74
import org.gvsig.gui.beans.buttonspanel.ButtonsPanelListener;
75
import org.gvsig.tools.observer.ObservableHelper;
76
import org.gvsig.tools.observer.Observer;
77
import org.gvsig.tools.swing.api.ToolsSwingLocator;
78
import org.gvsig.tools.swing.api.dynobject.DynObjectSwingManager;
79
import org.gvsig.tools.swing.api.dynobject.JDynObjectComponent;
80
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
81
import org.slf4j.Logger;
82
import org.slf4j.LoggerFactory;
83

    
84
public class EditionManager implements LayerListener, LayerCollectionListener, IEditionManager {
85

    
86
    private static final Logger LOG = LoggerFactory
87
        .getLogger(EditionManager.class);
88

    
89
    private List<ILayerEdited> editedLayers = new ArrayList<ILayerEdited>();
90
    private MapControl mapCtrl = null;
91
    private ILayerEdited ile = null;
92
    private ObservableHelper observableHelper = new ObservableHelper();
93
    private GeometryManager geomManager = GeometryLocator.getGeometryManager();
94
    private MapControlManager mapControlManager = MapControlLocator.getMapControlManager();
95
    
96
    /* (non-Javadoc)
97
         * @see org.gvsig.editing.IEditionManager#getLayerEdited(org.gvsig.fmap.mapcontext.layers.FLayer)
98
         */
99
    public ILayerEdited getLayerEdited(FLayer lyr) {
100
        ILayerEdited aux = null;
101
        for (int i = 0; i < editedLayers.size(); i++) {
102
            aux = editedLayers.get(i);
103
            if (aux.getLayer() == lyr)
104
                return aux;
105
        }
106
        return null;
107
    }
108
    
109
    /* (non-Javadoc)
110
         * @see org.gvsig.editing.IEditionManager#editLayer(org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect, org.gvsig.app.project.documents.view.gui.DefaultViewPanel)
111
         */
112
    public void editLayer(FLyrVect lv, DefaultViewPanel vista)
113
        throws DataException {
114

    
115
        CADExtension.initFocus();
116
        vista.showConsole();
117
        MapControl mapControl = vista.getMapControl();
118
        this.setMapControl(mapControl);
119

    
120
        lv.addLayerListener(this);
121

    
122
        // This line also enables the spatial cache for snapping:
123
        lv.getFeatureStore().edit();
124
        lv.getFeatureStore().addObserver(vista);
125

    
126
        ApplicationLocator.getManager().refreshMenusAndToolBars();
127

    
128
        lv.getFeatureStore().addObserver(mapControl);
129
        StartEditing.startCommandsApplicable(vista, lv);
130

    
131
        // vista.repaintMap();
132
        // ----------------------------
133
        // this forces a true repaint:
134
        lv.drawValueChanged(LayerEvent.createDrawValuesChangedEvent(lv, ""));
135

    
136
    }
137

    
138
    public void visibilityChanged(LayerEvent e) {
139
    }
140

    
141
    public void activationChanged(LayerEvent e) {
142
        if (e.getSource().isActive()) {
143
            ile = getLayerEdited(e.getSource());
144
        }
145
        if (ile == null || ile.getLayer().equals(e.getSource())) {
146

    
147
            if (ile != null && !ile.getLayer().isActive()) {
148
                VectorialLayerEdited lastVLE = (VectorialLayerEdited) ile;
149
                lastVLE.activationLost(e);
150
            }
151
            if (e.getSource() instanceof FLyrVect) {
152
                VectorialLayerEdited vle = null;
153
                vle = (VectorialLayerEdited) getLayerEdited(e.getSource());
154
                ile = vle;
155
                if (getMapControl() != null && vle != null
156
                    && vle.getLayer().isActive()) {
157
                    getMapControl().setTool("cadtooladapter");
158
                    vle.activationGained(e);
159
                    return;
160
                }
161
            }
162
            if (getMapControl() != null) {
163
                getMapControl().setTool("zoomIn");
164
                PluginServices.getMainFrame().setSelectedTool("ZOOM_IN");
165
            }
166
        }
167
    }
168

    
169
    public void nameChanged(LayerEvent e) {
170
    }
171

    
172
    public void editionChanged(LayerEvent e) {
173
        ILayerEdited lyrEdit = getLayerEdited(e.getSource());
174

    
175
        // Si no est? en la lista, comprobamos que est? en edici?n
176
        // y lo a?adimos
177
        if ((lyrEdit == null) && e.getSource().isEditing()) {
178
            lyrEdit =
179
                FactoryLayerEdited.createLayerEdited(e.getSource(), mapCtrl);
180
            editedLayers.add(lyrEdit);
181
            if (getMapControl() != null) {
182
                getMapControl().setTool("cadtooladapter");
183
                CADExtension.setCADTool("_selection", true);
184
            }
185
            PluginServices.getMainFrame().setSelectedTool("_selection");
186
            // idActiveLayer = editedLayers.size() - 1;
187
            ile = getLayerEdited(e.getSource());
188
            LOG.debug("NUEVA CAPA EN EDICION: {}", lyrEdit.getLayer().getName());
189

    
190
            // Ponemos el resto de temas desactivados
191
            if (mapCtrl != null)
192
                mapCtrl.getMapContext().getLayers().setActive(false);
193
            // y activamos el nuevo.
194
            e.getSource().setActive(true);
195

    
196
            if (e.getSource() instanceof FLyrVect) {
197
                FLyrVect fLyrVect = (FLyrVect) e.getSource();
198
                ((VectorialLayerEdited) lyrEdit)
199
                    .setEditionChangeManager(new EditionChangeManager(fLyrVect));
200

    
201
                addCheckRules(fLyrVect);
202
            }
203
        } else {
204
            for (int i = 0; i < editedLayers.size(); i++) {
205
                VectorialLayerEdited vle =
206
                    (VectorialLayerEdited) editedLayers.get(i);
207
                if (vle.equals(lyrEdit)) {
208
                    editedLayers.remove(i);
209
                    ile = null;
210
                    return;
211
                }
212
            }
213
        }
214

    
215
    }
216

    
217
    /* (non-Javadoc)
218
         * @see org.gvsig.editing.IEditionManager#getActiveLayerEdited()
219
         */
220
    public ILayerEdited getActiveLayerEdited() {
221
        return ile;
222
    }
223

    
224
    /* (non-Javadoc)
225
         * @see org.gvsig.editing.IEditionManager#getMapControl()
226
         */
227
    public MapControl getMapControl() {
228
        return mapCtrl;
229
    }
230

    
231
    /* (non-Javadoc)
232
         * @see org.gvsig.editing.IEditionManager#setMapControl(org.gvsig.fmap.mapcontrol.MapControl)
233
         */
234
    public void setMapControl(MapControl mapCtrl) {
235
        if (mapCtrl != null) {
236
            this.mapCtrl = mapCtrl;
237
            mapCtrl.getMapContext().getLayers().addLayerListener(this);
238
            mapCtrl.getMapContext().getLayers()
239
                .addLayerCollectionListener(this);
240
        }
241
    }
242

    
243
    public void layerAdded(LayerCollectionEvent e) {
244
        // Nothing to do
245

    
246
    }
247

    
248
    public void layerMoved(LayerPositionEvent e) {
249
        // Nothing to do
250
    }
251

    
252
    public void layerRemoved(LayerCollectionEvent e) {
253
        VectorialLayerEdited vle =
254
            (VectorialLayerEdited) getActiveLayerEdited();
255
        if (vle != null && vle.getLayer().isActive()) {
256
            try {
257
                vle.clearSelection();
258
            } catch (DataException e1) {
259
                NotificationManager.addError(e1);
260
            }
261
            editedLayers.remove(vle);
262
            getMapControl().setTool("zoomIn");
263
            FLyrVect lv = (FLyrVect) vle.getLayer();
264
            if (e.getAffectedLayer().equals(lv)) {
265
                IWindow window =
266
                    PluginServices.getMDIManager().getActiveWindow();
267
                if (window instanceof DefaultViewPanel) {
268
                    DefaultViewPanel view = (DefaultViewPanel) window;
269
                    view.hideConsole();
270
                    view.validate();
271
                    view.repaint();
272
                }
273
            }
274
        }
275
        PluginServices.getMainFrame().enableControls();
276
    }
277

    
278
    public void layerAdding(LayerCollectionEvent e) throws CancelationException {
279
        // Nothing to do
280
    }
281

    
282
    public void layerMoving(LayerPositionEvent e) throws CancelationException {
283
        // Nothing to do
284
    }
285

    
286
    public void layerRemoving(LayerCollectionEvent e)
287
        throws CancelationException {
288
        // Nothing to do
289
    }
290

    
291
    public void activationChanged(LayerCollectionEvent e)
292
        throws CancelationException {
293
        // Nothing to do
294
    }
295

    
296
    public void visibilityChanged(LayerCollectionEvent e)
297
        throws CancelationException {
298
        // Nothing to do
299
    }
300

    
301
    public void drawValueChanged(LayerEvent e) {
302
        // Nothing to do
303
    }
304

    
305
    public class CheckMandatoryAttributtes extends AbstractFeatureRule {
306

    
307
        protected CheckMandatoryAttributtes() {
308
            super("CheckMandatoryAttributtes", "CheckMandatoryAttributtes");
309
        }
310

    
311
        public void validate(Feature feature, FeatureStore featureStore)
312
            throws DataException {
313
            // Comprobar si hay campos obligatorios y presentar formulario
314
            FeatureType featureType = feature.getType();
315
            FeatureAttributeDescriptor[] attributeDescriptors =
316
                featureType.getAttributeDescriptors();
317
            boolean showForm = false;
318
            for (int i = 0; i < attributeDescriptors.length; i++) {
319
                FeatureAttributeDescriptor attrDesc = attributeDescriptors[i];
320
                if (((attrDesc.isPrimaryKey() && !attrDesc.isAutomatic())|| !attrDesc.allowNull())
321
                    && feature.get(attrDesc.getName()) == null) {
322
                    showForm = true;
323
                    break;
324
                }
325
            }
326
            if (showForm) {
327
                askRequiredAttributtes((EditableFeature) feature, featureStore);
328
            }
329
        }
330

    
331
    }
332

    
333
    private void askRequiredAttributtes(final EditableFeature feature,
334
        final FeatureStore store)
335
        throws FeatureRuleMandatoryAttributesException {
336

    
337
        // Comprobar que estamos en el thread de swing y si no excepcion
338
        if (!SwingUtilities.isEventDispatchThread()) {
339
            try {
340
                SwingUtilities.invokeAndWait(new Runnable() {
341

    
342
                    public void run() {
343
                        askRequiredAttributtes(feature, store);
344
                    }
345
                });
346
            } catch (Exception e1) {
347
                throw new FeatureRuleMandatoryAttributesException(e1,
348
                    store.getFullName());
349
            }
350
            return;
351
        }
352
        DynObjectSwingManager dynObjectSwinManager =
353
            ToolsSwingLocator.getDynObjectSwingManager();
354
        final JDynObjectComponent dynObjectComponent;
355
        try {
356
            dynObjectComponent =
357
                dynObjectSwinManager.createJDynObjectComponent(
358
                    feature.getAsDynObject(), true);
359
        } catch (Exception e) {
360
            
361
            // TODO This has to be improved
362
            // Instead of this warning, show dialog to
363
            // fill feature type 
364
            showBadValuesMessage(e.getMessage());
365
            return;
366
            
367
        }
368
        final JPanel panel = new JPanel();
369

    
370
        ButtonsPanel buttonsPanel =
371
            new ButtonsPanel(ButtonsPanel.BUTTONS_ACCEPTCANCEL);
372
        buttonsPanel.addButtonPressedListener(new ButtonsPanelListener() {
373

    
374
            public void actionButtonPressed(ButtonsPanelEvent e) {
375
                if (e.getButton() == ButtonsPanel.BUTTON_ACCEPT) {
376
                    dynObjectComponent.saveStatus();
377
                    panel.setVisible(false);
378
                }
379
                if (e.getButton() == ButtonsPanel.BUTTON_CANCEL) {
380
                    panel.setVisible(false);
381
                    throw new FeatureRuleMandatoryAttributesException(store
382
                        .getFullName());
383
                }
384
            }
385

    
386
        });
387
        panel.setLayout(new BorderLayout());
388
        ScrollPane scrollPanel = new ScrollPane();
389
        scrollPanel.add(dynObjectComponent.asJComponent(), BorderLayout.CENTER);
390
        panel.add(scrollPanel);
391
        panel.add(buttonsPanel, BorderLayout.SOUTH);
392
        panel.setPreferredSize(new Dimension(800, 600));
393
        WindowManager wm = ToolsSwingLocator.getWindowManager();
394
        wm.showWindow(panel, "Fill mandatory fields", WindowManager.MODE.DIALOG);
395

    
396
    }
397

    
398
    /**
399
     * @param message
400
     */
401
    private void showBadValuesMessage(String message) {
402
        
403
        ApplicationLocator.getManager().message(
404
            message,
405
            JOptionPane.WARNING_MESSAGE);
406
        
407
        /*
408
         * We cannot do this because window focus
409
         * causes exception in drawing
410
         * 
411
        IWindow iw = PluginServices.getMDIManager().getActiveWindow();
412
        Component pare = null;
413
        if (iw instanceof Component) {
414
            pare = (Component) iw;
415
        }
416
        
417
        String _tit = Messages.getText("editing");
418
        String _msg = Messages.getText("_Invalid_values_in_some_fields_must_be_edited_before_end_editing");
419
        _msg = _msg + "\n\n[" + message + "]";
420
        
421
        JOptionPane.showMessageDialog(
422
            pare,
423
            _msg, _tit,
424
            JOptionPane.WARNING_MESSAGE);
425
            */
426
    }
427

    
428
    private void addCheckRules(FLyrVect layer) {
429
        try {
430
            FeatureType featureType =
431
                layer.getFeatureStore().getDefaultFeatureType();
432
            FeatureRules featureRules = featureType.getRules();
433
            for (Iterator it = featureRules.iterator(); it.hasNext();) {
434
                FeatureRule rule = (FeatureRule) it.next();
435
                if (rule instanceof CheckMandatoryAttributtes) {
436
                    return;
437
                }
438
            }
439
            featureRules.add(new CheckMandatoryAttributtes());
440
        } catch (DataException e) {
441
            throw new RuntimeException(e);
442
        }
443
    }
444

    
445
    public class FeatureRuleMandatoryAttributesException extends
446
        DataRuntimeException {
447

    
448
        private static final long serialVersionUID = -7965533441336164612L;
449
        private final static String MESSAGE_FORMAT =
450
            "Can't apply rule in store %(store)s.";
451
        private final static String MESSAGE_KEY =
452
            "_FeatureRuleMandatoryAttributesException";
453

    
454
        public FeatureRuleMandatoryAttributesException(Throwable cause,
455
            String store) {
456
            super(MESSAGE_FORMAT, cause, MESSAGE_KEY, serialVersionUID);
457
            this.setValue("store", store);
458
        }
459

    
460
        public FeatureRuleMandatoryAttributesException(String store) {
461
            super(MESSAGE_FORMAT, MESSAGE_KEY, serialVersionUID);
462
            this.setValue("store", store);
463
        }
464
    }
465

    
466
    private VectorialLayerEdited getVLE() {
467
        return (VectorialLayerEdited) getActiveLayerEdited();
468
    }
469
    
470
        private void insertSpatialCache(Geometry geom)
471
                        throws CreateEnvelopeException {
472
                VectorialLayerEdited vle = getVLE();
473
                SpatialCache spatialCache = ((FLyrVect) vle.getLayer())
474
                                .getSpatialCache();
475
                Envelope r = geom.getEnvelope();
476
                if (geom.getType() == Geometry.TYPES.POINT) {
477
                        r = geomManager.createEnvelope(r.getMinimum(0), r.getMinimum(1),
478
                                        r.getMinimum(0) + 1, r.getMinimum(1) + 1, SUBTYPES.GEOM2D);
479
                }
480
                spatialCache.insert(r, geom);
481

    
482
        }
483

    
484
        private void updateSpatialCache(Geometry geom) {
485
                // TODO: no se actualizaban la cache espacial cuando se modifican las geometrias,
486
                // habria que hacerlo.
487
                LOG.info("TODO: need update spatial cache");
488
        }
489

    
490
        private void removeSpatialCache(Geometry geom) {
491
                // TODO: no se actualizaban la cache espacial cuando se modifican las geometrias,
492
                // habria que hacerlo.
493
                LOG.info("TODO: need update spatial cache");
494
        }
495

    
496
    private void draw(Geometry geometry, Feature feature) {
497
        if (geometry != null) {
498
            getMapControl().getMapControlDrawer()
499
                .draw(geometry, mapControlManager.getGeometrySelectionSymbol());
500
        }
501
    }
502

    
503
    public Feature  insertGeometry(Geometry geometry) {
504
            VectorialLayerEdited vle = getVLE();
505
        try {
506
            FeatureStore featureStore =
507
                ((FLyrVect) vle.getLayer()).getFeatureStore();
508
            EditableFeature eFeature = featureStore.createNewFeature(true);
509
           
510
            //Reproject the geometry
511
            Geometry insertedGeometry = geometry;
512
            if (getVLE().getLayer().getCoordTrans() != null){
513
                insertedGeometry = insertedGeometry.cloneGeometry();
514
                insertedGeometry.reProject(getVLE().getLayer().getCoordTrans().getInverted());
515
            }
516
            
517
            eFeature.setGeometry(featureStore.getDefaultFeatureType()
518
                .getDefaultGeometryAttributeName(), insertedGeometry);
519
            
520
                EditionNotifycation notification = notifyObservers(EditionNotifycation.BEFORE_INSERT_FEATURE, getVLE().getLayer(), featureStore, eFeature);
521
                if( notification.isProcessCanceled() ) {
522
                        return null;
523
                }
524

    
525
            featureStore.insert(eFeature);
526
            insertSpatialCache(insertedGeometry);
527
            draw(insertedGeometry, eFeature);
528
            
529
                notifyObservers(EditionNotifycation.AFTER_INSERT_FEATURE, vle.getLayer(), featureStore, eFeature);
530

    
531
            return eFeature;
532
        } catch (Exception e) {
533
            NotificationManager.addError(e.getMessage(), e);
534
            return null;
535
        }
536
    }
537
    
538
    public Feature insertGeometry(Geometry geometry, Feature feature) {
539
        VectorialLayerEdited vle = getVLE();
540

    
541
        try {
542
            FeatureStore featureStore =
543
                ((FLyrVect) vle.getLayer()).getFeatureStore();
544
            EditableFeature eFeature =
545
                featureStore.createNewFeature(
546
                    featureStore.getDefaultFeatureType(), feature);
547
            eFeature.setGeometry(featureStore.getDefaultFeatureType()
548
                .getDefaultGeometryAttributeName(), geometry);
549

    
550
                EditionNotifycation notification = notifyObservers(EditionNotifycation.BEFORE_INSERT_FEATURE, getVLE().getLayer(), featureStore, feature);
551
                if( notification.isProcessCanceled() ) {
552
                        return null;
553
                }
554

    
555
            featureStore.insert(eFeature);
556
            insertSpatialCache(geometry);
557
            draw(geometry, eFeature);
558

    
559
            notifyObservers(EditionNotifycation.AFTER_INSERT_FEATURE, vle.getLayer(), featureStore, eFeature);
560

    
561
            return eFeature;
562
        } catch (Exception e) {
563
            NotificationManager.addError(e.getMessage(), e);
564
            return null;
565
        }
566
    }
567

    
568
    
569
    public Feature insertFeature(Feature feature) {
570
        VectorialLayerEdited vle = getVLE();
571

    
572
        try {
573
                
574
            FeatureStore featureStore =
575
                ((FLyrVect) vle.getLayer()).getFeatureStore();
576
            EditableFeature eFeature =
577
                featureStore.createNewFeature(
578
                    featureStore.getDefaultFeatureType(), feature);
579
            Geometry geometry = feature.getDefaultGeometry();
580

    
581
                EditionNotifycation notification = notifyObservers(EditionNotifycation.BEFORE_INSERT_FEATURE, getVLE().getLayer(), featureStore, feature);
582
                if( notification.isProcessCanceled() ) {
583
                        return null;
584
                }
585

    
586
                featureStore.insert(eFeature);
587
            insertSpatialCache(geometry);
588
            draw(geometry, eFeature);
589

    
590
            notifyObservers(EditionNotifycation.AFTER_INSERT_FEATURE, vle.getLayer(), featureStore, eFeature);
591

    
592
            return eFeature;
593
        } catch (Exception e) {
594
            NotificationManager.addError(e.getMessage(), e);
595
            return null;
596
        }
597
    }
598

    
599
    public Feature insertAndSelectGeometry(String toolName, Geometry geometry) {
600
        Feature feature = null;
601
        try {
602
            FeatureStore featureStore = getVLE().getFeatureStore();
603
            featureStore.beginComplexNotification();
604
            featureStore.beginEditingGroup(toolName);
605
            FeatureSelection newSelection =
606
                featureStore.createFeatureSelection();
607
            feature = insertGeometry(geometry);
608
            if( feature != null ) {
609
                    newSelection.select(feature);
610
                    featureStore.setSelection(newSelection);
611
            }
612
            featureStore.endEditingGroup();
613
            featureStore.endComplexNotification();
614
            
615
        } catch (DataException e) {
616
            NotificationManager.showMessageError("insertAndSelectGeoemtry", e);
617
        }
618
        return feature;
619
    }
620
            
621

    
622
    public EditableFeature updateGeometry(FeatureStore store, Feature feature, Geometry geometry) {
623
                try {
624
                        EditableFeature eFeature = feature.getEditable();
625
                        eFeature.setGeometry(feature.getType()
626
                                        .getDefaultGeometryAttributeName(), geometry);
627
                EditionNotifycation notification = notifyObservers(EditionNotifycation.BEFORE_UPDATE_FEATURE, getVLE().getLayer(), store, feature);
628
                if( notification.isProcessCanceled() ) {
629
                        return null;
630
                }
631
                        store.update(eFeature);
632
            updateSpatialCache(geometry);
633
                notifyObservers(EditionNotifycation.AFTER_UPDATE_FEATURE, getVLE().getLayer(), store, eFeature);
634
                return eFeature;
635
                } catch (Exception e) {
636
            NotificationManager.addError(e.getMessage(), e);
637
            return null;
638
                }
639
        
640
    }
641

    
642
    public EditableFeature updateFeature(FeatureStore store, Feature feature) {
643
                try {
644
                        EditableFeature eFeature = feature.getEditable();
645
                EditionNotifycation notification = notifyObservers(EditionNotifycation.BEFORE_UPDATE_FEATURE, getVLE().getLayer(), store, feature);
646
                if( notification.isProcessCanceled() ) {
647
                        return null;
648
                }
649
                        store.update(eFeature);
650
            updateSpatialCache(feature.getDefaultGeometry());
651
                notifyObservers(EditionNotifycation.AFTER_UPDATE_FEATURE, getVLE().getLayer(), store, eFeature);
652
                return eFeature;
653
                } catch (Exception e) {
654
            NotificationManager.addError(e.getMessage(), e);
655
            return null;
656
                }
657
        
658
    }
659
    
660
    public void removeFeature(FeatureStore store, Feature feature) {
661
                try {
662
                EditionNotifycation notification = notifyObservers(EditionNotifycation.BEFORE_REMOVE_FEATURE, getVLE().getLayer(), store, feature);
663
                if( notification.isProcessCanceled() ) {
664
                        return;
665
                }
666
                        store.delete(feature);
667
            removeSpatialCache(feature.getDefaultGeometry());
668
                notifyObservers(EditionNotifycation.AFTER_REMOVE_FEATURE, getVLE().getLayer(), store, feature);
669
                } catch (Exception e) {
670
            NotificationManager.addError(e.getMessage(), e);
671
                }
672
            
673
    }
674
    
675
        public void addObserver(Observer o) {
676
                observableHelper.addObserver(o);                
677
        }
678

    
679
        public void deleteObserver(Observer o) {
680
                observableHelper.deleteObserver(o);
681
        }
682

    
683
        public void deleteObservers() {
684
                observableHelper.deleteObservers();
685
        }
686
        
687
        private void notifyObservers(EditionNotifycation notifycation) {
688
                observableHelper.notifyObservers(this, notifycation);
689
        }
690

    
691
        private EditionNotifycation notifyObservers(int type, FLayer layer,
692
                        FeatureStore store, Feature feature) {
693
                DefaultEditionNotifycation notifycation = new DefaultEditionNotifycation(
694
                                type, layer, store, feature);
695
                try {
696
                        observableHelper.notifyObservers(this, notifycation);
697
                } catch (Exception ex) {
698
                        LOG.info("Can't notify observers", ex);
699
                }
700
                return notifycation;
701
        }
702
        
703
        class DefaultEditionNotifycation implements EditionNotifycation {
704

    
705
                private int type;
706
                private FLayer layer;
707
                private FeatureStore store;
708
                private Feature feature;
709
                private boolean processCanceled=false;
710

    
711
                DefaultEditionNotifycation(int type, FLayer layer, FeatureStore store, Feature feature) {
712
                        this.type = type;
713
                        this.layer = layer; 
714
                        this.store = store;
715
                        this.feature = feature;
716
                }
717
                
718
                public int getNotificationType() {
719
                        return type;
720
                }
721

    
722
                public FLyrVect getLayer() {
723
                        return (FLyrVect) layer;
724
                }
725

    
726
                public FeatureStore getStore() {
727
                        return store;
728
                }
729

    
730
                public Feature getFeature() {
731
                        return feature;
732
                }
733
                
734
                public void cancelProcess() {
735
                        processCanceled = true;
736
                }
737
                
738
                public boolean isProcessCanceled() {
739
                        return processCanceled;
740
                }
741
                
742
        }
743
}