root / branches / v2_0_0_prep / libraries / libFMap_data / src / org / gvsig / fmap / data / feature / AbstractFeatureStore.java @ 23303
History | View | Annotate | Download (27.6 KB)
1 |
package org.gvsig.fmap.data.feature; |
---|---|
2 |
|
3 |
import java.lang.ref.Reference; |
4 |
import java.util.ArrayList; |
5 |
import java.util.Iterator; |
6 |
import java.util.List; |
7 |
|
8 |
import org.gvsig.fmap.data.CloseException; |
9 |
import org.gvsig.fmap.data.DataCollection; |
10 |
import org.gvsig.fmap.data.DataException; |
11 |
import org.gvsig.fmap.data.DataManager; |
12 |
import org.gvsig.fmap.data.DataStoreParameters; |
13 |
import org.gvsig.fmap.data.InitializeException; |
14 |
import org.gvsig.fmap.data.OpenException; |
15 |
import org.gvsig.fmap.data.ReadException; |
16 |
import org.gvsig.fmap.data.Resource; |
17 |
import org.gvsig.fmap.data.ResourceNotification; |
18 |
import org.gvsig.fmap.data.WriteException; |
19 |
import org.gvsig.fmap.data.commands.Command; |
20 |
import org.gvsig.fmap.data.commands.CommandsRecord; |
21 |
import org.gvsig.fmap.data.commands.implementation.FeatureCommandsRecord; |
22 |
import org.gvsig.fmap.data.feature.expansionadapter.ExpansionAdapter; |
23 |
import org.gvsig.fmap.data.feature.expansionadapter.MemoryExpansionAdapter; |
24 |
import org.gvsig.fmap.data.feature.expressionevaluator.AttributeValueEvaluator; |
25 |
import org.gvsig.fmap.data.index.IndexException; |
26 |
import org.gvsig.fmap.data.index.IndexStore; |
27 |
import org.gvsig.fmap.data.index.spatial.PersistentSpatialIndex; |
28 |
import org.gvsig.fmap.data.index.spatial.SpatialIndex; |
29 |
import org.gvsig.fmap.data.index.spatial.SpatialIndexFactory; |
30 |
import org.gvsig.fmap.data.index.spatial.SpatialIndexParameters; |
31 |
import org.gvsig.fmap.data.operation.DataStoreOperationContext; |
32 |
import org.gvsig.fmap.data.operation.DataStoreOperationException; |
33 |
import org.gvsig.fmap.data.operation.DataStoreOperationNotSupportedException; |
34 |
import org.gvsig.fmap.geom.Geometry; |
35 |
import org.gvsig.fmap.geom.primitive.Envelope; |
36 |
import org.gvsig.tools.exception.BaseException; |
37 |
import org.gvsig.tools.observer.ComplexNotification; |
38 |
import org.gvsig.tools.observer.DefaultObservable; |
39 |
import org.gvsig.tools.observer.Observable; |
40 |
import org.gvsig.tools.observer.Observer; |
41 |
|
42 |
import com.iver.utiles.XMLEntity; |
43 |
import com.iver.utiles.XMLException; |
44 |
|
45 |
|
46 |
public abstract class AbstractFeatureStore implements FeatureStore { |
47 |
protected DataStoreParameters parameters = null; |
48 |
protected DataCollection selection;
|
49 |
protected CommandsRecord commands;
|
50 |
protected boolean alterMode = false; |
51 |
// protected ComplexObservable observable=new ComplexObservable();
|
52 |
protected DataCollection locked;
|
53 |
protected DefaultObservable observable=new DefaultObservable(); |
54 |
protected FeatureManager featureManager;
|
55 |
protected SpatialManager spatialManager;
|
56 |
protected AttributeManager attributeManager;
|
57 |
protected ArrayList resouceObservers = new ArrayList(); |
58 |
protected FeatureType defaultFeatureType = null; |
59 |
protected Observer selectionObserver = null; |
60 |
protected IndexStore indexStore = null; |
61 |
|
62 |
|
63 |
public void init(DataStoreParameters parameters) throws InitializeException { |
64 |
if (this.parameters != null) { |
65 |
throw new InitializeException("initialized two times", this |
66 |
.getName()); |
67 |
} |
68 |
this.parameters = parameters;
|
69 |
} |
70 |
|
71 |
public void init(DataStoreParameters parameters,Resource resource) throws InitializeException { |
72 |
if (this.parameters != null) { |
73 |
throw new InitializeException("initialized two times", this |
74 |
.getName()); |
75 |
} |
76 |
this.parameters = parameters;
|
77 |
this.observeResource(resource);
|
78 |
} |
79 |
|
80 |
public void setXMLEntity(XMLEntity xmlEntity) throws XMLException { |
81 |
DataManager manager = DataManager.getManager(); |
82 |
|
83 |
XMLEntity paramsXML = xmlEntity.firstChild("type", "parameters"); |
84 |
|
85 |
if (paramsXML == null) { |
86 |
throw new XMLInitializeException("parameters not found", this |
87 |
.getName()); |
88 |
} |
89 |
try {
|
90 |
DataStoreParameters params = manager |
91 |
.createDataStoreParameters(paramsXML); |
92 |
this.init(params);
|
93 |
} catch (InitializeException e) {
|
94 |
throw new XMLInitializeException("inititalize", e); |
95 |
} |
96 |
//TODO Selection and Lock persistence
|
97 |
|
98 |
} |
99 |
|
100 |
public XMLEntity getXMLEntity() {
|
101 |
XMLEntity xml = new XMLEntity();
|
102 |
XMLEntity paramsXML = this.parameters.getXMLEntity();
|
103 |
xml.putProperty("dataStoreName", this.getName()); |
104 |
paramsXML.putProperty("type", "parameters"); |
105 |
|
106 |
xml.addChild(paramsXML); |
107 |
|
108 |
//TODO Selection and Lock persistence... IndexParams???
|
109 |
|
110 |
return xml;
|
111 |
} |
112 |
|
113 |
|
114 |
|
115 |
|
116 |
protected final void observeResource(Resource resource){ |
117 |
ResourceChangedObserver observer=new ResourceChangedObserver(this); |
118 |
resource.addObserver(observer); |
119 |
this.resouceObservers.add(observer);
|
120 |
} |
121 |
|
122 |
protected final void clearResourceObservers() { |
123 |
this.resouceObservers.clear();
|
124 |
} |
125 |
|
126 |
protected void initSpatialManager(){ |
127 |
spatialManager=new SpatialManager();
|
128 |
} |
129 |
|
130 |
protected void initAttributeManager() { |
131 |
ExpansionAdapter expansionAttributeAdapter=new MemoryExpansionAdapter();
|
132 |
attributeManager=new AttributeManager(expansionAttributeAdapter,getDefaultFeatureType());
|
133 |
|
134 |
} |
135 |
|
136 |
protected void initExpansionManager() { |
137 |
ExpansionAdapter expansionFeatureAdapter=new MemoryExpansionAdapter();
|
138 |
featureManager=new FeatureManager(expansionFeatureAdapter);
|
139 |
} |
140 |
|
141 |
public DataCollection getDataCollection() throws ReadException { |
142 |
return getDataCollection(this.getDefaultFeatureType(), null, null); |
143 |
} |
144 |
|
145 |
|
146 |
public DataCollection getDataCollection(String[] fields, String filter, |
147 |
String order) throws ReadException { |
148 |
try {
|
149 |
return getDataCollection(this.getDefaultFeatureType().getSubFeatureType(fields), filter, order); |
150 |
} catch (DataException e) {
|
151 |
throw new ReadException(this.getName(), e); |
152 |
} |
153 |
} |
154 |
|
155 |
public void getDataCollection(Observer observer) { |
156 |
getDataCollection(this.getDefaultFeatureType(), null, null,observer); |
157 |
} |
158 |
|
159 |
public final void setSelection(DataCollection selection) |
160 |
throws DataException {
|
161 |
if (selection.equals(this.selection)) { |
162 |
return;
|
163 |
} |
164 |
if (!selection.isFromStore(this)){ |
165 |
throw new DataException("selection not form this store"); |
166 |
} |
167 |
doSetSelection(selection); |
168 |
this.notifySelectionChange();
|
169 |
} |
170 |
|
171 |
protected void doSetSelection(DataCollection selection) { |
172 |
this.unsetSelectionObserver();
|
173 |
if (this.getSelection().getClass().isInstance(selection)) { |
174 |
this.selection = selection;
|
175 |
} else {
|
176 |
this.selection = null; |
177 |
this.getSelection().addAll(selection);
|
178 |
} |
179 |
this.setSelectionObserver();
|
180 |
} |
181 |
|
182 |
protected void setSelectionObserver(){ |
183 |
if (this.selection instanceof Observable) { |
184 |
Observable obSelection = (Observable) this.selection; |
185 |
if (this.selectionObserver == null){ |
186 |
this.selectionObserver=new SelectionObserver(this); |
187 |
} |
188 |
obSelection.addObserver(this.selectionObserver);
|
189 |
} |
190 |
} |
191 |
|
192 |
protected void unsetSelectionObserver() { |
193 |
if (this.selection instanceof Observable) { |
194 |
Observable obSelection = (Observable) this.selection; |
195 |
obSelection.deleteObserver(this.selectionObserver);
|
196 |
} |
197 |
} |
198 |
|
199 |
public DataCollection createSelection() {
|
200 |
|
201 |
MemoryFeatureCollection selection = new MemoryFeatureCollection(this); |
202 |
return selection;
|
203 |
} |
204 |
|
205 |
public DataCollection getSelection() {
|
206 |
if( selection == null ){ |
207 |
this.selection = createSelection();
|
208 |
this.setSelectionObserver();
|
209 |
} |
210 |
return selection;
|
211 |
} |
212 |
|
213 |
public DataCollection createLocked() {
|
214 |
MemoryFeatureCollection locked = new MemoryFeatureCollection(this); |
215 |
return locked;
|
216 |
} |
217 |
|
218 |
public DataCollection getLocked() {
|
219 |
if( locked == null ){ |
220 |
locked = createLocked(); |
221 |
} |
222 |
return locked;
|
223 |
} |
224 |
|
225 |
public final void setLocked(DataCollection locked) { |
226 |
this.observable.notifyObservers(this, |
227 |
new DefaultFeatureStoreNotification(this,DefaultFeatureStoreNotification.BEFORE_LOCKEDCHANGE) |
228 |
); |
229 |
doLocked(locked); |
230 |
this.observable.notifyObservers(this, |
231 |
new DefaultFeatureStoreNotification(this,DefaultFeatureStoreNotification.AFTER_LOCKEDCHANGE) |
232 |
); |
233 |
|
234 |
} |
235 |
protected void doLocked(DataCollection locked) { |
236 |
this.locked = locked;
|
237 |
|
238 |
} |
239 |
|
240 |
public boolean isLocked(FeatureID id) { |
241 |
return locked.contains(id);
|
242 |
} |
243 |
|
244 |
public final boolean lock(FeatureID id) { |
245 |
this.observable.notifyObservers(this, |
246 |
new DefaultFeatureStoreNotification(this,DefaultFeatureStoreNotification.BEFORE_LOCKEDCHANGE) |
247 |
); |
248 |
doLock(id); |
249 |
this.observable.notifyObservers(this, |
250 |
new DefaultFeatureStoreNotification(this,DefaultFeatureStoreNotification.AFTER_LOCKEDCHANGE) |
251 |
); |
252 |
return true; |
253 |
} |
254 |
|
255 |
|
256 |
protected void doLock(FeatureID id) { |
257 |
locked.add(id); |
258 |
} |
259 |
|
260 |
public final void startEditing() throws ReadException { |
261 |
if (!this.isEditable()) { |
262 |
throw new ReadException("AbstractFeatureStore", |
263 |
new UnsupportedOperationException("Not editable")); |
264 |
} |
265 |
this.observable.notifyObservers(this, |
266 |
new DefaultFeatureStoreNotification(this,DefaultFeatureStoreNotification.BEFORE_STARTEDITING) |
267 |
); |
268 |
doStartEditing(); |
269 |
this.observable.notifyObservers(this, |
270 |
new DefaultFeatureStoreNotification(this,DefaultFeatureStoreNotification.AFTER_STARTEDITING) |
271 |
); |
272 |
|
273 |
} |
274 |
|
275 |
|
276 |
protected void doStartEditing() { |
277 |
// commands.clear();
|
278 |
initExpansionManager(); |
279 |
initSpatialManager(); |
280 |
initAttributeManager(); |
281 |
commands = new FeatureCommandsRecord(featureManager, spatialManager, attributeManager);
|
282 |
|
283 |
|
284 |
alterMode = true;
|
285 |
} |
286 |
|
287 |
public final void delete(FeatureAttributeDescriptor attributeDescriptor) { |
288 |
//FIXME Comporobar que el attribute viene del Fype de este store
|
289 |
if( !alterMode ) {
|
290 |
throw new RuntimeException("alterMode is false"); |
291 |
} |
292 |
this.observable.notifyObservers(this, |
293 |
new DefaultAttributeStoreNotification(this,DefaultAttributeStoreNotification.BEFORE_DELETE_ATTRIBUTE,attributeDescriptor) |
294 |
); |
295 |
doDelete(attributeDescriptor); |
296 |
this.observable.notifyObservers(this, |
297 |
new DefaultAttributeStoreNotification(this,DefaultAttributeStoreNotification.AFTER_DELETE_ATTRIBUTE,attributeDescriptor) |
298 |
); |
299 |
|
300 |
|
301 |
} |
302 |
|
303 |
protected void doDelete(FeatureAttributeDescriptor attributeDescriptor) { |
304 |
commands.delete(attributeDescriptor); |
305 |
|
306 |
} |
307 |
|
308 |
public final void insert(FeatureAttributeDescriptor attributeDescriptor) throws DataException { |
309 |
if( !alterMode ) {
|
310 |
throw new DataException("alterMode is false"); |
311 |
} |
312 |
if (!((AttributeDescriptor)attributeDescriptor).isNew()){
|
313 |
throw new DataException("attribute is not new"); |
314 |
} |
315 |
this.observable.notifyObservers(this, |
316 |
new DefaultAttributeStoreNotification(this,DefaultAttributeStoreNotification.BEFORE_INSERT_ATTRIBUTE,attributeDescriptor) |
317 |
); |
318 |
doInsert(attributeDescriptor); |
319 |
this.observable.notifyObservers(this, |
320 |
new DefaultAttributeStoreNotification(this,DefaultFeatureStoreNotification.AFTER_INSERT,attributeDescriptor) |
321 |
); |
322 |
|
323 |
} |
324 |
|
325 |
protected void doInsert(FeatureAttributeDescriptor attributeDescriptor) { |
326 |
((AttributeDescriptor)attributeDescriptor).stopEditing(); |
327 |
commands.insert(attributeDescriptor); |
328 |
} |
329 |
|
330 |
public final void update(FeatureAttributeDescriptor attributeDescriptor) { |
331 |
//FIXME Comporobar que el attribute viene del Fype de este store
|
332 |
if( !alterMode ) {
|
333 |
throw new RuntimeException("alterMode is false"); |
334 |
} |
335 |
this.observable.notifyObservers(this, |
336 |
new DefaultAttributeStoreNotification(this,DefaultAttributeStoreNotification.BEFORE_UPDATE_ATTRIBUTE,attributeDescriptor) |
337 |
); |
338 |
doUpdate(attributeDescriptor); |
339 |
this.observable.notifyObservers(this, |
340 |
new DefaultAttributeStoreNotification(this,DefaultAttributeStoreNotification.AFTER_UPDATE_ATTRIBUTE,attributeDescriptor) |
341 |
); |
342 |
} |
343 |
|
344 |
|
345 |
protected void doUpdate(FeatureAttributeDescriptor attributeDescriptor) { |
346 |
commands.update(((AttributeDescriptor)attributeDescriptor).getNewAttributeDescriptor(),attributeDescriptor); |
347 |
((AttributeDescriptor)attributeDescriptor).stopEditing(); |
348 |
} |
349 |
|
350 |
public final void delete(Feature feature) { |
351 |
if( !alterMode ) {
|
352 |
throw new RuntimeException("alterMode is false"); |
353 |
} |
354 |
this.observable.notifyObservers(this, |
355 |
new DefaultFeatureStoreNotification(this,DefaultFeatureStoreNotification.BEFORE_DELETE,feature) |
356 |
); |
357 |
doDelete(feature); |
358 |
this.observable.notifyObservers(this, |
359 |
new DefaultFeatureStoreNotification(this,DefaultFeatureStoreNotification.AFTER_DELETE,feature) |
360 |
); |
361 |
|
362 |
|
363 |
} |
364 |
|
365 |
protected void doDelete(Feature feature) { |
366 |
commands.delete(feature); |
367 |
} |
368 |
|
369 |
public final void insert(Feature feature) { |
370 |
if( !alterMode ) {
|
371 |
throw new RuntimeException("alterMode is false"); |
372 |
} |
373 |
// FIXME: Comprobar que la feature es de este store
|
374 |
feature.validateModification(this);
|
375 |
this.observable.notifyObservers(this, |
376 |
new DefaultFeatureStoreNotification(this,DefaultFeatureStoreNotification.BEFORE_INSERT,feature) |
377 |
); |
378 |
doInsert(feature); |
379 |
this.observable.notifyObservers(this, |
380 |
new DefaultFeatureStoreNotification(this,DefaultFeatureStoreNotification.AFTER_INSERT,feature) |
381 |
); |
382 |
|
383 |
} |
384 |
|
385 |
protected void doInsert(Feature feature) { |
386 |
commands.insert(((AbstractFeature)feature).getNewFeature()); |
387 |
} |
388 |
|
389 |
public final void update(Feature feature) { |
390 |
if( !alterMode ) {
|
391 |
throw new RuntimeException("alterMode is false"); |
392 |
} |
393 |
// FIXME: Comprobar que la feature es de este store
|
394 |
feature.validateModification(this);
|
395 |
this.observable.notifyObservers(this, |
396 |
new DefaultFeatureStoreNotification(this,DefaultFeatureStoreNotification.BEFORE_UPDATE,feature) |
397 |
); |
398 |
doUpdate(feature); |
399 |
this.observable.notifyObservers(this, |
400 |
new DefaultFeatureStoreNotification(this,DefaultFeatureStoreNotification.AFTER_UPDATE,feature) |
401 |
); |
402 |
} |
403 |
|
404 |
protected void doUpdate(Feature feature) { |
405 |
feature.validateModification(this);
|
406 |
AbstractFeature oldFeature = (AbstractFeature)feature; |
407 |
Feature newFeature=oldFeature.getNewFeature(); |
408 |
oldFeature.stopEditing(); |
409 |
commands.update(newFeature,oldFeature); |
410 |
} |
411 |
|
412 |
public final void redo() { |
413 |
if( !alterMode ) {
|
414 |
throw new RuntimeException("alterMode is false"); |
415 |
} |
416 |
Command redo = commands.getNextRedoCommand(); |
417 |
this.observable.notifyObservers(this, |
418 |
new DefaultFeatureStoreNotification(this,DefaultFeatureStoreNotification.BEFORE_REDO,redo) |
419 |
); |
420 |
|
421 |
doRedo(); |
422 |
|
423 |
this.observable.notifyObservers(this, |
424 |
new DefaultFeatureStoreNotification(this,DefaultFeatureStoreNotification.AFTER_REDO,redo) |
425 |
); |
426 |
|
427 |
} |
428 |
|
429 |
|
430 |
protected void doRedo() { |
431 |
commands.redo(); |
432 |
} |
433 |
|
434 |
public final void undo() { |
435 |
if( !alterMode ) {
|
436 |
throw new RuntimeException("alterMode is false"); |
437 |
} |
438 |
Command undo = commands.getNextUndoCommand(); |
439 |
this.observable.notifyObservers(this, |
440 |
new DefaultFeatureStoreNotification(this,DefaultFeatureStoreNotification.BEFORE_UNDO,undo) |
441 |
); |
442 |
doUndo(); |
443 |
|
444 |
this.observable.notifyObservers(this, |
445 |
new DefaultFeatureStoreNotification(this,DefaultFeatureStoreNotification.AFTER_UNDO,undo) |
446 |
); |
447 |
|
448 |
} |
449 |
|
450 |
protected void doUndo() { |
451 |
commands.undo(); |
452 |
|
453 |
} |
454 |
|
455 |
public CommandsRecord getCommandsRecord() {
|
456 |
if( !alterMode ) {
|
457 |
throw new RuntimeException("alterMode is false"); |
458 |
} |
459 |
return commands;
|
460 |
} |
461 |
|
462 |
protected void doCancelEditing(){ |
463 |
commands.clear(); |
464 |
} |
465 |
|
466 |
public final void cancelEditing() { |
467 |
if( !alterMode ) {
|
468 |
throw new RuntimeException("alterMode is false"); |
469 |
} |
470 |
this.observable.notifyObservers(this, |
471 |
new DefaultFeatureStoreNotification(this,DefaultFeatureStoreNotification.BEFORE_CANCELEDITING) |
472 |
); |
473 |
|
474 |
doCancelEditing(); |
475 |
alterMode = false;
|
476 |
this.observable.notifyObservers(this, |
477 |
new DefaultFeatureStoreNotification(this,DefaultFeatureStoreNotification.AFTER_CANCELEDITING) |
478 |
); |
479 |
|
480 |
} |
481 |
|
482 |
public final void finishEditing() throws WriteException, ReadException{ |
483 |
if( !alterMode ) {
|
484 |
//FIXME: OJO arreglar esta excepci?n!!!
|
485 |
throw new RuntimeException("alterMode is false"); |
486 |
} |
487 |
|
488 |
this.observable.notifyObservers(this, |
489 |
new DefaultFeatureStoreNotification(this,DefaultFeatureStoreNotification.BEFORE_FINISHEDITING) |
490 |
); |
491 |
|
492 |
this.validateEndEditing();
|
493 |
|
494 |
doFinishEdition(); |
495 |
|
496 |
|
497 |
commands.clear(); |
498 |
featureManager=null;
|
499 |
spatialManager=null;
|
500 |
attributeManager=null;
|
501 |
commands = null;
|
502 |
|
503 |
alterMode = false;
|
504 |
|
505 |
this.observable.notifyObservers(this, |
506 |
new DefaultFeatureStoreNotification(this,DefaultFeatureStoreNotification.AFTER_FINISHEDITING) |
507 |
); |
508 |
|
509 |
} |
510 |
|
511 |
protected abstract void doFinishEdition() throws WriteException, ReadException ; |
512 |
|
513 |
|
514 |
public Iterator getChilds() { |
515 |
return null; |
516 |
} |
517 |
|
518 |
public void beginComplexNotification() { |
519 |
this.observable.beginComplexNotification(new ComplexNotification()); |
520 |
|
521 |
} |
522 |
|
523 |
public void endComplexNotification() { |
524 |
this.observable.endComplexNotification(this); |
525 |
|
526 |
} |
527 |
|
528 |
public void addObserver(Observer o) { |
529 |
this.observable.addObserver(o);
|
530 |
|
531 |
} |
532 |
|
533 |
public void addObserver(Reference ref) { |
534 |
this.observable.addObserver(ref);
|
535 |
} |
536 |
|
537 |
public void deleteObserver(Observer o) { |
538 |
this.observable.deleteObserver(o);
|
539 |
} |
540 |
|
541 |
public void deleteObserver(Reference ref) { |
542 |
this.observable.deleteObserver(ref);
|
543 |
} |
544 |
|
545 |
public void deleteObservers() { |
546 |
this.observable.deleteObservers();
|
547 |
|
548 |
} |
549 |
|
550 |
public boolean isEditing() { |
551 |
return alterMode;
|
552 |
} |
553 |
|
554 |
protected void validateEndEditing() throws ReadException{ |
555 |
FeatureCollection collection = (FeatureCollection)this.getDataCollection();
|
556 |
Iterator iter = collection.iterator();
|
557 |
while (iter.hasNext()){
|
558 |
((Feature)iter.next()).validateEnd(this);
|
559 |
} |
560 |
|
561 |
} |
562 |
|
563 |
public void disableNotifications() { |
564 |
this.observable.diableNotifications();
|
565 |
|
566 |
} |
567 |
|
568 |
public void enableNotifications() { |
569 |
this.observable.enableNotifications();
|
570 |
} |
571 |
|
572 |
|
573 |
|
574 |
public void getDataCollection(String[] fields, String filter, String order, |
575 |
Observer observer) throws DataException { |
576 |
|
577 |
this.getDataCollection(this.getDefaultFeatureType().getSubFeatureType(fields), filter, order, observer); |
578 |
} |
579 |
|
580 |
public void getDataCollection(FeatureType type, String filter, String order,Observer observer) { |
581 |
LoadInBackGround task = new LoadInBackGround(this,type,filter,order,observer); |
582 |
Thread thread = new Thread(task); |
583 |
thread.run(); |
584 |
} |
585 |
private class LoadInBackGround implements Runnable{ |
586 |
|
587 |
private FeatureStore store;
|
588 |
private FeatureType type;
|
589 |
private String filter; |
590 |
private String order; |
591 |
|
592 |
private Observer observer; |
593 |
|
594 |
public DataCollection collection = null; |
595 |
public LoadInBackGround(FeatureStore store,FeatureType type, String filter, String order,Observer observer){ |
596 |
this.store = store;
|
597 |
this.type = type;
|
598 |
this.filter = filter;
|
599 |
this.order = order;
|
600 |
this.observer = observer;
|
601 |
|
602 |
} |
603 |
|
604 |
public void run() { |
605 |
try{
|
606 |
collection = getDataCollection(type, filter, order); |
607 |
} catch (Exception e) { |
608 |
this.observer.update(this.store, new DefaultFeatureStoreNotification( |
609 |
this.store,
|
610 |
FeatureStoreNotification.LOAD_FINISHED, |
611 |
e) |
612 |
); |
613 |
} |
614 |
this.observer.update(
|
615 |
this.store, new DefaultFeatureStoreNotification( |
616 |
this.store,
|
617 |
FeatureStoreNotification.LOAD_FINISHED, |
618 |
collection) |
619 |
); |
620 |
|
621 |
} |
622 |
|
623 |
|
624 |
} |
625 |
public Feature createFeature(FeatureType type, boolean defaultValues) throws InitializeException { |
626 |
Feature feature; |
627 |
try {
|
628 |
feature = new CreatedFeature(type,defaultValues);
|
629 |
} catch (ReadException e) {
|
630 |
throw new InitializeException(this.getName(),e); |
631 |
} |
632 |
return feature;
|
633 |
} |
634 |
|
635 |
public Feature createDefaultFeature(boolean defaultValues) throws InitializeException{ |
636 |
return this.createFeature(this.getDefaultFeatureType(),defaultValues); |
637 |
} |
638 |
|
639 |
public DataStoreParameters getParameters() {
|
640 |
return parameters;
|
641 |
} |
642 |
|
643 |
protected abstract void doOpen() throws OpenException; |
644 |
|
645 |
protected abstract void doClose() throws CloseException; |
646 |
|
647 |
protected void doDispose() throws CloseException{ |
648 |
this.parameters = null; |
649 |
if (this.selection != null){ |
650 |
this.selection.dispose();
|
651 |
this.selection = null; |
652 |
} |
653 |
this.commands = null; |
654 |
if (this.locked != null){ |
655 |
this.locked.dispose();
|
656 |
this.locked = null; |
657 |
} |
658 |
this.observable=null; |
659 |
this.featureManager = null; |
660 |
this.spatialManager = null; |
661 |
this.attributeManager = null; |
662 |
this.clearResourceObservers();
|
663 |
this.resouceObservers = null; |
664 |
} |
665 |
|
666 |
public final void open() throws OpenException { |
667 |
this.observable.notifyObservers(this, |
668 |
new DefaultFeatureStoreNotification(this,DefaultFeatureStoreNotification.BEFORE_OPEN) |
669 |
); |
670 |
doOpen(); |
671 |
this.observable.notifyObservers(this, |
672 |
new DefaultFeatureStoreNotification(this,DefaultFeatureStoreNotification.AFTER_OPEN) |
673 |
); |
674 |
|
675 |
} |
676 |
|
677 |
public final void close() throws CloseException { |
678 |
this.observable.notifyObservers(this, |
679 |
new DefaultFeatureStoreNotification(this,DefaultFeatureStoreNotification.BEFORE_CLOSE) |
680 |
); |
681 |
doClose(); |
682 |
this.observable.notifyObservers(this, |
683 |
new DefaultFeatureStoreNotification(this,DefaultFeatureStoreNotification.AFTER_CLOSE) |
684 |
); |
685 |
|
686 |
} |
687 |
|
688 |
public final void dispose() throws CloseException{ |
689 |
this.observable.notifyObservers(this, |
690 |
new DefaultFeatureStoreNotification(this,DefaultFeatureStoreNotification.BEFORE_DISPOSE) |
691 |
); |
692 |
doDispose(); |
693 |
} |
694 |
|
695 |
protected abstract void doRefresh() throws OpenException,InitializeException; |
696 |
|
697 |
public final void refresh() throws OpenException,InitializeException{ |
698 |
doRefresh(); |
699 |
} |
700 |
|
701 |
public void notifyResourceChange(){ |
702 |
this.observable.notifyObservers(this, |
703 |
new DefaultFeatureStoreNotification(this,DefaultFeatureStoreNotification.RESOURCE_CHANGED) |
704 |
); |
705 |
|
706 |
} |
707 |
|
708 |
private class ResourceChangedObserver implements Observer{ |
709 |
|
710 |
private AbstractFeatureStore theStore;
|
711 |
|
712 |
public ResourceChangedObserver(AbstractFeatureStore theStore){
|
713 |
this.theStore = theStore;
|
714 |
} |
715 |
|
716 |
/* (non-Javadoc)
|
717 |
* @see org.gvsig.tools.observer.Observer#update(org.gvsig.util.observer.Observable, java.lang.Object)
|
718 |
*/
|
719 |
public void update(Observable observable, Object notification) { |
720 |
if (!(notification instanceof ResourceNotification)){ |
721 |
return;
|
722 |
} |
723 |
if (((ResourceNotification)notification).getStore() == this.theStore){ |
724 |
return;
|
725 |
} |
726 |
|
727 |
if (((ResourceNotification)notification).getType().equals(ResourceNotification.CHANGED)){
|
728 |
this.theStore.notifyResourceChange();
|
729 |
} |
730 |
} |
731 |
|
732 |
} |
733 |
|
734 |
/* (non-Javadoc)
|
735 |
* @see org.gvsig.fmap.data.feature.FeatureStore#getDefaultFeatureType()
|
736 |
*/
|
737 |
public FeatureType getDefaultFeatureType() {
|
738 |
if (isEditing()){
|
739 |
// Aqu? hay que construir un FeatureType con los cambios que se hayan hecho en la edici?n.
|
740 |
return attributeManager.getFeatureType();
|
741 |
} |
742 |
return defaultFeatureType;
|
743 |
} |
744 |
|
745 |
public Feature getFeatureByID(FeatureID id) throws ReadException { |
746 |
return this.getFeatureByID(id, null); |
747 |
} |
748 |
|
749 |
public Object invokeOperation(int code, DataStoreOperationContext context) |
750 |
throws DataStoreOperationException,
|
751 |
DataStoreOperationNotSupportedException { |
752 |
|
753 |
DataManager manager = DataManager.getManager(); |
754 |
return manager.invokeDataStoreOperation(this, code, context); |
755 |
} |
756 |
|
757 |
public Object invokeOperation(String name, DataStoreOperationContext context) |
758 |
throws DataStoreOperationException,
|
759 |
DataStoreOperationNotSupportedException { |
760 |
DataManager manager = DataManager.getManager(); |
761 |
return manager.invokeDataStoreOperation(this, name, context); |
762 |
} |
763 |
|
764 |
public boolean implementsOperation(int code) { |
765 |
DataManager manager = DataManager.getManager(); |
766 |
return manager.implementsDataStoreOperation(this.getName(), code); |
767 |
} |
768 |
|
769 |
public boolean implementsOperation(String name) { |
770 |
DataManager manager = DataManager.getManager(); |
771 |
return manager.implementsDataStoreOperation(this.getName(), name); |
772 |
} |
773 |
|
774 |
private void notifySelectionChange() { |
775 |
this.observable.notifyObservers(this, |
776 |
new DefaultFeatureStoreNotification(this, |
777 |
DefaultFeatureStoreNotification.SELECTION_CHANGE)); |
778 |
|
779 |
} |
780 |
|
781 |
public class SelectionObserver implements Observer { |
782 |
private AbstractFeatureStore store;
|
783 |
|
784 |
public SelectionObserver(AbstractFeatureStore store) {
|
785 |
this.store = store;
|
786 |
} |
787 |
|
788 |
public void update(Observable observable, Object notification) { |
789 |
this.store.notifySelectionChange();
|
790 |
} |
791 |
} |
792 |
|
793 |
/**
|
794 |
* Create a default spatial index. If a filename is provided then the index will be persistent
|
795 |
* (the extension of the resulting index file depends on each implementation).
|
796 |
*
|
797 |
* Convenience method for creating a default spatial index that any AbstractFeatureStore subclass can use
|
798 |
*/
|
799 |
protected void createDefaultSpatialIndex(FeatureType fType, String colName, String filename) throws IndexException { |
800 |
// the column must be a geometry, otherwise throw an exception
|
801 |
FeatureAttributeDescriptor fad = fType.get(colName); |
802 |
if (!fad.getDataType().equals(FeatureAttributeDescriptor.TYPE_GEOMETRY)) {
|
803 |
throw new IllegalArgumentException("Can't create spatial index because " + colName + " is not a GEOMETRY."); |
804 |
} |
805 |
|
806 |
SpatialIndex index = null;
|
807 |
|
808 |
FeatureStore fstore = this;
|
809 |
|
810 |
try {
|
811 |
SpatialIndexFactory factory = SpatialIndexFactory.getFactory(SpatialIndexFactory.Factories.GT2_QUADTREE); |
812 |
|
813 |
SpatialIndexParameters param = new SpatialIndexParameters();
|
814 |
param.setEnvelope((Envelope) fstore.getMetadata().get("extent"));
|
815 |
|
816 |
DataCollection data = getDataCollection(); |
817 |
param.setFeatureCount(data.size()); |
818 |
//param.setFilename(((FileStoreParameters) getParameters()).getFile().getAbsolutePath());
|
819 |
param.setFilename(filename); |
820 |
param.setOverwrite(true);
|
821 |
|
822 |
index = factory.createSpatialIndex(param); |
823 |
|
824 |
Iterator it = data.iterator();
|
825 |
|
826 |
int i=0; |
827 |
while (it.hasNext()) {
|
828 |
Feature feat = (Feature) it.next(); |
829 |
Geometry geom = (Geometry) feat.get(colName); |
830 |
index.insert(geom.getEnvelope(), feat.getID()); |
831 |
} |
832 |
|
833 |
indexStore.addIndex(fType, colName, index); |
834 |
|
835 |
if (index instanceof PersistentSpatialIndex) { |
836 |
((PersistentSpatialIndex)index).flush(); |
837 |
} |
838 |
|
839 |
} catch (IllegalAccessException e) { |
840 |
throw new IndexException(e); |
841 |
} catch (InstantiationException e) { |
842 |
throw new IndexException(e); |
843 |
} catch (ReadException e) {
|
844 |
throw new IndexException(e); |
845 |
} catch (BaseException e) {
|
846 |
throw new IndexException(e); |
847 |
} |
848 |
} |
849 |
|
850 |
public boolean hasIndex(FeatureType fType, String colName) { |
851 |
return indexStore.contains(fType, colName);
|
852 |
} |
853 |
|
854 |
public FeatureAttributeDescriptor addEvaluatedAttribute(
|
855 |
FeatureType featureType, String attributeName,
|
856 |
String attributeType, String expression, |
857 |
AttributeValueEvaluator evaluator) throws ReadException {
|
858 |
if (featureType == null) { |
859 |
featureType = this.getDefaultFeatureType();
|
860 |
} else {
|
861 |
List types = this.getFeatureTypes(); |
862 |
if (!types.contains(featureType)) {
|
863 |
throw new ReadException("Incompatible feature type", this |
864 |
.getName()); |
865 |
} |
866 |
} |
867 |
|
868 |
if (evaluator == null) { |
869 |
evaluator = DataManager.getManager().getExpressionParser() |
870 |
.newAttributeValueEvaluator(); |
871 |
} |
872 |
|
873 |
AttributeDescriptor attr = (AttributeDescriptor) featureType |
874 |
.createNewAttributeDescriptor(); |
875 |
attr.loading(); |
876 |
try {
|
877 |
attr.setEvalued(true);
|
878 |
attr.setName(attributeName); |
879 |
attr.setType(attributeType); |
880 |
attr.setExpression(expression); |
881 |
attr.setEvaluator(evaluator); |
882 |
} catch (IsNotAttributeSettingException e) {
|
883 |
throw new ReadException(this.getName(), e); |
884 |
} |
885 |
featureType.add(attr); |
886 |
|
887 |
return attr;
|
888 |
} |
889 |
|
890 |
public void removeEvaluatedAttribute(FeatureAttributeDescriptor attibute) |
891 |
throws DataException {
|
892 |
// TODO Auto-generated method stub
|
893 |
|
894 |
} |
895 |
|
896 |
|
897 |
public String getClassName() { |
898 |
return this.getClass().getName(); |
899 |
} |
900 |
|
901 |
protected FeatureType checkFeatureTypeForCollection(FeatureType fType)
|
902 |
throws DataException {
|
903 |
FeatureType defType = this.getDefaultFeatureType();
|
904 |
if (fType == null || fType.equals(defType)) { |
905 |
//TODO we must return a copy of Ftype but there are probles with
|
906 |
// weakRefs of Ftype of Attributes in edition mode
|
907 |
// return defType.getSubFeatureType(null);
|
908 |
return defType;
|
909 |
} |
910 |
if (fType.isSubtypeOf(defType)) {
|
911 |
return fType;
|
912 |
} |
913 |
Iterator iter = this.getFeatureTypes().iterator(); |
914 |
FeatureType tmpType; |
915 |
while (iter.hasNext()) {
|
916 |
tmpType = (FeatureType) iter.next(); |
917 |
if (fType.isSubtypeOf(tmpType)) {
|
918 |
return fType;
|
919 |
} |
920 |
|
921 |
} |
922 |
throw new ReadException("invalid type", this.getName()); |
923 |
} |
924 |
} |