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 @ 484

History | View | Annotate | Download (36 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
    }
438

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

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

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

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

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

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

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

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

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

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

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

    
538
        case CANCEL:
539
            return;
540
        }
541

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

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

    
550
    }
551

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

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

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

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

    
573
            }
574

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

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

    
590
            doAction(layer, option);
591

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

    
595
        }
596

    
597
    }
598

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

    
602
    }
603

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

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

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

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

    
639
        getNextParameter();
640
    }
641

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

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

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

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

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

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

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

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

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

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

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

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

    
710
    protected void getNextParameter() {
711

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

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

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

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

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

    
738
        if (editingBehavior != null) {
739

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
855
    }
856

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

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

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

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

    
881
    private void setCurrentLayer(FLyrVect layer) {
882

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

    
888
    }
889

    
890
    public void setMapControl(MapControl mapControl) {
891

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

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

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

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

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

    
939
                    refreshMenusAndToolBars();
940

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

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

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

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

    
968
                    try {
969

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

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

    
982
                    try {
983

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

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

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

    
997
                    try {
998

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

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

    
1014
                        try {
1015

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

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

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

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