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 @ 44612
History | View | Annotate | Download (11.2 KB)
1 | 40559 | jjdelcerro | /**
|
---|---|---|---|
2 | * gvSIG. Desktop Geographic Information System.
|
||
3 | 40435 | jjdelcerro | *
|
4 | 40559 | jjdelcerro | * Copyright (C) 2007-2013 gvSIG Association.
|
5 | *
|
||
6 | 40435 | jjdelcerro | * This program is free software; you can redistribute it and/or
|
7 | * modify it under the terms of the GNU General Public License
|
||
8 | 40559 | jjdelcerro | * as published by the Free Software Foundation; either version 3
|
9 | 40435 | jjdelcerro | * of the License, or (at your option) any later version.
|
10 | 40559 | jjdelcerro | *
|
11 | 40435 | jjdelcerro | * This program is distributed in the hope that it will be useful,
|
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
14 | * GNU General Public License for more details.
|
||
15 | 40559 | jjdelcerro | *
|
16 | 40435 | jjdelcerro | * You should have received a copy of the GNU General Public License
|
17 | * along with this program; if not, write to the Free Software
|
||
18 | 40559 | jjdelcerro | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
19 | 40435 | jjdelcerro | * MA 02110-1301, USA.
|
20 | 40559 | jjdelcerro | *
|
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 | 40435 | jjdelcerro | */
|
24 | |||
25 | package org.gvsig.fmap.dal.store.memory; |
||
26 | |||
27 | import java.util.ArrayList; |
||
28 | 44612 | jjdelcerro | import java.util.HashMap; |
29 | 40435 | jjdelcerro | import java.util.Hashtable; |
30 | import java.util.Iterator; |
||
31 | import java.util.List; |
||
32 | import java.util.Map; |
||
33 | |||
34 | import org.slf4j.Logger; |
||
35 | import org.slf4j.LoggerFactory; |
||
36 | import org.gvsig.fmap.dal.DataStore; |
||
37 | import org.gvsig.fmap.dal.DataTypes; |
||
38 | import org.gvsig.fmap.dal.exception.DataException; |
||
39 | import org.gvsig.fmap.dal.exception.InitializeException; |
||
40 | import org.gvsig.fmap.dal.exception.OpenException; |
||
41 | import org.gvsig.fmap.dal.feature.Feature; |
||
42 | import org.gvsig.fmap.dal.feature.FeatureSet; |
||
43 | import org.gvsig.fmap.dal.feature.FeatureType; |
||
44 | import org.gvsig.fmap.dal.feature.exception.PerformEditingException; |
||
45 | 42467 | jjdelcerro | import org.gvsig.fmap.dal.feature.spi.DefaultFeatureProvider; |
46 | 40435 | jjdelcerro | import org.gvsig.fmap.dal.feature.spi.FeatureProvider; |
47 | import org.gvsig.fmap.dal.feature.spi.FeatureReferenceProviderServices; |
||
48 | import org.gvsig.fmap.dal.feature.spi.FeatureStoreProviderServices; |
||
49 | import org.gvsig.fmap.dal.feature.spi.memory.AbstractMemoryStoreProvider; |
||
50 | import org.gvsig.fmap.dal.feature.spi.memory.MemoryResource; |
||
51 | import org.gvsig.fmap.dal.resource.spi.ResourceProvider; |
||
52 | import org.gvsig.fmap.dal.spi.DataStoreProviderServices; |
||
53 | import org.gvsig.fmap.geom.exception.CreateEnvelopeException; |
||
54 | import org.gvsig.fmap.geom.primitive.Envelope; |
||
55 | import org.gvsig.metadata.MetadataLocator; |
||
56 | import org.gvsig.metadata.MetadataManager; |
||
57 | import org.gvsig.metadata.exceptions.MetadataException; |
||
58 | import org.gvsig.tools.ToolsLocator; |
||
59 | import org.gvsig.tools.dispose.DisposableIterator; |
||
60 | import org.gvsig.tools.dynobject.DynObject; |
||
61 | import org.gvsig.tools.dynobject.DynStruct; |
||
62 | import org.gvsig.tools.exception.BaseException; |
||
63 | import org.gvsig.tools.visitor.VisitCanceledException; |
||
64 | import org.gvsig.tools.visitor.Visitor; |
||
65 | |||
66 | /**
|
||
67 | * @author <a href="mailto:jpiera@gvsig.org">Jorge Piera</a>
|
||
68 | *
|
||
69 | * TODO: take into account the parameter "autoOrderAttributeName" to
|
||
70 | * order the {@link Feature}s by default by that attribute, in ascending
|
||
71 | * order.
|
||
72 | */
|
||
73 | public class MemoryStoreProvider extends AbstractMemoryStoreProvider { |
||
74 | |||
75 | private static final Logger logger = LoggerFactory |
||
76 | .getLogger(MemoryStoreProvider.class); |
||
77 | |||
78 | public static final String NAME = "Memory"; |
||
79 | public static final String DESCRIPTION = "Memory provider"; |
||
80 | |||
81 | public static final String METADATA_DEFINITION_NAME = "MemoryProvider"; |
||
82 | |||
83 | private long counterNewsOIDs = 0; |
||
84 | private Envelope envelope = null; |
||
85 | private Map oids = null; |
||
86 | |||
87 | private Double sourceID = null; |
||
88 | |||
89 | private ResourceProvider memoryResource;
|
||
90 | |||
91 | public static DynObject newMetadataContainer(String name) { |
||
92 | return ToolsLocator.getDynObjectManager().createDynObject(
|
||
93 | MetadataLocator.getMetadataManager().getDefinition(name)); |
||
94 | } |
||
95 | |||
96 | public MemoryStoreProvider(MemoryStoreParameters memoryStoreParameters,
|
||
97 | DataStoreProviderServices storeServices) throws InitializeException {
|
||
98 | super(memoryStoreParameters, storeServices,
|
||
99 | newMetadataContainer(METADATA_DEFINITION_NAME)); |
||
100 | 44612 | jjdelcerro | sourceID = Math.random();
|
101 | 40435 | jjdelcerro | data = new ArrayList(); |
102 | 44612 | jjdelcerro | oids = new HashMap(); |
103 | 40435 | jjdelcerro | initialize(); |
104 | memoryResource = |
||
105 | createResource(MemoryResource.NAME, |
||
106 | new Object[] { memoryStoreParameters.getName() }); |
||
107 | } |
||
108 | |||
109 | 44439 | jjdelcerro | @Override
|
110 | 44454 | jjdelcerro | public boolean isTemporary() { |
111 | try {
|
||
112 | return (boolean) this.getParameters().getDynValue(MemoryStoreParameters.ISTEMPORARY_NAME); |
||
113 | } catch(Throwable th) { |
||
114 | return false; |
||
115 | } |
||
116 | } |
||
117 | |||
118 | 44541 | omartinez | |
119 | 44454 | jjdelcerro | @Override
|
120 | 42467 | jjdelcerro | public FeatureProvider createFeatureProvider(FeatureType featureType)throws DataException { |
121 | this.open();
|
||
122 | 44541 | omartinez | return new MemoryFeatureProvider(featureType, this.createNewOID()); |
123 | 42467 | jjdelcerro | } |
124 | |||
125 | 40435 | jjdelcerro | public String getName() { |
126 | 40887 | jjdelcerro | return "Memory_" + Integer.toHexString((int) (Math.random()*100000)).toUpperCase(); |
127 | 40435 | jjdelcerro | } |
128 | |||
129 | public String getFullName() { |
||
130 | 40887 | jjdelcerro | return "memory:" + Double.toHexString(this.sourceID.doubleValue()); |
131 | 40435 | jjdelcerro | } |
132 | |||
133 | private void initialize() { |
||
134 | FeatureType featureType = |
||
135 | 40887 | jjdelcerro | getStoreServices().createFeatureType(getName()).getNotEditableCopy(); |
136 | 40435 | jjdelcerro | List types = new ArrayList(1); |
137 | types.add(featureType); |
||
138 | getStoreServices().setFeatureTypes(types, featureType); |
||
139 | } |
||
140 | |||
141 | /*
|
||
142 | * (non-Javadoc)
|
||
143 | *
|
||
144 | * @see org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider#createNewOID()
|
||
145 | */
|
||
146 | public Object createNewOID() { |
||
147 | return new Long(counterNewsOIDs++); |
||
148 | } |
||
149 | |||
150 | /*
|
||
151 | * (non-Javadoc)
|
||
152 | *
|
||
153 | * @see org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider#getName()
|
||
154 | */
|
||
155 | public String getProviderName() { |
||
156 | return NAME;
|
||
157 | } |
||
158 | |||
159 | /*
|
||
160 | * (non-Javadoc)
|
||
161 | *
|
||
162 | * @see org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider#getOIDType()
|
||
163 | */
|
||
164 | public int getOIDType() { |
||
165 | return DataTypes.LONG;
|
||
166 | } |
||
167 | |||
168 | /*
|
||
169 | * (non-Javadoc)
|
||
170 | *
|
||
171 | * @see org.gvsig.fmap.dal.spi.DataStoreProvider#getSourceId()
|
||
172 | */
|
||
173 | public Object getSourceId() { |
||
174 | return sourceID;
|
||
175 | } |
||
176 | |||
177 | public void open() throws OpenException { |
||
178 | } |
||
179 | |||
180 | public static void registerMetadataDefinition() throws MetadataException { |
||
181 | MetadataManager manager = MetadataLocator.getMetadataManager(); |
||
182 | if (manager.getDefinition(METADATA_DEFINITION_NAME) == null) { |
||
183 | DynStruct metadataDefinition = |
||
184 | manager.addDefinition(METADATA_DEFINITION_NAME, "Memory Store");
|
||
185 | metadataDefinition.extend(manager |
||
186 | .getDefinition(DataStore.SPATIAL_METADATA_DEFINITION_NAME)); |
||
187 | } |
||
188 | } |
||
189 | |||
190 | public boolean allowWrite() { |
||
191 | return true; |
||
192 | } |
||
193 | |||
194 | public void performChanges(Iterator deleteds, Iterator inserteds, |
||
195 | Iterator updateds, Iterator originalFeatureTypesUpdated) |
||
196 | throws PerformEditingException {
|
||
197 | FeatureSet set = null;
|
||
198 | DisposableIterator iter = null;
|
||
199 | try {
|
||
200 | FeatureType featureType = |
||
201 | this.getStoreServices().getDefaultFeatureType();
|
||
202 | List types = new ArrayList(1); |
||
203 | types.add(featureType); |
||
204 | getStoreServices().setFeatureTypes(types, featureType); |
||
205 | |||
206 | set = this.getFeatureStore().getFeatureSet();
|
||
207 | |||
208 | // Create a visitor to generate new data
|
||
209 | EditionVisitor visitor = new EditionVisitor(set.getSize());
|
||
210 | |||
211 | // collect new data
|
||
212 | set.accept(visitor); |
||
213 | |||
214 | // update data objects
|
||
215 | data = visitor.getData(); |
||
216 | oids = visitor.getOids(); |
||
217 | envelope = visitor.getEnvelope(); |
||
218 | |||
219 | } catch (DataException e) {
|
||
220 | logger.error("Error adding features", e);
|
||
221 | } catch (BaseException e) {
|
||
222 | logger.error("Error performing edition", e);
|
||
223 | } finally {
|
||
224 | dispose(iter); |
||
225 | dispose(set); |
||
226 | } |
||
227 | } |
||
228 | |||
229 | public Envelope getEnvelope() throws DataException { |
||
230 | return envelope;
|
||
231 | } |
||
232 | |||
233 | protected FeatureProvider internalGetFeatureProviderByReference(
|
||
234 | FeatureReferenceProviderServices reference) throws DataException {
|
||
235 | return (FeatureProvider) oids.get(reference.getOID());
|
||
236 | } |
||
237 | |||
238 | public ResourceProvider getResource() {
|
||
239 | return memoryResource;
|
||
240 | } |
||
241 | |||
242 | public boolean supportsAppendMode() { |
||
243 | return true; |
||
244 | } |
||
245 | |||
246 | public void append(FeatureProvider featureProvider) throws DataException { |
||
247 | FeatureProvider newFeatureProvider = featureProvider.getCopy(); |
||
248 | if (data.isEmpty()) {
|
||
249 | try {
|
||
250 | envelope = |
||
251 | (Envelope) newFeatureProvider.getDefaultEnvelope().clone(); |
||
252 | } catch (CloneNotSupportedException e) { |
||
253 | envelope = newFeatureProvider.getDefaultEnvelope(); |
||
254 | } |
||
255 | } else {
|
||
256 | envelope.add(newFeatureProvider.getDefaultEnvelope()); |
||
257 | } |
||
258 | |||
259 | newFeatureProvider.setNew(false);
|
||
260 | data.add(newFeatureProvider); |
||
261 | oids.put(newFeatureProvider.getOID(), newFeatureProvider); |
||
262 | logger.debug("Envelope after adding feature: ", envelope.toString());
|
||
263 | } |
||
264 | |||
265 | public void beginAppend() throws DataException { |
||
266 | // Nothing to do
|
||
267 | } |
||
268 | |||
269 | public void endAppend() throws DataException { |
||
270 | // Nothing to do
|
||
271 | } |
||
272 | |||
273 | /**
|
||
274 | * Visitor to create new data objects from finish edition operation
|
||
275 | *
|
||
276 | * @author jmvivo ( jmvivo at disid dot com)
|
||
277 | *
|
||
278 | */
|
||
279 | private class EditionVisitor implements Visitor { |
||
280 | |||
281 | private List data; |
||
282 | private Map oids; |
||
283 | private Envelope envelope;
|
||
284 | private FeatureStoreProviderServices services;
|
||
285 | |||
286 | /**
|
||
287 | * @param size
|
||
288 | * to use to initialize data structures
|
||
289 | * @throws CreateEnvelopeException
|
||
290 | */
|
||
291 | public EditionVisitor(long size) { |
||
292 | data = new ArrayList((int) size); |
||
293 | 44612 | jjdelcerro | oids = new HashMap((int) size); |
294 | 40435 | jjdelcerro | envelope = null;
|
295 | services = MemoryStoreProvider.this.getStoreServices(); |
||
296 | } |
||
297 | |||
298 | public void visit(Object obj) throws VisitCanceledException, |
||
299 | BaseException { |
||
300 | Feature feature = (Feature) obj; |
||
301 | FeatureProvider featureProvider = |
||
302 | services.getFeatureProviderFromFeature(feature); |
||
303 | featureProvider.setNew(false);
|
||
304 | data.add(featureProvider); |
||
305 | oids.put(featureProvider.getOID(), featureProvider); |
||
306 | 44612 | jjdelcerro | // if (envelope == null) {
|
307 | // try {
|
||
308 | // envelope = (Envelope) feature.getDefaultEnvelope().clone();
|
||
309 | // } catch (CloneNotSupportedException e) {
|
||
310 | // envelope = feature.getDefaultEnvelope();
|
||
311 | // }
|
||
312 | // } else {
|
||
313 | // envelope.add(feature.getDefaultEnvelope());
|
||
314 | // }
|
||
315 | 40435 | jjdelcerro | Envelope aux = feature.getDefaultEnvelope(); |
316 | if (aux != null) { //There are geometries |
||
317 | if (envelope == null) { |
||
318 | try {
|
||
319 | envelope = (Envelope) aux.clone(); |
||
320 | } catch (CloneNotSupportedException e) { |
||
321 | envelope = feature.getDefaultEnvelope(); |
||
322 | } |
||
323 | } else {
|
||
324 | envelope.add(feature.getDefaultEnvelope()); |
||
325 | } |
||
326 | } |
||
327 | } |
||
328 | |||
329 | public List getData() { |
||
330 | return data;
|
||
331 | } |
||
332 | |||
333 | public Map getOids() { |
||
334 | return oids;
|
||
335 | } |
||
336 | |||
337 | public Envelope getEnvelope() {
|
||
338 | return envelope;
|
||
339 | } |
||
340 | } |
||
341 | |||
342 | } |