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

History | View | Annotate | Download (10.6 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.FeatureProvider;
45
import org.gvsig.fmap.dal.feature.spi.FeatureReferenceProviderServices;
46
import org.gvsig.fmap.dal.feature.spi.FeatureStoreProviderServices;
47
import org.gvsig.fmap.dal.feature.spi.memory.AbstractMemoryStoreProvider;
48
import org.gvsig.fmap.dal.feature.spi.memory.MemoryResource;
49
import org.gvsig.fmap.dal.resource.spi.ResourceProvider;
50
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
51
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
52
import org.gvsig.fmap.geom.primitive.Envelope;
53
import org.gvsig.metadata.MetadataLocator;
54
import org.gvsig.metadata.MetadataManager;
55
import org.gvsig.metadata.exceptions.MetadataException;
56
import org.gvsig.tools.ToolsLocator;
57
import org.gvsig.tools.dispose.DisposableIterator;
58
import org.gvsig.tools.dynobject.DynObject;
59
import org.gvsig.tools.dynobject.DynStruct;
60
import org.gvsig.tools.exception.BaseException;
61
import org.gvsig.tools.visitor.VisitCanceledException;
62
import org.gvsig.tools.visitor.Visitor;
63

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

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

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

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

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

    
85
    private Double sourceID = null;
86

    
87
    private ResourceProvider memoryResource;
88

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

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

    
107
    public String getName() {
108
        return "Memory_" + Integer.toHexString((int) (Math.random()*100000)).toUpperCase();
109
    }
110

    
111
    public String getFullName() {
112
        return "memory:" + Double.toHexString(this.sourceID.doubleValue());
113
    }
114

    
115
    private void initialize() {
116
        FeatureType featureType =
117
            getStoreServices().createFeatureType(getName()).getNotEditableCopy();
118
        List types = new ArrayList(1);
119
        types.add(featureType);
120
        getStoreServices().setFeatureTypes(types, featureType);
121
    }
122

    
123
    /*
124
     * (non-Javadoc)
125
     * 
126
     * @see org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider#createNewOID()
127
     */
128
    public Object createNewOID() {
129
        return new Long(counterNewsOIDs++);
130
    }
131

    
132
    /*
133
     * (non-Javadoc)
134
     * 
135
     * @see org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider#getName()
136
     */
137
    public String getProviderName() {
138
        return NAME;
139
    }
140

    
141
    /*
142
     * (non-Javadoc)
143
     * 
144
     * @see org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider#getOIDType()
145
     */
146
    public int getOIDType() {
147
        return DataTypes.LONG;
148
    }
149

    
150
    /*
151
     * (non-Javadoc)
152
     * 
153
     * @see org.gvsig.fmap.dal.spi.DataStoreProvider#getSourceId()
154
     */
155
    public Object getSourceId() {
156
        return sourceID;
157
    }
158

    
159
    public void open() throws OpenException {
160
    }
161

    
162
    public static void registerMetadataDefinition() throws MetadataException {
163
        MetadataManager manager = MetadataLocator.getMetadataManager();
164
        if (manager.getDefinition(METADATA_DEFINITION_NAME) == null) {
165
            DynStruct metadataDefinition =
166
                manager.addDefinition(METADATA_DEFINITION_NAME, "Memory Store");
167
            metadataDefinition.extend(manager
168
                .getDefinition(DataStore.SPATIAL_METADATA_DEFINITION_NAME));
169
        }
170
    }
171

    
172
    public boolean allowWrite() {
173
        return true;
174
    }
175

    
176
    public void performChanges(Iterator deleteds, Iterator inserteds,
177
        Iterator updateds, Iterator originalFeatureTypesUpdated)
178
        throws PerformEditingException {
179
        FeatureSet set = null;
180
        DisposableIterator iter = null;
181
        try {
182
            FeatureType featureType =
183
                this.getStoreServices().getDefaultFeatureType();
184
            List types = new ArrayList(1);
185
            types.add(featureType);
186
            getStoreServices().setFeatureTypes(types, featureType);
187

    
188
            set = this.getFeatureStore().getFeatureSet();
189

    
190
            // Create a visitor to generate new data
191
            EditionVisitor visitor = new EditionVisitor(set.getSize());
192

    
193
            // collect new data
194
            set.accept(visitor);
195

    
196
            // update data objects
197
            data = visitor.getData();
198
            oids = visitor.getOids();
199
            envelope = visitor.getEnvelope();
200

    
201
        } catch (DataException e) {
202
            logger.error("Error adding features", e);
203
        } catch (BaseException e) {
204
            logger.error("Error performing edition", e);
205
        } finally {
206
            dispose(iter);
207
            dispose(set);
208
        }
209
    }
210

    
211
    public Envelope getEnvelope() throws DataException {
212
        return envelope;
213
    }
214

    
215
    protected FeatureProvider internalGetFeatureProviderByReference(
216
        FeatureReferenceProviderServices reference) throws DataException {
217
        return (FeatureProvider) oids.get(reference.getOID());
218
    }
219

    
220
    public ResourceProvider getResource() {
221
        return memoryResource;
222
    }
223

    
224
    public boolean supportsAppendMode() {
225
        return true;
226
    }
227

    
228
    public void append(FeatureProvider featureProvider) throws DataException {
229
        FeatureProvider newFeatureProvider = featureProvider.getCopy();
230
        if (data.isEmpty()) {
231
            try {
232
                envelope =
233
                    (Envelope) newFeatureProvider.getDefaultEnvelope().clone();
234
            } catch (CloneNotSupportedException e) {
235
                envelope = newFeatureProvider.getDefaultEnvelope();
236
            }
237
        } else {
238
            envelope.add(newFeatureProvider.getDefaultEnvelope());
239
        }
240

    
241
        newFeatureProvider.setNew(false);
242
        data.add(newFeatureProvider);
243
        oids.put(newFeatureProvider.getOID(), newFeatureProvider);
244
        logger.debug("Envelope after adding feature: ", envelope.toString());
245
    }
246

    
247
    public void beginAppend() throws DataException {
248
        // Nothing to do
249
    }
250

    
251
    public void endAppend() throws DataException {
252
        // Nothing to do
253
    }
254

    
255
    /**
256
     * Visitor to create new data objects from finish edition operation
257
     * 
258
     * @author jmvivo ( jmvivo at disid dot com)
259
     * 
260
     */
261
    private class EditionVisitor implements Visitor {
262

    
263
        private List data;
264
        private Map oids;
265
        private Envelope envelope;
266
        private FeatureStoreProviderServices services;
267

    
268
        /**
269
         * @param size
270
         *            to use to initialize data structures
271
         * @throws CreateEnvelopeException
272
         */
273
        public EditionVisitor(long size) {
274
            data = new ArrayList((int) size);
275
            oids = new Hashtable((int) size);
276
            envelope = null;
277
            services = MemoryStoreProvider.this.getStoreServices();
278
        }
279

    
280
        public void visit(Object obj) throws VisitCanceledException,
281
            BaseException {
282
            Feature feature = (Feature) obj;
283
            FeatureProvider featureProvider =
284
                services.getFeatureProviderFromFeature(feature);
285
            featureProvider.setNew(false);
286
            data.add(featureProvider);
287
            oids.put(featureProvider.getOID(), featureProvider);
288
            if (envelope == null) {
289
                try {
290
                    envelope = (Envelope) feature.getDefaultEnvelope().clone();
291
                } catch (CloneNotSupportedException e) {
292
                    envelope = feature.getDefaultEnvelope();
293
                }
294
            } else {
295
                envelope.add(feature.getDefaultEnvelope());
296
            }
297
            Envelope aux = feature.getDefaultEnvelope();
298
            if (aux != null) { //There are geometries
299
                    if (envelope == null) {
300
                            try {
301
                                    envelope = (Envelope) aux.clone();
302
                            } catch (CloneNotSupportedException e) {
303
                                    envelope = feature.getDefaultEnvelope();
304
                            }
305
                    } else {
306
                            envelope.add(feature.getDefaultEnvelope());
307
                    }
308
            }
309
        }
310

    
311
        public List getData() {
312
            return data;
313
        }
314

    
315
        public Map getOids() {
316
            return oids;
317
        }
318

    
319
        public Envelope getEnvelope() {
320
            return envelope;
321
        }
322
    }
323

    
324
}