Statistics
| Revision:

root / trunk / libraries / libFMap_data / src / org / gvsig / data / vectorial / FeatureStore.java @ 20898

History | View | Annotate | Download (18.3 KB)

1
package org.gvsig.data.vectorial;
2

    
3
import java.lang.ref.Reference;
4
import java.util.ArrayList;
5
import java.util.Iterator;
6

    
7
import org.gvsig.data.IDataCollection;
8
import org.gvsig.data.IDataStoreParameters;
9
import org.gvsig.data.IResourceNotification;
10
import org.gvsig.data.Resource;
11
import org.gvsig.data.commands.ICommand;
12
import org.gvsig.data.commands.ICommandsRecord;
13
import org.gvsig.data.commands.implementation.FeatureCommandsRecord;
14
import org.gvsig.data.exception.CloseException;
15
import org.gvsig.data.exception.DataException;
16
import org.gvsig.data.exception.InitializeException;
17
import org.gvsig.data.exception.OpenException;
18
import org.gvsig.data.exception.ReadException;
19
import org.gvsig.data.exception.WriteException;
20
import org.gvsig.data.vectorial.expansionadapter.IExpansionAdapter;
21
import org.gvsig.data.vectorial.expansionadapter.MemoryExpansionAdapter;
22
import org.gvsig.util.observer.ComplexNotification;
23
import org.gvsig.util.observer.IObservable;
24
import org.gvsig.util.observer.IObserver;
25
import org.gvsig.util.observer.Observable;
26

    
27

    
28
public abstract class FeatureStore implements IFeatureStore {
29

    
30
        protected IDataStoreParameters parameters;
31
        protected IDataCollection selection;
32
        protected ICommandsRecord commands;
33
        protected boolean alterMode = false;
34
//        protected ComplexObservable observable=new ComplexObservable();
35
        protected IDataCollection locked;
36
        protected Observable observable=new Observable();
37
        protected FeatureManager featureManager;
38
        protected SpatialManager spatialManager;
39
        protected AttributeManager attributeManager;
40
        protected ArrayList resouceObservers = new ArrayList();
41
        protected IFeatureType defaultFeatureType = null;
42

    
43

    
44
        public void init(IDataStoreParameters parameters) throws InitializeException {
45
                this.parameters = parameters;
46
        }
47

    
48
        public void init(IDataStoreParameters parameters,Resource resource) throws InitializeException {
49
                this.parameters = parameters;
50
                this.observeResource(resource);
51
        }
52

    
53
        protected final void observeResource(Resource resource){
54
                ResourceChangedObserver observer=new ResourceChangedObserver(this);
55
                resource.addObserver(observer);
56
                this.resouceObservers.add(observer);
57
        }
58

    
59
        protected void initSpatialManager(){
60
                spatialManager=new SpatialManager();
61
        }
62

    
63
        protected void initAttributeManager() {
64
                IExpansionAdapter expansionAttributeAdapter=new MemoryExpansionAdapter();
65
                attributeManager=new AttributeManager(expansionAttributeAdapter,getDefaultFeatureType());
66

    
67
        }
68

    
69
        protected void initExpansionManager() {
70
                IExpansionAdapter expansionFeatureAdapter=new MemoryExpansionAdapter();
71
                featureManager=new FeatureManager(expansionFeatureAdapter);
72
        }
73

    
74
        public IDataCollection getDataCollection() throws ReadException {
75
                return getDataCollection(null, null, null);
76
        }
77

    
78
        public void getDataCollection(IObserver observer) {
79
                getDataCollection(null, null, null,observer);
80
        }
81

    
82
        public final void setSelection(IDataCollection selection) {
83
                this.observable.notifyObservers(this,
84
                                new FeatureStoreNotification(this,FeatureStoreNotification.BEFORE_SELECTIONCHANGE)
85
                        );
86
                doSelection(selection);
87
                this.observable.notifyObservers(this,
88
                                new FeatureStoreNotification(this,FeatureStoreNotification.AFTER_SELECTIONCHANGE)
89
                        );
90

    
91
        }
92

    
93
        protected void doSelection(IDataCollection selection) {
94
                this.selection = selection;
95
        }
96

    
97
        public IDataCollection createSelection() {
98

    
99
                MemoryFeatureCollection selection = new MemoryFeatureCollection();
100
                return selection;
101
        }
102

    
103
        public IDataCollection getSelection() {
104
                if( selection == null ){
105
                        selection = createSelection();
106
                }
107
                return selection;
108
        }
109

    
110
        public IDataCollection createLocked() {
111
                MemoryFeatureCollection locked = new MemoryFeatureCollection();
112
                return locked;
113
        }
114

    
115
        public IDataCollection getLocked() {
116
                if( locked == null ){
117
                        locked = createLocked();
118
                }
119
                return locked;
120
        }
121

    
122
        public final void setLocked(IDataCollection locked) {
123
                this.observable.notifyObservers(this,
124
                                new FeatureStoreNotification(this,FeatureStoreNotification.BEFORE_LOCKEDCHANGE)
125
                        );
126
                doLocked(locked);
127
                this.observable.notifyObservers(this,
128
                                new FeatureStoreNotification(this,FeatureStoreNotification.AFTER_LOCKEDCHANGE)
129
                        );
130

    
131
        }
132
        protected void doLocked(IDataCollection locked) {
133
                this.locked = locked;
134

    
135
        }
136

    
137
        public boolean isLocked(IFeatureID id) {
138
        return locked.contains(id);
139
    }
140

    
141
    public final boolean lock(IFeatureID id) {
142
            this.observable.notifyObservers(this,
143
                                new FeatureStoreNotification(this,FeatureStoreNotification.BEFORE_LOCKEDCHANGE)
144
                        );
145
                doLock(id);
146
            this.observable.notifyObservers(this,
147
                                new FeatureStoreNotification(this,FeatureStoreNotification.AFTER_LOCKEDCHANGE)
148
                        );
149
                return true;
150
    }
151

    
152

    
153
        protected void doLock(IFeatureID id) {
154
                locked.add(id);
155
        }
156

    
157
        public final void startEditing() throws ReadException {
158
                if (!this.isEditable()) {
159
                        throw new ReadException("AbstractFeatureStore",
160
                                        new UnsupportedOperationException("Not editable"));
161
                }
162
                this.observable.notifyObservers(this,
163
                                new FeatureStoreNotification(this,FeatureStoreNotification.BEFORE_STARTEDITING)
164
                        );
165
                doStartEditing();
166
                this.observable.notifyObservers(this,
167
                                new FeatureStoreNotification(this,FeatureStoreNotification.AFTER_STARTEDITING)
168
                        );
169

    
170
        }
171

    
172

    
173
        protected void doStartEditing() {
174
//                commands.clear();
175
                initExpansionManager();
176
                initSpatialManager();
177
                initAttributeManager();
178
                commands = new FeatureCommandsRecord(featureManager, spatialManager, attributeManager);
179

    
180

    
181
                alterMode = true;
182
        }
183

    
184
        public final void delete(IFeatureAttributeDescriptor attributeDescriptor) {
185
                //FIXME Comporobar que el attribute viene del Fype de este store
186
                if( !alterMode ) {
187
                        throw new RuntimeException("alterMode is false");
188
                }
189
                this.observable.notifyObservers(this,
190
                                new AttributeStoreNotification(this,AttributeStoreNotification.BEFORE_DELETE_ATTRIBUTE,attributeDescriptor)
191
                        );
192
                doDelete(attributeDescriptor);
193
                this.observable.notifyObservers(this,
194
                                new AttributeStoreNotification(this,AttributeStoreNotification.AFTER_DELETE_ATTRIBUTE,attributeDescriptor)
195
                        );
196

    
197

    
198
        }
199

    
200
        protected void doDelete(IFeatureAttributeDescriptor attributeDescriptor) {
201
                commands.delete(attributeDescriptor);
202

    
203
        }
204

    
205
        public final void insert(IFeatureAttributeDescriptor attributeDescriptor) throws DataException {
206
                if( !alterMode ) {
207
                        throw new DataException("alterMode is false");
208
                }
209
                if (!((AttributeDescriptor)attributeDescriptor).isNew()){
210
                        throw new DataException("attribute is not new");
211
                }
212
                this.observable.notifyObservers(this,
213
                                new AttributeStoreNotification(this,AttributeStoreNotification.BEFORE_INSERT_ATTRIBUTE,attributeDescriptor)
214
                        );
215
                doInsert(attributeDescriptor);
216
                this.observable.notifyObservers(this,
217
                                new AttributeStoreNotification(this,FeatureStoreNotification.AFTER_INSERT,attributeDescriptor)
218
                        );
219

    
220
        }
221

    
222
        protected void doInsert(IFeatureAttributeDescriptor attributeDescriptor) {
223
                ((AttributeDescriptor)attributeDescriptor).stopEditing();
224
                commands.insert(attributeDescriptor);
225
        }
226

    
227
        public final void update(IFeatureAttributeDescriptor attributeDescriptor) {
228
                //FIXME Comporobar que el attribute viene del Fype de este store
229
                if( !alterMode ) {
230
                        throw new RuntimeException("alterMode is false");
231
                }
232
                this.observable.notifyObservers(this,
233
                                new AttributeStoreNotification(this,AttributeStoreNotification.BEFORE_UPDATE_ATTRIBUTE,attributeDescriptor)
234
                        );
235
                doUpdate(attributeDescriptor);
236
                this.observable.notifyObservers(this,
237
                                new AttributeStoreNotification(this,AttributeStoreNotification.AFTER_UPDATE_ATTRIBUTE,attributeDescriptor)
238
                        );
239
        }
240

    
241

    
242
        protected void doUpdate(IFeatureAttributeDescriptor attributeDescriptor) {
243
                commands.update(((AttributeDescriptor)attributeDescriptor).getNewAttributeDescriptor(),attributeDescriptor);
244
                ((AttributeDescriptor)attributeDescriptor).stopEditing();
245
        }
246

    
247
        public final void delete(IFeature feature) {
248
                if( !alterMode ) {
249
                        throw new RuntimeException("alterMode is false");
250
                }
251
                this.observable.notifyObservers(this,
252
                                new FeatureStoreNotification(this,FeatureStoreNotification.BEFORE_DELETE,feature)
253
                        );
254
                doDelete(feature);
255
                this.observable.notifyObservers(this,
256
                                new FeatureStoreNotification(this,FeatureStoreNotification.AFTER_DELETE,feature)
257
                        );
258

    
259

    
260
        }
261

    
262
        protected void doDelete(IFeature feature) {
263
                commands.delete(feature);
264
        }
265

    
266
        public final void insert(IFeature feature) {
267
                if( !alterMode ) {
268
                        throw new RuntimeException("alterMode is false");
269
                }
270
                // FIXME: Comprobar que la feature es de este store
271
                feature.validateModification(this);
272
                this.observable.notifyObservers(this,
273
                                new FeatureStoreNotification(this,FeatureStoreNotification.BEFORE_INSERT,feature)
274
                        );
275
        doInsert(feature);
276
                this.observable.notifyObservers(this,
277
                                new FeatureStoreNotification(this,FeatureStoreNotification.AFTER_INSERT,feature)
278
                        );
279

    
280
        }
281

    
282
        protected void doInsert(IFeature feature) {
283
                commands.insert(((Feature)feature).getNewFeature());
284
        }
285

    
286
        public final void update(IFeature feature) {
287
                if( !alterMode ) {
288
                        throw new RuntimeException("alterMode is false");
289
                }
290
                //        FIXME: Comprobar que la feature es de este store
291
                feature.validateModification(this);
292
                this.observable.notifyObservers(this,
293
                                new FeatureStoreNotification(this,FeatureStoreNotification.BEFORE_UPDATE,feature)
294
                        );
295
                doUpdate(feature);
296
                this.observable.notifyObservers(this,
297
                                new FeatureStoreNotification(this,FeatureStoreNotification.AFTER_UPDATE,feature)
298
                        );
299
        }
300

    
301
        protected void doUpdate(IFeature feature) {
302
                feature.validateModification(this);
303
                Feature oldFeature = (Feature)feature;
304
                IFeature newFeature=oldFeature.getNewFeature();
305
                oldFeature.stopEditing();
306
                commands.update(newFeature,oldFeature);
307
        }
308

    
309
        public final void redo() {
310
                if( !alterMode ) {
311
                        throw new RuntimeException("alterMode is false");
312
                }
313
                ICommand redo = commands.getNextRedoCommand();
314
                this.observable.notifyObservers(this,
315
                        new FeatureStoreNotification(this,FeatureStoreNotification.BEFORE_REDO,redo)
316
                );
317

    
318
                doRedo();
319

    
320
                this.observable.notifyObservers(this,
321
                                new FeatureStoreNotification(this,FeatureStoreNotification.AFTER_REDO,redo)
322
                        );
323

    
324
        }
325

    
326

    
327
        protected void doRedo() {
328
                commands.redo();
329
        }
330

    
331
        public final void undo() {
332
                if( !alterMode ) {
333
                        throw new RuntimeException("alterMode is false");
334
                }
335
                ICommand undo = commands.getNextUndoCommand();
336
                this.observable.notifyObservers(this,
337
                        new FeatureStoreNotification(this,FeatureStoreNotification.BEFORE_UNDO,undo)
338
                );
339
                doUndo();
340

    
341
                this.observable.notifyObservers(this,
342
                                new FeatureStoreNotification(this,FeatureStoreNotification.AFTER_UNDO,undo)
343
                        );
344

    
345
        }
346

    
347
        protected void doUndo() {
348
                commands.undo();
349

    
350
        }
351

    
352
        public ICommandsRecord getCommandsRecord() {
353
                if( !alterMode ) {
354
                        throw new RuntimeException("alterMode is false");
355
                }
356
                return commands;
357
        }
358

    
359
        protected void doCancelEditing(){
360
                commands.clear();
361
        }
362

    
363
        public final void cancelEditing() {
364
                if( !alterMode ) {
365
                        throw new RuntimeException("alterMode is false");
366
                }
367
                this.observable.notifyObservers(this,
368
                        new FeatureStoreNotification(this,FeatureStoreNotification.BEFORE_CANCELEDITING)
369
                );
370

    
371
                doCancelEditing();
372
                alterMode = false;
373
                this.observable.notifyObservers(this,
374
                        new FeatureStoreNotification(this,FeatureStoreNotification.AFTER_CANCELEDITING)
375
                );
376

    
377
        }
378

    
379
        public final void finishEditing() throws WriteException, ReadException{
380
                if( !alterMode ) {
381
                        //FIXME: OJO arreglar esta excepci?n!!!
382
                        throw new RuntimeException("alterMode is false");
383
                }
384

    
385
                this.observable.notifyObservers(this,
386
                        new FeatureStoreNotification(this,FeatureStoreNotification.BEFORE_FINISHEDITING)
387
                );
388

    
389
                this.validateEndEditing();
390

    
391
                doFinishEdition();
392

    
393

    
394
                commands.clear();
395
                featureManager=null;
396
                spatialManager=null;
397
                attributeManager=null;
398
                commands = null;
399

    
400
                alterMode = false;
401

    
402
                this.observable.notifyObservers(this,
403
                        new FeatureStoreNotification(this,FeatureStoreNotification.AFTER_FINISHEDITING)
404
                );
405

    
406
        }
407

    
408
        protected abstract void doFinishEdition() throws WriteException, ReadException ;
409

    
410

    
411
        public Iterator getChilds() {
412
                return null;
413
        }
414

    
415
        public void beginComplexNotification() {
416
                this.observable.beginComplexNotification(new ComplexNotification());
417

    
418
        }
419

    
420
        public void endComplexNotification() {
421
                this.observable.endComplexNotification(this);
422

    
423
        }
424

    
425
        public void addObserver(IObserver o) {
426
                this.observable.addObserver(o);
427

    
428
        }
429

    
430
        public void addObserver(Reference ref) {
431
                this.observable.addObserver(ref);
432
        }
433

    
434
        public void deleteObserver(IObserver o) {
435
                this.observable.deleteObserver(o);
436
        }
437

    
438
        public void deleteObserver(Reference ref) {
439
                this.observable.deleteObserver(ref);
440
        }
441

    
442
        public void deleteObservers() {
443
                this.observable.deleteObservers();
444

    
445
        }
446

    
447
        public boolean isEditing() {
448
                return alterMode;
449
        }
450

    
451
        protected void validateEndEditing() throws ReadException{
452
                IFeatureCollection collection = (IFeatureCollection)this.getDataCollection();
453
                Iterator iter = collection.iterator();
454
                while (iter.hasNext()){
455
                        ((IFeature)iter.next()).validateEnd(this);
456
                }
457

    
458
        }
459

    
460
        public void disableNotifications() {
461
                this.observable.diableNotifications();
462

    
463
        }
464

    
465
        public void enableNotifications() {
466
                this.observable.enableNotifications();
467
        }
468
        public void getDataCollection(IFeatureType type, String filter, String order,IObserver observer) {
469
            LoadInBackGround task = new LoadInBackGround(this,type,filter,order,observer);
470
            Thread thread = new Thread(task);
471
            thread.run();
472
    }
473
         private class LoadInBackGround implements Runnable{
474

    
475
                    private IFeatureStore store;
476
                    private IFeatureType type;
477
                    private String filter;
478
                    private String order;
479

    
480
                    private IObserver observer;
481

    
482
                        public IDataCollection collection = null;
483
                    public LoadInBackGround(IFeatureStore store,IFeatureType type, String filter, String order,IObserver observer){
484
                            this.store = store;
485
                            this.type = type;
486
                            this.filter = filter;
487
                            this.order = order;
488
                            this.observer = observer;
489

    
490
                    }
491

    
492
                        public void run() {
493
                                try{
494
                                        collection = getDataCollection(type, filter, order);
495
                                } catch (Exception e) {
496
                                        this.observer.update(this.store, new FeatureStoreNotification(
497
                                                                        this.store,
498
                                                                        IFeatureStoreNotification.LOAD_FINISHED,
499
                                                                        e)
500
                                                        );
501
                                }
502
                                this.observer.update(
503
                                                this.store, new FeatureStoreNotification(
504
                                                                        this.store,
505
                                                                        IFeatureStoreNotification.LOAD_FINISHED,
506
                                                                        collection)
507
                                                );
508

    
509
                        }
510

    
511

    
512
            }
513
         public IFeature createFeature(IFeatureType type) throws InitializeException {
514
                return this.createDefaultFeature(true);
515
         }
516

    
517
         public IFeature createDefaultFeature(boolean defaultValues) throws InitializeException{
518
                 IFeature feature;
519
                try {
520
                        feature = new CreatedFeature(getDefaultFeatureType(),defaultValues);
521
                } catch (ReadException e) {
522
                        throw new InitializeException(this.getName(),e);
523
                }
524
                 return feature;
525
         }
526

    
527
        public IDataStoreParameters getParameters() {
528
                return parameters;
529
        }
530

    
531
        protected abstract void doOpen() throws OpenException;
532

    
533
        protected abstract void doClose() throws CloseException;
534

    
535
        protected void doDispose() throws CloseException{
536
                this.parameters = null;
537
                if (this.selection != null){
538
                        this.selection.dispose();
539
                        this.selection = null;
540
                }
541
                this.commands = null;
542
                if (this.locked != null){
543
                        this.locked.dispose();
544
                        this.locked = null;
545
                }
546
                this.observable=null;
547
                this.featureManager = null;
548
                this.spatialManager = null;
549
                this.attributeManager = null;
550
                this.resouceObservers.clear();
551
                this.resouceObservers = null;
552
        }
553

    
554
        public final void open() throws OpenException {
555
                this.observable.notifyObservers(this,
556
                                new FeatureStoreNotification(this,FeatureStoreNotification.BEFORE_OPEN)
557
                );
558
                doOpen();
559
                this.observable.notifyObservers(this,
560
                                new FeatureStoreNotification(this,FeatureStoreNotification.AFTER_OPEN)
561
                );
562

    
563
        }
564

    
565
        public final void close() throws CloseException {
566
                this.observable.notifyObservers(this,
567
                new FeatureStoreNotification(this,FeatureStoreNotification.BEFORE_CLOSE)
568
            );
569
                doClose();
570
        this.observable.notifyObservers(this,
571
                new FeatureStoreNotification(this,FeatureStoreNotification.AFTER_CLOSE)
572
            );
573

    
574
        }
575

    
576
        public final void dispose() throws CloseException{
577
                this.observable.notifyObservers(this,
578
                new FeatureStoreNotification(this,FeatureStoreNotification.BEFORE_DISPOSE)
579
            );
580
        doDispose();
581
        }
582

    
583
        protected abstract void doRefresh() throws OpenException,InitializeException;
584

    
585
        public final void refresh() throws OpenException,InitializeException{
586
        doRefresh();
587
        }
588

    
589
        private void notifyResourceChange(){
590
        this.observable.notifyObservers(this,
591
                new FeatureStoreNotification(this,FeatureStoreNotification.RESOURCE_CHANGED)
592
            );
593

    
594
        }
595

    
596
        private class ResourceChangedObserver implements IObserver{
597

    
598
                private FeatureStore theStore;
599

    
600
                public ResourceChangedObserver(FeatureStore theStore){
601
                        this.theStore = theStore;
602
                }
603

    
604
                /* (non-Javadoc)
605
                 * @see org.gvsig.util.observer.IObserver#update(org.gvsig.util.observer.IObservable, java.lang.Object)
606
                 */
607
                public void update(IObservable observable, Object notification) {
608
                        if (!(notification instanceof IResourceNotification)){
609
                                return;
610
                        }
611
                        if (((IResourceNotification)notification).getStore() == this.theStore){
612
                                return;
613
                        }
614

    
615
                        if (((IResourceNotification)notification).getType().equals(IResourceNotification.CHANGED)){
616
                                this.theStore.notifyResourceChange();
617
                        }
618
                }
619

    
620
        }
621

    
622
        /* (non-Javadoc)
623
         * @see org.gvsig.data.vectorial.IFeatureStore#getDefaultFeatureType()
624
         */
625
        public IFeatureType getDefaultFeatureType() {
626
                if (isEditing()){
627
//                    Aqu? hay que construir un FeatureType con los cambios que se hayan hecho en la edici?n.
628
                    return attributeManager.getFeatureType();
629
            }
630
        return defaultFeatureType;
631
        }
632

    
633
        /* (non-Javadoc)
634
         * @see org.gvsig.data.vectorial.IFeatureStore#createAttributeDescriptor()
635
         */
636
        public IFeatureAttributeDescriptor createAttributeDescriptor() {
637
                // FIXME Hay que identificar de que FType queremos crear el attributo
638
                // FIXME el Attribute lo deber?a de crea el FType
639
                return new AttributeDescriptor(true);
640
        }
641
}