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 / store / memory / MemoryStoreProvider.java @ 44541

History | View | Annotate | Download (11.1 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
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 3
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
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24

    
25
package org.gvsig.fmap.dal.store.memory;
26

    
27
import java.util.ArrayList;
28
import java.util.Hashtable;
29
import java.util.Iterator;
30
import java.util.List;
31
import java.util.Map;
32

    
33
import org.slf4j.Logger;
34
import org.slf4j.LoggerFactory;
35
import org.gvsig.fmap.dal.DataStore;
36
import org.gvsig.fmap.dal.DataTypes;
37
import org.gvsig.fmap.dal.exception.DataException;
38
import org.gvsig.fmap.dal.exception.InitializeException;
39
import org.gvsig.fmap.dal.exception.OpenException;
40
import org.gvsig.fmap.dal.feature.Feature;
41
import org.gvsig.fmap.dal.feature.FeatureSet;
42
import org.gvsig.fmap.dal.feature.FeatureType;
43
import org.gvsig.fmap.dal.feature.exception.PerformEditingException;
44
import org.gvsig.fmap.dal.feature.spi.DefaultFeatureProvider;
45
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
46
import org.gvsig.fmap.dal.feature.spi.FeatureReferenceProviderServices;
47
import org.gvsig.fmap.dal.feature.spi.FeatureStoreProviderServices;
48
import org.gvsig.fmap.dal.feature.spi.memory.AbstractMemoryStoreProvider;
49
import org.gvsig.fmap.dal.feature.spi.memory.MemoryResource;
50
import org.gvsig.fmap.dal.resource.spi.ResourceProvider;
51
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
52
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
53
import org.gvsig.fmap.geom.primitive.Envelope;
54
import org.gvsig.metadata.MetadataLocator;
55
import org.gvsig.metadata.MetadataManager;
56
import org.gvsig.metadata.exceptions.MetadataException;
57
import org.gvsig.tools.ToolsLocator;
58
import org.gvsig.tools.dispose.DisposableIterator;
59
import org.gvsig.tools.dynobject.DynObject;
60
import org.gvsig.tools.dynobject.DynStruct;
61
import org.gvsig.tools.exception.BaseException;
62
import org.gvsig.tools.visitor.VisitCanceledException;
63
import org.gvsig.tools.visitor.Visitor;
64

    
65
/**
66
 * @author <a href="mailto:jpiera@gvsig.org">Jorge Piera</a>
67
 * 
68
 *         TODO: take into account the parameter "autoOrderAttributeName" to
69
 *         order the {@link Feature}s by default by that attribute, in ascending
70
 *         order.
71
 */
72
public class MemoryStoreProvider extends AbstractMemoryStoreProvider {
73

    
74
    private static final Logger logger = LoggerFactory
75
        .getLogger(MemoryStoreProvider.class);
76

    
77
    public static final String NAME = "Memory";
78
    public static final String DESCRIPTION = "Memory provider";
79

    
80
    public static final String METADATA_DEFINITION_NAME = "MemoryProvider";
81

    
82
    private long counterNewsOIDs = 0;
83
    private Envelope envelope = null;
84
    private Map oids = null;
85

    
86
    private Double sourceID = null;
87

    
88
    private ResourceProvider memoryResource;
89

    
90
    public static DynObject newMetadataContainer(String name) {
91
        return ToolsLocator.getDynObjectManager().createDynObject(
92
            MetadataLocator.getMetadataManager().getDefinition(name));
93
    }
94

    
95
    public MemoryStoreProvider(MemoryStoreParameters memoryStoreParameters,
96
        DataStoreProviderServices storeServices) throws InitializeException {
97
        super(memoryStoreParameters, storeServices,
98
            newMetadataContainer(METADATA_DEFINITION_NAME));
99
        sourceID = new Double(Math.random());
100
        data = new ArrayList();
101
        oids = new Hashtable();
102
        initialize();
103
        memoryResource =
104
            createResource(MemoryResource.NAME,
105
                new Object[] { memoryStoreParameters.getName() });
106
    }
107

    
108
    @Override
109
    public boolean isTemporary() {
110
        try {
111
            return (boolean) this.getParameters().getDynValue(MemoryStoreParameters.ISTEMPORARY_NAME);
112
        } catch(Throwable th) {
113
            return false;
114
        }
115
    }
116

    
117
    
118
    @Override
119
    public FeatureProvider createFeatureProvider(FeatureType featureType)throws DataException  {
120
            this.open();
121
            return new MemoryFeatureProvider(featureType, this.createNewOID());
122
    }
123

    
124
    public String getName() {
125
        return "Memory_" + Integer.toHexString((int) (Math.random()*100000)).toUpperCase();
126
    }
127

    
128
    public String getFullName() {
129
        return "memory:" + Double.toHexString(this.sourceID.doubleValue());
130
    }
131

    
132
    private void initialize() {
133
        FeatureType featureType =
134
            getStoreServices().createFeatureType(getName()).getNotEditableCopy();
135
        List types = new ArrayList(1);
136
        types.add(featureType);
137
        getStoreServices().setFeatureTypes(types, featureType);
138
    }
139

    
140
    /*
141
     * (non-Javadoc)
142
     * 
143
     * @see org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider#createNewOID()
144
     */
145
    public Object createNewOID() {
146
        return new Long(counterNewsOIDs++);
147
    }
148

    
149
    /*
150
     * (non-Javadoc)
151
     * 
152
     * @see org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider#getName()
153
     */
154
    public String getProviderName() {
155
        return NAME;
156
    }
157

    
158
    /*
159
     * (non-Javadoc)
160
     * 
161
     * @see org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider#getOIDType()
162
     */
163
    public int getOIDType() {
164
        return DataTypes.LONG;
165
    }
166

    
167
    /*
168
     * (non-Javadoc)
169
     * 
170
     * @see org.gvsig.fmap.dal.spi.DataStoreProvider#getSourceId()
171
     */
172
    public Object getSourceId() {
173
        return sourceID;
174
    }
175

    
176
    public void open() throws OpenException {
177
    }
178

    
179
    public static void registerMetadataDefinition() throws MetadataException {
180
        MetadataManager manager = MetadataLocator.getMetadataManager();
181
        if (manager.getDefinition(METADATA_DEFINITION_NAME) == null) {
182
            DynStruct metadataDefinition =
183
                manager.addDefinition(METADATA_DEFINITION_NAME, "Memory Store");
184
            metadataDefinition.extend(manager
185
                .getDefinition(DataStore.SPATIAL_METADATA_DEFINITION_NAME));
186
        }
187
    }
188

    
189
    public boolean allowWrite() {
190
        return true;
191
    }
192

    
193
    public void performChanges(Iterator deleteds, Iterator inserteds,
194
        Iterator updateds, Iterator originalFeatureTypesUpdated)
195
        throws PerformEditingException {
196
        FeatureSet set = null;
197
        DisposableIterator iter = null;
198
        try {
199
            FeatureType featureType =
200
                this.getStoreServices().getDefaultFeatureType();
201
            List types = new ArrayList(1);
202
            types.add(featureType);
203
            getStoreServices().setFeatureTypes(types, featureType);
204

    
205
            set = this.getFeatureStore().getFeatureSet();
206

    
207
            // Create a visitor to generate new data
208
            EditionVisitor visitor = new EditionVisitor(set.getSize());
209

    
210
            // collect new data
211
            set.accept(visitor);
212

    
213
            // update data objects
214
            data = visitor.getData();
215
            oids = visitor.getOids();
216
            envelope = visitor.getEnvelope();
217

    
218
        } catch (DataException e) {
219
            logger.error("Error adding features", e);
220
        } catch (BaseException e) {
221
            logger.error("Error performing edition", e);
222
        } finally {
223
            dispose(iter);
224
            dispose(set);
225
        }
226
    }
227

    
228
    public Envelope getEnvelope() throws DataException {
229
        return envelope;
230
    }
231

    
232
    protected FeatureProvider internalGetFeatureProviderByReference(
233
        FeatureReferenceProviderServices reference) throws DataException {
234
        return (FeatureProvider) oids.get(reference.getOID());
235
    }
236

    
237
    public ResourceProvider getResource() {
238
        return memoryResource;
239
    }
240

    
241
    public boolean supportsAppendMode() {
242
        return true;
243
    }
244

    
245
    public void append(FeatureProvider featureProvider) throws DataException {
246
        FeatureProvider newFeatureProvider = featureProvider.getCopy();
247
        if (data.isEmpty()) {
248
            try {
249
                envelope =
250
                    (Envelope) newFeatureProvider.getDefaultEnvelope().clone();
251
            } catch (CloneNotSupportedException e) {
252
                envelope = newFeatureProvider.getDefaultEnvelope();
253
            }
254
        } else {
255
            envelope.add(newFeatureProvider.getDefaultEnvelope());
256
        }
257

    
258
        newFeatureProvider.setNew(false);
259
        data.add(newFeatureProvider);
260
        oids.put(newFeatureProvider.getOID(), newFeatureProvider);
261
        logger.debug("Envelope after adding feature: ", envelope.toString());
262
    }
263

    
264
    public void beginAppend() throws DataException {
265
        // Nothing to do
266
    }
267

    
268
    public void endAppend() throws DataException {
269
        // Nothing to do
270
    }
271

    
272
    /**
273
     * Visitor to create new data objects from finish edition operation
274
     * 
275
     * @author jmvivo ( jmvivo at disid dot com)
276
     * 
277
     */
278
    private class EditionVisitor implements Visitor {
279

    
280
        private List data;
281
        private Map oids;
282
        private Envelope envelope;
283
        private FeatureStoreProviderServices services;
284

    
285
        /**
286
         * @param size
287
         *            to use to initialize data structures
288
         * @throws CreateEnvelopeException
289
         */
290
        public EditionVisitor(long size) {
291
            data = new ArrayList((int) size);
292
            oids = new Hashtable((int) size);
293
            envelope = null;
294
            services = MemoryStoreProvider.this.getStoreServices();
295
        }
296

    
297
        public void visit(Object obj) throws VisitCanceledException,
298
            BaseException {
299
            Feature feature = (Feature) obj;
300
            FeatureProvider featureProvider =
301
                services.getFeatureProviderFromFeature(feature);
302
            featureProvider.setNew(false);
303
            data.add(featureProvider);
304
            oids.put(featureProvider.getOID(), featureProvider);
305
            if (envelope == null) {
306
                try {
307
                    envelope = (Envelope) feature.getDefaultEnvelope().clone();
308
                } catch (CloneNotSupportedException e) {
309
                    envelope = feature.getDefaultEnvelope();
310
                }
311
            } else {
312
                envelope.add(feature.getDefaultEnvelope());
313
            }
314
            Envelope aux = feature.getDefaultEnvelope();
315
            if (aux != null) { //There are geometries
316
                    if (envelope == null) {
317
                            try {
318
                                    envelope = (Envelope) aux.clone();
319
                            } catch (CloneNotSupportedException e) {
320
                                    envelope = feature.getDefaultEnvelope();
321
                            }
322
                    } else {
323
                            envelope.add(feature.getDefaultEnvelope());
324
                    }
325
            }
326
        }
327

    
328
        public List getData() {
329
            return data;
330
        }
331

    
332
        public Map getOids() {
333
            return oids;
334
        }
335

    
336
        public Envelope getEnvelope() {
337
            return envelope;
338
        }
339
    }
340

    
341
}