Statistics
| Revision:

root / branches / v2_0_0_prep / libraries / libFMap_dal / src / org / gvsig / fmap / dal / feature / impl / DefaultFeatureStore.java @ 27234

History | View | Annotate | Download (40.1 KB)

1
package org.gvsig.fmap.dal.feature.impl;
2

    
3
import java.util.ArrayList;
4
import java.util.Collections;
5
import java.util.Iterator;
6
import java.util.List;
7
import java.util.Set;
8

    
9
import org.cresques.cts.IProjection;
10
import org.gvsig.fmap.dal.DALLocator;
11
import org.gvsig.fmap.dal.DataManager;
12
import org.gvsig.fmap.dal.DataQuery;
13
import org.gvsig.fmap.dal.DataServerExplorer;
14
import org.gvsig.fmap.dal.DataSet;
15
import org.gvsig.fmap.dal.DataStore;
16
import org.gvsig.fmap.dal.DataStoreNotification;
17
import org.gvsig.fmap.dal.DataStoreParameters;
18
import org.gvsig.fmap.dal.exception.CloseException;
19
import org.gvsig.fmap.dal.exception.DataException;
20
import org.gvsig.fmap.dal.exception.InitializeException;
21
import org.gvsig.fmap.dal.exception.OpenException;
22
import org.gvsig.fmap.dal.exception.ProviderNotRegisteredException;
23
import org.gvsig.fmap.dal.exception.ReadException;
24
import org.gvsig.fmap.dal.feature.EditableFeature;
25
import org.gvsig.fmap.dal.feature.EditableFeatureType;
26
import org.gvsig.fmap.dal.feature.Feature;
27
import org.gvsig.fmap.dal.feature.FeatureIndex;
28
import org.gvsig.fmap.dal.feature.FeatureIndexes;
29
import org.gvsig.fmap.dal.feature.FeatureLocks;
30
import org.gvsig.fmap.dal.feature.FeatureQuery;
31
import org.gvsig.fmap.dal.feature.FeatureReference;
32
import org.gvsig.fmap.dal.feature.FeatureSelection;
33
import org.gvsig.fmap.dal.feature.FeatureSet;
34
import org.gvsig.fmap.dal.feature.FeatureStore;
35
import org.gvsig.fmap.dal.feature.FeatureStoreNotification;
36
import org.gvsig.fmap.dal.feature.FeatureStoreTransforms;
37
import org.gvsig.fmap.dal.feature.FeatureType;
38
import org.gvsig.fmap.dal.feature.NewFeatureStoreParameters;
39
import org.gvsig.fmap.dal.feature.exception.AlreadyEditingException;
40
import org.gvsig.fmap.dal.feature.exception.ConcurrentDataModificationException;
41
import org.gvsig.fmap.dal.feature.exception.CreateFeatureException;
42
import org.gvsig.fmap.dal.feature.exception.DataExportException;
43
import org.gvsig.fmap.dal.feature.exception.FeatureIndexException;
44
import org.gvsig.fmap.dal.feature.exception.FinishEditingException;
45
import org.gvsig.fmap.dal.feature.exception.GetFeatureTypeException;
46
import org.gvsig.fmap.dal.feature.exception.IllegalFeatureException;
47
import org.gvsig.fmap.dal.feature.exception.IllegalFeatureTypeException;
48
import org.gvsig.fmap.dal.feature.exception.NeedEditingModeException;
49
import org.gvsig.fmap.dal.feature.exception.NoNewFeatureInsertException;
50
import org.gvsig.fmap.dal.feature.exception.NullFeatureTypeException;
51
import org.gvsig.fmap.dal.feature.exception.SelectionNotAllowedException;
52
import org.gvsig.fmap.dal.feature.exception.StoreCancelEditingException;
53
import org.gvsig.fmap.dal.feature.exception.StoreDeleteEditableFeatureException;
54
import org.gvsig.fmap.dal.feature.exception.StoreDeleteFeatureException;
55
import org.gvsig.fmap.dal.feature.exception.StoreEditException;
56
import org.gvsig.fmap.dal.feature.exception.StoreInsertFeatureException;
57
import org.gvsig.fmap.dal.feature.exception.StoreUpdateFeatureException;
58
import org.gvsig.fmap.dal.feature.exception.StoreUpdateFeatureTypeException;
59
import org.gvsig.fmap.dal.feature.exception.ValidateFeaturesException;
60
import org.gvsig.fmap.dal.feature.exception.WriteNotAllowedException;
61
import org.gvsig.fmap.dal.feature.impl.expansionadapter.MemoryExpansionAdapter;
62
import org.gvsig.fmap.dal.feature.impl.featureset.DefaultFeatureSet;
63
import org.gvsig.fmap.dal.feature.impl.undo.DefaultFeatureCommandsStack;
64
import org.gvsig.fmap.dal.feature.impl.undo.FeatureCommandsStack;
65
import org.gvsig.fmap.dal.feature.spi.DefaultFeatureData;
66
import org.gvsig.fmap.dal.feature.spi.FeatureData;
67
import org.gvsig.fmap.dal.feature.spi.FeatureReferenceProviderServices;
68
import org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider;
69
import org.gvsig.fmap.dal.feature.spi.FeatureStoreProviderServices;
70
import org.gvsig.fmap.dal.feature.spi.index.FeatureIndexProviderServices;
71
import org.gvsig.fmap.dal.impl.DefaultDataManager;
72
import org.gvsig.fmap.dal.resource.Resource;
73
import org.gvsig.fmap.geom.primitive.Envelope;
74
import org.gvsig.tools.ToolsLocator;
75
import org.gvsig.tools.dynobject.DelegatedDynObject;
76
import org.gvsig.tools.dynobject.DynClass;
77
import org.gvsig.tools.dynobject.DynObject;
78
import org.gvsig.tools.dynobject.DynObjectManager;
79
import org.gvsig.tools.dynobject.exception.DynFieldNotFoundException;
80
import org.gvsig.tools.dynobject.exception.DynMethodException;
81
import org.gvsig.tools.exception.NotYetImplemented;
82
import org.gvsig.tools.observer.Observable;
83
import org.gvsig.tools.observer.Observer;
84
import org.gvsig.tools.observer.impl.DelegateWeakReferencingObservable;
85
import org.gvsig.tools.persistence.AbstractPersistenceManager;
86
import org.gvsig.tools.persistence.PersistenceException;
87
import org.gvsig.tools.persistence.PersistenceValueNotFoundException;
88
import org.gvsig.tools.persistence.PersistentState;
89
import org.gvsig.tools.task.Executor;
90
import org.gvsig.tools.undo.RedoException;
91
import org.gvsig.tools.undo.UndoException;
92
import org.gvsig.tools.undo.command.Command;
93
import org.slf4j.Logger;
94
import org.slf4j.LoggerFactory;
95

    
96
final public class DefaultFeatureStore implements
97
FeatureStoreProviderServices,
98
Observer {
99

    
100
        final static private Logger logger = LoggerFactory
101
        .getLogger(DefaultFeatureStore.class);
102

    
103
        private DataStoreParameters parameters = null;
104
        private FeatureSelection selection;
105
        private FeatureLocks locks;
106

    
107
        private DelegateWeakReferencingObservable delegateObservable = new DelegateWeakReferencingObservable(this);
108

    
109
        private FeatureCommandsStack commands;
110
        private FeatureTypeManager featureTypeManager;
111
        private FeatureManager featureManager;
112
        private SpatialManager spatialManager;
113

    
114
        private FeatureType defaultFeatureType = null;
115
        private List featureTypes = new ArrayList();
116

    
117
        private int mode = MODE_QUERY;
118
        private long versionOfUpdate = 0;
119
        private boolean hasStrongChanges = true;
120

    
121
        private DefaultDataManager dataManager = null;
122

    
123
        private FeatureStoreProvider provider = null;
124

    
125
        private DefaultFeatureIndexes indexes;
126

    
127
        private DefaultFeatureStoreTransforms transforms;
128

    
129
        private DelegatedDynObject dynObject;
130

    
131
        /*
132
         * TODO:
133
         *
134
         * - Comprobar que solo se pueden a�adir reglas de validacion sobre un
135
         * EditableFeatureType. - Comprobar que solo se puede hacer un update con un
136
         * featureType al que se le han cambiado las reglas de validacion cuando
137
         * hasStrongChanges=false.
138
         */
139

    
140
        public DefaultFeatureStore() {
141

    
142
        }
143

    
144
        public DefaultFeatureStore(DefaultDataManager manager,
145
                        DataStoreParameters parameters, FeatureStoreProvider provider)
146
        throws InitializeException {
147
                initialize(manager, parameters, provider);
148
        }
149

    
150
        private void initialize(DefaultDataManager manager,
151
                        DataStoreParameters parameters, FeatureStoreProvider provider)
152
        throws InitializeException {
153

    
154
                DynObjectManager dynManager = ToolsLocator.getDynObjectManager();
155

    
156
                this.dynObject = (DelegatedDynObject) dynManager
157
                .createDynObject(dynManager
158
                                .get(DataStore.DYNCLASS_NAME));
159
                this.dataManager = manager;
160
                this.provider = provider;
161
                this.parameters = parameters;
162
                this.transforms = new DefaultFeatureStoreTransforms(this);
163
                this.provider.initialize(this);
164
                try {
165
                        indexes=new DefaultFeatureIndexes(this);
166
                } catch (DataException e) {
167
                        throw new InitializeException(e);
168
                }
169
                this.delegate(provider);
170
        }
171

    
172
        public Logger getLogger() {
173
                return DefaultFeatureStore.logger;
174
        }
175

    
176
        public String getName() {
177
                return this.parameters.getDataStoreName();
178
        }
179

    
180
        public DataStoreParameters getParameters() {
181
                return parameters;
182
        }
183

    
184
        public int getMode() {
185
                return this.mode;
186
        }
187

    
188
        public DefaultDataManager getManager() {
189
                return this.dataManager;
190
        }
191

    
192
        public Iterator getChildren() {
193
                return this.provider.getChilds();
194
        }
195

    
196
        public FeatureStoreProvider getProvider() {
197
                return this.provider;
198
        }
199

    
200
        public FeatureManager getFeatureManager() {
201
                return this.featureManager;
202
        }
203

    
204
        public void setFeatureTypes(List types, FeatureType defaultType) {
205
                this.featureTypes = types;
206
                this.defaultFeatureType = defaultType;
207
        }
208

    
209
        public void open() throws OpenException {
210
                // TODO: Se puede hacer un open estando en edicion ?
211
                this.notifyChange(FeatureStoreNotification.BEFORE_OPEN);
212
                this.provider.open();
213
                this.notifyChange(FeatureStoreNotification.AFTER_OPEN);
214
        }
215

    
216
        public void refresh() throws OpenException, InitializeException {
217
                if (this.mode != MODE_QUERY) {
218
                        throw new IllegalStateException();
219
                }
220
                this.notifyChange(FeatureStoreNotification.BEFORE_REFRESH);
221
                this.provider.refresh();
222
                this.notifyChange(FeatureStoreNotification.AFTER_REFRESH);
223
        }
224

    
225
        public void close() throws CloseException {
226
                // TODO: Se puede hacer un close estando en edicion ?
227
                this.notifyChange(FeatureStoreNotification.BEFORE_CLOSE);
228
                this.provider.close();
229
                this.notifyChange(FeatureStoreNotification.AFTER_CLOSE);
230
        }
231

    
232
        public void dispose() throws CloseException {
233
                this.notifyChange(FeatureStoreNotification.BEFORE_DISPOSE);
234
                this.provider.dispose();
235
                if (this.selection != null) {
236
                        this.selection.dispose();
237
                        this.selection = null;
238
                }
239
                this.commands = null;
240

    
241
                if (this.locks != null) {
242
                        //this.locks.dispose();
243
                        this.locks = null;
244
                }
245

    
246
                if (this.featureTypeManager != null) {
247
                        this.featureTypeManager.dispose();
248
                        this.featureTypeManager = null;
249
                }
250

    
251
                this.featureManager = null;
252
                this.spatialManager = null;
253

    
254
                this.parameters = null;
255
                this.notifyChange(FeatureStoreNotification.AFTER_DISPOSE);
256
                this.delegateObservable.deleteObservers();
257
                this.delegateObservable = null;
258
        }
259

    
260
        public boolean allowWrite() {
261
                return this.provider.allowWrite();
262
        }
263

    
264
        public boolean canWriteGeometry(int geometryType) throws DataException {
265
                return this.provider.canWriteGeometry(geometryType);
266
        }
267

    
268
        public DataServerExplorer getExplorer() throws ReadException {
269
                return this.provider.getExplorer();
270
        }
271

    
272
        /*
273
        public Metadata getMetadata() throws MetadataNotFoundException {
274
                // TODO:
275
                // Si el provider devuelbe null habria que ver de construir aqui
276
                // los metadatos basicos, como el Envelope y el SRS.
277

278
                // TODO: Estando en edicion el Envelope deberia de
279
                // actualizarse usando el spatialManager
280
                return this.provider.getMetadata();
281
        }
282
         */
283

    
284
        public Envelope getEnvelope() throws DataException {
285
                if (this.mode == MODE_FULLEDIT) {
286
                        return this.spatialManager.getEnvelope();
287
                }
288
                return this.provider.getEnvelope();
289
        }
290

    
291
        /**
292
         * @deprecated use getDefaultFeatureType().getDefaultSRS()
293
         */
294
        public IProjection getSRSDefaultGeometry() throws DataException {
295
                return this.getDefaultFeatureType().getDefaultSRS();
296
        }
297

    
298
        public FeatureSelection createDefaultFeatureSelection()
299
        throws DataException {
300
                return new DefaultFeatureSelection(this);
301
        }
302

    
303
        public FeatureData createDefaultFeatureData(FeatureType type)
304
        throws DataException {
305
                if( type.hasOID() ) {
306
                        return new DefaultFeatureData(type, this.provider.createNewOID());
307
                }
308
                return new DefaultFeatureData(type);
309
        }
310
        public PersistentState getState()
311
        throws PersistenceException {
312
                return AbstractPersistenceManager.getState(this);
313
        }
314

    
315
        public void loadState(PersistentState state) throws PersistenceException {
316
                state.setTheClass(this);
317
                state.set("dataStoreName", this.getName());
318
                state.set("parameters", this.parameters);
319
                state.set("provider", this.provider);
320
                if (this.selection != null) {
321
                        state.set("selection", this.selection);
322
                }
323
        }
324

    
325
        public void setState(PersistentState state) throws PersistenceException {
326
                if (this.provider != null) {
327
                        throw new PersistenceException(null);
328
                }
329
                if (this.getManager() == null) {
330
                        this.dataManager = (DefaultDataManager) DALLocator.getDataManager();
331
                }
332

    
333
                DataStoreParameters params = (DataStoreParameters) state.get("parameters");
334
                FeatureStoreProvider provider = (FeatureStoreProvider) state.get("provider");
335

    
336
                try {
337

    
338
                        initialize(this.getManager(), params, provider);
339
                        try {
340
                                setSelection((FeatureSelection) state.get("selection"));
341
                        } catch (PersistenceValueNotFoundException e) {
342
                                setSelection(null);
343
                        }
344

    
345
                } catch (InitializeException e) {
346
                        throw new PersistenceException(e);
347
                } catch (DataException e) {
348
                        throw new PersistenceException(e);
349
                }
350

    
351
        }
352

    
353
        //
354
        // ====================================================================
355
        // Gestion de la seleccion
356
        //
357

    
358
        public void setSelection(DataSet selection)
359
        throws DataException {
360
                this.setSelection((FeatureSet) selection);
361
        }
362

    
363
        public DataSet createSelection() throws DataException {
364
                return createFeatureSelection();
365
        }
366

    
367
        public DataSet getSelection() throws DataException {
368
                return this.getFeatureSelection();
369
        }
370

    
371
    public void setSelection(FeatureSet selection) throws DataException {
372
        setSelection(selection, true);
373
    }
374

    
375
    /**
376
     * @see #setSelection(FeatureSet)
377
     * @param undoable
378
     *            if the action must be undoable
379
     */
380
    public void setSelection(FeatureSet selection, boolean undoable)
381
        throws DataException {
382
                if (selection.equals(this.selection)) {
383
                        return;
384
                }
385
                if (!selection.isFromStore(this)) {
386
                        throw new SelectionNotAllowedException(getName());
387
                }
388

    
389
                this.selection.deleteObserver(this);
390
                if (selection instanceof FeatureSelection) {
391
                        if (undoable && isEditing()) {
392
                                commands.selectionSet(this, this.selection,
393
                                                (FeatureSelection) selection);
394
                        }
395
                        this.selection = (FeatureSelection) selection;
396
                } else {
397
                        if (undoable && isEditing()) {
398
                                commands.startComplex("_selectionSet");
399
                        }
400
                        if (selection instanceof DefaultFeatureSelection) {
401
                DefaultFeatureSelection defSelection = (DefaultFeatureSelection) selection;
402
                defSelection.deselectAll(undoable);
403
                defSelection.select(selection, undoable);
404
            } else {
405
                this.selection.deselectAll();
406
                this.selection.select(selection);
407
            }
408
                        if (undoable && isEditing()) {
409
                                commands.endComplex();
410
                        }
411
                }
412
                this.selection.addObserver(this);
413

    
414
                this.notifyChange(DataStoreNotification.SELECTION_CHANGE);
415
        }
416

    
417
        public FeatureSelection createFeatureSelection() throws DataException {
418
                return this.provider.createFeatureSelection();
419
        }
420

    
421
        public FeatureSelection getFeatureSelection() throws DataException {
422
                if (selection == null) {
423
                        this.selection = createFeatureSelection();
424
                        this.selection.addObserver(this);
425
                }
426
                return selection;
427
        }
428

    
429
        //
430
        // ====================================================================
431
        // Gestion de notificaciones
432
        //
433

    
434
        public void notifyChange(String notification) {
435
                delegateObservable.notifyObservers(new DefaultFeatureStoreNotification(this,
436
                                notification));
437

    
438
        }
439

    
440
        public void notifyChange(String notification, Feature feature) {
441
                delegateObservable.notifyObservers(new DefaultFeatureStoreNotification(
442
                                this, notification, feature));
443
        }
444

    
445
        public void notifyChange(String notification, Command command) {
446
                delegateObservable.notifyObservers(new DefaultFeatureStoreNotification(
447
                                this, notification, command));
448
        }
449

    
450
        public void notifyChange(String notification, EditableFeatureType type) {
451
                delegateObservable.notifyObservers(new DefaultFeatureStoreNotification(this,
452
                                notification, type));
453
        }
454

    
455
        /*
456
         * (non-Javadoc)
457
         *
458
         * @see
459
         * org.gvsig.fmap.dal.feature.spi.FeatureStoreProviderServices#notifyChange
460
         * (java.lang.String, org.gvsig.fmap.dal.resource.Resource)
461
         */
462
        public void notifyChange(String notification, Resource resource) {
463
                delegateObservable.notifyObservers(new DefaultFeatureStoreNotification(this,
464
                                FeatureStoreNotification.RESOURCE_CHANGED));
465
        }
466

    
467

    
468
        //
469
        // ====================================================================
470
        // Gestion de bloqueos
471
        //
472

    
473
        public boolean isLocksSupported() {
474
                return this.provider.isLocksSupported();
475
        }
476

    
477
        public FeatureLocks getLocks() throws DataException {
478
                if (!this.provider.isLocksSupported()) {
479
                        getLogger().warn("Locks not supporteds");
480
                        return null;
481
                }
482
                if (locks == null) {
483
                        this.locks = this.provider.createFeatureLocks();
484
                }
485
                return locks;
486
        }
487

    
488
        //
489
        // ====================================================================
490
        // Interface Observable
491
        //
492

    
493
        public void disableNotifications() {
494
                this.delegateObservable.disableNotifications();
495

    
496
        }
497

    
498
        public void enableNotifications() {
499
                this.delegateObservable.enableNotifications();
500
        }
501

    
502
        public void beginComplexNotification() {
503
                this.delegateObservable.beginComplexNotification();
504

    
505
        }
506

    
507
        public void endComplexNotification() {
508
                this.delegateObservable.endComplexNotification();
509

    
510
        }
511

    
512
        public void addObserver(Observer observer) {
513
                this.delegateObservable.addObserver(observer);
514

    
515
        }
516

    
517
        public void deleteObserver(Observer observer) {
518
                this.delegateObservable.deleteObserver(observer);
519
        }
520

    
521
        public void deleteObservers() {
522
                this.delegateObservable.deleteObservers();
523

    
524
        }
525

    
526
        //
527
        // ====================================================================
528
        // Interface Observer
529
        //
530
        // Usado para observar:
531
        // - su seleccion
532
        // - sus bloqueos
533
        // - sus recursos
534
        //
535

    
536
        public void update(Observable observable, Object notification) {
537
                if (observable instanceof FeatureSet) {
538
                        if (observable == this.selection) {
539
                                this.notifyChange(FeatureStoreNotification.SELECTION_CHANGE);
540
                        } else if (observable == this.locks) {
541
                                this.notifyChange(FeatureStoreNotification.LOCKS_CHANGE);
542
                        }
543

    
544
                } else if (observable instanceof FeatureStoreProvider) {
545
                        if (observable == this.provider) {
546

    
547
                        }
548

    
549
                }
550
        }
551

    
552
        //
553
        // ====================================================================
554
        // Edicion
555
        //
556

    
557
        private void newVersionOfUpdate() {
558
                this.versionOfUpdate++;
559
        }
560

    
561
        private long currentVersionOfUpdate() {
562
                return this.versionOfUpdate;
563
        }
564

    
565
        private void checkInEditingMode()
566
        throws NeedEditingModeException {
567
                if (mode != MODE_FULLEDIT) {
568
                        throw new NeedEditingModeException(this.getName());
569
                }
570
        }
571

    
572
        private void checkNotInAppendMode() throws IllegalStateException {
573
                if (mode == MODE_APPEND) {
574
                        throw new IllegalStateException(this.getName());
575
                }
576
        }
577

    
578
        private void checkIsOwnFeature(Feature feature)
579
        throws IllegalFeatureException {
580
                if (((DefaultFeature) feature).getStore() != this) {
581
                        throw new IllegalFeatureException(this.getName());
582
                }
583
                // FIXME: fixFeatureType no vale para el checkIsOwnFeature
584
                // fixFeatureType((DefaultFeatureType) feature.getType());
585
        }
586

    
587
        private void exitEditingMode() {
588
                if (commands != null) {
589
                        commands.clear();
590
                        commands = null;
591
                }
592

    
593
                if (featureTypeManager != null) {
594
                        featureTypeManager.dispose();
595
                        featureTypeManager = null;
596

    
597
                }
598

    
599
                // TODO implementar un dispose para estos dos
600
                featureManager = null;
601
                spatialManager = null;
602

    
603
                mode = MODE_QUERY;
604
                hasStrongChanges = true; // Lo deja a true por si las moscas
605
        }
606

    
607
        synchronized public void edit() throws DataException {
608
                edit(MODE_FULLEDIT);
609
        }
610

    
611
        synchronized public void edit(int mode) throws DataException {
612
                try {
613
                        if ( this.mode != MODE_QUERY ) {
614
                                throw new AlreadyEditingException(this.getName());
615
                        }
616
                        if (!this.provider.supportsAppendMode()) {
617
                                mode = MODE_FULLEDIT;
618
                        }
619
                        switch (mode) {
620
                        case MODE_QUERY:
621
                                throw new IllegalStateException(this.getName());
622

    
623
                        case MODE_FULLEDIT:
624
                                if (!this.transforms.isEmpty()) {
625
                                        throw new IllegalStateException(this.getName());
626
                                }
627
                                notifyChange(FeatureStoreNotification.BEFORE_STARTEDITING);
628
                                featureManager = new FeatureManager(new MemoryExpansionAdapter());
629
                                featureTypeManager = new FeatureTypeManager(this,
630
                                                new MemoryExpansionAdapter());
631
                                spatialManager = new SpatialManager(this);
632

    
633
                                commands = new DefaultFeatureCommandsStack(featureManager,
634
                                                spatialManager, featureTypeManager);
635
                                this.mode = MODE_FULLEDIT;
636
                                hasStrongChanges = false;
637
                                notifyChange(FeatureStoreNotification.AFTER_STARTEDITING);
638
                                break;
639
                        case MODE_APPEND:
640
                                if (!this.transforms.isEmpty()) {
641
                                        throw new IllegalStateException(this.getName());
642
                                }
643
                                notifyChange(FeatureStoreNotification.BEFORE_STARTEDITING);
644
                                this.provider.beginAppend();
645
                                this.mode = MODE_APPEND;
646
                                notifyChange(FeatureStoreNotification.AFTER_STARTEDITING);
647
                                break;
648
                        }
649
                } catch (Exception e) {
650
                        throw new StoreEditException(e, this.getName());
651
                }
652
        }
653

    
654
        public boolean isEditing() {
655
                return mode == MODE_FULLEDIT;
656
        }
657

    
658
        public boolean isAppending() {
659
                return mode == MODE_APPEND;
660
        }
661

    
662
        synchronized public void update(EditableFeatureType type)
663
        throws DataException {
664
                try {
665
                        checkInEditingMode();
666
                        if (type == null) {
667
                                throw new NullFeatureTypeException(getName());
668
                        }
669
                        // FIXME: Comprobar que es un featureType aceptable.
670
                        notifyChange(FeatureStoreNotification.BEFORE_UPDATE_TYPE, type);
671
                        newVersionOfUpdate();
672

    
673
                        FeatureType oldt = type.getSource().getCopy();
674
                        FeatureType newt = type.getNotEditableCopy();
675
                        commands.update(newt, oldt);
676

    
677
                        if (((DefaultEditableFeatureType) type).hasStrongChanges()) {
678
                                hasStrongChanges = true;
679
                        }
680
                        notifyChange(FeatureStoreNotification.AFTER_UPDATE_TYPE, type);
681
                } catch (Exception e) {
682
                        throw new StoreUpdateFeatureTypeException(e, this.getName());
683
                }
684
        }
685

    
686
        synchronized public void delete(Feature feature) throws DataException {
687
                try {
688
                        checkInEditingMode();
689
                        checkIsOwnFeature(feature);
690
                        if (feature instanceof EditableFeature) {
691
                                throw new StoreDeleteEditableFeatureException(getName());
692
                        }
693
                        notifyChange(FeatureStoreNotification.BEFORE_DELETE, feature);
694
                        this.commands.delete(feature);
695
                        newVersionOfUpdate();
696
                        hasStrongChanges = true;
697
                        notifyChange(FeatureStoreNotification.AFTER_DELETE, feature);
698
                } catch (Exception e) {
699
                        throw new StoreDeleteFeatureException(e, this.getName());
700
                }
701
        }
702

    
703
        private static EditableFeature lastChangedFeature = null;
704

    
705
        synchronized public void insert(EditableFeature feature)
706
        throws DataException {
707
                try {
708
                        switch (mode) {
709
                        case MODE_QUERY:
710
                                throw new NeedEditingModeException(this.getName());
711

    
712
                        case MODE_APPEND:
713
                                checkIsOwnFeature(feature);
714
                                if (feature.getSource() != null) {
715
                                        throw new NoNewFeatureInsertException(this.getName());
716
                                }
717
                                notifyChange(FeatureStoreNotification.BEFORE_INSERT, feature);
718
                                feature.validate(Feature.UPDATE);
719
                                provider.append(feature);
720
                                hasStrongChanges = true;
721
                                notifyChange(FeatureStoreNotification.AFTER_INSERT, feature);
722
                                break;
723

    
724
                        case MODE_FULLEDIT:
725
                                checkIsOwnFeature(feature);
726
                                if (feature.getSource() != null) {
727
                                        throw new NoNewFeatureInsertException(this.getName());
728
                                }
729
                                notifyChange(FeatureStoreNotification.BEFORE_INSERT, feature);
730
                                newVersionOfUpdate();
731
                                if (lastChangedFeature ==null || lastChangedFeature.getSource() != feature.getSource()) {
732
                                        lastChangedFeature = feature;
733
                                        feature.validate(Feature.UPDATE);
734
                                        lastChangedFeature = null;
735
                                }
736
                                commands.insert(feature.getNotEditableCopy());
737
                                hasStrongChanges = true;
738
                                notifyChange(FeatureStoreNotification.AFTER_INSERT, feature);
739
                                break;
740
                        }
741
                } catch (Exception e) {
742
                        throw new StoreInsertFeatureException(e, this.getName());
743
                }
744
        }
745

    
746
        synchronized public void update(EditableFeature feature)
747
        throws DataException {
748
                try {
749
                        if ((feature).getSource() == null) {
750
                                insert(feature);
751
                                return;
752
                        }
753
                        checkInEditingMode();
754
                        checkIsOwnFeature(feature);
755
                        notifyChange(FeatureStoreNotification.BEFORE_UPDATE, feature);
756
                        newVersionOfUpdate();
757
                        if (lastChangedFeature==null || lastChangedFeature.getSource() != feature.getSource()) {
758
                                lastChangedFeature = feature;
759
                                feature.validate(Feature.UPDATE);
760
                                lastChangedFeature = null;
761
                        }
762

    
763
                        Feature oldf = feature.getSource();
764
                        Feature newf = feature.getNotEditableCopy();
765
                        commands.update(newf, oldf);
766

    
767
                        hasStrongChanges = true;
768
                        notifyChange(FeatureStoreNotification.AFTER_UPDATE, feature);
769
                } catch (Exception e) {
770
                        throw new StoreUpdateFeatureException(e, this.getName());
771
                }
772
        }
773

    
774
        synchronized public void redo() throws RedoException {
775
                Command redo = commands.getNextRedoCommand();
776
                try {
777
                        checkInEditingMode();
778
                } catch (NeedEditingModeException ex) {
779
                        throw new RedoException(redo, ex);
780
                }
781
                notifyChange(FeatureStoreNotification.BEFORE_REDO, redo);
782
                newVersionOfUpdate();
783
                commands.redo();
784
                hasStrongChanges = true;
785
                notifyChange(FeatureStoreNotification.AFTER_REDO, redo);
786
        }
787

    
788
        synchronized public void undo() throws UndoException {
789
                Command undo = commands.getNextUndoCommand();
790
                try {
791
                        checkInEditingMode();
792
                } catch (NeedEditingModeException ex) {
793
                        throw new UndoException(undo, ex);
794
                }
795
                notifyChange(FeatureStoreNotification.BEFORE_UNDO, undo);
796
                newVersionOfUpdate();
797
                commands.undo();
798
                hasStrongChanges = true;
799
                notifyChange(FeatureStoreNotification.AFTER_UNDO, undo);
800
        }
801

    
802
        public List getRedoInfos() {
803
                if (isEditing() && commands != null) {
804
                        return commands.getRedoInfos();
805
                } else {
806
                        return null;
807
                }
808
        }
809

    
810
        public List getUndoInfos() {
811
                if (isEditing() && commands != null) {
812
                        return commands.getUndoInfos();
813
                } else {
814
                        return null;
815
                }
816
        }
817

    
818
        public synchronized FeatureCommandsStack getCommandsStack()
819
        throws DataException {
820
                checkInEditingMode();
821
                return commands;
822
        }
823

    
824
        synchronized public void cancelEditing() throws DataException {
825
                spatialManager.cancelModifies();
826
                try {
827
                        checkInEditingMode();
828
                        notifyChange(FeatureStoreNotification.BEFORE_CANCELEDITING);
829
                        exitEditingMode();
830
                        notifyChange(FeatureStoreNotification.AFTER_CANCELEDITING);
831
                } catch (Exception e) {
832
                        throw new StoreCancelEditingException(e, this.getName());
833
                }
834
        }
835

    
836
        synchronized public void finishEditing() throws DataException {
837
                try {
838
                        switch (mode) {
839
                        case MODE_QUERY:
840
                                throw new NeedEditingModeException(this.getName());
841

    
842
                        case MODE_APPEND:
843
                                notifyChange(FeatureStoreNotification.BEFORE_FINISHEDITING);
844
                                provider.endAppend();
845
                                exitEditingMode();
846
                                notifyChange(FeatureStoreNotification.AFTER_FINISHEDITING);
847
                                break;
848

    
849
                        case MODE_FULLEDIT:
850
                                if (!hasStrongChanges) {
851
                                        performLightEditing();
852
                                        return;
853
                                }
854
                                if (!this.allowWrite()) {
855
                                        throw new WriteNotAllowedException(getName());
856
                                }
857

    
858
                                notifyChange(FeatureStoreNotification.BEFORE_FINISHEDITING);
859
                                validateFeatures(Feature.FINISH_EDITING);
860
                                provider.performEditing(featureManager.getInserted(),
861
                                                featureManager.getUpdated(), featureManager
862
                                                .getDeleted());
863
                                exitEditingMode();
864
                                notifyChange(FeatureStoreNotification.AFTER_FINISHEDITING);
865
                                break;
866
                        }
867
                } catch (Exception e) {
868
                        throw new FinishEditingException(e);
869
                }
870
        }
871

    
872
        private void performLightEditing() throws DataException {
873
                throw new NotYetImplemented(
874
                "lightFinishEdition not yet implemented");
875

    
876
                // TODO: implementar
877
                // notifyChange(FeatureStoreNotification.BEFORE_FINISHEDITING);
878
                // exitEditingMode();
879
                // notifyChange(FeatureStoreNotification.AFTER_FINISHEDITING);
880
        }
881

    
882

    
883
        public void beginEditingGroup(String description)
884
        throws NeedEditingModeException {
885
                checkInEditingMode();
886
                commands.startComplex(description);
887
        }
888

    
889
        public void endEditingGroup() throws NeedEditingModeException {
890
                checkInEditingMode();
891
                commands.endComplex();
892
        }
893

    
894
        public boolean isAppendModeSupported() {
895
                return this.provider.supportsAppendMode();
896
        }
897

    
898

    
899
        public void export(DataServerExplorer explorer, NewFeatureStoreParameters params)
900
        throws DataException {
901

    
902
                if (this.getFeatureTypes().size() != 1) {
903
                        throw new NotYetImplemented(
904
                        "export whith more than one type not yet implemented");
905
                }
906
                FeatureSelection featureSelection=(FeatureSelection)getSelection();
907
                try {
908
                        FeatureType type = this.getDefaultFeatureType();
909
                        if (params.getDefaultFeatureType() == null
910
                                        || params.getDefaultFeatureType().size() == 0) {
911
                                params.setDefaultFeatureType(new DefaultEditableFeatureType(
912
                                                (DefaultFeatureType) type));
913

    
914
                        }
915
                        explorer.add(params, true);
916

    
917
                        DataManager manager = DALLocator.getDataManager();
918
                        FeatureStore target = (FeatureStore) manager
919
                        .createStore(params);
920
                        FeatureType targetType = target.getDefaultFeatureType();
921

    
922
                        target.edit(MODE_APPEND);
923
                        FeatureSet features=null;
924
                        if (featureSelection.getSize()>0){
925
                                features = this.getFeatureSelection();
926
                        }else{
927
                                features = this.getFeatureSet();
928
                        }
929
                        Iterator it1 = features.iterator();
930
                        while (it1.hasNext()) {
931
                                Feature feature = (Feature) it1.next();
932
                                target.insert(target.createNewFeature(targetType, feature));
933
                        }
934
                        features.dispose();
935
                        target.finishEditing();
936
                        target.dispose();
937
                } catch (Exception e) {
938
                        throw new DataExportException(e, params.toString());
939
                }
940
        }
941

    
942
        //
943
        // ====================================================================
944
        // Obtencion de datos
945
        // getDataCollection, getFeatureCollection
946
        //
947

    
948
        public DataSet getDataSet() throws DataException {
949
                checkNotInAppendMode();
950
                FeatureQuery query = new FeatureQuery(this.getDefaultFeatureType());
951
                return new DefaultFeatureSet(this, query);
952
        }
953

    
954
        public DataSet getDataSet(DataQuery dataQuery)
955
        throws DataException {
956
                checkNotInAppendMode();
957
                return new DefaultFeatureSet(this, (FeatureQuery) dataQuery);
958
        }
959

    
960
        public void getDataSet(Observer observer) throws DataException {
961
                checkNotInAppendMode();
962
                this.getFeatureSet(null, observer);
963
        }
964

    
965
        public void getDataSet(DataQuery dataQuery, Observer observer)
966
        throws DataException {
967
                checkNotInAppendMode();
968
                this.getFeatureSet((FeatureQuery) dataQuery, observer);
969
        }
970

    
971
        public FeatureSet getFeatureSet() throws DataException {
972
                checkNotInAppendMode();
973
                FeatureQuery query = new FeatureQuery(this.getDefaultFeatureType());
974
                return new DefaultFeatureSet(this, query);
975
        }
976

    
977
        public FeatureSet getFeatureSet(FeatureQuery featureQuery)
978
        throws DataException {
979
                checkNotInAppendMode();
980
                return new DefaultFeatureSet(this, featureQuery);
981
        }
982

    
983
        public FeatureType getFeatureType(FeatureQuery featureQuery)
984
                        throws DataException {
985
                DefaultFeatureType fType = (DefaultFeatureType) this
986
                                .getFeatureType(featureQuery.getFeatureTypeId());
987
                if (featureQuery.getAttributeNames() != null){
988
                        return fType.getSubtype(featureQuery.getAttributeNames());
989
                }
990
                return fType;
991
        }
992

    
993
        public void getFeatureSet(Observer observer)
994
        throws DataException {
995
                checkNotInAppendMode();
996
                this.getFeatureSet(null, observer);
997
        }
998

    
999
        public void getFeatureSet(FeatureQuery query, Observer observer)
1000
        throws DataException {
1001
                class LoadInBackGround implements Runnable {
1002
                        private FeatureStore store;
1003
                        private FeatureQuery query;
1004
                        private Observer observer;
1005
                        private Executor executor;
1006
                        private FeatureStoreNotification notification;
1007

    
1008
                        public LoadInBackGround(FeatureStore store, FeatureQuery query,
1009
                                        Observer observer, Executor executor) {
1010
                                this.store = store;
1011
                                this.query = query;
1012
                                this.observer = observer;
1013
                                this.executor = executor;
1014
                        }
1015

    
1016
                        void notify(FeatureStoreNotification theNotification) {
1017
                                if (executor == null) {
1018
                                        observer.update(store, theNotification);
1019
                                        return;
1020
                                }
1021
                                this.notification = theNotification;
1022
                                executor.execute(new Runnable() {
1023
                                        public void run() {
1024
                                                observer.update(store, notification);
1025
                                        }
1026
                                });
1027

    
1028
                        }
1029

    
1030
                        public void run() {
1031
                                try {
1032
                                        FeatureSet set = store.getFeatureSet(query);
1033
                                        notify(new DefaultFeatureStoreNotification(store,
1034
                                                        FeatureStoreNotification.LOAD_FINISHED, set));
1035
                                } catch (Exception e) {
1036
                                        notify(new DefaultFeatureStoreNotification(store,
1037
                                                        FeatureStoreNotification.LOAD_FINISHED, e));
1038
                                }
1039
                        }
1040
                }
1041

    
1042
                checkNotInAppendMode();
1043
                if (query == null) {
1044
                        query = new FeatureQuery(this.getDefaultFeatureType());
1045
                }
1046
                Executor executor = ToolsLocator.getTaskManager().getExecutor();
1047
                LoadInBackGround task = new LoadInBackGround(this, query, observer,
1048
                                executor);
1049
                Thread thread = new Thread(task);
1050
                thread.run();
1051
        }
1052

    
1053
        public Feature getFeatureByReference(FeatureReference reference) throws DataException {
1054
                checkNotInAppendMode();
1055
                return this.getFeatureByReference(reference, this.getDefaultFeatureType());
1056
        }
1057

    
1058
        public Feature getFeatureByReference(FeatureReference reference, FeatureType featureType)
1059
        throws DataException {
1060
                checkNotInAppendMode();
1061
                featureType = fixFeatureType((DefaultFeatureType) featureType);
1062
                if (!this.transforms.isEmpty()) {
1063

    
1064
                        featureType = this.transforms
1065
                        .getSourceFeatureTypeFrom(featureType);
1066

    
1067
                }
1068
                // TODO comprobar que el id es de este store
1069

    
1070
                if (this.mode == MODE_FULLEDIT) {
1071
                        Feature f = featureManager.get(reference, this, featureType);
1072
                        if (f!=null) {
1073
                                return f;
1074
                        }
1075
                }
1076
                DefaultFeature feature = new DefaultFeature(
1077
                                this,
1078
                                this.provider
1079
                                .getFeatureDataByReference(
1080
                                                (FeatureReferenceProviderServices) reference,
1081
                                                featureType));
1082

    
1083
                if (!this.transforms.isEmpty()) {
1084
                        return this.transforms.applyTransform(feature, featureType);
1085
                }
1086
                return feature;
1087
        }
1088

    
1089
        //
1090
        // ====================================================================
1091
        // Gestion de features
1092
        //
1093

    
1094
        private FeatureType fixFeatureType(DefaultFeatureType type)
1095
        throws DataException {
1096
                FeatureType defaultType = this.getDefaultFeatureType();
1097
                if (type == null || type.equals(defaultType)) {
1098
                        return defaultType;
1099
                }
1100
                if (type.isSubtypeOf(defaultType)) {
1101
                        return type;
1102
                }
1103
                Iterator iter = this.getFeatureTypes().iterator();
1104
                FeatureType tmpType;
1105
                while (iter.hasNext()) {
1106
                        tmpType = (FeatureType) iter.next();
1107
                        if (type.equals(tmpType) || type.isSubtypeOf(tmpType)) {
1108
                                return type;
1109
                        }
1110

    
1111
                }
1112
                throw new IllegalFeatureTypeException(getName());
1113
        }
1114

    
1115
        public void validateFeatures(int mode) throws DataException {
1116
                try {
1117
                        checkNotInAppendMode();
1118
                        FeatureSet collection = this.getFeatureSet();
1119
                        Iterator iter = collection.iterator();
1120
                        long previousVersionOfUpdate = currentVersionOfUpdate();
1121
                        while (iter.hasNext()) {
1122
                                ((DefaultFeature) iter.next()).validate(mode);
1123
                                if (previousVersionOfUpdate != currentVersionOfUpdate()) {
1124
                                        throw new ConcurrentDataModificationException(getName());
1125
                                }
1126
                        }
1127
                } catch (Exception e) {
1128
                        throw new ValidateFeaturesException(e, getName());
1129
                }
1130
        }
1131

    
1132
        public FeatureType getDefaultFeatureType() throws DataException {
1133
                try {
1134
                        if (isEditing()) {
1135
                                FeatureType auxFeatureType=featureTypeManager.getType(defaultFeatureType.getId());
1136
                                if (auxFeatureType!=null) {
1137
                                        return auxFeatureType;
1138
                                }
1139
                        }
1140
                        FeatureType type = this.transforms.getDefaultFeatureType();
1141
                        if (type != null) {
1142
                                return type;
1143
                        }
1144
                        return defaultFeatureType;
1145
                } catch (Exception e) {
1146
                        throw new GetFeatureTypeException(e, getName());
1147
                }
1148
        }
1149

    
1150
        public FeatureType getFeatureType(String featureTypeId)
1151
                        throws DataException {
1152
                if (featureTypeId == null) {
1153
                        return this.getDefaultFeatureType();
1154
                }
1155
                try {
1156
                        if (isEditing()) {
1157
                                FeatureType auxFeatureType = featureTypeManager
1158
                                                .getType(featureTypeId);
1159
                                if (auxFeatureType != null) {
1160
                                        return auxFeatureType;
1161
                                }
1162
                        }
1163
                        FeatureType type = this.transforms.getFeatureType(featureTypeId);
1164
                        if (type != null) {
1165
                                return type;
1166
                        }
1167
                        Iterator iter = this.featureTypes.iterator();
1168
                        while (iter.hasNext()){
1169
                                type = (FeatureType) iter.next();
1170
                                if (type.getId().equals(featureTypeId)) {
1171
                                        return type;
1172
                                }
1173
                        }
1174
                        return null;
1175
                } catch (Exception e) {
1176
                        throw new GetFeatureTypeException(e, getName());
1177
                }
1178
        }
1179

    
1180

    
1181
        public FeatureType getProviderDefaultFeatureType() {
1182
                return defaultFeatureType;
1183
        }
1184

    
1185
        public List getFeatureTypes() throws DataException {
1186
                try {
1187
                        List types;
1188
                        if (isEditing()) {
1189
                                types=new ArrayList();
1190
                                Iterator it=featureTypes.iterator();
1191
                                while (it.hasNext()) {
1192
                                        FeatureType type = (FeatureType) it.next();
1193
                                        FeatureType typeaux = featureTypeManager.getType(type.getId());
1194
                                        if (typeaux!=null) {
1195
                                                types.add(typeaux);
1196
                                        }else{
1197
                                                types.add(type);
1198
                                        }
1199
                                }
1200
                                it = featureTypeManager.newsIterator();
1201
                                while (it.hasNext()) {
1202
                                        FeatureType type = (FeatureType) it.next();
1203
                                        types.add(type);
1204
                                }
1205
                        } else {
1206
                                types = this.transforms.getFeatureTypes();
1207
                                if (types == null) {
1208
                                        types = featureTypes;
1209
                                }
1210
                        }
1211
                        return Collections.unmodifiableList(types);
1212
                } catch (Exception e) {
1213
                        throw new GetFeatureTypeException(e, getName());
1214
                }
1215
        }
1216

    
1217
        public List getProviderFeatureTypes() throws DataException {
1218
                return Collections.unmodifiableList(this.featureTypes);
1219
        }
1220

    
1221
        public Feature createFeature(FeatureData data)
1222
        throws DataException {
1223
                DefaultFeature feature = new DefaultFeature(this, data);
1224
                return feature;
1225
        }
1226

    
1227
        public Feature createFeature(FeatureData data, FeatureType type)
1228
        throws DataException {
1229
                // FIXME: falta por implementar
1230
                // Comprobar si es un subtipo del feature de data
1231
                // y construir un feature usando el subtipo.
1232
                // Probablemente requiera generar una copia del data.
1233
                throw new NotYetImplemented();
1234
        }
1235

    
1236
        public EditableFeature createNewFeature(FeatureType type,
1237
                        Feature defaultValues)
1238
        throws DataException {
1239
                try {
1240
                        type = this.fixFeatureType((DefaultFeatureType) type);
1241
                        FeatureData data = this.provider.createFeatureData(type);
1242
                        data.setNew(true);
1243
                        if (type.hasOID() && data.getOID() == null) {
1244
                                data.setOID(this.provider.createNewOID());
1245
                        }
1246
                        DefaultEditableFeature feature = new DefaultEditableFeature(this, data);
1247
                        feature.initializeValues(defaultValues);
1248
                        return feature;
1249
                } catch (Exception e) {
1250
                        throw new CreateFeatureException(e, getName());
1251
                }
1252
        }
1253

    
1254
        public EditableFeature createNewFeature(FeatureType type,
1255
                        boolean defaultValues)
1256
        throws DataException {
1257
                try {
1258
                        type = this.fixFeatureType((DefaultFeatureType) type);
1259
                        FeatureData data = this.provider.createFeatureData(type);
1260
                        data.setNew(true);
1261
                        if (type.hasOID() && data.getOID() == null) {
1262
                                data.setOID(this.provider.createNewOID());
1263
                        }
1264
                        DefaultEditableFeature feature = new DefaultEditableFeature(this, data);
1265
                        if (defaultValues) {
1266
                                feature.initializeValues();
1267
                        }
1268
                        return feature;
1269
                } catch (Exception e) {
1270
                        throw new CreateFeatureException(e, getName());
1271
                }
1272
        }
1273

    
1274
        public EditableFeature createNewFeature(boolean defaultValues)
1275
        throws DataException {
1276
                return this.createNewFeature(this.getDefaultFeatureType(), defaultValues);
1277
        }
1278

    
1279
        public EditableFeature createNewFeature() throws DataException {
1280
                return this.createNewFeature(this.getDefaultFeatureType(), true);
1281
        }
1282

    
1283
        public EditableFeatureType createFeatureType() {
1284
                return new DefaultEditableFeatureType();
1285
        }
1286

    
1287
        //
1288
        // ====================================================================
1289
        // Index related methods
1290
        //
1291

    
1292
        public FeatureIndexes getIndexes() {
1293
                return this.indexes;
1294
        }
1295

    
1296
        public FeatureIndex createIndex(FeatureType featureType,
1297
                        String attributeName, String indexName) throws ProviderNotRegisteredException, InitializeException {
1298
                checkNotInAppendMode();
1299
                FeatureIndexProviderServices index = null;
1300
                index = getManager().createFeatureIndexProvider(null, this, featureType, indexName, featureType.getAttributeDescriptor(attributeName));
1301
                try {
1302
                        index.fill();
1303
                } catch (FeatureIndexException e) {
1304
                        throw new InitializeException(index.getName(), e);
1305
                }
1306
                ((DefaultFeatureIndexes) getIndexes()).addIndex(index);
1307
                return index;
1308
        }
1309

    
1310
        public FeatureIndex createIndex(FeatureType featureType,
1311
                        String attributeName, String indexName, Observer observer) {
1312
                // TODO Implement observer interaction
1313
                throw new UnsupportedOperationException();
1314
        }
1315

    
1316
        //
1317
        // ====================================================================
1318
        // Transforms related methods
1319
        //
1320

    
1321
        public FeatureStoreTransforms getTransforms() {
1322
                return this.transforms;
1323
        }
1324

    
1325
        public FeatureQuery createFeatureQuery() {
1326
                return new FeatureQuery();
1327
        }
1328

    
1329
        //
1330
        // ====================================================================
1331
        // UndoRedo related methods
1332
        //
1333

    
1334
        public boolean canRedo() {
1335
                return commands.canRedo();
1336
        }
1337

    
1338
        public boolean canUndo() {
1339
                return commands.canUndo();
1340
        }
1341

    
1342
        public void redo(int num) throws RedoException {
1343
                commands.redo(num);
1344
        }
1345

    
1346
        public void undo(int num) throws UndoException {
1347
                commands.undo(num);
1348
        }
1349

    
1350
        //
1351
        // ====================================================================
1352
        // Metadata related methods
1353
        //
1354

    
1355
        public Object getMetadataID() {
1356
                return this.provider.getSourceId();
1357
        }
1358

    
1359
        public void delegate(DynObject dynObject) {
1360
                this.dynObject.delegate(dynObject);
1361
        }
1362

    
1363
        public DynClass getDynClass() {
1364
                return this.dynObject.getDynClass();
1365
        }
1366

    
1367
        public Object getDynValue(String name) throws DynFieldNotFoundException {
1368
                return this.dynObject.getDynValue(name);
1369
        }
1370

    
1371
        public boolean hasDynValue(String name) {
1372
                return this.dynObject.hasDynValue(name);
1373
        }
1374

    
1375
        public void implement(DynClass dynClass) {
1376
                this.dynObject.implement(dynClass);
1377
        }
1378

    
1379
        public Object invokeDynMethod(String name, DynObject context)
1380
        throws DynMethodException {
1381
                return this.dynObject.invokeDynMethod(this, name, context);
1382
        }
1383

    
1384
        public Object invokeDynMethod(int code, DynObject context)
1385
        throws DynMethodException {
1386
                return this.dynObject.invokeDynMethod(this, code, context);
1387
        }
1388

    
1389
        public void setDynValue(String name, Object value)
1390
        throws DynFieldNotFoundException {
1391
                this.setDynValue(name, value);
1392

    
1393
        }
1394

    
1395
        /*
1396
         * (non-Javadoc)
1397
         *
1398
         * @see org.gvsig.metadata.Metadata#getMetadataChildren()
1399
         */
1400
        public Set getMetadataChildren() {
1401
                return null;
1402
        }
1403

    
1404
        /*
1405
         * (non-Javadoc)
1406
         *
1407
         * @see org.gvsig.metadata.Metadata#getMetadataName()
1408
         */
1409
        public String getMetadataName() {
1410
                return this.provider.getName();
1411
        }
1412

    
1413
        public FeatureTypeManager getFeatureTypeManager() {
1414
                return this.featureTypeManager;
1415
        }
1416

    
1417
}