Statistics
| Revision:

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

History | View | Annotate | Download (37.4 KB)

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

    
3
import java.io.IOException;
4
import java.util.ArrayList;
5
import java.util.Collection;
6
import java.util.HashMap;
7
import java.util.Iterator;
8
import java.util.TreeMap;
9

    
10
import com.hardcode.driverManager.Driver;
11
import com.hardcode.driverManager.DriverLoadException;
12
import com.hardcode.gdbms.engine.data.DataSourceFactory;
13
import com.hardcode.gdbms.engine.data.NoSuchTableException;
14
import com.hardcode.gdbms.engine.data.driver.DriverException;
15
import com.hardcode.gdbms.engine.data.driver.ObjectDriver;
16
import com.hardcode.gdbms.engine.data.edition.DataWare;
17
import com.hardcode.gdbms.engine.values.Value;
18
import com.iver.cit.gvsig.fmap.core.DefaultRow;
19
import com.iver.cit.gvsig.fmap.core.IRow;
20
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
21
import com.iver.cit.gvsig.fmap.drivers.FieldDescription;
22
import com.iver.cit.gvsig.fmap.drivers.ITableDefinition;
23
import com.iver.cit.gvsig.fmap.drivers.TableDefinition;
24
import com.iver.cit.gvsig.fmap.edition.commands.AddFieldCommand;
25
import com.iver.cit.gvsig.fmap.edition.commands.AddRowCommand;
26
import com.iver.cit.gvsig.fmap.edition.commands.Command;
27
import com.iver.cit.gvsig.fmap.edition.commands.CommandCollection;
28
import com.iver.cit.gvsig.fmap.edition.commands.CommandRecord;
29
import com.iver.cit.gvsig.fmap.edition.commands.MemoryCommandRecord;
30
import com.iver.cit.gvsig.fmap.edition.commands.ModifyRowCommand;
31
import com.iver.cit.gvsig.fmap.edition.commands.RemoveFieldCommand;
32
import com.iver.cit.gvsig.fmap.edition.commands.RemoveRowCommand;
33
import com.iver.cit.gvsig.fmap.edition.commands.RenameFieldCommand;
34
import com.iver.cit.gvsig.fmap.edition.fieldmanagers.AbstractFieldManager;
35
import com.iver.cit.gvsig.fmap.edition.rules.IRule;
36
import com.iver.cit.gvsig.fmap.layers.FBitSet;
37
import com.iver.cit.gvsig.fmap.layers.LayerFactory;
38
import com.iver.cit.gvsig.fmap.layers.SelectableDataSource;
39
import com.iver.cit.gvsig.fmap.operations.Cancel;
40

    
41
/**
42
 * DOCUMENT ME!
43
 * 
44
 * @author Vicente Caballero Navarro
45
 */
46
public class EditableAdapter implements IEditableSource, IWriteable {
47
        protected boolean isEditing = false;
48

    
49
        private SelectableDataSource ds = null;
50

    
51
        protected FBitSet delRows = new FBitSet();
52

    
53
        private CommandRecord cr;
54

    
55
        protected IWriter writer;
56

    
57
        /**
58
         * Flag que indica que hay que tomar las siguientes operaciones como una
59
         * operaci?n at?mica
60
         */
61
        private boolean complex = false;
62

    
63
        private CommandCollection commands = null;
64

    
65
        protected ArrayList listFields = new ArrayList();
66

    
67
        protected ArrayList listInternalFields = new ArrayList();
68

    
69
        /**
70
         * La clave ser? el fieldIndex. Para buscar si un value de una row ha de ser
71
         * rellenado con defaultValue o con lo que venga del expansion file,
72
         * miraremos si existe en este hash. Si existe, usamos el value del
73
         * expansion file. Si no existe, usamos el defaultValue del campo busc?ndolo
74
         * en la lista internalFields. Por cierto, en listInternalFields NO se
75
         * borran campos. Solo se marcan como borrados.
76
         */
77
        protected TreeMap actualFields; // la clave ser? el fieldIndex.
78

    
79
        protected class MyFieldManager extends AbstractFieldManager {
80

    
81
                public boolean alterTable() throws EditionException {
82
                        return getFieldManager().alterTable();
83
                }
84

    
85
                public void addField(FieldDescription fieldDesc) {
86
                        super.addField(fieldDesc);
87
                }
88

    
89
                public FieldDescription removeField(String fieldName) {
90
                        // TODO Auto-generated method stub
91
                        return super.removeField(fieldName);
92
                }
93

    
94
                public void renameField(String antName, String newName) {
95
                        // TODO Auto-generated method stub
96
                        super.renameField(antName, newName);
97
                }
98

    
99
        }
100

    
101
        /*
102
         * Establece una relaci?n entre los ?ndices de las geometr?as en el
103
         * EditableFeatureSource y los ?ndices en el fichero de expansi?n FJP:
104
         * CAMBIO: NECESITAMOS TRABAJAR CON FEATURE Y FEATUREITERATOR PARA IR
105
         * PREPARANDO EL CAMINO, GUARDAMOS EL FEATUREID (STRING) COMO CLAVE, Y COMO
106
         * VALOR, EL INDICE DENTRO DEL FICHERO DE EXPANSION (Integer). Lo de que
107
         * FeatureId sea un String es por compatibilidad con OGC. Seg?n OGC, una
108
         * Feature tiene que tener un Id string En el caso de los randomaccess,
109
         * ser?n el id de registro En los casos de base de datos espaciales, supongo
110
         * que siempre ser? num?rico tambi?n, pero lo tendremos que convertir a
111
         * string. Lo que est? claro es que NO se puede confiar nunca en que sea
112
         * algo correlativo (1, 2, 3, 4, 5, ... => FALSO!!)
113
         */
114
        protected HashMap relations = new HashMap();
115

    
116
        /*
117
         * Fichero en el que se guardan las nuevas geometr?as, producto de adiciones
118
         * o de modificaciones
119
         */
120
        protected ExpansionFile expansionFile;
121

    
122
        protected int numAdd = 0;
123

    
124
        private ObjectDriver editingDriver = new myObjectDriver();
125

    
126
        private SelectableDataSource ods;
127

    
128
        private ArrayList editionListeners = new ArrayList();
129

    
130
        private ArrayList rules = new ArrayList();
131

    
132
        protected int actualIndexFields;
133

    
134
        /**
135
         * Crea un nuevo EditableAdapter.
136
         */
137
        public EditableAdapter() {
138
                expansionFile = new MemoryExpansionFile(this);
139
                cr = new MemoryCommandRecord();
140
        }
141

    
142
        /**
143
         * DOCUMENT ME!
144
         * 
145
         * @param ds
146
         *            DOCUMENT ME!
147
         * @throws DriverException 
148
         */
149
        public void setOriginalDataSource(SelectableDataSource ds) throws DriverException {
150
                this.ods = ds;
151
                initalizeFields(ds);
152
                
153
        }
154

    
155
        /**
156
         * @param ds
157
         * @throws DriverException
158
         */
159
        private void initalizeFields(SelectableDataSource ds) throws DriverException {
160
                boolean bReallyClosed = false;
161
                while (!bReallyClosed)
162
                {
163
                        try {
164
                                ds.stop();
165
                        }
166
                        catch (RuntimeException e) {
167
                                bReallyClosed = true;
168
                                ds.start();
169
                        }
170
                }
171
                
172
                
173
                FieldDescription[] fields = ds.getFieldsDescription();
174
                listInternalFields.clear();
175
                actualFields = new TreeMap();
176
                for (int i=0; i < fields.length; i++)
177
                {
178
                        InternalField field = new InternalField(fields[i], InternalField.ORIGINAL, new Integer(i));
179
                        listFields.add(field);
180
                        field.setFieldIndex(i);
181
                        actualFields.put(field.getFieldId(), field);
182
                }
183
                try {
184
                        fieldsChanged();
185
                } catch (EditionException e) {
186
                        e.printStackTrace();
187
                        throw new DriverException(e);
188
                }
189
        }
190

    
191
        private void fieldsChanged() throws EditionException {
192
                listInternalFields.add(actualFields.clone());
193
                actualIndexFields = listInternalFields.size()-1;
194
                try {
195
                        getRecordset().mapExternalFields();
196
                } catch (DriverLoadException e) {
197
                        e.printStackTrace();
198
                        throw new EditionException(e);
199
                } catch (DriverException e) {
200
                        e.printStackTrace();
201
                        throw new EditionException(e);
202
                }
203
        }
204

    
205
        /**
206
         * DOCUMENT ME!
207
         * 
208
         * @throws EditionException
209
         *             DOCUMENT ME!
210
         */
211
        public void startEdition(int sourceType) throws EditionException {
212
                isEditing = true;
213
                // Obtenemos el driver y vemos si implementa IWriter.
214
                /*
215
                 * DataWare dataWare =
216
                 * ods.getDataWare(DataSourceFactory.DATA_WARE_DIRECT_MODE);
217
                 * dataWare.get
218
                 */
219
                Driver drv = ods.getDriver();
220
                if (drv instanceof IWriteable) {
221
                        setWriter(((IWriteable) drv).getWriter());
222
                }
223

    
224
                fireStartEditionEvent(sourceType);
225
        }
226

    
227
        /**
228
         * Se ejecuta preProcess() del IWriter, luego se itera por los registros
229
         * borrados por si el IWriter los quiere borrar (solo ser? necesario cuando
230
         * escribimos sobre la misma tabla) y luego se itera por los nuevos
231
         * registros llamando a process con el registro correcto. (A?adidos,
232
         * modificados). Para finalizar, se ejecuta PostProcess
233
         * 
234
         * @param writer
235
         *            IWriter que recibir? las llamadas.
236
         * 
237
         * @throws EditionException
238
         *             DOCUMENT ME!
239
         */
240
        public void stopEdition(IWriter writer, int sourceType)
241
                        throws EditionException {
242

    
243
                saveEdits(writer, sourceType);
244
                isEditing = false;
245
                fireStopEditionEvent(sourceType);
246
        }
247

    
248
        public void saveEdits(IWriter writer, int sourceType)
249
                        throws EditionException {
250
                writer.preProcess();
251

    
252
                try {
253

    
254
                        // Procesamos primero los borrados.
255
                        // Cuando se genere un tema nuevo, no se les debe hacer caso
256
                        // a estos registros
257

    
258
                        for (int i = delRows.nextSetBit(0); i >= 0; i = delRows
259
                                        .nextSetBit(i + 1)) {
260
                                int calculatedIndex = i;
261
                                Integer integer = new Integer(calculatedIndex);
262
                                // Si no est? en el fichero de expansi?n, es de los originales
263
                                // y hay que borrarlo
264
                                DefaultRowEdited edRow = null;
265
                                if (!relations.containsKey(integer)) {
266
                                        edRow = new DefaultRowEdited(new DefaultRow(ods
267
                                                        .getRow(calculatedIndex)),
268
                                                        DefaultRowEdited.STATUS_DELETED, calculatedIndex);
269
                                        writer.process(edRow);
270
                                } else {
271
                                        int num = ((Integer) relations.get(integer)).intValue();
272

    
273
                                        // return expansionFile.getRow(num);
274
                                        IRowEdited rowFromExpansion = expansionFile.getRow(num);
275
                                        // ?Habr?a que hacer aqu? setID(index + "")?
276
                                        edRow = new DefaultRowEdited(rowFromExpansion
277
                                                        .getLinkedRow().cloneRow(),
278
                                                        DefaultRowEdited.STATUS_DELETED, calculatedIndex);
279
                                        writer.process(edRow);
280
                                }
281

    
282
                        }
283

    
284
                        int rowCount = getRowCount();
285
                        for (int i = 0; i < rowCount; i++) {
286
                                IRowEdited rowEdited = getRow(i);
287

    
288
                                if (rowEdited != null) {
289
                                        writer.process(rowEdited);
290
                                }
291
                        }
292
                        writer.postProcess();
293
                        clean();
294
                        ods.stop();
295
                        ods.start();
296

    
297
                } catch (DriverIOException e) {
298
                        e.printStackTrace();
299
                        throw new EditionException(e);
300
                } catch (IOException e) {
301
                        e.printStackTrace();
302
                        throw new EditionException(e);
303
                } catch (DriverException e) {
304
                        e.printStackTrace();
305
                        throw new EditionException(e);
306
                }
307

    
308
        }
309

    
310
        /**
311
         * DOCUMENT ME!
312
         * 
313
         * @throws IOException
314
         *             DOCUMENT ME!
315
         */
316
        public void cancelEdition(int sourceType) throws IOException {
317
                isEditing = false;
318
                try {
319
                        clean();
320
                } catch (DriverException e) {
321
                        e.printStackTrace();
322
                        throw new IOException("Error: " + e.getMessage());
323
                }
324
                fireCancelEditionEvent(sourceType);
325
        }
326

    
327
        /*
328
         * (non-Javadoc)
329
         * 
330
         * @see com.iver.cit.gvsig.fmap.edition.IEditableSource#getRow(int)
331
         */
332
        public IRowEdited getRow(int index) throws DriverIOException, IOException {
333
                int calculatedIndex = getCalculatedIndex(index);
334
                Integer integer = new Integer(calculatedIndex);
335
                DefaultRowEdited edRow = null;
336
                // Si no est? en el fichero de expansi?n
337
                if (!relations.containsKey(integer)) {
338
                        try {
339
                                /*
340
                                 * edRow = new DefaultRowEdited(new
341
                                 * DefaultRow(ods.getRow(calculatedIndex), "" + index),
342
                                 * DefaultRowEdited.STATUS_ORIGINAL, index);
343
                                 */
344
                                DefaultRow auxR = new DefaultRow(ods.getRow(calculatedIndex));
345
                                edRow = new DefaultRowEdited(auxR,
346
                                                DefaultRowEdited.STATUS_ORIGINAL, index);
347
                                return createExternalRow(edRow, 0);
348
//                                edRow = new DefaultRowEdited(new DefaultRow(ods
349
//                                                .getRow(calculatedIndex)),
350
//                                                DefaultRowEdited.STATUS_ORIGINAL, index);
351
                        } catch (DriverException e) {
352
                                throw new DriverIOException(e);
353
                        }
354
                } else {
355
                        int num = ((Integer) relations.get(integer)).intValue();
356

    
357
                        // return expansionFile.getRow(num);
358
                        // ExpansionFile ya entrega el registro formateado como debe
359
                        IRowEdited rowFromExpansion = expansionFile.getRow(num);
360
                        // ?Habr?a que hacer aqu? setID(index + "")?
361
                        edRow = new DefaultRowEdited(rowFromExpansion.getLinkedRow()
362
                                        .cloneRow(), rowFromExpansion.getStatus(), index);
363
                        return edRow;
364
                }
365
                
366
                
367

    
368
        }
369

    
370
        /**
371
         * DOCUMENT ME!
372
         * 
373
         * @return DOCUMENT ME!
374
         * 
375
         * @throws DriverIOException
376
         *             DOCUMENT ME!
377
         * @throws IOException
378
         *             DOCUMENT ME!
379
         */
380
        public int getRowCount() throws DriverIOException, IOException {
381
                try {
382
                        return (int) (ods.getRowCount() + numAdd) - delRows.cardinality();// -
383
                        // expansionFile.getInvalidRows().cardinality();
384
                } catch (DriverException e) {
385
                        throw new DriverIOException(e);
386
                }
387

    
388
        }
389

    
390
        /*
391
         * (non-Javadoc)
392
         * 
393
         * @see com.iver.cit.gvsig.fmap.edition.IEditableSource#addRow(com.iver.cit.gvsig.fmap.core.IRow,
394
         *      java.lang.String)
395
         */
396
        public int addRow(IRow row, String descrip, int sourceType)
397
                        throws DriverIOException, IOException {
398

    
399
                try {
400
                        validateRow(row);
401
                } catch (EditionException e) {
402
                        e.printStackTrace();
403
                        throw new IOException(e.getMessage());
404
                }
405

    
406
                int calculatedIndex = doAddRow(row, sourceType);
407
                Command command = new AddRowCommand(this, row, calculatedIndex,
408
                                sourceType);
409
                command.setDescription(descrip);
410
                if (complex) {
411
                        commands.add(command);
412
                } else {
413
                        cr.pushCommand(command);
414
                }
415

    
416
                return calculatedIndex;
417
        }
418

    
419
        /**
420
         * DOCUMENT ME!
421
         * 
422
         * @throws DriverIOException
423
         *             DOCUMENT ME!
424
         * @throws IOException
425
         *             DOCUMENT ME!
426
         */
427
        public void undo() throws DriverIOException, IOException {
428
                // seleccion.clear();
429
                if (cr.moreUndoCommands()) {
430
                        cr.undoCommand();
431
                }
432
        }
433

    
434
        /**
435
         * DOCUMENT ME!
436
         * 
437
         * @throws DriverIOException
438
         *             DOCUMENT ME!
439
         * @throws IOException
440
         *             DOCUMENT ME!
441
         */
442
        public void redo() throws DriverIOException, IOException {
443
                // seleccion.clear();
444
                if (cr.moreRedoCommands()) {
445
                        cr.redoCommand();
446
                }
447
        }
448

    
449
        /*
450
         * (non-Javadoc)
451
         * 
452
         * @see com.iver.cit.gvsig.fmap.edition.IEditableSource#removeRow(int)
453
         */
454
        public void removeRow(int index, String descrip, int sourceType)
455
                        throws IOException, DriverIOException {
456

    
457
                int calculatedIndex = getCalculatedIndex(index);
458
                Command command = new RemoveRowCommand(this, calculatedIndex,
459
                                sourceType);
460
                command.setDescription(descrip);
461
                if (complex) {
462
                        commands.add(command);
463
                } else {
464
                        cr.pushCommand(command);
465
                }
466
                doRemoveRow(calculatedIndex, sourceType);
467

    
468
        }
469

    
470
        /*
471
         * (non-Javadoc)
472
         * 
473
         * @see com.iver.cit.gvsig.fmap.edition.IEditableSource#modifyRow(int,
474
         *      com.iver.cit.gvsig.fmap.core.IRow)
475
         */
476
        public int modifyRow(int index, IRow row, String descrip, int sourceType)
477
                        throws IOException, DriverIOException {
478

    
479
                try {
480
                        validateRow(row);
481
                } catch (EditionException e) {
482
                        e.printStackTrace();
483
                        throw new IOException(e.getMessage());
484
                }
485

    
486
                int calculatedIndex = getCalculatedIndex(index);
487
                int pos = doModifyRow(calculatedIndex, row, sourceType);
488
                Command command = new ModifyRowCommand(this, calculatedIndex, pos, row,
489
                                sourceType);
490
                command.setDescription(descrip);
491
                if (complex) {
492
                        commands.add(command);
493
                } else {
494
                        cr.pushCommand(command);
495
                }
496

    
497
                return pos;
498
        }
499

    
500
        /**
501
         * DOCUMENT ME!
502
         */
503
        public void compact() {
504
                expansionFile.compact(relations);
505
        }
506

    
507
        /**
508
         * DOCUMENT ME!
509
         */
510
        public void startComplexRow() {
511
                complex = true;
512
                commands = new CommandCollection();
513
        }
514

    
515
        /**
516
         * DOCUMENT ME!
517
         * 
518
         * @throws IOException
519
         *             DOCUMENT ME!
520
         * @throws DriverIOException
521
         *             DOCUMENT ME!
522
         */
523
        public void endComplexRow(String description) throws IOException,
524
                        DriverIOException {
525
                commands.setDescription(description);
526
                cr.pushCommand(commands);
527
                complex = false;
528
        }
529

    
530
        /**
531
         * Actualiza en el mapa de ?ndices, la posici?n en la que estaba la
532
         * geometr?a antes de ser modificada. Se marca como v?lida, en caso de que
533
         * fuera una modificaci?n de una geometr?a que estuviese en el fichero de
534
         * expansi?n antes de ser modificada y se pone el puntero de escritura del
535
         * expansion file a justo despues de la penultima geometr?a
536
         * 
537
         * @param geometryIndex
538
         *            ?ndice de la geometr?a que se quiere deshacer su modificaci?n
539
         * @param previousExpansionFileIndex
540
         *            ?ndice que ten?a antes la geometr?a en el expansionFile. Si
541
         *            vale -1 quiere decir que es una modificaci?n de una geometr?a
542
         *            original y por tanto no hay que actualizar el mapa de indices
543
         *            sino eliminar su entrada.
544
         * 
545
         * @throws IOException
546
         * @throws DriverIOException
547
         */
548
        public void undoModifyRow(int geometryIndex,
549
                        int previousExpansionFileIndex, int sourceType) throws IOException,
550
                        DriverIOException {
551

    
552
                if (previousExpansionFileIndex == -1) {
553
                        DefaultRowEdited edRow = null;
554
                        try {
555
                                edRow = new DefaultRowEdited(new DefaultRow(ods
556
                                                .getRow(geometryIndex)),
557
                                                DefaultRowEdited.STATUS_ORIGINAL, geometryIndex);
558
                        } catch (DriverException e) {
559
                                e.printStackTrace();
560
                        }
561
                        boolean cancel = fireBeforeModifyRow(edRow, geometryIndex,
562
                                        sourceType);
563
                        if (cancel)
564
                                return;
565
                        // Se elimina de las relaciones y del fichero de expansi?n
566
                        relations.remove(new Integer(geometryIndex));
567
                        expansionFile.deleteLastRow();
568
                } else {
569
                        boolean cancel = fireBeforeModifyRow(expansionFile
570
                                        .getRow(previousExpansionFileIndex), geometryIndex,
571
                                        sourceType);
572
                        if (cancel)
573
                                return;
574
                        // Se actualiza la relaci?n de ?ndices
575
                        relations.put(new Integer(geometryIndex), new Integer(
576
                                        previousExpansionFileIndex));
577
                }
578
                fireAfterModifyRow(geometryIndex, sourceType);
579
        }
580

    
581
        /**
582
         * Elimina una geometria. Si es una geometr?a original de la capa en edici?n
583
         * se marca como eliminada (haya sido modificada o no). Si es una geometr?a
584
         * a?adida posteriormente se invalida en el fichero de expansi?n, para que
585
         * una futura compactaci?n termine con ella.
586
         * 
587
         * @param index
588
         *            ?ndice de la geometr?a.
589
         * 
590
         * @throws DriverIOException
591
         * @throws IOException
592
         */
593
        public IRow doRemoveRow(int index, int sourceType)
594
                        throws DriverIOException, IOException {
595
                boolean cancel = fireBeforeRemoveRow(index, sourceType);
596
                if (cancel)
597
                        return null;
598
                // Llega un calculatedIndex
599
                delRows.set(index, true);
600
                System.err.println("Elimina una Row en la posici?n: " + index);
601
                // TODO: Con tablas no es necesario devolver la anterior feature. Por
602
                // ahora.
603
                fireAfterRemoveRow(index, sourceType);
604
                return null;
605
        }
606

    
607
        /**
608
         * Si se intenta modificar una geometr?a original de la capa en edici?n se
609
         * a?ade al fichero de expansi?n y se registra la posici?n en la que se
610
         * a?adi?. Si se intenta modificar una geometria que se encuentra en el
611
         * fichero de expansi?n (por ser nueva o original pero modificada) se invoca
612
         * el m?todo modifyGeometry y se actualiza el ?ndice de la geometria en el
613
         * fichero.
614
         * 
615
         * @param index
616
         *            DOCUMENT ME!
617
         * @param feat
618
         *            DOCUMENT ME!
619
         * 
620
         * @return DOCUMENT ME!
621
         * 
622
         * @throws IOException
623
         * @throws DriverIOException
624
         */
625
        public int doModifyRow(int index, IRow feat, int sourceType)
626
                        throws IOException, DriverIOException {
627
                boolean cancel = fireBeforeModifyRow(feat, index, sourceType);
628
                if (cancel)
629
                        return -1;
630

    
631
                int pos = -1;
632
                Integer integer = new Integer(index);
633
                System.err.println("Modifica una Row en la posici?n: " + index);
634
                // Si la geometr?a no ha sido modificada
635
                if (!relations.containsKey(integer)) {
636
                        int expansionIndex = expansionFile.addRow(feat,
637
                                        IRowEdited.STATUS_MODIFIED, actualIndexFields);
638
                        relations.put(integer, new Integer(expansionIndex));
639
                } else {
640
                        // Obtenemos el ?ndice en el fichero de expansi?n
641
                        int num = ((Integer) relations.get(integer)).intValue();
642
                        pos = num;
643

    
644
                        /*
645
                         * Se modifica la geometr?a y nos guardamos el ?ndice dentro del
646
                         * fichero de expansi?n en el que se encuentra la geometr?a
647
                         * modificada
648
                         */
649
                        num = expansionFile.modifyRow(num, feat, actualIndexFields);
650

    
651
                        /*
652
                         * Actualiza la relaci?n del ?ndice de la geometr?a al ?ndice en el
653
                         * fichero de expansi?n.
654
                         */
655
                        relations.put(integer, new Integer(num));
656
                }
657
                fireAfterModifyRow(index, sourceType);
658
                return pos;
659
        }
660

    
661
        /**
662
         * A?ade una geometria al fichero de expansi?n y guarda la correspondencia
663
         * en la tabla relations.
664
         * 
665
         * @param feat
666
         *            geometr?a a guardar.
667
         * 
668
         * @return calculatedIndex
669
         * 
670
         * @throws DriverIOException
671
         * @throws IOException
672
         */
673
        public int doAddRow(IRow feat, int sourceType) throws DriverIOException,
674
                        IOException {
675
                boolean cancel = fireBeforeRowAdded(sourceType);
676
                if (cancel)
677
                        return -1;
678
                // A?ade la geometr?a
679
                // int virtualIndex = 0;
680
                int calculatedIndex = -1;
681

    
682
                try {
683
                        calculatedIndex = (int) ods.getRowCount() + numAdd;
684
                        // int externalIndex = getRowCount();
685
                        // calculatedIndex = getCalculatedIndex(externalIndex);
686
                } catch (DriverException e) {
687
                        throw new DriverIOException(e);
688
                }
689

    
690
                int pos = expansionFile.addRow(feat, IRowEdited.STATUS_ADDED, actualIndexFields);
691
                relations.put(new Integer(calculatedIndex), new Integer(pos));
692
                numAdd++;
693
                System.err.println("A?ade una Row en la posici?n: " + calculatedIndex);
694
                fireAfterRowAdded(calculatedIndex, sourceType);
695
                return calculatedIndex;
696
        }
697

    
698
        /**
699
         * Se desmarca como invalidada en el fichero de expansion o como eliminada
700
         * en el fichero original
701
         * 
702
         * @param index
703
         *            DOCUMENT ME!
704
         * 
705
         * @throws IOException
706
         * @throws DriverIOException
707
         */
708
        public void undoRemoveRow(int index, int sourceType) throws IOException,
709
                        DriverIOException {
710
                boolean cancel = fireBeforeRowAdded(sourceType);
711
                if (cancel)
712
                        return;
713
                delRows.set(index, false);
714
                fireAfterRowAdded(index, sourceType);
715
        }
716

    
717
        /**
718
         * Se elimina del final del fichero de expansi?n poniendo el puntero de
719
         * escritura apuntando al final de la pen?ltima geometr?a. Deber? quitar la
720
         * relaci?n del mapa de relaciones
721
         * 
722
         * @param index
723
         *            ?ndice de la geometr?a que se a?adi?
724
         * 
725
         * @throws DriverIOException
726
         * @throws IOException
727
         */
728
        public void undoAddRow(int calculatedIndex, int sourceType)
729
                        throws DriverIOException, IOException {
730
                boolean cancel = fireBeforeRemoveRow(calculatedIndex, sourceType);
731
                if (cancel)
732
                        return;
733
                expansionFile.deleteLastRow();
734
                relations.remove(new Integer(calculatedIndex));
735
                numAdd--;
736
                fireAfterRemoveRow(calculatedIndex, sourceType);
737
        }
738

    
739
        /*
740
         * (non-Javadoc)
741
         * 
742
         * @see com.iver.cit.gvsig.fmap.layers.VectorialAdapter#getRecordset()
743
         */
744
        public SelectableDataSource getRecordset() throws DriverLoadException {
745
                if (isEditing) {
746
                        if (ds == null) {
747
                                String name = LayerFactory.getDataSourceFactory()
748
                                                .addDataSource((ObjectDriver) editingDriver);
749

    
750
                                try {
751
                                        ds = new SelectableDataSource(LayerFactory
752
                                                        .getDataSourceFactory().createRandomDataSource(
753
                                                                        name, DataSourceFactory.MANUAL_OPENING));
754
                                        ds.start();
755
                                        ds.setSelectionSupport(ods.getSelectionSupport());
756

    
757
                                } catch (NoSuchTableException e) {
758
                                        throw new RuntimeException(e);
759
                                } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
760
                                        throw new RuntimeException(e);
761
                                }
762
                        }
763

    
764
                        return ds;
765
                } else {
766
                        return ods;
767
                }
768
        }
769

    
770

    
771
        /**
772
         * DOCUMENT ME!
773
         * 
774
         * @return
775
         */
776
        public FBitSet getSelection() {
777
                /*
778
                 * try { return getRecordset().getSelection(); } catch
779
                 * (DriverLoadException e) { // TODO Auto-generated catch block
780
                 * e.printStackTrace(); } return null;
781
                 */
782
                return getRecordset().getSelection();
783
        }
784

    
785
        public void setSelection(FBitSet selection) {
786
                /*
787
                 * try { getRecordset().setSelection(selection); } catch
788
                 * (DriverLoadException e) { // TODO Auto-generated catch block
789
                 * e.printStackTrace(); }
790
                 */
791
                getRecordset().setSelection(selection);
792
        }
793

    
794
        /**
795
         * DOCUMENT ME!
796
         * 
797
         * @return DOCUMENT ME!
798
         */
799
        public boolean isEditing() {
800
                return isEditing;
801
        }
802

    
803
        public int getInversedIndex(long rowIndex) {
804
                int intervalNotDeleted = 0;
805
                int antDeleted = -1;
806
                int idPedido = (int) rowIndex;
807
                int numNotDeleted = 0;
808
                int numBorradosAnt = 0;
809

    
810
                for (int i = delRows.nextSetBit(0); i >= 0; i = delRows
811
                                .nextSetBit(i + 1)) {
812
                        intervalNotDeleted = i - antDeleted - 1;
813
                        numNotDeleted += intervalNotDeleted;
814
                        if (i > idPedido) {
815
                                numNotDeleted = numNotDeleted + (i - idPedido);
816
                                break;
817
                        }
818
                        numBorradosAnt++;
819
                        antDeleted = i;
820
                }
821
                numNotDeleted = idPedido - numBorradosAnt;
822
                // System.out.println("Piden Viejo : "+ rowIndex + " y devuelvo como
823
                // nuevo " + (numNotDeleted));
824
                return numNotDeleted;
825
        }
826

    
827
        /**
828
         * DOCUMENT ME!
829
         * 
830
         * @param rowIndex
831
         *            DOCUMENT ME!
832
         * 
833
         * @return DOCUMENT ME!
834
         */
835
        public int getCalculatedIndex(long rowIndex) {
836
                int numNotDeleted = 0;
837
                int intervalNotDeleted = 0;
838
                int antDeleted = -1;
839
                int calculatedIndex;
840
                int idPedido = (int) rowIndex;
841
                int numBorradosAnt = 0;
842

    
843
                for (int i = delRows.nextSetBit(0); i >= 0; i = delRows
844
                                .nextSetBit(i + 1)) {
845
                        intervalNotDeleted = i - antDeleted - 1;
846
                        numNotDeleted += intervalNotDeleted;
847
                        if (numNotDeleted > idPedido) {
848
                                break;
849
                        }
850
                        numBorradosAnt++;
851
                        antDeleted = i;
852
                }
853
                calculatedIndex = numBorradosAnt + idPedido;
854
                // System.out.println("Piden Registro : "+ rowIndex + " y devuelvo el "
855
                // + (calculatedIndex));
856
                return calculatedIndex;
857
        }
858

    
859
        /**
860
         * DOCUMENT ME!
861
         * 
862
         * @author Vicente Caballero Navarro
863
         */
864
        private class myObjectDriver implements ObjectDriver {
865
                /*
866
                 * (non-Javadoc)
867
                 * 
868
                 * @see com.hardcode.gdbms.engine.data.driver.ObjectDriver#getPrimaryKeys()
869
                 */
870
                public int[] getPrimaryKeys() throws DriverException {
871
                        return ods.getPrimaryKeys();
872
                        // int[] pk=new int[1];
873
                        /*
874
                         * for (int i=0;i<getRowCount();i++){ pk[i]=i; }
875
                         */
876
                        // pk[0]=1;
877
                        // return pk;
878
                }
879

    
880
                /*
881
                 * (non-Javadoc)
882
                 * 
883
                 * @see com.hardcode.gdbms.engine.data.driver.ObjectDriver#write(com.hardcode.gdbms.engine.data.edition.DataWare)
884
                 */
885
                public void write(DataWare dataWare) throws DriverException {
886
                        DataWare dataWareOrig = ods
887
                                        .getDataWare(DataSourceFactory.DATA_WARE_DIRECT_MODE);
888
                        dataWareOrig.commitTrans();
889
                }
890

    
891
                /*
892
                 * (non-Javadoc)
893
                 * 
894
                 * @see com.hardcode.gdbms.engine.data.driver.GDBMSDriver#setDataSourceFactory(com.hardcode.gdbms.engine.data.DataSourceFactory)
895
                 */
896
                public void setDataSourceFactory(DataSourceFactory dsf) {
897
                        ods.setDataSourceFactory(dsf);
898
                }
899

    
900
                /*
901
                 * (non-Javadoc)
902
                 * 
903
                 * @see com.hardcode.driverManager.Driver#getName()
904
                 */
905
                public String getName() {
906
                        return ods.getName();
907
                }
908

    
909
                /*
910
                 * (non-Javadoc)
911
                 * 
912
                 * @see com.hardcode.gdbms.engine.data.driver.ReadAccess#getFieldValue(long,
913
                 *      int)
914
                 */
915
                public Value getFieldValue(long rowIndex, int fieldId)
916
                                throws DriverException {
917
                        // Si no est? en el fichero de expansi?n
918
                        // Integer integer = new Integer(getCalculatedIndex(rowIndex));
919

    
920

    
921
                        try {
922
                                IRow row = getRow((int)rowIndex);
923
                                return row.getAttribute(fieldId);
924
//                                if (!relations.containsKey(integer)) {
925
//                                        return ods.getFieldValue(rowIndex, fieldId);
926
//                                } else {
927
//                                        int num = ((Integer) relations.get(integer)).intValue();
928
//                                        DefaultRowEdited feat = (DefaultRowEdited) expansionFile
929
//                                                        .getRow(num);
930
//
931
//                                        if (feat == null) {
932
//                                                return null;
933
//                                        }
934
//
935
//                                        return feat.getAttribute(fieldId);
936
//                                }
937
//                        } catch (DriverException e) {
938
//                                e.printStackTrace();
939
//                                throw new DriverException(e);
940
                        } catch (IOException e) {
941
                                e.printStackTrace();
942
                                throw new DriverException(e);
943
                        } catch (DriverIOException e) {
944
                                e.printStackTrace();
945
                                throw new DriverException(e);
946
                        }
947

    
948
                        /**
949
                         * try { if (!relations.containsKey(integer)) { // Si ha sido
950
                         * eliminada if (delRows.get(integer.intValue())) { return null; }
951
                         * else { return ods.getFieldValue(rowIndex, fieldId); }} else { int
952
                         * num = ((Integer) relations.get(integer)).intValue();
953
                         * DefaultRowEdited feat = (DefaultRowEdited)
954
                         * expansionFile.getRow(num); if (feat==null)return null; return
955
                         * feat.getAttribute(fieldId); }} catch (DriverException e) {
956
                         * e.printStackTrace(); throw new DriverException(e); } catch
957
                         * (IOException e) { e.printStackTrace(); throw new
958
                         * DriverException(e); }
959
                         */
960
                }
961

    
962
                /*
963
                 * (non-Javadoc)
964
                 * 
965
                 * @see com.hardcode.gdbms.engine.data.driver.ReadAccess#getFieldCount()
966
                 */
967
                public int getFieldCount() throws DriverException {
968
                        return actualFields.size();
969
                }
970

    
971
                /*
972
                 * (non-Javadoc)
973
                 * 
974
                 * @see com.hardcode.gdbms.engine.data.driver.ReadAccess#getFieldName(int)
975
                 */
976
                public String getFieldName(int fieldId) throws DriverException {
977
                        
978
                        for (Iterator iter = actualFields.values().iterator(); iter.hasNext();) {
979
                                InternalField fld = (InternalField) iter.next();
980
                                if (fld.getFieldIndex() == fieldId)
981
                                        return fld.getFieldDesc().getFieldAlias();
982
                                
983
                        }
984
                        throw new DriverException("FieldId " + fieldId + " not found ");
985
                        // return null;
986
                        // return ods.getFieldName(fieldId);
987
                }
988

    
989
                /*
990
                 * (non-Javadoc)
991
                 * 
992
                 * @see com.hardcode.gdbms.engine.data.driver.ReadAccess#getRowCount()
993
                 */
994
                public long getRowCount() {
995
                        try {
996
                                return (int) (ods.getRowCount() + numAdd)
997
                                                - delRows.cardinality();// -
998
                                // expansionFile.getInvalidRows().cardinality();
999
                        } catch (DriverException e) {
1000
                                // TODO Auto-generated catch block
1001
                                e.printStackTrace();
1002
                        }
1003

    
1004
                        return 0;
1005
                }
1006

    
1007
                /*
1008
                 * (non-Javadoc)
1009
                 * 
1010
                 * @see com.hardcode.gdbms.engine.data.driver.ReadAccess#getFieldType(int)
1011
                 */
1012
                public int getFieldType(int i) throws DriverException {
1013
                        for (Iterator iter = actualFields.values().iterator(); iter.hasNext();) {
1014
                                InternalField fld = (InternalField) iter.next();
1015
                                if (fld.getFieldIndex() == i)
1016
                                        return fld.getFieldDesc().getFieldType();
1017
                                
1018
                        }
1019
                        
1020
                        return ods.getFieldType(i);
1021
                }
1022

    
1023
                public int getFieldWidth(int i) throws DriverException {
1024
                        for (Iterator iter = actualFields.values().iterator(); iter.hasNext();) {
1025
                                InternalField fld = (InternalField) iter.next();
1026
                                if (fld.getFieldIndex() == i)
1027
                                        return fld.getFieldDesc().getFieldLength();
1028
                                
1029
                        }
1030

    
1031
                        return ods.getFieldWidth(i);
1032
                }
1033
        }
1034

    
1035
        public CommandRecord getCommandRecord() {
1036
                return cr;
1037
        }
1038

    
1039
        protected void fireAfterRemoveRow(int index, int sourceType) {
1040
                AfterRowEditEvent event = new AfterRowEditEvent(this, index,
1041
                                EditionEvent.CHANGE_TYPE_DELETE, sourceType);
1042
                for (int i = 0; i < editionListeners.size(); i++) {
1043
                        IEditionListener listener = (IEditionListener) editionListeners
1044
                                        .get(i);
1045
                        listener.afterRowEditEvent(event);
1046
                }
1047

    
1048
        }
1049

    
1050
        protected boolean fireBeforeRemoveRow(int index, int sourceType) {
1051
                Cancel cancel = new Cancel();
1052
                BeforeRowEditEvent event = new BeforeRowEditEvent(this, index,
1053
                                EditionEvent.CHANGE_TYPE_DELETE, cancel, sourceType);
1054
                for (int i = 0; i < editionListeners.size(); i++) {
1055
                        IEditionListener listener = (IEditionListener) editionListeners
1056
                                        .get(i);
1057
                        listener.beforeRowEditEvent(null, event);
1058
                        if (cancel.isCanceled())
1059
                                return true;
1060
                }
1061
                return false;
1062
        }
1063

    
1064
        protected void fireAfterRowAdded(int calculatedIndex, int sourceType) {
1065
                AfterRowEditEvent event = new AfterRowEditEvent(this, calculatedIndex,
1066
                                EditionEvent.CHANGE_TYPE_ADD, sourceType);
1067
                for (int i = 0; i < editionListeners.size(); i++) {
1068
                        IEditionListener listener = (IEditionListener) editionListeners
1069
                                        .get(i);
1070
                        listener.afterRowEditEvent(event);
1071
                }
1072
        }
1073

    
1074
        protected boolean fireBeforeRowAdded(int sourceType)
1075
                        throws DriverIOException, IOException {
1076
                Cancel cancel = new Cancel();
1077
                BeforeRowEditEvent event = new BeforeRowEditEvent(this, getRowCount(),
1078
                                EditionEvent.CHANGE_TYPE_ADD, cancel, sourceType);
1079
                for (int i = 0; i < editionListeners.size(); i++) {
1080
                        IEditionListener listener = (IEditionListener) editionListeners
1081
                                        .get(i);
1082
                        listener.beforeRowEditEvent(null, event);
1083
                        if (cancel.isCanceled())
1084
                                return true;
1085
                }
1086
                return false;
1087
        }
1088

    
1089
        protected boolean fireBeforeModifyRow(IRow feat, int index, int sourceType) {
1090
                Cancel cancel = new Cancel();
1091
                BeforeRowEditEvent event = new BeforeRowEditEvent(this, index,
1092
                                EditionEvent.CHANGE_TYPE_MODIFY, cancel, sourceType);
1093
                for (int i = 0; i < editionListeners.size(); i++) {
1094
                        IEditionListener listener = (IEditionListener) editionListeners
1095
                                        .get(i);
1096
                        listener.beforeRowEditEvent(feat, event);
1097
                        if (cancel.isCanceled())
1098
                                return true;
1099
                }
1100
                return false;
1101
        }
1102

    
1103
        protected void fireAfterModifyRow(int index, int sourceType) {
1104
                AfterRowEditEvent event = new AfterRowEditEvent(this, index,
1105
                                EditionEvent.CHANGE_TYPE_MODIFY, sourceType);
1106
                for (int i = 0; i < editionListeners.size(); i++) {
1107
                        IEditionListener listener = (IEditionListener) editionListeners
1108
                                        .get(i);
1109
                        listener.afterRowEditEvent(event);
1110
                }
1111

    
1112
        }
1113

    
1114
        protected void fireStartEditionEvent(int sourceType) {
1115
                EditionEvent ev = new EditionEvent(this, EditionEvent.START_EDITION,
1116
                                sourceType);
1117
                for (int i = 0; i < editionListeners.size(); i++) {
1118
                        IEditionListener listener = (IEditionListener) editionListeners
1119
                                        .get(i);
1120
                        listener.processEvent(ev);
1121
                }
1122

    
1123
        }
1124

    
1125
        protected void fireStopEditionEvent(int sourceType) {
1126
                EditionEvent ev = new EditionEvent(this, EditionEvent.STOP_EDITION,
1127
                                sourceType);
1128
                for (int i = 0; i < editionListeners.size(); i++) {
1129
                        IEditionListener listener = (IEditionListener) editionListeners
1130
                                        .get(i);
1131
                        listener.processEvent(ev);
1132
                }
1133

    
1134
        }
1135

    
1136
        protected void fireCancelEditionEvent(int sourceType) {
1137
                EditionEvent ev = new EditionEvent(this, EditionEvent.CANCEL_EDITION,
1138
                                sourceType);
1139
                for (int i = 0; i < editionListeners.size(); i++) {
1140
                        IEditionListener listener = (IEditionListener) editionListeners
1141
                                        .get(i);
1142
                        listener.processEvent(ev);
1143
                }
1144

    
1145
        }
1146

    
1147
        public void addEditionListener(IEditionListener listener) {
1148
                if (!editionListeners.contains(listener))
1149
                        editionListeners.add(listener);
1150
        }
1151

    
1152
        public void removeEditionListener(IEditionListener listener) {
1153
                editionListeners.remove(listener);
1154
        }
1155

    
1156
        public IWriter getWriter() {
1157
                return writer;
1158
        }
1159

    
1160
        protected void setWriter(IWriter writer) {
1161
                this.writer = writer;
1162

    
1163
        }
1164

    
1165
        public ITableDefinition getTableDefinition() throws DriverLoadException,
1166
                        DriverException {
1167
                TableDefinition tableDef = new TableDefinition();
1168
                tableDef.setFieldsDesc(getRecordset().getFieldsDescription());
1169
                tableDef.setName(getRecordset().getSourceInfo().name);
1170
                return tableDef;
1171
        }
1172

    
1173
        public void validateRow(IRow row) throws EditionException {
1174
                for (int i = 0; i < rules.size(); i++) {
1175
                        IRule rule = (IRule) rules.get(i);
1176
                        boolean bAux = rule.validate(row);
1177
                        if (bAux == false) {
1178
                                EditionException ex = new EditionException(
1179
                                                "NOT follow the rule: " + rule.getDescription());
1180
                                // TODO: Lanzar una RuleException con datos como el registro
1181
                                // que no cumple, la regla que no lo ha cumplido, etc.
1182
                                throw ex;
1183
                        }
1184
                }
1185
        }
1186

    
1187
        public ArrayList getRules() {
1188
                return rules;
1189
        }
1190

    
1191
        public void setRules(ArrayList rules) {
1192
                this.rules = rules;
1193
        }
1194

    
1195
        private void clean() throws IOException, DriverException {
1196
                expansionFile.close();
1197
                relations.clear();
1198
                numAdd = 0;
1199
                delRows.clear();
1200
                // TODO: Es muy probable que necesitemos un reload de los datasources, al
1201
                // igual que lo tenemos en las capas. Por ahora, basta con retocar
1202
                // listInternalFields, pero casi seguro que lo correcto ser?a hacer un
1203
                // reload completo.
1204
                initalizeFields(ods);
1205
                
1206
//                listInternalFields.clear();
1207
//                listInternalFields.add(actualFields);
1208
        }
1209

    
1210
        /*
1211
         * (non-Javadoc)
1212
         * 
1213
         * @see com.iver.cit.gvsig.fmap.edition.IEditableSource#getFieldManager()
1214
         */
1215
        public IFieldManager getFieldManager() {
1216
                if (ods.getDriver() instanceof IFieldManager)
1217
                        return (IFieldManager) ods.getDriver();
1218
                return null;
1219
        }
1220

    
1221
        /**
1222
         * Tiene en cuenta los campos actuales para formatear una row con ellos. Le
1223
         * pasamos los campos que hab?a en el momento en que se cre? esa row.
1224
         * 
1225
         * @param edRow
1226
         * @param indexInternalFields
1227
         * @return
1228
         */
1229
        public IRowEdited createExternalRow(IRowEdited edRow,
1230
                        int indexInternalFields) {
1231
                Value[] att = edRow.getAttributes();
1232
                TreeMap ancientFields = (TreeMap) listInternalFields
1233
                                .get(indexInternalFields);
1234
                Value[] newAtt = new Value[actualFields.size()];
1235
                Collection aux = actualFields.values();
1236
                Iterator it = aux.iterator();
1237
                int i = 0;
1238
                Value val = null;
1239
                while (it.hasNext()) {
1240
                        InternalField fld = (InternalField) it.next();
1241
                        System.err.println("fld = " + fld.getFieldDesc().getFieldAlias() + " index=" + fld.getFieldIndex() + " id=" + fld.getFieldId());
1242
                        if (ancientFields.containsKey(fld.getFieldId())) {
1243
                                InternalField ancientField = (InternalField) ancientFields
1244
                                                .get(fld.getFieldId());
1245
                                val = att[ancientField.getFieldIndex()];
1246
                                System.out.println("fld: " + fld.getFieldDesc().getFieldAlias() + " ancient:" + ancientField.getFieldIndex() + " val" + val);
1247
                        } else
1248
                                val = fld.getFieldDesc().getDefaultValue();
1249
                        newAtt[i++] = val;
1250
                }
1251
                IRowEdited newRow = (IRowEdited) edRow.cloneRow();
1252
                newRow.setAttributes(newAtt);
1253
                return newRow;
1254
        }
1255

    
1256
        public void removeField(String fieldName) throws EditionException {
1257

    
1258
                InternalField fld = findFieldByName(fieldName);
1259
                if (fld == null)
1260
                        throw new EditionException("Field " + fieldName + " not found when removing field");
1261
                Command command = new RemoveFieldCommand(this, fld);
1262
                if (complex) {
1263
                        commands.add(command);
1264
                } else {
1265
                        cr.pushCommand(command);
1266
                }
1267
                doRemoveField(fld);
1268

    
1269
        }
1270

    
1271
        private InternalField findFieldByName(String fieldName) {
1272
                Collection aux = actualFields.values();
1273
                Iterator it = aux.iterator();
1274
                while (it.hasNext()) {
1275
                        InternalField fld = (InternalField) it.next();
1276
                        if (fld.getFieldDesc().getFieldName().compareToIgnoreCase(fieldName) == 0)
1277
                                return fld;
1278
                }
1279
                
1280
                return null;
1281
        }
1282

    
1283
        public void undoRemoveField(InternalField field) throws EditionException {
1284
                field.setDeleted(false);
1285
                field.setFieldIndex(actualFields.size());
1286
                actualFields.put(field.getFieldId(), field);
1287
                fieldsChanged();
1288
        }
1289

    
1290
        public void doRemoveField(InternalField field) throws EditionException {
1291
                field.setDeleted(true);
1292
                actualFields.remove(field.getFieldId());
1293
                fieldsChanged();
1294
        }
1295

    
1296
        public void renameField(String antName, String newName) throws EditionException {
1297

    
1298
                InternalField fld = findFieldByName(antName);
1299
                Command command = new RenameFieldCommand(this, fld, newName);
1300
                if (complex) {
1301
                        commands.add(command);
1302
                } else {
1303
                        cr.pushCommand(command);
1304
                }
1305
                doRenameField(fld, newName);
1306

    
1307
        }
1308
        
1309
        public void undoRenameField(InternalField field, String antName) {
1310
                field.getFieldDesc().setFieldAlias(antName);
1311
        }
1312

    
1313
        public void doRenameField(InternalField field, String newName) {
1314
                field.getFieldDesc().setFieldAlias(newName);
1315
        }
1316

    
1317

    
1318
        public void addField(FieldDescription field) throws EditionException {
1319

    
1320
                InternalField fld = new InternalField(field, InternalField.ADDED, new Integer(listFields.size()));
1321
                Command command = new AddFieldCommand(this, fld);
1322
                if (complex) {
1323
                        commands.add(command);
1324
                } else {
1325
                        cr.pushCommand(command);
1326
                }
1327
                listFields.add(fld);
1328
                doAddField(fld);
1329

    
1330
        }
1331

    
1332
        public void undoAddField(InternalField field) throws EditionException {
1333
                field.setDeleted(true);
1334
                
1335
                actualFields.remove(field.getFieldId());
1336
                fieldsChanged();
1337
                
1338
        }
1339

    
1340
        public void doAddField(InternalField field) throws EditionException {
1341
                field.setDeleted(false);
1342
                field.setFieldIndex(actualFields.size());
1343
                actualFields.put(field.getFieldId(), field);
1344
                fieldsChanged();
1345
                
1346
        }
1347
        
1348
}