Statistics
| Revision:

gvsig-vectorediting / org.gvsig.vectorediting / trunk / org.gvsig.vectorediting / org.gvsig.vectorediting.swing / org.gvsig.vectorediting.swing.impl / src / main / java / org / gvsig / vectorediting / swing / impl / DefaultEditingContext.java @ 486

History | View | Annotate | Download (36.1 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright ? 2007-2014 gvSIG Association
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
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24

    
25
package org.gvsig.vectorediting.swing.impl;
26

    
27
import java.awt.BorderLayout;
28
import java.awt.Component;
29
import java.lang.ref.WeakReference;
30
import java.util.ArrayList;
31
import java.util.Set;
32
import java.util.Stack;
33
import java.util.prefs.PreferenceChangeEvent;
34
import java.util.prefs.PreferenceChangeListener;
35
import java.util.prefs.Preferences;
36

    
37
import javax.swing.JComponent;
38

    
39
import org.slf4j.Logger;
40
import org.slf4j.LoggerFactory;
41

    
42
import org.gvsig.editing.EditingNotification;
43
import org.gvsig.editing.EditingNotificationManager;
44
import org.gvsig.fmap.dal.exception.DataException;
45
import org.gvsig.fmap.dal.feature.FeatureStore;
46
import org.gvsig.fmap.geom.Geometry;
47
import org.gvsig.fmap.geom.GeometryLocator;
48
import org.gvsig.fmap.geom.GeometryManager;
49
import org.gvsig.fmap.geom.primitive.Point;
50
import org.gvsig.fmap.geom.type.GeometryType;
51
import org.gvsig.fmap.mapcontext.MapContext;
52
import org.gvsig.fmap.mapcontext.layers.CancelationException;
53
import org.gvsig.fmap.mapcontext.layers.FLayer;
54
import org.gvsig.fmap.mapcontext.layers.FLayers;
55
import org.gvsig.fmap.mapcontext.layers.LayerCollectionEvent;
56
import org.gvsig.fmap.mapcontext.layers.LayerCollectionListener;
57
import org.gvsig.fmap.mapcontext.layers.LayerEvent;
58
import org.gvsig.fmap.mapcontext.layers.LayerListener;
59
import org.gvsig.fmap.mapcontext.layers.LayerPositionEvent;
60
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
61
import org.gvsig.fmap.mapcontrol.MapControl;
62
import org.gvsig.fmap.mapcontrol.MapControlLocator;
63
import org.gvsig.fmap.mapcontrol.tools.CompoundBehavior;
64
import org.gvsig.fmap.mapcontrol.tools.Behavior.Behavior;
65
import org.gvsig.tools.ToolsLocator;
66
import org.gvsig.tools.i18n.I18nManager;
67
import org.gvsig.tools.observer.BaseNotification;
68
import org.gvsig.tools.observer.Notification;
69
import org.gvsig.tools.observer.ObservableHelper;
70
import org.gvsig.tools.observer.Observer;
71
import org.gvsig.utils.console.JDockPanel;
72
import org.gvsig.utils.console.ResponseListener;
73
import org.gvsig.vectorediting.lib.api.EditingLocator;
74
import org.gvsig.vectorediting.lib.api.EditingManager;
75
import org.gvsig.vectorediting.lib.api.EditingService;
76
import org.gvsig.vectorediting.lib.api.EditingServiceInfo;
77
import org.gvsig.vectorediting.lib.api.EditingServiceParameter;
78
import org.gvsig.vectorediting.lib.api.EditingServiceParameter.TYPE;
79
import org.gvsig.vectorediting.lib.api.exceptions.CreateEditingBehaviorException;
80
import org.gvsig.vectorediting.lib.api.exceptions.EndEditingException;
81
import org.gvsig.vectorediting.lib.api.exceptions.InvalidEntryException;
82
import org.gvsig.vectorediting.lib.api.exceptions.ParsePointException;
83
import org.gvsig.vectorediting.lib.api.exceptions.ParseValueException;
84
import org.gvsig.vectorediting.lib.api.exceptions.ServiceInformationException;
85
import org.gvsig.vectorediting.lib.api.exceptions.StartEditingException;
86
import org.gvsig.vectorediting.lib.api.exceptions.StartServiceException;
87
import org.gvsig.vectorediting.lib.api.exceptions.StopServiceException;
88
import org.gvsig.vectorediting.lib.api.exceptions.VectorEditingException;
89
import org.gvsig.vectorediting.swing.api.EditingContext;
90
import org.gvsig.vectorediting.swing.api.EditingSwingLocator;
91
import org.gvsig.vectorediting.swing.api.EditingSwingManager;
92
import org.gvsig.vectorediting.swing.api.console.EditingConsole;
93
import org.gvsig.vectorediting.swing.impl.console.DefaultEditingConsole;
94

    
95
public class DefaultEditingContext implements EditingContext {
96

    
97
    private static final Logger logger = LoggerFactory
98
        .getLogger(EditingManager.class);
99

    
100
    private WeakReference<MapControl> mapControlReference;
101

    
102
    private WeakReference<MapContext> mapContextReference;
103

    
104
    private EditingCompoundBehavior editingCompoundBehavior;
105

    
106
    private Behavior[] lastAdditionalBehaviors;
107

    
108
    private ObservableHelper observableHelper;
109

    
110
    private EditingConsole console;
111

    
112
    private JDockPanel dockConsole = null;
113

    
114
    private boolean isShowConsole = false;
115

    
116
    private Stack<EditingService> serviceStack;
117

    
118
    private FLyrVect currentLayer;
119

    
120
    private EditingServiceParameter currentParam;
121

    
122
    private boolean isEditingInitialized;
123

    
124
    private Behavior[] defaultBehaviors;
125

    
126
    private LayerListener layerListener = new LayerListener() {
127

    
128
        public void activationChanged(LayerEvent e) {
129
            FLayer layer = e.getSource();
130

    
131
            FLayer[] activeLayers =
132
                layer.getMapContext().getLayers().getActives();
133

    
134
            if ((activeLayers.length == 1) && (layer instanceof FLyrVect)) {
135
                if (layer.isActive() && layer.isEditing()) {
136
                    getMapControl().setTool("VectorEditing");
137
                    setCurrentLayer((FLyrVect) layer);
138
                    showConsole();
139
                    return;
140
                }
141
            }
142

    
143
            hideConsole();
144
            if ((getMapControl().getCurrentTool() != null)
145
                && getMapControl().getCurrentTool().equals("VectorEditing")) {
146
                getMapControl().setPrevTool();
147
            }
148
        }
149

    
150
        public void drawValueChanged(LayerEvent e) {
151
        }
152

    
153
        public void editionChanged(LayerEvent e) {
154
            FLayer layer = e.getSource();
155

    
156
            if (layer instanceof FLyrVect) {
157
                if (layer.isEditing()) {
158
                    synchronized (DefaultEditingContext.this) {
159
                        if (!isEditingInitialized) {
160
                            beginEdition((FLyrVect) layer,
161
                                DefaultEditingContext.this
162
                                    .getDefaultBehaviors());
163
                        }
164
                        showConsole();
165
                    }
166
                } else {
167
                    hideConsole();
168
                }
169
            }
170

    
171
        }
172

    
173
        public void nameChanged(LayerEvent e) {
174
        }
175

    
176
        public void visibilityChanged(LayerEvent e) {
177
        }
178
    };
179

    
180
    private PreferenceChangeListener preferenceChangeListener =
181
        new PreferenceChangeListener() {
182

    
183
            public void preferenceChange(PreferenceChangeEvent evt) {
184
                String key = evt.getKey();
185
                if (key.equalsIgnoreCase("apply-snappers")) {
186
                    boolean newValue = Boolean.parseBoolean(evt.getNewValue());
187
                    getMapControl().setRefentEnabled(newValue);
188
                }
189
            }
190
        };
191

    
192
    public DefaultEditingContext(MapControl mapControl) {
193

    
194
        this.isEditingInitialized = false;
195
        this.mapControlReference = new WeakReference<MapControl>(mapControl);
196
        this.mapContextReference =
197
            new WeakReference<MapContext>(mapControl.getMapContext());
198
        this.observableHelper = new ObservableHelper();
199

    
200
        this.serviceStack = new Stack<EditingService>();
201

    
202
        addLayerListeners();
203
        addPreferenceListener();
204
    }
205

    
206
    private void addPreferenceListener() {
207
        Preferences prefs = Preferences.userRoot().node("snappers");
208
        prefs.addPreferenceChangeListener(preferenceChangeListener);
209
    }
210

    
211
    public void activateService(String name) {
212

    
213
        if ((getMapControl() != null)
214
            && getMapControl().hasTool("VectorEditing")) {
215

    
216
            CompoundBehavior editingCompoundBehavior =
217
                getEditingCompoundBehavior();
218
            getMapControl().setTool("VectorEditing");
219
            editingCompoundBehavior.setDrawnBehavior(
220
                EditingCompoundBehavior.EDITING_INDEX, true);
221

    
222
            EditingManager manager = EditingLocator.getManager();
223

    
224
            if (currentLayer != null) {
225

    
226
                EditingService service =
227
                    manager.getEditingService(name,
228
                        currentLayer.getFeatureStore(),
229
                        mapContextReference.get());
230

    
231
                if (service != null) {
232

    
233
                    this.enableSelection(false);
234

    
235
                    try {
236
                        service.start();
237
                    } catch (StartServiceException e) {
238

    
239
                        logger.info(String.format(
240
                            "Can't start the service %1$s", service.getName()),
241
                            e);
242
                        cleanEditingContext();
243
                        return;
244

    
245
                    } catch (InvalidEntryException e) {
246

    
247
                        I18nManager i18nManager = ToolsLocator.getI18nManager();
248
                        showConsoleMessage("\n"
249
                            + i18nManager.getTranslation("invalid_option"));
250
                    }
251

    
252
                    if (!serviceStack.isEmpty()
253
                        && !getActiveService().next().getTypes()
254
                            .contains(TYPE.GEOMETRY)) {
255
                        serviceStack.pop();
256
                    }
257

    
258
                    setActiveService(service);
259

    
260
                    getNextParameter();
261
                }
262
            }
263
        }
264
    }
265

    
266
    private void addBehaviors(Behavior[] additionalBehavior)
267
        throws CreateEditingBehaviorException {
268

    
269
        DefaultEditingBehavior editingBehavior;
270
        EditingCompoundBehavior editingCompoundBehavior;
271

    
272
        if (!getMapControl().hasTool("VectorEditing")) {
273

    
274
            editingBehavior = new DefaultEditingBehavior(this);
275
            editingCompoundBehavior =
276
                new EditingCompoundBehavior(editingBehavior);
277
            setCompoundBehavior(editingCompoundBehavior);
278

    
279
            if (additionalBehavior != null) {
280

    
281
                Behavior[] behaviors =
282
                    new Behavior[additionalBehavior.length + 1];
283
                behaviors[0] = editingCompoundBehavior;
284

    
285
                for (int i = 0; i < additionalBehavior.length; i++) {
286
                    behaviors[i + 1] = additionalBehavior[i];
287
                }
288

    
289
                getMapControl().addBehavior("VectorEditing", behaviors);
290

    
291
                lastAdditionalBehaviors = additionalBehavior;
292

    
293
            } else {
294
                getMapControl().addBehavior("VectorEditing",
295
                    editingCompoundBehavior);
296
            }
297

    
298
        } else {
299
            editingCompoundBehavior = getEditingCompoundBehavior();
300
            editingBehavior =
301
                (DefaultEditingBehavior) editingCompoundBehavior
302
                    .getBehavior(EditingCompoundBehavior.EDITING_INDEX);
303
            setCompoundBehavior(editingCompoundBehavior);
304
            cleanEditingContext();
305
        }
306

    
307
    }
308

    
309
    private void addLayerListeners() {
310

    
311
        FLayers layers = mapContextReference.get().getLayers();
312

    
313
        layers.addLayerListener(layerListener);
314

    
315
        layers.addLayerCollectionListener(new LayerCollectionListener() {
316

    
317
            public void layerAdded(LayerCollectionEvent e) {
318
                FLayers layers2 = e.getLayers();
319
                for (int i = 0; i < layers2.getLayersCount(); i++) {
320
                    FLayer layer = layers2.getLayer(i);
321
                    if (layer instanceof FLyrVect) {
322
                        ((FLyrVect) layer).addLayerListener(layerListener);
323
                    }
324
                }
325
            }
326

    
327
            public void layerAdding(LayerCollectionEvent e)
328
                throws CancelationException {
329
            }
330

    
331
            public void layerMoved(LayerPositionEvent e) {
332
            }
333

    
334
            public void layerMoving(LayerPositionEvent e)
335
                throws CancelationException {
336
            }
337

    
338
            public void layerRemoved(LayerCollectionEvent e) {
339
                FLayers layers2 = e.getLayers();
340
                for (int i = 0; i < layers2.getLayersCount(); i++) {
341
                    FLayer layer = layers2.getLayer(i);
342
                    if (layer instanceof FLyrVect) {
343
                        ((FLyrVect) layer).removeLayerListener(layerListener);
344
                    }
345
                }
346
            }
347

    
348
            public void layerRemoving(LayerCollectionEvent e)
349
                throws CancelationException {
350
            }
351

    
352
            public void visibilityChanged(LayerCollectionEvent e)
353
                throws CancelationException {
354
            }
355
        });
356
    }
357

    
358
    public void addObserver(Observer o) {
359
        this.observableHelper.addObserver(o);
360
    }
361

    
362
    private void askQuestion(EditingServiceParameter param) {
363
        I18nManager i18nManager = ToolsLocator.getI18nManager();
364
        String translation = i18nManager.getTranslation(param.getDescription());
365
        String activeServiceName =
366
            i18nManager.getTranslation(getActiveService().getName());
367

    
368
        Object defaultValue = param.getDefaultValue();
369
        String strDefaultValue;
370

    
371
        if (defaultValue != null) {
372
            if (defaultValue instanceof String) {
373
                strDefaultValue = (String) defaultValue;
374
                strDefaultValue =
375
                    i18nManager.getTranslation((String) defaultValue);
376
            } else {
377
                strDefaultValue = defaultValue.toString();
378
            }
379
            showConsoleMessage("\n" + activeServiceName + "# " + translation
380
                + "<" + strDefaultValue + "> : ");
381
        } else {
382
            showConsoleMessage("\n" + activeServiceName + "# " + translation
383
                + " : ");
384
        }
385
    }
386

    
387
    public synchronized void beginEdition(FLyrVect layer,
388
        Behavior[] additionalBehaviors) {
389

    
390
        EditingNotificationManager editingNotificationManager =
391
            MapControlLocator.getEditingNotificationManager();
392

    
393
        EditingNotification notification =
394
            editingNotificationManager.notifyObservers(this,
395
                EditingNotification.BEFORE_ENTER_EDITING_STORE, null, layer);
396

    
397
        if (notification.isCanceled()) {
398
            String msg =
399
                String.format("Edit layer %1$s canceled by somme observer.",
400
                    layer.getName());
401
            logger.info(msg, new StartEditingException(msg, null));
402
            return;
403
        }
404

    
405
        try {
406
            addBehaviors(additionalBehaviors);
407
        } catch (CreateEditingBehaviorException e1) {
408
            logger.info("Problems adding behaviors to editing context", e1);
409
            getMapControl().setTool("pan");
410
            return;
411
        }
412

    
413
        setCurrentLayer(layer);
414

    
415
        FeatureStore featureStore = layer.getFeatureStore();
416
        if (!featureStore.isEditing()) {
417
            try {
418
                featureStore.edit();
419
            } catch (Exception e) {
420
                String msg =
421
                    String.format("Can't set %1$s in edit mode",
422
                        featureStore.getName());
423
                logger.info(msg, new VectorEditingException(e));
424
                cleanEditingContext();
425
                return;
426
            }
427
        }
428

    
429
        featureStore.addObserver(getMapControl());
430

    
431
        editingNotificationManager.notifyObservers(this,
432
            EditingNotification.AFTER_ENTER_EDITING_STORE, null, layer);
433

    
434
        getMapControl().setTool("VectorEditing");
435
        enableSnapping();
436
        isEditingInitialized = true;
437
//        changeSelectedTool(DEFAULT_TOOL);
438
    }
439

    
440
    @SuppressWarnings({ "rawtypes", "unchecked" })
441
    private void enableSnapping() {
442
        Preferences prefs = Preferences.userRoot().node("snappers");
443
        if ((prefs.getBoolean("apply-snappers", false) && currentLayer != null)) {
444
            ArrayList layersToSnap =
445
                getMapControl().getMapContext().getLayersToSnap();
446
            if (!layersToSnap.contains(currentLayer)) {
447
                layersToSnap.add(currentLayer);
448
            }
449
        }
450
    }
451

    
452
    @SuppressWarnings("rawtypes")
453
    private void disableSnapping() {
454
        ArrayList layersToSnap =
455
            getMapControl().getMapContext().getLayersToSnap();
456
        if (layersToSnap.contains(currentLayer)) {
457
            layersToSnap.remove(currentLayer);
458
        }
459
    }
460

    
461
    private void changeSelectedTool(String name) {
462
        if (name.equalsIgnoreCase(DEFAULT_TOOL)) {
463
            name = "selection-simple-select-view";
464
            this.getMapControl().setTool("pointSelection");
465
        }
466
        Notification notification =
467
            new BaseNotification(
468
                EditingContext.CHANGE_SELECTED_TOOL_NOTIFICATION,
469
                new Object[] { name });
470
        this.observableHelper.notifyObservers(this, notification);
471
    }
472

    
473
    private void cleanEditingContext() {
474
        serviceStack.clear();
475
        currentParam = null;
476
        this.enableSelection(false);
477
        refreshMenusAndToolBars();
478

    
479
        I18nManager i18nManager = ToolsLocator.getI18nManager();
480
        showConsoleMessage("\n" + i18nManager.getTranslation("select_new_tool")
481
            + "\n");
482
    }
483

    
484
    public void deleteObserver(Observer o) {
485
        this.observableHelper.deleteObserver(o);
486
    }
487

    
488
    public void deleteObservers() {
489
        this.observableHelper.deleteObservers();
490
    }
491

    
492
    private void discardChanges(FLyrVect layer) throws EndEditingException {
493
        FeatureStore featureStore = layer.getFeatureStore();
494
        try {
495
            featureStore.cancelEditing();
496
        } catch (Exception e) {
497
            throw new EndEditingException(e);
498
        }
499
    }
500

    
501
    private void doAction(FLyrVect layer, int option) {
502
        switch (option) {
503
        case SAVE_CHANGES:
504
            try {
505
                saveChanges(layer);
506
            } catch (VectorEditingException e) {
507
                String msg =
508
                    String.format("Changes can not be saved in %1$s",
509
                        layer.getName());
510
                logger.info(msg, e);
511
                return;
512
            }
513
            break;
514

    
515
        case DISCARD_CHANGES:
516
            try {
517
                discardChanges(layer);
518
            } catch (VectorEditingException e) {
519
                String msg =
520
                    String.format("Changes can not be discared in %1$s",
521
                        layer.getName());
522
                logger.info(msg, e);
523
                return;
524
            }
525
            break;
526

    
527
        case EXPORT_LAYER:
528
            try {
529
                exportLayer(layer);
530
            } catch (VectorEditingException e) {
531
                String msg =
532
                    String.format("Changes of %1$s can not be exported",
533
                        layer.getName());
534
                logger.info(msg, e);
535
                return;
536
            }
537
            break;
538

    
539
        case CANCEL:
540
            return;
541
        }
542

    
543
        cleanEditingContext();
544
        hideConsole();
545
        disableSnapping();
546
        changeSelectedTool(DEFAULT_TOOL);
547

    
548
        FeatureStore featureStore = layer.getFeatureStore();
549
        featureStore.deleteObserver(getMapControl());
550

    
551
    }
552

    
553
    private void enableSelection(boolean enableSelection) {
554
        this.editingCompoundBehavior.setDrawnBehavior(
555
            EditingCompoundBehavior.SELECTION_INDEX, enableSelection);
556
    }
557

    
558
    public void endEdition(FLyrVect layer) {
559
        if (layer.isEditing()) {
560
            EditingNotificationManager editingNotificationManager =
561
                MapControlLocator.getEditingNotificationManager();
562

    
563
            EditingNotification notification =
564
                editingNotificationManager.notifyObservers(this,
565
                    EditingNotification.BEFORE_EXIT_EDITING_STORE, null, layer);
566

    
567
            if (notification.isCanceled()) {
568
                String msg =
569
                    String.format(
570
                        "Stop edit layer %1$s canceled by somme observer.",
571
                        layer.getName());
572
                logger.info(msg, new EndEditingException(msg, null));
573

    
574
            }
575

    
576
            getMapControl().getCanceldraw().setCanceled(true);
577
            int option;
578
            EditingSwingManager swingManager =
579
                EditingSwingLocator.getSwingManager();
580

    
581
            if (layer.isWritable()) {
582
                option =
583
                    swingManager.showPanelSaveOrDiscard(getMapControl(),
584
                        layer.getName());
585
            } else {
586
                option =
587
                    swingManager.showPanelExportOrDiscard(getMapControl(),
588
                        layer.getName());
589
            }
590

    
591
            doAction(layer, option);
592

    
593
            editingNotificationManager.notifyObservers(this,
594
                EditingNotification.AFTER_EXIT_EDITING_STORE, null, layer);
595

    
596
        }
597

    
598
    }
599

    
600
    private void exportLayer(FLyrVect layer) throws EndEditingException {
601
        // TODO Auto-generated method stub
602

    
603
    }
604

    
605
    protected void finishService() {
606
        EditingService lastService = serviceStack.pop();
607
        try {
608

    
609
            if (!serviceStack.isEmpty()
610
                && getActiveService().next().getTypes().contains(TYPE.GEOMETRY)) {
611
                Geometry geometry = lastService.finish();
612
                if (geometry != null) {
613
                    getActiveService().setValue(geometry);
614
                }
615
            } else {
616
                lastService.finishAndStore();
617
                getMapControl().rePaintDirtyLayers();
618

    
619
                I18nManager i18nManager = ToolsLocator.getI18nManager();
620
                showConsoleMessage("\n"
621
                    + i18nManager.getTranslation(lastService.getName()) + "# "
622
                    + i18nManager.getTranslation("finished") + "\n");
623
                lastService.stop();
624
                setActiveService(lastService);
625
                lastService.start();
626
                changeSelectedTool(getActiveService().getName());
627
            }
628

    
629
        } catch (InvalidEntryException ex) {
630
            I18nManager i18nManager = ToolsLocator.getI18nManager();
631
            showConsoleMessage("\n"
632
                + i18nManager.getTranslation("invalid_option"));
633
            changeSelectedTool(getActiveService().getName());
634
        } catch (VectorEditingException ex) {
635
            logger.info("Can't finish " + lastService.getName(), ex);
636
            cleanEditingContext();
637
            return;
638
        }
639

    
640
        getNextParameter();
641
    }
642

    
643
    protected EditingService getActiveService() {
644
        if (!serviceStack.isEmpty()) {
645
            return serviceStack.peek();
646
        }
647
        return null;
648
    }
649

    
650
    private EditingConsole getConsolePanel() {
651
        if (console == null) {
652
            console = new DefaultEditingConsole(new ResponseListener() {
653

    
654
                public void acceptResponse(String response) {
655
                    textEntered(response);
656
                }
657
            });
658
        }
659
        return console;
660
    }
661

    
662
    protected FLyrVect getCurrentLayer() {
663
        return this.currentLayer;
664
    }
665

    
666
    protected EditingServiceParameter getCurrentParam() {
667
        return this.currentParam;
668
    }
669

    
670
    private Component getDockConsole() {
671
        if (dockConsole == null) {
672
            dockConsole = new JDockPanel((JComponent) getConsolePanel());
673
        }
674
        return dockConsole;
675
    }
676

    
677
    private DefaultEditingBehavior getEditingBehavior() {
678
        if (editingCompoundBehavior != null) {
679
            return (DefaultEditingBehavior) editingCompoundBehavior
680
                .getBehavior(EditingCompoundBehavior.EDITING_INDEX);
681
        }
682
        return null;
683
    }
684

    
685
    private EditingCompoundBehavior getEditingCompoundBehavior() {
686
        if (editingCompoundBehavior != null) {
687
            return editingCompoundBehavior;
688
        } else {
689
            EditingCompoundBehavior editingCompoundBehavior;
690

    
691
            CompoundBehavior compoundBehavior =
692
                (CompoundBehavior) getMapControl().getMapTool("VectorEditing");
693

    
694
            if (compoundBehavior instanceof EditingCompoundBehavior) {
695
                editingCompoundBehavior =
696
                    (EditingCompoundBehavior) compoundBehavior;
697
            } else {
698
                editingCompoundBehavior =
699
                    (EditingCompoundBehavior) compoundBehavior.getBehavior(0);
700
            }
701

    
702
            setCompoundBehavior(editingCompoundBehavior);
703
            return editingCompoundBehavior;
704
        }
705
    }
706

    
707
    public MapControl getMapControl() {
708
        return mapControlReference.get();
709
    }
710

    
711
    protected void getNextParameter() {
712

    
713
        currentParam = getActiveService().next();
714

    
715
        if (currentParam == null) {
716
            finishService();
717
        } else {
718
            askQuestion(currentParam);
719
            if (currentParam.getTypes().contains(TYPE.SELECTION)) {
720
                enableSelection(true);
721
            } else if (currentParam.getTypes().contains(TYPE.GEOMETRY)) {
722
                refreshMenusAndToolBars();
723
            }
724
        }
725
    }
726

    
727
    protected Stack<EditingService> getServiceStack() {
728
        return this.serviceStack;
729
    }
730

    
731
    private void hideConsole() {
732
        isShowConsole = false;
733
        getDockConsole().setVisible(false);
734
    }
735

    
736
    public boolean isServiceCompatible(String name) {
737
        DefaultEditingBehavior editingBehavior = getEditingBehavior();
738

    
739
        if (editingBehavior != null) {
740

    
741
            try {
742
                EditingManager manager = EditingLocator.getManager();
743
                EditingServiceInfo serviceInfo = manager.getServiceInfo(name);
744
                GeometryType geoType = null;
745

    
746
                for (EditingService editingService : getServiceStack()) {
747
                    EditingServiceParameter parameter = editingService.next();
748
                    if (parameter != null
749
                        && parameter.getTypes().contains(TYPE.GEOMETRY)) {
750

    
751
                        int geometryType = parameter.getGeometryType();
752
                        int subType = -1;
753

    
754
                        try {
755
                            subType =
756
                                getCurrentLayer().getFeatureStore()
757
                                    .getDefaultFeatureType()
758
                                    .getDefaultGeometryAttribute()
759
                                    .getGeomType().getSubType();
760

    
761
                            geoType =
762
                                GeometryLocator.getGeometryManager()
763
                                    .getGeometryType(geometryType, subType);
764
                        } catch (Exception e) {
765

    
766
                            String msg =
767
                                String.format(
768
                                    "Problems getting default feature"
769
                                        + " type of %1$s or getting geometry"
770
                                        + " type of %2$s %3$s",
771
                                    getCurrentLayer().getName(), geometryType,
772
                                    subType);
773

    
774
                            throw new ServiceInformationException(msg, e);
775
                        }
776

    
777
                        return serviceInfo.isCompatibleWith(geoType)
778
                            && serviceInfo.createsNewGeometries();
779
                    }
780
                }
781

    
782
                if (getCurrentLayer() != null) {
783
                    try {
784
                        geoType =
785
                            getCurrentLayer().getFeatureStore()
786
                                .getDefaultFeatureType()
787
                                .getDefaultGeometryAttribute().getGeomType();
788
                    } catch (DataException e) {
789
                        String msg =
790
                            String.format("Problems getting default "
791
                                + "feature type of %1$s", getCurrentLayer()
792
                                .getName());
793
                        throw new ServiceInformationException(msg, e);
794
                    }
795

    
796
                    return serviceInfo.isCompatibleWith(geoType);
797
                }
798

    
799
                return false;
800
            } catch (ServiceInformationException e) {
801
                logger.warn(
802
                    "Problems getting if editing context is compatible with "
803
                        + name, e);
804
            }
805
        }
806
        return false;
807
    }
808

    
809
    private Point parsePoint(String response) throws ParsePointException {
810
        String[] numbers = new String[1];
811
        numbers[0] = response;
812
        numbers = response.split(",");
813
        if (numbers.length == 2) {
814

    
815
            if (numbers[0].startsWith("(") && numbers[1].endsWith(")\n")) { // CCS
816
                numbers[0] = numbers[0].replace("(", "");
817
                numbers[1] = numbers[1].replace(")\n", "");
818
            }
819

    
820
            double[] values;
821
            try {
822
                values =
823
                    new double[] { Double.parseDouble(numbers[0]),
824
                        Double.parseDouble(numbers[1]) };
825
            } catch (Exception e) {
826
                throw new ParsePointException(e);
827
            }
828

    
829
            Point point;
830
            try {
831
                GeometryManager geomManager =
832
                    GeometryLocator.getGeometryManager();
833
                int subType =
834
                    getCurrentLayer().getFeatureStore().getDefaultFeatureType()
835
                        .getDefaultGeometryAttribute().getGeomType()
836
                        .getSubType();
837
                point = geomManager.createPoint(values[0], values[1], subType);
838

    
839
            } catch (Exception e) {
840
                throw new ParsePointException(e);
841
            }
842

    
843
            return point;
844
        } else {
845
            throw new ParsePointException(null);
846
        }
847
    }
848

    
849
    private Double parseValue(String response) throws ParseValueException {
850
        try {
851
            return Double.valueOf(response);
852
        } catch (Exception e) {
853
            throw new ParseValueException(e);
854
        }
855

    
856
    }
857

    
858
    protected void refreshMenusAndToolBars() {
859
        Notification notification =
860
            new BaseNotification(EditingContext.REFRESH_TOOLS_NOTIFICATION,
861
                null);
862
        this.observableHelper.notifyObservers(this, notification);
863
    }
864

    
865
    private void saveChanges(FLyrVect layer) throws EndEditingException {
866
        FeatureStore featureStore = layer.getFeatureStore();
867
        try {
868
            featureStore.finishEditing();
869
        } catch (Exception e) {
870
            throw new EndEditingException(e);
871
        }
872
    }
873

    
874
    private void setActiveService(EditingService service) {
875
        serviceStack.add(service);
876
    }
877

    
878
    private void setCompoundBehavior(EditingCompoundBehavior compoundBehavior) {
879
        this.editingCompoundBehavior = compoundBehavior;
880
    }
881

    
882
    private void setCurrentLayer(FLyrVect layer) {
883

    
884
        if (this.currentLayer != layer) {
885
            this.currentLayer = layer;
886
            cleanEditingContext();
887
        }
888

    
889
    }
890

    
891
    public void setMapControl(MapControl mapControl) {
892

    
893
        this.mapControlReference = new WeakReference<MapControl>(mapControl);
894
        this.mapContextReference =
895
            new WeakReference<MapContext>(mapControl.getMapContext());
896

    
897
        // When mapControl is updated we have to add older additional behaviors
898
        // to new mapControl
899
        if (lastAdditionalBehaviors != null) {
900
            try {
901
                addBehaviors(lastAdditionalBehaviors);
902
            } catch (CreateEditingBehaviorException e1) {
903
                logger.info("Problems adding behaviors to editing context", e1);
904
                getMapControl().setTool("pan");
905
                return;
906
            }
907
        }
908
    }
909

    
910
    private void showConsole() {
911
        if (isShowConsole) {
912
            return;
913
        }
914
        isShowConsole = true;
915
        getMapControl().remove(getDockConsole());
916
        getMapControl().setLayout(new BorderLayout());
917
        getMapControl().add(getDockConsole(), BorderLayout.SOUTH);
918
        getDockConsole().setVisible(true);
919
    }
920

    
921
    protected void showConsoleMessage(String text) {
922
        getConsolePanel().addText(text);
923
    }
924

    
925
    protected void textEntered(String response) {
926
        FeatureStore featureStore = getCurrentLayer().getFeatureStore();
927
        if (response == null) {
928
            if (getActiveService() != null) {
929
                try {
930
                    getActiveService().stop();
931
                    serviceStack.pop();
932
                    if (serviceStack.isEmpty()) {
933
                        featureStore
934
                            .getFeatureSelection().deselectAll();
935
                        changeSelectedTool(DEFAULT_TOOL);
936
                    } else {
937
                        changeSelectedTool(getActiveService().getName());
938
                    }
939

    
940
                    refreshMenusAndToolBars();
941

    
942
                    if (getActiveService() != null) {
943
                        getNextParameter();
944
                    } else {
945
                        cleanEditingContext();
946
                    }
947

    
948
                } catch (StopServiceException e) {
949
                    logger
950
                        .info("Can't stop " + getActiveService().getName(), e);
951
                    return;
952
                } catch (DataException e) {
953
                    logger.info("Can't get selection of "
954
                        + featureStore.getFullName(), e);
955
                    return;
956
                }
957
            }
958
        } else {
959

    
960
            if (getCurrentParam() != null) {
961
                Set<TYPE> types = getCurrentParam().getTypes();
962
                Point point = null;
963
                Double value = null;
964

    
965
                boolean insertedValue = false;
966
                if ((!insertedValue && types.contains(TYPE.POSITION))
967
                    || types.contains(TYPE.LIST_POSITIONS)) {
968

    
969
                    try {
970

    
971
                        point = parsePoint(response);
972
                        if (point != null) {
973
                            getActiveService().setValue(point);
974
                            insertedValue = true;
975
                        }
976

    
977
                    } catch (VectorEditingException e) {
978
                        // Do nothing to try other types
979
                    }
980
                }
981
                if (!insertedValue && types.contains(TYPE.VALUE)) {
982

    
983
                    try {
984

    
985
                        value = parseValue(response);
986
                        if (value != null) {
987
                            getActiveService().setValue(value);
988
                            insertedValue = true;
989
                        }
990

    
991
                    } catch (VectorEditingException e) {
992
                        // Do nothing to try other types
993
                    }
994

    
995
                }
996
                if (!insertedValue && types.contains(TYPE.OPTION)) {
997

    
998
                    try {
999

    
1000
                        response = response.replace("\n", "");
1001
                        if (response != null) {
1002
                            getActiveService().setValue(response);
1003
                            insertedValue = true;
1004
                        }
1005

    
1006
                    } catch (VectorEditingException e) {
1007
                        // Do nothing to try other types
1008
                    }
1009
                }
1010
                if (!insertedValue && types.contains(TYPE.SELECTION)) {
1011
                    if (response.equalsIgnoreCase("\n")) {
1012
                        enableSelection(false);
1013
                        insertedValue = true;
1014

    
1015
                        try {
1016

    
1017
                            getActiveService().setValue(
1018
                                featureStore
1019
                                    .getFeatureSelection().clone());
1020

    
1021
                        } catch (InvalidEntryException e) {
1022
                            I18nManager i18nManager =
1023
                                ToolsLocator.getI18nManager();
1024
                            showConsoleMessage("\n"
1025
                                + i18nManager.getTranslation("invalid_option"));
1026
                        } catch (Exception e) {
1027
                            logger.info("Can't access to selection.", e);
1028
                            cleanEditingContext();
1029
                            return;
1030
                        }
1031
                    }
1032
                }
1033
                if (!insertedValue) {
1034
                    I18nManager i18nManager = ToolsLocator.getI18nManager();
1035
                    showConsoleMessage("\n"
1036
                        + i18nManager.getTranslation("invalid_option"));
1037
                }
1038
                getNextParameter();
1039
            }
1040
        }
1041
    }
1042

    
1043
    public void setDefaultBehaviors(Behavior[] defaultBehaviors) {
1044
        this.defaultBehaviors = defaultBehaviors;
1045
    }
1046

    
1047
    public Behavior[] getDefaultBehaviors() {
1048
        return this.defaultBehaviors;
1049
    }
1050
}