Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / libraries / libFMap_dal / src / org / gvsig / fmap / dal / feature / impl / DefaultFeatureStore.java @ 28676

History | View | Annotate | Download (44.2 KB)

1 24496 jmvivo
package org.gvsig.fmap.dal.feature.impl;
2 23772 jjdelcerro
3 28017 jmvivo
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 23772 jjdelcerro
9 26717 jmvivo
import org.cresques.cts.IProjection;
10 28017 jmvivo
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.exception.ValidateDataParametersException;
25
import org.gvsig.fmap.dal.feature.EditableFeature;
26
import org.gvsig.fmap.dal.feature.EditableFeatureType;
27
import org.gvsig.fmap.dal.feature.Feature;
28
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
29
import org.gvsig.fmap.dal.feature.FeatureIndex;
30
import org.gvsig.fmap.dal.feature.FeatureIndexes;
31
import org.gvsig.fmap.dal.feature.FeatureLocks;
32
import org.gvsig.fmap.dal.feature.FeatureQuery;
33
import org.gvsig.fmap.dal.feature.FeatureReference;
34
import org.gvsig.fmap.dal.feature.FeatureReferenceSelection;
35
import org.gvsig.fmap.dal.feature.FeatureSelection;
36
import org.gvsig.fmap.dal.feature.FeatureSet;
37
import org.gvsig.fmap.dal.feature.FeatureStore;
38
import org.gvsig.fmap.dal.feature.FeatureStoreNotification;
39
import org.gvsig.fmap.dal.feature.FeatureStoreTransforms;
40
import org.gvsig.fmap.dal.feature.FeatureType;
41
import org.gvsig.fmap.dal.feature.NewFeatureStoreParameters;
42
import org.gvsig.fmap.dal.feature.exception.AlreadyEditingException;
43
import org.gvsig.fmap.dal.feature.exception.ConcurrentDataModificationException;
44
import org.gvsig.fmap.dal.feature.exception.CreateFeatureException;
45
import org.gvsig.fmap.dal.feature.exception.DataExportException;
46
import org.gvsig.fmap.dal.feature.exception.FeatureIndexException;
47
import org.gvsig.fmap.dal.feature.exception.FinishEditingException;
48
import org.gvsig.fmap.dal.feature.exception.GetFeatureTypeException;
49
import org.gvsig.fmap.dal.feature.exception.IllegalFeatureException;
50
import org.gvsig.fmap.dal.feature.exception.IllegalFeatureTypeException;
51
import org.gvsig.fmap.dal.feature.exception.NeedEditingModeException;
52
import org.gvsig.fmap.dal.feature.exception.NoNewFeatureInsertException;
53
import org.gvsig.fmap.dal.feature.exception.NullFeatureTypeException;
54
import org.gvsig.fmap.dal.feature.exception.SelectionNotAllowedException;
55
import org.gvsig.fmap.dal.feature.exception.StoreCancelEditingException;
56
import org.gvsig.fmap.dal.feature.exception.StoreDeleteEditableFeatureException;
57
import org.gvsig.fmap.dal.feature.exception.StoreDeleteFeatureException;
58
import org.gvsig.fmap.dal.feature.exception.StoreEditException;
59
import org.gvsig.fmap.dal.feature.exception.StoreInsertFeatureException;
60
import org.gvsig.fmap.dal.feature.exception.StoreUpdateFeatureException;
61
import org.gvsig.fmap.dal.feature.exception.StoreUpdateFeatureTypeException;
62
import org.gvsig.fmap.dal.feature.exception.ValidateFeaturesException;
63
import org.gvsig.fmap.dal.feature.exception.WriteNotAllowedException;
64 24496 jmvivo
import org.gvsig.fmap.dal.feature.impl.expansionadapter.MemoryExpansionAdapter;
65 24507 jmvivo
import org.gvsig.fmap.dal.feature.impl.featureset.DefaultFeatureSet;
66 24961 cordinyana
import org.gvsig.fmap.dal.feature.impl.undo.DefaultFeatureCommandsStack;
67
import org.gvsig.fmap.dal.feature.impl.undo.FeatureCommandsStack;
68 28017 jmvivo
import org.gvsig.fmap.dal.feature.spi.DefaultFeatureData;
69
import org.gvsig.fmap.dal.feature.spi.FeatureData;
70
import org.gvsig.fmap.dal.feature.spi.FeatureReferenceProviderServices;
71
import org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider;
72
import org.gvsig.fmap.dal.feature.spi.FeatureStoreProviderServices;
73 24496 jmvivo
import org.gvsig.fmap.dal.feature.spi.index.FeatureIndexProviderServices;
74
import org.gvsig.fmap.dal.impl.DefaultDataManager;
75 25785 jmvivo
import org.gvsig.fmap.dal.resource.Resource;
76 23772 jjdelcerro
import org.gvsig.fmap.geom.primitive.Envelope;
77 25267 jjdelcerro
import org.gvsig.tools.ToolsLocator;
78 28017 jmvivo
import org.gvsig.tools.dynobject.DelegatedDynObject;
79
import org.gvsig.tools.dynobject.DynClass;
80
import org.gvsig.tools.dynobject.DynObject;
81
import org.gvsig.tools.dynobject.DynObjectManager;
82 25785 jmvivo
import org.gvsig.tools.dynobject.exception.DynFieldNotFoundException;
83
import org.gvsig.tools.dynobject.exception.DynMethodException;
84 24180 jjdelcerro
import org.gvsig.tools.exception.NotYetImplemented;
85 24794 jmvivo
import org.gvsig.tools.observer.Observable;
86 23772 jjdelcerro
import org.gvsig.tools.observer.Observer;
87 24268 jjdelcerro
import org.gvsig.tools.observer.impl.DelegateWeakReferencingObservable;
88 28017 jmvivo
import org.gvsig.tools.persistence.PersistenceException;
89
import org.gvsig.tools.persistence.PersistenceValueNotFoundException;
90
import org.gvsig.tools.persistence.PersistentState;
91 25267 jjdelcerro
import org.gvsig.tools.task.Executor;
92 24961 cordinyana
import org.gvsig.tools.undo.RedoException;
93
import org.gvsig.tools.undo.UndoException;
94 24922 vcaballero
import org.gvsig.tools.undo.command.Command;
95 23879 jjdelcerro
import org.slf4j.Logger;
96
import org.slf4j.LoggerFactory;
97 23772 jjdelcerro
98
final public class DefaultFeatureStore implements
99 26252 jmvivo
FeatureStoreProviderServices,
100
Observer {
101 23772 jjdelcerro
102 26252 jmvivo
        final static private Logger logger = LoggerFactory
103
        .getLogger(DefaultFeatureStore.class);
104 24178 cordinyana
105 23772 jjdelcerro
        private DataStoreParameters parameters = null;
106
        private FeatureSelection selection;
107
        private FeatureLocks locks;
108
109 24268 jjdelcerro
        private DelegateWeakReferencingObservable delegateObservable = new DelegateWeakReferencingObservable(this);
110 23772 jjdelcerro
111 24961 cordinyana
        private FeatureCommandsStack commands;
112 23772 jjdelcerro
        private FeatureTypeManager featureTypeManager;
113
        private FeatureManager featureManager;
114
        private SpatialManager spatialManager;
115
116
        private FeatureType defaultFeatureType = null;
117
        private List featureTypes = new ArrayList();
118
119 24162 jjdelcerro
        private int mode = MODE_QUERY;
120 23772 jjdelcerro
        private long versionOfUpdate = 0;
121
        private boolean hasStrongChanges = true;
122 27334 jmvivo
        private boolean hasInserts = true;
123 23772 jjdelcerro
124
        private DefaultDataManager dataManager = null;
125
126
        private FeatureStoreProvider provider = null;
127
128 23962 jiyarza
        private DefaultFeatureIndexes indexes;
129 23894 jjdelcerro
130 24613 jjdelcerro
        private DefaultFeatureStoreTransforms transforms;
131
132 25785 jmvivo
        private DelegatedDynObject dynObject;
133
134 28017 jmvivo
        private Long featureCount = null;
135
136 28423 jmvivo
        private long temporalOid = 0;
137
138 23772 jjdelcerro
        /*
139
         * TODO:
140
         *
141 24396 jiyarza
         * - Comprobar que solo se pueden a�adir reglas de validacion sobre un
142 23772 jjdelcerro
         * EditableFeatureType. - Comprobar que solo se puede hacer un update con un
143
         * featureType al que se le han cambiado las reglas de validacion cuando
144
         * hasStrongChanges=false.
145
         */
146
147
        public DefaultFeatureStore() {
148
149
        }
150
151
        public DefaultFeatureStore(DefaultDataManager manager,
152 23820 jjdelcerro
                        DataStoreParameters parameters, FeatureStoreProvider provider)
153 26252 jmvivo
        throws InitializeException {
154 23772 jjdelcerro
                initialize(manager, parameters, provider);
155
        }
156
157
        private void initialize(DefaultDataManager manager,
158 23820 jjdelcerro
                        DataStoreParameters parameters, FeatureStoreProvider provider)
159 26252 jmvivo
        throws InitializeException {
160 25785 jmvivo
161
                DynObjectManager dynManager = ToolsLocator.getDynObjectManager();
162
163
                this.dynObject = (DelegatedDynObject) dynManager
164 26252 jmvivo
                .createDynObject(dynManager
165 25785 jmvivo
                                .get(DataStore.DYNCLASS_NAME));
166 23772 jjdelcerro
                this.dataManager = manager;
167
                this.provider = provider;
168
                this.parameters = parameters;
169 24613 jjdelcerro
                this.transforms = new DefaultFeatureStoreTransforms(this);
170 23772 jjdelcerro
                this.provider.initialize(this);
171 25587 vcaballero
                try {
172
                        indexes=new DefaultFeatureIndexes(this);
173
                } catch (DataException e) {
174
                        throw new InitializeException(e);
175
                }
176 26777 jmvivo
                this.delegate(provider);
177 23772 jjdelcerro
        }
178
179 24613 jjdelcerro
        public Logger getLogger() {
180
                return DefaultFeatureStore.logger;
181
        }
182
183 23772 jjdelcerro
        public String getName() {
184
                return this.parameters.getDataStoreName();
185
        }
186
187
        public DataStoreParameters getParameters() {
188
                return parameters;
189
        }
190
191 24613 jjdelcerro
        public int getMode() {
192
                return this.mode;
193
        }
194
195 27758 cordinyana
        public DataManager getManager() {
196 23772 jjdelcerro
                return this.dataManager;
197
        }
198
199 24396 jiyarza
        public Iterator getChildren() {
200 23820 jjdelcerro
                return this.provider.getChilds();
201 23772 jjdelcerro
        }
202
203 23820 jjdelcerro
        public FeatureStoreProvider getProvider() {
204
                return this.provider;
205
        }
206
207
        public FeatureManager getFeatureManager() {
208
                return this.featureManager;
209
        }
210
211 23772 jjdelcerro
        public void setFeatureTypes(List types, FeatureType defaultType) {
212
                this.featureTypes = types;
213
                this.defaultFeatureType = defaultType;
214
        }
215
216
        public void open() throws OpenException {
217
                // TODO: Se puede hacer un open estando en edicion ?
218
                this.notifyChange(FeatureStoreNotification.BEFORE_OPEN);
219
                this.provider.open();
220
                this.notifyChange(FeatureStoreNotification.AFTER_OPEN);
221
        }
222
223
        public void refresh() throws OpenException, InitializeException {
224 24180 jjdelcerro
                if (this.mode != MODE_QUERY) {
225 23772 jjdelcerro
                        throw new IllegalStateException();
226
                }
227
                this.notifyChange(FeatureStoreNotification.BEFORE_REFRESH);
228 28017 jmvivo
                this.featureCount = null;
229 23772 jjdelcerro
                this.provider.refresh();
230
                this.notifyChange(FeatureStoreNotification.AFTER_REFRESH);
231
        }
232
233
        public void close() throws CloseException {
234
                // TODO: Se puede hacer un close estando en edicion ?
235
                this.notifyChange(FeatureStoreNotification.BEFORE_CLOSE);
236 28017 jmvivo
                this.featureCount = null;
237 23772 jjdelcerro
                this.provider.close();
238
                this.notifyChange(FeatureStoreNotification.AFTER_CLOSE);
239
        }
240
241
        public void dispose() throws CloseException {
242
                this.notifyChange(FeatureStoreNotification.BEFORE_DISPOSE);
243
                this.provider.dispose();
244
                if (this.selection != null) {
245
                        this.selection.dispose();
246
                        this.selection = null;
247
                }
248
                this.commands = null;
249 28017 jmvivo
                this.featureCount = null;
250 23772 jjdelcerro
                if (this.locks != null) {
251 25547 jjdelcerro
                        //this.locks.dispose();
252 23772 jjdelcerro
                        this.locks = null;
253
                }
254 23820 jjdelcerro
255 26252 jmvivo
                if (this.featureTypeManager != null) {
256
                        this.featureTypeManager.dispose();
257
                        this.featureTypeManager = null;
258
                }
259
260 23772 jjdelcerro
                this.featureManager = null;
261
                this.spatialManager = null;
262
263
                this.parameters = null;
264
                this.notifyChange(FeatureStoreNotification.AFTER_DISPOSE);
265 24178 cordinyana
                this.delegateObservable.deleteObservers();
266
                this.delegateObservable = null;
267 23772 jjdelcerro
        }
268
269
        public boolean allowWrite() {
270
                return this.provider.allowWrite();
271
        }
272
273 24446 jmvivo
        public boolean canWriteGeometry(int geometryType) throws DataException {
274 23772 jjdelcerro
                return this.provider.canWriteGeometry(geometryType);
275
        }
276
277 27723 jmvivo
        public DataServerExplorer getExplorer() throws ReadException,
278
                        ValidateDataParametersException {
279 23772 jjdelcerro
                return this.provider.getExplorer();
280
        }
281
282 25547 jjdelcerro
        /*
283 25420 cordinyana
        public Metadata getMetadata() throws MetadataNotFoundException {
284 23772 jjdelcerro
                // TODO:
285
                // Si el provider devuelbe null habria que ver de construir aqui
286
                // los metadatos basicos, como el Envelope y el SRS.
287 25276 jmvivo

288
                // TODO: Estando en edicion el Envelope deberia de
289
                // actualizarse usando el spatialManager
290 23772 jjdelcerro
                return this.provider.getMetadata();
291
        }
292 26252 jmvivo
         */
293 23772 jjdelcerro
294 25176 jmvivo
        public Envelope getEnvelope() throws DataException {
295 25277 jmvivo
                if (this.mode == MODE_FULLEDIT) {
296 25276 jmvivo
                        return this.spatialManager.getEnvelope();
297
                }
298 23772 jjdelcerro
                return this.provider.getEnvelope();
299
        }
300
301 24180 jjdelcerro
        /**
302
         * @deprecated use getDefaultFeatureType().getDefaultSRS()
303
         */
304 26717 jmvivo
        public IProjection getSRSDefaultGeometry() throws DataException {
305 24180 jjdelcerro
                return this.getDefaultFeatureType().getDefaultSRS();
306 23772 jjdelcerro
        }
307
308
        public FeatureSelection createDefaultFeatureSelection()
309 26252 jmvivo
        throws DataException {
310 23772 jjdelcerro
                return new DefaultFeatureSelection(this);
311
        }
312
313
        public FeatureData createDefaultFeatureData(FeatureType type)
314 26252 jmvivo
        throws DataException {
315 25609 vcaballero
                if( type.hasOID() ) {
316
                        return new DefaultFeatureData(type, this.provider.createNewOID());
317
                }
318 23879 jjdelcerro
                return new DefaultFeatureData(type);
319 23772 jjdelcerro
        }
320
321 28076 cmartinez
        public void saveToState(PersistentState state) throws PersistenceException {
322 24019 jjdelcerro
                state.set("dataStoreName", this.getName());
323
                state.set("parameters", this.parameters);
324
                state.set("provider", this.provider);
325 24805 jmvivo
                if (this.selection != null) {
326
                        state.set("selection", this.selection);
327
                }
328 24019 jjdelcerro
        }
329
330 28474 cmartinez
        public void loadFromState(PersistentState state) throws PersistenceException {
331 24019 jjdelcerro
                if (this.provider != null) {
332 28260 jmvivo
                        throw new PersistenceException("Provider not set");
333 24019 jjdelcerro
                }
334
                if (this.getManager() == null) {
335
                        this.dataManager = (DefaultDataManager) DALLocator.getDataManager();
336
                }
337
338
                DataStoreParameters params = (DataStoreParameters) state.get("parameters");
339
                FeatureStoreProvider provider = (FeatureStoreProvider) state.get("provider");
340
341 24062 jjdelcerro
                try {
342 24019 jjdelcerro
343 27758 cordinyana
                        initialize(this.dataManager, params, provider);
344 24805 jmvivo
                        try {
345
                                setSelection((FeatureSelection) state.get("selection"));
346
                        } catch (PersistenceValueNotFoundException e) {
347
                                setSelection(null);
348
                        }
349 24062 jjdelcerro
350
                } catch (InitializeException e) {
351
                        throw new PersistenceException(e);
352
                } catch (DataException e) {
353
                        throw new PersistenceException(e);
354
                }
355
356 24019 jjdelcerro
        }
357
358 23772 jjdelcerro
        //
359
        // ====================================================================
360
        // Gestion de la seleccion
361
        //
362
363 23842 jjdelcerro
        public void setSelection(DataSet selection)
364 26252 jmvivo
        throws DataException {
365 23894 jjdelcerro
                this.setSelection((FeatureSet) selection);
366 23772 jjdelcerro
        }
367
368 23842 jjdelcerro
        public DataSet createSelection() throws DataException {
369 23772 jjdelcerro
                return createFeatureSelection();
370
        }
371
372 23842 jjdelcerro
        public DataSet getSelection() throws DataException {
373 23772 jjdelcerro
                return this.getFeatureSelection();
374
        }
375
376 26317 cordinyana
    public void setSelection(FeatureSet selection) throws DataException {
377
        setSelection(selection, true);
378
    }
379
380
    /**
381
     * @see #setSelection(FeatureSet)
382
     * @param undoable
383
     *            if the action must be undoable
384
     */
385
    public void setSelection(FeatureSet selection, boolean undoable)
386 26252 jmvivo
        throws DataException {
387 23772 jjdelcerro
                if (selection.equals(this.selection)) {
388
                        return;
389
                }
390
                if (!selection.isFromStore(this)) {
391
                        throw new SelectionNotAllowedException(getName());
392
                }
393 23894 jjdelcerro
394
                this.selection.deleteObserver(this);
395
                if (selection instanceof FeatureSelection) {
396 26317 cordinyana
                        if (undoable && isEditing()) {
397 24346 cordinyana
                                commands.selectionSet(this, this.selection,
398 24194 jjdelcerro
                                                (FeatureSelection) selection);
399
                        }
400 23894 jjdelcerro
                        this.selection = (FeatureSelection) selection;
401 23772 jjdelcerro
                } else {
402 26317 cordinyana
                        if (undoable && isEditing()) {
403 24195 jjdelcerro
                                commands.startComplex("_selectionSet");
404 24194 jjdelcerro
                        }
405 26318 cordinyana
                        if (selection instanceof DefaultFeatureSelection) {
406
                DefaultFeatureSelection defSelection = (DefaultFeatureSelection) selection;
407
                defSelection.deselectAll(undoable);
408
                defSelection.select(selection, undoable);
409
            } else {
410
                this.selection.deselectAll();
411
                this.selection.select(selection);
412
            }
413 26317 cordinyana
                        if (undoable && isEditing()) {
414 24195 jjdelcerro
                                commands.endComplex();
415 24194 jjdelcerro
                        }
416 23772 jjdelcerro
                }
417 23894 jjdelcerro
                this.selection.addObserver(this);
418
419 23772 jjdelcerro
                this.notifyChange(DataStoreNotification.SELECTION_CHANGE);
420
        }
421
422 23894 jjdelcerro
        public FeatureSelection createFeatureSelection() throws DataException {
423 23772 jjdelcerro
                return this.provider.createFeatureSelection();
424
        }
425
426 23894 jjdelcerro
        public FeatureSelection getFeatureSelection() throws DataException {
427 23772 jjdelcerro
                if (selection == null) {
428 23894 jjdelcerro
                        this.selection = createFeatureSelection();
429
                        this.selection.addObserver(this);
430 23772 jjdelcerro
                }
431
                return selection;
432
        }
433
434
        //
435
        // ====================================================================
436
        // Gestion de notificaciones
437
        //
438
439
        public void notifyChange(String notification) {
440 24178 cordinyana
                delegateObservable.notifyObservers(new DefaultFeatureStoreNotification(this,
441 26252 jmvivo
                                notification));
442 23772 jjdelcerro
443
        }
444
445
        public void notifyChange(String notification, Feature feature) {
446 26252 jmvivo
                delegateObservable.notifyObservers(new DefaultFeatureStoreNotification(
447
                                this, notification, feature));
448 23772 jjdelcerro
        }
449
450
        public void notifyChange(String notification, Command command) {
451 26252 jmvivo
                delegateObservable.notifyObservers(new DefaultFeatureStoreNotification(
452
                                this, notification, command));
453 23772 jjdelcerro
        }
454
455
        public void notifyChange(String notification, EditableFeatureType type) {
456 26252 jmvivo
                delegateObservable.notifyObservers(new DefaultFeatureStoreNotification(this,
457
                                notification, type));
458 23772 jjdelcerro
        }
459
460 25785 jmvivo
        /*
461
         * (non-Javadoc)
462 25809 vcaballero
         *
463 25785 jmvivo
         * @see
464
         * org.gvsig.fmap.dal.feature.spi.FeatureStoreProviderServices#notifyChange
465
         * (java.lang.String, org.gvsig.fmap.dal.resource.Resource)
466
         */
467
        public void notifyChange(String notification, Resource resource) {
468 26209 jmvivo
                delegateObservable.notifyObservers(new DefaultFeatureStoreNotification(this,
469 26252 jmvivo
                                FeatureStoreNotification.RESOURCE_CHANGED));
470 25785 jmvivo
        }
471
472
473 23772 jjdelcerro
        //
474
        // ====================================================================
475
        // Gestion de bloqueos
476
        //
477
478 24613 jjdelcerro
        public boolean isLocksSupported() {
479
                return this.provider.isLocksSupported();
480
        }
481 23772 jjdelcerro
482 25547 jjdelcerro
        public FeatureLocks getLocks() throws DataException {
483 23894 jjdelcerro
                if (!this.provider.isLocksSupported()) {
484
                        getLogger().warn("Locks not supporteds");
485
                        return null;
486
                }
487 23772 jjdelcerro
                if (locks == null) {
488 25676 jmvivo
                        this.locks = this.provider.createFeatureLocks();
489 23772 jjdelcerro
                }
490
                return locks;
491
        }
492
493
        //
494
        // ====================================================================
495 26252 jmvivo
        // Interface Observable
496 23772 jjdelcerro
        //
497
498 26252 jmvivo
        public void disableNotifications() {
499
                this.delegateObservable.disableNotifications();
500 23772 jjdelcerro
501 26252 jmvivo
        }
502 23772 jjdelcerro
503 26252 jmvivo
        public void enableNotifications() {
504
                this.delegateObservable.enableNotifications();
505
        }
506 23772 jjdelcerro
507 26252 jmvivo
        public void beginComplexNotification() {
508
                this.delegateObservable.beginComplexNotification();
509 23772 jjdelcerro
510 26252 jmvivo
        }
511 23772 jjdelcerro
512 26252 jmvivo
        public void endComplexNotification() {
513
                this.delegateObservable.endComplexNotification();
514 23772 jjdelcerro
515 26252 jmvivo
        }
516 23772 jjdelcerro
517 24178 cordinyana
        public void addObserver(Observer observer) {
518
                this.delegateObservable.addObserver(observer);
519 23772 jjdelcerro
520
        }
521
522 24178 cordinyana
        public void deleteObserver(Observer observer) {
523 26252 jmvivo
                this.delegateObservable.deleteObserver(observer);
524 23772 jjdelcerro
        }
525
526
        public void deleteObservers() {
527 24178 cordinyana
                this.delegateObservable.deleteObservers();
528 23772 jjdelcerro
529
        }
530
531
        //
532
        // ====================================================================
533
        // Interface Observer
534
        //
535
        // Usado para observar:
536
        // - su seleccion
537
        // - sus bloqueos
538
        // - sus recursos
539
        //
540
541 24794 jmvivo
        public void update(Observable observable, Object notification) {
542 23894 jjdelcerro
                if (observable instanceof FeatureSet) {
543 23772 jjdelcerro
                        if (observable == this.selection) {
544
                                this.notifyChange(FeatureStoreNotification.SELECTION_CHANGE);
545
                        } else if (observable == this.locks) {
546
                                this.notifyChange(FeatureStoreNotification.LOCKS_CHANGE);
547
                        }
548
549 25785 jmvivo
                } else if (observable instanceof FeatureStoreProvider) {
550
                        if (observable == this.provider) {
551 23772 jjdelcerro
552 25785 jmvivo
                        }
553 23772 jjdelcerro
554 25785 jmvivo
                }
555 23772 jjdelcerro
        }
556
557
        //
558
        // ====================================================================
559
        // Edicion
560
        //
561
562
        private void newVersionOfUpdate() {
563
                this.versionOfUpdate++;
564
        }
565
566
        private long currentVersionOfUpdate() {
567
                return this.versionOfUpdate;
568
        }
569
570
        private void checkInEditingMode()
571 26252 jmvivo
        throws NeedEditingModeException {
572 24162 jjdelcerro
                if (mode != MODE_FULLEDIT) {
573 23772 jjdelcerro
                        throw new NeedEditingModeException(this.getName());
574
                }
575
        }
576
577 24180 jjdelcerro
        private void checkNotInAppendMode() throws IllegalStateException {
578
                if (mode == MODE_APPEND) {
579
                        throw new IllegalStateException(this.getName());
580
                }
581
        }
582
583 23772 jjdelcerro
        private void checkIsOwnFeature(Feature feature)
584 26252 jmvivo
        throws IllegalFeatureException {
585 23772 jjdelcerro
                if (((DefaultFeature) feature).getStore() != this) {
586 24017 jjdelcerro
                        throw new IllegalFeatureException(this.getName());
587 23772 jjdelcerro
                }
588
                // FIXME: fixFeatureType no vale para el checkIsOwnFeature
589
                // fixFeatureType((DefaultFeatureType) feature.getType());
590
        }
591
592
        private void exitEditingMode() {
593 25977 jmvivo
                if (commands != null) {
594
                        commands.clear();
595 26252 jmvivo
                        commands = null;
596 25977 jmvivo
                }
597 26252 jmvivo
598
                if (featureTypeManager != null) {
599
                        featureTypeManager.dispose();
600
                        featureTypeManager = null;
601
602
                }
603
604
                // TODO implementar un dispose para estos dos
605 23772 jjdelcerro
                featureManager = null;
606
                spatialManager = null;
607
608 28017 jmvivo
                featureCount = null;
609
610 24162 jjdelcerro
                mode = MODE_QUERY;
611 23772 jjdelcerro
                hasStrongChanges = true; // Lo deja a true por si las moscas
612 27334 jmvivo
                hasInserts = true;
613 23772 jjdelcerro
        }
614
615
        synchronized public void edit() throws DataException {
616 24162 jjdelcerro
                edit(MODE_FULLEDIT);
617
        }
618
619
        synchronized public void edit(int mode) throws DataException {
620 23772 jjdelcerro
                try {
621 24162 jjdelcerro
                        if ( this.mode != MODE_QUERY ) {
622 23772 jjdelcerro
                                throw new AlreadyEditingException(this.getName());
623
                        }
624 24185 jjdelcerro
                        if (!this.provider.supportsAppendMode()) {
625
                                mode = MODE_FULLEDIT;
626
                        }
627 24162 jjdelcerro
                        switch (mode) {
628
                        case MODE_QUERY:
629
                                throw new IllegalStateException(this.getName());
630 23772 jjdelcerro
631 24162 jjdelcerro
                        case MODE_FULLEDIT:
632 24613 jjdelcerro
                                if (!this.transforms.isEmpty()) {
633
                                        throw new IllegalStateException(this.getName());
634
                                }
635 24162 jjdelcerro
                                notifyChange(FeatureStoreNotification.BEFORE_STARTEDITING);
636
                                featureManager = new FeatureManager(new MemoryExpansionAdapter());
637 26252 jmvivo
                                featureTypeManager = new FeatureTypeManager(this,
638 24162 jjdelcerro
                                                new MemoryExpansionAdapter());
639 28319 jmvivo
                                spatialManager = new SpatialManager(this, provider
640
                                                .getEnvelope());
641 23772 jjdelcerro
642 24961 cordinyana
                                commands = new DefaultFeatureCommandsStack(featureManager,
643 24162 jjdelcerro
                                                spatialManager, featureTypeManager);
644
                                this.mode = MODE_FULLEDIT;
645
                                hasStrongChanges = false;
646 27334 jmvivo
                                hasInserts = false;
647 24162 jjdelcerro
                                notifyChange(FeatureStoreNotification.AFTER_STARTEDITING);
648
                                break;
649
                        case MODE_APPEND:
650 24613 jjdelcerro
                                if (!this.transforms.isEmpty()) {
651
                                        throw new IllegalStateException(this.getName());
652
                                }
653 24162 jjdelcerro
                                notifyChange(FeatureStoreNotification.BEFORE_STARTEDITING);
654
                                this.provider.beginAppend();
655
                                this.mode = MODE_APPEND;
656 27334 jmvivo
                                hasInserts = false;
657 24162 jjdelcerro
                                notifyChange(FeatureStoreNotification.AFTER_STARTEDITING);
658
                                break;
659
                        }
660 23772 jjdelcerro
                } catch (Exception e) {
661
                        throw new StoreEditException(e, this.getName());
662
                }
663
        }
664
665
        public boolean isEditing() {
666 24162 jjdelcerro
                return mode == MODE_FULLEDIT;
667 23772 jjdelcerro
        }
668
669 24162 jjdelcerro
        public boolean isAppending() {
670
                return mode == MODE_APPEND;
671
        }
672
673 23772 jjdelcerro
        synchronized public void update(EditableFeatureType type)
674 26252 jmvivo
        throws DataException {
675 23772 jjdelcerro
                try {
676
                        checkInEditingMode();
677
                        if (type == null) {
678
                                throw new NullFeatureTypeException(getName());
679
                        }
680
                        // FIXME: Comprobar que es un featureType aceptable.
681
                        notifyChange(FeatureStoreNotification.BEFORE_UPDATE_TYPE, type);
682
                        newVersionOfUpdate();
683
684
                        FeatureType oldt = type.getSource().getCopy();
685
                        FeatureType newt = type.getNotEditableCopy();
686
                        commands.update(newt, oldt);
687
688
                        if (((DefaultEditableFeatureType) type).hasStrongChanges()) {
689
                                hasStrongChanges = true;
690
                        }
691
                        notifyChange(FeatureStoreNotification.AFTER_UPDATE_TYPE, type);
692
                } catch (Exception e) {
693
                        throw new StoreUpdateFeatureTypeException(e, this.getName());
694
                }
695
        }
696
697
        synchronized public void delete(Feature feature) throws DataException {
698
                try {
699
                        checkInEditingMode();
700
                        checkIsOwnFeature(feature);
701
                        if (feature instanceof EditableFeature) {
702
                                throw new StoreDeleteEditableFeatureException(getName());
703
                        }
704
                        notifyChange(FeatureStoreNotification.BEFORE_DELETE, feature);
705
                        this.commands.delete(feature);
706
                        newVersionOfUpdate();
707
                        hasStrongChanges = true;
708
                        notifyChange(FeatureStoreNotification.AFTER_DELETE, feature);
709
                } catch (Exception e) {
710
                        throw new StoreDeleteFeatureException(e, this.getName());
711
                }
712
        }
713
714
        private static EditableFeature lastChangedFeature = null;
715
716
        synchronized public void insert(EditableFeature feature)
717 26252 jmvivo
        throws DataException {
718 23772 jjdelcerro
                try {
719 24162 jjdelcerro
                        switch (mode) {
720
                        case MODE_QUERY:
721
                                throw new NeedEditingModeException(this.getName());
722
723
                        case MODE_APPEND:
724
                                checkIsOwnFeature(feature);
725
                                if (feature.getSource() != null) {
726
                                        throw new NoNewFeatureInsertException(this.getName());
727
                                }
728 28017 jmvivo
                                this.featureCount = null;
729 24162 jjdelcerro
                                notifyChange(FeatureStoreNotification.BEFORE_INSERT, feature);
730 23772 jjdelcerro
                                feature.validate(Feature.UPDATE);
731 28676 jmvivo
                                provider.append(((DefaultEditableFeature) feature).getData());
732 24162 jjdelcerro
                                hasStrongChanges = true;
733 27334 jmvivo
                                hasInserts = true;
734 24162 jjdelcerro
                                notifyChange(FeatureStoreNotification.AFTER_INSERT, feature);
735
                                break;
736
737
                        case MODE_FULLEDIT:
738
                                checkIsOwnFeature(feature);
739
                                if (feature.getSource() != null) {
740
                                        throw new NoNewFeatureInsertException(this.getName());
741
                                }
742
                                notifyChange(FeatureStoreNotification.BEFORE_INSERT, feature);
743
                                newVersionOfUpdate();
744 25565 vcaballero
                                if (lastChangedFeature ==null || lastChangedFeature.getSource() != feature.getSource()) {
745 24162 jjdelcerro
                                        lastChangedFeature = feature;
746
                                        feature.validate(Feature.UPDATE);
747
                                        lastChangedFeature = null;
748
                                }
749
                                commands.insert(feature.getNotEditableCopy());
750
                                hasStrongChanges = true;
751 27334 jmvivo
                                hasInserts = true;
752 24162 jjdelcerro
                                notifyChange(FeatureStoreNotification.AFTER_INSERT, feature);
753
                                break;
754 23772 jjdelcerro
                        }
755
                } catch (Exception e) {
756
                        throw new StoreInsertFeatureException(e, this.getName());
757
                }
758
        }
759
760
        synchronized public void update(EditableFeature feature)
761 26252 jmvivo
        throws DataException {
762 23772 jjdelcerro
                try {
763
                        if ((feature).getSource() == null) {
764
                                insert(feature);
765
                                return;
766
                        }
767
                        checkInEditingMode();
768
                        checkIsOwnFeature(feature);
769
                        notifyChange(FeatureStoreNotification.BEFORE_UPDATE, feature);
770
                        newVersionOfUpdate();
771 25781 vcaballero
                        if (lastChangedFeature==null || lastChangedFeature.getSource() != feature.getSource()) {
772 23772 jjdelcerro
                                lastChangedFeature = feature;
773
                                feature.validate(Feature.UPDATE);
774
                                lastChangedFeature = null;
775
                        }
776
777
                        Feature oldf = feature.getSource();
778
                        Feature newf = feature.getNotEditableCopy();
779
                        commands.update(newf, oldf);
780
781
                        hasStrongChanges = true;
782
                        notifyChange(FeatureStoreNotification.AFTER_UPDATE, feature);
783
                } catch (Exception e) {
784
                        throw new StoreUpdateFeatureException(e, this.getName());
785
                }
786
        }
787
788 24961 cordinyana
        synchronized public void redo() throws RedoException {
789 26252 jmvivo
                Command redo = commands.getNextRedoCommand();
790
                try {
791
                        checkInEditingMode();
792
                } catch (NeedEditingModeException ex) {
793
                        throw new RedoException(redo, ex);
794
                }
795 24961 cordinyana
                notifyChange(FeatureStoreNotification.BEFORE_REDO, redo);
796 26252 jmvivo
                newVersionOfUpdate();
797
                commands.redo();
798
                hasStrongChanges = true;
799
                notifyChange(FeatureStoreNotification.AFTER_REDO, redo);
800 23772 jjdelcerro
        }
801
802 24961 cordinyana
        synchronized public void undo() throws UndoException {
803 26252 jmvivo
                Command undo = commands.getNextUndoCommand();
804
                try {
805
                        checkInEditingMode();
806
                } catch (NeedEditingModeException ex) {
807
                        throw new UndoException(undo, ex);
808
                }
809 24961 cordinyana
                notifyChange(FeatureStoreNotification.BEFORE_UNDO, undo);
810 26252 jmvivo
                newVersionOfUpdate();
811
                commands.undo();
812
                hasStrongChanges = true;
813
                notifyChange(FeatureStoreNotification.AFTER_UNDO, undo);
814 23772 jjdelcerro
        }
815
816 26252 jmvivo
        public List getRedoInfos() {
817
                if (isEditing() && commands != null) {
818
                        return commands.getRedoInfos();
819
                } else {
820
                        return null;
821
                }
822
        }
823 23772 jjdelcerro
824 26252 jmvivo
        public List getUndoInfos() {
825
                if (isEditing() && commands != null) {
826
                        return commands.getUndoInfos();
827
                } else {
828
                        return null;
829
                }
830
        }
831 24961 cordinyana
832 26252 jmvivo
        public synchronized FeatureCommandsStack getCommandsStack()
833
        throws DataException {
834
                checkInEditingMode();
835
                return commands;
836
        }
837 24961 cordinyana
838 23772 jjdelcerro
        synchronized public void cancelEditing() throws DataException {
839 25809 vcaballero
                spatialManager.cancelModifies();
840 23772 jjdelcerro
                try {
841
                        checkInEditingMode();
842 27334 jmvivo
843
                        boolean clearSelection = this.hasStrongChanges;
844
                        if (this.selection instanceof FeatureReferenceSelection) {
845
                                clearSelection = this.hasInserts;
846
                        }
847 23772 jjdelcerro
                        notifyChange(FeatureStoreNotification.BEFORE_CANCELEDITING);
848
                        exitEditingMode();
849 27334 jmvivo
                        if (clearSelection) {
850
                                ((FeatureSelection) this.getSelection()).deselectAll();
851
                        }
852 23772 jjdelcerro
                        notifyChange(FeatureStoreNotification.AFTER_CANCELEDITING);
853
                } catch (Exception e) {
854
                        throw new StoreCancelEditingException(e, this.getName());
855
                }
856
        }
857
858
        synchronized public void finishEditing() throws DataException {
859
                try {
860 24162 jjdelcerro
                        switch (mode) {
861
                        case MODE_QUERY:
862
                                throw new NeedEditingModeException(this.getName());
863
864
                        case MODE_APPEND:
865
                                notifyChange(FeatureStoreNotification.BEFORE_FINISHEDITING);
866
                                provider.endAppend();
867
                                exitEditingMode();
868
                                notifyChange(FeatureStoreNotification.AFTER_FINISHEDITING);
869
                                break;
870
871
                        case MODE_FULLEDIT:
872
                                if (!hasStrongChanges) {
873
                                        performLightEditing();
874
                                        return;
875
                                }
876
                                if (!this.allowWrite()) {
877
                                        throw new WriteNotAllowedException(getName());
878
                                }
879
880
                                notifyChange(FeatureStoreNotification.BEFORE_FINISHEDITING);
881
                                validateFeatures(Feature.FINISH_EDITING);
882 28318 jmvivo
                                provider.performEditing(featureManager.getDeleted(),
883
                                                featureManager.getInserted(),
884 28260 jmvivo
                                                featureManager.getUpdated(),
885 28098 jmvivo
                                                featureTypeManager.getOriginalsFeatureTypesUpdated());
886 24162 jjdelcerro
                                exitEditingMode();
887
                                notifyChange(FeatureStoreNotification.AFTER_FINISHEDITING);
888
                                break;
889 23772 jjdelcerro
                        }
890
                } catch (Exception e) {
891
                        throw new FinishEditingException(e);
892
                }
893
        }
894
895
        private void performLightEditing() throws DataException {
896 24180 jjdelcerro
                throw new NotYetImplemented(
897 26252 jmvivo
                "lightFinishEdition not yet implemented");
898 23772 jjdelcerro
899
                // TODO: implementar
900
                // notifyChange(FeatureStoreNotification.BEFORE_FINISHEDITING);
901
                // exitEditingMode();
902
                // notifyChange(FeatureStoreNotification.AFTER_FINISHEDITING);
903
        }
904
905 24185 jjdelcerro
906 24613 jjdelcerro
        public void beginEditingGroup(String description)
907 26252 jmvivo
        throws NeedEditingModeException {
908 24613 jjdelcerro
                checkInEditingMode();
909
                commands.startComplex(description);
910
        }
911
912
        public void endEditingGroup() throws NeedEditingModeException {
913
                checkInEditingMode();
914
                commands.endComplex();
915
        }
916
917 24185 jjdelcerro
        public boolean isAppendModeSupported() {
918
                return this.provider.supportsAppendMode();
919
        }
920
921
922 24874 jmvivo
        public void export(DataServerExplorer explorer, NewFeatureStoreParameters params)
923 26252 jmvivo
        throws DataException {
924 23772 jjdelcerro
925
                if (this.getFeatureTypes().size() != 1) {
926 24180 jjdelcerro
                        throw new NotYetImplemented(
927 26252 jmvivo
                        "export whith more than one type not yet implemented");
928 23772 jjdelcerro
                }
929 25751 vcaballero
                FeatureSelection featureSelection=(FeatureSelection)getSelection();
930 23772 jjdelcerro
                try {
931
                        FeatureType type = this.getDefaultFeatureType();
932 25977 jmvivo
                        if (params.getDefaultFeatureType() == null
933
                                        || params.getDefaultFeatureType().size() == 0) {
934
                                params.setDefaultFeatureType(new DefaultEditableFeatureType(
935
                                                (DefaultFeatureType) type));
936
937 24568 jmvivo
                        }
938 26234 vcaballero
                        explorer.add(params, true);
939 23772 jjdelcerro
940
                        DataManager manager = DALLocator.getDataManager();
941
                        FeatureStore target = (FeatureStore) manager
942 26252 jmvivo
                        .createStore(params);
943 25977 jmvivo
                        FeatureType targetType = target.getDefaultFeatureType();
944
945 24568 jmvivo
                        target.edit(MODE_APPEND);
946 25751 vcaballero
                        FeatureSet features=null;
947 28423 jmvivo
                        FeatureAttributeDescriptor[] pk = type.getPrimaryKey();
948 25751 vcaballero
                        if (featureSelection.getSize()>0){
949
                                features = this.getFeatureSelection();
950
                        }else{
951 28423 jmvivo
                                if (pk != null && pk.length > 0){
952
                                        FeatureQuery query = createFeatureQuery();
953
                                        for (int i = 0; i < pk.length; i++) {
954
                                                query.getOrder().add(pk[i].getName(), true);
955
                                        }
956
                                        features = this.getFeatureSet(query);
957
                                } else {
958
                                        features = this.getFeatureSet();
959
                                }
960 25751 vcaballero
                        }
961 23772 jjdelcerro
                        Iterator it1 = features.iterator();
962
                        while (it1.hasNext()) {
963 28423 jmvivo
                                DefaultFeature feature = (DefaultFeature) it1.next();
964 25977 jmvivo
                                target.insert(target.createNewFeature(targetType, feature));
965 23772 jjdelcerro
                        }
966
                        features.dispose();
967
                        target.finishEditing();
968
                        target.dispose();
969
                } catch (Exception e) {
970
                        throw new DataExportException(e, params.toString());
971
                }
972
        }
973
974
        //
975
        // ====================================================================
976
        // Obtencion de datos
977
        // getDataCollection, getFeatureCollection
978
        //
979
980 23842 jjdelcerro
        public DataSet getDataSet() throws DataException {
981 24180 jjdelcerro
                checkNotInAppendMode();
982 27575 jmvivo
                FeatureQuery query = new DefaultFeatureQuery(this
983
                                .getDefaultFeatureType());
984 23842 jjdelcerro
                return new DefaultFeatureSet(this, query);
985 23772 jjdelcerro
        }
986
987 23842 jjdelcerro
        public DataSet getDataSet(DataQuery dataQuery)
988 26252 jmvivo
        throws DataException {
989 24180 jjdelcerro
                checkNotInAppendMode();
990 23842 jjdelcerro
                return new DefaultFeatureSet(this, (FeatureQuery) dataQuery);
991 23772 jjdelcerro
        }
992
993 23842 jjdelcerro
        public void getDataSet(Observer observer) throws DataException {
994 24180 jjdelcerro
                checkNotInAppendMode();
995 23842 jjdelcerro
                this.getFeatureSet(null, observer);
996 23772 jjdelcerro
        }
997
998 23842 jjdelcerro
        public void getDataSet(DataQuery dataQuery, Observer observer)
999 26252 jmvivo
        throws DataException {
1000 24180 jjdelcerro
                checkNotInAppendMode();
1001 23842 jjdelcerro
                this.getFeatureSet((FeatureQuery) dataQuery, observer);
1002 23772 jjdelcerro
        }
1003
1004 23842 jjdelcerro
        public FeatureSet getFeatureSet() throws DataException {
1005 24180 jjdelcerro
                checkNotInAppendMode();
1006 27575 jmvivo
                FeatureQuery query = new DefaultFeatureQuery(this
1007
                                .getDefaultFeatureType());
1008 23842 jjdelcerro
                return new DefaultFeatureSet(this, query);
1009 23772 jjdelcerro
        }
1010
1011 23842 jjdelcerro
        public FeatureSet getFeatureSet(FeatureQuery featureQuery)
1012 26252 jmvivo
        throws DataException {
1013 24180 jjdelcerro
                checkNotInAppendMode();
1014 23820 jjdelcerro
                return new DefaultFeatureSet(this, featureQuery);
1015 23772 jjdelcerro
        }
1016
1017 27700 jmvivo
1018 27234 jmvivo
        public FeatureType getFeatureType(FeatureQuery featureQuery)
1019
                        throws DataException {
1020
                DefaultFeatureType fType = (DefaultFeatureType) this
1021
                                .getFeatureType(featureQuery.getFeatureTypeId());
1022 23820 jjdelcerro
                if (featureQuery.getAttributeNames() != null){
1023 27234 jmvivo
                        return fType.getSubtype(featureQuery.getAttributeNames());
1024 23820 jjdelcerro
                }
1025 27234 jmvivo
                return fType;
1026 23820 jjdelcerro
        }
1027
1028 23842 jjdelcerro
        public void getFeatureSet(Observer observer)
1029 26252 jmvivo
        throws DataException {
1030 24180 jjdelcerro
                checkNotInAppendMode();
1031 23842 jjdelcerro
                this.getFeatureSet(null, observer);
1032 23772 jjdelcerro
        }
1033
1034 23842 jjdelcerro
        public void getFeatureSet(FeatureQuery query, Observer observer)
1035 26252 jmvivo
        throws DataException {
1036 23772 jjdelcerro
                class LoadInBackGround implements Runnable {
1037
                        private FeatureStore store;
1038
                        private FeatureQuery query;
1039
                        private Observer observer;
1040 25267 jjdelcerro
                        private Executor executor;
1041
                        private FeatureStoreNotification notification;
1042 23772 jjdelcerro
1043
                        public LoadInBackGround(FeatureStore store, FeatureQuery query,
1044 25267 jjdelcerro
                                        Observer observer, Executor executor) {
1045 23772 jjdelcerro
                                this.store = store;
1046
                                this.query = query;
1047
                                this.observer = observer;
1048 25267 jjdelcerro
                                this.executor = executor;
1049 23772 jjdelcerro
                        }
1050
1051 25267 jjdelcerro
                        void notify(FeatureStoreNotification theNotification) {
1052
                                if (executor == null) {
1053
                                        observer.update(store, theNotification);
1054
                                        return;
1055
                                }
1056
                                this.notification = theNotification;
1057
                                executor.execute(new Runnable() {
1058
                                        public void run() {
1059
                                                observer.update(store, notification);
1060
                                        }
1061
                                });
1062
1063
                        }
1064
1065 23772 jjdelcerro
                        public void run() {
1066
                                try {
1067 25267 jjdelcerro
                                        FeatureSet set = store.getFeatureSet(query);
1068
                                        notify(new DefaultFeatureStoreNotification(store,
1069
                                                        FeatureStoreNotification.LOAD_FINISHED, set));
1070 23772 jjdelcerro
                                } catch (Exception e) {
1071 25267 jjdelcerro
                                        notify(new DefaultFeatureStoreNotification(store,
1072
                                                        FeatureStoreNotification.LOAD_FINISHED, e));
1073 23772 jjdelcerro
                                }
1074
                        }
1075
                }
1076
1077 24180 jjdelcerro
                checkNotInAppendMode();
1078 23772 jjdelcerro
                if (query == null) {
1079 27575 jmvivo
                        query = new DefaultFeatureQuery(this.getDefaultFeatureType());
1080 23772 jjdelcerro
                }
1081 25267 jjdelcerro
                Executor executor = ToolsLocator.getTaskManager().getExecutor();
1082
                LoadInBackGround task = new LoadInBackGround(this, query, observer,
1083
                                executor);
1084 23772 jjdelcerro
                Thread thread = new Thread(task);
1085
                thread.run();
1086
        }
1087
1088 23842 jjdelcerro
        public Feature getFeatureByReference(FeatureReference reference) throws DataException {
1089 24180 jjdelcerro
                checkNotInAppendMode();
1090 28660 jmvivo
                DefaultFeatureReference ref = (DefaultFeatureReference) reference;
1091
                FeatureType featureType;
1092
                if (ref.getFeatureTypeId() == null) {
1093
                        featureType = this.getDefaultFeatureType();
1094
                } else {
1095
                        featureType = this.getFeatureType(ref.getFeatureTypeId());
1096
                }
1097
                return this.getFeatureByReference(reference, featureType);
1098 23772 jjdelcerro
        }
1099
1100 23842 jjdelcerro
        public Feature getFeatureByReference(FeatureReference reference, FeatureType featureType)
1101 26252 jmvivo
        throws DataException {
1102 24180 jjdelcerro
                checkNotInAppendMode();
1103 23820 jjdelcerro
                featureType = fixFeatureType((DefaultFeatureType) featureType);
1104 25843 jmvivo
                if (!this.transforms.isEmpty()) {
1105
1106
                        featureType = this.transforms
1107 26252 jmvivo
                        .getSourceFeatureTypeFrom(featureType);
1108 25843 jmvivo
1109
                }
1110 23820 jjdelcerro
                // TODO comprobar que el id es de este store
1111
1112 24162 jjdelcerro
                if (this.mode == MODE_FULLEDIT) {
1113 24132 vcaballero
                        Feature f = featureManager.get(reference, this, featureType);
1114
                        if (f!=null) {
1115
                                return f;
1116 23820 jjdelcerro
                        }
1117
                }
1118 25917 jmvivo
                DefaultFeature feature = new DefaultFeature(
1119 25843 jmvivo
                                this,
1120
                                this.provider
1121
                                .getFeatureDataByReference(
1122
                                                (FeatureReferenceProviderServices) reference,
1123
                                                featureType));
1124
1125
                if (!this.transforms.isEmpty()) {
1126
                        return this.transforms.applyTransform(feature, featureType);
1127
                }
1128
                return feature;
1129 23772 jjdelcerro
        }
1130
1131
        //
1132
        // ====================================================================
1133
        // Gestion de features
1134
        //
1135
1136
        private FeatureType fixFeatureType(DefaultFeatureType type)
1137 26252 jmvivo
        throws DataException {
1138 27672 jmvivo
                FeatureType original = this.getDefaultFeatureType();
1139
1140
                if (type == null || type.equals(original)) {
1141
                        return original;
1142
                } else {
1143
                        if (!type.isSubtypeOf(original)) {
1144
                                Iterator iter = this.getFeatureTypes().iterator();
1145
                                FeatureType tmpType;
1146
                                boolean found = false;
1147
                                while (iter.hasNext()) {
1148
                                        tmpType = (FeatureType) iter.next();
1149
                                        if (type.equals(tmpType)) {
1150
                                                return type;
1151
1152
                                        }else if (type.isSubtypeOf(tmpType)) {
1153
                                                found = true;
1154
                                                original = tmpType;
1155
                                                break;
1156
                                        }
1157
1158
                                }
1159
                                if (!found) {
1160
                                        throw new IllegalFeatureTypeException(getName());
1161
                                }
1162
                        }
1163 23772 jjdelcerro
                }
1164 27672 jmvivo
1165
                // Checks that type has all fields of pk
1166
                // else add the missing attributes at the end.
1167
                if (!original.hasOID()) {
1168
                        // Gets original pk attributes
1169
                        DefaultEditableFeatureType edOriginal = (DefaultEditableFeatureType) original
1170
                                        .getEditable();
1171
                        FeatureAttributeDescriptor orgAttr;
1172
                        Iterator edOriginalIter = edOriginal.iterator();
1173
                        while (edOriginalIter.hasNext()) {
1174
                                orgAttr = (FeatureAttributeDescriptor) edOriginalIter.next();
1175
                                if (!orgAttr.isPrimaryKey()) {
1176
                                        edOriginalIter.remove();
1177
                                }
1178 23772 jjdelcerro
                        }
1179
1180 27672 jmvivo
                        // Checks if all pk attributes are in type
1181
                        Iterator typeIterator;
1182
                        edOriginalIter = edOriginal.iterator();
1183
                        FeatureAttributeDescriptor attr;
1184
                        while (edOriginalIter.hasNext()) {
1185
                                orgAttr = (FeatureAttributeDescriptor) edOriginalIter.next();
1186
                                typeIterator = type.iterator();
1187
                                while (typeIterator.hasNext()) {
1188
                                        attr = (FeatureAttributeDescriptor) typeIterator.next();
1189
                                        if (attr.getName().equals(orgAttr.getName())) {
1190
                                                edOriginalIter.remove();
1191
                                                break;
1192
                                        }
1193
                                }
1194
                        }
1195
1196
                        // add missing pk attributes if any
1197
                        if (edOriginal.size() > 0) {
1198 27697 jmvivo
                                boolean isEditable = type instanceof DefaultEditableFeatureType;
1199 27700 jmvivo
                                DefaultEditableFeatureType edType = (DefaultEditableFeatureType) original
1200
                                                .getEditable();
1201
                                edType.clear();
1202
                                edType.addAll(type);
1203 27672 jmvivo
                                edType.addAll(edOriginal);
1204 27697 jmvivo
                                if (!isEditable) {
1205
                                        type = (DefaultFeatureType) edType.getNotEditableCopy();
1206
                                }
1207 27672 jmvivo
                        }
1208
1209 23772 jjdelcerro
                }
1210 27672 jmvivo
1211
1212
                return type;
1213 23772 jjdelcerro
        }
1214
1215
        public void validateFeatures(int mode) throws DataException {
1216
                try {
1217 24180 jjdelcerro
                        checkNotInAppendMode();
1218 23842 jjdelcerro
                        FeatureSet collection = this.getFeatureSet();
1219 23772 jjdelcerro
                        Iterator iter = collection.iterator();
1220
                        long previousVersionOfUpdate = currentVersionOfUpdate();
1221
                        while (iter.hasNext()) {
1222
                                ((DefaultFeature) iter.next()).validate(mode);
1223
                                if (previousVersionOfUpdate != currentVersionOfUpdate()) {
1224
                                        throw new ConcurrentDataModificationException(getName());
1225
                                }
1226
                        }
1227
                } catch (Exception e) {
1228
                        throw new ValidateFeaturesException(e, getName());
1229
                }
1230
        }
1231
1232
        public FeatureType getDefaultFeatureType() throws DataException {
1233
                try {
1234
                        if (isEditing()) {
1235 25565 vcaballero
                                FeatureType auxFeatureType=featureTypeManager.getType(defaultFeatureType.getId());
1236 25676 jmvivo
                                if (auxFeatureType!=null) {
1237 25565 vcaballero
                                        return auxFeatureType;
1238 25676 jmvivo
                                }
1239 23772 jjdelcerro
                        }
1240 24613 jjdelcerro
                        FeatureType type = this.transforms.getDefaultFeatureType();
1241
                        if (type != null) {
1242
                                return type;
1243
                        }
1244 23772 jjdelcerro
                        return defaultFeatureType;
1245
                } catch (Exception e) {
1246
                        throw new GetFeatureTypeException(e, getName());
1247
                }
1248
        }
1249
1250 27234 jmvivo
        public FeatureType getFeatureType(String featureTypeId)
1251
                        throws DataException {
1252
                if (featureTypeId == null) {
1253
                        return this.getDefaultFeatureType();
1254
                }
1255
                try {
1256
                        if (isEditing()) {
1257
                                FeatureType auxFeatureType = featureTypeManager
1258
                                                .getType(featureTypeId);
1259
                                if (auxFeatureType != null) {
1260
                                        return auxFeatureType;
1261
                                }
1262
                        }
1263
                        FeatureType type = this.transforms.getFeatureType(featureTypeId);
1264
                        if (type != null) {
1265
                                return type;
1266
                        }
1267
                        Iterator iter = this.featureTypes.iterator();
1268
                        while (iter.hasNext()){
1269
                                type = (FeatureType) iter.next();
1270
                                if (type.getId().equals(featureTypeId)) {
1271
                                        return type;
1272
                                }
1273
                        }
1274
                        return null;
1275
                } catch (Exception e) {
1276
                        throw new GetFeatureTypeException(e, getName());
1277
                }
1278
        }
1279
1280
1281 25917 jmvivo
        public FeatureType getProviderDefaultFeatureType() {
1282
                return defaultFeatureType;
1283
        }
1284
1285 23772 jjdelcerro
        public List getFeatureTypes() throws DataException {
1286
                try {
1287
                        List types;
1288
                        if (isEditing()) {
1289 24132 vcaballero
                                types=new ArrayList();
1290
                                Iterator it=featureTypes.iterator();
1291
                                while (it.hasNext()) {
1292
                                        FeatureType type = (FeatureType) it.next();
1293 26234 vcaballero
                                        FeatureType typeaux = featureTypeManager.getType(type.getId());
1294
                                        if (typeaux!=null) {
1295
                                                types.add(typeaux);
1296
                                        }else{
1297 24132 vcaballero
                                                types.add(type);
1298 24162 jjdelcerro
                                        }
1299 24132 vcaballero
                                }
1300
                                it = featureTypeManager.newsIterator();
1301
                                while (it.hasNext()) {
1302
                                        FeatureType type = (FeatureType) it.next();
1303
                                        types.add(type);
1304
                                }
1305 23772 jjdelcerro
                        } else {
1306 24613 jjdelcerro
                                types = this.transforms.getFeatureTypes();
1307
                                if (types == null) {
1308
                                        types = featureTypes;
1309
                                }
1310 23772 jjdelcerro
                        }
1311
                        return Collections.unmodifiableList(types);
1312
                } catch (Exception e) {
1313
                        throw new GetFeatureTypeException(e, getName());
1314
                }
1315
        }
1316
1317 25917 jmvivo
        public List getProviderFeatureTypes() throws DataException {
1318
                return Collections.unmodifiableList(this.featureTypes);
1319
        }
1320
1321 23879 jjdelcerro
        public Feature createFeature(FeatureData data)
1322 26252 jmvivo
        throws DataException {
1323 23772 jjdelcerro
                DefaultFeature feature = new DefaultFeature(this, data);
1324
                return feature;
1325
        }
1326
1327 24248 jjdelcerro
        public Feature createFeature(FeatureData data, FeatureType type)
1328 26252 jmvivo
        throws DataException {
1329 23879 jjdelcerro
                // FIXME: falta por implementar
1330
                // Comprobar si es un subtipo del feature de data
1331
                // y construir un feature usando el subtipo.
1332
                // Probablemente requiera generar una copia del data.
1333 24248 jjdelcerro
                throw new NotYetImplemented();
1334 23879 jjdelcerro
        }
1335
1336 24152 jjdelcerro
        public EditableFeature createNewFeature(FeatureType type,
1337 23772 jjdelcerro
                        Feature defaultValues)
1338 26252 jmvivo
        throws DataException {
1339 23772 jjdelcerro
                try {
1340 28662 jmvivo
                        FeatureData data = createNewFeatureData(type);
1341 25632 jjdelcerro
                        DefaultEditableFeature feature = new DefaultEditableFeature(this, data);
1342 23772 jjdelcerro
                        feature.initializeValues(defaultValues);
1343
                        return feature;
1344
                } catch (Exception e) {
1345
                        throw new CreateFeatureException(e, getName());
1346
                }
1347
        }
1348
1349 28662 jmvivo
        private FeatureData createNewFeatureData(FeatureType type)
1350
                        throws DataException {
1351
                type = this.fixFeatureType((DefaultFeatureType) type);
1352
                FeatureData data = this.provider.createFeatureData(type);
1353
                data.setNew(true);
1354
                if (type.hasOID() && data.getOID() == null) {
1355
                        data.setOID(this.provider.createNewOID());
1356
                } else {
1357
                        data.setOID(this.getTemporalOID());
1358
                }
1359
                return data;
1360
1361
        }
1362
1363 24152 jjdelcerro
        public EditableFeature createNewFeature(FeatureType type,
1364 23772 jjdelcerro
                        boolean defaultValues)
1365 26252 jmvivo
        throws DataException {
1366 23772 jjdelcerro
                try {
1367 28662 jmvivo
                        FeatureData data = createNewFeatureData(type);
1368 25609 vcaballero
                        DefaultEditableFeature feature = new DefaultEditableFeature(this, data);
1369 23772 jjdelcerro
                        if (defaultValues) {
1370
                                feature.initializeValues();
1371
                        }
1372
                        return feature;
1373
                } catch (Exception e) {
1374
                        throw new CreateFeatureException(e, getName());
1375
                }
1376
        }
1377
1378 24152 jjdelcerro
        public EditableFeature createNewFeature(boolean defaultValues)
1379 26252 jmvivo
        throws DataException {
1380 24152 jjdelcerro
                return this.createNewFeature(this.getDefaultFeatureType(), defaultValues);
1381 23772 jjdelcerro
        }
1382
1383 24152 jjdelcerro
        public EditableFeature createNewFeature() throws DataException {
1384
                return this.createNewFeature(this.getDefaultFeatureType(), true);
1385 23772 jjdelcerro
        }
1386
1387 23879 jjdelcerro
        public EditableFeatureType createFeatureType() {
1388 27439 jmvivo
                DefaultEditableFeatureType ftype = new DefaultEditableFeatureType();
1389
                ftype.setAllowAutomaticValues(this.provider.allowAutomaticValues());
1390
                return ftype;
1391 23820 jjdelcerro
        }
1392 23772 jjdelcerro
1393 27262 jmvivo
        public EditableFeatureType createFeatureType(String id) {
1394 27439 jmvivo
                DefaultEditableFeatureType ftype = new DefaultEditableFeatureType(id);
1395
                ftype.setAllowAutomaticValues(this.provider.allowAutomaticValues());
1396
                return ftype;
1397 27262 jmvivo
        }
1398
1399
1400 24613 jjdelcerro
        //
1401
        // ====================================================================
1402
        // Index related methods
1403
        //
1404 23879 jjdelcerro
1405 24613 jjdelcerro
        public FeatureIndexes getIndexes() {
1406
                return this.indexes;
1407 23879 jjdelcerro
        }
1408 23894 jjdelcerro
1409 23949 jiyarza
        public FeatureIndex createIndex(FeatureType featureType,
1410
                        String attributeName, String indexName) throws ProviderNotRegisteredException, InitializeException {
1411 24180 jjdelcerro
                checkNotInAppendMode();
1412 23949 jiyarza
                FeatureIndexProviderServices index = null;
1413 27758 cordinyana
                index = dataManager.createFeatureIndexProvider(null, this, featureType,
1414
                indexName, featureType.getAttributeDescriptor(attributeName));
1415 23949 jiyarza
                try {
1416
                        index.fill();
1417 24202 jiyarza
                } catch (FeatureIndexException e) {
1418 23949 jiyarza
                        throw new InitializeException(index.getName(), e);
1419
                }
1420 23995 jmvivo
                ((DefaultFeatureIndexes) getIndexes()).addIndex(index);
1421 23949 jiyarza
                return index;
1422 23894 jjdelcerro
        }
1423 25276 jmvivo
1424 25124 jiyarza
        public FeatureIndex createIndex(FeatureType featureType,
1425
                        String attributeName, String indexName, Observer observer) {
1426
                // TODO Implement observer interaction
1427
                throw new UnsupportedOperationException();
1428
        }
1429 23894 jjdelcerro
1430 24613 jjdelcerro
        //
1431
        // ====================================================================
1432
        // Transforms related methods
1433
        //
1434
1435
        public FeatureStoreTransforms getTransforms() {
1436
                return this.transforms;
1437 24186 vcaballero
        }
1438 25176 jmvivo
1439 24690 vcaballero
        public FeatureQuery createFeatureQuery() {
1440 27575 jmvivo
                return new DefaultFeatureQuery();
1441 26252 jmvivo
        }
1442 24690 vcaballero
1443 27575 jmvivo
        public DataQuery createQuery() {
1444
                return createFeatureQuery();
1445
        }
1446
1447 25785 jmvivo
        //
1448
        // ====================================================================
1449
        // UndoRedo related methods
1450
        //
1451
1452 26252 jmvivo
        public boolean canRedo() {
1453
                return commands.canRedo();
1454
        }
1455 24961 cordinyana
1456 26252 jmvivo
        public boolean canUndo() {
1457
                return commands.canUndo();
1458
        }
1459 24961 cordinyana
1460 26252 jmvivo
        public void redo(int num) throws RedoException {
1461
                commands.redo(num);
1462
        }
1463 24961 cordinyana
1464 26252 jmvivo
        public void undo(int num) throws UndoException {
1465
                commands.undo(num);
1466
        }
1467 25785 jmvivo
1468
        //
1469
        // ====================================================================
1470
        // Metadata related methods
1471
        //
1472
1473
        public Object getMetadataID() {
1474 26837 jmvivo
                return this.provider.getSourceId();
1475 25785 jmvivo
        }
1476
1477
        public void delegate(DynObject dynObject) {
1478
                this.dynObject.delegate(dynObject);
1479
        }
1480
1481
        public DynClass getDynClass() {
1482
                return this.dynObject.getDynClass();
1483
        }
1484
1485
        public Object getDynValue(String name) throws DynFieldNotFoundException {
1486
                return this.dynObject.getDynValue(name);
1487
        }
1488
1489
        public boolean hasDynValue(String name) {
1490
                return this.dynObject.hasDynValue(name);
1491
        }
1492
1493
        public void implement(DynClass dynClass) {
1494
                this.dynObject.implement(dynClass);
1495
        }
1496
1497
        public Object invokeDynMethod(String name, DynObject context)
1498 26252 jmvivo
        throws DynMethodException {
1499 25785 jmvivo
                return this.dynObject.invokeDynMethod(this, name, context);
1500
        }
1501
1502
        public Object invokeDynMethod(int code, DynObject context)
1503 26252 jmvivo
        throws DynMethodException {
1504 25785 jmvivo
                return this.dynObject.invokeDynMethod(this, code, context);
1505
        }
1506
1507
        public void setDynValue(String name, Object value)
1508 26252 jmvivo
        throws DynFieldNotFoundException {
1509 25785 jmvivo
                this.setDynValue(name, value);
1510
1511
        }
1512
1513
        /*
1514
         * (non-Javadoc)
1515 25809 vcaballero
         *
1516 25785 jmvivo
         * @see org.gvsig.metadata.Metadata#getMetadataChildren()
1517
         */
1518
        public Set getMetadataChildren() {
1519
                return null;
1520
        }
1521
1522
        /*
1523
         * (non-Javadoc)
1524 25809 vcaballero
         *
1525 25785 jmvivo
         * @see org.gvsig.metadata.Metadata#getMetadataName()
1526
         */
1527
        public String getMetadataName() {
1528 26837 jmvivo
                return this.provider.getName();
1529 25785 jmvivo
        }
1530
1531 26252 jmvivo
        public FeatureTypeManager getFeatureTypeManager() {
1532
                return this.featureTypeManager;
1533
        }
1534
1535 28017 jmvivo
        public long getFeatureCount() throws DataException {
1536
                if (featureCount == null) {
1537
                        featureCount = new Long(this.provider.getFeatureCount());
1538
                }
1539
                if (this.isEditing() && !this.isAppending()) {
1540
                        return featureCount.longValue()
1541
                                        - this.featureManager.getDeltaSize();
1542
                }
1543
                return featureCount.longValue();
1544
        }
1545 27262 jmvivo
1546 28423 jmvivo
        private Long getTemporalOID() {
1547
                return new Long(this.temporalOid++);
1548
        }
1549 28017 jmvivo
1550 28671 jmvivo
        public FeatureType getProviderFeatureType(String featureTypeId) {
1551
                if (featureTypeId == null) {
1552
                        return this.defaultFeatureType;
1553
                }
1554
                FeatureType type;
1555
                Iterator iter = this.featureTypes.iterator();
1556
                while (iter.hasNext()) {
1557
                        type = (FeatureType) iter.next();
1558
                        if (type.getId().equals(featureTypeId)) {
1559
                                return type;
1560
                        }
1561
                }
1562
                return null;
1563
        }
1564 28423 jmvivo
1565 28671 jmvivo
1566 24961 cordinyana
}