Statistics
| Revision:

root / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / edition / EditableAdapter.java @ 6071

History | View | Annotate | Download (29 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
                try {
279
                        validateRow(row);
280
                } catch (EditionException e) {
281
                        e.printStackTrace();
282
                        throw new IOException(e.getMessage());
283
                }
284

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

    
294
                return calculatedIndex;
295
        }
296

    
297

    
298

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

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

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

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

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

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

    
365
        }
366

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

    
376
                try {
377
                        validateRow(row);
378
                } catch (EditionException e) {
379
                        e.printStackTrace();
380
                        throw new IOException(e.getMessage());
381
                }
382

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

    
393
                return pos;
394
        }
395

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
637
                                try {
638
                                        ds = new SelectableDataSource(LayerFactory
639
                                                        .getDataSourceFactory().createRandomDataSource(
640
                                                                        name, DataSourceFactory.AUTOMATIC_OPENING));
641
                                        ds.setSelectionSupport(ods.getSelectionSupport());
642

    
643
                                } catch (NoSuchTableException e) {
644
                                        throw new RuntimeException(e);
645
                                } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
646
                                        throw new RuntimeException(e);
647
                                }
648
                        }
649

    
650
                        return ds;
651
                } else {
652
                        return ods;
653
                }
654
        }
655

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

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

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

    
689
        /**
690
         * DOCUMENT ME!
691
         *
692
         * @return DOCUMENT ME!
693
         */
694
        public boolean isEditing() {
695
                return isEditing;
696
        }
697

    
698
        public int getInversedIndex(long rowIndex) {
699
                int intervalNotDeleted = 0;
700
                int antDeleted = -1;
701
                int idPedido = (int) rowIndex;
702
                int numNotDeleted = 0;
703
                int numBorradosAnt = 0;
704

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

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

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

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

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

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

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

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

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

    
823
                                        if (feat == null) {
824
                                                return null;
825
                                        }
826

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

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

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

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

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

    
885
                        return 0;
886
                }
887

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

    
897
                public int getFieldWidth(int i) throws DriverException {
898
                        return ods.getFieldWidth(i);
899
                }
900
        }
901

    
902
        public CommandRecord getCommandRecord() {
903
                return cr;
904
        }
905

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

    
914
        }
915

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

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

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

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

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

    
972

    
973
        }
974

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

    
983
        }
984

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

    
993
        }
994

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

    
1003
        }
1004

    
1005

    
1006
        public void addEditionListener(IEditionListener listener){
1007
                if (!editionListeners.contains(listener))
1008
                        editionListeners.add(listener);
1009
        }
1010

    
1011
        public void removeEditionListener(IEditionListener listener)
1012
        {
1013
                editionListeners.remove(listener);
1014
        }
1015

    
1016
        public IWriter getWriter() {
1017
                return writer;
1018
        }
1019

    
1020
        public void setWriter(IWriter writer) {
1021
                this.writer = writer;
1022

    
1023
        }
1024

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

    
1032
        public void validateRow(IRow row) throws EditionException {
1033
                for (int i=0; i< rules.size(); i++)
1034
                {
1035
                        IRule rule = (IRule) rules.get(i);
1036
                        boolean bAux = rule.validate(row);
1037
                        if (bAux == false)
1038
                        {
1039
                                EditionException ex = new EditionException("NOT follow the rule: " + rule.getDescription());
1040
                                // TODO: Lanzar una RuleException con datos como el registro
1041
                                // que no cumple, la regla que no lo ha cumplido, etc.
1042
                                throw ex;
1043
                        }
1044
                }
1045
        }
1046

    
1047
        public ArrayList getRules() {
1048
                return rules;
1049
        }
1050

    
1051
        public void setRules(ArrayList rules) {
1052
                this.rules = rules;
1053
        }
1054

    
1055
}