Statistics
| Revision:

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

History | View | Annotate | Download (68 KB)

1 29956 jmvivo
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 *
6
 * 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 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * 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
 *
16
 * 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
 *
21
 */
22
23
/*
24
 * AUTHORS (In addition to CIT):
25
 * 2008 IVER T.I. S.A.   {{Task}}
26
 */
27
28 24496 jmvivo
package org.gvsig.fmap.dal.feature.impl;
29 23772 jjdelcerro
30 28017 jmvivo
import java.util.ArrayList;
31 37297 jpiera
import java.util.Collection;
32 28017 jmvivo
import java.util.Collections;
33 30208 jmvivo
import java.util.HashMap;
34 32880 jjdelcerro
import java.util.HashSet;
35 28017 jmvivo
import java.util.Iterator;
36
import java.util.List;
37 30208 jmvivo
import java.util.Map;
38 37595 jpiera
import java.util.Map.Entry;
39 37297 jpiera
import java.util.Set;
40 23772 jjdelcerro
41 26717 jmvivo
import org.cresques.cts.IProjection;
42 33657 cordinyana
import org.slf4j.Logger;
43
import org.slf4j.LoggerFactory;
44
45 28017 jmvivo
import org.gvsig.fmap.dal.DALLocator;
46
import org.gvsig.fmap.dal.DataManager;
47
import org.gvsig.fmap.dal.DataQuery;
48
import org.gvsig.fmap.dal.DataServerExplorer;
49
import org.gvsig.fmap.dal.DataSet;
50
import org.gvsig.fmap.dal.DataStore;
51
import org.gvsig.fmap.dal.DataStoreNotification;
52
import org.gvsig.fmap.dal.DataStoreParameters;
53
import org.gvsig.fmap.dal.exception.CloseException;
54 31541 jpiera
import org.gvsig.fmap.dal.exception.CreateException;
55 28017 jmvivo
import org.gvsig.fmap.dal.exception.DataException;
56
import org.gvsig.fmap.dal.exception.InitializeException;
57
import org.gvsig.fmap.dal.exception.OpenException;
58
import org.gvsig.fmap.dal.exception.ReadException;
59
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
60
import org.gvsig.fmap.dal.feature.EditableFeature;
61
import org.gvsig.fmap.dal.feature.EditableFeatureType;
62
import org.gvsig.fmap.dal.feature.Feature;
63
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
64 31541 jpiera
import org.gvsig.fmap.dal.feature.FeatureCache;
65 28017 jmvivo
import org.gvsig.fmap.dal.feature.FeatureIndex;
66
import org.gvsig.fmap.dal.feature.FeatureIndexes;
67
import org.gvsig.fmap.dal.feature.FeatureLocks;
68
import org.gvsig.fmap.dal.feature.FeatureQuery;
69
import org.gvsig.fmap.dal.feature.FeatureReference;
70
import org.gvsig.fmap.dal.feature.FeatureReferenceSelection;
71
import org.gvsig.fmap.dal.feature.FeatureSelection;
72
import org.gvsig.fmap.dal.feature.FeatureSet;
73
import org.gvsig.fmap.dal.feature.FeatureStore;
74
import org.gvsig.fmap.dal.feature.FeatureStoreNotification;
75
import org.gvsig.fmap.dal.feature.FeatureStoreTransforms;
76
import org.gvsig.fmap.dal.feature.FeatureType;
77
import org.gvsig.fmap.dal.feature.NewFeatureStoreParameters;
78
import org.gvsig.fmap.dal.feature.exception.AlreadyEditingException;
79
import org.gvsig.fmap.dal.feature.exception.ConcurrentDataModificationException;
80
import org.gvsig.fmap.dal.feature.exception.CreateFeatureException;
81
import org.gvsig.fmap.dal.feature.exception.DataExportException;
82
import org.gvsig.fmap.dal.feature.exception.FeatureIndexException;
83
import org.gvsig.fmap.dal.feature.exception.FinishEditingException;
84
import org.gvsig.fmap.dal.feature.exception.GetFeatureTypeException;
85
import org.gvsig.fmap.dal.feature.exception.IllegalFeatureException;
86
import org.gvsig.fmap.dal.feature.exception.IllegalFeatureTypeException;
87
import org.gvsig.fmap.dal.feature.exception.NeedEditingModeException;
88
import org.gvsig.fmap.dal.feature.exception.NoNewFeatureInsertException;
89
import org.gvsig.fmap.dal.feature.exception.NullFeatureTypeException;
90 32880 jjdelcerro
import org.gvsig.fmap.dal.feature.exception.PersistenceCantFindDefaultFeatureTypeException;
91
import org.gvsig.fmap.dal.feature.exception.PersistenceCantFindFeatureTypeException;
92
import org.gvsig.fmap.dal.feature.exception.PersistenceStoreAlreadyLoadedException;
93 28017 jmvivo
import org.gvsig.fmap.dal.feature.exception.SelectionNotAllowedException;
94
import org.gvsig.fmap.dal.feature.exception.StoreCancelEditingException;
95
import org.gvsig.fmap.dal.feature.exception.StoreDeleteEditableFeatureException;
96
import org.gvsig.fmap.dal.feature.exception.StoreDeleteFeatureException;
97
import org.gvsig.fmap.dal.feature.exception.StoreEditException;
98
import org.gvsig.fmap.dal.feature.exception.StoreInsertFeatureException;
99
import org.gvsig.fmap.dal.feature.exception.StoreUpdateFeatureException;
100
import org.gvsig.fmap.dal.feature.exception.StoreUpdateFeatureTypeException;
101
import org.gvsig.fmap.dal.feature.exception.ValidateFeaturesException;
102
import org.gvsig.fmap.dal.feature.exception.WriteNotAllowedException;
103 24496 jmvivo
import org.gvsig.fmap.dal.feature.impl.expansionadapter.MemoryExpansionAdapter;
104 24507 jmvivo
import org.gvsig.fmap.dal.feature.impl.featureset.DefaultFeatureSet;
105 24961 cordinyana
import org.gvsig.fmap.dal.feature.impl.undo.DefaultFeatureCommandsStack;
106
import org.gvsig.fmap.dal.feature.impl.undo.FeatureCommandsStack;
107 29289 jmvivo
import org.gvsig.fmap.dal.feature.spi.DefaultFeatureProvider;
108
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
109 28017 jmvivo
import org.gvsig.fmap.dal.feature.spi.FeatureReferenceProviderServices;
110
import org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider;
111
import org.gvsig.fmap.dal.feature.spi.FeatureStoreProviderServices;
112 31541 jpiera
import org.gvsig.fmap.dal.feature.spi.cache.FeatureCacheProvider;
113 24496 jmvivo
import org.gvsig.fmap.dal.feature.spi.index.FeatureIndexProviderServices;
114
import org.gvsig.fmap.dal.impl.DefaultDataManager;
115 25785 jmvivo
import org.gvsig.fmap.dal.resource.Resource;
116 35347 nbrodin
import org.gvsig.fmap.dal.spi.DataStoreInitializer;
117 29326 jmvivo
import org.gvsig.fmap.dal.spi.DataStoreProvider;
118 23772 jjdelcerro
import org.gvsig.fmap.geom.primitive.Envelope;
119 32880 jjdelcerro
import org.gvsig.metadata.MetadataLocator;
120
import org.gvsig.metadata.MetadataManager;
121
import org.gvsig.metadata.exceptions.MetadataException;
122 37297 jpiera
import org.gvsig.timesupport.Interval;
123 25267 jjdelcerro
import org.gvsig.tools.ToolsLocator;
124 33205 cordinyana
import org.gvsig.tools.dispose.DisposableIterator;
125 31284 cordinyana
import org.gvsig.tools.dispose.impl.AbstractDisposable;
126 28017 jmvivo
import org.gvsig.tools.dynobject.DelegatedDynObject;
127
import org.gvsig.tools.dynobject.DynClass;
128
import org.gvsig.tools.dynobject.DynObject;
129
import org.gvsig.tools.dynobject.DynObjectManager;
130 32880 jjdelcerro
import org.gvsig.tools.dynobject.DynStruct;
131 25785 jmvivo
import org.gvsig.tools.dynobject.exception.DynFieldNotFoundException;
132
import org.gvsig.tools.dynobject.exception.DynMethodException;
133 31284 cordinyana
import org.gvsig.tools.exception.BaseException;
134 24180 jjdelcerro
import org.gvsig.tools.exception.NotYetImplemented;
135 24794 jmvivo
import org.gvsig.tools.observer.Observable;
136 23772 jjdelcerro
import org.gvsig.tools.observer.Observer;
137 24268 jjdelcerro
import org.gvsig.tools.observer.impl.DelegateWeakReferencingObservable;
138 32880 jjdelcerro
import org.gvsig.tools.persistence.PersistenceManager;
139 30208 jmvivo
import org.gvsig.tools.persistence.Persistent;
140 28017 jmvivo
import org.gvsig.tools.persistence.PersistentState;
141 32880 jjdelcerro
import org.gvsig.tools.persistence.exception.PersistenceException;
142 24961 cordinyana
import org.gvsig.tools.undo.RedoException;
143
import org.gvsig.tools.undo.UndoException;
144 24922 vcaballero
import org.gvsig.tools.undo.command.Command;
145 31284 cordinyana
import org.gvsig.tools.visitor.Visitor;
146 23772 jjdelcerro
147 31284 cordinyana
public final class DefaultFeatureStore extends AbstractDisposable implements
148 36207 cordinyana
    DataStoreInitializer, FeatureStoreProviderServices, FeatureStore, Observer {
149 23772 jjdelcerro
150 36207 cordinyana
    private static final Logger LOG = LoggerFactory
151
        .getLogger(DefaultFeatureStore.class);
152 24178 cordinyana
153 34112 jpiera
    private static final String PERSISTENCE_DEFINITION_NAME = "FeatureStore";
154 32880 jjdelcerro
155 34112 jpiera
    private DataStoreParameters parameters = null;
156
    private FeatureSelection selection;
157
    private FeatureLocks locks;
158 23772 jjdelcerro
159 34968 nfrancisco
    private DelegateWeakReferencingObservable delegateObservable =
160
        new DelegateWeakReferencingObservable(this);
161 23772 jjdelcerro
162 34112 jpiera
    private FeatureCommandsStack commands;
163
    private FeatureTypeManager featureTypeManager;
164
    private FeatureManager featureManager;
165
    private SpatialManager spatialManager;
166 23772 jjdelcerro
167 34112 jpiera
    private FeatureType defaultFeatureType = null;
168
    private List featureTypes = new ArrayList();
169 23772 jjdelcerro
170 34112 jpiera
    private int mode = MODE_QUERY;
171
    private long versionOfUpdate = 0;
172
    private boolean hasStrongChanges = true;
173
    private boolean hasInserts = true;
174 23772 jjdelcerro
175 34112 jpiera
    private DefaultDataManager dataManager = null;
176 23772 jjdelcerro
177 34112 jpiera
    private FeatureStoreProvider provider = null;
178 23772 jjdelcerro
179 34112 jpiera
    private DefaultFeatureIndexes indexes;
180 23894 jjdelcerro
181 34112 jpiera
    private DefaultFeatureStoreTransforms transforms;
182 24613 jjdelcerro
183 37496 jjdelcerro
    DelegatedDynObject metadata;
184
185 34112 jpiera
    private Set metadataChildren;
186 25785 jmvivo
187 34112 jpiera
    private Long featureCount = null;
188 28017 jmvivo
189 34112 jpiera
    private long temporalOid = 0;
190 28423 jmvivo
191 34112 jpiera
    private FeatureCacheProvider cache;
192 31541 jpiera
193 34112 jpiera
    /*
194
     * TODO:
195 34968 nfrancisco
     *
196 34112 jpiera
     * - Comprobar que solo se pueden a�adir reglas de validacion sobre un
197
     * EditableFeatureType. - Comprobar que solo se puede hacer un update con un
198
     * featureType al que se le han cambiado las reglas de validacion cuando
199
     * hasStrongChanges=false.
200
     */
201 23772 jjdelcerro
202 33657 cordinyana
    public DefaultFeatureStore() {
203 23772 jjdelcerro
204 34112 jpiera
    }
205 23772 jjdelcerro
206 35347 nbrodin
    public void intializePhase1(DataManager dataManager,
207 34112 jpiera
        DataStoreParameters parameters) throws InitializeException {
208 23772 jjdelcerro
209 34112 jpiera
        DynObjectManager dynManager = ToolsLocator.getDynObjectManager();
210 25785 jmvivo
211 34968 nfrancisco
        this.metadata =
212
            (DelegatedDynObject) dynManager.createDynObject(
213
                METADATA_DEFINITION_NAME, MetadataManager.METADATA_NAMESPACE);
214 29326 jmvivo
215 36207 cordinyana
        this.dataManager = (DefaultDataManager) dataManager;
216 29326 jmvivo
217 34112 jpiera
        this.parameters = parameters;
218
        this.transforms = new DefaultFeatureStoreTransforms(this);
219
        try {
220
            indexes = new DefaultFeatureIndexes(this);
221
        } catch (DataException e) {
222
            throw new InitializeException(e);
223
        }
224 23772 jjdelcerro
225 34112 jpiera
    }
226 23772 jjdelcerro
227 34112 jpiera
    public void intializePhase2(DataStoreProvider provider) {
228
        this.provider = (FeatureStoreProvider) provider;
229
        this.delegate(provider);
230
        this.metadataChildren = new HashSet();
231
        this.metadataChildren.add(provider);
232
    }
233 24613 jjdelcerro
234 34112 jpiera
    public DataStoreParameters getParameters() {
235
        return parameters;
236
    }
237 23772 jjdelcerro
238 34112 jpiera
    public int getMode() {
239
        return this.mode;
240
    }
241 23772 jjdelcerro
242 34112 jpiera
    public DataManager getManager() {
243
        return this.dataManager;
244
    }
245 23820 jjdelcerro
246 34112 jpiera
    public Iterator getChildren() {
247
        return this.provider.getChilds();
248
    }
249 23820 jjdelcerro
250 34112 jpiera
    public FeatureStoreProvider getProvider() {
251
        return this.provider;
252
    }
253 23772 jjdelcerro
254 34112 jpiera
    public FeatureManager getFeatureManager() {
255
        return this.featureManager;
256
    }
257 23772 jjdelcerro
258 34112 jpiera
    public void setFeatureTypes(List types, FeatureType defaultType) {
259
        this.featureTypes = types;
260
        this.defaultFeatureType = defaultType;
261
    }
262 23772 jjdelcerro
263 34112 jpiera
    public void open() throws OpenException {
264
        // TODO: Se puede hacer un open estando en edicion ?
265 34968 nfrancisco
        this.notifyChange(DataStoreNotification.BEFORE_OPEN);
266 34112 jpiera
        this.provider.open();
267 34968 nfrancisco
        this.notifyChange(DataStoreNotification.AFTER_OPEN);
268 34112 jpiera
    }
269 23772 jjdelcerro
270 34112 jpiera
    public void refresh() throws OpenException, InitializeException {
271
        if (this.mode != MODE_QUERY) {
272
            throw new IllegalStateException();
273
        }
274
        this.notifyChange(FeatureStoreNotification.BEFORE_REFRESH);
275
        this.featureCount = null;
276
        this.provider.refresh();
277
        this.notifyChange(FeatureStoreNotification.AFTER_REFRESH);
278
    }
279 23820 jjdelcerro
280 34112 jpiera
    public void close() throws CloseException {
281
        // TODO: Se puede hacer un close estando en edicion ?
282 34968 nfrancisco
        this.notifyChange(DataStoreNotification.BEFORE_CLOSE);
283 34112 jpiera
        this.featureCount = null;
284
        this.provider.close();
285 34968 nfrancisco
        this.notifyChange(DataStoreNotification.AFTER_CLOSE);
286 34112 jpiera
    }
287 26252 jmvivo
288 34112 jpiera
    protected void doDispose() throws BaseException {
289 34968 nfrancisco
        this.notifyChange(DataStoreNotification.BEFORE_DISPOSE);
290 36242 cordinyana
        this.disposeIndexes();
291 34112 jpiera
        this.provider.dispose();
292
        if (this.selection != null) {
293
            this.selection.dispose();
294
            this.selection = null;
295
        }
296
        this.commands = null;
297
        this.featureCount = null;
298
        if (this.locks != null) {
299 34968 nfrancisco
            // this.locks.dispose();
300 34112 jpiera
            this.locks = null;
301
        }
302 23772 jjdelcerro
303 34112 jpiera
        if (this.featureTypeManager != null) {
304
            this.featureTypeManager.dispose();
305
            this.featureTypeManager = null;
306
        }
307 23772 jjdelcerro
308 34112 jpiera
        this.featureManager = null;
309
        this.spatialManager = null;
310 23772 jjdelcerro
311 34112 jpiera
        this.parameters = null;
312 34968 nfrancisco
        this.notifyChange(DataStoreNotification.AFTER_DISPOSE);
313 34112 jpiera
        if (delegateObservable != null) {
314
            this.delegateObservable.deleteObservers();
315
            this.delegateObservable = null;
316
        }
317
    }
318 23772 jjdelcerro
319 34112 jpiera
    public boolean allowWrite() {
320
        return this.provider.allowWrite();
321
    }
322 23772 jjdelcerro
323 34112 jpiera
    public boolean canWriteGeometry(int geometryType) throws DataException {
324
        return this.provider.canWriteGeometry(geometryType, 0);
325
    }
326
327
    public DataServerExplorer getExplorer() throws ReadException,
328 34968 nfrancisco
        ValidateDataParametersException {
329 34112 jpiera
        return this.provider.getExplorer();
330
    }
331
332
    /*
333 34968 nfrancisco
     * public Metadata getMetadata() throws MetadataNotFoundException {
334
     * // TODO:
335
     * // Si el provider devuelbe null habria que ver de construir aqui
336
     * // los metadatos basicos, como el Envelope y el SRS.
337
     *
338
     * // TODO: Estando en edicion el Envelope deberia de
339
     * // actualizarse usando el spatialManager
340
     * return this.provider.getMetadata();
341
     * }
342 34112 jpiera
     */
343 32901 cordinyana
344 34112 jpiera
    public Envelope getEnvelope() throws DataException {
345
        if (this.mode == MODE_FULLEDIT) {
346
            return this.spatialManager.getEnvelope();
347
        }
348 37521 jpiera
        if (hasDynValue(DataStore.METADATA_ENVELOPE)){
349
            return (Envelope)getDynValue(DataStore.METADATA_ENVELOPE);
350
        }
351 34112 jpiera
        return this.provider.getEnvelope();
352
    }
353 23772 jjdelcerro
354 34112 jpiera
    /**
355
     * @deprecated use getDefaultFeatureType().getDefaultSRS()
356
     */
357
    public IProjection getSRSDefaultGeometry() throws DataException {
358
        return this.getDefaultFeatureType().getDefaultSRS();
359
    }
360 23772 jjdelcerro
361 34112 jpiera
    public FeatureSelection createDefaultFeatureSelection()
362 34968 nfrancisco
        throws DataException {
363 34112 jpiera
        return new DefaultFeatureSelection(this);
364
    }
365 23772 jjdelcerro
366 34112 jpiera
    public FeatureProvider createDefaultFeatureProvider(FeatureType type)
367 34968 nfrancisco
        throws DataException {
368
        if (type.hasOID()) {
369 36207 cordinyana
            return new DefaultFeatureProvider(type,
370
                this.provider.createNewOID());
371 34112 jpiera
        }
372
        return new DefaultFeatureProvider(type);
373
    }
374 23772 jjdelcerro
375 34112 jpiera
    public void saveToState(PersistentState state) throws PersistenceException {
376 34968 nfrancisco
        if (this.mode != FeatureStore.MODE_QUERY) {
377 36207 cordinyana
            throw new PersistenceException(new IllegalStateException(
378
                this.getName()));
379 34112 jpiera
        }
380
        state.set("dataStoreName", this.getName());
381
        state.set("parameters", this.parameters);
382
        state.set("selection", this.selection);
383
        state.set("transforms", this.transforms);
384
        // TODO locks persistence
385
        // state.set("locks", this.locks);
386
        // TODO indexes persistence
387
        // state.set("indexes", this.indexes);
388
        Map evaluatedAttr = new HashMap(1);
389
        Iterator iterType = featureTypes.iterator();
390
        Iterator iterAttr;
391
        FeatureType type;
392
        DefaultFeatureAttributeDescriptor attr;
393
        List attrs;
394
        while (iterType.hasNext()) {
395
            type = (FeatureType) iterType.next();
396
            attrs = new ArrayList();
397
            iterAttr = type.iterator();
398
            while (iterAttr.hasNext()) {
399
                attr = (DefaultFeatureAttributeDescriptor) iterAttr.next();
400 34968 nfrancisco
                if ((attr.getEvaluator() != null)
401
                    && (attr.getEvaluator() instanceof Persistent)) {
402 34112 jpiera
                    attrs.add(attr);
403
                }
404
            }
405
            if (!attrs.isEmpty()) {
406
                evaluatedAttr.put(type.getId(), attrs);
407
            }
408 30208 jmvivo
409 34112 jpiera
        }
410 30208 jmvivo
411 34112 jpiera
        if (evaluatedAttr.isEmpty()) {
412
            evaluatedAttr = null;
413
        }
414 30208 jmvivo
415 34112 jpiera
        state.set("evaluatedAttributes", evaluatedAttr);
416
        state.set("defaultFeatureTypeId", defaultFeatureType.getId());
417 30208 jmvivo
418 34112 jpiera
    }
419 24019 jjdelcerro
420 34968 nfrancisco
    public void loadFromState(PersistentState state)
421
        throws PersistenceException {
422 34112 jpiera
        if (this.provider != null) {
423
            throw new PersistenceStoreAlreadyLoadedException(this.getName());
424
        }
425
        if (this.getManager() == null) {
426
            this.dataManager = (DefaultDataManager) DALLocator.getDataManager();
427
        }
428 24019 jjdelcerro
429 34968 nfrancisco
        DataStoreParameters params =
430
            (DataStoreParameters) state.get("parameters");
431 24019 jjdelcerro
432 34112 jpiera
        try {
433 24019 jjdelcerro
434 34112 jpiera
            this.dataManager.intializeDataStore(this, params);
435
            this.selection = (FeatureSelection) state.get("selection");
436 34968 nfrancisco
            this.transforms =
437
                (DefaultFeatureStoreTransforms) state.get("transforms");
438 34112 jpiera
            Map evaluatedAttributes = (Map) state.get("evaluatedAttributes");
439 34968 nfrancisco
            if ((evaluatedAttributes != null) && !evaluatedAttributes.isEmpty()) {
440 34112 jpiera
                List attrs;
441 34968 nfrancisco
                Iterator iterEntries =
442
                    evaluatedAttributes.entrySet().iterator();
443 34112 jpiera
                Entry entry;
444 34968 nfrancisco
                while (iterEntries.hasNext()) {
445 34112 jpiera
                    entry = (Entry) iterEntries.next();
446
                    attrs = (List) entry.getValue();
447 34968 nfrancisco
                    if (attrs.isEmpty()) {
448 34112 jpiera
                        continue;
449
                    }
450
                    int fTypePos = -1;
451
                    DefaultFeatureType type = null;
452 34968 nfrancisco
                    for (int i = 0; i < featureTypes.size(); i++) {
453 34112 jpiera
                        type = (DefaultFeatureType) featureTypes.get(i);
454 34968 nfrancisco
                        if (type.getId().equals(entry.getKey())) {
455 34112 jpiera
                            fTypePos = i;
456
                            break;
457
                        }
458
                    }
459 34968 nfrancisco
                    if (fTypePos < 0) {
460 36207 cordinyana
                        throw new PersistenceCantFindFeatureTypeException(
461
                            this.getName(), (String) entry.getKey());
462 34112 jpiera
                    }
463 34968 nfrancisco
                    DefaultEditableFeatureType eType =
464
                        (DefaultEditableFeatureType) type.getEditable();
465 34112 jpiera
                    Iterator iterAttr = attrs.iterator();
466
                    FeatureAttributeDescriptor attr;
467
                    while (iterAttr.hasNext()) {
468
                        attr = (FeatureAttributeDescriptor) iterAttr.next();
469
                        eType.addLike(attr);
470
                    }
471
                    featureTypes.set(fTypePos, eType.getNotEditableCopy());
472 30208 jmvivo
473 34112 jpiera
                }
474 30208 jmvivo
475 34112 jpiera
            }
476 24062 jjdelcerro
477 34112 jpiera
            String defFTypeid = state.getString("defaultFeatureTypeId");
478
            FeatureType ftype = null;
479
            if (!this.defaultFeatureType.getId().equals(
480
                state.getString("defaultFeatureTypeId"))) {
481 30208 jmvivo
482 34112 jpiera
                ftype = getFeatureType(defFTypeid);
483
                if (ftype == null) {
484 34968 nfrancisco
                    throw new PersistenceCantFindDefaultFeatureTypeException(
485
                        this.getName(), defFTypeid);
486 34112 jpiera
                }
487
                this.defaultFeatureType = ftype;
488
            }
489 30208 jmvivo
490 34112 jpiera
        } catch (InitializeException e) {
491
            throw new PersistenceException(e);
492
        } catch (DataException e) {
493
            throw new PersistenceException(e);
494
        }
495 24062 jjdelcerro
496 34112 jpiera
    }
497 24019 jjdelcerro
498 34112 jpiera
    public static void registerPersistenceDefinition() {
499
        PersistenceManager manager = ToolsLocator.getPersistenceManager();
500 34968 nfrancisco
        if (manager.getDefinition(PERSISTENCE_DEFINITION_NAME) == null) {
501
            DynStruct definition =
502
                manager.addDefinition(DefaultFeatureStore.class,
503
                    PERSISTENCE_DEFINITION_NAME, PERSISTENCE_DEFINITION_NAME
504
                        + " Persistent definition", null, null);
505
            definition.addDynFieldString("dataStoreName").setMandatory(true)
506
                .setPersistent(true);
507 30208 jmvivo
508 36207 cordinyana
            definition.addDynFieldObject("parameters")
509
                .setClassOfValue(DynObject.class).setMandatory(true)
510
                .setPersistent(true);
511 23772 jjdelcerro
512 36207 cordinyana
            definition.addDynFieldObject("selection")
513
                .setClassOfValue(FeatureSelection.class).setMandatory(false)
514 34968 nfrancisco
                .setPersistent(true);
515 23772 jjdelcerro
516 36207 cordinyana
            definition.addDynFieldObject("transforms")
517
                .setClassOfValue(DefaultFeatureStoreTransforms.class)
518
                .setMandatory(true).setPersistent(true);
519
520
            definition.addDynFieldMap("evaluatedAttributes")
521
                .setClassOfItems(List.class) // List<DefaultFeatureAttributeDescriptor>
522 34968 nfrancisco
                .setMandatory(false).setPersistent(true);
523 23772 jjdelcerro
524 36207 cordinyana
            definition.addDynFieldString("defaultFeatureTypeId")
525
                .setMandatory(true).setPersistent(true);
526 34112 jpiera
        }
527
    }
528
529
    public static void registerMetadataDefinition() throws MetadataException {
530
        MetadataManager manager = MetadataLocator.getMetadataManager();
531 34968 nfrancisco
        if (manager.getDefinition(METADATA_DEFINITION_NAME) == null) {
532
            DynStruct metadataDefinition =
533
                manager.addDefinition(METADATA_DEFINITION_NAME, null);
534
            metadataDefinition.extend(manager
535
                .getDefinition(DataStore.METADATA_DEFINITION_NAME));
536 34112 jpiera
        }
537
    }
538
539
    //
540
    // ====================================================================
541
    // Gestion de la seleccion
542
    //
543
544 34968 nfrancisco
    public void setSelection(DataSet selection) throws DataException {
545 34112 jpiera
        this.setSelection((FeatureSet) selection);
546
    }
547
548
    public DataSet createSelection() throws DataException {
549
        return createFeatureSelection();
550
    }
551
552
    public DataSet getSelection() throws DataException {
553
        return this.getFeatureSelection();
554
    }
555
556 26317 cordinyana
    public void setSelection(FeatureSet selection) throws DataException {
557
        setSelection(selection, true);
558
    }
559
560
    /**
561
     * @see #setSelection(FeatureSet)
562
     * @param undoable
563
     *            if the action must be undoable
564
     */
565
    public void setSelection(FeatureSet selection, boolean undoable)
566 34968 nfrancisco
        throws DataException {
567 34112 jpiera
        if (selection == null) {
568
            if (undoable) {
569
                throw new SelectionNotAllowedException(getName());
570
            }
571 30064 jmvivo
572 34112 jpiera
        } else {
573
            if (selection.equals(this.selection)) {
574
                return;
575
            }
576
            if (!selection.isFromStore(this)) {
577
                throw new SelectionNotAllowedException(getName());
578
            }
579
        }
580 30064 jmvivo
581 34112 jpiera
        if (this.selection != null) {
582
            this.selection.deleteObserver(this);
583
        }
584
        if (selection == null) {
585
            if (this.selection != null) {
586
                this.selection.dispose();
587
            }
588
            this.selection = null;
589
            return;
590
        }
591
        if (selection instanceof FeatureSelection) {
592
            if (undoable && isEditing()) {
593
                commands.selectionSet(this, this.selection,
594
                    (FeatureSelection) selection);
595
            }
596
            if (this.selection != null) {
597
                this.selection.dispose();
598
            }
599
            this.selection = (FeatureSelection) selection;
600
        } else {
601
            if (undoable && isEditing()) {
602
                commands.startComplex("_selectionSet");
603
            }
604
            if (selection instanceof DefaultFeatureSelection) {
605 34968 nfrancisco
                DefaultFeatureSelection defSelection =
606
                    (DefaultFeatureSelection) selection;
607 26318 cordinyana
                defSelection.deselectAll(undoable);
608
                defSelection.select(selection, undoable);
609
            } else {
610
                this.selection.deselectAll();
611
                this.selection.select(selection);
612
            }
613 34112 jpiera
            if (undoable && isEditing()) {
614
                commands.endComplex();
615
            }
616
        }
617
        this.selection.addObserver(this);
618 23894 jjdelcerro
619 34112 jpiera
        this.notifyChange(DataStoreNotification.SELECTION_CHANGE);
620
    }
621 23772 jjdelcerro
622 34112 jpiera
    public FeatureSelection createFeatureSelection() throws DataException {
623
        return this.provider.createFeatureSelection();
624
    }
625 23772 jjdelcerro
626 34112 jpiera
    public FeatureSelection getFeatureSelection() throws DataException {
627
        if (selection == null) {
628
            this.selection = createFeatureSelection();
629
            this.selection.addObserver(this);
630
        }
631
        return selection;
632
    }
633 23772 jjdelcerro
634 34112 jpiera
    //
635
    // ====================================================================
636
    // Gestion de notificaciones
637
    //
638 23772 jjdelcerro
639 34112 jpiera
    public void notifyChange(String notification) {
640
        if (delegateObservable != null) {
641 34968 nfrancisco
            notifyChange(new DefaultFeatureStoreNotification(this, notification));
642 34112 jpiera
        }
643 23772 jjdelcerro
644 34112 jpiera
    }
645 23772 jjdelcerro
646 34968 nfrancisco
    public void notifyChange(String notification, FeatureProvider data) {
647
        try {
648
            notifyChange(notification, createFeature(data));
649
        } catch (DataException ex) {
650 36207 cordinyana
            LOG.error("Error notifying about the notification: " + notification
651
                + ", with the data: " + data, ex);
652 34968 nfrancisco
        }
653
    }
654 34319 cordinyana
655 34112 jpiera
    public void notifyChange(String notification, Feature feature) {
656 34968 nfrancisco
        notifyChange(new DefaultFeatureStoreNotification(this, notification,
657
            feature));
658 34112 jpiera
    }
659 23772 jjdelcerro
660 34112 jpiera
    public void notifyChange(String notification, Command command) {
661 34968 nfrancisco
        notifyChange(new DefaultFeatureStoreNotification(this, notification,
662
            command));
663 34112 jpiera
    }
664 23772 jjdelcerro
665 34112 jpiera
    public void notifyChange(String notification, EditableFeatureType type) {
666 34968 nfrancisco
        notifyChange(new DefaultFeatureStoreNotification(this, notification,
667
            type));
668 34112 jpiera
    }
669 23772 jjdelcerro
670 34968 nfrancisco
    public void notifyChange(FeatureStoreNotification storeNotification) {
671
        delegateObservable.notifyObservers(storeNotification);
672
    }
673 34319 cordinyana
674 34112 jpiera
    public void notifyChange(String notification, Resource resource) {
675 34968 nfrancisco
        notifyChange(new DefaultFeatureStoreNotification(this,
676
            DataStoreNotification.RESOURCE_CHANGED));
677 34112 jpiera
    }
678 25785 jmvivo
679 34112 jpiera
    //
680
    // ====================================================================
681
    // Gestion de bloqueos
682
    //
683 23772 jjdelcerro
684 34112 jpiera
    public boolean isLocksSupported() {
685
        return this.provider.isLocksSupported();
686
    }
687 23772 jjdelcerro
688 34112 jpiera
    public FeatureLocks getLocks() throws DataException {
689
        if (!this.provider.isLocksSupported()) {
690 36207 cordinyana
            LOG.warn("Locks not supporteds");
691 34112 jpiera
            return null;
692
        }
693
        if (locks == null) {
694
            this.locks = this.provider.createFeatureLocks();
695
        }
696
        return locks;
697
    }
698 23772 jjdelcerro
699 34112 jpiera
    //
700
    // ====================================================================
701
    // Interface Observable
702
    //
703 23772 jjdelcerro
704 34112 jpiera
    public void disableNotifications() {
705
        this.delegateObservable.disableNotifications();
706 23772 jjdelcerro
707 34112 jpiera
    }
708 23772 jjdelcerro
709 34112 jpiera
    public void enableNotifications() {
710
        this.delegateObservable.enableNotifications();
711
    }
712 23772 jjdelcerro
713 34112 jpiera
    public void beginComplexNotification() {
714
        this.delegateObservable.beginComplexNotification();
715 23772 jjdelcerro
716 34112 jpiera
    }
717 23772 jjdelcerro
718 34112 jpiera
    public void endComplexNotification() {
719
        this.delegateObservable.endComplexNotification();
720 23772 jjdelcerro
721 34112 jpiera
    }
722 23772 jjdelcerro
723 34112 jpiera
    public void addObserver(Observer observer) {
724 36242 cordinyana
        if (delegateObservable != null) {
725
            this.delegateObservable.addObserver(observer);
726
        }
727 34112 jpiera
    }
728 23772 jjdelcerro
729 34112 jpiera
    public void deleteObserver(Observer observer) {
730
        if (delegateObservable != null) {
731
            this.delegateObservable.deleteObserver(observer);
732
        }
733
    }
734 23772 jjdelcerro
735 34112 jpiera
    public void deleteObservers() {
736
        this.delegateObservable.deleteObservers();
737 23772 jjdelcerro
738 34112 jpiera
    }
739 23772 jjdelcerro
740 34112 jpiera
    //
741
    // ====================================================================
742
    // Interface Observer
743
    //
744
    // Usado para observar:
745
    // - su seleccion
746
    // - sus bloqueos
747
    // - sus recursos
748
    //
749 23772 jjdelcerro
750 34112 jpiera
    public void update(Observable observable, Object notification) {
751
        if (observable instanceof FeatureSet) {
752
            if (observable == this.selection) {
753 34968 nfrancisco
                this.notifyChange(DataStoreNotification.SELECTION_CHANGE);
754
            } else
755
                if (observable == this.locks) {
756
                    this.notifyChange(FeatureStoreNotification.LOCKS_CHANGE);
757
                }
758 23772 jjdelcerro
759 34968 nfrancisco
        } else
760
            if (observable instanceof FeatureStoreProvider) {
761
                if (observable == this.provider) {
762 23772 jjdelcerro
763 34968 nfrancisco
                }
764 23772 jjdelcerro
765 34968 nfrancisco
            }
766 34112 jpiera
    }
767 23772 jjdelcerro
768 34112 jpiera
    //
769
    // ====================================================================
770
    // Edicion
771
    //
772 23772 jjdelcerro
773 34112 jpiera
    private void newVersionOfUpdate() {
774
        this.versionOfUpdate++;
775
    }
776 23772 jjdelcerro
777 34112 jpiera
    private long currentVersionOfUpdate() {
778
        return this.versionOfUpdate;
779
    }
780 23772 jjdelcerro
781 34968 nfrancisco
    private void checkInEditingMode() throws NeedEditingModeException {
782 34112 jpiera
        if (mode != MODE_FULLEDIT) {
783
            throw new NeedEditingModeException(this.getName());
784
        }
785
    }
786 23772 jjdelcerro
787 34112 jpiera
    private void checkNotInAppendMode() throws IllegalStateException {
788
        if (mode == MODE_APPEND) {
789 38198 cordinyana
                        throw new IllegalStateException("Error: store "
790
                                        + this.getFullName() + " is in append mode");
791 34112 jpiera
        }
792
    }
793 24180 jjdelcerro
794 34112 jpiera
    private void checkIsOwnFeature(Feature feature)
795 34968 nfrancisco
        throws IllegalFeatureException {
796 34112 jpiera
        if (((DefaultFeature) feature).getStore() != this) {
797
            throw new IllegalFeatureException(this.getName());
798
        }
799
        // FIXME: fixFeatureType no vale para el checkIsOwnFeature
800
        // fixFeatureType((DefaultFeatureType) feature.getType());
801
    }
802 23772 jjdelcerro
803 34112 jpiera
    private void exitEditingMode() {
804
        if (commands != null) {
805
            commands.clear();
806
            commands = null;
807
        }
808 26252 jmvivo
809 34112 jpiera
        if (featureTypeManager != null) {
810
            featureTypeManager.dispose();
811
            featureTypeManager = null;
812 26252 jmvivo
813 34112 jpiera
        }
814 26252 jmvivo
815 34112 jpiera
        // TODO implementar un dispose para estos dos
816
        featureManager = null;
817
        spatialManager = null;
818 23772 jjdelcerro
819 34112 jpiera
        featureCount = null;
820 28017 jmvivo
821 34112 jpiera
        mode = MODE_QUERY;
822
        hasStrongChanges = true; // Lo deja a true por si las moscas
823
        hasInserts = true;
824
    }
825 23772 jjdelcerro
826 34112 jpiera
    synchronized public void edit() throws DataException {
827
        edit(MODE_FULLEDIT);
828
    }
829 24162 jjdelcerro
830 34112 jpiera
    synchronized public void edit(int mode) throws DataException {
831 36359 cordinyana
        LOG.debug("Starting editing in mode: {}", new Integer(mode));
832 34112 jpiera
        try {
833 34968 nfrancisco
            if (this.mode != MODE_QUERY) {
834 34112 jpiera
                throw new AlreadyEditingException(this.getName());
835
            }
836
            if (!this.provider.supportsAppendMode()) {
837
                mode = MODE_FULLEDIT;
838
            }
839
            switch (mode) {
840
            case MODE_QUERY:
841
                throw new IllegalStateException(this.getName());
842 23772 jjdelcerro
843 34112 jpiera
            case MODE_FULLEDIT:
844
                if (!this.transforms.isEmpty()) {
845
                    throw new IllegalStateException(this.getName());
846
                }
847
                notifyChange(FeatureStoreNotification.BEFORE_STARTEDITING);
848 36190 cordinyana
                invalidateIndexes();
849 34968 nfrancisco
                featureManager =
850
                    new FeatureManager(new MemoryExpansionAdapter());
851
                featureTypeManager =
852
                    new FeatureTypeManager(this, new MemoryExpansionAdapter());
853
                spatialManager =
854
                    new SpatialManager(this, provider.getEnvelope());
855 23772 jjdelcerro
856 34968 nfrancisco
                commands =
857 37595 jpiera
                    new DefaultFeatureCommandsStack(this, featureManager,
858 34968 nfrancisco
                        spatialManager, featureTypeManager);
859 34112 jpiera
                this.mode = MODE_FULLEDIT;
860
                hasStrongChanges = false;
861
                hasInserts = false;
862
                notifyChange(FeatureStoreNotification.AFTER_STARTEDITING);
863
                break;
864
            case MODE_APPEND:
865
                if (!this.transforms.isEmpty()) {
866
                    throw new IllegalStateException(this.getName());
867
                }
868
                notifyChange(FeatureStoreNotification.BEFORE_STARTEDITING);
869 36190 cordinyana
                invalidateIndexes();
870 34112 jpiera
                this.provider.beginAppend();
871
                this.mode = MODE_APPEND;
872
                hasInserts = false;
873
                notifyChange(FeatureStoreNotification.AFTER_STARTEDITING);
874
                break;
875
            }
876
        } catch (Exception e) {
877
            throw new StoreEditException(e, this.getName());
878
        }
879
    }
880 23772 jjdelcerro
881 36190 cordinyana
    private void invalidateIndexes() {
882 36207 cordinyana
        setIndexesValidStatus(false);
883 36190 cordinyana
    }
884
885 36207 cordinyana
    private void setIndexesValidStatus(boolean valid) {
886 36190 cordinyana
        FeatureIndexes indexes = getIndexes();
887 36359 cordinyana
        LOG.debug("Setting the store indexes to valid status {}: {}", (valid
888
            ? Boolean.TRUE : Boolean.FALSE), indexes);
889 36190 cordinyana
        for (Iterator iterator = indexes.iterator(); iterator.hasNext();) {
890
            FeatureIndex index = (FeatureIndex) iterator.next();
891 36359 cordinyana
            if (index instanceof FeatureIndexProviderServices) {
892
                FeatureIndexProviderServices indexServices =
893
                    (FeatureIndexProviderServices) index;
894
                indexServices.setValid(valid);
895 36190 cordinyana
            }
896
        }
897
    }
898
899 36207 cordinyana
    private void updateIndexes() throws FeatureIndexException {
900 36190 cordinyana
        FeatureIndexes indexes = getIndexes();
901 36359 cordinyana
        LOG.debug("Refilling indexes: {}", indexes);
902 36190 cordinyana
        for (Iterator iterator = indexes.iterator(); iterator.hasNext();) {
903
            FeatureIndex index = (FeatureIndex) iterator.next();
904 36207 cordinyana
            if (index instanceof FeatureIndexProviderServices) {
905
                FeatureIndexProviderServices indexServices =
906
                    (FeatureIndexProviderServices) index;
907 36235 cordinyana
                indexServices.fill(true, null);
908 36190 cordinyana
            }
909
        }
910
    }
911
912 36359 cordinyana
    private void waitForIndexes() {
913
        FeatureIndexes indexes = getIndexes();
914
        LOG.debug("Waiting for indexes to finish filling: {}", indexes);
915
        for (Iterator iterator = indexes.iterator(); iterator.hasNext();) {
916
            FeatureIndex index = (FeatureIndex) iterator.next();
917
            if (index instanceof FeatureIndexProviderServices) {
918
                FeatureIndexProviderServices indexServices =
919
                    (FeatureIndexProviderServices) index;
920
                indexServices.waitForIndex();
921
            }
922
        }
923
    }
924
925 36242 cordinyana
    private void disposeIndexes() {
926
        FeatureIndexes indexes = getIndexes();
927 36359 cordinyana
        LOG.debug("Disposing indexes: {}", indexes);
928 36242 cordinyana
        for (Iterator iterator = indexes.iterator(); iterator.hasNext();) {
929
            FeatureIndex index = (FeatureIndex) iterator.next();
930
            if (index instanceof FeatureIndexProviderServices) {
931
                FeatureIndexProviderServices indexServices =
932
                    (FeatureIndexProviderServices) index;
933
                indexServices.dispose();
934
            }
935
        }
936
    }
937
938 34112 jpiera
    public boolean isEditing() {
939
        return mode == MODE_FULLEDIT;
940
    }
941 23772 jjdelcerro
942 34112 jpiera
    public boolean isAppending() {
943
        return mode == MODE_APPEND;
944
    }
945 24162 jjdelcerro
946 34112 jpiera
    synchronized public void update(EditableFeatureType type)
947 34968 nfrancisco
        throws DataException {
948 34112 jpiera
        try {
949
            checkInEditingMode();
950
            if (type == null) {
951
                throw new NullFeatureTypeException(getName());
952
            }
953
            // FIXME: Comprobar que es un featureType aceptable.
954
            notifyChange(FeatureStoreNotification.BEFORE_UPDATE_TYPE, type);
955
            newVersionOfUpdate();
956 23772 jjdelcerro
957 34112 jpiera
            FeatureType oldt = type.getSource().getCopy();
958
            FeatureType newt = type.getNotEditableCopy();
959
            commands.update(newt, oldt);
960 23772 jjdelcerro
961 34112 jpiera
            if (((DefaultEditableFeatureType) type).hasStrongChanges()) {
962
                hasStrongChanges = true;
963
            }
964
            notifyChange(FeatureStoreNotification.AFTER_UPDATE_TYPE, type);
965
        } catch (Exception e) {
966
            throw new StoreUpdateFeatureTypeException(e, this.getName());
967
        }
968
    }
969 23772 jjdelcerro
970 37595 jpiera
    public void delete(Feature feature) throws DataException {
971
        this.commands.delete(feature);
972
    }
973
974
    synchronized public void doDelete(Feature feature) throws DataException {
975 34112 jpiera
        try {
976
            checkInEditingMode();
977
            checkIsOwnFeature(feature);
978
            if (feature instanceof EditableFeature) {
979
                throw new StoreDeleteEditableFeatureException(getName());
980
            }
981 37595 jpiera
            notifyChange(FeatureStoreNotification.BEFORE_DELETE, feature);
982
983
            //Update the featureManager and the spatialManager
984
            featureManager.delete(feature.getReference());
985
            spatialManager.deleteFeature(feature);
986
987 34112 jpiera
            newVersionOfUpdate();
988
            hasStrongChanges = true;
989
            notifyChange(FeatureStoreNotification.AFTER_DELETE, feature);
990
        } catch (Exception e) {
991
            throw new StoreDeleteFeatureException(e, this.getName());
992
        }
993
    }
994 23772 jjdelcerro
995 34112 jpiera
    private static EditableFeature lastChangedFeature = null;
996 23772 jjdelcerro
997 37595 jpiera
    public synchronized void insert(EditableFeature feature)
998 34968 nfrancisco
        throws DataException {
999 36359 cordinyana
        LOG.debug("In editing mode {}, insert feature: {}", new Integer(mode),
1000
            feature);
1001 34112 jpiera
        try {
1002
            switch (mode) {
1003
            case MODE_QUERY:
1004
                throw new NeedEditingModeException(this.getName());
1005 24162 jjdelcerro
1006 34112 jpiera
            case MODE_APPEND:
1007
                checkIsOwnFeature(feature);
1008
                if (feature.getSource() != null) {
1009
                    throw new NoNewFeatureInsertException(this.getName());
1010
                }
1011
                this.featureCount = null;
1012
                notifyChange(FeatureStoreNotification.BEFORE_INSERT, feature);
1013
                feature.validate(Feature.UPDATE);
1014
                provider.append(((DefaultEditableFeature) feature).getData());
1015
                hasStrongChanges = true;
1016
                hasInserts = true;
1017
                notifyChange(FeatureStoreNotification.AFTER_INSERT, feature);
1018
                break;
1019 24162 jjdelcerro
1020 37595 jpiera
            case MODE_FULLEDIT:
1021 34112 jpiera
                if (feature.getSource() != null) {
1022
                    throw new NoNewFeatureInsertException(this.getName());
1023
                }
1024 37595 jpiera
                commands.insert(feature);
1025 34112 jpiera
            }
1026
        } catch (Exception e) {
1027
            throw new StoreInsertFeatureException(e, this.getName());
1028
        }
1029
    }
1030 37595 jpiera
1031
    synchronized public void doInsert(EditableFeature feature)
1032
        throws DataException {
1033
        checkIsOwnFeature(feature);
1034
1035
        waitForIndexes();
1036 23772 jjdelcerro
1037 37595 jpiera
        notifyChange(FeatureStoreNotification.BEFORE_INSERT, feature);
1038
        newVersionOfUpdate();
1039
        if ((lastChangedFeature == null)
1040
            || (lastChangedFeature.getSource() != feature.getSource())) {
1041
            lastChangedFeature = feature;
1042
            feature.validate(Feature.UPDATE);
1043
            lastChangedFeature = null;
1044
        }
1045
        //Update the featureManager and the spatialManager
1046 38249 jldominguez
        ((DefaultEditableFeature) feature).setInserted(true);
1047
        DefaultFeature newFeature = (DefaultFeature) feature.getNotEditableCopy();
1048
1049
1050 37595 jpiera
        featureManager.add(newFeature);
1051
        spatialManager.insertFeature(newFeature);
1052
1053
        hasStrongChanges = true;
1054
        hasInserts = true;
1055
        notifyChange(FeatureStoreNotification.AFTER_INSERT, feature);
1056
    }
1057
1058
    public void update(EditableFeature feature)
1059
    throws DataException {
1060
        if ((feature).getSource() == null) {
1061
            insert(feature);
1062
            return;
1063
        }
1064
        commands.update(feature, feature.getSource());
1065
    }
1066
1067
    synchronized public void doUpdate(EditableFeature feature, Feature oldFeature)
1068 34968 nfrancisco
        throws DataException {
1069 37595 jpiera
        try {
1070 34112 jpiera
            checkInEditingMode();
1071
            checkIsOwnFeature(feature);
1072
            notifyChange(FeatureStoreNotification.BEFORE_UPDATE, feature);
1073
            newVersionOfUpdate();
1074 34968 nfrancisco
            if ((lastChangedFeature == null)
1075
                || (lastChangedFeature.getSource() != feature.getSource())) {
1076 34112 jpiera
                lastChangedFeature = feature;
1077
                feature.validate(Feature.UPDATE);
1078
                lastChangedFeature = null;
1079
            }
1080 37595 jpiera
1081
            //Update the featureManager and the spatialManager
1082 34112 jpiera
            Feature newf = feature.getNotEditableCopy();
1083 37595 jpiera
            featureManager.update(newf, oldFeature);
1084
            spatialManager.updateFeature(newf, oldFeature);
1085
1086 34112 jpiera
            hasStrongChanges = true;
1087
            notifyChange(FeatureStoreNotification.AFTER_UPDATE, feature);
1088
        } catch (Exception e) {
1089
            throw new StoreUpdateFeatureException(e, this.getName());
1090
        }
1091
    }
1092 23772 jjdelcerro
1093 34112 jpiera
    synchronized public void redo() throws RedoException {
1094
        Command redo = commands.getNextRedoCommand();
1095
        try {
1096
            checkInEditingMode();
1097
        } catch (NeedEditingModeException ex) {
1098
            throw new RedoException(redo, ex);
1099
        }
1100
        notifyChange(FeatureStoreNotification.BEFORE_REDO, redo);
1101
        newVersionOfUpdate();
1102
        commands.redo();
1103
        hasStrongChanges = true;
1104
        notifyChange(FeatureStoreNotification.AFTER_REDO, redo);
1105
    }
1106 23772 jjdelcerro
1107 34112 jpiera
    synchronized public void undo() throws UndoException {
1108
        Command undo = commands.getNextUndoCommand();
1109
        try {
1110
            checkInEditingMode();
1111
        } catch (NeedEditingModeException ex) {
1112
            throw new UndoException(undo, ex);
1113
        }
1114
        notifyChange(FeatureStoreNotification.BEFORE_UNDO, undo);
1115
        newVersionOfUpdate();
1116
        commands.undo();
1117
        hasStrongChanges = true;
1118
        notifyChange(FeatureStoreNotification.AFTER_UNDO, undo);
1119
    }
1120 23772 jjdelcerro
1121 34112 jpiera
    public List getRedoInfos() {
1122 34968 nfrancisco
        if (isEditing() && (commands != null)) {
1123 34112 jpiera
            return commands.getRedoInfos();
1124
        } else {
1125
            return null;
1126
        }
1127
    }
1128 23772 jjdelcerro
1129 34112 jpiera
    public List getUndoInfos() {
1130 34968 nfrancisco
        if (isEditing() && (commands != null)) {
1131 34112 jpiera
            return commands.getUndoInfos();
1132
        } else {
1133
            return null;
1134
        }
1135
    }
1136 24961 cordinyana
1137 34112 jpiera
    public synchronized FeatureCommandsStack getCommandsStack()
1138 34968 nfrancisco
        throws DataException {
1139 34112 jpiera
        checkInEditingMode();
1140
        return commands;
1141
    }
1142 24961 cordinyana
1143 34112 jpiera
    synchronized public void cancelEditing() throws DataException {
1144
        spatialManager.cancelModifies();
1145
        try {
1146
            checkInEditingMode();
1147 27334 jmvivo
1148 34112 jpiera
            boolean clearSelection = this.hasStrongChanges;
1149
            if (this.selection instanceof FeatureReferenceSelection) {
1150
                clearSelection = this.hasInserts;
1151
            }
1152
            notifyChange(FeatureStoreNotification.BEFORE_CANCELEDITING);
1153
            exitEditingMode();
1154
            if (clearSelection) {
1155
                ((FeatureSelection) this.getSelection()).deselectAll();
1156
            }
1157 36207 cordinyana
            updateIndexes();
1158 34112 jpiera
            notifyChange(FeatureStoreNotification.AFTER_CANCELEDITING);
1159
        } catch (Exception e) {
1160
            throw new StoreCancelEditingException(e, this.getName());
1161
        }
1162
    }
1163 23772 jjdelcerro
1164 34112 jpiera
    synchronized public void finishEditing() throws DataException {
1165 36359 cordinyana
        LOG.debug("finish editing of mode: {}", new Integer(mode));
1166 34112 jpiera
        try {
1167
            switch (mode) {
1168
            case MODE_QUERY:
1169
                throw new NeedEditingModeException(this.getName());
1170 24162 jjdelcerro
1171 34112 jpiera
            case MODE_APPEND:
1172
                notifyChange(FeatureStoreNotification.BEFORE_FINISHEDITING);
1173
                provider.endAppend();
1174
                exitEditingMode();
1175 36207 cordinyana
                updateIndexes();
1176 34112 jpiera
                notifyChange(FeatureStoreNotification.AFTER_FINISHEDITING);
1177
                break;
1178 24162 jjdelcerro
1179 34112 jpiera
            case MODE_FULLEDIT:
1180
                if (hasStrongChanges && !this.allowWrite()) {
1181
                    throw new WriteNotAllowedException(getName());
1182
                }
1183
                notifyChange(FeatureStoreNotification.BEFORE_FINISHEDITING);
1184
                if (hasStrongChanges) {
1185
                    validateFeatures(Feature.FINISH_EDITING);
1186
                    provider.performChanges(featureManager.getDeleted(),
1187 36207 cordinyana
                        featureManager.getInserted(),
1188
                        featureManager.getUpdated(),
1189
                        featureTypeManager.getFeatureTypesChanged());
1190 34112 jpiera
                }
1191
                exitEditingMode();
1192 36207 cordinyana
                updateIndexes();
1193 34112 jpiera
                notifyChange(FeatureStoreNotification.AFTER_FINISHEDITING);
1194
                break;
1195
            }
1196
        } catch (Exception e) {
1197
            throw new FinishEditingException(e);
1198
        }
1199
    }
1200 23772 jjdelcerro
1201 34112 jpiera
    public void beginEditingGroup(String description)
1202 34968 nfrancisco
        throws NeedEditingModeException {
1203 34112 jpiera
        checkInEditingMode();
1204
        commands.startComplex(description);
1205
    }
1206 24613 jjdelcerro
1207 34112 jpiera
    public void endEditingGroup() throws NeedEditingModeException {
1208
        checkInEditingMode();
1209
        commands.endComplex();
1210
    }
1211 24613 jjdelcerro
1212 34112 jpiera
    public boolean isAppendModeSupported() {
1213
        return this.provider.supportsAppendMode();
1214
    }
1215 24185 jjdelcerro
1216 34968 nfrancisco
    public void export(DataServerExplorer explorer, String provider,
1217
        NewFeatureStoreParameters params) throws DataException {
1218 24185 jjdelcerro
1219 34112 jpiera
        if (this.getFeatureTypes().size() != 1) {
1220
            throw new NotYetImplemented(
1221 34968 nfrancisco
                "export whith more than one type not yet implemented");
1222 34112 jpiera
        }
1223 34968 nfrancisco
        FeatureSelection featureSelection = (FeatureSelection) getSelection();
1224 34112 jpiera
        FeatureStore target = null;
1225
        FeatureSet features = null;
1226
        DisposableIterator iterator = null;
1227
        try {
1228
            FeatureType type = this.getDefaultFeatureType();
1229 34968 nfrancisco
            if ((params.getDefaultFeatureType() == null)
1230
                || (params.getDefaultFeatureType().size() == 0)) {
1231 34112 jpiera
                params.setDefaultFeatureType(type.getEditable());
1232 25977 jmvivo
1233 34112 jpiera
            }
1234
            explorer.add(provider, params, true);
1235 23772 jjdelcerro
1236 34112 jpiera
            DataManager manager = DALLocator.getDataManager();
1237
            target = (FeatureStore) manager.openStore(provider, params);
1238
            FeatureType targetType = target.getDefaultFeatureType();
1239 25977 jmvivo
1240 34112 jpiera
            target.edit(MODE_APPEND);
1241
            FeatureAttributeDescriptor[] pk = type.getPrimaryKey();
1242 34968 nfrancisco
            if (featureSelection.getSize() > 0) {
1243 34112 jpiera
                features = this.getFeatureSelection();
1244 34968 nfrancisco
            } else {
1245
                if ((pk != null) && (pk.length > 0)) {
1246 34112 jpiera
                    FeatureQuery query = createFeatureQuery();
1247
                    for (int i = 0; i < pk.length; i++) {
1248
                        query.getOrder().add(pk[i].getName(), true);
1249
                    }
1250
                    features = this.getFeatureSet(query);
1251
                } else {
1252
                    features = this.getFeatureSet();
1253
                }
1254
            }
1255 36190 cordinyana
            iterator = features.fastIterator();
1256 34112 jpiera
            while (iterator.hasNext()) {
1257
                DefaultFeature feature = (DefaultFeature) iterator.next();
1258
                target.insert(target.createNewFeature(targetType, feature));
1259
            }
1260
            target.finishEditing();
1261
            target.dispose();
1262
        } catch (Exception e) {
1263
            throw new DataExportException(e, params.toString());
1264
        } finally {
1265
            dispose(iterator);
1266
            dispose(features);
1267
            dispose(target);
1268
        }
1269
    }
1270 23772 jjdelcerro
1271 34112 jpiera
    //
1272
    // ====================================================================
1273
    // Obtencion de datos
1274
    // getDataCollection, getFeatureCollection
1275
    //
1276 23772 jjdelcerro
1277 34112 jpiera
    public DataSet getDataSet() throws DataException {
1278
        checkNotInAppendMode();
1279 34968 nfrancisco
        FeatureQuery query =
1280
            new DefaultFeatureQuery(this.getDefaultFeatureType());
1281 34112 jpiera
        return new DefaultFeatureSet(this, query);
1282
    }
1283 23772 jjdelcerro
1284 34968 nfrancisco
    public DataSet getDataSet(DataQuery dataQuery) throws DataException {
1285 34112 jpiera
        checkNotInAppendMode();
1286
        return new DefaultFeatureSet(this, (FeatureQuery) dataQuery);
1287
    }
1288 23772 jjdelcerro
1289 34112 jpiera
    public void getDataSet(Observer observer) throws DataException {
1290
        checkNotInAppendMode();
1291
        this.getFeatureSet(null, observer);
1292
    }
1293 23772 jjdelcerro
1294 34112 jpiera
    public void getDataSet(DataQuery dataQuery, Observer observer)
1295 34968 nfrancisco
        throws DataException {
1296 34112 jpiera
        checkNotInAppendMode();
1297
        this.getFeatureSet((FeatureQuery) dataQuery, observer);
1298
    }
1299 23772 jjdelcerro
1300 34112 jpiera
    public FeatureSet getFeatureSet() throws DataException {
1301
        checkNotInAppendMode();
1302 34968 nfrancisco
        FeatureQuery query =
1303
            new DefaultFeatureQuery(this.getDefaultFeatureType());
1304 34112 jpiera
        return new DefaultFeatureSet(this, query);
1305
    }
1306 23772 jjdelcerro
1307 34112 jpiera
    public FeatureSet getFeatureSet(FeatureQuery featureQuery)
1308 34968 nfrancisco
        throws DataException {
1309 34112 jpiera
        checkNotInAppendMode();
1310
        return new DefaultFeatureSet(this, featureQuery);
1311
    }
1312 23772 jjdelcerro
1313 34112 jpiera
    public void accept(Visitor visitor) throws BaseException {
1314
        FeatureSet set = getFeatureSet();
1315
        try {
1316
            set.accept(visitor);
1317
        } finally {
1318
            set.dispose();
1319
        }
1320
    }
1321 27700 jmvivo
1322 34112 jpiera
    public void accept(Visitor visitor, DataQuery dataQuery)
1323 34968 nfrancisco
        throws BaseException {
1324 34112 jpiera
        FeatureSet set = getFeatureSet((FeatureQuery) dataQuery);
1325
        try {
1326
            set.accept(visitor);
1327
        } finally {
1328
            set.dispose();
1329
        }
1330
    }
1331 31284 cordinyana
1332 34112 jpiera
    public FeatureType getFeatureType(FeatureQuery featureQuery)
1333 34968 nfrancisco
        throws DataException {
1334
        DefaultFeatureType fType =
1335
            (DefaultFeatureType) this.getFeatureType(featureQuery
1336
                .getFeatureTypeId());
1337 36207 cordinyana
        if ((featureQuery.getAttributeNames() != null)
1338
            && (featureQuery.getAttributeNames().length > 0)) {
1339 34112 jpiera
            return fType.getSubtype(featureQuery.getAttributeNames());
1340
        }
1341
        return fType;
1342
    }
1343 23820 jjdelcerro
1344 34968 nfrancisco
    public void getFeatureSet(Observer observer) throws DataException {
1345 34112 jpiera
        checkNotInAppendMode();
1346
        this.getFeatureSet(null, observer);
1347
    }
1348 23772 jjdelcerro
1349 34112 jpiera
    public void getFeatureSet(FeatureQuery query, Observer observer)
1350 34968 nfrancisco
        throws DataException {
1351 34112 jpiera
        class LoadInBackGround implements Runnable {
1352 34968 nfrancisco
1353 34112 jpiera
            private FeatureStore store;
1354
            private FeatureQuery query;
1355
            private Observer observer;
1356 23772 jjdelcerro
1357 34112 jpiera
            public LoadInBackGround(FeatureStore store, FeatureQuery query,
1358 34917 jjdelcerro
                Observer observer) {
1359 34112 jpiera
                this.store = store;
1360
                this.query = query;
1361
                this.observer = observer;
1362
            }
1363 23772 jjdelcerro
1364 34112 jpiera
            void notify(FeatureStoreNotification theNotification) {
1365 34917 jjdelcerro
                observer.update(store, theNotification);
1366
                return;
1367 34112 jpiera
            }
1368 25267 jjdelcerro
1369 34112 jpiera
            public void run() {
1370
                FeatureSet set = null;
1371
                try {
1372
                    set = store.getFeatureSet(query);
1373
                    notify(new DefaultFeatureStoreNotification(store,
1374
                        FeatureStoreNotification.LOAD_FINISHED, set));
1375
                } catch (Exception e) {
1376
                    notify(new DefaultFeatureStoreNotification(store,
1377
                        FeatureStoreNotification.LOAD_FINISHED, e));
1378
                } finally {
1379
                    dispose(set);
1380
                }
1381
            }
1382
        }
1383 23772 jjdelcerro
1384 34112 jpiera
        checkNotInAppendMode();
1385
        if (query == null) {
1386
            query = new DefaultFeatureQuery(this.getDefaultFeatureType());
1387
        }
1388 34917 jjdelcerro
        LoadInBackGround task = new LoadInBackGround(this, query, observer);
1389 36207 cordinyana
        Thread thread = new Thread(task, "Load Feature Set in background");
1390
        thread.start();
1391 34112 jpiera
    }
1392 23772 jjdelcerro
1393 34968 nfrancisco
    public Feature getFeatureByReference(FeatureReference reference)
1394
        throws DataException {
1395 34112 jpiera
        checkNotInAppendMode();
1396
        DefaultFeatureReference ref = (DefaultFeatureReference) reference;
1397
        FeatureType featureType;
1398
        if (ref.getFeatureTypeId() == null) {
1399
            featureType = this.getDefaultFeatureType();
1400
        } else {
1401
            featureType = this.getFeatureType(ref.getFeatureTypeId());
1402
        }
1403
        return this.getFeatureByReference(reference, featureType);
1404
    }
1405 23772 jjdelcerro
1406 34968 nfrancisco
    public Feature getFeatureByReference(FeatureReference reference,
1407
        FeatureType featureType) throws DataException {
1408 34112 jpiera
        checkNotInAppendMode();
1409
        featureType = fixFeatureType((DefaultFeatureType) featureType);
1410
        if (!this.transforms.isEmpty()) {
1411 25843 jmvivo
1412 34968 nfrancisco
            featureType = this.transforms.getSourceFeatureTypeFrom(featureType);
1413 25843 jmvivo
1414 34112 jpiera
        }
1415
        // TODO comprobar que el id es de este store
1416 23820 jjdelcerro
1417 34112 jpiera
        if (this.mode == MODE_FULLEDIT) {
1418
            Feature f = featureManager.get(reference, this, featureType);
1419 34968 nfrancisco
            if (f != null) {
1420 34112 jpiera
                return f;
1421
            }
1422
        }
1423 38241 jldominguez
1424
1425 34968 nfrancisco
        DefaultFeature feature =
1426 36207 cordinyana
            new DefaultFeature(this,
1427
                this.provider.getFeatureProviderByReference(
1428 34968 nfrancisco
                    (FeatureReferenceProviderServices) reference, featureType));
1429 25843 jmvivo
1430 34112 jpiera
        if (!this.transforms.isEmpty()) {
1431
            return this.transforms.applyTransform(feature, featureType);
1432
        }
1433
        return feature;
1434
    }
1435 23772 jjdelcerro
1436 34112 jpiera
    //
1437
    // ====================================================================
1438
    // Gestion de features
1439
    //
1440 23772 jjdelcerro
1441 34112 jpiera
    private FeatureType fixFeatureType(DefaultFeatureType type)
1442 34968 nfrancisco
        throws DataException {
1443 34112 jpiera
        FeatureType original = this.getDefaultFeatureType();
1444 27672 jmvivo
1445 34968 nfrancisco
        if ((type == null) || type.equals(original)) {
1446 34112 jpiera
            return original;
1447
        } else {
1448
            if (!type.isSubtypeOf(original)) {
1449
                Iterator iter = this.getFeatureTypes().iterator();
1450
                FeatureType tmpType;
1451
                boolean found = false;
1452
                while (iter.hasNext()) {
1453
                    tmpType = (FeatureType) iter.next();
1454
                    if (type.equals(tmpType)) {
1455
                        return type;
1456 27672 jmvivo
1457 34968 nfrancisco
                    } else
1458
                        if (type.isSubtypeOf(tmpType)) {
1459
                            found = true;
1460
                            original = tmpType;
1461
                            break;
1462
                        }
1463 27672 jmvivo
1464 34112 jpiera
                }
1465
                if (!found) {
1466
                    throw new IllegalFeatureTypeException(getName());
1467
                }
1468
            }
1469
        }
1470 27672 jmvivo
1471 34112 jpiera
        // Checks that type has all fields of pk
1472
        // else add the missing attributes at the end.
1473
        if (!original.hasOID()) {
1474
            // Gets original pk attributes
1475 34968 nfrancisco
            DefaultEditableFeatureType edOriginal =
1476
                (DefaultEditableFeatureType) original.getEditable();
1477 34112 jpiera
            FeatureAttributeDescriptor orgAttr;
1478
            Iterator edOriginalIter = edOriginal.iterator();
1479
            while (edOriginalIter.hasNext()) {
1480
                orgAttr = (FeatureAttributeDescriptor) edOriginalIter.next();
1481
                if (!orgAttr.isPrimaryKey()) {
1482
                    edOriginalIter.remove();
1483
                }
1484
            }
1485 23772 jjdelcerro
1486 34112 jpiera
            // Checks if all pk attributes are in type
1487
            Iterator typeIterator;
1488
            edOriginalIter = edOriginal.iterator();
1489
            FeatureAttributeDescriptor attr;
1490
            while (edOriginalIter.hasNext()) {
1491
                orgAttr = (FeatureAttributeDescriptor) edOriginalIter.next();
1492
                typeIterator = type.iterator();
1493
                while (typeIterator.hasNext()) {
1494
                    attr = (FeatureAttributeDescriptor) typeIterator.next();
1495
                    if (attr.getName().equals(orgAttr.getName())) {
1496
                        edOriginalIter.remove();
1497
                        break;
1498
                    }
1499
                }
1500
            }
1501 27672 jmvivo
1502 34112 jpiera
            // add missing pk attributes if any
1503
            if (edOriginal.size() > 0) {
1504
                boolean isEditable = type instanceof DefaultEditableFeatureType;
1505 34968 nfrancisco
                DefaultEditableFeatureType edType =
1506
                    (DefaultEditableFeatureType) original.getEditable();
1507 34112 jpiera
                edType.clear();
1508
                edType.addAll(type);
1509
                edType.addAll(edOriginal);
1510
                if (!isEditable) {
1511
                    type = (DefaultFeatureType) edType.getNotEditableCopy();
1512
                }
1513
            }
1514 27672 jmvivo
1515 34112 jpiera
        }
1516 27672 jmvivo
1517 34112 jpiera
        return type;
1518
    }
1519 23772 jjdelcerro
1520 34112 jpiera
    public void validateFeatures(int mode) throws DataException {
1521
        FeatureSet collection = null;
1522
        DisposableIterator iter = null;
1523
        try {
1524
            checkNotInAppendMode();
1525
            collection = this.getFeatureSet();
1526 36190 cordinyana
            iter = collection.fastIterator();
1527 34112 jpiera
            long previousVersionOfUpdate = currentVersionOfUpdate();
1528
            while (iter.hasNext()) {
1529
                ((DefaultFeature) iter.next()).validate(mode);
1530
                if (previousVersionOfUpdate != currentVersionOfUpdate()) {
1531
                    throw new ConcurrentDataModificationException(getName());
1532
                }
1533
            }
1534
        } catch (Exception e) {
1535
            throw new ValidateFeaturesException(e, getName());
1536
        } finally {
1537
            dispose(iter);
1538
            dispose(collection);
1539
        }
1540
    }
1541 23772 jjdelcerro
1542 34112 jpiera
    public FeatureType getDefaultFeatureType() throws DataException {
1543
        try {
1544
            if (isEditing()) {
1545 34968 nfrancisco
                FeatureType auxFeatureType =
1546
                    featureTypeManager.getType(defaultFeatureType.getId());
1547
                if (auxFeatureType != null) {
1548 34112 jpiera
                    return auxFeatureType;
1549
                }
1550
            }
1551
            FeatureType type = this.transforms.getDefaultFeatureType();
1552
            if (type != null) {
1553
                return type;
1554
            }
1555
            return defaultFeatureType;
1556
        } catch (Exception e) {
1557
            throw new GetFeatureTypeException(e, getName());
1558
        }
1559
    }
1560 23772 jjdelcerro
1561 34112 jpiera
    public FeatureType getFeatureType(String featureTypeId)
1562 34968 nfrancisco
        throws DataException {
1563 34112 jpiera
        if (featureTypeId == null) {
1564
            return this.getDefaultFeatureType();
1565
        }
1566
        try {
1567
            if (isEditing()) {
1568 34968 nfrancisco
                FeatureType auxFeatureType =
1569
                    featureTypeManager.getType(featureTypeId);
1570 34112 jpiera
                if (auxFeatureType != null) {
1571
                    return auxFeatureType;
1572
                }
1573
            }
1574
            FeatureType type = this.transforms.getFeatureType(featureTypeId);
1575
            if (type != null) {
1576
                return type;
1577
            }
1578
            Iterator iter = this.featureTypes.iterator();
1579 34968 nfrancisco
            while (iter.hasNext()) {
1580 34112 jpiera
                type = (FeatureType) iter.next();
1581
                if (type.getId().equals(featureTypeId)) {
1582
                    return type;
1583
                }
1584
            }
1585
            return null;
1586
        } catch (Exception e) {
1587
            throw new GetFeatureTypeException(e, getName());
1588
        }
1589
    }
1590 27234 jmvivo
1591 34112 jpiera
    public FeatureType getProviderDefaultFeatureType() {
1592
        return defaultFeatureType;
1593
    }
1594 25917 jmvivo
1595 34112 jpiera
    public List getFeatureTypes() throws DataException {
1596
        try {
1597
            List types;
1598
            if (isEditing()) {
1599 34968 nfrancisco
                types = new ArrayList();
1600
                Iterator it = featureTypes.iterator();
1601 34112 jpiera
                while (it.hasNext()) {
1602
                    FeatureType type = (FeatureType) it.next();
1603 34968 nfrancisco
                    FeatureType typeaux =
1604
                        featureTypeManager.getType(type.getId());
1605
                    if (typeaux != null) {
1606 34112 jpiera
                        types.add(typeaux);
1607 34968 nfrancisco
                    } else {
1608 34112 jpiera
                        types.add(type);
1609
                    }
1610
                }
1611
                it = featureTypeManager.newsIterator();
1612
                while (it.hasNext()) {
1613
                    FeatureType type = (FeatureType) it.next();
1614
                    types.add(type);
1615
                }
1616
            } else {
1617
                types = this.transforms.getFeatureTypes();
1618
                if (types == null) {
1619
                    types = featureTypes;
1620
                }
1621
            }
1622
            return Collections.unmodifiableList(types);
1623
        } catch (Exception e) {
1624
            throw new GetFeatureTypeException(e, getName());
1625
        }
1626
    }
1627 23772 jjdelcerro
1628 34112 jpiera
    public List getProviderFeatureTypes() throws DataException {
1629
        return Collections.unmodifiableList(this.featureTypes);
1630
    }
1631 25917 jmvivo
1632 34968 nfrancisco
    public Feature createFeature(FeatureProvider data) throws DataException {
1633 34112 jpiera
        DefaultFeature feature = new DefaultFeature(this, data);
1634
        return feature;
1635
    }
1636 23772 jjdelcerro
1637 34112 jpiera
    public Feature createFeature(FeatureProvider data, FeatureType type)
1638 34968 nfrancisco
        throws DataException {
1639 34112 jpiera
        // FIXME: falta por implementar
1640
        // Comprobar si es un subtipo del feature de data
1641
        // y construir un feature usando el subtipo.
1642
        // Probablemente requiera generar una copia del data.
1643
        throw new NotYetImplemented();
1644
    }
1645 23879 jjdelcerro
1646 34112 jpiera
    public EditableFeature createNewFeature(FeatureType type,
1647 34968 nfrancisco
        Feature defaultValues) throws DataException {
1648 34112 jpiera
        try {
1649
            FeatureProvider data = createNewFeatureProvider(type);
1650 34968 nfrancisco
            DefaultEditableFeature feature =
1651
                new DefaultEditableFeature(this, data);
1652 34112 jpiera
            feature.initializeValues(defaultValues);
1653 38241 jldominguez
            data.setNew(true);
1654
1655 34112 jpiera
            return feature;
1656
        } catch (Exception e) {
1657
            throw new CreateFeatureException(e, getName());
1658
        }
1659
    }
1660 23772 jjdelcerro
1661 34112 jpiera
    private FeatureProvider createNewFeatureProvider(FeatureType type)
1662 34968 nfrancisco
        throws DataException {
1663 34112 jpiera
        type = this.fixFeatureType((DefaultFeatureType) type);
1664
        FeatureProvider data = this.provider.createFeatureProvider(type);
1665
        data.setNew(true);
1666 34968 nfrancisco
        if (type.hasOID() && (data.getOID() == null)) {
1667 34112 jpiera
            data.setOID(this.provider.createNewOID());
1668
        } else {
1669
            data.setOID(this.getTemporalOID());
1670
        }
1671
        return data;
1672 28662 jmvivo
1673 34112 jpiera
    }
1674 28662 jmvivo
1675 34112 jpiera
    public EditableFeature createNewFeature(FeatureType type,
1676 34968 nfrancisco
        boolean defaultValues) throws DataException {
1677 34112 jpiera
        try {
1678
            FeatureProvider data = createNewFeatureProvider(type);
1679 34968 nfrancisco
            DefaultEditableFeature feature =
1680
                new DefaultEditableFeature(this, data);
1681 34112 jpiera
            if (defaultValues) {
1682
                feature.initializeValues();
1683
            }
1684
            return feature;
1685
        } catch (Exception e) {
1686
            throw new CreateFeatureException(e, getName());
1687
        }
1688
    }
1689 23772 jjdelcerro
1690 34112 jpiera
    public EditableFeature createNewFeature(boolean defaultValues)
1691 34968 nfrancisco
        throws DataException {
1692
        return this.createNewFeature(this.getDefaultFeatureType(),
1693
            defaultValues);
1694 34112 jpiera
    }
1695 23772 jjdelcerro
1696 34112 jpiera
    public EditableFeature createNewFeature() throws DataException {
1697
        return this.createNewFeature(this.getDefaultFeatureType(), true);
1698
    }
1699 23772 jjdelcerro
1700 34112 jpiera
    public EditableFeatureType createFeatureType() {
1701
        DefaultEditableFeatureType ftype = new DefaultEditableFeatureType();
1702
        return ftype;
1703
    }
1704 23772 jjdelcerro
1705 34112 jpiera
    public EditableFeatureType createFeatureType(String id) {
1706
        DefaultEditableFeatureType ftype = new DefaultEditableFeatureType(id);
1707
        return ftype;
1708
    }
1709 27262 jmvivo
1710 34112 jpiera
    //
1711
    // ====================================================================
1712
    // Index related methods
1713
    //
1714 23879 jjdelcerro
1715 34112 jpiera
    public FeatureIndexes getIndexes() {
1716
        return this.indexes;
1717
    }
1718 23894 jjdelcerro
1719 34112 jpiera
    public FeatureIndex createIndex(FeatureType featureType,
1720 34968 nfrancisco
        String attributeName, String indexName) throws DataException {
1721
        return createIndex(null, featureType, attributeName, indexName);
1722
    }
1723
1724
    public FeatureIndex createIndex(String indexTypeName,
1725
        FeatureType featureType, String attributeName, String indexName)
1726
        throws DataException {
1727 36207 cordinyana
1728
        return createIndex(indexTypeName, featureType, attributeName,
1729
            indexName, false, null);
1730
    }
1731
1732
    public FeatureIndex createIndex(FeatureType featureType,
1733
        String attributeName, String indexName, Observer observer)
1734
        throws DataException {
1735
        return createIndex(null, featureType, attributeName, indexName,
1736
            observer);
1737
    }
1738
1739
    public FeatureIndex createIndex(String indexTypeName,
1740
        FeatureType featureType, String attributeName, String indexName,
1741
        final Observer observer) throws DataException {
1742
1743
        return createIndex(indexTypeName, featureType, attributeName,
1744
            indexName, true, observer);
1745
    }
1746
1747
    private FeatureIndex createIndex(String indexTypeName,
1748
        FeatureType featureType, String attributeName, String indexName,
1749
        boolean background, final Observer observer) throws DataException {
1750
1751 34112 jpiera
        checkNotInAppendMode();
1752
        FeatureIndexProviderServices index = null;
1753 34968 nfrancisco
        index =
1754
            dataManager.createFeatureIndexProvider(indexTypeName, this,
1755 36207 cordinyana
                featureType, indexName,
1756
                featureType.getAttributeDescriptor(attributeName));
1757
1758 34112 jpiera
        try {
1759 36235 cordinyana
            index.fill(background, observer);
1760 34112 jpiera
        } catch (FeatureIndexException e) {
1761
            throw new InitializeException(index.getName(), e);
1762
        }
1763 36207 cordinyana
1764 34112 jpiera
        ((DefaultFeatureIndexes) getIndexes()).addIndex(index);
1765
        return index;
1766
    }
1767 25276 jmvivo
1768 34112 jpiera
    //
1769
    // ====================================================================
1770
    // Transforms related methods
1771
    //
1772 24613 jjdelcerro
1773 34112 jpiera
    public FeatureStoreTransforms getTransforms() {
1774
        return this.transforms;
1775
    }
1776 25176 jmvivo
1777 34112 jpiera
    public FeatureQuery createFeatureQuery() {
1778
        return new DefaultFeatureQuery();
1779
    }
1780 24690 vcaballero
1781 34112 jpiera
    public DataQuery createQuery() {
1782
        return createFeatureQuery();
1783
    }
1784 27575 jmvivo
1785 34112 jpiera
    //
1786
    // ====================================================================
1787
    // UndoRedo related methods
1788
    //
1789 25785 jmvivo
1790 34112 jpiera
    public boolean canRedo() {
1791
        return commands.canRedo();
1792
    }
1793 24961 cordinyana
1794 34112 jpiera
    public boolean canUndo() {
1795
        return commands.canUndo();
1796
    }
1797 24961 cordinyana
1798 34112 jpiera
    public void redo(int num) throws RedoException {
1799 37595 jpiera
        for (int i = 0; i < num; i++) {
1800
            redo();
1801
        }
1802 34112 jpiera
    }
1803 24961 cordinyana
1804 34112 jpiera
    public void undo(int num) throws UndoException {
1805 37595 jpiera
        for (int i = 0; i < num; i++) {
1806
            undo();
1807
        }
1808 34112 jpiera
    }
1809 25785 jmvivo
1810 34112 jpiera
    //
1811
    // ====================================================================
1812
    // Metadata related methods
1813
    //
1814 25785 jmvivo
1815 34112 jpiera
    public Object getMetadataID() {
1816
        return this.provider.getSourceId();
1817
    }
1818 25785 jmvivo
1819 34112 jpiera
    public void delegate(DynObject dynObject) {
1820
        this.metadata.delegate(dynObject);
1821
    }
1822 25785 jmvivo
1823 34112 jpiera
    public DynClass getDynClass() {
1824
        return this.metadata.getDynClass();
1825
    }
1826 25785 jmvivo
1827 37496 jjdelcerro
        public Object getDynValue(String name) throws DynFieldNotFoundException {
1828
                if( this.transforms.hasDynValue(name) ) {
1829
                        return this.transforms.getDynValue(name);
1830
                }
1831
                if (this.metadata.hasDynValue(name)) {
1832
                        return this.metadata.getDynValue(name);
1833
                }
1834
                if (METADATA_PROVIDER.equalsIgnoreCase(name)) {
1835
                        return this.provider.getProviderName();
1836
                } else if (METADATA_CONTAINERNAME.equalsIgnoreCase(name)) {
1837
                        return this.provider.getSourceId();
1838
                } else if (METADATA_FEATURETYPE.equalsIgnoreCase(name)) {
1839
                        try {
1840
                                return this.getDefaultFeatureType();
1841
                        } catch (DataException e) {
1842
                                return null;
1843
                        }
1844
                }
1845
                return this.metadata.getDynValue(name);
1846
        }
1847 25785 jmvivo
1848 34112 jpiera
    public boolean hasDynValue(String name) {
1849 37496 jjdelcerro
                if( this.transforms.hasDynValue(name) ) {
1850
                        return true;
1851
                }
1852 34112 jpiera
        return this.metadata.hasDynValue(name);
1853
    }
1854 25785 jmvivo
1855 34112 jpiera
    public void implement(DynClass dynClass) {
1856
        this.metadata.implement(dynClass);
1857
    }
1858 25785 jmvivo
1859 34112 jpiera
    public Object invokeDynMethod(String name, DynObject context)
1860 34968 nfrancisco
        throws DynMethodException {
1861 34112 jpiera
        return this.metadata.invokeDynMethod(this, name, context);
1862
    }
1863 25785 jmvivo
1864 34112 jpiera
    public Object invokeDynMethod(int code, DynObject context)
1865 34968 nfrancisco
        throws DynMethodException {
1866 34112 jpiera
        return this.metadata.invokeDynMethod(this, code, context);
1867
    }
1868 25785 jmvivo
1869 34112 jpiera
    public void setDynValue(String name, Object value)
1870 34968 nfrancisco
        throws DynFieldNotFoundException {
1871 37496 jjdelcerro
                if( this.transforms.hasDynValue(name) ) {
1872
                        this.transforms.setDynValue(name, value);
1873
                        return;
1874
                }
1875 34112 jpiera
        this.metadata.setDynValue(name, value);
1876 25785 jmvivo
1877 34112 jpiera
    }
1878 25785 jmvivo
1879 34112 jpiera
    /*
1880
     * (non-Javadoc)
1881 34968 nfrancisco
     *
1882 34112 jpiera
     * @see org.gvsig.metadata.Metadata#getMetadataChildren()
1883
     */
1884
    public Set getMetadataChildren() {
1885
        return this.metadataChildren;
1886
    }
1887 25785 jmvivo
1888 34112 jpiera
    /*
1889
     * (non-Javadoc)
1890 34968 nfrancisco
     *
1891 34112 jpiera
     * @see org.gvsig.metadata.Metadata#getMetadataName()
1892
     */
1893
    public String getMetadataName() {
1894
        return this.provider.getProviderName();
1895
    }
1896 25785 jmvivo
1897 34112 jpiera
    public FeatureTypeManager getFeatureTypeManager() {
1898
        return this.featureTypeManager;
1899
    }
1900 26252 jmvivo
1901 34112 jpiera
    public long getFeatureCount() throws DataException {
1902
        if (featureCount == null) {
1903
            featureCount = new Long(this.provider.getFeatureCount());
1904
        }
1905
        if (this.isEditing() && !this.isAppending()) {
1906
            return featureCount.longValue()
1907 34968 nfrancisco
                - this.featureManager.getDeltaSize();
1908 34112 jpiera
        }
1909
        return featureCount.longValue();
1910
    }
1911 27262 jmvivo
1912 34112 jpiera
    private Long getTemporalOID() {
1913
        return new Long(this.temporalOid++);
1914
    }
1915 28017 jmvivo
1916 34112 jpiera
    public FeatureType getProviderFeatureType(String featureTypeId) {
1917
        if (featureTypeId == null) {
1918
            return this.defaultFeatureType;
1919
        }
1920
        FeatureType type;
1921
        Iterator iter = this.featureTypes.iterator();
1922
        while (iter.hasNext()) {
1923
            type = (FeatureType) iter.next();
1924
            if (type.getId().equals(featureTypeId)) {
1925
                return type;
1926
            }
1927
        }
1928
        return null;
1929
    }
1930 28423 jmvivo
1931 34112 jpiera
    public FeatureProvider getFeatureProviderFromFeature(Feature feature) {
1932
        return ((DefaultFeature) feature).getData();
1933
    }
1934 28671 jmvivo
1935 34112 jpiera
    public DataStore getStore() {
1936
        return this;
1937
    }
1938 29020 jmvivo
1939 34112 jpiera
    public FeatureStore getFeatureStore() {
1940
        return this;
1941
    }
1942 29326 jmvivo
1943 34112 jpiera
    public void createCache(String name, DynObject parameters)
1944 34968 nfrancisco
        throws DataException {
1945 34112 jpiera
        cache = dataManager.createFeatureCacheProvider(name, parameters);
1946 34968 nfrancisco
        if (cache == null) {
1947 34112 jpiera
            throw new CreateException("FeaureCacheProvider", null);
1948
        }
1949
        cache.apply(this, provider);
1950
        provider = cache;
1951 30208 jmvivo
1952 34112 jpiera
        featureCount = null;
1953
    }
1954 31541 jpiera
1955 34112 jpiera
    public FeatureCache getCache() {
1956
        return cache;
1957
    }
1958 31699 cordinyana
1959 34112 jpiera
    public void clear() {
1960
        if (metadata != null) {
1961
            metadata.clear();
1962
        }
1963
    }
1964 32735 vcaballero
1965 34112 jpiera
    public String getName() {
1966
        return this.provider.getName();
1967
    }
1968 33717 jjdelcerro
1969 34112 jpiera
    public String getFullName() {
1970
        return this.provider.getFullName();
1971
    }
1972 33717 jjdelcerro
1973 34112 jpiera
    public String getProviderName() {
1974
        return this.provider.getProviderName();
1975
    }
1976
1977
    public boolean isKnownEnvelope() {
1978
        return this.provider.isKnownEnvelope();
1979
    }
1980
1981
    public boolean hasRetrievedFeaturesLimit() {
1982
        return this.provider.hasRetrievedFeaturesLimit();
1983
    }
1984
1985
    public int getRetrievedFeaturesLimit() {
1986
        return this.provider.getRetrievedFeaturesLimit();
1987
    }
1988 37297 jpiera
1989
    public Interval getInterval() {
1990
        return this.provider.getInterval();
1991
    }
1992
1993
    public Collection getTimes() {
1994
        return this.provider.getTimes();
1995
    }
1996
1997
    public Collection getTimes(Interval interval) {
1998
        return this.provider.getTimes(interval);
1999
    }
2000
}