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

History | View | Annotate | Download (48.3 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.lang.reflect.InvocationTargetException;
31
import java.util.ArrayList;
32
import java.util.HashSet;
33
import java.util.Iterator;
34
import java.util.List;
35
import java.util.Set;
36
import java.util.Stack;
37
import java.util.logging.Level;
38
import java.util.prefs.PreferenceChangeEvent;
39
import java.util.prefs.PreferenceChangeListener;
40
import java.util.prefs.Preferences;
41
import javax.swing.JComponent;
42
import javax.swing.JOptionPane;
43
import javax.swing.SwingUtilities;
44
import org.apache.commons.lang3.StringUtils;
45
import org.apache.commons.text.StringEscapeUtils;
46
import org.gvsig.expressionevaluator.ExpressionEvaluatorLocator;
47
import org.gvsig.expressionevaluator.ExpressionEvaluatorManager;
48
import org.gvsig.expressionevaluator.ExpressionUtils;
49
import org.gvsig.expressionevaluator.Function;
50
import org.gvsig.expressionevaluator.SymbolTable;
51
import org.gvsig.fmap.dal.DataTypes;
52
import org.gvsig.fmap.dal.EditingNotification;
53
import org.gvsig.fmap.dal.EditingNotificationManager;
54
import org.gvsig.fmap.dal.exception.DataException;
55
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
56
import org.gvsig.fmap.dal.feature.FeatureSelection;
57
import org.gvsig.fmap.dal.feature.FeatureStore;
58
import org.gvsig.fmap.dal.feature.FeatureType;
59
import org.gvsig.fmap.dal.swing.DALSwingLocator;
60
import org.gvsig.fmap.geom.Geometry;
61
import org.gvsig.fmap.geom.GeometryLocator;
62
import org.gvsig.fmap.geom.GeometryUtils;
63
import org.gvsig.fmap.geom.primitive.Point;
64
import org.gvsig.fmap.geom.type.GeometryType;
65
import org.gvsig.fmap.mapcontext.MapContext;
66
import org.gvsig.fmap.mapcontext.layers.CancelationException;
67
import org.gvsig.fmap.mapcontext.layers.FLayer;
68
import org.gvsig.fmap.mapcontext.layers.FLayers;
69
import org.gvsig.fmap.mapcontext.layers.LayerCollectionEvent;
70
import org.gvsig.fmap.mapcontext.layers.LayerCollectionListener;
71
import org.gvsig.fmap.mapcontext.layers.LayerEvent;
72
import org.gvsig.fmap.mapcontext.layers.LayerListener;
73
import org.gvsig.fmap.mapcontext.layers.LayerPositionEvent;
74
import org.gvsig.fmap.mapcontext.layers.SpatialCache;
75
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
76
import org.gvsig.fmap.mapcontext.rendering.legend.IVectorLegend;
77
import org.gvsig.fmap.mapcontrol.MapControl;
78
import org.gvsig.fmap.mapcontrol.tools.Behavior.Behavior;
79
import org.gvsig.fmap.mapcontrol.tools.CompoundBehavior;
80
import org.gvsig.tools.ToolsLocator;
81
import org.gvsig.tools.bookmarksandhistory.Bookmark;
82
import org.gvsig.tools.dataTypes.Coercion;
83
import org.gvsig.tools.i18n.I18nManager;
84
import org.gvsig.tools.locator.LocatorException;
85
import org.gvsig.tools.observer.BaseNotification;
86
import org.gvsig.tools.observer.Notification;
87
import org.gvsig.tools.observer.ObservableHelper;
88
import org.gvsig.tools.observer.Observer;
89
import org.gvsig.tools.swing.api.ToolsSwingLocator;
90
import org.gvsig.tools.swing.api.threadsafedialogs.ThreadSafeDialogsManager;
91
import org.gvsig.utils.console.JDockPanel;
92
import org.gvsig.utils.console.ResponseListener;
93
import org.gvsig.vectorediting.lib.api.EditingLocator;
94
import org.gvsig.vectorediting.lib.api.EditingManager;
95
import org.gvsig.vectorediting.lib.api.EditingService;
96
import org.gvsig.vectorediting.lib.api.EditingServiceInfo;
97
import org.gvsig.vectorediting.lib.api.EditingServiceParameter;
98
import org.gvsig.vectorediting.lib.api.EditingServiceParameter.TYPE;
99
import org.gvsig.vectorediting.lib.api.exceptions.CreateEditingBehaviorException;
100
import org.gvsig.vectorediting.lib.api.exceptions.EndEditingException;
101
import org.gvsig.vectorediting.lib.api.exceptions.InvalidEntryException;
102
import org.gvsig.vectorediting.lib.api.exceptions.ParsePointException;
103
import org.gvsig.vectorediting.lib.api.exceptions.ParseValueException;
104
import org.gvsig.vectorediting.lib.api.exceptions.ServiceInformationException;
105
import org.gvsig.vectorediting.lib.api.exceptions.StartEditingException;
106
import org.gvsig.vectorediting.lib.api.exceptions.StartServiceException;
107
import org.gvsig.vectorediting.lib.api.exceptions.StopServiceException;
108
import org.gvsig.vectorediting.lib.api.exceptions.VectorEditingException;
109
import org.gvsig.vectorediting.swing.api.EditingContext;
110
import org.gvsig.vectorediting.swing.api.EditingSwingLocator;
111
import org.gvsig.vectorediting.swing.api.EditingSwingManager;
112
import org.gvsig.vectorediting.swing.api.console.EditingConsole;
113
import org.gvsig.vectorediting.swing.impl.console.DefaultEditingConsole;
114
import org.slf4j.Logger;
115
import org.slf4j.LoggerFactory;
116

    
117
public class DefaultEditingContext implements EditingContext {
118

    
119
    private static final Logger LOGGER = LoggerFactory
120
        .getLogger(EditingManager.class);
121

    
122
    private WeakReference<MapControl> mapControlReference;
123

    
124
    private WeakReference<MapContext> mapContextReference;
125

    
126
    private EditingCompoundBehavior editingCompoundBehavior;
127

    
128
    private Behavior[] lastAdditionalBehaviors;
129

    
130
    private final ObservableHelper observableHelper;
131

    
132
    private EditingConsole console;
133

    
134
    private JDockPanel dockConsole = null;
135

    
136
    private boolean isShowConsole = false;
137

    
138
    private final Stack<EditingService> serviceStack;
139

    
140
    private FLyrVect currentLayer;
141

    
142
    private EditingServiceParameter currentParam;
143

    
144
    private Behavior[] defaultBehaviors;
145
    
146
    private Set<FLyrVect> layersSpatialCacheEnabled = new HashSet<>();
147

    
148
    private final LayerListener layerListener = new LayerListener() {
149

    
150
        @Override
151
        public void activationChanged(final LayerEvent e) {
152
            if( !SwingUtilities.isEventDispatchThread() ) {
153
                SwingUtilities.invokeLater(new Runnable() {
154

    
155
                    @Override
156
                    public void run() {
157
                        activationChanged(e);
158
                    }
159
                });
160
                return;
161
            }
162

    
163
            FLayer layer = e.getSource();
164
            final MapContext mapContext = layer.getMapContext();
165

    
166
            if (countActiveAndEditingLayers(mapContext) > 1) {
167
                hideConsole();
168
                return;
169
            }
170

    
171
            if (layer instanceof FLyrVect) {
172
                if (layer.isActive()) {
173
                    if(layer.isEditing()) {
174
                        getMapControl().setTool("VectorEditing");
175
                        setCurrentLayer((FLyrVect) layer);
176
                        showConsole();
177
                        return;
178
                    } else {
179
                        final SpatialCache spatialCache = ((FLyrVect) layer).getSpatialCache();
180
                        if(!spatialCache.isEnabled()){
181
                            spatialCache.setEnabled(true);
182
                            //We keep the list of layers whose spatial cache is enabled here.
183
                            layersSpatialCacheEnabled.add((FLyrVect) layer);
184

    
185
                        }
186
                    }
187
                } else {
188
                    if(!layer.isEditing()) {
189
                        //We disabled the spatial cache of the layers that we had enabled here.
190
                        final SpatialCache spatialCache = ((FLyrVect) layer).getSpatialCache();
191
                        if(spatialCache.isEnabled() && layersSpatialCacheEnabled.contains((FLyrVect) layer)){
192
                            spatialCache.setEnabled(false);
193
                            layersSpatialCacheEnabled.remove((FLyrVect) layer);
194
                        }
195
                    }
196
                }
197
            }
198

    
199
            FLayer[] activeLayers =
200
                layer.getMapContext().getLayers().getActives();
201
            
202
            for (FLayer activeLayer : activeLayers) {
203
                if (activeLayer instanceof FLyrVect) {
204
                    if (activeLayer.isEditing()) {
205
                        getMapControl().setTool("VectorEditing");
206
                        setCurrentLayer((FLyrVect) activeLayer);
207
                        showConsole();
208
                        return;
209
                    }
210
                }
211
            }
212

    
213
            hideConsole();
214
            if ((getMapControl().getCurrentTool() != null)
215
                && getMapControl().getCurrentTool().equals("VectorEditing")) {
216
                getMapControl().setPrevTool();
217
            }
218
        }
219

    
220
        @Override
221
        public void drawValueChanged(LayerEvent e) {
222
        }
223

    
224
        @Override
225
        public void editionChanged(final LayerEvent e) {
226
            if( !SwingUtilities.isEventDispatchThread() ) {
227
                SwingUtilities.invokeLater(new Runnable() {
228

    
229
                    @Override
230
                    public void run() {
231
                        editionChanged(e);
232
                    }
233
                });
234
                return;
235
            }
236
            FLayer layer = e.getSource();
237

    
238
            if (layer instanceof FLyrVect) {
239
                if (layer.isEditing()) {
240
                    synchronized (DefaultEditingContext.this) {
241
                        beginEdition((FLyrVect) layer);
242
                        showConsole();
243
                    }
244
                } else {
245
                    hideConsole();
246
                }
247
            }
248

    
249
        }
250

    
251
        @Override
252
        public void nameChanged(LayerEvent e) {
253
        }
254

    
255
        @Override
256
        public void visibilityChanged(LayerEvent e) {
257
        }
258
    };
259
    
260
    private int countActiveAndEditingLayers(MapContext mapcontext){
261
        int count = 0;
262
        
263
        FLayer[] activeLayers =
264
                mapcontext.getLayers().getActives();
265
            
266
        for (FLayer activeLayer : activeLayers) {
267
            if (activeLayer instanceof FLyrVect) {
268
                if (activeLayer.isEditing()) {
269
                    count++;
270
                }
271
            }
272
        }
273
        
274
        return count;
275
    }
276

    
277
    private final PreferenceChangeListener preferenceChangeListener =
278
        new PreferenceChangeListener() {
279

    
280
            @Override
281
            public void preferenceChange(PreferenceChangeEvent evt) {
282
                String key = evt.getKey();
283
                if (key.equalsIgnoreCase("apply-snappers")) {
284
                    boolean newValue = Boolean.parseBoolean(evt.getNewValue());
285
                    getMapControl().setRefentEnabled(newValue);
286
                }
287
            }
288
        };
289

    
290
    public DefaultEditingContext(MapControl mapControl) {
291

    
292
        this.mapControlReference = new WeakReference<>(mapControl);
293
        this.mapContextReference =
294
            new WeakReference<>(mapControl.getMapContext());
295
        this.observableHelper = new ObservableHelper();
296

    
297
        this.serviceStack = new Stack<>();
298

    
299
        addLayerListeners();
300
        addPreferenceListener();
301
    }
302

    
303
    private void addPreferenceListener() {
304
        Preferences prefs = Preferences.userRoot().node("snappers");
305
        prefs.addPreferenceChangeListener(preferenceChangeListener);
306
    }
307

    
308
    @Override
309
    public void activateService(String name) {
310

    
311
        if ((getMapControl() != null)
312
            && getMapControl().hasTool("VectorEditing")) {
313

    
314
            CompoundBehavior editingCompoundBehavior =
315
                getEditingCompoundBehavior();
316
            getMapControl().setTool("VectorEditing");
317
            editingCompoundBehavior.setDrawnBehavior(
318
                EditingCompoundBehavior.EDITING_INDEX, true);
319

    
320
            EditingManager manager = EditingLocator.getManager();
321

    
322
            if (currentLayer != null) {
323
                IVectorLegend legend = null;
324
                try {
325
                    legend = (IVectorLegend) currentLayer.getLegend();
326
                } catch (Exception e) {
327
                    LOGGER.trace("Can't retrieve legend from layer.");
328
                    //DO NOTHING
329
                }
330

    
331
//                EditingService activeService = getActiveService();
332
//                if(activeService != null && !activeService.next().getTypes().contains(TYPE.GEOMETRY)) {
333
//                    activeService.setShowPreviewSymbol(true);
334
//                }
335
                EditingService service =
336
                    manager.getEditingService(name,
337
                        currentLayer.getFeatureStore(),
338
                        mapContextReference.get(), 
339
                        legend);
340

    
341
                if (service != null) {
342
//                     if(!serviceStack.isEmpty()) { service.setShowPreviewSymbol(false); }
343
                    this.enableSelection(false);
344

    
345
                    try {
346
                        service.activate();
347
                        service.start();                       
348
                    } catch (StartServiceException e) {
349

    
350
                        LOGGER.info(String.format(
351
                            "Can't start the service %1$s", service.getName()),
352
                            e);
353
                        cleanEditingContext();
354
                        return;
355

    
356
                    } catch (InvalidEntryException e) {
357

    
358
                        I18nManager i18nManager = ToolsLocator.getI18nManager();
359
                        showConsoleMessage("\n"
360
                            + i18nManager.getTranslation("invalid_option"));
361
                    }
362

    
363
                    if (!serviceStack.isEmpty()){
364
                        if(getActiveService().next().getTypes().contains(TYPE.GEOMETRY)) {
365
                            service.setShowPreviewSymbol(false);
366
                        } else {
367
//                            service.setShowPreviewSymbol(true);
368
//                            getActiveService().setShowPreviewSymbol(true);
369
                            serviceStack.pop();
370
                        }
371
                    }
372

    
373
                    setActiveService(service);
374

    
375
                    nextParameter();
376
                }
377
            }
378
        }
379
    }
380

    
381
    private void addBehaviors(Behavior[] additionalBehavior)
382
        throws CreateEditingBehaviorException {
383

    
384
        DefaultEditingBehavior editingBehavior;
385
        EditingCompoundBehavior editingCompoundBehavior;
386

    
387
        if (!getMapControl().hasTool("VectorEditing")) {
388

    
389
            editingBehavior = new DefaultEditingBehavior(this);
390
            editingCompoundBehavior =
391
                new EditingCompoundBehavior(editingBehavior);
392
            setCompoundBehavior(editingCompoundBehavior);
393

    
394
            if (additionalBehavior != null) {
395

    
396
                Behavior[] behaviors =
397
                    new Behavior[additionalBehavior.length + 1];
398
                behaviors[0] = editingCompoundBehavior;
399

    
400
                System.arraycopy(additionalBehavior, 0, behaviors, 1, additionalBehavior.length);
401

    
402
                getMapControl().addBehavior("VectorEditing", behaviors);
403

    
404
                lastAdditionalBehaviors = additionalBehavior;
405

    
406
            } else {
407
                getMapControl().addBehavior("VectorEditing",
408
                    editingCompoundBehavior);
409
            }
410

    
411
        } else {
412
            editingCompoundBehavior = getEditingCompoundBehavior();
413
            editingBehavior =
414
                (DefaultEditingBehavior) editingCompoundBehavior
415
                    .getBehavior(EditingCompoundBehavior.EDITING_INDEX);
416
            setCompoundBehavior(editingCompoundBehavior);
417
            cleanEditingContext();
418
        }
419

    
420
    }
421

    
422
    private void addLayerListeners() {
423

    
424
        FLayers layers = mapContextReference.get().getLayers();
425

    
426
        layers.addLayerListener(layerListener);
427

    
428
        layers.addLayerCollectionListener(new LayerCollectionListener() {
429

    
430
            public void addLayer(FLayer layer) {
431
                if (layer instanceof FLayers) {
432
                    FLayers layers = (FLayers) layer;
433
                    for (int i = 0; i < layers.getLayersCount(); i++) {
434
                        addLayer(layers.getLayer(i));
435
                    }
436
                } else if (layer instanceof FLyrVect) {
437
                    ((FLyrVect) layer).addLayerListener(layerListener);
438
                }
439
            }
440

    
441
            @Override
442
            public void layerAdded(LayerCollectionEvent e) {
443
                addLayer(e.getLayers());
444
            }
445

    
446
            @Override
447
            public void layerAdding(LayerCollectionEvent e)
448
                throws CancelationException {
449
            }
450

    
451
            @Override
452
            public void layerMoved(LayerPositionEvent e) {
453
            }
454

    
455
            @Override
456
            public void layerMoving(LayerPositionEvent e)
457
                throws CancelationException {
458
            }
459

    
460
            public void removeLayer(FLayer layer) {
461
                if (layer instanceof FLayers) {
462
                    FLayers layers = (FLayers) layer;
463
                    for (int i = 0; i < layers.getLayersCount(); i++) {
464
                        addLayer(layers.getLayer(i));
465
                    }
466
                } else if (layer instanceof FLyrVect) {
467
                    ((FLyrVect) layer).removeLayerListener(layerListener);
468
                }
469
            }
470

    
471
            @Override
472
            public void layerRemoved(LayerCollectionEvent e) {
473
                removeLayer(e.getLayers());
474
            }
475

    
476
            @Override
477
            public void layerRemoving(LayerCollectionEvent e)
478
                throws CancelationException {
479
            }
480

    
481
            @Override
482
            public void visibilityChanged(LayerCollectionEvent e)
483
                throws CancelationException {
484
            }
485
        });
486
    }
487

    
488
    @Override
489
    public void addObserver(Observer o) {
490
        this.observableHelper.addObserver(o);
491
    }
492

    
493
    private void askQuestion(EditingServiceParameter param) {
494
        I18nManager i18nManager = ToolsLocator.getI18nManager();
495
        String translation = i18nManager.getTranslation(param.getDescription());
496
        String activeServiceName =
497
            i18nManager.getTranslation(getActiveService().getName());
498

    
499
        String strDefaultValue = param.getConsoleDefaultValue();
500
        
501
        if(StringUtils.isBlank(strDefaultValue)) {
502
            showConsoleMessage("\n" + activeServiceName + "# " + translation + " : ");
503
        } else {
504
            showConsoleMessage("\n" + activeServiceName + "# " + translation + "<" + strDefaultValue + "> : ");
505
        }
506
    }
507

    
508
    @Override
509
    public synchronized void beginEdition(FLyrVect layer,
510
        Behavior[] additionalBehaviors) {
511

    
512
        try{
513
            throw new Exception("Deprecated method");
514
        } catch (Exception e){
515
            LOGGER.info("Deprecated method", e);
516
        }
517

    
518
        beginEdition(layer);
519
        try {
520
            addBehaviors(additionalBehaviors);
521
        } catch (CreateEditingBehaviorException e1) {
522
            LOGGER.info("Problems adding behaviors to editing context", e1);
523
            getMapControl().setTool("pan");
524
        }
525
    }
526

    
527
    @Override
528
    public synchronized void beginEdition(FLyrVect layer) {
529

    
530
        EditingNotificationManager editingNotificationManager =
531
            DALSwingLocator.getEditingNotificationManager();
532

    
533
        EditingNotification notification =
534
            editingNotificationManager.notifyObservers(this,
535
                EditingNotification.BEFORE_ENTER_EDITING_STORE, null, layer,layer.getFeatureStore());
536

    
537
        if (notification.isCanceled()) {
538
            String msg =
539
                String.format("Edit layer %1$s canceled by somme observer.",
540
                    layer.getName());
541
            LOGGER.info(msg, new StartEditingException(msg, null));
542
            return;
543
        }
544

    
545
        setCurrentLayer(layer);
546

    
547
        FeatureStore featureStore = layer.getFeatureStore();
548
        if (!featureStore.isEditing()) {
549
            try {
550
                featureStore.edit();
551
            } catch (Exception e) {
552
                String msg =
553
                    String.format("Can't set %1$s in edit mode",
554
                        featureStore.getName());
555
                LOGGER.info(msg, new VectorEditingException(e));
556
                cleanEditingContext();
557
                return;
558
            }
559
        }
560

    
561
        featureStore.addObserver(getMapControl());
562

    
563
        editingNotificationManager.notifyObservers(this,
564
            EditingNotification.AFTER_ENTER_EDITING_STORE, null, layer, layer.getFeatureStore());
565

    
566
        enableSnapping();
567
    }
568

    
569
    @SuppressWarnings({ "rawtypes", "unchecked" })
570
    private void enableSnapping() {
571
        Preferences prefs = Preferences.userRoot().node("snappers");
572
         getMapControl().setRefentEnabled(prefs.getBoolean("apply-snappers", false));
573
         if (currentLayer != null) {
574
            ArrayList layersToSnap =
575
                getMapControl().getMapContext().getLayersToSnap();
576
            if (!layersToSnap.contains(currentLayer)) {
577
                layersToSnap.add(currentLayer);
578
            }
579
        }
580
    }
581

    
582
    @SuppressWarnings("rawtypes")
583
    private void disableSnapping() {
584
        ArrayList layersToSnap =
585
            getMapControl().getMapContext().getLayersToSnap();
586
        if (layersToSnap.contains(currentLayer)) {
587
            layersToSnap.remove(currentLayer);
588
        }
589
    }
590

    
591
    private void changeSelectedTool(String name) {
592
        if (name.equalsIgnoreCase(DEFAULT_TOOL)) {
593
            name = "selection-simple-select-view";
594
            this.getMapControl().setTool("pointSelection");
595
//            notifyChangeSelectedTool();
596
        }
597
    }
598
    
599
    private void notifyChangeSelectedTool() {
600
        Notification notification = new BaseNotification(
601
            EditingContext.CHANGE_SELECTED_TOOL_NOTIFICATION,
602
            null
603
        );
604
        this.observableHelper.notifyObservers(this, notification);
605
    }
606

    
607
    private void cleanEditingContext() {
608
        serviceStack.clear();
609
        currentParam = null;
610
        this.enableSelection(false);
611
        refreshMenusAndToolBars();
612

    
613
        I18nManager i18nManager = ToolsLocator.getI18nManager();
614
        showConsoleMessage("\n" + i18nManager.getTranslation("select_new_tool")
615
            + "\n");
616
        notifyChangeSelectedTool();
617
    }
618

    
619
    @Override
620
    public void deleteObserver(Observer o) {
621
        this.observableHelper.deleteObserver(o);
622
    }
623

    
624
    @Override
625
    public void deleteObservers() {
626
        this.observableHelper.deleteObservers();
627
    }
628

    
629
    private void discardChanges(FLyrVect layer) throws EndEditingException {
630
        FeatureStore featureStore = layer.getFeatureStore();
631
        try {
632
            featureStore.cancelEditing();
633
        } catch (Exception e) {
634
            throw new EndEditingException(e);
635
        }
636
    }
637

    
638
    private void doAction(FLyrVect layer, int option) {
639
        ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
640
        I18nManager i18n = ToolsLocator.getI18nManager();
641
        
642
        switch (option) {
643
        case SAVE_CHANGES:
644
            try {
645
                saveChanges(layer);
646
            } catch (VectorEditingException e) {
647
                String msg =
648
                    String.format("Changes can not be saved in %1$s",
649
                        layer.getName());
650
                LOGGER.info(msg, e);
651
                dialogs.messageDialog(                   
652
                    i18n.getTranslation("_There_are_problems_saving_changes")+"\n\n"+
653
                    i18n.getTranslation("_See_error_log_for_more_information"), 
654
                    null, 
655
                    i18n.getTranslation("_Warning"), 
656
                    JOptionPane.WARNING_MESSAGE, 
657
                    "Vectorediting_cant_save_changes"
658
                );
659
                return;
660
            }
661
            break;
662

    
663
        case DISCARD_CHANGES:
664
            try {
665
                discardChanges(layer);
666
            } catch (VectorEditingException e) {
667
                String msg =
668
                    String.format("Changes can not be discared in %1$s",
669
                        layer.getName());
670
                LOGGER.info(msg, e);
671
                dialogs.messageDialog(                   
672
                    i18n.getTranslation("_There_are_problems_discarding_changes")+"\n"+
673
                    "\n" + i18n.getTranslation("_See_error_log_for_more_information"), 
674
                    null, 
675
                    i18n.getTranslation("_Warning"), 
676
                    JOptionPane.WARNING_MESSAGE, 
677
                    "Vectorediting_cant_discard_changes"
678
                );
679
                return;
680
            }
681
            break;
682

    
683
        case EXPORT_LAYER:
684
            try {
685
                exportLayer(layer);
686
            } catch (VectorEditingException e) {
687
                String msg =
688
                    String.format("Changes of %1$s can not be exported",
689
                        layer.getName());
690
                LOGGER.info(msg, e);
691
                dialogs.messageDialog(                   
692
                    i18n.getTranslation("_There_are_problems_exporting_changes")+"\n\n"+
693
                    i18n.getTranslation("_See_error_log_for_more_information"), 
694
                    null, 
695
                    i18n.getTranslation("_Warning"), 
696
                    JOptionPane.WARNING_MESSAGE, 
697
                    "Vectorediting_cant_export_changes"
698
                );
699
                return;
700
            }
701
            break;
702

    
703
        case CANCEL:
704
            return;
705
        }
706

    
707
        cleanEditingContext();
708
        hideConsole();
709
        disableSnapping();
710
        changeSelectedTool(DEFAULT_TOOL);
711

    
712
        FeatureStore featureStore = layer.getFeatureStore();
713
        featureStore.deleteObserver(getMapControl());
714

    
715
    }
716

    
717
    private void enableSelection(boolean enableSelection) {
718
        this.getEditingCompoundBehavior().setDrawnBehavior(
719
                EditingCompoundBehavior.SELECTION_INDEX, enableSelection);
720
    }
721

    
722
    @Override
723
    public void endEdition(FLyrVect layer) {
724
        if (layer.isEditing()) {
725
            EditingNotificationManager editingNotificationManager =
726
                DALSwingLocator.getEditingNotificationManager();
727

    
728
            EditingNotification notification =
729
                editingNotificationManager.notifyObservers(this,
730
                    EditingNotification.BEFORE_EXIT_EDITING_STORE, null, layer, layer.getFeatureStore());
731

    
732
            if (notification.isCanceled()) {
733
                String msg =
734
                    String.format(
735
                        "Stop edit layer %1$s canceled by somme observer.",
736
                        layer.getName());
737
                LOGGER.info(msg, new EndEditingException(msg, null));
738

    
739
            }
740

    
741
            getMapControl().getCanceldraw().setCanceled(true);
742
            int option;
743
            EditingSwingManager swingManager =
744
                EditingSwingLocator.getSwingManager();
745

    
746

    
747
            if (layer.isWritable() && getMapControl().getProjection().equals(layer.getProjection()) ) {
748
                option =
749
                    swingManager.showPanelSaveOrDiscard(getMapControl(),
750
                        layer.getName());
751
            } else {
752
                option =
753
                    swingManager.showPanelExportOrDiscard(getMapControl(),
754
                        layer.getName());
755
            }
756

    
757
            doAction(layer, option);
758

    
759
            editingNotificationManager.notifyObservers(this,
760
                EditingNotification.AFTER_EXIT_EDITING_STORE, null, layer, layer.getFeatureStore());
761

    
762
        }
763

    
764
    }
765

    
766
    private void exportLayer(FLyrVect layer) throws EndEditingException {
767
        Notification notification = new BaseNotification(EditingContext.EXPORT_LAYER_NOTIFICATION,1);
768
        notification.setValue(layer);
769
        this.observableHelper.notifyObservers(this, notification);
770
    }
771

    
772
    protected void finishService() {
773
        EditingService lastService = serviceStack.pop();
774
        try {
775

    
776
            if (!serviceStack.isEmpty()
777
                && getActiveService().next().getTypes().contains(TYPE.GEOMETRY)) {
778
                Geometry geometry = lastService.finish();
779
                lastService.setShowPreviewSymbol(true);
780
                if (geometry != null) {
781
                    getActiveService().setValue(geometry);
782
                }
783
            } else {
784
                lastService.finishAndStore();
785
                getMapControl().rePaintDirtyLayers();
786
                refreshMenusAndToolBars();
787

    
788
                I18nManager i18nManager = ToolsLocator.getI18nManager();
789
                showConsoleMessage("\n"
790
                    + i18nManager.getTranslation(lastService.getName()) + "# "
791
                    + i18nManager.getTranslation("finished") + "\n");
792
//                lastService.stop();
793
                setActiveService(lastService);
794
//                lastService.start();
795
                lastService.restart();
796
                changeSelectedTool(getActiveService().getName());
797
            }
798

    
799
        } catch (InvalidEntryException ex) {
800
            I18nManager i18nManager = ToolsLocator.getI18nManager();
801
            showConsoleMessage("\n"
802
                + i18nManager.getTranslation("invalid_option"));
803
            changeSelectedTool(getActiveService().getName());
804
        } catch (VectorEditingException ex) {
805
            LOGGER.info("Can't finish " + lastService.getName(), ex);
806
            cleanEditingContext();
807
            return;
808
        }
809

    
810
        nextParameter();
811
    }
812

    
813
    public EditingService getActiveService() {
814
        if (!serviceStack.isEmpty()) {
815
            return serviceStack.peek();
816
        }
817
        return null;
818
    }
819

    
820
    public EditingConsole getConsolePanel() {
821
        if (console == null) {
822
            console = new DefaultEditingConsole(new ResponseListener() {
823

    
824
                @Override
825
                public void acceptResponse(String response) {
826
                    textEntered(response);
827
                }
828
            });
829
        }
830
        return console;
831
    }
832

    
833
    protected FLyrVect getCurrentLayer() {
834
        return this.currentLayer;
835
    }
836

    
837
    protected EditingServiceParameter getCurrentParam() {
838
        return this.currentParam;
839
    }
840

    
841
    private Component getDockConsole() {
842
        if (dockConsole == null) {
843
            dockConsole = new JDockPanel((JComponent) getConsolePanel());
844
        }
845
        return dockConsole;
846
    }
847

    
848
    private DefaultEditingBehavior getEditingBehavior() {
849
        if (editingCompoundBehavior != null) {
850
            return (DefaultEditingBehavior) editingCompoundBehavior
851
                .getBehavior(EditingCompoundBehavior.EDITING_INDEX);
852
        }
853
        return null;
854
    }
855

    
856
    private EditingCompoundBehavior getEditingCompoundBehavior() {
857
        if (editingCompoundBehavior != null) {
858
            return editingCompoundBehavior;
859
        } else {
860
            EditingCompoundBehavior editingCompoundBehavior;
861

    
862
            CompoundBehavior compoundBehavior =
863
                (CompoundBehavior) getMapControl().getMapTool("VectorEditing");
864

    
865
            if (compoundBehavior instanceof EditingCompoundBehavior) {
866
                editingCompoundBehavior =
867
                    (EditingCompoundBehavior) compoundBehavior;
868
            } else {
869
                editingCompoundBehavior =
870
                    (EditingCompoundBehavior) compoundBehavior.getBehavior(0);
871
            }
872

    
873
            setCompoundBehavior(editingCompoundBehavior);
874
            return editingCompoundBehavior;
875
        }
876
    }
877

    
878
    @Override
879
    public MapControl getMapControl() {
880
        return mapControlReference.get();
881
    }
882

    
883
    
884
    public void nextParameter() {
885
        if ((getMapControl().getCurrentTool() != null)
886
            && !getMapControl().getCurrentTool().equals("VectorEditing")) {
887
            getMapControl().setTool("VectorEditing");
888
        }
889
        EditingService activeService = getActiveService();
890
        currentParam = activeService.next();
891

    
892
        if (currentParam == null) {
893
            finishService();
894
        } else {
895
            askQuestion(currentParam);
896
            if (currentParam.getTypes().contains(TYPE.SELECTION)) {
897
                enableSelection(true);
898
            } else if (currentParam.getTypes().contains(TYPE.GEOMETRY)) {
899
                refreshMenusAndToolBars();
900
            }
901
        }
902
    }
903

    
904
    protected Stack<EditingService> getServiceStack() {
905
        return this.serviceStack;
906
    }
907

    
908
    private void hideConsole() {
909
        isShowConsole = false;
910
        if( !SwingUtilities.isEventDispatchThread() ) {
911
            try {
912
                SwingUtilities.invokeAndWait(new Runnable() {
913

    
914
                    @Override
915
                    public void run() {
916
                        hideConsole();
917
                    }
918
                });
919
                return;
920
            } catch (InterruptedException | InvocationTargetException ex) {
921
                LOGGER.warn("Can't hide editing console.",ex);
922
            }
923
            return;
924
        }
925
        getDockConsole().setVisible(false);
926
    }
927

    
928
    @Override
929
    public boolean isServiceCompatible(String name) {
930
        DefaultEditingBehavior editingBehavior = getEditingBehavior();
931

    
932
        if (editingBehavior != null) {
933

    
934
            try {
935
                EditingManager manager = EditingLocator.getManager();
936
                EditingServiceInfo serviceInfo = manager.getServiceInfo(name);
937
                GeometryType geoType = null;
938

    
939
                for (EditingService editingService : getServiceStack()) {
940
                    EditingServiceParameter parameter = editingService.next();
941
                    if (parameter != null) {
942
                        if (parameter.getTypes().contains(TYPE.GEOMETRY)) {
943

    
944
                            int geometryType = parameter.getGeometryType();
945
                            int subType = -1;
946

    
947
                            try {
948
                                subType
949
                                        = getCurrentLayer().getFeatureStore()
950
                                                .getDefaultFeatureType()
951
                                                .getDefaultGeometryAttribute()
952
                                                .getGeomType().getSubType();
953

    
954
                                geoType
955
                                        = GeometryLocator.getGeometryManager()
956
                                                .getGeometryType(geometryType, subType);
957
                            } catch (Exception e) {
958

    
959
                                String msg
960
                                        = String.format(
961
                                                "Problems getting default feature"
962
                                                + " type of %1$s or getting geometry"
963
                                                + " type of %2$s %3$s",
964
                                                getCurrentLayer().getName(), geometryType,
965
                                                subType);
966

    
967
                                throw new ServiceInformationException(msg, e);
968
                            }
969

    
970
                            return serviceInfo.isCompatibleWith(geoType)
971
                                    && serviceInfo.createsNewGeometries();
972
                        }
973
                    }
974
                }
975

    
976
                if (getCurrentLayer() != null) {
977
                    try {
978
                        geoType
979
                                = getCurrentLayer().getFeatureStore()
980
                                        .getDefaultFeatureType()
981
                                        .getDefaultGeometryAttribute().getGeomType();
982

    
983
                        if (serviceInfo.isCompatibleWith(geoType)) {
984
                            return true;
985
                        }
986
                    } catch (DataException e) {
987
                        String msg
988
                                = String.format("Problems getting default "
989
                                        + "feature type of %1$s", getCurrentLayer()
990
                                                .getName());
991
                        throw new ServiceInformationException(msg, e);
992
                    }
993
                }
994

    
995
                return false;
996
            } catch (ServiceInformationException e) {
997
                LOGGER.warn(
998
                    "Problems getting if editing context is compatible with "
999
                        + name, e);
1000
            }
1001
        }
1002
        return false;
1003
    }
1004
     
1005
    private static final EditingContextSymbolTable contextSymbolTable = new EditingContextSymbolTable();
1006
    
1007
    @Override
1008
    public SymbolTable getContextSymbolTable() {
1009
        return contextSymbolTable;
1010
    }
1011
    
1012
    @Override
1013
    public Point parsePoint(String response) throws ParsePointException {
1014
        response = fixResponseUsingBookmarks(response);
1015
        
1016
        try {
1017
            Object x = ExpressionUtils.evaluate(contextSymbolTable, response);
1018
            if( x instanceof Point ) {
1019
                contextSymbolTable.addPoint((Point) x);
1020
                return (Point) x;
1021
            }
1022
        } catch(Exception ex) {
1023
            LOGGER.debug("Can't evaluate: "+StringEscapeUtils.escapeJava(response),ex);
1024
        }
1025
        String s = "ST_MakePoint("+response+")";
1026
        try {
1027
            Object x = ExpressionUtils.evaluate(contextSymbolTable, s);
1028
            if( x instanceof Point ) {
1029
                contextSymbolTable.addPoint((Point) x);
1030
                return (Point) x;
1031
            }
1032
        } catch(Exception ex) {
1033
            throw new ParsePointException(ex);
1034
        }
1035
        throw new ParsePointException(null);
1036
    }
1037
    
1038
    private Double parseValue(String response) throws ParseValueException {
1039
        response = fixResponseUsingBookmarks(response);
1040

    
1041
        try {
1042
            Object x = ExpressionUtils.evaluate(contextSymbolTable, response);
1043
            if( x instanceof Double ) {
1044
                return (Double) x;
1045
            }  
1046
            if( x==null ) {
1047
                throw new ParseValueException(new NullPointerException());
1048
            }
1049
            Coercion toDouble = ToolsLocator.getDataTypesManager().get(DataTypes.DOUBLE).getCoercion();
1050
            return (Double) toDouble.coerce(x);
1051
        } catch(Exception ex) {
1052
            throw new ParseValueException(ex);
1053
        }
1054

    
1055
    }
1056

    
1057
    protected String fixResponseUsingBookmarks(String response) throws LocatorException {
1058
        if( response != null ) {
1059
            response = response.trim();
1060
            int n = StringUtils.indexOf(response, " ");
1061
            if(n>0){
1062
                String name = StringUtils.left(response, n);
1063
                Function fn = contextSymbolTable.function(name);
1064
                if(fn != null){
1065
                    response = name+"("+response.substring(n)+")";
1066
                }
1067
            }
1068
        }
1069
        return response;
1070
    }
1071

    
1072
    protected void refreshMenusAndToolBars() {
1073
        if (!SwingUtilities.isEventDispatchThread()) {
1074
            SwingUtilities.invokeLater(new Runnable() {
1075

    
1076
                @Override
1077
                public void run() {
1078
                    refreshMenusAndToolBars();
1079
                }
1080
            });
1081
            return;
1082
        }
1083
        Notification notification = new BaseNotification(
1084
                EditingContext.REFRESH_TOOLS_NOTIFICATION,
1085
                null
1086
        );
1087
        this.observableHelper.notifyObservers(this, notification);
1088
    }
1089

    
1090
    private void saveChanges(FLyrVect layer) throws EndEditingException {
1091
        FeatureStore featureStore = layer.getFeatureStore();
1092
        try {
1093
            featureStore.finishEditing();
1094
        } catch (Exception e) {
1095
            throw new EndEditingException(e);
1096
        }
1097
    }
1098

    
1099
    private void setActiveService(EditingService service) {
1100
        serviceStack.add(service);
1101
        notifyChangeSelectedTool();
1102
    }
1103

    
1104
    private void setCompoundBehavior(EditingCompoundBehavior compoundBehavior) {
1105
        this.editingCompoundBehavior = compoundBehavior;
1106
    }
1107

    
1108
    private void setCurrentLayer(FLyrVect layer) {
1109

    
1110
        if (this.currentLayer != layer) {
1111
            this.currentLayer = layer;
1112
            cleanEditingContext();
1113
        }
1114

    
1115
    }
1116

    
1117
    @Override
1118
    public void setMapControl(MapControl mapControl) {
1119

    
1120
        this.mapControlReference = new WeakReference<>(mapControl);
1121
        this.mapContextReference =
1122
            new WeakReference<>(mapControl.getMapContext());
1123

    
1124
        // When mapControl is updated we have to add older additional behaviors
1125
        // to new mapControl
1126
        if (lastAdditionalBehaviors != null) {
1127
            try {
1128
                addBehaviors(lastAdditionalBehaviors);
1129
            } catch (CreateEditingBehaviorException e1) {
1130
                LOGGER.info("Problems adding behaviors to editing context", e1);
1131
                getMapControl().setTool("pan");
1132
            }
1133
        }
1134
    }
1135

    
1136
    private void showConsole() {
1137
        if (isShowConsole) {
1138
            return;
1139
        }
1140
        if( !SwingUtilities.isEventDispatchThread() ) {
1141
            try {
1142
                SwingUtilities.invokeAndWait(new Runnable() {
1143

    
1144
                    @Override
1145
                    public void run() {
1146
                        showConsole();
1147
                    }
1148
                });
1149
                return;
1150
            } catch (InterruptedException | InvocationTargetException ex) {
1151
                LOGGER.warn("Can't show editing console.",ex);
1152
            }
1153
            return;
1154
        }
1155
        isShowConsole = true;
1156
        getMapControl().remove(getDockConsole());
1157
        getMapControl().setLayout(new BorderLayout());
1158
        getMapControl().add(getDockConsole(), BorderLayout.SOUTH);
1159
        getDockConsole().setVisible(true);
1160
    }
1161

    
1162
    protected void showConsoleMessage(final String text) {
1163
        if (!SwingUtilities.isEventDispatchThread()) {
1164
            SwingUtilities.invokeLater(new Runnable() {
1165

    
1166
                @Override
1167
                public void run() {
1168
                    showConsoleMessage(text);
1169
                }
1170
            });
1171
            return;
1172
        }
1173
        getConsolePanel().addText(text);
1174
    }
1175

    
1176
    @Override
1177
    public void cancelActiveService() {
1178
        this.textEntered(null);
1179
    }
1180
    
1181
    protected void selectedValue(Object value) {
1182
        EditingService activeService = getActiveService();
1183
        I18nManager i18nManager = ToolsLocator.getI18nManager();
1184
        
1185
        try {
1186
            activeService.setValue(value);
1187
        } catch (InvalidEntryException ex) {
1188
            showConsoleMessage("\n"
1189
                    + i18nManager.getTranslation("invalid_option"));
1190
        }
1191

    
1192
        activeService = getActiveService();
1193
        if (activeService != null) {
1194
            nextParameter();
1195
        } else {
1196
            cleanEditingContext();
1197
        }
1198

    
1199
    }
1200
    
1201
    protected void textEntered(String response) {
1202
        FeatureStore featureStore = getCurrentLayer().getFeatureStore();
1203
        EditingService activeService = getActiveService();
1204
        if (response == null) {
1205
            if (activeService != null) {
1206
                try {
1207
                    activeService.stop();
1208
                    serviceStack.pop();
1209
                    if (serviceStack.isEmpty()) {
1210
                        featureStore
1211
                            .getFeatureSelection().deselectAll();
1212
                        changeSelectedTool(DEFAULT_TOOL);
1213
                    } else {
1214
                        changeSelectedTool(activeService.getName());
1215
                    }
1216

    
1217
                    refreshMenusAndToolBars();
1218
                    activeService = getActiveService();
1219
                    if (activeService != null) {
1220
                        nextParameter();
1221
                    } else {
1222
                        cleanEditingContext();
1223
                    }
1224

    
1225
                } catch (StopServiceException e) {
1226
                    LOGGER
1227
                        .info("Can't stop " + activeService.getName(), e);
1228
                } catch (DataException e) {
1229
                    LOGGER.info("Can't get selection of "
1230
                        + featureStore.getFullName(), e);
1231
                }
1232
            }
1233
        } else {
1234

    
1235
            I18nManager i18nManager = ToolsLocator.getI18nManager();
1236
            if (getCurrentParam() != null) {
1237
                try {
1238
                    Object coercedValue = coerceInputParameter(getCurrentParam(), response);
1239
                    activeService.setValue(coercedValue);
1240
                } catch (InvalidEntryException ex) {
1241
                    showConsoleMessage("\n"
1242
                            + i18nManager.getTranslation("invalid_option"));
1243
                }
1244
            }
1245

    
1246
            activeService = getActiveService();
1247
            if (activeService != null) {
1248
                nextParameter();
1249
            } else {
1250
                cleanEditingContext();
1251
            }
1252
        }
1253
    }
1254
    
1255
    private Object coerceInputParameter(EditingServiceParameter parameter, String input) throws InvalidEntryException {
1256
        if (parameter != null) {
1257
            FeatureStore featureStore = getCurrentLayer().getFeatureStore();
1258
            Set<TYPE> types = parameter.getTypes();
1259
            Point point = null;
1260
            Double value = null;
1261
            Point defaultPoint = null;
1262
            Object defaultValue = parameter.getDefaultValue();
1263

    
1264
            boolean insertedValue = false;
1265
            if ((!insertedValue && types.contains(TYPE.POSITION))
1266
                    || types.contains(TYPE.LIST_POSITIONS)) {
1267

    
1268
                defaultPoint = (Point) defaultValue;
1269
                try {
1270
                    if (StringUtils.isEmpty(input.replace("\n", ""))) {
1271
                        point = defaultPoint;
1272
                    } else {
1273
                        point = parsePoint(input);
1274
                    }
1275

    
1276
                    if (point != null) {
1277
                        return point;
1278
                    }
1279

    
1280
                } catch (ParsePointException e) {
1281
                    // Do nothing to try other types
1282
                }
1283
            }
1284
            if (types.contains(TYPE.VALUE)) {
1285

    
1286
                try {
1287
                    value = parseValue(input);
1288
                    if (value != null) {
1289
                        return value;
1290
                    }
1291

    
1292
                } catch (ParseValueException e) {
1293
                    // Do nothing to try other types
1294
                }
1295

    
1296
            }
1297
            if (types.contains(TYPE.OPTION)) {
1298
                input = input.replace("\n", "");
1299
                return input;
1300
            }
1301

    
1302
            if (!insertedValue && types.contains(TYPE.SELECTION)) {
1303
                if (input.equalsIgnoreCase("\n")) {
1304
                    enableSelection(false);
1305
                    insertedValue = true;
1306

    
1307
                    FeatureSelection clonedSelection;
1308
                    try {
1309
                        clonedSelection = (FeatureSelection) featureStore
1310
                                .getFeatureSelection().clone();
1311
                        if (clonedSelection.isEmpty()) {
1312
                            throw new InvalidEntryException(null);
1313
                        }
1314
                    } catch (InvalidEntryException e) {
1315
                        throw e;
1316
                    } catch (Exception e) {
1317
                        LOGGER.warn("Can't access to selection.", e);
1318
                        throw new InvalidEntryException(e);
1319
//                        cleanEditingContext();
1320
//                        return null;
1321
                    }
1322
                    
1323
                    return clonedSelection;
1324
                }
1325
            }
1326
        }
1327
        return null;
1328
    }
1329

    
1330
    @Override
1331
    public void setDefaultBehaviors(Behavior[] defaultBehaviors) {
1332
        this.defaultBehaviors = defaultBehaviors;
1333
        try {
1334
            addBehaviors(defaultBehaviors);
1335
        } catch (CreateEditingBehaviorException e1) {
1336
            LOGGER.info("Problems adding behaviors to editing context", e1);
1337
            getMapControl().setTool("pan");
1338
        }
1339
    }
1340

    
1341
    @Override
1342
    public Behavior[] getDefaultBehaviors() {
1343
        return this.defaultBehaviors;
1344
    }
1345

    
1346
    @Override
1347
    public void setValue(EditingServiceParameter parameter, Object value) throws InvalidEntryException {
1348
        if( value instanceof CharSequence){
1349
            value = coerceInputParameter(parameter, value.toString());
1350
        } else if( value instanceof Point) {
1351
            contextSymbolTable.addPoint((Point) value);
1352
        }
1353
        getActiveService().setValue(parameter, value);
1354
//        nextParameter();
1355
    }
1356

    
1357
    public GeometryType getGeometryType() {
1358
        if( this.currentLayer==null ) {
1359
            return null;
1360
        }
1361
        FeatureStore store = this.currentLayer.getFeatureStore();
1362
        if( store == null ) {
1363
            return null;
1364
        }
1365
        FeatureType ftype = store.getDefaultFeatureTypeQuietly();
1366
        if( ftype == null ) {
1367
            return null;
1368
        }
1369
        FeatureAttributeDescriptor geomattr = ftype.getDefaultGeometryAttribute();
1370
        if( geomattr == null ) {
1371
            return null;
1372
        }
1373
        return geomattr.getGeomType();
1374
    }    
1375
    
1376
}