Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.impl / src / main / java / org / gvsig / fmap / dal / feature / impl / DefaultFeatureStore.java @ 43377

History | View | Annotate | Download (85.9 KB)

1 40559 jjdelcerro
/**
2
 * gvSIG. Desktop Geographic Information System.
3 40435 jjdelcerro
 *
4 40559 jjdelcerro
 * Copyright (C) 2007-2013 gvSIG Association.
5 40435 jjdelcerro
 *
6 42293 jjdelcerro
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10 40435 jjdelcerro
 *
11 42293 jjdelcerro
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15 40435 jjdelcerro
 *
16 42293 jjdelcerro
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20 40435 jjdelcerro
 *
21 42293 jjdelcerro
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23 40435 jjdelcerro
 */
24 42293 jjdelcerro
25 40435 jjdelcerro
package org.gvsig.fmap.dal.feature.impl;
26
27 43020 jjdelcerro
import org.gvsig.fmap.dal.feature.spi.SQLBuilderBase;
28 43152 fdiaz
29 40435 jjdelcerro
import java.util.ArrayList;
30
import java.util.Collection;
31
import java.util.Collections;
32
import java.util.HashMap;
33
import java.util.HashSet;
34
import java.util.Iterator;
35
import java.util.List;
36
import java.util.Map;
37
import java.util.Map.Entry;
38
import java.util.Set;
39 43371 fdiaz
40 43215 jjdelcerro
import org.apache.commons.io.FilenameUtils;
41 40435 jjdelcerro
import org.cresques.cts.IProjection;
42 43152 fdiaz
43 40435 jjdelcerro
import org.gvsig.fmap.dal.DALLocator;
44
import org.gvsig.fmap.dal.DataManager;
45
import org.gvsig.fmap.dal.DataQuery;
46
import org.gvsig.fmap.dal.DataServerExplorer;
47
import org.gvsig.fmap.dal.DataSet;
48
import org.gvsig.fmap.dal.DataStore;
49
import org.gvsig.fmap.dal.DataStoreNotification;
50
import org.gvsig.fmap.dal.DataStoreParameters;
51 43152 fdiaz
import org.gvsig.fmap.dal.DataStoreProviderFactory;
52 43088 jjdelcerro
import org.gvsig.fmap.dal.ExpressionEvaluator;
53 40435 jjdelcerro
import org.gvsig.fmap.dal.exception.CloneException;
54
import org.gvsig.fmap.dal.exception.CloseException;
55
import org.gvsig.fmap.dal.exception.CreateException;
56
import org.gvsig.fmap.dal.exception.DataException;
57
import org.gvsig.fmap.dal.exception.InitializeException;
58
import org.gvsig.fmap.dal.exception.OpenException;
59
import org.gvsig.fmap.dal.exception.ReadException;
60
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
61 40597 jldominguez
import org.gvsig.fmap.dal.exception.WriteException;
62 40435 jjdelcerro
import org.gvsig.fmap.dal.feature.EditableFeature;
63
import org.gvsig.fmap.dal.feature.EditableFeatureType;
64
import org.gvsig.fmap.dal.feature.Feature;
65
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
66
import org.gvsig.fmap.dal.feature.FeatureCache;
67
import org.gvsig.fmap.dal.feature.FeatureIndex;
68
import org.gvsig.fmap.dal.feature.FeatureIndexes;
69
import org.gvsig.fmap.dal.feature.FeatureLocks;
70
import org.gvsig.fmap.dal.feature.FeatureQuery;
71
import org.gvsig.fmap.dal.feature.FeatureReference;
72
import org.gvsig.fmap.dal.feature.FeatureReferenceSelection;
73
import org.gvsig.fmap.dal.feature.FeatureSelection;
74
import org.gvsig.fmap.dal.feature.FeatureSet;
75
import org.gvsig.fmap.dal.feature.FeatureStore;
76
import org.gvsig.fmap.dal.feature.FeatureStoreNotification;
77 43358 jjdelcerro
import org.gvsig.fmap.dal.feature.FeatureStoreProviderFactory;
78 40435 jjdelcerro
import org.gvsig.fmap.dal.feature.FeatureStoreTransforms;
79
import org.gvsig.fmap.dal.feature.FeatureType;
80
import org.gvsig.fmap.dal.feature.NewFeatureStoreParameters;
81 43135 jjdelcerro
import org.gvsig.fmap.dal.feature.FeatureStoreTimeSupport;
82 43215 jjdelcerro
import org.gvsig.fmap.dal.feature.FeatureStoreTransform;
83 40435 jjdelcerro
import org.gvsig.fmap.dal.feature.exception.AlreadyEditingException;
84
import org.gvsig.fmap.dal.feature.exception.ConcurrentDataModificationException;
85
import org.gvsig.fmap.dal.feature.exception.CreateFeatureException;
86
import org.gvsig.fmap.dal.feature.exception.DataExportException;
87
import org.gvsig.fmap.dal.feature.exception.FeatureIndexException;
88
import org.gvsig.fmap.dal.feature.exception.FinishEditingException;
89
import org.gvsig.fmap.dal.feature.exception.GetFeatureTypeException;
90
import org.gvsig.fmap.dal.feature.exception.IllegalFeatureException;
91
import org.gvsig.fmap.dal.feature.exception.IllegalFeatureTypeException;
92
import org.gvsig.fmap.dal.feature.exception.NeedEditingModeException;
93
import org.gvsig.fmap.dal.feature.exception.NoNewFeatureInsertException;
94
import org.gvsig.fmap.dal.feature.exception.NullFeatureTypeException;
95 40597 jldominguez
import org.gvsig.fmap.dal.feature.exception.PerformEditingException;
96 40435 jjdelcerro
import org.gvsig.fmap.dal.feature.exception.PersistenceCantFindFeatureTypeException;
97
import org.gvsig.fmap.dal.feature.exception.PersistenceStoreAlreadyLoadedException;
98
import org.gvsig.fmap.dal.feature.exception.SelectionNotAllowedException;
99
import org.gvsig.fmap.dal.feature.exception.StoreCancelEditingException;
100
import org.gvsig.fmap.dal.feature.exception.StoreDeleteEditableFeatureException;
101
import org.gvsig.fmap.dal.feature.exception.StoreDeleteFeatureException;
102
import org.gvsig.fmap.dal.feature.exception.StoreEditException;
103
import org.gvsig.fmap.dal.feature.exception.StoreInsertFeatureException;
104
import org.gvsig.fmap.dal.feature.exception.StoreUpdateFeatureException;
105
import org.gvsig.fmap.dal.feature.exception.StoreUpdateFeatureTypeException;
106
import org.gvsig.fmap.dal.feature.exception.ValidateFeaturesException;
107
import org.gvsig.fmap.dal.feature.exception.WriteNotAllowedException;
108
import org.gvsig.fmap.dal.feature.impl.expansionadapter.MemoryExpansionAdapter;
109
import org.gvsig.fmap.dal.feature.impl.featureset.DefaultFeatureSet;
110 42775 jjdelcerro
import org.gvsig.fmap.dal.feature.impl.dynobjectutils.DynObjectFeatureFacade;
111 40435 jjdelcerro
import org.gvsig.fmap.dal.feature.impl.undo.DefaultFeatureCommandsStack;
112
import org.gvsig.fmap.dal.feature.impl.undo.FeatureCommandsStack;
113 42925 jjdelcerro
import org.gvsig.fmap.dal.feature.paging.FeaturePagingHelper;
114 40435 jjdelcerro
import org.gvsig.fmap.dal.feature.spi.DefaultFeatureProvider;
115
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
116
import org.gvsig.fmap.dal.feature.spi.FeatureReferenceProviderServices;
117
import org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider;
118
import org.gvsig.fmap.dal.feature.spi.FeatureStoreProviderServices;
119 43020 jjdelcerro
import org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider_v2;
120 40435 jjdelcerro
import org.gvsig.fmap.dal.feature.spi.cache.FeatureCacheProvider;
121
import org.gvsig.fmap.dal.feature.spi.index.FeatureIndexProviderServices;
122
import org.gvsig.fmap.dal.impl.DefaultDataManager;
123
import org.gvsig.fmap.dal.resource.Resource;
124 43020 jjdelcerro
import org.gvsig.fmap.dal.spi.DataStoreInitializer2;
125 40435 jjdelcerro
import org.gvsig.fmap.dal.spi.DataStoreProvider;
126 43020 jjdelcerro
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
127 43358 jjdelcerro
import org.gvsig.fmap.geom.GeometryLocator;
128
import org.gvsig.fmap.geom.GeometryManager;
129
import org.gvsig.fmap.geom.SpatialIndex;
130 40435 jjdelcerro
import org.gvsig.fmap.geom.primitive.Envelope;
131
import org.gvsig.metadata.MetadataLocator;
132
import org.gvsig.metadata.MetadataManager;
133
import org.gvsig.metadata.exceptions.MetadataException;
134
import org.gvsig.timesupport.Interval;
135
import org.gvsig.tools.ToolsLocator;
136
import org.gvsig.tools.dispose.DisposableIterator;
137
import org.gvsig.tools.dispose.impl.AbstractDisposable;
138
import org.gvsig.tools.dynobject.DelegatedDynObject;
139
import org.gvsig.tools.dynobject.DynClass;
140
import org.gvsig.tools.dynobject.DynObject;
141
import org.gvsig.tools.dynobject.DynObjectManager;
142 43246 jjdelcerro
import org.gvsig.tools.dynobject.DynObject_v2;
143 40435 jjdelcerro
import org.gvsig.tools.dynobject.DynStruct;
144
import org.gvsig.tools.dynobject.exception.DynFieldNotFoundException;
145
import org.gvsig.tools.dynobject.exception.DynMethodException;
146
import org.gvsig.tools.exception.BaseException;
147
import org.gvsig.tools.exception.NotYetImplemented;
148 41928 jjdelcerro
import org.gvsig.tools.identitymanagement.SimpleIdentityManager;
149 40435 jjdelcerro
import org.gvsig.tools.observer.Observable;
150
import org.gvsig.tools.observer.Observer;
151
import org.gvsig.tools.observer.impl.DelegateWeakReferencingObservable;
152
import org.gvsig.tools.persistence.PersistenceManager;
153
import org.gvsig.tools.persistence.Persistent;
154
import org.gvsig.tools.persistence.PersistentState;
155
import org.gvsig.tools.persistence.exception.PersistenceException;
156
import org.gvsig.tools.undo.RedoException;
157
import org.gvsig.tools.undo.UndoException;
158
import org.gvsig.tools.undo.command.Command;
159 43215 jjdelcerro
import org.gvsig.tools.util.HasAFile;
160 40435 jjdelcerro
import org.gvsig.tools.visitor.Visitor;
161 43152 fdiaz
162 42533 dmartinezizquierdo
import org.slf4j.Logger;
163
import org.slf4j.LoggerFactory;
164 40435 jjdelcerro
165 41243 jjdelcerro
public class DefaultFeatureStore extends AbstractDisposable implements
166 43020 jjdelcerro
    DataStoreInitializer2, FeatureStoreProviderServices, FeatureStore, Observer {
167 40435 jjdelcerro
168
    private static final Logger LOG = LoggerFactory
169 42293 jjdelcerro
        .getLogger(DefaultFeatureStore.class);
170 40435 jjdelcerro
171
    private static final String PERSISTENCE_DEFINITION_NAME = "FeatureStore";
172
173
    private DataStoreParameters parameters = null;
174
    private FeatureSelection selection;
175
    private FeatureLocks locks;
176
177 42293 jjdelcerro
    private DelegateWeakReferencingObservable delegateObservable =
178
        new DelegateWeakReferencingObservable(this);
179 40435 jjdelcerro
180
    private FeatureCommandsStack commands;
181
    private FeatureTypeManager featureTypeManager;
182
    private FeatureManager featureManager;
183
    private SpatialManager spatialManager;
184
185
    private FeatureType defaultFeatureType = null;
186
    private List featureTypes = new ArrayList();
187
188
    private int mode = MODE_QUERY;
189
    private long versionOfUpdate = 0;
190
    private boolean hasStrongChanges = true;
191
    private boolean hasInserts = true;
192
193
    private DefaultDataManager dataManager = null;
194
195
    private FeatureStoreProvider provider = null;
196
197
    private DefaultFeatureIndexes indexes;
198
199
    private DefaultFeatureStoreTransforms transforms;
200
201
    DelegatedDynObject metadata;
202 41818 fdiaz
203 40435 jjdelcerro
    private Set metadataChildren;
204
205
    private Long featureCount = null;
206
207
    private long temporalOid = 0;
208
209
    private FeatureCacheProvider cache;
210
211 43215 jjdelcerro
    StateInformation state;
212 43270 fdiaz
213 43135 jjdelcerro
    FeatureStoreTimeSupport timeSupport;
214 43215 jjdelcerro
215
216
    private class StateInformation extends HashMap<Object, Object> {
217
218
        private static final long serialVersionUID = 4109026189635185666L;
219
220
        private boolean broken;
221
        private Throwable breakingsCause;
222 43270 fdiaz
223 43215 jjdelcerro
        public StateInformation() {
224
            this.clear();
225
        }
226 43270 fdiaz
227 43215 jjdelcerro
        @Override
228
        public void clear() {
229
            this.broken = false;
230
            this.breakingsCause = null;
231
            super.clear();
232
        }
233 43270 fdiaz
234 43215 jjdelcerro
        public boolean isBroken() {
235
            return this.broken;
236
        }
237 43270 fdiaz
238 43215 jjdelcerro
        public void broken() {
239
            this.broken = true;
240
        }
241 43270 fdiaz
242 43215 jjdelcerro
        public Throwable getBreakingsCause() {
243
            return this.breakingsCause;
244
        }
245 43270 fdiaz
246 43215 jjdelcerro
        public void setBreakingsCause(Throwable cause) {
247
            if( this.breakingsCause==null ) {
248
                this.breakingsCause = cause;
249
            }
250
            this.broken = true;
251 43270 fdiaz
        }
252 43215 jjdelcerro
    }
253
254
255 43270 fdiaz
256 40435 jjdelcerro
    /*
257
     * TODO:
258 41818 fdiaz
     *
259 40435 jjdelcerro
     * - Comprobar que solo se pueden a?adir reglas de validacion sobre un
260
     * EditableFeatureType. - Comprobar que solo se puede hacer un update con un
261
     * featureType al que se le han cambiado las reglas de validacion cuando
262
     * hasStrongChanges=false.
263
     */
264 42293 jjdelcerro
265 40435 jjdelcerro
    public DefaultFeatureStore() {
266 43215 jjdelcerro
        this.state = new StateInformation();
267 40435 jjdelcerro
    }
268
269 43020 jjdelcerro
    @Override
270
    public void intialize(DataManager dataManager,
271 42293 jjdelcerro
        DataStoreParameters parameters) throws InitializeException {
272 40435 jjdelcerro
273
        DynObjectManager dynManager = ToolsLocator.getDynObjectManager();
274
275 43020 jjdelcerro
        this.metadata = (DelegatedDynObject) dynManager.createDynObject(
276 43152 fdiaz
            FeatureStore.METADATA_DEFINITION_NAME,
277 43020 jjdelcerro
            MetadataManager.METADATA_NAMESPACE
278
        );
279 40435 jjdelcerro
280
        this.dataManager = (DefaultDataManager) dataManager;
281
282
        this.parameters = parameters;
283
        this.transforms = new DefaultFeatureStoreTransforms(this);
284
        try {
285
            indexes = new DefaultFeatureIndexes(this);
286
        } catch (DataException e) {
287
            throw new InitializeException(e);
288
        }
289
290
    }
291
292 43020 jjdelcerro
    @Override
293
    public void setProvider(org.gvsig.fmap.dal.DataStoreProvider provider) {
294 40435 jjdelcerro
        this.provider = (FeatureStoreProvider) provider;
295 43020 jjdelcerro
        this.delegate((DynObject) provider);
296 40435 jjdelcerro
        this.metadataChildren = new HashSet();
297
        this.metadataChildren.add(provider);
298
    }
299
300 43215 jjdelcerro
    @Override
301 40435 jjdelcerro
    public DataStoreParameters getParameters() {
302
        return parameters;
303
    }
304
305
    public int getMode() {
306
        return this.mode;
307
    }
308
309 43215 jjdelcerro
    @Override
310 40435 jjdelcerro
    public DataManager getManager() {
311
        return this.dataManager;
312
    }
313
314 43215 jjdelcerro
    @Override
315 40435 jjdelcerro
    public Iterator getChildren() {
316
        return this.provider.getChilds();
317
    }
318
319 43215 jjdelcerro
    @Override
320 40435 jjdelcerro
    public FeatureStoreProvider getProvider() {
321
        return this.provider;
322
    }
323
324
    public FeatureManager getFeatureManager() {
325
        return this.featureManager;
326
    }
327
328 43215 jjdelcerro
    @Override
329 40435 jjdelcerro
    public void setFeatureTypes(List types, FeatureType defaultType) {
330
        this.featureTypes = types;
331
        this.defaultFeatureType = defaultType;
332
    }
333
334
    public void open() throws OpenException {
335 42049 jjdelcerro
        if (this.mode != MODE_QUERY) {
336
            // TODO: Se puede hacer un open estando en edicion ?
337
            try {
338
                throw new IllegalStateException();
339 42293 jjdelcerro
            } catch(Exception ex) {
340
                LOG.warn("Opening a store in editing/append mode ("+this.getFullName()+").",ex);
341 42049 jjdelcerro
            }
342
        }
343 40435 jjdelcerro
        this.notifyChange(DataStoreNotification.BEFORE_OPEN);
344
        this.provider.open();
345
        this.notifyChange(DataStoreNotification.AFTER_OPEN);
346
    }
347
348 43215 jjdelcerro
    @Override
349 40435 jjdelcerro
    public void refresh() throws OpenException, InitializeException {
350
        if (this.mode != MODE_QUERY) {
351
            throw new IllegalStateException();
352
        }
353
        this.notifyChange(FeatureStoreNotification.BEFORE_REFRESH);
354 43215 jjdelcerro
        if( state.isBroken() ) {
355
            this.load(state);
356
        } else {
357
            this.featureCount = null;
358
            this.provider.refresh();
359
        }
360 40435 jjdelcerro
        this.notifyChange(FeatureStoreNotification.AFTER_REFRESH);
361
    }
362
363
    public void close() throws CloseException {
364 42049 jjdelcerro
        if (this.mode != MODE_QUERY) {
365
            // TODO: Se puede hacer un close estando en edicion ?
366
            try {
367
                throw new IllegalStateException();
368 42293 jjdelcerro
            } catch(Exception ex) {
369
                LOG.warn("Clossing a store in editing/append mode ("+this.getFullName()+").",ex);
370 42049 jjdelcerro
            }
371
        }
372 40435 jjdelcerro
        this.notifyChange(DataStoreNotification.BEFORE_CLOSE);
373
        this.featureCount = null;
374
        this.provider.close();
375
        this.notifyChange(DataStoreNotification.AFTER_CLOSE);
376
    }
377
378 43215 jjdelcerro
    @Override
379 40435 jjdelcerro
    protected void doDispose() throws BaseException {
380 42049 jjdelcerro
        if (this.mode != MODE_QUERY) {
381
            // TODO: Se puede hacer un dispose estando en edicion ?
382
            try {
383
                throw new IllegalStateException();
384 42293 jjdelcerro
            } catch(Exception ex) {
385
                LOG.warn("Dispossing a store in editing/append mode ("+this.getFullName()+").",ex);
386 42049 jjdelcerro
            }
387
        }
388 40435 jjdelcerro
        this.notifyChange(DataStoreNotification.BEFORE_DISPOSE);
389
        this.disposeIndexes();
390 43377 jjdelcerro
        if( this.provider!=null ) {
391
            this.provider.dispose();
392
        }
393 40435 jjdelcerro
        if (this.selection != null) {
394
            this.selection.dispose();
395
            this.selection = null;
396
        }
397
        this.commands = null;
398
        this.featureCount = null;
399
        if (this.locks != null) {
400
            // this.locks.dispose();
401
            this.locks = null;
402
        }
403
404
        if (this.featureTypeManager != null) {
405
            this.featureTypeManager.dispose();
406
            this.featureTypeManager = null;
407
        }
408
409
        this.featureManager = null;
410
        this.spatialManager = null;
411
412
        this.parameters = null;
413
        this.notifyChange(DataStoreNotification.AFTER_DISPOSE);
414
        if (delegateObservable != null) {
415
            this.delegateObservable.deleteObservers();
416
            this.delegateObservable = null;
417
        }
418
    }
419
420 43215 jjdelcerro
    @Override
421 40435 jjdelcerro
    public boolean allowWrite() {
422 41928 jjdelcerro
        SimpleIdentityManager identityManager = ToolsLocator.getIdentityManager();
423 42293 jjdelcerro
        if( ! identityManager.getCurrentIdentity().isAuthorized(DataManager.WRITE_STORE_AUTHORIZATION,this.getParameters(), this.getName()) ) {
424 41928 jjdelcerro
            return false;
425
        }
426 40435 jjdelcerro
        return this.provider.allowWrite();
427
    }
428
429 43215 jjdelcerro
    @Override
430 40435 jjdelcerro
    public boolean canWriteGeometry(int geometryType) throws DataException {
431
        return this.provider.canWriteGeometry(geometryType, 0);
432
    }
433
434 43215 jjdelcerro
    @Override
435 40435 jjdelcerro
    public DataServerExplorer getExplorer() throws ReadException,
436 42293 jjdelcerro
        ValidateDataParametersException {
437 43215 jjdelcerro
        if( this.state.isBroken() ) {
438
            try {
439
                return this.provider.getExplorer();
440
            } catch(Throwable th) {
441
                return null;
442
            }
443
        } else {
444
            return this.provider.getExplorer();
445
        }
446 40435 jjdelcerro
    }
447
448
    /*
449
     * public Metadata getMetadata() throws MetadataNotFoundException {
450
     * // TODO:
451
     * // Si el provider devuelbe null habria que ver de construir aqui
452
     * // los metadatos basicos, como el Envelope y el SRS.
453 41818 fdiaz
     *
454 40435 jjdelcerro
     * // TODO: Estando en edicion el Envelope deberia de
455
     * // actualizarse usando el spatialManager
456
     * return this.provider.getMetadata();
457
     * }
458
     */
459 42293 jjdelcerro
460 43215 jjdelcerro
    @Override
461 40435 jjdelcerro
    public Envelope getEnvelope() throws DataException {
462
        if (this.mode == MODE_FULLEDIT) {
463 42293 jjdelcerro
                // Just in case another thread tries to write in the store
464
                synchronized (this) {
465
                        return this.spatialManager.getEnvelope();
466
                        }
467 40435 jjdelcerro
        }
468 42293 jjdelcerro
        if (hasDynValue(DataStore.METADATA_ENVELOPE)){
469
            return (Envelope)getDynValue(DataStore.METADATA_ENVELOPE);
470 40435 jjdelcerro
        }
471
        return this.provider.getEnvelope();
472
    }
473
474
    /**
475
     * @deprecated use getDefaultFeatureType().getDefaultSRS()
476
     */
477 43215 jjdelcerro
    @Override
478 40435 jjdelcerro
    public IProjection getSRSDefaultGeometry() throws DataException {
479
        return this.getDefaultFeatureType().getDefaultSRS();
480
    }
481
482 43215 jjdelcerro
    @Override
483 40435 jjdelcerro
    public FeatureSelection createDefaultFeatureSelection()
484 42293 jjdelcerro
        throws DataException {
485 40435 jjdelcerro
        return new DefaultFeatureSelection(this);
486
    }
487
488 43215 jjdelcerro
    @Override
489 40435 jjdelcerro
    public FeatureProvider createDefaultFeatureProvider(FeatureType type)
490 42293 jjdelcerro
        throws DataException {
491 40435 jjdelcerro
        if (type.hasOID()) {
492
            return new DefaultFeatureProvider(type,
493 42293 jjdelcerro
                this.provider.createNewOID());
494 40435 jjdelcerro
        }
495
        return new DefaultFeatureProvider(type);
496
    }
497
498 43215 jjdelcerro
    @Override
499 40435 jjdelcerro
    public void saveToState(PersistentState state) throws PersistenceException {
500 40776 nbrodin
        /*if (this.mode != FeatureStore.MODE_QUERY) {
501 42293 jjdelcerro
            throw new PersistenceException(new IllegalStateException(
502
                this.getName()));
503
        }*/
504 40435 jjdelcerro
        state.set("dataStoreName", this.getName());
505
        state.set("parameters", this.parameters);
506
        state.set("selection", this.selection);
507
        state.set("transforms", this.transforms);
508
        // TODO locks persistence
509
        // state.set("locks", this.locks);
510
        // TODO indexes persistence
511
        // state.set("indexes", this.indexes);
512
        Map evaluatedAttr = new HashMap(1);
513
        Iterator iterType = featureTypes.iterator();
514
        Iterator iterAttr;
515
        FeatureType type;
516
        DefaultFeatureAttributeDescriptor attr;
517
        List attrs;
518
        while (iterType.hasNext()) {
519
            type = (FeatureType) iterType.next();
520
            attrs = new ArrayList();
521
            iterAttr = type.iterator();
522
            while (iterAttr.hasNext()) {
523
                attr = (DefaultFeatureAttributeDescriptor) iterAttr.next();
524
                if ((attr.getEvaluator() != null)
525 42293 jjdelcerro
                    && (attr.getEvaluator() instanceof Persistent)) {
526 40435 jjdelcerro
                    attrs.add(attr);
527
                }
528
            }
529
            if (!attrs.isEmpty()) {
530
                evaluatedAttr.put(type.getId(), attrs);
531
            }
532
533
        }
534
535
        if (evaluatedAttr.isEmpty()) {
536
            evaluatedAttr = null;
537
        }
538
539
        state.set("evaluatedAttributes", evaluatedAttr);
540
        state.set("defaultFeatureTypeId", defaultFeatureType.getId());
541
542
    }
543 43270 fdiaz
544 43215 jjdelcerro
    @Override
545
    public void loadFromState(final PersistentState persistentState)
546 42293 jjdelcerro
        throws PersistenceException {
547 40435 jjdelcerro
        if (this.provider != null) {
548
            throw new PersistenceStoreAlreadyLoadedException(this.getName());
549
        }
550
        if (this.getManager() == null) {
551
            this.dataManager = (DefaultDataManager) DALLocator.getDataManager();
552
        }
553 43215 jjdelcerro
        state.clear();
554
        try {
555
            state.put("parameters", persistentState.get("parameters"));
556
        } catch(Throwable th) {
557
            state.setBreakingsCause(th);
558
        }
559
        try {
560
            state.put("selection", persistentState.get("selection"));
561
        } catch(Throwable th) {
562
            state.setBreakingsCause(th);
563
        }
564
        try {
565
            state.put("transforms",  persistentState.get("transforms"));
566
        } catch(Throwable th) {
567
            state.setBreakingsCause(th);
568
        }
569
        try {
570
            state.put("evaluatedAttributes",  persistentState.get("evaluatedAttributes"));
571
        } catch(Throwable th) {
572
            state.setBreakingsCause(th);
573
        }
574
        try {
575
            state.put("defaultFeatureTypeId", persistentState.getString("defaultFeatureTypeId"));
576
        } catch(Throwable th) {
577
            state.setBreakingsCause(th);
578
        }
579
        load(state);
580 43270 fdiaz
    }
581
582
    private void load(StateInformation state) {
583 43215 jjdelcerro
        this.featureTypes = new ArrayList();
584
        this.defaultFeatureType = null;
585
        this.featureCount = null;
586 40435 jjdelcerro
587 43215 jjdelcerro
        DataStoreParameters params = (DataStoreParameters) state.get("parameters");
588
        try {
589
            intialize(dataManager, params);
590
        } catch(Throwable th) {
591
            state.setBreakingsCause(th);
592
        }
593 40435 jjdelcerro
594
        try {
595 43215 jjdelcerro
            DataStoreProvider prov = dataManager.createProvider(
596
                getStoreProviderServices(),
597
                params
598 43020 jjdelcerro
            );
599 43215 jjdelcerro
            setProvider(prov);
600
        } catch(Throwable th) {
601
            state.setBreakingsCause(th);
602
        }
603 43152 fdiaz
604 43215 jjdelcerro
        try {
605
            selection = (FeatureSelection) state.get("selection");
606
        } catch(Throwable th) {
607
            state.setBreakingsCause(th);
608
        }
609
610
        try {
611
            this.transforms = (DefaultFeatureStoreTransforms) state.get("transforms");
612
            this.transforms.setFeatureStore(this);
613
            for( FeatureStoreTransform transform : this.transforms ) {
614
                try {
615
                    transform.setUp();
616
                } catch(Throwable th) {
617
                    state.setBreakingsCause(th);
618
                }
619
            }
620
        } catch(Throwable th) {
621
            state.setBreakingsCause(th);
622
        }
623
624
        try {
625 40435 jjdelcerro
            Map evaluatedAttributes = (Map) state.get("evaluatedAttributes");
626
            if ((evaluatedAttributes != null) && !evaluatedAttributes.isEmpty()) {
627 43215 jjdelcerro
                    Iterator iterEntries = evaluatedAttributes.entrySet().iterator();
628
                    while (iterEntries.hasNext()) {
629
                            Entry entry = (Entry) iterEntries.next();
630
                            List attrs = (List) entry.getValue();
631
                            if (attrs.isEmpty()) {
632
                                    continue;
633
                            }
634
                            int fTypePos = -1;
635
                            DefaultFeatureType type = null;
636
                            for (int i = 0; i < featureTypes.size(); i++) {
637
                                    type = (DefaultFeatureType) featureTypes.get(i);
638
                                    if (type.getId().equals(entry.getKey())) {
639
                                            fTypePos = i;
640
                                            break;
641
                                    }
642
                            }
643
                            if (type == null) {
644
                                    throw new PersistenceCantFindFeatureTypeException(
645
                                            getName(), (String) entry.getKey());
646
                            }
647
                            DefaultEditableFeatureType eType = (DefaultEditableFeatureType) type.getEditable();
648
                            Iterator<FeatureAttributeDescriptor> iterAttr = attrs.iterator();
649
                            while (iterAttr.hasNext()) {
650
                                    FeatureAttributeDescriptor attr = iterAttr.next();
651
                                    eType.addLike(attr);
652
                            }
653
                            featureTypes.set(fTypePos, eType.getNotEditableCopy());
654
655 40435 jjdelcerro
                    }
656
657
            }
658 43215 jjdelcerro
        } catch(Throwable th) {
659
            state.setBreakingsCause(th);
660
        }
661 40435 jjdelcerro
662 43270 fdiaz
663 43215 jjdelcerro
        try {
664
            String defaultFeatureTypeId = (String) state.get("defaultFeatureTypeId");
665
            FeatureType ftype;
666 41818 fdiaz
667 43215 jjdelcerro
            if (defaultFeatureType == null ||
668
                    defaultFeatureType.getId() == null ||
669
                    !defaultFeatureType.getId().equals(defaultFeatureTypeId)) {
670 40435 jjdelcerro
671 43215 jjdelcerro
                    ftype = getFeatureType(defaultFeatureTypeId);
672
                    if (ftype == null) {
673
                            /*
674
                             * Un error en el m?todo de PostgreSQL getName(), hace que
675
                             * el nombre del featureType sea valor retornado por el getProviderName()
676
                             * De momento se pone este parche para apa?arlo y poder mantener compatibilidad
677
                             * con proyectos antiguos (2.1 y 2.2)
678
                             */
679
                            ftype = getFeatureType(getName());
680
                            if(ftype == null ) {
681
                                    throw new RuntimeException("Can't locate feature type");
682
                            }
683
                    }
684
                    defaultFeatureType = ftype;
685 40435 jjdelcerro
            }
686 43215 jjdelcerro
        } catch(Throwable th) {
687
            state.setBreakingsCause(th);
688 40435 jjdelcerro
        }
689
690 43270 fdiaz
        LOG.info("load() broken:{}, {}, {}.",
691 43215 jjdelcerro
                new Object[] { state.isBroken(), this.getProviderName(), params }
692
        );
693 40435 jjdelcerro
    }
694
695 43215 jjdelcerro
        public DataStoreProviderServices getStoreProviderServices() {
696
                return this;
697
        }
698 43270 fdiaz
699 40435 jjdelcerro
    public static void registerPersistenceDefinition() {
700
        PersistenceManager manager = ToolsLocator.getPersistenceManager();
701
        if (manager.getDefinition(PERSISTENCE_DEFINITION_NAME) == null) {
702 42293 jjdelcerro
            DynStruct definition =
703
                manager.addDefinition(DefaultFeatureStore.class,
704
                    PERSISTENCE_DEFINITION_NAME, PERSISTENCE_DEFINITION_NAME
705
                        + " Persistent definition", null, null);
706 40435 jjdelcerro
            definition.addDynFieldString("dataStoreName").setMandatory(true)
707 42293 jjdelcerro
                .setPersistent(true);
708 40435 jjdelcerro
709
            definition.addDynFieldObject("parameters")
710 42293 jjdelcerro
                .setClassOfValue(DynObject.class).setMandatory(true)
711
                .setPersistent(true);
712 40435 jjdelcerro
713
            definition.addDynFieldObject("selection")
714 42293 jjdelcerro
                .setClassOfValue(FeatureSelection.class).setMandatory(false)
715
                .setPersistent(true);
716 40435 jjdelcerro
717
            definition.addDynFieldObject("transforms")
718 42293 jjdelcerro
                .setClassOfValue(DefaultFeatureStoreTransforms.class)
719
                .setMandatory(true).setPersistent(true);
720 40435 jjdelcerro
721
            definition.addDynFieldMap("evaluatedAttributes")
722 42293 jjdelcerro
                .setClassOfItems(List.class) // List<DefaultFeatureAttributeDescriptor>
723
                .setMandatory(false).setPersistent(true);
724 40435 jjdelcerro
725
            definition.addDynFieldString("defaultFeatureTypeId")
726 42293 jjdelcerro
                .setMandatory(true).setPersistent(true);
727 40435 jjdelcerro
        }
728
    }
729
730
    public static void registerMetadataDefinition() throws MetadataException {
731
        MetadataManager manager = MetadataLocator.getMetadataManager();
732 43020 jjdelcerro
        if (manager.getDefinition(FeatureStore.METADATA_DEFINITION_NAME) == null) {
733 42293 jjdelcerro
            DynStruct metadataDefinition =
734 43020 jjdelcerro
                manager.addDefinition(FeatureStore.METADATA_DEFINITION_NAME, null);
735 40435 jjdelcerro
            metadataDefinition.extend(manager
736 42293 jjdelcerro
                .getDefinition(DataStore.METADATA_DEFINITION_NAME));
737 40435 jjdelcerro
        }
738
    }
739
740
    //
741
    // ====================================================================
742
    // Gestion de la seleccion
743
    //
744 42293 jjdelcerro
745 43215 jjdelcerro
    @Override
746 40435 jjdelcerro
    public void setSelection(DataSet selection) throws DataException {
747
        this.setSelection((FeatureSet) selection);
748
    }
749
750 43215 jjdelcerro
    @Override
751 40435 jjdelcerro
    public DataSet createSelection() throws DataException {
752
        return createFeatureSelection();
753
    }
754
755 43215 jjdelcerro
    @Override
756 40435 jjdelcerro
    public DataSet getSelection() throws DataException {
757
        return this.getFeatureSelection();
758
    }
759
760 43215 jjdelcerro
    @Override
761 40435 jjdelcerro
    public void setSelection(FeatureSet selection) throws DataException {
762
        setSelection(selection, true);
763
    }
764
765
    public void setSelection(FeatureSet selection, boolean undoable)
766 42293 jjdelcerro
        throws DataException {
767 40435 jjdelcerro
        if (selection == null) {
768
            if (undoable) {
769
                throw new SelectionNotAllowedException(getName());
770
            }
771
772
        } else {
773
            if (selection.equals(this.selection)) {
774
                return;
775
            }
776
            if (!selection.isFromStore(this)) {
777
                throw new SelectionNotAllowedException(getName());
778
            }
779
        }
780
781
        if (this.selection != null) {
782
            this.selection.deleteObserver(this);
783
        }
784
        if (selection == null) {
785
            if (this.selection != null) {
786
                this.selection.dispose();
787
            }
788
            this.selection = null;
789
            return;
790
        }
791
        if (selection instanceof FeatureSelection) {
792
            if (undoable && isEditing()) {
793
                commands.selectionSet(this, this.selection,
794 42293 jjdelcerro
                    (FeatureSelection) selection);
795 40435 jjdelcerro
            }
796
            if (this.selection != null) {
797
                this.selection.dispose();
798
            }
799
            this.selection = (FeatureSelection) selection;
800
        } else {
801
            if (undoable && isEditing()) {
802
                commands.startComplex("_selectionSet");
803
            }
804
            if (selection instanceof DefaultFeatureSelection) {
805 42293 jjdelcerro
                DefaultFeatureSelection defSelection =
806
                    (DefaultFeatureSelection) selection;
807 40435 jjdelcerro
                defSelection.deselectAll(undoable);
808
                defSelection.select(selection, undoable);
809
            } else {
810
                this.selection.deselectAll();
811
                this.selection.select(selection);
812
            }
813
            if (undoable && isEditing()) {
814
                commands.endComplex();
815
            }
816
        }
817
        this.selection.addObserver(this);
818
819
        this.notifyChange(DataStoreNotification.SELECTION_CHANGE);
820
    }
821
822 43215 jjdelcerro
    @Override
823 40435 jjdelcerro
    public FeatureSelection createFeatureSelection() throws DataException {
824
        return this.provider.createFeatureSelection();
825
    }
826
827 43215 jjdelcerro
    @Override
828 40435 jjdelcerro
    public FeatureSelection getFeatureSelection() throws DataException {
829
        if (selection == null) {
830
            this.selection = createFeatureSelection();
831
            this.selection.addObserver(this);
832
        }
833
        return selection;
834
    }
835
836
    //
837
    // ====================================================================
838
    // Gestion de notificaciones
839
    //
840 42293 jjdelcerro
841 43093 jjdelcerro
    @Override
842
    public void notifyChange(FeatureStoreNotification storeNotification) {
843
        try {
844
            delegateObservable.notifyObservers(storeNotification);
845
        } catch (Throwable ex) {
846
            LOG.warn("Problems notifying changes in the store '"+this.getName()+" ("+storeNotification.getType()+").",ex);
847
        }
848
    }
849
850
    @Override
851 40435 jjdelcerro
    public void notifyChange(String notification) {
852
        if (delegateObservable != null) {
853
            notifyChange(new DefaultFeatureStoreNotification(this, notification));
854
        }
855
856
    }
857
858 43093 jjdelcerro
    @Override
859 40435 jjdelcerro
    public void notifyChange(String notification, FeatureProvider data) {
860 43093 jjdelcerro
        Feature f = null;
861 40435 jjdelcerro
        try {
862 43093 jjdelcerro
            f = createFeature(data);
863
        } catch (Throwable ex) {
864
            LOG.warn("Problems creating a feature to notifying changes in the store '"+this.getName()+" ("+notification+").",ex);
865 40435 jjdelcerro
        }
866 43093 jjdelcerro
        notifyChange(notification, f);
867 40435 jjdelcerro
    }
868
869
    public void notifyChange(String notification, Feature feature) {
870
        notifyChange(new DefaultFeatureStoreNotification(this, notification,
871 42293 jjdelcerro
            feature));
872 40435 jjdelcerro
    }
873
874
    public void notifyChange(String notification, Command command) {
875
        notifyChange(new DefaultFeatureStoreNotification(this, notification,
876 42293 jjdelcerro
            command));
877 40435 jjdelcerro
    }
878
879
    public void notifyChange(String notification, EditableFeatureType type) {
880
        notifyChange(new DefaultFeatureStoreNotification(this, notification,
881 42293 jjdelcerro
            type));
882 40435 jjdelcerro
    }
883
884 43093 jjdelcerro
    @Override
885 40435 jjdelcerro
    public void notifyChange(String notification, Resource resource) {
886
        notifyChange(new DefaultFeatureStoreNotification(this,
887 42293 jjdelcerro
            DataStoreNotification.RESOURCE_CHANGED));
888 40435 jjdelcerro
    }
889
890
    //
891
    // ====================================================================
892
    // Gestion de bloqueos
893
    //
894 42293 jjdelcerro
895 43215 jjdelcerro
    @Override
896 40435 jjdelcerro
    public boolean isLocksSupported() {
897
        return this.provider.isLocksSupported();
898
    }
899
900 43215 jjdelcerro
    @Override
901 40435 jjdelcerro
    public FeatureLocks getLocks() throws DataException {
902
        if (!this.provider.isLocksSupported()) {
903
            LOG.warn("Locks not supported");
904
            return null;
905
        }
906
        if (locks == null) {
907
            this.locks = this.provider.createFeatureLocks();
908
        }
909
        return locks;
910
    }
911
912
    //
913
    // ====================================================================
914
    // Interface Observable
915
    //
916 42293 jjdelcerro
917 43215 jjdelcerro
    @Override
918 40435 jjdelcerro
    public void disableNotifications() {
919
        this.delegateObservable.disableNotifications();
920
921
    }
922
923 43215 jjdelcerro
    @Override
924 40435 jjdelcerro
    public void enableNotifications() {
925
        this.delegateObservable.enableNotifications();
926
    }
927
928 43215 jjdelcerro
    @Override
929 40435 jjdelcerro
    public void beginComplexNotification() {
930
        this.delegateObservable.beginComplexNotification();
931
932
    }
933
934 43215 jjdelcerro
    @Override
935 40435 jjdelcerro
    public void endComplexNotification() {
936
        this.delegateObservable.endComplexNotification();
937
938
    }
939
940 43215 jjdelcerro
    @Override
941 40435 jjdelcerro
    public void addObserver(Observer observer) {
942
        if (delegateObservable != null) {
943
            this.delegateObservable.addObserver(observer);
944
        }
945
    }
946
947 43215 jjdelcerro
    @Override
948 40435 jjdelcerro
    public void deleteObserver(Observer observer) {
949
        if (delegateObservable != null) {
950
            this.delegateObservable.deleteObserver(observer);
951
        }
952
    }
953
954 43215 jjdelcerro
    @Override
955 40435 jjdelcerro
    public void deleteObservers() {
956
        this.delegateObservable.deleteObservers();
957
958
    }
959
960
    //
961
    // ====================================================================
962
    // Interface Observer
963
    //
964
    // Usado para observar:
965
    // - su seleccion
966
    // - sus bloqueos
967
    // - sus recursos
968
    //
969 42293 jjdelcerro
970 43215 jjdelcerro
    @Override
971 40435 jjdelcerro
    public void update(Observable observable, Object notification) {
972
        if (observable instanceof FeatureSet) {
973
            if (observable == this.selection) {
974
                this.notifyChange(DataStoreNotification.SELECTION_CHANGE);
975 43270 fdiaz
            } else if (observable == this.locks) {
976
                this.notifyChange(FeatureStoreNotification.LOCKS_CHANGE);
977
            }
978 40435 jjdelcerro
979 43270 fdiaz
        } else if (observable instanceof FeatureStoreProvider) {
980
            if (observable == this.provider) {
981 40435 jjdelcerro
982
            }
983 43270 fdiaz
        } else if (observable instanceof FeatureReferenceSelection) {
984
            if(notification instanceof String){
985
                    this.notifyChange((String)notification);
986
            }
987
        }
988 40435 jjdelcerro
    }
989
990
    //
991
    // ====================================================================
992
    // Edicion
993
    //
994 42293 jjdelcerro
995 40435 jjdelcerro
    private void newVersionOfUpdate() {
996
        this.versionOfUpdate++;
997
    }
998
999
    private long currentVersionOfUpdate() {
1000
        return this.versionOfUpdate;
1001
    }
1002
1003
    private void checkInEditingMode() throws NeedEditingModeException {
1004
        if (mode != MODE_FULLEDIT) {
1005
            throw new NeedEditingModeException(this.getName());
1006
        }
1007
    }
1008
1009
    private void checkNotInAppendMode() throws IllegalStateException {
1010
        if (mode == MODE_APPEND) {
1011 42293 jjdelcerro
                        throw new IllegalStateException("Error: store "
1012
                                        + this.getFullName() + " is in append mode");
1013 40435 jjdelcerro
        }
1014
    }
1015
1016
    private void checkIsOwnFeature(Feature feature)
1017 42293 jjdelcerro
        throws IllegalFeatureException {
1018 40435 jjdelcerro
        if (((DefaultFeature) feature).getStore() != this) {
1019
            throw new IllegalFeatureException(this.getName());
1020
        }
1021
        // FIXME: fixFeatureType no vale para el checkIsOwnFeature
1022
        // fixFeatureType((DefaultFeatureType) feature.getType());
1023
    }
1024
1025
    private void exitEditingMode() {
1026
        if (commands != null) {
1027
            commands.clear();
1028
            commands = null;
1029
        }
1030
1031
        if (featureTypeManager != null) {
1032
            featureTypeManager.dispose();
1033
            featureTypeManager = null;
1034
1035
        }
1036
1037
        // TODO implementar un dispose para estos dos
1038
        featureManager = null;
1039
        spatialManager = null;
1040
1041
        featureCount = null;
1042
1043
        mode = MODE_QUERY;
1044
        hasStrongChanges = true; // Lo deja a true por si las moscas
1045
        hasInserts = true;
1046
    }
1047
1048 43215 jjdelcerro
    @Override
1049 40435 jjdelcerro
    synchronized public void edit() throws DataException {
1050
        edit(MODE_FULLEDIT);
1051
    }
1052
1053 43215 jjdelcerro
    @Override
1054 40435 jjdelcerro
    synchronized public void edit(int mode) throws DataException {
1055 43215 jjdelcerro
        LOG.debug("Starting editing in mode: {}", mode);
1056 40435 jjdelcerro
        try {
1057
            if (this.mode != MODE_QUERY) {
1058
                throw new AlreadyEditingException(this.getName());
1059
            }
1060
            if (!this.provider.supportsAppendMode()) {
1061
                mode = MODE_FULLEDIT;
1062
            }
1063
            switch (mode) {
1064 42293 jjdelcerro
            case MODE_QUERY:
1065
                throw new IllegalStateException(this.getName());
1066
1067
            case MODE_FULLEDIT:
1068
                if (!this.transforms.isEmpty()) {
1069 40435 jjdelcerro
                    throw new IllegalStateException(this.getName());
1070 42293 jjdelcerro
                }
1071
                notifyChange(FeatureStoreNotification.BEFORE_STARTEDITING);
1072
                invalidateIndexes();
1073
                featureManager =
1074
                    new FeatureManager(new MemoryExpansionAdapter());
1075
                featureTypeManager =
1076
                    new FeatureTypeManager(this, new MemoryExpansionAdapter());
1077
                spatialManager =
1078
                    new SpatialManager(this, provider.getEnvelope());
1079 40435 jjdelcerro
1080 42293 jjdelcerro
                commands =
1081
                    new DefaultFeatureCommandsStack(this, featureManager,
1082
                        spatialManager, featureTypeManager);
1083
                this.mode = MODE_FULLEDIT;
1084
                hasStrongChanges = false;
1085
                hasInserts = false;
1086
                notifyChange(FeatureStoreNotification.AFTER_STARTEDITING);
1087
                break;
1088
            case MODE_APPEND:
1089
                if (!this.transforms.isEmpty()) {
1090
                    throw new IllegalStateException(this.getName());
1091
                }
1092
                notifyChange(FeatureStoreNotification.BEFORE_STARTEDITING);
1093
                invalidateIndexes();
1094
                this.provider.beginAppend();
1095
                this.mode = MODE_APPEND;
1096
                hasInserts = false;
1097
                notifyChange(FeatureStoreNotification.AFTER_STARTEDITING);
1098
                break;
1099 40435 jjdelcerro
            }
1100
        } catch (Exception e) {
1101
            throw new StoreEditException(e, this.getName());
1102
        }
1103
    }
1104
1105
    private void invalidateIndexes() {
1106
        setIndexesValidStatus(false);
1107
    }
1108
1109
    private void setIndexesValidStatus(boolean valid) {
1110 43215 jjdelcerro
        FeatureIndexes theIndexes = getIndexes();
1111 40435 jjdelcerro
        LOG.debug("Setting the store indexes to valid status {}: {}", (valid
1112 43215 jjdelcerro
            ? Boolean.TRUE : Boolean.FALSE), theIndexes);
1113
        for (Iterator iterator = theIndexes.iterator(); iterator.hasNext();) {
1114 40435 jjdelcerro
            FeatureIndex index = (FeatureIndex) iterator.next();
1115
            if (index instanceof FeatureIndexProviderServices) {
1116 42293 jjdelcerro
                FeatureIndexProviderServices indexServices =
1117
                    (FeatureIndexProviderServices) index;
1118 40435 jjdelcerro
                indexServices.setValid(valid);
1119
            }
1120
        }
1121
    }
1122
1123
    private void updateIndexes() throws FeatureIndexException {
1124 43215 jjdelcerro
        FeatureIndexes theIndexes = getIndexes();
1125
        LOG.debug("Refilling indexes: {}", theIndexes);
1126
        for (Iterator iterator = theIndexes.iterator(); iterator.hasNext();) {
1127 40435 jjdelcerro
            FeatureIndex index = (FeatureIndex) iterator.next();
1128
            if (index instanceof FeatureIndexProviderServices) {
1129 42293 jjdelcerro
                FeatureIndexProviderServices indexServices =
1130
                    (FeatureIndexProviderServices) index;
1131 40435 jjdelcerro
                indexServices.fill(true, null);
1132
            }
1133
        }
1134
    }
1135
1136
    private void waitForIndexes() {
1137 43215 jjdelcerro
        FeatureIndexes theIndexes = getIndexes();
1138
        LOG.debug("Waiting for indexes to finish filling: {}", theIndexes);
1139
        for (Iterator iterator = theIndexes.iterator(); iterator.hasNext();) {
1140 40435 jjdelcerro
            FeatureIndex index = (FeatureIndex) iterator.next();
1141
            if (index instanceof FeatureIndexProviderServices) {
1142 42293 jjdelcerro
                FeatureIndexProviderServices indexServices =
1143
                    (FeatureIndexProviderServices) index;
1144 40435 jjdelcerro
                indexServices.waitForIndex();
1145
            }
1146
        }
1147
    }
1148
1149
    private void disposeIndexes() {
1150 43215 jjdelcerro
        FeatureIndexes theIndexes = getIndexes();
1151
        LOG.debug("Disposing indexes: {}", theIndexes);
1152 43377 jjdelcerro
        if( theIndexes==null ) {
1153
            return;
1154
        }
1155 43215 jjdelcerro
        for (Iterator iterator = theIndexes.iterator(); iterator.hasNext();) {
1156 40435 jjdelcerro
            FeatureIndex index = (FeatureIndex) iterator.next();
1157
            if (index instanceof FeatureIndexProviderServices) {
1158 42293 jjdelcerro
                FeatureIndexProviderServices indexServices =
1159
                    (FeatureIndexProviderServices) index;
1160 40435 jjdelcerro
                indexServices.dispose();
1161
            }
1162
        }
1163
    }
1164
1165 43215 jjdelcerro
    @Override
1166 40435 jjdelcerro
    public boolean isEditing() {
1167
        return mode == MODE_FULLEDIT;
1168
    }
1169
1170 43215 jjdelcerro
    @Override
1171 40435 jjdelcerro
    public boolean isAppending() {
1172
        return mode == MODE_APPEND;
1173
    }
1174
1175 43215 jjdelcerro
    @Override
1176 40435 jjdelcerro
    synchronized public void update(EditableFeatureType type)
1177 42293 jjdelcerro
        throws DataException {
1178 40435 jjdelcerro
        try {
1179
            checkInEditingMode();
1180
            if (type == null) {
1181
                throw new NullFeatureTypeException(getName());
1182
            }
1183
            // FIXME: Comprobar que es un featureType aceptable.
1184
            notifyChange(FeatureStoreNotification.BEFORE_UPDATE_TYPE, type);
1185
            newVersionOfUpdate();
1186
1187
            FeatureType oldt = type.getSource().getCopy();
1188
            FeatureType newt = type.getCopy();
1189
            commands.update(newt, oldt);
1190
1191
            if (((DefaultEditableFeatureType) type).hasStrongChanges()) {
1192
                hasStrongChanges = true;
1193
            }
1194
            notifyChange(FeatureStoreNotification.AFTER_UPDATE_TYPE, type);
1195
        } catch (Exception e) {
1196
            throw new StoreUpdateFeatureTypeException(e, this.getName());
1197
        }
1198
    }
1199
1200 43215 jjdelcerro
    @Override
1201 41818 fdiaz
    public void delete(Feature feature) throws DataException {
1202 40435 jjdelcerro
        this.commands.delete(feature);
1203
    }
1204 41818 fdiaz
1205 40435 jjdelcerro
    synchronized public void doDelete(Feature feature) throws DataException {
1206
        try {
1207
            checkInEditingMode();
1208
            checkIsOwnFeature(feature);
1209
            if (feature instanceof EditableFeature) {
1210
                throw new StoreDeleteEditableFeatureException(getName());
1211
            }
1212 41818 fdiaz
            notifyChange(FeatureStoreNotification.BEFORE_DELETE, feature);
1213
1214 40435 jjdelcerro
            //Update the featureManager and the spatialManager
1215
            featureManager.delete(feature.getReference());
1216
            spatialManager.deleteFeature(feature);
1217 41818 fdiaz
1218 40435 jjdelcerro
            newVersionOfUpdate();
1219
            hasStrongChanges = true;
1220
            notifyChange(FeatureStoreNotification.AFTER_DELETE, feature);
1221
        } catch (Exception e) {
1222
            throw new StoreDeleteFeatureException(e, this.getName());
1223
        }
1224
    }
1225
1226
    private static EditableFeature lastChangedFeature = null;
1227
1228 43215 jjdelcerro
    @Override
1229 41818 fdiaz
    public synchronized void insert(EditableFeature feature)
1230 42293 jjdelcerro
        throws DataException {
1231 43215 jjdelcerro
        LOG.debug("In editing mode {}, insert feature: {}", mode, feature);
1232 40435 jjdelcerro
        try {
1233
            switch (mode) {
1234 42293 jjdelcerro
            case MODE_QUERY:
1235
                throw new NeedEditingModeException(this.getName());
1236 40435 jjdelcerro
1237 42293 jjdelcerro
            case MODE_APPEND:
1238
                checkIsOwnFeature(feature);
1239
                if (feature.getSource() != null) {
1240
                    throw new NoNewFeatureInsertException(this.getName());
1241
                }
1242
                this.featureCount = null;
1243
                notifyChange(FeatureStoreNotification.BEFORE_INSERT, feature);
1244
                feature.validate(Feature.UPDATE);
1245
                provider.append(((DefaultEditableFeature) feature).getData());
1246
                hasStrongChanges = true;
1247
                hasInserts = true;
1248
                notifyChange(FeatureStoreNotification.AFTER_INSERT, feature);
1249
                break;
1250 40435 jjdelcerro
1251 42293 jjdelcerro
            case MODE_FULLEDIT:
1252
                if (feature.getSource() != null) {
1253
                    throw new NoNewFeatureInsertException(this.getName());
1254
                }
1255
                commands.insert(feature);
1256 40435 jjdelcerro
            }
1257
        } catch (Exception e) {
1258
            throw new StoreInsertFeatureException(e, this.getName());
1259
        }
1260
    }
1261 41818 fdiaz
1262 40435 jjdelcerro
    synchronized public void doInsert(EditableFeature feature)
1263 42293 jjdelcerro
        throws DataException {
1264 40435 jjdelcerro
        checkIsOwnFeature(feature);
1265 41818 fdiaz
1266 40435 jjdelcerro
        waitForIndexes();
1267
1268
        notifyChange(FeatureStoreNotification.BEFORE_INSERT, feature);
1269
        newVersionOfUpdate();
1270
        if ((lastChangedFeature == null)
1271 42293 jjdelcerro
            || (lastChangedFeature.getSource() != feature.getSource())) {
1272 40435 jjdelcerro
            lastChangedFeature = feature;
1273
            feature.validate(Feature.UPDATE);
1274
            lastChangedFeature = null;
1275
        }
1276
        //Update the featureManager and the spatialManager
1277
        ((DefaultEditableFeature) feature).setInserted(true);
1278
        DefaultFeature newFeature = (DefaultFeature) feature.getNotEditableCopy();
1279 41818 fdiaz
1280 42293 jjdelcerro
1281 40435 jjdelcerro
        featureManager.add(newFeature);
1282
        spatialManager.insertFeature(newFeature);
1283 41818 fdiaz
1284 40435 jjdelcerro
        hasStrongChanges = true;
1285
        hasInserts = true;
1286 41818 fdiaz
        notifyChange(FeatureStoreNotification.AFTER_INSERT, feature);
1287 40435 jjdelcerro
    }
1288 41818 fdiaz
1289 43215 jjdelcerro
    @Override
1290 40435 jjdelcerro
    public void update(EditableFeature feature)
1291 42293 jjdelcerro
    throws DataException {
1292 40435 jjdelcerro
        if ((feature).getSource() == null) {
1293
            insert(feature);
1294
            return;
1295
        }
1296
        commands.update(feature, feature.getSource());
1297
    }
1298
1299
    synchronized public void doUpdate(EditableFeature feature, Feature oldFeature)
1300 42293 jjdelcerro
        throws DataException {
1301 41818 fdiaz
        try {
1302 40435 jjdelcerro
            checkInEditingMode();
1303
            checkIsOwnFeature(feature);
1304
            notifyChange(FeatureStoreNotification.BEFORE_UPDATE, feature);
1305
            newVersionOfUpdate();
1306
            if ((lastChangedFeature == null)
1307 42293 jjdelcerro
                || (lastChangedFeature.getSource() != feature.getSource())) {
1308 40435 jjdelcerro
                lastChangedFeature = feature;
1309
                feature.validate(Feature.UPDATE);
1310
                lastChangedFeature = null;
1311
            }
1312 41818 fdiaz
1313 40435 jjdelcerro
            //Update the featureManager and the spatialManager
1314
            Feature newf = feature.getNotEditableCopy();
1315
            featureManager.update(newf, oldFeature);
1316
            spatialManager.updateFeature(newf, oldFeature);
1317 41818 fdiaz
1318 40435 jjdelcerro
            hasStrongChanges = true;
1319
            notifyChange(FeatureStoreNotification.AFTER_UPDATE, feature);
1320
        } catch (Exception e) {
1321
            throw new StoreUpdateFeatureException(e, this.getName());
1322
        }
1323
    }
1324
1325 43215 jjdelcerro
    @Override
1326 40435 jjdelcerro
    synchronized public void redo() throws RedoException {
1327
        Command redo = commands.getNextRedoCommand();
1328
        try {
1329
            checkInEditingMode();
1330
        } catch (NeedEditingModeException ex) {
1331
            throw new RedoException(redo, ex);
1332
        }
1333
        notifyChange(FeatureStoreNotification.BEFORE_REDO, redo);
1334
        newVersionOfUpdate();
1335
        commands.redo();
1336
        hasStrongChanges = true;
1337
        notifyChange(FeatureStoreNotification.AFTER_REDO, redo);
1338
    }
1339
1340 43215 jjdelcerro
    @Override
1341 40435 jjdelcerro
    synchronized public void undo() throws UndoException {
1342
        Command undo = commands.getNextUndoCommand();
1343
        try {
1344
            checkInEditingMode();
1345
        } catch (NeedEditingModeException ex) {
1346
            throw new UndoException(undo, ex);
1347
        }
1348
        notifyChange(FeatureStoreNotification.BEFORE_UNDO, undo);
1349
        newVersionOfUpdate();
1350
        commands.undo();
1351
        hasStrongChanges = true;
1352
        notifyChange(FeatureStoreNotification.AFTER_UNDO, undo);
1353
    }
1354
1355 43215 jjdelcerro
    @Override
1356 40435 jjdelcerro
    public List getRedoInfos() {
1357
        if (isEditing() && (commands != null)) {
1358
            return commands.getRedoInfos();
1359
        } else {
1360
            return null;
1361
        }
1362
    }
1363
1364 43215 jjdelcerro
    @Override
1365 40435 jjdelcerro
    public List getUndoInfos() {
1366
        if (isEditing() && (commands != null)) {
1367
            return commands.getUndoInfos();
1368
        } else {
1369
            return null;
1370
        }
1371
    }
1372
1373
    public synchronized FeatureCommandsStack getCommandsStack()
1374 42293 jjdelcerro
        throws DataException {
1375 40435 jjdelcerro
        checkInEditingMode();
1376
        return commands;
1377
    }
1378
1379 43215 jjdelcerro
    @Override
1380 40435 jjdelcerro
    synchronized public void cancelEditing() throws DataException {
1381
        spatialManager.cancelModifies();
1382
        try {
1383
            checkInEditingMode();
1384
1385
            boolean clearSelection = this.hasStrongChanges;
1386
            if (this.selection instanceof FeatureReferenceSelection) {
1387
                clearSelection = this.hasInserts;
1388
            }
1389
            notifyChange(FeatureStoreNotification.BEFORE_CANCELEDITING);
1390
            exitEditingMode();
1391
            if (clearSelection) {
1392
                ((FeatureSelection) this.getSelection()).deselectAll();
1393
            }
1394
            updateIndexes();
1395
            notifyChange(FeatureStoreNotification.AFTER_CANCELEDITING);
1396
        } catch (Exception e) {
1397
            throw new StoreCancelEditingException(e, this.getName());
1398
        }
1399
    }
1400
1401 43215 jjdelcerro
    @Override
1402 40435 jjdelcerro
    synchronized public void finishEditing() throws DataException {
1403 43215 jjdelcerro
        LOG.debug("finish editing of mode: {}", mode);
1404 40435 jjdelcerro
        try {
1405 41818 fdiaz
1406 40435 jjdelcerro
            /*
1407
             * Selection needs to be cleared when editing stops
1408
             * to prevent conflicts with selection remaining from
1409
             * editing mode.
1410
             */
1411 42639 dmartinezizquierdo
//            ((FeatureSelection) this.getSelection()).deselectAll();
1412 41818 fdiaz
1413 40435 jjdelcerro
            switch (mode) {
1414 42293 jjdelcerro
            case MODE_QUERY:
1415
                throw new NeedEditingModeException(this.getName());
1416 40435 jjdelcerro
1417 42293 jjdelcerro
            case MODE_APPEND:
1418 43377 jjdelcerro
                if( selection!=null ) {
1419
                    selection = null;
1420
                }
1421 42293 jjdelcerro
                notifyChange(FeatureStoreNotification.BEFORE_FINISHEDITING);
1422
                provider.endAppend();
1423
                exitEditingMode();
1424
                updateIndexes();
1425
                notifyChange(FeatureStoreNotification.AFTER_FINISHEDITING);
1426
                break;
1427 40435 jjdelcerro
1428 42293 jjdelcerro
            case MODE_FULLEDIT:
1429
                if (hasStrongChanges && !this.allowWrite()) {
1430
                    throw new WriteNotAllowedException(getName());
1431
                }
1432 43377 jjdelcerro
                if(featureManager.isSelectionCompromised() && selection!=null ) {
1433
                    selection = null;
1434
                }
1435 42293 jjdelcerro
                notifyChange(FeatureStoreNotification.BEFORE_FINISHEDITING);
1436
                if (hasStrongChanges) {
1437
                    validateFeatures(Feature.FINISH_EDITING);
1438 41818 fdiaz
1439 42293 jjdelcerro
                    /*
1440
                     * This will throw a PerformEditingExceptionif the provider
1441
                     * does not accept the changes (for example, an invalid field name)
1442
                     */
1443
                    provider.performChanges(featureManager.getDeleted(),
1444
                        featureManager.getInserted(),
1445
                        featureManager.getUpdated(),
1446
                        featureTypeManager.getFeatureTypesChanged());
1447
                }
1448
                exitEditingMode();
1449
                updateIndexes();
1450
                notifyChange(FeatureStoreNotification.AFTER_FINISHEDITING);
1451
                break;
1452 40435 jjdelcerro
            }
1453 40597 jldominguez
        } catch (PerformEditingException pee) {
1454 41437 jjdelcerro
            throw new WriteException(provider.getSourceId().toString(), pee);
1455 40435 jjdelcerro
        } catch (Exception e) {
1456
            throw new FinishEditingException(e);
1457
        }
1458
    }
1459
1460
    /**
1461 42293 jjdelcerro
     * Save changes in the provider without leaving the edit mode.
1462
     * Do not call observers to communicate a change of ediding mode.
1463
     * The operation's history is eliminated to prevent inconsistencies
1464
     * in the data.
1465 40435 jjdelcerro
     *
1466
     * @throws DataException
1467
     */
1468 43215 jjdelcerro
    @Override
1469 40435 jjdelcerro
    synchronized public void commitChanges() throws DataException {
1470 43215 jjdelcerro
      LOG.debug("commitChanges of mode: {}", mode);
1471 42293 jjdelcerro
      if( !canCommitChanges() ) {
1472
              throw new WriteNotAllowedException(getName());
1473
      }
1474
      try {
1475
        switch (mode) {
1476
        case MODE_QUERY:
1477
          throw new NeedEditingModeException(this.getName());
1478 40435 jjdelcerro
1479 42293 jjdelcerro
        case MODE_APPEND:
1480
          this.provider.endAppend();
1481
          exitEditingMode();
1482
          invalidateIndexes();
1483
          this.provider.beginAppend();
1484
          hasInserts = false;
1485
          break;
1486 40435 jjdelcerro
1487 42293 jjdelcerro
        case MODE_FULLEDIT:
1488
          if (hasStrongChanges && !this.allowWrite()) {
1489
            throw new WriteNotAllowedException(getName());
1490
          }
1491
          if (hasStrongChanges) {
1492
            validateFeatures(Feature.FINISH_EDITING);
1493
            provider.performChanges(featureManager.getDeleted(),
1494
              featureManager.getInserted(),
1495
              featureManager.getUpdated(),
1496
              featureTypeManager.getFeatureTypesChanged());
1497
          }
1498
          invalidateIndexes();
1499
          featureManager =
1500
            new FeatureManager(new MemoryExpansionAdapter());
1501
          featureTypeManager =
1502
            new FeatureTypeManager(this, new MemoryExpansionAdapter());
1503
          spatialManager =
1504
            new SpatialManager(this, provider.getEnvelope());
1505 40435 jjdelcerro
1506 42293 jjdelcerro
          commands =
1507
            new DefaultFeatureCommandsStack(this, featureManager,
1508
              spatialManager, featureTypeManager);
1509
          featureCount = null;
1510
          hasStrongChanges = false;
1511
          hasInserts = false;
1512
          break;
1513 40435 jjdelcerro
        }
1514 42293 jjdelcerro
      } catch (Exception e) {
1515
        throw new FinishEditingException(e);
1516
      }
1517 40435 jjdelcerro
    }
1518
1519 43215 jjdelcerro
    @Override
1520 40435 jjdelcerro
    synchronized public boolean canCommitChanges() throws DataException {
1521 42293 jjdelcerro
        if ( !this.allowWrite()) {
1522
                return false;
1523 40435 jjdelcerro
        }
1524 42293 jjdelcerro
            switch (mode) {
1525
            default:
1526
        case MODE_QUERY:
1527
                return false;
1528 41818 fdiaz
1529 42293 jjdelcerro
        case MODE_APPEND:
1530
                return true;
1531 41818 fdiaz
1532 42293 jjdelcerro
        case MODE_FULLEDIT:
1533
            List types = this.getFeatureTypes();
1534
            for( int i=0; i<types.size(); i++ ) {
1535
                    Object type = types.get(i);
1536
                    if( type instanceof DefaultEditableFeatureType ) {
1537
                            if( ((DefaultEditableFeatureType)type).hasStrongChanges() ) {
1538
                                    return false;
1539
                            }
1540
                    }
1541
            }
1542
            return true;
1543
            }
1544 40435 jjdelcerro
    }
1545 41818 fdiaz
1546 43215 jjdelcerro
    @Override
1547 40435 jjdelcerro
    public void beginEditingGroup(String description)
1548 42293 jjdelcerro
        throws NeedEditingModeException {
1549 40435 jjdelcerro
        checkInEditingMode();
1550
        commands.startComplex(description);
1551
    }
1552
1553 43215 jjdelcerro
    @Override
1554 40435 jjdelcerro
    public void endEditingGroup() throws NeedEditingModeException {
1555
        checkInEditingMode();
1556
        commands.endComplex();
1557
    }
1558
1559 43215 jjdelcerro
    @Override
1560 40435 jjdelcerro
    public boolean isAppendModeSupported() {
1561
        return this.provider.supportsAppendMode();
1562
    }
1563
1564 43215 jjdelcerro
    @Override
1565 40435 jjdelcerro
    public void export(DataServerExplorer explorer, String provider,
1566 42293 jjdelcerro
        NewFeatureStoreParameters params) throws DataException {
1567 40435 jjdelcerro
1568
        if (this.getFeatureTypes().size() != 1) {
1569
            throw new NotYetImplemented(
1570 42293 jjdelcerro
                "export whith more than one type not yet implemented");
1571 40435 jjdelcerro
        }
1572
        FeatureSelection featureSelection = (FeatureSelection) getSelection();
1573
        FeatureStore target = null;
1574
        FeatureSet features = null;
1575
        DisposableIterator iterator = null;
1576
        try {
1577
            FeatureType type = this.getDefaultFeatureType();
1578
            if ((params.getDefaultFeatureType() == null)
1579 42293 jjdelcerro
                || (params.getDefaultFeatureType().size() == 0)) {
1580 40435 jjdelcerro
                params.setDefaultFeatureType(type.getEditable());
1581
1582
            }
1583
            explorer.add(provider, params, true);
1584
1585
            DataManager manager = DALLocator.getDataManager();
1586
            target = (FeatureStore) manager.openStore(provider, params);
1587
            FeatureType targetType = target.getDefaultFeatureType();
1588
1589
            target.edit(MODE_APPEND);
1590
            FeatureAttributeDescriptor[] pk = type.getPrimaryKey();
1591
            if (featureSelection.getSize() > 0) {
1592
                features = this.getFeatureSelection();
1593
            } else {
1594
                if ((pk != null) && (pk.length > 0)) {
1595
                    FeatureQuery query = createFeatureQuery();
1596
                    for (int i = 0; i < pk.length; i++) {
1597
                        query.getOrder().add(pk[i].getName(), true);
1598
                    }
1599
                    features = this.getFeatureSet(query);
1600
                } else {
1601
                    features = this.getFeatureSet();
1602
                }
1603
            }
1604
            iterator = features.fastIterator();
1605
            while (iterator.hasNext()) {
1606
                DefaultFeature feature = (DefaultFeature) iterator.next();
1607
                target.insert(target.createNewFeature(targetType, feature));
1608
            }
1609
            target.finishEditing();
1610
            target.dispose();
1611
        } catch (Exception e) {
1612
            throw new DataExportException(e, params.toString());
1613
        } finally {
1614
            dispose(iterator);
1615
            dispose(features);
1616
            dispose(target);
1617
        }
1618
    }
1619
1620
    //
1621
    // ====================================================================
1622
    // Obtencion de datos
1623
    // getDataCollection, getFeatureCollection
1624
    //
1625 42293 jjdelcerro
1626 43215 jjdelcerro
    @Override
1627 40435 jjdelcerro
    public DataSet getDataSet() throws DataException {
1628
        checkNotInAppendMode();
1629 42293 jjdelcerro
        FeatureQuery query =
1630
            new DefaultFeatureQuery(this.getDefaultFeatureType());
1631 40435 jjdelcerro
        return new DefaultFeatureSet(this, query);
1632
    }
1633
1634 43215 jjdelcerro
    @Override
1635 40435 jjdelcerro
    public DataSet getDataSet(DataQuery dataQuery) throws DataException {
1636
        checkNotInAppendMode();
1637
        return new DefaultFeatureSet(this, (FeatureQuery) dataQuery);
1638
    }
1639
1640 43215 jjdelcerro
    @Override
1641 40435 jjdelcerro
    public void getDataSet(Observer observer) throws DataException {
1642
        checkNotInAppendMode();
1643
        this.getFeatureSet(null, observer);
1644
    }
1645
1646 43215 jjdelcerro
    @Override
1647 40435 jjdelcerro
    public void getDataSet(DataQuery dataQuery, Observer observer)
1648 42293 jjdelcerro
        throws DataException {
1649 40435 jjdelcerro
        checkNotInAppendMode();
1650
        this.getFeatureSet((FeatureQuery) dataQuery, observer);
1651
    }
1652
1653 42799 jjdelcerro
    @Override
1654 40435 jjdelcerro
    public FeatureSet getFeatureSet() throws DataException {
1655 42799 jjdelcerro
        return this.getFeatureSet((FeatureQuery)null);
1656 40435 jjdelcerro
    }
1657
1658 42799 jjdelcerro
    @Override
1659 40435 jjdelcerro
    public FeatureSet getFeatureSet(FeatureQuery featureQuery)
1660 42293 jjdelcerro
        throws DataException {
1661 40435 jjdelcerro
        checkNotInAppendMode();
1662 42799 jjdelcerro
        if( featureQuery==null ) {
1663
            featureQuery = new DefaultFeatureQuery(this.getDefaultFeatureType());
1664
        }
1665 40435 jjdelcerro
        return new DefaultFeatureSet(this, featureQuery);
1666
    }
1667
1668 42925 jjdelcerro
    @Override
1669
    public List<Feature> getFeatures(FeatureQuery query, int pageSize)  {
1670
        try {
1671
            FeaturePagingHelper pager = this.dataManager.createFeaturePagingHelper(this, query, pageSize);
1672
            return pager.asList();
1673
        } catch (BaseException ex) {
1674
            throw new RuntimeException("Can't create the list of features.", ex);
1675
        }
1676
    }
1677 43020 jjdelcerro
1678
    @Override
1679
    public List<Feature> getFeatures() {
1680
        return this.getFeatures(null, 500);
1681
    }
1682 43152 fdiaz
1683 43215 jjdelcerro
    @Override
1684 40435 jjdelcerro
    public void accept(Visitor visitor) throws BaseException {
1685
        FeatureSet set = getFeatureSet();
1686
        try {
1687
            set.accept(visitor);
1688
        } finally {
1689
            set.dispose();
1690
        }
1691
    }
1692
1693 43215 jjdelcerro
    @Override
1694 40435 jjdelcerro
    public void accept(Visitor visitor, DataQuery dataQuery)
1695 42293 jjdelcerro
        throws BaseException {
1696 40435 jjdelcerro
        FeatureSet set = getFeatureSet((FeatureQuery) dataQuery);
1697
        try {
1698
            set.accept(visitor);
1699
        } finally {
1700
            set.dispose();
1701
        }
1702
    }
1703
1704
    public FeatureType getFeatureType(FeatureQuery featureQuery)
1705 42293 jjdelcerro
        throws DataException {
1706
        DefaultFeatureType fType =
1707
            (DefaultFeatureType) this.getFeatureType(featureQuery
1708
                .getFeatureTypeId());
1709
        if( featureQuery.hasAttributeNames() || featureQuery.hasConstantsAttributeNames() ) {
1710
            return fType.getSubtype(featureQuery.getAttributeNames(), featureQuery.getConstantsAttributeNames() );
1711 40435 jjdelcerro
        }
1712
        return fType;
1713
    }
1714
1715 43215 jjdelcerro
    @Override
1716 40435 jjdelcerro
    public void getFeatureSet(Observer observer) throws DataException {
1717
        checkNotInAppendMode();
1718
        this.getFeatureSet(null, observer);
1719
    }
1720
1721 43215 jjdelcerro
    @Override
1722 40435 jjdelcerro
    public void getFeatureSet(FeatureQuery query, Observer observer)
1723 42293 jjdelcerro
        throws DataException {
1724 40435 jjdelcerro
        class LoadInBackGround implements Runnable {
1725
1726 43215 jjdelcerro
            private final FeatureStore store;
1727
            private final FeatureQuery query;
1728
            private final Observer observer;
1729 40435 jjdelcerro
1730
            public LoadInBackGround(FeatureStore store, FeatureQuery query,
1731 42293 jjdelcerro
                Observer observer) {
1732 40435 jjdelcerro
                this.store = store;
1733
                this.query = query;
1734
                this.observer = observer;
1735
            }
1736
1737
            void notify(FeatureStoreNotification theNotification) {
1738
                observer.update(store, theNotification);
1739
            }
1740
1741 43215 jjdelcerro
            @Override
1742 40435 jjdelcerro
            public void run() {
1743
                FeatureSet set = null;
1744
                try {
1745
                    set = store.getFeatureSet(query);
1746
                    notify(new DefaultFeatureStoreNotification(store,
1747 42293 jjdelcerro
                        FeatureStoreNotification.LOAD_FINISHED, set));
1748 40435 jjdelcerro
                } catch (Exception e) {
1749
                    notify(new DefaultFeatureStoreNotification(store,
1750 42293 jjdelcerro
                        FeatureStoreNotification.LOAD_FINISHED, e));
1751 40435 jjdelcerro
                } finally {
1752
                    dispose(set);
1753
                }
1754
            }
1755
        }
1756
1757
        checkNotInAppendMode();
1758
        if (query == null) {
1759
            query = new DefaultFeatureQuery(this.getDefaultFeatureType());
1760
        }
1761
        LoadInBackGround task = new LoadInBackGround(this, query, observer);
1762
        Thread thread = new Thread(task, "Load Feature Set in background");
1763
        thread.start();
1764
    }
1765
1766 43215 jjdelcerro
    @Override
1767 40435 jjdelcerro
    public Feature getFeatureByReference(FeatureReference reference)
1768 42293 jjdelcerro
        throws DataException {
1769 40435 jjdelcerro
        checkNotInAppendMode();
1770
        DefaultFeatureReference ref = (DefaultFeatureReference) reference;
1771
        FeatureType featureType;
1772
        if (ref.getFeatureTypeId() == null) {
1773
            featureType = this.getDefaultFeatureType();
1774
        } else {
1775
            featureType = this.getFeatureType(ref.getFeatureTypeId());
1776
        }
1777
        return this.getFeatureByReference(reference, featureType);
1778
    }
1779
1780 43215 jjdelcerro
    @Override
1781 40435 jjdelcerro
    public Feature getFeatureByReference(FeatureReference reference,
1782 42293 jjdelcerro
        FeatureType featureType) throws DataException {
1783 40435 jjdelcerro
        checkNotInAppendMode();
1784
        featureType = fixFeatureType((DefaultFeatureType) featureType);
1785
        if (this.mode == MODE_FULLEDIT) {
1786
            Feature f = featureManager.get(reference, this, featureType);
1787
            if (f != null) {
1788
                return f;
1789
            }
1790
        }
1791 41818 fdiaz
1792 42092 fdiaz
        FeatureType sourceFeatureType = featureType;
1793
        if (!this.transforms.isEmpty()) {
1794
            sourceFeatureType = this.transforms.getSourceFeatureTypeFrom(featureType);
1795
        }
1796
        // TODO comprobar que el id es de este store
1797 41818 fdiaz
1798 42293 jjdelcerro
        DefaultFeature feature =
1799
            new DefaultFeature(this,
1800
                this.provider.getFeatureProviderByReference(
1801
                    (FeatureReferenceProviderServices) reference, sourceFeatureType));
1802 40435 jjdelcerro
1803
        if (!this.transforms.isEmpty()) {
1804
            return this.transforms.applyTransform(feature, featureType);
1805
        }
1806
        return feature;
1807
    }
1808
1809
    //
1810
    // ====================================================================
1811
    // Gestion de features
1812
    //
1813 42293 jjdelcerro
1814 40435 jjdelcerro
    private FeatureType fixFeatureType(DefaultFeatureType type)
1815 42293 jjdelcerro
        throws DataException {
1816 40435 jjdelcerro
        FeatureType original = this.getDefaultFeatureType();
1817
1818
        if ((type == null) || type.equals(original)) {
1819
            return original;
1820
        } else {
1821
            if (!type.isSubtypeOf(original)) {
1822
                Iterator iter = this.getFeatureTypes().iterator();
1823
                FeatureType tmpType;
1824
                boolean found = false;
1825
                while (iter.hasNext()) {
1826
                    tmpType = (FeatureType) iter.next();
1827
                    if (type.equals(tmpType)) {
1828
                        return type;
1829
1830 42293 jjdelcerro
                    } else
1831
                        if (type.isSubtypeOf(tmpType)) {
1832
                            found = true;
1833
                            original = tmpType;
1834
                            break;
1835
                        }
1836 40435 jjdelcerro
1837
                }
1838
                if (!found) {
1839
                    throw new IllegalFeatureTypeException(getName());
1840
                }
1841
            }
1842
        }
1843
1844
        // Checks that type has all fields of pk
1845
        // else add the missing attributes at the end.
1846
        if (!original.hasOID()) {
1847
            // Gets original pk attributes
1848 42293 jjdelcerro
            DefaultEditableFeatureType edOriginal =
1849
                (DefaultEditableFeatureType) original.getEditable();
1850 40435 jjdelcerro
            FeatureAttributeDescriptor orgAttr;
1851
            Iterator edOriginalIter = edOriginal.iterator();
1852
            while (edOriginalIter.hasNext()) {
1853
                orgAttr = (FeatureAttributeDescriptor) edOriginalIter.next();
1854
                if (!orgAttr.isPrimaryKey()) {
1855
                    edOriginalIter.remove();
1856
                }
1857
            }
1858
1859
            // Checks if all pk attributes are in type
1860
            Iterator typeIterator;
1861
            edOriginalIter = edOriginal.iterator();
1862
            FeatureAttributeDescriptor attr;
1863
            while (edOriginalIter.hasNext()) {
1864
                orgAttr = (FeatureAttributeDescriptor) edOriginalIter.next();
1865
                typeIterator = type.iterator();
1866
                while (typeIterator.hasNext()) {
1867
                    attr = (FeatureAttributeDescriptor) typeIterator.next();
1868
                    if (attr.getName().equals(orgAttr.getName())) {
1869
                        edOriginalIter.remove();
1870
                        break;
1871
                    }
1872
                }
1873
            }
1874
1875
            // add missing pk attributes if any
1876
            if (edOriginal.size() > 0) {
1877
                boolean isEditable = type instanceof DefaultEditableFeatureType;
1878 42293 jjdelcerro
                DefaultEditableFeatureType edType =
1879
                    (DefaultEditableFeatureType) original.getEditable();
1880 40435 jjdelcerro
                edType.clear();
1881
                edType.addAll(type);
1882
                edType.addAll(edOriginal);
1883
                if (!isEditable) {
1884
                    type = (DefaultFeatureType) edType.getNotEditableCopy();
1885
                }
1886
            }
1887
1888
        }
1889
1890
        return type;
1891
    }
1892
1893 43215 jjdelcerro
    @Override
1894 40435 jjdelcerro
    public void validateFeatures(int mode) throws DataException {
1895
        FeatureSet collection = null;
1896
        DisposableIterator iter = null;
1897
        try {
1898
            checkNotInAppendMode();
1899
            collection = this.getFeatureSet();
1900
            iter = collection.fastIterator();
1901
            long previousVersionOfUpdate = currentVersionOfUpdate();
1902
            while (iter.hasNext()) {
1903
                ((DefaultFeature) iter.next()).validate(mode);
1904
                if (previousVersionOfUpdate != currentVersionOfUpdate()) {
1905
                    throw new ConcurrentDataModificationException(getName());
1906
                }
1907
            }
1908
        } catch (Exception e) {
1909
            throw new ValidateFeaturesException(e, getName());
1910
        } finally {
1911
            dispose(iter);
1912
            dispose(collection);
1913
        }
1914
    }
1915
1916 43215 jjdelcerro
    @Override
1917 40435 jjdelcerro
    public FeatureType getDefaultFeatureType() throws DataException {
1918
        try {
1919 41818 fdiaz
1920 40435 jjdelcerro
            if (isEditing()) {
1921 42293 jjdelcerro
                FeatureType auxFeatureType =
1922
                    featureTypeManager.getType(defaultFeatureType.getId());
1923 40435 jjdelcerro
                if (auxFeatureType != null) {
1924
                    return avoidEditable(auxFeatureType);
1925
                }
1926
            }
1927
            FeatureType type = this.transforms.getDefaultFeatureType();
1928
            if (type != null) {
1929
                return avoidEditable(type);
1930
            }
1931 41818 fdiaz
1932 40435 jjdelcerro
            return avoidEditable(defaultFeatureType);
1933 41818 fdiaz
1934 40435 jjdelcerro
        } catch (Exception e) {
1935
            throw new GetFeatureTypeException(e, getName());
1936
        }
1937
    }
1938 41818 fdiaz
1939 40435 jjdelcerro
    private FeatureType avoidEditable(FeatureType ft) {
1940
        if (ft instanceof EditableFeatureType) {
1941
            return ((EditableFeatureType) ft).getNotEditableCopy();
1942
        } else {
1943
            return ft;
1944
        }
1945
    }
1946
1947 43215 jjdelcerro
    @Override
1948 40435 jjdelcerro
    public FeatureType getFeatureType(String featureTypeId)
1949 42293 jjdelcerro
        throws DataException {
1950 40435 jjdelcerro
        if (featureTypeId == null) {
1951
            return this.getDefaultFeatureType();
1952
        }
1953
        try {
1954
            if (isEditing()) {
1955 42293 jjdelcerro
                FeatureType auxFeatureType =
1956
                    featureTypeManager.getType(featureTypeId);
1957 40435 jjdelcerro
                if (auxFeatureType != null) {
1958
                    return auxFeatureType;
1959
                }
1960
            }
1961
            FeatureType type = this.transforms.getFeatureType(featureTypeId);
1962
            if (type != null) {
1963
                return type;
1964
            }
1965
            Iterator iter = this.featureTypes.iterator();
1966
            while (iter.hasNext()) {
1967
                type = (FeatureType) iter.next();
1968
                if (type.getId().equals(featureTypeId)) {
1969
                    return type;
1970
                }
1971
            }
1972
            return null;
1973
        } catch (Exception e) {
1974
            throw new GetFeatureTypeException(e, getName());
1975
        }
1976
    }
1977
1978
    public FeatureType getProviderDefaultFeatureType() {
1979
        return defaultFeatureType;
1980
    }
1981
1982 43215 jjdelcerro
    @Override
1983 40435 jjdelcerro
    public List getFeatureTypes() throws DataException {
1984
        try {
1985
            List types;
1986
            if (isEditing()) {
1987
                types = new ArrayList();
1988
                Iterator it = featureTypes.iterator();
1989
                while (it.hasNext()) {
1990
                    FeatureType type = (FeatureType) it.next();
1991 42293 jjdelcerro
                    FeatureType typeaux =
1992
                        featureTypeManager.getType(type.getId());
1993 40435 jjdelcerro
                    if (typeaux != null) {
1994
                        types.add(typeaux);
1995
                    } else {
1996
                        types.add(type);
1997
                    }
1998
                }
1999
                it = featureTypeManager.newsIterator();
2000
                while (it.hasNext()) {
2001
                    FeatureType type = (FeatureType) it.next();
2002
                    types.add(type);
2003
                }
2004
            } else {
2005
                types = this.transforms.getFeatureTypes();
2006
                if (types == null) {
2007
                    types = featureTypes;
2008
                }
2009
            }
2010
            return Collections.unmodifiableList(types);
2011
        } catch (Exception e) {
2012
            throw new GetFeatureTypeException(e, getName());
2013
        }
2014
    }
2015
2016
    public List getProviderFeatureTypes() throws DataException {
2017
        return Collections.unmodifiableList(this.featureTypes);
2018
    }
2019
2020 43215 jjdelcerro
    @Override
2021 40435 jjdelcerro
    public Feature createFeature(FeatureProvider data) throws DataException {
2022
        DefaultFeature feature = new DefaultFeature(this, data);
2023
        return feature;
2024
    }
2025
2026
    public Feature createFeature(FeatureProvider data, FeatureType type)
2027 42293 jjdelcerro
        throws DataException {
2028 40435 jjdelcerro
        // FIXME: falta por implementar
2029
        // Comprobar si es un subtipo del feature de data
2030
        // y construir un feature usando el subtipo.
2031
        // Probablemente requiera generar una copia del data.
2032
        throw new NotYetImplemented();
2033
    }
2034
2035 43215 jjdelcerro
    @Override
2036 40435 jjdelcerro
    public EditableFeature createNewFeature(FeatureType type,
2037 42293 jjdelcerro
        Feature defaultValues) throws DataException {
2038 40435 jjdelcerro
        try {
2039
            FeatureProvider data = createNewFeatureProvider(type);
2040 42293 jjdelcerro
            DefaultEditableFeature feature =
2041
                new DefaultEditableFeature(this, data);
2042 40435 jjdelcerro
            feature.initializeValues(defaultValues);
2043
            data.setNew(true);
2044 41818 fdiaz
2045 40435 jjdelcerro
            return feature;
2046
        } catch (Exception e) {
2047
            throw new CreateFeatureException(e, getName());
2048
        }
2049
    }
2050
2051
    private FeatureProvider createNewFeatureProvider(FeatureType type)
2052 42293 jjdelcerro
        throws DataException {
2053 40435 jjdelcerro
        type = this.fixFeatureType((DefaultFeatureType) type);
2054
        FeatureProvider data = this.provider.createFeatureProvider(type);
2055
        data.setNew(true);
2056
        if (type.hasOID() && (data.getOID() == null)) {
2057
            data.setOID(this.provider.createNewOID());
2058
        } else {
2059
            data.setOID(this.getTemporalOID());
2060
        }
2061
        return data;
2062
2063
    }
2064
2065 43215 jjdelcerro
    @Override
2066 40435 jjdelcerro
    public EditableFeature createNewFeature(FeatureType type,
2067 42293 jjdelcerro
        boolean defaultValues) throws DataException {
2068 40435 jjdelcerro
        try {
2069
            FeatureProvider data = createNewFeatureProvider(type);
2070 42293 jjdelcerro
            DefaultEditableFeature feature =
2071
                new DefaultEditableFeature(this, data);
2072 40435 jjdelcerro
            if (defaultValues) {
2073
                feature.initializeValues();
2074
            }
2075
            return feature;
2076
        } catch (Exception e) {
2077
            throw new CreateFeatureException(e, getName());
2078
        }
2079
    }
2080
2081 43215 jjdelcerro
    @Override
2082 40435 jjdelcerro
    public EditableFeature createNewFeature(boolean defaultValues)
2083 42293 jjdelcerro
        throws DataException {
2084 40435 jjdelcerro
        return this.createNewFeature(this.getDefaultFeatureType(),
2085 42293 jjdelcerro
            defaultValues);
2086 40435 jjdelcerro
    }
2087
2088 43215 jjdelcerro
    @Override
2089 40435 jjdelcerro
    public EditableFeature createNewFeature() throws DataException {
2090
        return this.createNewFeature(this.getDefaultFeatureType(), true);
2091
    }
2092
2093 43215 jjdelcerro
    @Override
2094 42293 jjdelcerro
    public EditableFeature createNewFeature(Feature defaultValues) throws DataException {
2095
        FeatureType ft = this.getDefaultFeatureType();
2096
        EditableFeature f = this.createNewFeature(ft, false);
2097 43215 jjdelcerro
                for( FeatureAttributeDescriptor desc : ft ) {
2098
                        try {
2099
                                f.set(desc.getName(), defaultValues.get(desc.getName()));
2100
                        } catch(Throwable th) {
2101
                                // Ignore
2102
                        }
2103
                }
2104 42293 jjdelcerro
        return f;
2105
    }
2106
2107 43215 jjdelcerro
    @Override
2108 40435 jjdelcerro
    public EditableFeatureType createFeatureType() {
2109 43377 jjdelcerro
        EditableFeatureType ftype = this.dataManager.createFeatureType();
2110 40435 jjdelcerro
        return ftype;
2111
    }
2112
2113 43215 jjdelcerro
    @Override
2114 40435 jjdelcerro
    public EditableFeatureType createFeatureType(String id) {
2115
        DefaultEditableFeatureType ftype = new DefaultEditableFeatureType(id);
2116
        return ftype;
2117
    }
2118
2119
    //
2120
    // ====================================================================
2121
    // Index related methods
2122
    //
2123 42293 jjdelcerro
2124 43215 jjdelcerro
    @Override
2125 40435 jjdelcerro
    public FeatureIndexes getIndexes() {
2126
        return this.indexes;
2127
    }
2128
2129 43215 jjdelcerro
    @Override
2130 40435 jjdelcerro
    public FeatureIndex createIndex(FeatureType featureType,
2131 42293 jjdelcerro
        String attributeName, String indexName) throws DataException {
2132 40435 jjdelcerro
        return createIndex(null, featureType, attributeName, indexName);
2133
    }
2134
2135 43215 jjdelcerro
    @Override
2136 40435 jjdelcerro
    public FeatureIndex createIndex(String indexTypeName,
2137 42293 jjdelcerro
        FeatureType featureType, String attributeName, String indexName)
2138
        throws DataException {
2139 40435 jjdelcerro
2140
        return createIndex(indexTypeName, featureType, attributeName,
2141 42293 jjdelcerro
            indexName, false, null);
2142 40435 jjdelcerro
    }
2143
2144 43215 jjdelcerro
    @Override
2145 40435 jjdelcerro
    public FeatureIndex createIndex(FeatureType featureType,
2146 42293 jjdelcerro
        String attributeName, String indexName, Observer observer)
2147
        throws DataException {
2148 40435 jjdelcerro
        return createIndex(null, featureType, attributeName, indexName,
2149 42293 jjdelcerro
            observer);
2150 40435 jjdelcerro
    }
2151
2152 43215 jjdelcerro
    @Override
2153 40435 jjdelcerro
    public FeatureIndex createIndex(String indexTypeName,
2154 42293 jjdelcerro
        FeatureType featureType, String attributeName, String indexName,
2155
        final Observer observer) throws DataException {
2156 40435 jjdelcerro
2157
        return createIndex(indexTypeName, featureType, attributeName,
2158 42293 jjdelcerro
            indexName, true, observer);
2159 40435 jjdelcerro
    }
2160
2161
    private FeatureIndex createIndex(String indexTypeName,
2162 42293 jjdelcerro
        FeatureType featureType, String attributeName, String indexName,
2163
        boolean background, final Observer observer) throws DataException {
2164 40435 jjdelcerro
2165
        checkNotInAppendMode();
2166 43215 jjdelcerro
        FeatureIndexProviderServices index;
2167
        index = dataManager.createFeatureIndexProvider(indexTypeName, this,
2168 42293 jjdelcerro
                featureType, indexName,
2169
                featureType.getAttributeDescriptor(attributeName));
2170 40435 jjdelcerro
2171
        try {
2172
            index.fill(background, observer);
2173
        } catch (FeatureIndexException e) {
2174
            throw new InitializeException(index.getName(), e);
2175
        }
2176
2177
        ((DefaultFeatureIndexes) getIndexes()).addIndex(index);
2178
        return index;
2179
    }
2180
2181
    //
2182
    // ====================================================================
2183
    // Transforms related methods
2184
    //
2185 42293 jjdelcerro
2186 43215 jjdelcerro
    @Override
2187 40435 jjdelcerro
    public FeatureStoreTransforms getTransforms() {
2188
        return this.transforms;
2189
    }
2190
2191 43215 jjdelcerro
    @Override
2192 40435 jjdelcerro
    public FeatureQuery createFeatureQuery() {
2193
        return new DefaultFeatureQuery();
2194
    }
2195
2196 43215 jjdelcerro
    @Override
2197 40435 jjdelcerro
    public DataQuery createQuery() {
2198
        return createFeatureQuery();
2199
    }
2200
2201
    //
2202
    // ====================================================================
2203
    // UndoRedo related methods
2204
    //
2205 42293 jjdelcerro
2206 43215 jjdelcerro
    @Override
2207 40435 jjdelcerro
    public boolean canRedo() {
2208
        return commands.canRedo();
2209
    }
2210
2211 43215 jjdelcerro
    @Override
2212 40435 jjdelcerro
    public boolean canUndo() {
2213
        return commands.canUndo();
2214
    }
2215
2216 43215 jjdelcerro
    @Override
2217 40435 jjdelcerro
    public void redo(int num) throws RedoException {
2218
        for (int i = 0; i < num; i++) {
2219
            redo();
2220
        }
2221
    }
2222
2223 43215 jjdelcerro
    @Override
2224 40435 jjdelcerro
    public void undo(int num) throws UndoException {
2225
        for (int i = 0; i < num; i++) {
2226
            undo();
2227
        }
2228
    }
2229
2230
    //
2231
    // ====================================================================
2232
    // Metadata related methods
2233
    //
2234 42293 jjdelcerro
2235 43215 jjdelcerro
    @Override
2236 40435 jjdelcerro
    public Object getMetadataID() {
2237
        return this.provider.getSourceId();
2238
    }
2239
2240 43215 jjdelcerro
    @Override
2241 40435 jjdelcerro
    public void delegate(DynObject dynObject) {
2242
        this.metadata.delegate(dynObject);
2243
    }
2244
2245 43215 jjdelcerro
    @Override
2246 40435 jjdelcerro
    public DynClass getDynClass() {
2247
        return this.metadata.getDynClass();
2248
    }
2249
2250 43215 jjdelcerro
    @Override
2251 42293 jjdelcerro
        public Object getDynValue(String name) throws DynFieldNotFoundException {
2252
                if( this.transforms.hasDynValue(name) ) {
2253
                        return this.transforms.getDynValue(name);
2254
                }
2255
                if (this.metadata.hasDynValue(name)) {
2256
                        return this.metadata.getDynValue(name);
2257
                }
2258
                if (METADATA_PROVIDER.equalsIgnoreCase(name)) {
2259
                        return this.provider.getProviderName();
2260
                } else if (METADATA_CONTAINERNAME.equalsIgnoreCase(name)) {
2261
                        return this.provider.getSourceId();
2262
                } else if (METADATA_FEATURETYPE.equalsIgnoreCase(name)) {
2263
                        try {
2264
                                return this.getDefaultFeatureType();
2265
                        } catch (DataException e) {
2266
                                return null;
2267
                        }
2268
                }
2269
                return this.metadata.getDynValue(name);
2270
        }
2271 40435 jjdelcerro
2272 43215 jjdelcerro
    @Override
2273 40435 jjdelcerro
    public boolean hasDynValue(String name) {
2274 42293 jjdelcerro
                if( this.transforms.hasDynValue(name) ) {
2275
                        return true;
2276
                }
2277 40435 jjdelcerro
        return this.metadata.hasDynValue(name);
2278
    }
2279 43270 fdiaz
2280 43215 jjdelcerro
    @Override
2281 43246 jjdelcerro
    public boolean hasDynMethod(String name) {
2282
        return ((DynObject_v2)this.metadata).hasDynMethod(name);
2283
    }
2284 43270 fdiaz
2285 43246 jjdelcerro
    @Override
2286 40435 jjdelcerro
    public void implement(DynClass dynClass) {
2287
        this.metadata.implement(dynClass);
2288
    }
2289
2290 43215 jjdelcerro
    @Override
2291 42775 jjdelcerro
    public Object invokeDynMethod(String name, Object[] args)
2292 42293 jjdelcerro
        throws DynMethodException {
2293 42775 jjdelcerro
        return this.metadata.invokeDynMethod(this, name, args);
2294 40435 jjdelcerro
    }
2295
2296 43215 jjdelcerro
    @Override
2297 42775 jjdelcerro
    public Object invokeDynMethod(int code, Object[] args)
2298 42293 jjdelcerro
        throws DynMethodException {
2299 42775 jjdelcerro
        return this.metadata.invokeDynMethod(this, code, args);
2300 40435 jjdelcerro
    }
2301
2302 43215 jjdelcerro
    @Override
2303 40435 jjdelcerro
    public void setDynValue(String name, Object value)
2304 42293 jjdelcerro
        throws DynFieldNotFoundException {
2305
                if( this.transforms.hasDynValue(name) ) {
2306
                        this.transforms.setDynValue(name, value);
2307
                        return;
2308
                }
2309 40435 jjdelcerro
        this.metadata.setDynValue(name, value);
2310
2311
    }
2312
2313
    /*
2314
     * (non-Javadoc)
2315 41818 fdiaz
     *
2316 40435 jjdelcerro
     * @see org.gvsig.metadata.Metadata#getMetadataChildren()
2317
     */
2318 43215 jjdelcerro
    @Override
2319 40435 jjdelcerro
    public Set getMetadataChildren() {
2320
        return this.metadataChildren;
2321
    }
2322
2323
    /*
2324
     * (non-Javadoc)
2325 41818 fdiaz
     *
2326 40435 jjdelcerro
     * @see org.gvsig.metadata.Metadata#getMetadataName()
2327
     */
2328 43215 jjdelcerro
    @Override
2329 40435 jjdelcerro
    public String getMetadataName() {
2330
        return this.provider.getProviderName();
2331
    }
2332
2333
    public FeatureTypeManager getFeatureTypeManager() {
2334
        return this.featureTypeManager;
2335
    }
2336
2337 43215 jjdelcerro
    @Override
2338 40435 jjdelcerro
    public long getFeatureCount() throws DataException {
2339
        if (featureCount == null) {
2340 43215 jjdelcerro
            featureCount = this.provider.getFeatureCount();
2341 40435 jjdelcerro
        }
2342 42556 dmartinezizquierdo
        if (this.isEditing()) {
2343
            if(this.isAppending()) {
2344
                try{
2345
                    throw new IllegalStateException();
2346
                } catch(IllegalStateException e) {
2347
                    LOG.info("Call DefaultFeatureStore.getFeatureCount editing in mode APPEND");
2348
                    e.printStackTrace();
2349
                }
2350
                return -1;
2351
            } else {
2352 43215 jjdelcerro
                return featureCount
2353 42556 dmartinezizquierdo
                    + this.featureManager.getDeltaSize();
2354
            }
2355 40435 jjdelcerro
        }
2356 43215 jjdelcerro
        return featureCount;
2357 40435 jjdelcerro
    }
2358
2359
    private Long getTemporalOID() {
2360 43215 jjdelcerro
        return this.temporalOid++;
2361 40435 jjdelcerro
    }
2362
2363 43215 jjdelcerro
    @Override
2364 40435 jjdelcerro
    public FeatureType getProviderFeatureType(String featureTypeId) {
2365
        if (featureTypeId == null) {
2366
            return this.defaultFeatureType;
2367
        }
2368
        FeatureType type;
2369
        Iterator iter = this.featureTypes.iterator();
2370
        while (iter.hasNext()) {
2371
            type = (FeatureType) iter.next();
2372
            if (type.getId().equals(featureTypeId)) {
2373
                return type;
2374
            }
2375
        }
2376
        return null;
2377
    }
2378
2379 43215 jjdelcerro
    @Override
2380 40435 jjdelcerro
    public FeatureProvider getFeatureProviderFromFeature(Feature feature) {
2381
        return ((DefaultFeature) feature).getData();
2382
    }
2383
2384 43215 jjdelcerro
    @Override
2385 40435 jjdelcerro
    public DataStore getStore() {
2386
        return this;
2387
    }
2388
2389 43215 jjdelcerro
    @Override
2390 40435 jjdelcerro
    public FeatureStore getFeatureStore() {
2391
        return this;
2392
    }
2393
2394 43215 jjdelcerro
    @Override
2395 43056 jjdelcerro
    public void createCache(String name, DynObject parameters)
2396
        throws DataException {
2397
        cache = dataManager.createFeatureCacheProvider(name, parameters);
2398
        if (cache == null) {
2399
            throw new CreateException("FeaureCacheProvider", null);
2400
        }
2401
        cache.apply(this, provider);
2402
        provider = cache;
2403 40435 jjdelcerro
2404 43056 jjdelcerro
        featureCount = null;
2405
    }
2406
2407 43215 jjdelcerro
    @Override
2408 43056 jjdelcerro
    public FeatureCache getCache() {
2409
        return cache;
2410
    }
2411
2412 43215 jjdelcerro
    @Override
2413 40435 jjdelcerro
    public void clear() {
2414
        if (metadata != null) {
2415
            metadata.clear();
2416
        }
2417
    }
2418
2419 43215 jjdelcerro
    @Override
2420 40435 jjdelcerro
    public String getName() {
2421 43215 jjdelcerro
        if( this.provider != null ) {
2422
            return this.provider.getName();
2423
        }
2424
        if( this.parameters instanceof HasAFile ) {
2425
            return FilenameUtils.getName(((HasAFile)this.parameters).getFile().getName());
2426
        }
2427
        return "unknow";
2428 40435 jjdelcerro
    }
2429
2430 43215 jjdelcerro
    @Override
2431 40435 jjdelcerro
    public String getFullName() {
2432 42049 jjdelcerro
        try {
2433 43215 jjdelcerro
            if( this.provider!=null ) {
2434
                return this.provider.getFullName();
2435
            }
2436
            if( this.parameters instanceof HasAFile ) {
2437
                return (((HasAFile)this.parameters).getFile().getAbsolutePath());
2438
            }
2439
            return null;
2440 42293 jjdelcerro
        } catch(Throwable th) {
2441 42049 jjdelcerro
            return null;
2442
        }
2443 40435 jjdelcerro
    }
2444
2445 43215 jjdelcerro
    @Override
2446 40435 jjdelcerro
    public String getProviderName() {
2447 43215 jjdelcerro
        if( this.provider!=null ) {
2448
            return this.provider.getProviderName();
2449
        }
2450
        if( this.parameters != null ) {
2451
            return this.parameters.getDataStoreName();
2452
        }
2453
        return null;
2454 43270 fdiaz
2455 40435 jjdelcerro
    }
2456
2457 43215 jjdelcerro
    @Override
2458 40435 jjdelcerro
    public boolean isKnownEnvelope() {
2459
        return this.provider.isKnownEnvelope();
2460
    }
2461
2462 43215 jjdelcerro
    @Override
2463 40435 jjdelcerro
    public boolean hasRetrievedFeaturesLimit() {
2464
        return this.provider.hasRetrievedFeaturesLimit();
2465
    }
2466
2467 43215 jjdelcerro
    @Override
2468 40435 jjdelcerro
    public int getRetrievedFeaturesLimit() {
2469
        return this.provider.getRetrievedFeaturesLimit();
2470
    }
2471
2472 43215 jjdelcerro
    @Override
2473 41818 fdiaz
    public Interval getInterval() {
2474 43135 jjdelcerro
        if( this.timeSupport!=null ) {
2475
            return this.timeSupport.getInterval();
2476
        }
2477 40435 jjdelcerro
        return this.provider.getInterval();
2478
    }
2479
2480 43215 jjdelcerro
    @Override
2481 41818 fdiaz
    public Collection getTimes() {
2482 43135 jjdelcerro
        if( this.timeSupport!=null ) {
2483
            return this.timeSupport.getTimes();
2484
        }
2485 40435 jjdelcerro
        return this.provider.getTimes();
2486
    }
2487
2488 43215 jjdelcerro
    @Override
2489 41818 fdiaz
    public Collection getTimes(Interval interval) {
2490 43135 jjdelcerro
        if( this.timeSupport!=null ) {
2491
            return this.timeSupport.getTimes(interval);
2492
        }
2493 40435 jjdelcerro
        return this.provider.getTimes(interval);
2494
    }
2495 41818 fdiaz
2496 43135 jjdelcerro
    public void setTimeSupport(FeatureStoreTimeSupport timeSupport) {
2497
        FeatureAttributeDescriptor attr;
2498
        DefaultFeatureType ft;
2499
        try {
2500
            ft = (DefaultFeatureType) this.getDefaultFeatureType();
2501
        } catch (DataException ex) {
2502
            throw new RuntimeException("Can't add time support, can't get the default feature type.", ex);
2503
        }
2504
        attr = ft.getAttributeDescriptor(timeSupport.getAttributeName());
2505
        if( attr != null ) {
2506
            throw new RuntimeException("Can't add time support, attribute '"+timeSupport.getAttributeName()+"'already exists.");
2507
        }
2508
        attr = ft.getAttributeDescriptor(timeSupport.getRequiredFieldNames()[0]);
2509
        if( attr != null ) {
2510
            throw new RuntimeException("Can't add time support over attribute '"+timeSupport.getAttributeName()+"', this attribute don't exists.");
2511
        }
2512
        DefaultEditableFeatureAttributeDescriptor attr2 = new DefaultEditableFeatureAttributeDescriptor();
2513
        attr2.setDataType(timeSupport.getDataType());
2514
        attr2.setIsTime(true);
2515
        attr2.setFeatureAttributeEmulator(timeSupport);
2516
        ft.add(attr2);
2517 43152 fdiaz
2518 43135 jjdelcerro
        this.timeSupport = timeSupport;
2519
    }
2520 43152 fdiaz
2521 43215 jjdelcerro
    @Override
2522 40435 jjdelcerro
    public Object clone() throws CloneNotSupportedException {
2523 41818 fdiaz
2524 40435 jjdelcerro
        DataStoreParameters dsp = getParameters();
2525 41818 fdiaz
2526 40435 jjdelcerro
        DefaultFeatureStore cloned_store = null;
2527 41818 fdiaz
2528 40435 jjdelcerro
        try {
2529
            cloned_store = (DefaultFeatureStore) DALLocator.getDataManager().
2530 42293 jjdelcerro
                openStore(this.getProviderName(), dsp);
2531 40435 jjdelcerro
            if (transforms != null) {
2532
                cloned_store.transforms = (DefaultFeatureStoreTransforms) transforms.clone();
2533 41093 jldominguez
                cloned_store.transforms.setStoreForClone(cloned_store);
2534 40435 jjdelcerro
            }
2535
        } catch (Exception e) {
2536
            throw new CloneException(e);
2537 41818 fdiaz
        }
2538 40435 jjdelcerro
        return cloned_store;
2539 41818 fdiaz
2540 40435 jjdelcerro
    }
2541 41818 fdiaz
2542 43215 jjdelcerro
    @Override
2543 41818 fdiaz
    public Feature getFeature(DynObject dynobject) {
2544 42293 jjdelcerro
        if (dynobject instanceof DynObjectFeatureFacade){
2545
            Feature f = ((DynObjectFeatureFacade)dynobject).getFeature();
2546 41818 fdiaz
            return f;
2547
        }
2548
        return null;
2549
    }
2550 42533 dmartinezizquierdo
2551 43215 jjdelcerro
    @Override
2552 42293 jjdelcerro
    public Iterator iterator() {
2553
        try {
2554
            return this.getFeatureSet().fastIterator();
2555
        } catch (DataException ex) {
2556
            throw new RuntimeException(ex);
2557
        }
2558
    }
2559 43020 jjdelcerro
2560
    @Override
2561 43088 jjdelcerro
    public ExpressionEvaluator createExpression() {
2562 43020 jjdelcerro
        if( this.provider instanceof FeatureStoreProvider_v2 ) {
2563 43088 jjdelcerro
            return ((FeatureStoreProvider_v2)this.provider).createExpression();
2564 43020 jjdelcerro
        }
2565
        return new SQLBuilderBase();
2566
    }
2567 43062 jjdelcerro
2568 43152 fdiaz
2569 43062 jjdelcerro
    public FeatureSet features() throws DataException {
2570
        // This is to avoid jython to create a property with this name
2571
        // to access method getFeatures.
2572
        return this.getFeatureSet();
2573
    }
2574 43152 fdiaz
2575
    @Override
2576 43190 jjdelcerro
    public DataStoreProviderFactory getProviderFactory() {
2577 43152 fdiaz
        DataStoreProviderFactory factory = dataManager.getStoreProviderFactory(parameters.getDataStoreName());
2578
        return factory;
2579
    }
2580
2581
    @Override
2582
    public void useCache(String providerName, DynObject parameters) throws DataException {
2583
        throw new UnsupportedOperationException();
2584
    }
2585 43270 fdiaz
2586 43215 jjdelcerro
    @Override
2587
    public boolean isBroken() {
2588
        return this.state.isBroken();
2589
    }
2590
2591
    @Override
2592
    public Throwable getBreakingsCause() {
2593
            return this.state.getBreakingsCause();
2594
    }
2595 43371 fdiaz
2596
    @Override
2597
    public SpatialIndex wrapSpatialIndex(SpatialIndex index) {
2598
//      FeatureStoreProviderFactory factory = (FeatureStoreProviderFactory) this.getProviderFactory();
2599
//      if( !factory.supportNumericOID() ) {
2600
//          return null;
2601
//      }
2602
      SpatialIndex wrappedIndex = new WrappedSpatialIndex(index, this);
2603
      return wrappedIndex;
2604
  }
2605 42293 jjdelcerro
}