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

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

    
94
public class DefaultEditingContext implements EditingContext {
95

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

    
99
    private WeakReference<MapControl> mapControlReference;
100

    
101
    private WeakReference<MapContext> mapContextReference;
102

    
103
    private EditingCompoundBehavior editingCompoundBehavior;
104

    
105
    private Behavior[] lastAdditionalBehaviors;
106

    
107
    private ObservableHelper observableHelper;
108

    
109
    private EditingConsole console;
110

    
111
    private JDockPanel dockConsole = null;
112

    
113
    private boolean isShowConsole = false;
114

    
115
    private Stack<EditingService> serviceStack;
116

    
117
    private FLyrVect currentLayer;
118

    
119
    private EditingServiceParameter currentParam;
120

    
121
    private Behavior[] defaultBehaviors;
122

    
123
    private LayerListener layerListener = new LayerListener() {
124

    
125
        public void activationChanged(LayerEvent e) {
126
            FLayer layer = e.getSource();
127

    
128
            FLayer[] activeLayers =
129
                layer.getMapContext().getLayers().getActives();
130

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

    
140
            hideConsole();
141
            if ((getMapControl().getCurrentTool() != null)
142
                && getMapControl().getCurrentTool().equals("VectorEditing")) {
143
                getMapControl().setPrevTool();
144
            }
145
        }
146

    
147
        public void drawValueChanged(LayerEvent e) {
148
        }
149

    
150
        public void editionChanged(LayerEvent e) {
151
            FLayer layer = e.getSource();
152

    
153
            if (layer instanceof FLyrVect) {
154
                if (layer.isEditing()) {
155
                    synchronized (DefaultEditingContext.this) {
156
                        beginEdition((FLyrVect) layer);
157
                        showConsole();
158
                    }
159
                } else {
160
                    hideConsole();
161
                }
162
            }
163

    
164
        }
165

    
166
        public void nameChanged(LayerEvent e) {
167
        }
168

    
169
        public void visibilityChanged(LayerEvent e) {
170
        }
171
    };
172

    
173
    private PreferenceChangeListener preferenceChangeListener =
174
        new PreferenceChangeListener() {
175

    
176
            public void preferenceChange(PreferenceChangeEvent evt) {
177
                String key = evt.getKey();
178
                if (key.equalsIgnoreCase("apply-snappers")) {
179
                    boolean newValue = Boolean.parseBoolean(evt.getNewValue());
180
                    getMapControl().setRefentEnabled(newValue);
181
                }
182
            }
183
        };
184

    
185
    public DefaultEditingContext(MapControl mapControl) {
186

    
187
        this.mapControlReference = new WeakReference<MapControl>(mapControl);
188
        this.mapContextReference =
189
            new WeakReference<MapContext>(mapControl.getMapContext());
190
        this.observableHelper = new ObservableHelper();
191

    
192
        this.serviceStack = new Stack<EditingService>();
193

    
194
        addLayerListeners();
195
        addPreferenceListener();
196
    }
197

    
198
    private void addPreferenceListener() {
199
        Preferences prefs = Preferences.userRoot().node("snappers");
200
        prefs.addPreferenceChangeListener(preferenceChangeListener);
201
    }
202

    
203
    public void activateService(String name) {
204

    
205
        if ((getMapControl() != null)
206
            && getMapControl().hasTool("VectorEditing")) {
207

    
208
            CompoundBehavior editingCompoundBehavior =
209
                getEditingCompoundBehavior();
210
            getMapControl().setTool("VectorEditing");
211
            editingCompoundBehavior.setDrawnBehavior(
212
                EditingCompoundBehavior.EDITING_INDEX, true);
213

    
214
            EditingManager manager = EditingLocator.getManager();
215

    
216
            if (currentLayer != null) {
217

    
218
                EditingService service =
219
                    manager.getEditingService(name,
220
                        currentLayer.getFeatureStore(),
221
                        mapContextReference.get());
222

    
223
                if (service != null) {
224

    
225
                    this.enableSelection(false);
226

    
227
                    try {
228
                        service.start();
229
                    } catch (StartServiceException e) {
230

    
231
                        logger.info(String.format(
232
                            "Can't start the service %1$s", service.getName()),
233
                            e);
234
                        cleanEditingContext();
235
                        return;
236

    
237
                    } catch (InvalidEntryException e) {
238

    
239
                        I18nManager i18nManager = ToolsLocator.getI18nManager();
240
                        showConsoleMessage("\n"
241
                            + i18nManager.getTranslation("invalid_option"));
242
                    }
243

    
244
                    if (!serviceStack.isEmpty()
245
                        && !getActiveService().next().getTypes()
246
                            .contains(TYPE.GEOMETRY)) {
247
                        serviceStack.pop();
248
                    }
249

    
250
                    setActiveService(service);
251

    
252
                    getNextParameter();
253
                }
254
            }
255
        }
256
    }
257

    
258
    private void addBehaviors(Behavior[] additionalBehavior)
259
        throws CreateEditingBehaviorException {
260

    
261
        DefaultEditingBehavior editingBehavior;
262
        EditingCompoundBehavior editingCompoundBehavior;
263

    
264
        if (!getMapControl().hasTool("VectorEditing")) {
265

    
266
            editingBehavior = new DefaultEditingBehavior(this);
267
            editingCompoundBehavior =
268
                new EditingCompoundBehavior(editingBehavior);
269
            setCompoundBehavior(editingCompoundBehavior);
270

    
271
            if (additionalBehavior != null) {
272

    
273
                Behavior[] behaviors =
274
                    new Behavior[additionalBehavior.length + 1];
275
                behaviors[0] = editingCompoundBehavior;
276

    
277
                for (int i = 0; i < additionalBehavior.length; i++) {
278
                    behaviors[i + 1] = additionalBehavior[i];
279
                }
280

    
281
                getMapControl().addBehavior("VectorEditing", behaviors);
282

    
283
                lastAdditionalBehaviors = additionalBehavior;
284

    
285
            } else {
286
                getMapControl().addBehavior("VectorEditing",
287
                    editingCompoundBehavior);
288
            }
289

    
290
        } else {
291
            editingCompoundBehavior = getEditingCompoundBehavior();
292
            editingBehavior =
293
                (DefaultEditingBehavior) editingCompoundBehavior
294
                    .getBehavior(EditingCompoundBehavior.EDITING_INDEX);
295
            setCompoundBehavior(editingCompoundBehavior);
296
            cleanEditingContext();
297
        }
298

    
299
    }
300

    
301
    private void addLayerListeners() {
302

    
303
        FLayers layers = mapContextReference.get().getLayers();
304

    
305
        layers.addLayerListener(layerListener);
306

    
307
        layers.addLayerCollectionListener(new LayerCollectionListener() {
308

    
309
            public void addLayer(FLayer layer) {
310
                if (layer instanceof FLayers) {
311
                    FLayers layers = (FLayers) layer;
312
                    for (int i = 0; i < layers.getLayersCount(); i++) {
313
                        addLayer(layers.getLayer(i));
314
                    }
315
                } else if (layer instanceof FLyrVect) {
316
                    ((FLyrVect) layer).addLayerListener(layerListener);
317
                }
318
            }
319
            
320
            public void layerAdded(LayerCollectionEvent e) {
321
                addLayer(e.getLayers());
322
            }
323

    
324
            public void layerAdding(LayerCollectionEvent e)
325
                throws CancelationException {
326
            }
327

    
328
            public void layerMoved(LayerPositionEvent e) {
329
            }
330

    
331
            public void layerMoving(LayerPositionEvent e)
332
                throws CancelationException {
333
            }
334
            
335
            public void removeLayer(FLayer layer) {
336
                if (layer instanceof FLayers) {
337
                    FLayers layers = (FLayers) layer;
338
                    for (int i = 0; i < layers.getLayersCount(); i++) {
339
                        addLayer(layers.getLayer(i));
340
                    }
341
                } else if (layer instanceof FLyrVect) {
342
                    ((FLyrVect) layer).removeLayerListener(layerListener);
343
                }
344
            }
345

    
346
            public void layerRemoved(LayerCollectionEvent e) {
347
                removeLayer(e.getLayers());
348
            }
349

    
350
            public void layerRemoving(LayerCollectionEvent e)
351
                throws CancelationException {
352
            }
353

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

    
360
    public void addObserver(Observer o) {
361
        this.observableHelper.addObserver(o);
362
    }
363

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

    
370
        Object defaultValue = param.getDefaultValue();
371
        String strDefaultValue;
372

    
373
        if (defaultValue != null) {
374
            if (defaultValue instanceof String) {
375
                strDefaultValue = (String) defaultValue;
376
                strDefaultValue =
377
                    i18nManager.getTranslation((String) defaultValue);
378
            } else {
379
                strDefaultValue = defaultValue.toString();
380
            }
381
            showConsoleMessage("\n" + activeServiceName + "# " + translation
382
                + "<" + strDefaultValue + "> : ");
383
        } else {
384
            showConsoleMessage("\n" + activeServiceName + "# " + translation
385
                + " : ");
386
        }
387
    }
388
    
389
    public synchronized void beginEdition(FLyrVect layer,
390
        Behavior[] additionalBehaviors) {
391
        
392
        try{
393
            throw new Exception("Deprecated method");
394
        } catch (Exception e){
395
            logger.info("Deprecated method", e);
396
        }
397
        
398
        beginEdition(layer);
399
        try {
400
            addBehaviors(additionalBehaviors);
401
        } catch (CreateEditingBehaviorException e1) {
402
            logger.info("Problems adding behaviors to editing context", e1);
403
            getMapControl().setTool("pan");
404
            return;
405
        }
406
    }
407
    
408
    public synchronized void beginEdition(FLyrVect layer) {        
409
     
410
        EditingNotificationManager editingNotificationManager =
411
            MapControlLocator.getEditingNotificationManager();
412

    
413
        EditingNotification notification =
414
            editingNotificationManager.notifyObservers(this,
415
                EditingNotification.BEFORE_ENTER_EDITING_STORE, null, layer);
416

    
417
        if (notification.isCanceled()) {
418
            String msg =
419
                String.format("Edit layer %1$s canceled by somme observer.",
420
                    layer.getName());
421
            logger.info(msg, new StartEditingException(msg, null));
422
            return;
423
        }
424
        
425
        setCurrentLayer(layer);
426

    
427
        FeatureStore featureStore = layer.getFeatureStore();
428
        if (!featureStore.isEditing()) {
429
            try {
430
                featureStore.edit();
431
            } catch (Exception e) {
432
                String msg =
433
                    String.format("Can't set %1$s in edit mode",
434
                        featureStore.getName());
435
                logger.info(msg, new VectorEditingException(e));
436
                cleanEditingContext();
437
                return;
438
            }
439
        }
440

    
441
        featureStore.addObserver(getMapControl());
442

    
443
        editingNotificationManager.notifyObservers(this,
444
            EditingNotification.AFTER_ENTER_EDITING_STORE, null, layer);
445

    
446
        enableSnapping();
447
    }
448

    
449
    @SuppressWarnings({ "rawtypes", "unchecked" })
450
    private void enableSnapping() {
451
        Preferences prefs = Preferences.userRoot().node("snappers");
452
        if ((prefs.getBoolean("apply-snappers", false) && currentLayer != null)) {
453
            ArrayList layersToSnap =
454
                getMapControl().getMapContext().getLayersToSnap();
455
            if (!layersToSnap.contains(currentLayer)) {
456
                layersToSnap.add(currentLayer);
457
            }
458
        }
459
    }
460

    
461
    @SuppressWarnings("rawtypes")
462
    private void disableSnapping() {
463
        ArrayList layersToSnap =
464
            getMapControl().getMapContext().getLayersToSnap();
465
        if (layersToSnap.contains(currentLayer)) {
466
            layersToSnap.remove(currentLayer);
467
        }
468
    }
469

    
470
    private void changeSelectedTool(String name) {
471
        if (name.equalsIgnoreCase(DEFAULT_TOOL)) {
472
            name = "selection-simple-select-view";
473
            this.getMapControl().setTool("pointSelection");
474
        }
475
        Notification notification =
476
            new BaseNotification(
477
                EditingContext.CHANGE_SELECTED_TOOL_NOTIFICATION,
478
                new Object[] { name });
479
        this.observableHelper.notifyObservers(this, notification);
480
    }
481

    
482
    private void cleanEditingContext() {
483
        serviceStack.clear();
484
        currentParam = null;
485
        this.enableSelection(false);
486
        refreshMenusAndToolBars();
487

    
488
        I18nManager i18nManager = ToolsLocator.getI18nManager();
489
        showConsoleMessage("\n" + i18nManager.getTranslation("select_new_tool")
490
            + "\n");
491
    }
492

    
493
    public void deleteObserver(Observer o) {
494
        this.observableHelper.deleteObserver(o);
495
    }
496

    
497
    public void deleteObservers() {
498
        this.observableHelper.deleteObservers();
499
    }
500

    
501
    private void discardChanges(FLyrVect layer) throws EndEditingException {
502
        FeatureStore featureStore = layer.getFeatureStore();
503
        try {
504
            featureStore.cancelEditing();
505
        } catch (Exception e) {
506
            throw new EndEditingException(e);
507
        }
508
    }
509

    
510
    private void doAction(FLyrVect layer, int option) {
511
        switch (option) {
512
        case SAVE_CHANGES:
513
            try {
514
                saveChanges(layer);
515
            } catch (VectorEditingException e) {
516
                String msg =
517
                    String.format("Changes can not be saved in %1$s",
518
                        layer.getName());
519
                logger.info(msg, e);
520
                return;
521
            }
522
            break;
523

    
524
        case DISCARD_CHANGES:
525
            try {
526
                discardChanges(layer);
527
            } catch (VectorEditingException e) {
528
                String msg =
529
                    String.format("Changes can not be discared in %1$s",
530
                        layer.getName());
531
                logger.info(msg, e);
532
                return;
533
            }
534
            break;
535

    
536
        case EXPORT_LAYER:
537
            try {
538
                exportLayer(layer);
539
            } catch (VectorEditingException e) {
540
                String msg =
541
                    String.format("Changes of %1$s can not be exported",
542
                        layer.getName());
543
                logger.info(msg, e);
544
                return;
545
            }
546
            break;
547

    
548
        case CANCEL:
549
            return;
550
        }
551

    
552
        cleanEditingContext();
553
        hideConsole();
554
        disableSnapping();
555
        changeSelectedTool(DEFAULT_TOOL);
556

    
557
        FeatureStore featureStore = layer.getFeatureStore();
558
        featureStore.deleteObserver(getMapControl());
559

    
560
    }
561

    
562
    private void enableSelection(boolean enableSelection) {
563
        this.editingCompoundBehavior.setDrawnBehavior(
564
            EditingCompoundBehavior.SELECTION_INDEX, enableSelection);
565
    }
566

    
567
    public void endEdition(FLyrVect layer) {
568
        if (layer.isEditing()) {
569
            EditingNotificationManager editingNotificationManager =
570
                MapControlLocator.getEditingNotificationManager();
571

    
572
            EditingNotification notification =
573
                editingNotificationManager.notifyObservers(this,
574
                    EditingNotification.BEFORE_EXIT_EDITING_STORE, null, layer);
575

    
576
            if (notification.isCanceled()) {
577
                String msg =
578
                    String.format(
579
                        "Stop edit layer %1$s canceled by somme observer.",
580
                        layer.getName());
581
                logger.info(msg, new EndEditingException(msg, null));
582

    
583
            }
584

    
585
            getMapControl().getCanceldraw().setCanceled(true);
586
            int option;
587
            EditingSwingManager swingManager =
588
                EditingSwingLocator.getSwingManager();
589

    
590
            
591
            if (layer.isWritable() && getMapControl().getProjection().equals(layer.getProjection()) ) {
592
                option =
593
                    swingManager.showPanelSaveOrDiscard(getMapControl(),
594
                        layer.getName());
595
            } else {
596
                option =
597
                    swingManager.showPanelExportOrDiscard(getMapControl(),
598
                        layer.getName());
599
            }
600

    
601
            doAction(layer, option);
602

    
603
            editingNotificationManager.notifyObservers(this,
604
                EditingNotification.AFTER_EXIT_EDITING_STORE, null, layer);
605

    
606
        }
607

    
608
    }
609

    
610
    private void exportLayer(FLyrVect layer) throws EndEditingException {
611
        Notification notification = new BaseNotification(EditingContext.EXPORT_LAYER_NOTIFICATION,1);
612
        notification.setValue(layer);
613
        this.observableHelper.notifyObservers(this, notification);
614
    }
615

    
616
    protected void finishService() {
617
        EditingService lastService = serviceStack.pop();
618
        try {
619

    
620
            if (!serviceStack.isEmpty()
621
                && getActiveService().next().getTypes().contains(TYPE.GEOMETRY)) {
622
                Geometry geometry = lastService.finish();
623
                if (geometry != null) {
624
                    getActiveService().setValue(geometry);
625
                }
626
            } else {
627
                lastService.finishAndStore();
628
                getMapControl().rePaintDirtyLayers();
629

    
630
                I18nManager i18nManager = ToolsLocator.getI18nManager();
631
                showConsoleMessage("\n"
632
                    + i18nManager.getTranslation(lastService.getName()) + "# "
633
                    + i18nManager.getTranslation("finished") + "\n");
634
                lastService.stop();
635
                setActiveService(lastService);
636
                lastService.start();
637
                changeSelectedTool(getActiveService().getName());
638
            }
639

    
640
        } catch (InvalidEntryException ex) {
641
            I18nManager i18nManager = ToolsLocator.getI18nManager();
642
            showConsoleMessage("\n"
643
                + i18nManager.getTranslation("invalid_option"));
644
            changeSelectedTool(getActiveService().getName());
645
        } catch (VectorEditingException ex) {
646
            logger.info("Can't finish " + lastService.getName(), ex);
647
            cleanEditingContext();
648
            return;
649
        }
650

    
651
        getNextParameter();
652
    }
653

    
654
    protected EditingService getActiveService() {
655
        if (!serviceStack.isEmpty()) {
656
            return serviceStack.peek();
657
        }
658
        return null;
659
    }
660

    
661
    private EditingConsole getConsolePanel() {
662
        if (console == null) {
663
            console = new DefaultEditingConsole(new ResponseListener() {
664

    
665
                public void acceptResponse(String response) {
666
                    textEntered(response);
667
                }
668
            });
669
        }
670
        return console;
671
    }
672

    
673
    protected FLyrVect getCurrentLayer() {
674
        return this.currentLayer;
675
    }
676

    
677
    protected EditingServiceParameter getCurrentParam() {
678
        return this.currentParam;
679
    }
680

    
681
    private Component getDockConsole() {
682
        if (dockConsole == null) {
683
            dockConsole = new JDockPanel((JComponent) getConsolePanel());
684
        }
685
        return dockConsole;
686
    }
687

    
688
    private DefaultEditingBehavior getEditingBehavior() {
689
        if (editingCompoundBehavior != null) {
690
            return (DefaultEditingBehavior) editingCompoundBehavior
691
                .getBehavior(EditingCompoundBehavior.EDITING_INDEX);
692
        }
693
        return null;
694
    }
695

    
696
    private EditingCompoundBehavior getEditingCompoundBehavior() {
697
        if (editingCompoundBehavior != null) {
698
            return editingCompoundBehavior;
699
        } else {
700
            EditingCompoundBehavior editingCompoundBehavior;
701

    
702
            CompoundBehavior compoundBehavior =
703
                (CompoundBehavior) getMapControl().getMapTool("VectorEditing");
704

    
705
            if (compoundBehavior instanceof EditingCompoundBehavior) {
706
                editingCompoundBehavior =
707
                    (EditingCompoundBehavior) compoundBehavior;
708
            } else {
709
                editingCompoundBehavior =
710
                    (EditingCompoundBehavior) compoundBehavior.getBehavior(0);
711
            }
712

    
713
            setCompoundBehavior(editingCompoundBehavior);
714
            return editingCompoundBehavior;
715
        }
716
    }
717

    
718
    public MapControl getMapControl() {
719
        return mapControlReference.get();
720
    }
721

    
722
    protected void getNextParameter() {
723

    
724
        currentParam = getActiveService().next();
725

    
726
        if (currentParam == null) {
727
            finishService();
728
        } else {
729
            askQuestion(currentParam);
730
            if (currentParam.getTypes().contains(TYPE.SELECTION)) {
731
                enableSelection(true);
732
            } else if (currentParam.getTypes().contains(TYPE.GEOMETRY)) {
733
                refreshMenusAndToolBars();
734
            }
735
        }
736
    }
737

    
738
    protected Stack<EditingService> getServiceStack() {
739
        return this.serviceStack;
740
    }
741

    
742
    private void hideConsole() {
743
        isShowConsole = false;
744
        getDockConsole().setVisible(false);
745
    }
746

    
747
    public boolean isServiceCompatible(String name) {
748
        DefaultEditingBehavior editingBehavior = getEditingBehavior();
749

    
750
        if (editingBehavior != null) {
751

    
752
            try {
753
                EditingManager manager = EditingLocator.getManager();
754
                EditingServiceInfo serviceInfo = manager.getServiceInfo(name);
755
                GeometryType geoType = null;
756

    
757
                for (EditingService editingService : getServiceStack()) {
758
                    EditingServiceParameter parameter = editingService.next();
759
                    if (parameter != null
760
                        && parameter.getTypes().contains(TYPE.GEOMETRY)) {
761

    
762
                        int geometryType = parameter.getGeometryType();
763
                        int subType = -1;
764

    
765
                        try {
766
                            subType =
767
                                getCurrentLayer().getFeatureStore()
768
                                    .getDefaultFeatureType()
769
                                    .getDefaultGeometryAttribute()
770
                                    .getGeomType().getSubType();
771

    
772
                            geoType =
773
                                GeometryLocator.getGeometryManager()
774
                                    .getGeometryType(geometryType, subType);
775
                        } catch (Exception e) {
776

    
777
                            String msg =
778
                                String.format(
779
                                    "Problems getting default feature"
780
                                        + " type of %1$s or getting geometry"
781
                                        + " type of %2$s %3$s",
782
                                    getCurrentLayer().getName(), geometryType,
783
                                    subType);
784

    
785
                            throw new ServiceInformationException(msg, e);
786
                        }
787

    
788
                        return serviceInfo.isCompatibleWith(geoType)
789
                            && serviceInfo.createsNewGeometries();
790
                    }
791
                }
792

    
793
                if (getCurrentLayer() != null) {
794
                    try {
795
                        geoType =
796
                            getCurrentLayer().getFeatureStore()
797
                                .getDefaultFeatureType()
798
                                .getDefaultGeometryAttribute().getGeomType();
799
                    } catch (DataException e) {
800
                        String msg =
801
                            String.format("Problems getting default "
802
                                + "feature type of %1$s", getCurrentLayer()
803
                                .getName());
804
                        throw new ServiceInformationException(msg, e);
805
                    }
806

    
807
                    return serviceInfo.isCompatibleWith(geoType);
808
                }
809

    
810
                return false;
811
            } catch (ServiceInformationException e) {
812
                logger.warn(
813
                    "Problems getting if editing context is compatible with "
814
                        + name, e);
815
            }
816
        }
817
        return false;
818
    }
819

    
820
    private Point parsePoint(String response) throws ParsePointException {
821
        String[] numbers = new String[1];
822
        numbers[0] = response;
823
        numbers = response.split(",");
824
        if (numbers.length == 2) {
825

    
826
            if (numbers[0].startsWith("(") && numbers[1].endsWith(")\n")) { // CCS
827
                numbers[0] = numbers[0].replace("(", "");
828
                numbers[1] = numbers[1].replace(")\n", "");
829
            }
830

    
831
            double[] values;
832
            try {
833
                values =
834
                    new double[] { Double.parseDouble(numbers[0]),
835
                        Double.parseDouble(numbers[1]) };
836
            } catch (Exception e) {
837
                throw new ParsePointException(e);
838
            }
839

    
840
            Point point;
841
            try {
842
                GeometryManager geomManager =
843
                    GeometryLocator.getGeometryManager();
844
                int subType =
845
                    getCurrentLayer().getFeatureStore().getDefaultFeatureType()
846
                        .getDefaultGeometryAttribute().getGeomType()
847
                        .getSubType();
848
                point = geomManager.createPoint(values[0], values[1], subType);
849

    
850
            } catch (Exception e) {
851
                throw new ParsePointException(e);
852
            }
853

    
854
            return point;
855
        } else {
856
            throw new ParsePointException(null);
857
        }
858
    }
859

    
860
    private Double parseValue(String response) throws ParseValueException {
861
        try {
862
            return Double.valueOf(response);
863
        } catch (Exception e) {
864
            throw new ParseValueException(e);
865
        }
866

    
867
    }
868

    
869
    protected void refreshMenusAndToolBars() {
870
        Notification notification =
871
            new BaseNotification(EditingContext.REFRESH_TOOLS_NOTIFICATION,
872
                null);
873
        this.observableHelper.notifyObservers(this, notification);
874
    }
875

    
876
    private void saveChanges(FLyrVect layer) throws EndEditingException {
877
        FeatureStore featureStore = layer.getFeatureStore();
878
        try {
879
            featureStore.finishEditing();
880
        } catch (Exception e) {
881
            throw new EndEditingException(e);
882
        }
883
    }
884

    
885
    private void setActiveService(EditingService service) {
886
        serviceStack.add(service);
887
    }
888

    
889
    private void setCompoundBehavior(EditingCompoundBehavior compoundBehavior) {
890
        this.editingCompoundBehavior = compoundBehavior;
891
    }
892

    
893
    private void setCurrentLayer(FLyrVect layer) {
894

    
895
        if (this.currentLayer != layer) {
896
            this.currentLayer = layer;
897
            cleanEditingContext();
898
        }
899

    
900
    }
901

    
902
    public void setMapControl(MapControl mapControl) {
903

    
904
        this.mapControlReference = new WeakReference<MapControl>(mapControl);
905
        this.mapContextReference =
906
            new WeakReference<MapContext>(mapControl.getMapContext());
907

    
908
        // When mapControl is updated we have to add older additional behaviors
909
        // to new mapControl
910
        if (lastAdditionalBehaviors != null) {
911
            try {
912
                addBehaviors(lastAdditionalBehaviors);
913
            } catch (CreateEditingBehaviorException e1) {
914
                logger.info("Problems adding behaviors to editing context", e1);
915
                getMapControl().setTool("pan");
916
                return;
917
            }
918
        }
919
    }
920

    
921
    private void showConsole() {
922
        if (isShowConsole) {
923
            return;
924
        }
925
        isShowConsole = true;
926
        getMapControl().remove(getDockConsole());
927
        getMapControl().setLayout(new BorderLayout());
928
        getMapControl().add(getDockConsole(), BorderLayout.SOUTH);
929
        getDockConsole().setVisible(true);
930
    }
931

    
932
    protected void showConsoleMessage(String text) {
933
        getConsolePanel().addText(text);
934
    }
935

    
936
    protected void textEntered(String response) {
937
        FeatureStore featureStore = getCurrentLayer().getFeatureStore();
938
        if (response == null) {
939
            if (getActiveService() != null) {
940
                try {
941
                    getActiveService().stop();
942
                    serviceStack.pop();
943
                    if (serviceStack.isEmpty()) {
944
                        featureStore
945
                            .getFeatureSelection().deselectAll();
946
                        changeSelectedTool(DEFAULT_TOOL);
947
                    } else {
948
                        changeSelectedTool(getActiveService().getName());
949
                    }
950

    
951
                    refreshMenusAndToolBars();
952

    
953
                    if (getActiveService() != null) {
954
                        getNextParameter();
955
                    } else {
956
                        cleanEditingContext();
957
                    }
958

    
959
                } catch (StopServiceException e) {
960
                    logger
961
                        .info("Can't stop " + getActiveService().getName(), e);
962
                    return;
963
                } catch (DataException e) {
964
                    logger.info("Can't get selection of "
965
                        + featureStore.getFullName(), e);
966
                    return;
967
                }
968
            }
969
        } else {
970

    
971
            if (getCurrentParam() != null) {
972
                Set<TYPE> types = getCurrentParam().getTypes();
973
                Point point = null;
974
                Double value = null;
975

    
976
                boolean insertedValue = false;
977
                if ((!insertedValue && types.contains(TYPE.POSITION))
978
                    || types.contains(TYPE.LIST_POSITIONS)) {
979

    
980
                    try {
981

    
982
                        point = parsePoint(response);
983
                        if (point != null) {
984
                            getActiveService().setValue(point);
985
                            insertedValue = true;
986
                        }
987

    
988
                    } catch (VectorEditingException e) {
989
                        // Do nothing to try other types
990
                    }
991
                }
992
                if (!insertedValue && types.contains(TYPE.VALUE)) {
993

    
994
                    try {
995

    
996
                        value = parseValue(response);
997
                        if (value != null) {
998
                            getActiveService().setValue(value);
999
                            insertedValue = true;
1000
                        }
1001

    
1002
                    } catch (VectorEditingException e) {
1003
                        // Do nothing to try other types
1004
                    }
1005

    
1006
                }
1007
                if (!insertedValue && types.contains(TYPE.OPTION)) {
1008

    
1009
                    try {
1010

    
1011
                        response = response.replace("\n", "");
1012
                        if (response != null) {
1013
                            getActiveService().setValue(response);
1014
                            insertedValue = true;
1015
                        }
1016

    
1017
                    } catch (VectorEditingException e) {
1018
                        // Do nothing to try other types
1019
                    }
1020
                }
1021
                if (!insertedValue && types.contains(TYPE.SELECTION)) {
1022
                    if (response.equalsIgnoreCase("\n")) {
1023
                        enableSelection(false);
1024
                        insertedValue = true;
1025

    
1026
                        try {
1027

    
1028
                            getActiveService().setValue(
1029
                                featureStore
1030
                                    .getFeatureSelection().clone());
1031

    
1032
                        } catch (InvalidEntryException e) {
1033
                            I18nManager i18nManager =
1034
                                ToolsLocator.getI18nManager();
1035
                            showConsoleMessage("\n"
1036
                                + i18nManager.getTranslation("invalid_option"));
1037
                        } catch (Exception e) {
1038
                            logger.info("Can't access to selection.", e);
1039
                            cleanEditingContext();
1040
                            return;
1041
                        }
1042
                    }
1043
                }
1044
                if (!insertedValue) {
1045
                    I18nManager i18nManager = ToolsLocator.getI18nManager();
1046
                    showConsoleMessage("\n"
1047
                        + i18nManager.getTranslation("invalid_option"));
1048
                }
1049
                getNextParameter();
1050
            }
1051
        }
1052
    }
1053

    
1054
    public void setDefaultBehaviors(Behavior[] defaultBehaviors) {
1055
        this.defaultBehaviors = defaultBehaviors;
1056
        try {
1057
            addBehaviors(defaultBehaviors);
1058
        } catch (CreateEditingBehaviorException e1) {
1059
            logger.info("Problems adding behaviors to editing context", e1);
1060
            getMapControl().setTool("pan");
1061
            return;
1062
        }
1063
    }
1064

    
1065
    public Behavior[] getDefaultBehaviors() {
1066
        return this.defaultBehaviors;
1067
    }
1068
}