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

History | View | Annotate | Download (86.4 KB)

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