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

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