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

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

    
611
                Geometry geometry = lastService.finish();
612

    
613
                if (geometry != null) {
614

    
615
                    getActiveService().setValue(geometry);
616

    
617
                }
618

    
619
            } else {
620

    
621
                lastService.finishAndStore();
622
                getMapControl().rePaintDirtyLayers();
623

    
624
                I18nManager i18nManager = ToolsLocator.getI18nManager();
625
                showConsoleMessage("\n"
626
                    + i18nManager.getTranslation(lastService.getName()) + "# "
627
                    + i18nManager.getTranslation("finished") + "\n");
628
                setActiveService(lastService);
629
                changeSelectedTool(getActiveService().getName());
630
            }
631

    
632
            lastService.stop();
633
            lastService.start();
634

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

    
646
        getNextParameter();
647
    }
648

    
649
    protected EditingService getActiveService() {
650
        if (!serviceStack.isEmpty()) {
651
            return serviceStack.peek();
652
        }
653
        return null;
654
    }
655

    
656
    private EditingConsole getConsolePanel() {
657
        if (console == null) {
658
            console = new DefaultEditingConsole(new ResponseListener() {
659

    
660
                public void acceptResponse(String response) {
661
                    textEntered(response);
662
                }
663
            });
664
        }
665
        return console;
666
    }
667

    
668
    protected FLyrVect getCurrentLayer() {
669
        return this.currentLayer;
670
    }
671

    
672
    protected EditingServiceParameter getCurrentParam() {
673
        return this.currentParam;
674
    }
675

    
676
    private Component getDockConsole() {
677
        if (dockConsole == null) {
678
            dockConsole = new JDockPanel((JComponent) getConsolePanel());
679
        }
680
        return dockConsole;
681
    }
682

    
683
    private DefaultEditingBehavior getEditingBehavior() {
684
        if (editingCompoundBehavior != null) {
685
            return (DefaultEditingBehavior) editingCompoundBehavior
686
                .getBehavior(EditingCompoundBehavior.EDITING_INDEX);
687
        }
688
        return null;
689
    }
690

    
691
    private EditingCompoundBehavior getEditingCompoundBehavior() {
692
        if (editingCompoundBehavior != null) {
693
            return editingCompoundBehavior;
694
        } else {
695
            EditingCompoundBehavior editingCompoundBehavior;
696

    
697
            CompoundBehavior compoundBehavior =
698
                (CompoundBehavior) getMapControl().getMapTool("VectorEditing");
699

    
700
            if (compoundBehavior instanceof EditingCompoundBehavior) {
701
                editingCompoundBehavior =
702
                    (EditingCompoundBehavior) compoundBehavior;
703
            } else {
704
                editingCompoundBehavior =
705
                    (EditingCompoundBehavior) compoundBehavior.getBehavior(0);
706
            }
707

    
708
            setCompoundBehavior(editingCompoundBehavior);
709
            return editingCompoundBehavior;
710
        }
711
    }
712

    
713
    public MapControl getMapControl() {
714
        return mapControlReference.get();
715
    }
716

    
717
    protected void getNextParameter() {
718

    
719
        currentParam = getActiveService().next();
720

    
721
        if (currentParam == null) {
722
            finishService();
723
        } else {
724
            askQuestion(currentParam);
725
            if (currentParam.getTypes().contains(TYPE.SELECTION)) {
726
                enableSelection(true);
727
            } else if (currentParam.getTypes().contains(TYPE.GEOMETRY)) {
728
                refreshMenusAndToolBars();
729
            }
730
        }
731
    }
732

    
733
    protected Stack<EditingService> getServiceStack() {
734
        return this.serviceStack;
735
    }
736

    
737
    private void hideConsole() {
738
        isShowConsole = false;
739
        getDockConsole().setVisible(false);
740
    }
741

    
742
    public boolean isServiceCompatible(String name) {
743
        DefaultEditingBehavior editingBehavior = getEditingBehavior();
744

    
745
        if (editingBehavior != null) {
746

    
747
            try {
748
                EditingManager manager = EditingLocator.getManager();
749
                EditingServiceInfo serviceInfo = manager.getServiceInfo(name);
750
                GeometryType geoType = null;
751

    
752
                for (EditingService editingService : getServiceStack()) {
753
                    EditingServiceParameter parameter = editingService.next();
754
                    if (parameter != null
755
                        && parameter.getTypes().contains(TYPE.GEOMETRY)) {
756

    
757
                        int geometryType = parameter.getGeometryType();
758
                        int subType = -1;
759

    
760
                        try {
761
                            subType =
762
                                getCurrentLayer().getFeatureStore()
763
                                    .getDefaultFeatureType()
764
                                    .getDefaultGeometryAttribute()
765
                                    .getGeomType().getSubType();
766

    
767
                            geoType =
768
                                GeometryLocator.getGeometryManager()
769
                                    .getGeometryType(geometryType, subType);
770
                        } catch (Exception e) {
771

    
772
                            String msg =
773
                                String.format(
774
                                    "Problems getting default feature"
775
                                        + " type of %1$s or getting geometry"
776
                                        + " type of %2$s %3$s",
777
                                    getCurrentLayer().getName(), geometryType,
778
                                    subType);
779

    
780
                            throw new ServiceInformationException(msg, e);
781
                        }
782

    
783
                        return serviceInfo.isCompatibleWith(geoType)
784
                            && serviceInfo.createsNewGeometries();
785
                    }
786
                }
787

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

    
802
                    return serviceInfo.isCompatibleWith(geoType);
803
                }
804

    
805
                return false;
806
            } catch (ServiceInformationException e) {
807
                logger.warn(
808
                    "Problems getting if editing context is compatible with "
809
                        + name, e);
810
            }
811
        }
812
        return false;
813
    }
814

    
815
    private Point parsePoint(String response) throws ParsePointException {
816
        String[] numbers = new String[1];
817
        numbers[0] = response;
818
        numbers = response.split(",");
819
        if (numbers.length == 2) {
820

    
821
            if (numbers[0].startsWith("(") && numbers[1].endsWith(")\n")) { // CCS
822
                numbers[0] = numbers[0].replace("(", "");
823
                numbers[1] = numbers[1].replace(")\n", "");
824
            }
825

    
826
            double[] values;
827
            try {
828
                values =
829
                    new double[] { Double.parseDouble(numbers[0]),
830
                        Double.parseDouble(numbers[1]) };
831
            } catch (Exception e) {
832
                throw new ParsePointException(e);
833
            }
834

    
835
            Point point;
836
            try {
837
                GeometryManager geomManager =
838
                    GeometryLocator.getGeometryManager();
839
                int subType =
840
                    getCurrentLayer().getFeatureStore().getDefaultFeatureType()
841
                        .getDefaultGeometryAttribute().getGeomType()
842
                        .getSubType();
843
                point = geomManager.createPoint(values[0], values[1], subType);
844

    
845
            } catch (Exception e) {
846
                throw new ParsePointException(e);
847
            }
848

    
849
            return point;
850
        } else {
851
            throw new ParsePointException(null);
852
        }
853
    }
854

    
855
    private Double parseValue(String response) throws ParseValueException {
856
        try {
857
            return Double.valueOf(response);
858
        } catch (Exception e) {
859
            throw new ParseValueException(e);
860
        }
861

    
862
    }
863

    
864
    protected void refreshMenusAndToolBars() {
865
        Notification notification =
866
            new BaseNotification(EditingContext.REFRESH_TOOLS_NOTIFICATION,
867
                null);
868
        this.observableHelper.notifyObservers(this, notification);
869
    }
870

    
871
    private void saveChanges(FLyrVect layer) throws EndEditingException {
872
        FeatureStore featureStore = layer.getFeatureStore();
873
        try {
874
            featureStore.finishEditing();
875
        } catch (Exception e) {
876
            throw new EndEditingException(e);
877
        }
878
    }
879

    
880
    private void setActiveService(EditingService service) {
881
        serviceStack.add(service);
882
    }
883

    
884
    private void setCompoundBehavior(EditingCompoundBehavior compoundBehavior) {
885
        this.editingCompoundBehavior = compoundBehavior;
886
    }
887

    
888
    private void setCurrentLayer(FLyrVect layer) {
889

    
890
        if (this.currentLayer != layer) {
891
            this.currentLayer = layer;
892
            cleanEditingContext();
893
        }
894

    
895
    }
896

    
897
    public void setMapControl(MapControl mapControl) {
898

    
899
        this.mapControlReference = new WeakReference<MapControl>(mapControl);
900
        this.mapContextReference =
901
            new WeakReference<MapContext>(mapControl.getMapContext());
902

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

    
916
    private void showConsole() {
917
        if (isShowConsole) {
918
            return;
919
        }
920
        isShowConsole = true;
921
        getMapControl().remove(getDockConsole());
922
        getMapControl().setLayout(new BorderLayout());
923
        getMapControl().add(getDockConsole(), BorderLayout.SOUTH);
924
        getDockConsole().setVisible(true);
925
    }
926

    
927
    protected void showConsoleMessage(String text) {
928
        getConsolePanel().addText(text);
929
    }
930

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

    
946
                    refreshMenusAndToolBars();
947

    
948
                    if (getActiveService() != null) {
949
                        getNextParameter();
950
                    } else {
951
                        cleanEditingContext();
952
                    }
953

    
954
                } catch (StopServiceException e) {
955
                    logger
956
                        .info("Can't stop " + getActiveService().getName(), e);
957
                    return;
958
                } catch (DataException e) {
959
                    logger.info("Can't get selection of "
960
                        + featureStore.getFullName(), e);
961
                    return;
962
                }
963
            }
964
        } else {
965

    
966
            if (getCurrentParam() != null) {
967
                Set<TYPE> types = getCurrentParam().getTypes();
968
                Point point = null;
969
                Double value = null;
970

    
971
                boolean insertedValue = false;
972
                if ((!insertedValue && types.contains(TYPE.POSITION))
973
                    || types.contains(TYPE.LIST_POSITIONS)) {
974

    
975
                    try {
976

    
977
                        point = parsePoint(response);
978
                        if (point != null) {
979
                            getActiveService().setValue(point);
980
                            insertedValue = true;
981
                        }
982

    
983
                    } catch (VectorEditingException e) {
984
                        // Do nothing to try other types
985
                    }
986
                }
987
                if (!insertedValue && types.contains(TYPE.VALUE)) {
988

    
989
                    try {
990

    
991
                        value = parseValue(response);
992
                        if (value != null) {
993
                            getActiveService().setValue(value);
994
                            insertedValue = true;
995
                        }
996

    
997
                    } catch (VectorEditingException e) {
998
                        // Do nothing to try other types
999
                    }
1000

    
1001
                }
1002
                if (!insertedValue && types.contains(TYPE.OPTION)) {
1003

    
1004
                    try {
1005

    
1006
                        response = response.replace("\n", "");
1007
                        if (response != null) {
1008
                            getActiveService().setValue(response);
1009
                            insertedValue = true;
1010
                        }
1011

    
1012
                    } catch (VectorEditingException e) {
1013
                        // Do nothing to try other types
1014
                    }
1015
                }
1016
                if (!insertedValue && types.contains(TYPE.SELECTION)) {
1017
                    if (response.equalsIgnoreCase("\n")) {
1018
                        enableSelection(false);
1019
                        insertedValue = true;
1020

    
1021
                        try {
1022

    
1023
                            getActiveService().setValue(
1024
                                featureStore
1025
                                    .getFeatureSelection().clone());
1026

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

    
1049
    public void setDefaultBehaviors(Behavior[] defaultBehaviors) {
1050
        this.defaultBehaviors = defaultBehaviors;
1051
    }
1052

    
1053
    public Behavior[] getDefaultBehaviors() {
1054
        return this.defaultBehaviors;
1055
    }
1056
}