Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / edition / EditableAdapter.java @ 5886

History | View | Annotate | Download (28.7 KB)

1
package com.iver.cit.gvsig.fmap.edition;
2

    
3
import java.io.IOException;
4
import java.util.ArrayList;
5
import java.util.HashMap;
6

    
7
import com.hardcode.driverManager.Driver;
8
import com.hardcode.driverManager.DriverLoadException;
9
import com.hardcode.gdbms.engine.data.DataSourceFactory;
10
import com.hardcode.gdbms.engine.data.NoSuchTableException;
11
import com.hardcode.gdbms.engine.data.driver.DriverException;
12
import com.hardcode.gdbms.engine.data.driver.ObjectDriver;
13
import com.hardcode.gdbms.engine.data.edition.DataWare;
14
import com.hardcode.gdbms.engine.values.Value;
15
import com.iver.cit.gvsig.fmap.MapControl.CancelDraw;
16
import com.iver.cit.gvsig.fmap.core.DefaultRow;
17
import com.iver.cit.gvsig.fmap.core.IRow;
18
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
19
import com.iver.cit.gvsig.fmap.drivers.ITableDefinition;
20
import com.iver.cit.gvsig.fmap.drivers.TableDefinition;
21
import com.iver.cit.gvsig.fmap.edition.commands.AddRowCommand;
22
import com.iver.cit.gvsig.fmap.edition.commands.Command;
23
import com.iver.cit.gvsig.fmap.edition.commands.CommandCollection;
24
import com.iver.cit.gvsig.fmap.edition.commands.CommandRecord;
25
import com.iver.cit.gvsig.fmap.edition.commands.MemoryCommandRecord;
26
import com.iver.cit.gvsig.fmap.edition.commands.ModifyRowCommand;
27
import com.iver.cit.gvsig.fmap.edition.commands.RemoveRowCommand;
28
import com.iver.cit.gvsig.fmap.edition.rules.IRule;
29
import com.iver.cit.gvsig.fmap.layers.FBitSet;
30
import com.iver.cit.gvsig.fmap.layers.LayerFactory;
31
import com.iver.cit.gvsig.fmap.layers.SelectableDataSource;
32
import com.iver.cit.gvsig.fmap.operations.Cancel;
33

    
34
/**
35
 * DOCUMENT ME!
36
 *
37
 * @author Vicente Caballero Navarro
38
 */
39
public class EditableAdapter implements IEditableSource, IWriteable {
40
        protected boolean isEditing = false;
41

    
42
        private SelectableDataSource ds = null;
43

    
44
        protected FBitSet delRows = new FBitSet();
45

    
46
        private CommandRecord cr;
47
        protected IWriter writer;
48

    
49
        /**
50
         * Flag que indica que hay que tomar las siguientes operaciones como una
51
         * operaci?n at?mica
52
         */
53
        private boolean complex = false;
54

    
55
        private CommandCollection commands = null;
56

    
57
        /*
58
         * Establece una relaci?n entre los ?ndices de las geometr?as en el
59
         * EditableFeatureSource y los ?ndices en el fichero de expansi?n FJP:
60
         * CAMBIO: NECESITAMOS TRABAJAR CON FEATURE Y FEATUREITERATOR PARA IR
61
         * PREPARANDO EL CAMINO, GUARDAMOS EL FEATUREID (STRING) COMO CLAVE, Y COMO
62
         * VALOR, EL INDICE DENTRO DEL FICHERO DE EXPANSION (Integer). Lo de que
63
         * FeatureId sea un String es por compatibilidad con OGC. Seg?n OGC, una
64
         * Feature tiene que tener un Id string En el caso de los randomaccess,
65
         * ser?n el id de registro En los casos de base de datos espaciales, supongo
66
         * que siempre ser? num?rico tambi?n, pero lo tendremos que convertir a
67
         * string. Lo que est? claro es que NO se puede confiar nunca en que sea
68
         * algo correlativo (1, 2, 3, 4, 5, ... => FALSO!!)
69
         */
70
        protected HashMap relations = new HashMap();
71

    
72
        /*
73
         * Fichero en el que se guardan las nuevas geometr?as, producto de adiciones
74
         * o de modificaciones
75
         */
76
        protected ExpansionFile expansionFile;
77

    
78
        protected int numAdd = 0;
79

    
80
        private ObjectDriver editingDriver = new myObjectDriver();
81

    
82
        private SelectableDataSource ods;
83

    
84
        private ArrayList editionListeners = new ArrayList();
85

    
86
        private ArrayList rules = new ArrayList();
87

    
88
        /**
89
         * Crea un nuevo EditableAdapter.
90
         */
91
        public EditableAdapter() {
92
                expansionFile = new MemoryExpansionFile();
93
                cr = new MemoryCommandRecord();
94
        }
95

    
96
        /**
97
         * DOCUMENT ME!
98
         *
99
         * @param ds
100
         *            DOCUMENT ME!
101
         */
102
        public void setOriginalDataSource(SelectableDataSource ds) {
103
                this.ods = ds;
104
        }
105

    
106
        /**
107
         * DOCUMENT ME!
108
         *
109
         * @throws EditionException
110
         *             DOCUMENT ME!
111
         */
112
        public void startEdition(int sourceType) throws EditionException {
113
                isEditing = true;
114
                // Obtenemos el driver y vemos si implementa IWriter.
115
                /* DataWare dataWare = ods.getDataWare(DataSourceFactory.DATA_WARE_DIRECT_MODE);
116
                dataWare.get */
117
                Driver drv = ods.getDriver();
118
                if (drv instanceof IWriteable)
119
                {
120
                        setWriter(((IWriteable) drv).getWriter());
121
                }
122
                
123
                fireStartEditionEvent(sourceType);
124
        }
125

    
126

    
127
        /**
128
         * Se ejecuta preProcess() del IWriter, luego se itera por los registros
129
         * borrados por si el IWriter los quiere borrar (solo ser? necesario cuando
130
         * escribimos sobre la misma tabla) y luego se itera por los nuevos
131
         * registros llamando a process con el registro correcto. (A?adidos,
132
         * modificados). Para finalizar, se ejecuta PostProcess
133
         *
134
         * @param writer
135
         *            IWriter que recibir? las llamadas.
136
         *
137
         * @throws EditionException
138
         *             DOCUMENT ME!
139
         */
140
        public void stopEdition(IWriter writer, int sourceType) throws EditionException {
141

    
142
                writer.preProcess();
143

    
144
                try {
145

    
146
                        // Procesamos primero los borrados.
147
                        // Cuando se genere un tema nuevo, no se les debe hacer caso
148
                        // a estos registros
149

    
150
                        for (int i = delRows.nextSetBit(0); i >= 0; i = delRows
151
                                        .nextSetBit(i + 1)) {
152
                                int calculatedIndex = i;
153
                                Integer integer = new Integer(calculatedIndex);
154
                                // Si no est? en el fichero de expansi?n, es de los originales
155
                                // y hay que borrarlo
156
                                DefaultRowEdited edRow = null;
157
                                if (!relations.containsKey(integer)) {
158
                                        edRow = new DefaultRowEdited(new DefaultRow(ods
159
                                                        .getRow(calculatedIndex)),
160
                                                        DefaultRowEdited.STATUS_DELETED, calculatedIndex);
161
                                        writer.process(edRow);
162
                                } else {
163
                                        int num = ((Integer) relations.get(integer)).intValue();
164

    
165
                                        // return expansionFile.getRow(num);
166
                                        IRowEdited rowFromExpansion = expansionFile.getRow(num);
167
                                        // ?Habr?a que hacer aqu? setID(index + "")?
168
                                        edRow = new DefaultRowEdited(rowFromExpansion
169
                                                        .getLinkedRow().cloneRow(), DefaultRowEdited.STATUS_DELETED
170
                                                        , calculatedIndex);
171
                                        writer.process(edRow);
172
                                }
173

    
174
                        }
175

    
176
                        int rowCount = getRowCount();
177
                        for (int i = 0; i < rowCount; i++) {
178
                                IRowEdited rowEdited = getRow(i);
179

    
180
                                if (rowEdited != null) {
181
                                        writer.process(rowEdited);
182
                                }
183
                        }
184
                        writer.postProcess();
185
                        isEditing = false;
186
                        ods.stop();
187
                        ods.start();
188
                        
189
                } catch (DriverIOException e) {
190
                        e.printStackTrace();
191
                        throw new EditionException(e);
192
                } catch (IOException e) {
193
                        e.printStackTrace();
194
                        throw new EditionException(e);
195
                } catch (DriverException e) {
196
                        e.printStackTrace();
197
                        throw new EditionException(e);
198
                }
199

    
200
                fireStopEditionEvent(sourceType);
201
        }
202

    
203
        /**
204
         * DOCUMENT ME!
205
         *
206
         * @throws IOException
207
         *             DOCUMENT ME!
208
         */
209
        public void cancelEdition(int sourceType) throws IOException {
210
                isEditing = false;
211
                expansionFile.close();
212
                fireCancelEditionEvent(sourceType);
213
        }
214

    
215
        /*
216
         * (non-Javadoc)
217
         *
218
         * @see com.iver.cit.gvsig.fmap.edition.IEditableSource#getRow(int)
219
         */
220
        public IRowEdited getRow(int index) throws DriverIOException, IOException {
221
                int calculatedIndex = getCalculatedIndex(index);
222
                Integer integer = new Integer(calculatedIndex);
223
                DefaultRowEdited edRow = null;
224
                // Si no est? en el fichero de expansi?n
225
                if (!relations.containsKey(integer)) {
226
                        try {
227
                                /*
228
                                 * edRow = new DefaultRowEdited(new
229
                                 * DefaultRow(ods.getRow(calculatedIndex), "" + index),
230
                                 * DefaultRowEdited.STATUS_ORIGINAL, index);
231
                                 */
232
                                edRow = new DefaultRowEdited(new DefaultRow(ods
233
                                                .getRow(calculatedIndex)),
234
                                                DefaultRowEdited.STATUS_ORIGINAL, index);
235
                        } catch (DriverException e) {
236
                                throw new DriverIOException(e);
237
                        }
238

    
239
                        return edRow;
240
                } else {
241
                        int num = ((Integer) relations.get(integer)).intValue();
242

    
243
                        // return expansionFile.getRow(num);
244
                        IRowEdited rowFromExpansion = expansionFile.getRow(num);
245
                        // ?Habr?a que hacer aqu? setID(index + "")?
246
                        edRow = new DefaultRowEdited(rowFromExpansion.getLinkedRow()
247
                                        .cloneRow(), rowFromExpansion.getStatus(), index);
248
                        return edRow;
249
                }
250
        }
251

    
252
        /**
253
         * DOCUMENT ME!
254
         *
255
         * @return DOCUMENT ME!
256
         *
257
         * @throws DriverIOException
258
         *             DOCUMENT ME!
259
         * @throws IOException
260
         *             DOCUMENT ME!
261
         */
262
        public int getRowCount() throws DriverIOException, IOException {
263
                try {
264
                        return (int) (ods.getRowCount() + numAdd) - delRows.cardinality();// -
265
                                                                                                                                                                // expansionFile.getInvalidRows().cardinality();
266
                } catch (DriverException e) {
267
                        throw new DriverIOException(e);
268
                }
269

    
270
        }
271

    
272
        /* (non-Javadoc)
273
         * @see com.iver.cit.gvsig.fmap.edition.IEditableSource#addRow(com.iver.cit.gvsig.fmap.core.IRow, java.lang.String)
274
         */
275
        public int addRow(IRow row, String descrip, int sourceType) throws DriverIOException,
276
                        IOException {
277
                
278
                boolean bIsValid = validateRow(row);
279
                if (bIsValid == false)
280
                {
281
                        throw new IOException("Invalid row: Doesn't follow the rules");
282
                }
283

    
284
                int calculatedIndex = doAddRow(row, sourceType);
285
                Command command = new AddRowCommand(this, row, calculatedIndex, sourceType);
286
                command.setDescription(descrip);
287
                if (complex) {
288
                        commands.add(command);
289
                } else {
290
                        cr.pushCommand(command);
291
                }
292

    
293
                return calculatedIndex;
294
        }
295

    
296

    
297

    
298
        /**
299
         * DOCUMENT ME!
300
         *
301
         * @throws DriverIOException
302
         *             DOCUMENT ME!
303
         * @throws IOException
304
         *             DOCUMENT ME!
305
         */
306
        public void undo() throws DriverIOException, IOException {
307
                // seleccion.clear();
308
                if (moreUndoCommands()) {
309
                        cr.undoCommand();
310
                }
311
        }
312

    
313
        /**
314
         * DOCUMENT ME!
315
         *
316
         * @throws DriverIOException
317
         *             DOCUMENT ME!
318
         * @throws IOException
319
         *             DOCUMENT ME!
320
         */
321
        public void redo() throws DriverIOException, IOException {
322
                // seleccion.clear();
323
                if (moreRedoCommands()) {
324
                        cr.redoCommand();
325
                }
326
        }
327

    
328
        /**
329
         * DOCUMENT ME!
330
         *
331
         * @return DOCUMENT ME!
332
         */
333
        public boolean moreUndoCommands() {
334
                return cr.moreUndoCommands();
335
        }
336

    
337
        /**
338
         * DOCUMENT ME!
339
         *
340
         * @return DOCUMENT ME!
341
         */
342
        public boolean moreRedoCommands() {
343
                return cr.moreRedoCommands();
344
        }
345

    
346
        /*
347
         * (non-Javadoc)
348
         *
349
         * @see com.iver.cit.gvsig.fmap.edition.IEditableSource#removeRow(int)
350
         */
351
        public void removeRow(int index, String descrip, int sourceType) throws IOException,
352
                        DriverIOException {
353

    
354
                int calculatedIndex = getCalculatedIndex(index);
355
                Command command = new RemoveRowCommand(this, calculatedIndex, sourceType);
356
                command.setDescription(descrip);
357
                if (complex) {
358
                        commands.add(command);
359
                } else {
360
                        cr.pushCommand(command);
361
                }
362
                doRemoveRow(calculatedIndex, sourceType);
363

    
364
        }
365

    
366
        /*
367
         * (non-Javadoc)
368
         *
369
         * @see com.iver.cit.gvsig.fmap.edition.IEditableSource#modifyRow(int,
370
         *      com.iver.cit.gvsig.fmap.core.IRow)
371
         */
372
        public int modifyRow(int index, IRow row, String descrip, int sourceType)
373
                        throws IOException, DriverIOException {
374

    
375
                boolean bIsValid = validateRow(row);
376
                if (bIsValid == false)
377
                {
378
                        throw new IOException("Invalid row: Doesn't follow the rules");
379
                }
380

    
381
                int calculatedIndex = getCalculatedIndex(index);
382
                int pos = doModifyRow(calculatedIndex, row, sourceType);
383
                Command command = new ModifyRowCommand(this, calculatedIndex, pos, row,sourceType);
384
                command.setDescription(descrip);
385
                if (complex) {
386
                        commands.add(command);
387
                } else {
388
                        cr.pushCommand(command);
389
                }
390

    
391
                return pos;
392
        }
393

    
394
        /**
395
         * DOCUMENT ME!
396
         */
397
        public void compact() {
398
                expansionFile.compact(relations);
399
        }
400

    
401
        /**
402
         * DOCUMENT ME!
403
         */
404
        public void startComplexRow() {
405
                complex = true;
406
                commands = new CommandCollection();
407
        }
408

    
409
        /**
410
         * DOCUMENT ME!
411
         *
412
         * @throws IOException
413
         *             DOCUMENT ME!
414
         * @throws DriverIOException
415
         *             DOCUMENT ME!
416
         */
417
        public void endComplexRow() throws IOException, DriverIOException {
418
                cr.pushCommand(commands);
419
                complex = false;
420
        }
421

    
422
        /**
423
         * Actualiza en el mapa de ?ndices, la posici?n en la que estaba la
424
         * geometr?a antes de ser modificada. Se marca como v?lida, en caso de que
425
         * fuera una modificaci?n de una geometr?a que estuviese en el fichero de
426
         * expansi?n antes de ser modificada y se pone el puntero de escritura del
427
         * expansion file a justo despues de la penultima geometr?a
428
         *
429
         * @param geometryIndex
430
         *            ?ndice de la geometr?a que se quiere deshacer su modificaci?n
431
         * @param previousExpansionFileIndex
432
         *            ?ndice que ten?a antes la geometr?a en el expansionFile. Si
433
         *            vale -1 quiere decir que es una modificaci?n de una geometr?a
434
         *            original y por tanto no hay que actualizar el mapa de indices
435
         *            sino eliminar su entrada.
436
         *
437
         * @throws IOException
438
         * @throws DriverIOException
439
         */
440
        public void undoModifyRow(int geometryIndex, int previousExpansionFileIndex, int sourceType)
441
                        throws IOException, DriverIOException {
442

    
443
                if (previousExpansionFileIndex == -1) {
444
                        DefaultRowEdited edRow=null;
445
                        try {
446
                                edRow = new DefaultRowEdited(new DefaultRow(ods
447
                                                .getRow(geometryIndex)),
448
                                                DefaultRowEdited.STATUS_ORIGINAL,geometryIndex);
449
                        } catch (DriverException e) {
450
                                e.printStackTrace();
451
                        }
452
                        boolean cancel = fireBeforeModifyRow(edRow,geometryIndex,sourceType);
453
                        if (cancel)
454
                                return;
455
                        // Se elimina de las relaciones y del fichero de expansi?n
456
                        relations.remove(new Integer(geometryIndex));
457
                        expansionFile.deleteLastRow();
458
                } else {
459
                        boolean cancel = fireBeforeModifyRow(expansionFile.getRow(previousExpansionFileIndex),geometryIndex,sourceType);
460
                        if (cancel)
461
                                return;
462
                        // Se actualiza la relaci?n de ?ndices
463
                        relations.put(new Integer(geometryIndex), new Integer(
464
                                        previousExpansionFileIndex));
465
                }
466
                fireAfterModifyRow(geometryIndex,sourceType);
467
        }
468

    
469
        /**
470
         * Elimina una geometria. Si es una geometr?a original de la capa en edici?n
471
         * se marca como eliminada (haya sido modificada o no). Si es una geometr?a
472
         * a?adida posteriormente se invalida en el fichero de expansi?n, para que
473
         * una futura compactaci?n termine con ella.
474
         *
475
         * @param index
476
         *            ?ndice de la geometr?a.
477
         *
478
         * @throws DriverIOException
479
         * @throws IOException
480
         */
481
        public IRow doRemoveRow(int index, int sourceType) throws DriverIOException, IOException {
482
                boolean cancel = fireBeforeRemoveRow(index, sourceType);
483
                if (cancel)
484
                        return null;
485
                // Llega un calculatedIndex
486
                delRows.set(index, true);
487
                System.err.println("Elimina una Row en la posici?n: " + index);
488
                // TODO: Con tablas no es necesario devolver la anterior feature. Por
489
                // ahora.
490
                fireAfterRemoveRow(index, sourceType);
491
                return null;
492
        }
493

    
494
        /**
495
         * Si se intenta modificar una geometr?a original de la capa en edici?n se
496
         * a?ade al fichero de expansi?n y se registra la posici?n en la que se
497
         * a?adi?. Si se intenta modificar una geometria que se encuentra en el
498
         * fichero de expansi?n (por ser nueva o original pero modificada) se invoca
499
         * el m?todo modifyGeometry y se actualiza el ?ndice de la geometria en el
500
         * fichero.
501
         *
502
         * @param index
503
         *            DOCUMENT ME!
504
         * @param feat
505
         *            DOCUMENT ME!
506
         *
507
         * @return DOCUMENT ME!
508
         *
509
         * @throws IOException
510
         * @throws DriverIOException
511
         */
512
        public int doModifyRow(int index, IRow feat, int sourceType) throws IOException,
513
                        DriverIOException {
514
                boolean cancel = fireBeforeModifyRow(feat,index, sourceType);
515
                if (cancel)
516
                        return -1;
517

    
518
                int pos = -1;
519
                Integer integer = new Integer(index);
520
                System.err.println("Modifica una Row en la posici?n: " + index);
521
                // Si la geometr?a no ha sido modificada
522
                if (!relations.containsKey(integer)) {
523
                        int expansionIndex = expansionFile.addRow(feat, IRowEdited.STATUS_MODIFIED);
524
                        relations.put(integer, new Integer(expansionIndex));
525
                } else {
526
                        // Obtenemos el ?ndice en el fichero de expansi?n
527
                        int num = ((Integer) relations.get(integer)).intValue();
528
                        pos = num;
529

    
530
                        /*
531
                         * Se modifica la geometr?a y nos guardamos el ?ndice dentro del
532
                         * fichero de expansi?n en el que se encuentra la geometr?a
533
                         * modificada
534
                         */
535
                        num = expansionFile.modifyRow(num, feat);
536

    
537
                        /*
538
                         * Actualiza la relaci?n del ?ndice de la geometr?a al ?ndice en el
539
                         * fichero de expansi?n.
540
                         */
541
                        relations.put(integer, new Integer(num));
542
                }
543
                fireAfterModifyRow(index, sourceType);
544
                return pos;
545
        }
546

    
547
        /**
548
         * A?ade una geometria al fichero de expansi?n y guarda la correspondencia
549
         * en la tabla relations.
550
         *
551
         * @param feat
552
         *            geometr?a a guardar.
553
         *
554
         * @return calculatedIndex
555
         *
556
         * @throws DriverIOException
557
         * @throws IOException
558
         */
559
        public int doAddRow(IRow feat,int sourceType) throws DriverIOException, IOException {
560
                boolean cancel = fireBeforeRowAdded(sourceType);
561
                if (cancel)
562
                        return -1;
563
                // A?ade la geometr?a
564
                // int virtualIndex = 0;
565
                int calculatedIndex = -1;
566

    
567
                try {
568
                        calculatedIndex = (int) ods.getRowCount() + numAdd;
569
                        // int externalIndex = getRowCount();
570
                        // calculatedIndex = getCalculatedIndex(externalIndex);
571
                } catch (DriverException e) {
572
                        throw new DriverIOException(e);
573
                }
574

    
575
                int pos = expansionFile.addRow(feat, IRowEdited.STATUS_ADDED);
576
                relations.put(new Integer(calculatedIndex), new Integer(pos));
577
                numAdd++;
578
                System.err.println("A?ade una Row en la posici?n: " + calculatedIndex);
579
                fireAfterRowAdded(calculatedIndex, sourceType);
580
                return calculatedIndex;
581
        }
582

    
583
        /**
584
         * Se desmarca como invalidada en el fichero de expansion o como eliminada
585
         * en el fichero original
586
         *
587
         * @param index
588
         *            DOCUMENT ME!
589
         *
590
         * @throws IOException
591
         * @throws DriverIOException
592
         */
593
        public void undoRemoveRow(int index, int sourceType) throws IOException, DriverIOException {
594
                boolean cancel = fireBeforeRowAdded(sourceType);
595
                if (cancel)
596
                        return;
597
                delRows.set(index, false);
598
                fireAfterRowAdded(index, sourceType);
599
        }
600

    
601
        /**
602
         * Se elimina del final del fichero de expansi?n poniendo el puntero de
603
         * escritura apuntando al final de la pen?ltima geometr?a. Deber? quitar la
604
         * relaci?n del mapa de relaciones
605
         *
606
         * @param index
607
         *            ?ndice de la geometr?a que se a?adi?
608
         *
609
         * @throws DriverIOException
610
         * @throws IOException
611
         */
612
        public void undoAddRow(int calculatedIndex,int sourceType) throws DriverIOException,
613
                        IOException {
614
                boolean cancel = fireBeforeRemoveRow(calculatedIndex,sourceType);
615
                if (cancel)
616
                        return;
617
                expansionFile.deleteLastRow();
618
                relations.remove(new Integer(calculatedIndex));
619
                numAdd--;
620
                fireAfterRemoveRow(calculatedIndex,sourceType);
621
        }
622

    
623
        /*
624
         * (non-Javadoc)
625
         *
626
         * @see com.iver.cit.gvsig.fmap.layers.VectorialAdapter#getRecordset()
627
         */
628
        public SelectableDataSource getRecordset() throws DriverLoadException {
629
                if (isEditing) {
630
                        if (ds == null) {
631
                                String name = LayerFactory.getDataSourceFactory()
632
                                                .addDataSource((ObjectDriver) editingDriver);
633

    
634
                                try {
635
                                        ds = new SelectableDataSource(LayerFactory
636
                                                        .getDataSourceFactory().createRandomDataSource(
637
                                                                        name, DataSourceFactory.AUTOMATIC_OPENING));
638
                                        ds.setSelectionSupport(ods.getSelectionSupport());
639

    
640
                                } catch (NoSuchTableException e) {
641
                                        throw new RuntimeException(e);
642
                                } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
643
                                        throw new RuntimeException(e);
644
                                }
645
                        }
646

    
647
                        return ds;
648
                } else {
649
                        return ods;
650
                }
651
        }
652

    
653
        /**
654
         * DOCUMENT ME!
655
         *
656
         * @param sds
657
         *            DOCUMENT ME!
658
         */
659
        public void setRecordSet(SelectableDataSource sds) {
660
                this.ods = sds;
661
        }
662

    
663
        /**
664
         * DOCUMENT ME!
665
         *
666
         * @return
667
         */
668
        public FBitSet getSelection() {
669
                /*
670
                 * try { return getRecordset().getSelection(); } catch
671
                 * (DriverLoadException e) { // TODO Auto-generated catch block
672
                 * e.printStackTrace(); } return null;
673
                 */
674
                return getRecordset().getSelection();
675
        }
676

    
677
        public void setSelection(FBitSet selection) {
678
                /*
679
                 * try { getRecordset().setSelection(selection); } catch
680
                 * (DriverLoadException e) { // TODO Auto-generated catch block
681
                 * e.printStackTrace(); }
682
                 */
683
                getRecordset().setSelection(selection);
684
        }
685

    
686
        /**
687
         * DOCUMENT ME!
688
         *
689
         * @return DOCUMENT ME!
690
         */
691
        public boolean isEditing() {
692
                return isEditing;
693
        }
694

    
695
        protected int getInversedIndex(long rowIndex) {
696
                int intervalNotDeleted = 0;
697
                int antDeleted = -1;
698
                int idPedido = (int) rowIndex;
699
                int numNotDeleted = 0;
700
                int numBorradosAnt = 0;
701

    
702
                for (int i = delRows.nextSetBit(0); i >= 0; i = delRows
703
                                .nextSetBit(i + 1)) {
704
                        intervalNotDeleted = i - antDeleted - 1;
705
                        numNotDeleted += intervalNotDeleted;
706
                        if (i > idPedido) {
707
                                numNotDeleted = numNotDeleted + (i - idPedido);
708
                                break;
709
                        }
710
                        numBorradosAnt++;
711
                        antDeleted = i;
712
                }
713
                numNotDeleted = idPedido - numBorradosAnt;
714
                // System.out.println("Piden Viejo : "+ rowIndex + " y devuelvo como
715
                // nuevo " + (numNotDeleted));
716
                return numNotDeleted;
717
        }
718

    
719
        /**
720
         * DOCUMENT ME!
721
         *
722
         * @param rowIndex
723
         *            DOCUMENT ME!
724
         *
725
         * @return DOCUMENT ME!
726
         */
727
        public int getCalculatedIndex(long rowIndex) {
728
                int numNotDeleted = 0;
729
                int intervalNotDeleted = 0;
730
                int antDeleted = -1;
731
                int calculatedIndex;
732
                int idPedido = (int) rowIndex;
733
                int numBorradosAnt = 0;
734

    
735
                for (int i = delRows.nextSetBit(0); i >= 0; i = delRows
736
                                .nextSetBit(i + 1)) {
737
                        intervalNotDeleted = i - antDeleted - 1;
738
                        numNotDeleted += intervalNotDeleted;
739
                        if (numNotDeleted > idPedido) {
740
                                break;
741
                        }
742
                        numBorradosAnt++;
743
                        antDeleted = i;
744
                }
745
                calculatedIndex = numBorradosAnt + idPedido;
746
                // System.out.println("Piden Registro : "+ rowIndex + " y devuelvo el "
747
                // + (calculatedIndex));
748
                return calculatedIndex;
749
        }
750

    
751
        /**
752
         * DOCUMENT ME!
753
         *
754
         * @author Vicente Caballero Navarro
755
         */
756
        private class myObjectDriver implements ObjectDriver {
757
                /*
758
                 * (non-Javadoc)
759
                 *
760
                 * @see com.hardcode.gdbms.engine.data.driver.ObjectDriver#getPrimaryKeys()
761
                 */
762
                public int[] getPrimaryKeys() throws DriverException {
763
                        return ods.getPrimaryKeys();
764
                        // int[] pk=new int[1];
765
                        /*
766
                         * for (int i=0;i<getRowCount();i++){ pk[i]=i; }
767
                         */
768
                        // pk[0]=1;
769
                        // return pk;
770
                }
771

    
772
                /*
773
                 * (non-Javadoc)
774
                 *
775
                 * @see com.hardcode.gdbms.engine.data.driver.ObjectDriver#write(com.hardcode.gdbms.engine.data.edition.DataWare)
776
                 */
777
                public void write(DataWare dataWare) throws DriverException {
778
                        DataWare dataWareOrig = ods
779
                                        .getDataWare(DataSourceFactory.DATA_WARE_DIRECT_MODE);
780
                        dataWareOrig.commitTrans();
781
                }
782

    
783
                /*
784
                 * (non-Javadoc)
785
                 *
786
                 * @see com.hardcode.gdbms.engine.data.driver.GDBMSDriver#setDataSourceFactory(com.hardcode.gdbms.engine.data.DataSourceFactory)
787
                 */
788
                public void setDataSourceFactory(DataSourceFactory dsf) {
789
                        ods.setDataSourceFactory(dsf);
790
                }
791

    
792
                /*
793
                 * (non-Javadoc)
794
                 *
795
                 * @see com.hardcode.driverManager.Driver#getName()
796
                 */
797
                public String getName() {
798
                        return ods.getName();
799
                }
800

    
801
                /*
802
                 * (non-Javadoc)
803
                 *
804
                 * @see com.hardcode.gdbms.engine.data.driver.ReadAccess#getFieldValue(long,
805
                 *      int)
806
                 */
807
                public Value getFieldValue(long rowIndex, int fieldId)
808
                                throws DriverException {
809
                        // Si no est? en el fichero de expansi?n
810
                        Integer integer = new Integer(getCalculatedIndex(rowIndex));
811

    
812
                        try {
813
                                if (!relations.containsKey(integer)) {
814
                                        return ods.getFieldValue(rowIndex, fieldId);
815
                                } else {
816
                                        int num = ((Integer) relations.get(integer)).intValue();
817
                                        DefaultRowEdited feat = (DefaultRowEdited) expansionFile
818
                                                        .getRow(num);
819

    
820
                                        if (feat == null) {
821
                                                return null;
822
                                        }
823

    
824
                                        return feat.getAttribute(fieldId);
825
                                }
826
                        } catch (DriverException e) {
827
                                e.printStackTrace();
828
                                throw new DriverException(e);
829
                        } catch (IOException e) {
830
                                e.printStackTrace();
831
                                throw new DriverException(e);
832
                        }
833

    
834
                        /**
835
                         * try { if (!relations.containsKey(integer)) { // Si ha sido
836
                         * eliminada if (delRows.get(integer.intValue())) { return null; }
837
                         * else { return ods.getFieldValue(rowIndex, fieldId); }} else { int
838
                         * num = ((Integer) relations.get(integer)).intValue();
839
                         * DefaultRowEdited feat = (DefaultRowEdited)
840
                         * expansionFile.getRow(num); if (feat==null)return null; return
841
                         * feat.getAttribute(fieldId); }} catch (DriverException e) {
842
                         * e.printStackTrace(); throw new DriverException(e); } catch
843
                         * (IOException e) { e.printStackTrace(); throw new
844
                         * DriverException(e); }
845
                         */
846
                }
847

    
848
                /*
849
                 * (non-Javadoc)
850
                 *
851
                 * @see com.hardcode.gdbms.engine.data.driver.ReadAccess#getFieldCount()
852
                 */
853
                public int getFieldCount() throws DriverException {
854
                        // TODO Por ahora, no dejamos que se a?adan campos
855
                        return ods.getFieldCount();
856
                }
857

    
858
                /*
859
                 * (non-Javadoc)
860
                 *
861
                 * @see com.hardcode.gdbms.engine.data.driver.ReadAccess#getFieldName(int)
862
                 */
863
                public String getFieldName(int fieldId) throws DriverException {
864
                        return ods.getFieldName(fieldId);
865
                }
866

    
867
                /*
868
                 * (non-Javadoc)
869
                 *
870
                 * @see com.hardcode.gdbms.engine.data.driver.ReadAccess#getRowCount()
871
                 */
872
                public long getRowCount() {
873
                        try {
874
                                return (int) (ods.getRowCount() + numAdd)
875
                                                - delRows.cardinality();// -
876
                                                                                                // expansionFile.getInvalidRows().cardinality();
877
                        } catch (DriverException e) {
878
                                // TODO Auto-generated catch block
879
                                e.printStackTrace();
880
                        }
881

    
882
                        return 0;
883
                }
884

    
885
                /*
886
                 * (non-Javadoc)
887
                 *
888
                 * @see com.hardcode.gdbms.engine.data.driver.ReadAccess#getFieldType(int)
889
                 */
890
                public int getFieldType(int i) throws DriverException {
891
                        return ods.getFieldType(i);
892
                }
893

    
894
                public int getFieldWidth(int i) throws DriverException {
895
                        return ods.getFieldWidth(i);
896
                }
897
        }
898

    
899
        public CommandRecord getCommandRecord() {
900
                return cr;
901
        }
902

    
903
        protected void fireAfterRemoveRow(int index,int sourceType) {
904
                AfterRowEditEvent event = new AfterRowEditEvent(this, index, EditionEvent.CHANGE_TYPE_DELETE, sourceType);
905
                for (int i=0; i < editionListeners.size(); i++)
906
                {
907
                        IEditionListener listener = (IEditionListener) editionListeners.get(i);
908
                        listener.afterRowEditEvent(event);
909
                }
910

    
911
        }
912

    
913
        protected boolean fireBeforeRemoveRow(int index,int sourceType) {
914
                Cancel cancel = new Cancel();
915
                BeforeRowEditEvent event = new BeforeRowEditEvent(this, index, EditionEvent.CHANGE_TYPE_DELETE, cancel, sourceType);
916
                for (int i=0; i < editionListeners.size(); i++)
917
                {
918
                        IEditionListener listener = (IEditionListener) editionListeners.get(i);
919
                        listener.beforeRowEditEvent(null,event);
920
                        if (cancel.isCanceled())
921
                                return true;
922
                }
923
                return false;
924
        }
925

    
926
        protected void fireAfterRowAdded(int calculatedIndex,int sourceType) {
927
                AfterRowEditEvent event = new AfterRowEditEvent(this, calculatedIndex, EditionEvent.CHANGE_TYPE_ADD, sourceType);
928
                for (int i=0; i < editionListeners.size(); i++)
929
                {
930
                        IEditionListener listener = (IEditionListener) editionListeners.get(i);
931
                        listener.afterRowEditEvent(event);
932
                }
933
        }
934

    
935
        protected boolean fireBeforeRowAdded(int sourceType) throws DriverIOException, IOException {
936
                Cancel cancel = new Cancel();
937
                BeforeRowEditEvent event = new BeforeRowEditEvent(this, getRowCount(), EditionEvent.CHANGE_TYPE_ADD, cancel, sourceType);
938
                for (int i=0; i < editionListeners.size(); i++)
939
                {
940
                        IEditionListener listener = (IEditionListener) editionListeners.get(i);
941
                        listener.beforeRowEditEvent(null,event);
942
                        if (cancel.isCanceled())
943
                                return true;
944
                }
945
                return false;
946
        }
947

    
948
        protected boolean fireBeforeModifyRow(IRow feat,int index, int sourceType) {
949
                Cancel cancel = new Cancel();
950
                BeforeRowEditEvent event = new BeforeRowEditEvent(this, index, EditionEvent.CHANGE_TYPE_MODIFY, cancel,sourceType);
951
                for (int i=0; i < editionListeners.size(); i++)
952
                {
953
                        IEditionListener listener = (IEditionListener) editionListeners.get(i);
954
                        listener.beforeRowEditEvent(feat, event);
955
                        if (cancel.isCanceled())
956
                                return true;
957
                }
958
                return false;
959
        }
960

    
961
        protected void fireAfterModifyRow(int index,int sourceType) {
962
                AfterRowEditEvent event = new AfterRowEditEvent(this, index, EditionEvent.CHANGE_TYPE_MODIFY,sourceType);
963
                for (int i=0; i < editionListeners.size(); i++)
964
                {
965
                        IEditionListener listener = (IEditionListener) editionListeners.get(i);
966
                        listener.afterRowEditEvent(event);
967
                }
968

    
969

    
970
        }
971

    
972
        protected void fireStartEditionEvent(int sourceType) {
973
                EditionEvent ev = new EditionEvent(this, EditionEvent.START_EDITION, sourceType);
974
                for (int i=0; i < editionListeners.size(); i++)
975
                {
976
                        IEditionListener listener = (IEditionListener) editionListeners.get(i);
977
                        listener.processEvent(ev);
978
                }
979

    
980
        }
981

    
982
        protected void fireStopEditionEvent(int sourceType) {
983
                EditionEvent ev = new EditionEvent(this, EditionEvent.STOP_EDITION, sourceType);
984
                for (int i=0; i < editionListeners.size(); i++)
985
                {
986
                        IEditionListener listener = (IEditionListener) editionListeners.get(i);
987
                        listener.processEvent(ev);
988
                }
989

    
990
        }
991

    
992
        protected void fireCancelEditionEvent(int sourceType) {
993
                EditionEvent ev = new EditionEvent(this, EditionEvent.CANCEL_EDITION, sourceType);
994
                for (int i=0; i < editionListeners.size(); i++)
995
                {
996
                        IEditionListener listener = (IEditionListener) editionListeners.get(i);
997
                        listener.processEvent(ev);
998
                }
999

    
1000
        }
1001

    
1002

    
1003
        public void addEditionListener(IEditionListener listener){
1004
                if (!editionListeners.contains(listener))
1005
                        editionListeners.add(listener);
1006
        }
1007

    
1008
        public void removeEditionListener(IEditionListener listener)
1009
        {
1010
                editionListeners.remove(listener);
1011
        }
1012

    
1013
        public IWriter getWriter() {
1014
                return writer;
1015
        }
1016

    
1017
        public void setWriter(IWriter writer) {
1018
                this.writer = writer;
1019
                
1020
        }
1021

    
1022
        public ITableDefinition getTableDefinition() throws DriverLoadException, DriverException {
1023
                TableDefinition tableDef = new TableDefinition();
1024
                tableDef.setFieldsDesc(getRecordset().getFieldsDescription());
1025
                tableDef.setName(getRecordset().getSourceInfo().name);
1026
                return tableDef;
1027
        }
1028

    
1029
        public boolean validateRow(IRow row) {
1030
                for (int i=0; i< rules.size(); i++)
1031
                {
1032
                        IRule rule = (IRule) rules.get(i);
1033
                        boolean bAux = rule.validate(row);
1034
                        if (bAux == false)
1035
                                return false;
1036
                }
1037
                return true;
1038
        }
1039

    
1040
        public ArrayList getRules() {
1041
                return rules;
1042
        }
1043

    
1044
        public void setRules(ArrayList rules) {
1045
                this.rules = rules;
1046
        }
1047

    
1048
}