Statistics
| Revision:

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

History | View | Annotate | Download (44.5 KB)

1 3940 caballero
package com.iver.cit.gvsig.fmap.edition;
2
3 4061 caballero
import java.io.IOException;
4 4832 fjp
import java.util.ArrayList;
5 6212 fjp
import java.util.Collection;
6 4061 caballero
import java.util.HashMap;
7 6212 fjp
import java.util.Iterator;
8
import java.util.TreeMap;
9 3940 caballero
10 5569 jmvivo
import com.hardcode.driverManager.Driver;
11 4061 caballero
import com.hardcode.driverManager.DriverLoadException;
12 3940 caballero
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 4026 caballero
import com.iver.cit.gvsig.fmap.core.DefaultRow;
19 3940 caballero
import com.iver.cit.gvsig.fmap.core.IRow;
20
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
21 6212 fjp
import com.iver.cit.gvsig.fmap.drivers.FieldDescription;
22 5558 fjp
import com.iver.cit.gvsig.fmap.drivers.ITableDefinition;
23
import com.iver.cit.gvsig.fmap.drivers.TableDefinition;
24 6356 fjp
import com.iver.cit.gvsig.fmap.drivers.dbf.DBFDriver;
25 6212 fjp
import com.iver.cit.gvsig.fmap.edition.commands.AddFieldCommand;
26 3940 caballero
import com.iver.cit.gvsig.fmap.edition.commands.AddRowCommand;
27 4120 caballero
import com.iver.cit.gvsig.fmap.edition.commands.Command;
28 3940 caballero
import com.iver.cit.gvsig.fmap.edition.commands.CommandCollection;
29
import com.iver.cit.gvsig.fmap.edition.commands.CommandRecord;
30
import com.iver.cit.gvsig.fmap.edition.commands.MemoryCommandRecord;
31
import com.iver.cit.gvsig.fmap.edition.commands.ModifyRowCommand;
32 6212 fjp
import com.iver.cit.gvsig.fmap.edition.commands.RemoveFieldCommand;
33 3940 caballero
import com.iver.cit.gvsig.fmap.edition.commands.RemoveRowCommand;
34 6212 fjp
import com.iver.cit.gvsig.fmap.edition.commands.RenameFieldCommand;
35
import com.iver.cit.gvsig.fmap.edition.fieldmanagers.AbstractFieldManager;
36 5886 fjp
import com.iver.cit.gvsig.fmap.edition.rules.IRule;
37 3940 caballero
import com.iver.cit.gvsig.fmap.layers.FBitSet;
38
import com.iver.cit.gvsig.fmap.layers.LayerFactory;
39
import com.iver.cit.gvsig.fmap.layers.SelectableDataSource;
40 4832 fjp
import com.iver.cit.gvsig.fmap.operations.Cancel;
41 3940 caballero
42
/**
43
 * DOCUMENT ME!
44 6212 fjp
 *
45 3940 caballero
 * @author Vicente Caballero Navarro
46
 */
47 5595 fjp
public class EditableAdapter implements IEditableSource, IWriteable {
48 4792 fjp
        protected boolean isEditing = false;
49 3996 caballero
50 4792 fjp
        private SelectableDataSource ds = null;
51 3940 caballero
52 4792 fjp
        protected FBitSet delRows = new FBitSet();
53 3940 caballero
54 4792 fjp
        private CommandRecord cr;
55 6212 fjp
56 5549 fjp
        protected IWriter writer;
57 3940 caballero
58 4792 fjp
        /**
59
         * Flag que indica que hay que tomar las siguientes operaciones como una
60
         * operaci?n at?mica
61
         */
62
        private boolean complex = false;
63 3940 caballero
64 4792 fjp
        private CommandCollection commands = null;
65 3940 caballero
66 6212 fjp
        protected ArrayList listFields = new ArrayList();
67
68
        protected ArrayList listInternalFields = new ArrayList();
69 6483 fjp
70
        protected boolean bFieldsHasBeenChanged = false;
71 6212 fjp
72
        /**
73 6483 fjp
         * La clave ser? el fieldId. Para buscar si un value de una row ha de ser
74 6212 fjp
         * rellenado con defaultValue o con lo que venga del expansion file,
75
         * miraremos si existe en este hash. Si existe, usamos el value del
76
         * expansion file. Si no existe, usamos el defaultValue del campo busc?ndolo
77
         * en la lista internalFields. Por cierto, en listInternalFields NO se
78 6483 fjp
         * borran campos. Solo se van a?adiendo nuevos actualFields.
79 6212 fjp
         */
80 6483 fjp
        protected TreeMap actualFields; // la clave ser? el fieldId.
81
82
        protected ArrayList fastAccessFields = new ArrayList();
83 6212 fjp
84
        protected class MyFieldManager extends AbstractFieldManager {
85
86
                public boolean alterTable() throws EditionException {
87
                        return getFieldManager().alterTable();
88
                }
89
90
                public void addField(FieldDescription fieldDesc) {
91
                        super.addField(fieldDesc);
92
                }
93
94
                public FieldDescription removeField(String fieldName) {
95
                        // TODO Auto-generated method stub
96
                        return super.removeField(fieldName);
97
                }
98
99
                public void renameField(String antName, String newName) {
100
                        // TODO Auto-generated method stub
101
                        super.renameField(antName, newName);
102
                }
103
104
        }
105
106 4792 fjp
        /*
107
         * Establece una relaci?n entre los ?ndices de las geometr?as en el
108
         * EditableFeatureSource y los ?ndices en el fichero de expansi?n FJP:
109
         * CAMBIO: NECESITAMOS TRABAJAR CON FEATURE Y FEATUREITERATOR PARA IR
110
         * PREPARANDO EL CAMINO, GUARDAMOS EL FEATUREID (STRING) COMO CLAVE, Y COMO
111
         * VALOR, EL INDICE DENTRO DEL FICHERO DE EXPANSION (Integer). Lo de que
112
         * FeatureId sea un String es por compatibilidad con OGC. Seg?n OGC, una
113
         * Feature tiene que tener un Id string En el caso de los randomaccess,
114
         * ser?n el id de registro En los casos de base de datos espaciales, supongo
115
         * que siempre ser? num?rico tambi?n, pero lo tendremos que convertir a
116
         * string. Lo que est? claro es que NO se puede confiar nunca en que sea
117
         * algo correlativo (1, 2, 3, 4, 5, ... => FALSO!!)
118
         */
119
        protected HashMap relations = new HashMap();
120 3940 caballero
121 4792 fjp
        /*
122
         * Fichero en el que se guardan las nuevas geometr?as, producto de adiciones
123
         * o de modificaciones
124
         */
125
        protected ExpansionFile expansionFile;
126 3940 caballero
127 4792 fjp
        protected int numAdd = 0;
128 3940 caballero
129 4792 fjp
        private ObjectDriver editingDriver = new myObjectDriver();
130 3996 caballero
131 4792 fjp
        private SelectableDataSource ods;
132 4954 caballero
133 4832 fjp
        private ArrayList editionListeners = new ArrayList();
134 3940 caballero
135 5886 fjp
        private ArrayList rules = new ArrayList();
136
137 6212 fjp
        protected int actualIndexFields;
138
139 4792 fjp
        /**
140
         * Crea un nuevo EditableAdapter.
141
         */
142
        public EditableAdapter() {
143 6212 fjp
                expansionFile = new MemoryExpansionFile(this);
144 4792 fjp
                cr = new MemoryCommandRecord();
145
        }
146 3940 caballero
147 4792 fjp
        /**
148
         * DOCUMENT ME!
149 6212 fjp
         *
150 4792 fjp
         * @param ds
151
         *            DOCUMENT ME!
152 6212 fjp
         * @throws DriverException
153 4792 fjp
         */
154 6212 fjp
        public void setOriginalDataSource(SelectableDataSource ds) throws DriverException {
155 4792 fjp
                this.ods = ds;
156 6313 fjp
                initalizeFields(ds);
157
158
        }
159
160
        /**
161
         * @param ds
162
         * @throws DriverException
163
         */
164
        private void initalizeFields(SelectableDataSource ds) throws DriverException {
165 6212 fjp
                FieldDescription[] fields = ds.getFieldsDescription();
166 6313 fjp
                listInternalFields.clear();
167 6326 fjp
                actualIndexFields = 0;
168 6212 fjp
                actualFields = new TreeMap();
169 6483 fjp
//                fastAccessFields = new ArrayList();
170 6212 fjp
                for (int i=0; i < fields.length; i++)
171
                {
172
                        InternalField field = new InternalField(fields[i], InternalField.ORIGINAL, new Integer(i));
173
                        listFields.add(field);
174 6384 fjp
                        // field.setFieldIndex(i);
175 6212 fjp
                        actualFields.put(field.getFieldId(), field);
176 6483 fjp
//                        fastAccessFields.add(fields[i]);
177 6326 fjp
                        System.out.println("INITIALIZEFIELDS: FIELD " + field.getFieldDesc().getFieldAlias());
178 6212 fjp
                }
179 6259 fjp
                try {
180
                        fieldsChanged();
181 6483 fjp
                        bFieldsHasBeenChanged = false;
182 6259 fjp
                } catch (EditionException e) {
183
                        e.printStackTrace();
184
                        throw new DriverException(e);
185
                }
186 4792 fjp
        }
187 3940 caballero
188 6259 fjp
        private void fieldsChanged() throws EditionException {
189 6483 fjp
                fastAccessFields= new ArrayList();
190
                for (Iterator iter = actualFields.values().iterator(); iter.hasNext();) {
191
                        InternalField fld = (InternalField) iter.next();
192
                        fastAccessFields.add(fld.getFieldDesc());
193
                }
194 6384 fjp
195 6313 fjp
                listInternalFields.add(actualFields.clone());
196 6212 fjp
                actualIndexFields = listInternalFields.size()-1;
197 6259 fjp
                try {
198 6365 fjp
                        ds = null;
199 6259 fjp
                        getRecordset().mapExternalFields();
200 6483 fjp
                        bFieldsHasBeenChanged = true;
201 6259 fjp
                } catch (DriverLoadException e) {
202
                        e.printStackTrace();
203
                        throw new EditionException(e);
204
                } catch (DriverException e) {
205
                        e.printStackTrace();
206
                        throw new EditionException(e);
207
                }
208 6212 fjp
        }
209
210 4792 fjp
        /**
211
         * DOCUMENT ME!
212 6212 fjp
         *
213 4792 fjp
         * @throws EditionException
214
         *             DOCUMENT ME!
215
         */
216 5184 caballero
        public void startEdition(int sourceType) throws EditionException {
217 4792 fjp
                isEditing = true;
218 5558 fjp
                // Obtenemos el driver y vemos si implementa IWriter.
219 6212 fjp
                /*
220
                 * DataWare dataWare =
221
                 * ods.getDataWare(DataSourceFactory.DATA_WARE_DIRECT_MODE);
222
                 * dataWare.get
223
                 */
224 5569 jmvivo
                Driver drv = ods.getDriver();
225 6212 fjp
                if (drv instanceof IWriteable) {
226 5595 fjp
                        setWriter(((IWriteable) drv).getWriter());
227 5569 jmvivo
                }
228 5986 caballero
229 5184 caballero
                fireStartEditionEvent(sourceType);
230 4792 fjp
        }
231 3996 caballero
232 4792 fjp
        /**
233
         * Se ejecuta preProcess() del IWriter, luego se itera por los registros
234
         * borrados por si el IWriter los quiere borrar (solo ser? necesario cuando
235
         * escribimos sobre la misma tabla) y luego se itera por los nuevos
236
         * registros llamando a process con el registro correcto. (A?adidos,
237
         * modificados). Para finalizar, se ejecuta PostProcess
238 6212 fjp
         *
239 4792 fjp
         * @param writer
240
         *            IWriter que recibir? las llamadas.
241 6212 fjp
         *
242 4792 fjp
         * @throws EditionException
243
         *             DOCUMENT ME!
244
         */
245 6212 fjp
        public void stopEdition(IWriter writer, int sourceType)
246
                        throws EditionException {
247
                saveEdits(writer, sourceType);
248 6227 fjp
                isEditing = false;
249 6356 fjp
                cr.clearAll();
250 6212 fjp
                fireStopEditionEvent(sourceType);
251
        }
252
253
        public void saveEdits(IWriter writer, int sourceType)
254
                        throws EditionException {
255 6579 fjp
256
                // TODO: ARREGLAR ESTO PARA QUE CUANDO HA HABIDO CAMBIOS
257
                // EN LOS CAMPOS, PODAMOS CAMBIAR LO QUE TOQUE (A SER POSIBLE
258
                // SIN TENER QUE REESCRIBIR TODA LA TABLA CON POSTGIS)
259
                if (bFieldsHasBeenChanged)
260
                {
261
                        // Para cada campo de los originales, miramos si no est? en
262
                        // los actuales. Si no est?, le decimos al fieldManager
263
                        // que lo borre. Si est?, pero le hemos cambiado el nombre
264
                        // le pedimos al fieldManager que le cambie el nombre.
265
                        // Luego recorremos los campos actuales para ver cuales
266
                        // son nuevos, y los a?adimos.
267
268
                        TreeMap ancientFields = (TreeMap) listInternalFields
269
                                        .get(0);
270
                        Collection aux = ancientFields.values();
271
                        Iterator it = aux.iterator();
272
                        while (it.hasNext()) {
273
                                InternalField fld = (InternalField) it.next();
274
                                // System.err.println("fld = " + fld.getFieldDesc().getFieldAlias() +  " id=" + fld.getFieldId());
275
                                if (actualFields.containsKey(fld.getFieldId())) {
276
                                        // Es un original
277
                                        String f1 = fld.getFieldDesc().getFieldName();
278
                                        String f2 = fld.getFieldDesc().getFieldAlias();
279
                                        if (f1.compareTo(f2) != 0)
280
                                        {
281
                                                getFieldManager().renameField(f1, f2);
282
                                        }
283
                                }
284
                                else
285
                                {        // No est?, hay que borrarlo
286
                                        getFieldManager().removeField(fld.getFieldDesc().getFieldAlias());
287
                                }
288
                        }
289
                        Collection aux2= actualFields.values();
290
                        Iterator it2 = aux2.iterator();
291
                        while (it2.hasNext()) {
292
                                InternalField fld = (InternalField) it2.next();
293
                                // System.err.println("fld = " + fld.getFieldDesc().getFieldAlias() +  " id=" + fld.getFieldId());
294
                                if (!ancientFields.containsKey(fld.getFieldId())) {
295
                                        // Es uno a?adido
296
                                        getFieldManager().addField(fld.getFieldDesc());
297
                                }
298
                        }
299
                        // getFieldManager().alterTable(); // Se llama dentro del preprocess()
300
                }
301
302 4792 fjp
                writer.preProcess();
303 4368 caballero
304 4792 fjp
                try {
305 3940 caballero
306 4792 fjp
                        // Procesamos primero los borrados.
307
                        // Cuando se genere un tema nuevo, no se les debe hacer caso
308
                        // a estos registros
309 3996 caballero
310 6212 fjp
                        for (int i = delRows.nextSetBit(0); i >= 0; i = delRows
311
                                        .nextSetBit(i + 1)) {
312 4792 fjp
                                int calculatedIndex = i;
313
                                Integer integer = new Integer(calculatedIndex);
314
                                // Si no est? en el fichero de expansi?n, es de los originales
315
                                // y hay que borrarlo
316
                                DefaultRowEdited edRow = null;
317
                                if (!relations.containsKey(integer)) {
318
                                        edRow = new DefaultRowEdited(new DefaultRow(ods
319
                                                        .getRow(calculatedIndex)),
320
                                                        DefaultRowEdited.STATUS_DELETED, calculatedIndex);
321
                                        writer.process(edRow);
322
                                } else {
323
                                        int num = ((Integer) relations.get(integer)).intValue();
324 4061 caballero
325 4792 fjp
                                        // return expansionFile.getRow(num);
326
                                        IRowEdited rowFromExpansion = expansionFile.getRow(num);
327
                                        // ?Habr?a que hacer aqu? setID(index + "")?
328
                                        edRow = new DefaultRowEdited(rowFromExpansion
329 6212 fjp
                                                        .getLinkedRow().cloneRow(),
330
                                                        DefaultRowEdited.STATUS_DELETED, calculatedIndex);
331 4792 fjp
                                        writer.process(edRow);
332
                                }
333 3940 caballero
334 4792 fjp
                        }
335 3940 caballero
336 4792 fjp
                        int rowCount = getRowCount();
337
                        for (int i = 0; i < rowCount; i++) {
338
                                IRowEdited rowEdited = getRow(i);
339 3940 caballero
340 4792 fjp
                                if (rowEdited != null) {
341
                                        writer.process(rowEdited);
342
                                }
343
                        }
344 5668 fjp
                        writer.postProcess();
345 5986 caballero
346 6580 fjp
                        // Hacemos que el escritor se entere de los nuevos campos
347
                        // que tiene. El escritor debe guardar una referencia
348
                        // a los campos con los que trabaja el drier, de forma
349
                        // que al recargar la capa (por ejemplo en el caso de
350
                        // PostGIS, se haga un setData con los campos que se hayan
351
                        // a?adido, borrado o renombrado).
352
                        writer.getTableDefinition().setFieldsDesc(getRecordset().getFieldsDescription());
353
354 6323 fjp
                        ods.reload();
355 6326 fjp
                        ds = null;
356
                        clean();
357 6323 fjp
358 4792 fjp
                } catch (DriverIOException e) {
359
                        e.printStackTrace();
360
                        throw new EditionException(e);
361
                } catch (IOException e) {
362
                        e.printStackTrace();
363
                        throw new EditionException(e);
364
                } catch (DriverException e) {
365
                        e.printStackTrace();
366
                        throw new EditionException(e);
367
                }
368 3940 caballero
369 4792 fjp
        }
370 3940 caballero
371 4792 fjp
        /**
372
         * DOCUMENT ME!
373 6212 fjp
         *
374 4792 fjp
         * @throws IOException
375
         *             DOCUMENT ME!
376
         */
377 5184 caballero
        public void cancelEdition(int sourceType) throws IOException {
378 4792 fjp
                isEditing = false;
379 6313 fjp
                try {
380 6341 fjp
                        ds= null;
381 6313 fjp
                        clean();
382 6356 fjp
                        cr.clearAll();
383 6313 fjp
                } catch (DriverException e) {
384
                        e.printStackTrace();
385
                        throw new IOException("Error: " + e.getMessage());
386
                }
387 5184 caballero
                fireCancelEditionEvent(sourceType);
388 4792 fjp
        }
389 3940 caballero
390 4792 fjp
        /*
391
         * (non-Javadoc)
392 6212 fjp
         *
393 4792 fjp
         * @see com.iver.cit.gvsig.fmap.edition.IEditableSource#getRow(int)
394
         */
395
        public IRowEdited getRow(int index) throws DriverIOException, IOException {
396
                int calculatedIndex = getCalculatedIndex(index);
397
                Integer integer = new Integer(calculatedIndex);
398
                DefaultRowEdited edRow = null;
399
                // Si no est? en el fichero de expansi?n
400
                if (!relations.containsKey(integer)) {
401
                        try {
402
                                /*
403
                                 * edRow = new DefaultRowEdited(new
404
                                 * DefaultRow(ods.getRow(calculatedIndex), "" + index),
405
                                 * DefaultRowEdited.STATUS_ORIGINAL, index);
406
                                 */
407 6313 fjp
                                DefaultRow auxR = new DefaultRow(ods.getRow(calculatedIndex));
408
                                edRow = new DefaultRowEdited(auxR,
409 4792 fjp
                                                DefaultRowEdited.STATUS_ORIGINAL, index);
410 6313 fjp
                                return createExternalRow(edRow, 0);
411
//                                edRow = new DefaultRowEdited(new DefaultRow(ods
412
//                                                .getRow(calculatedIndex)),
413
//                                                DefaultRowEdited.STATUS_ORIGINAL, index);
414 4792 fjp
                        } catch (DriverException e) {
415
                                throw new DriverIOException(e);
416
                        }
417
                } else {
418
                        int num = ((Integer) relations.get(integer)).intValue();
419 3940 caballero
420 4792 fjp
                        // return expansionFile.getRow(num);
421 6313 fjp
                        // ExpansionFile ya entrega el registro formateado como debe
422 4792 fjp
                        IRowEdited rowFromExpansion = expansionFile.getRow(num);
423
                        // ?Habr?a que hacer aqu? setID(index + "")?
424
                        edRow = new DefaultRowEdited(rowFromExpansion.getLinkedRow()
425
                                        .cloneRow(), rowFromExpansion.getStatus(), index);
426
                        return edRow;
427
                }
428 6313 fjp
429
430
431 4792 fjp
        }
432 3940 caballero
433 4792 fjp
        /**
434
         * DOCUMENT ME!
435 6212 fjp
         *
436 4792 fjp
         * @return DOCUMENT ME!
437 6212 fjp
         *
438 4792 fjp
         * @throws DriverIOException
439
         *             DOCUMENT ME!
440
         * @throws IOException
441
         *             DOCUMENT ME!
442
         */
443
        public int getRowCount() throws DriverIOException, IOException {
444
                try {
445
                        return (int) (ods.getRowCount() + numAdd) - delRows.cardinality();// -
446 6212 fjp
                        // expansionFile.getInvalidRows().cardinality();
447 4792 fjp
                } catch (DriverException e) {
448
                        throw new DriverIOException(e);
449
                }
450
451 4637 caballero
        }
452 3940 caballero
453 6212 fjp
        /*
454
         * (non-Javadoc)
455
         *
456
         * @see com.iver.cit.gvsig.fmap.edition.IEditableSource#addRow(com.iver.cit.gvsig.fmap.core.IRow,
457
         *      java.lang.String)
458 4792 fjp
         */
459 6212 fjp
        public int addRow(IRow row, String descrip, int sourceType)
460
                        throws DriverIOException, IOException {
461 6071 caballero
462 6002 fjp
                try {
463
                        validateRow(row);
464
                } catch (EditionException e) {
465
                        e.printStackTrace();
466
                        throw new IOException(e.getMessage());
467 5886 fjp
                }
468 5077 caballero
469 5184 caballero
                int calculatedIndex = doAddRow(row, sourceType);
470 6212 fjp
                Command command = new AddRowCommand(this, row, calculatedIndex,
471
                                sourceType);
472 4792 fjp
                command.setDescription(descrip);
473
                if (complex) {
474
                        commands.add(command);
475
                } else {
476
                        cr.pushCommand(command);
477
                }
478 5077 caballero
479 4792 fjp
                return calculatedIndex;
480
        }
481 3940 caballero
482 4792 fjp
        /**
483
         * DOCUMENT ME!
484 6212 fjp
         *
485 4792 fjp
         * @throws DriverIOException
486
         *             DOCUMENT ME!
487
         * @throws IOException
488
         *             DOCUMENT ME!
489
         */
490
        public void undo() throws DriverIOException, IOException {
491
                // seleccion.clear();
492 6127 fjp
                if (cr.moreUndoCommands()) {
493 4792 fjp
                        cr.undoCommand();
494
                }
495
        }
496 3940 caballero
497 4792 fjp
        /**
498
         * DOCUMENT ME!
499 6212 fjp
         *
500 4792 fjp
         * @throws DriverIOException
501
         *             DOCUMENT ME!
502
         * @throws IOException
503
         *             DOCUMENT ME!
504
         */
505
        public void redo() throws DriverIOException, IOException {
506
                // seleccion.clear();
507 6127 fjp
                if (cr.moreRedoCommands()) {
508 4792 fjp
                        cr.redoCommand();
509
                }
510
        }
511 3940 caballero
512 6212 fjp
        /*
513 4792 fjp
         * (non-Javadoc)
514 6212 fjp
         *
515 4792 fjp
         * @see com.iver.cit.gvsig.fmap.edition.IEditableSource#removeRow(int)
516
         */
517 6212 fjp
        public void removeRow(int index, String descrip, int sourceType)
518
                        throws IOException, DriverIOException {
519 5077 caballero
520 4792 fjp
                int calculatedIndex = getCalculatedIndex(index);
521 6212 fjp
                Command command = new RemoveRowCommand(this, calculatedIndex,
522
                                sourceType);
523 4792 fjp
                command.setDescription(descrip);
524
                if (complex) {
525
                        commands.add(command);
526
                } else {
527
                        cr.pushCommand(command);
528
                }
529 5184 caballero
                doRemoveRow(calculatedIndex, sourceType);
530 5077 caballero
531 4792 fjp
        }
532 3940 caballero
533 4792 fjp
        /*
534
         * (non-Javadoc)
535 6212 fjp
         *
536 4792 fjp
         * @see com.iver.cit.gvsig.fmap.edition.IEditableSource#modifyRow(int,
537
         *      com.iver.cit.gvsig.fmap.core.IRow)
538
         */
539 5184 caballero
        public int modifyRow(int index, IRow row, String descrip, int sourceType)
540 4792 fjp
                        throws IOException, DriverIOException {
541 4954 caballero
542 6002 fjp
                try {
543
                        validateRow(row);
544
                } catch (EditionException e) {
545
                        e.printStackTrace();
546
                        throw new IOException(e.getMessage());
547 5886 fjp
                }
548
549 4792 fjp
                int calculatedIndex = getCalculatedIndex(index);
550 5184 caballero
                int pos = doModifyRow(calculatedIndex, row, sourceType);
551 6212 fjp
                Command command = new ModifyRowCommand(this, calculatedIndex, pos, row,
552
                                sourceType);
553 4792 fjp
                command.setDescription(descrip);
554
                if (complex) {
555
                        commands.add(command);
556
                } else {
557
                        cr.pushCommand(command);
558
                }
559 5077 caballero
560 4792 fjp
                return pos;
561
        }
562 3940 caballero
563 4792 fjp
        /**
564
         * DOCUMENT ME!
565
         */
566
        public void compact() {
567
                expansionFile.compact(relations);
568
        }
569 3996 caballero
570 4792 fjp
        /**
571
         * DOCUMENT ME!
572
         */
573
        public void startComplexRow() {
574
                complex = true;
575
                commands = new CommandCollection();
576
        }
577 3996 caballero
578 4792 fjp
        /**
579
         * DOCUMENT ME!
580 6212 fjp
         *
581 4792 fjp
         * @throws IOException
582
         *             DOCUMENT ME!
583
         * @throws DriverIOException
584
         *             DOCUMENT ME!
585
         */
586 6212 fjp
        public void endComplexRow(String description) throws IOException,
587
                        DriverIOException {
588 6071 caballero
                commands.setDescription(description);
589 4792 fjp
                cr.pushCommand(commands);
590
                complex = false;
591
        }
592 3940 caballero
593 4792 fjp
        /**
594
         * Actualiza en el mapa de ?ndices, la posici?n en la que estaba la
595
         * geometr?a antes de ser modificada. Se marca como v?lida, en caso de que
596
         * fuera una modificaci?n de una geometr?a que estuviese en el fichero de
597
         * expansi?n antes de ser modificada y se pone el puntero de escritura del
598
         * expansion file a justo despues de la penultima geometr?a
599 6212 fjp
         *
600 4792 fjp
         * @param geometryIndex
601
         *            ?ndice de la geometr?a que se quiere deshacer su modificaci?n
602
         * @param previousExpansionFileIndex
603
         *            ?ndice que ten?a antes la geometr?a en el expansionFile. Si
604
         *            vale -1 quiere decir que es una modificaci?n de una geometr?a
605
         *            original y por tanto no hay que actualizar el mapa de indices
606
         *            sino eliminar su entrada.
607 6212 fjp
         *
608 4792 fjp
         * @throws IOException
609
         * @throws DriverIOException
610
         */
611 6212 fjp
        public void undoModifyRow(int geometryIndex,
612
                        int previousExpansionFileIndex, int sourceType) throws IOException,
613
                        DriverIOException {
614 5197 caballero
615 4792 fjp
                if (previousExpansionFileIndex == -1) {
616 6212 fjp
                        DefaultRowEdited edRow = null;
617 5197 caballero
                        try {
618
                                edRow = new DefaultRowEdited(new DefaultRow(ods
619
                                                .getRow(geometryIndex)),
620 6212 fjp
                                                DefaultRowEdited.STATUS_ORIGINAL, geometryIndex);
621 5197 caballero
                        } catch (DriverException e) {
622
                                e.printStackTrace();
623
                        }
624 6212 fjp
                        boolean cancel = fireBeforeModifyRow(edRow, geometryIndex,
625
                                        sourceType);
626 5197 caballero
                        if (cancel)
627
                                return;
628 4792 fjp
                        // Se elimina de las relaciones y del fichero de expansi?n
629
                        relations.remove(new Integer(geometryIndex));
630
                        expansionFile.deleteLastRow();
631
                } else {
632 6212 fjp
                        boolean cancel = fireBeforeModifyRow(expansionFile
633
                                        .getRow(previousExpansionFileIndex), geometryIndex,
634
                                        sourceType);
635 5197 caballero
                        if (cancel)
636
                                return;
637 4792 fjp
                        // Se actualiza la relaci?n de ?ndices
638
                        relations.put(new Integer(geometryIndex), new Integer(
639
                                        previousExpansionFileIndex));
640
                }
641 6212 fjp
                fireAfterModifyRow(geometryIndex, sourceType);
642 4792 fjp
        }
643 3940 caballero
644 4792 fjp
        /**
645
         * Elimina una geometria. Si es una geometr?a original de la capa en edici?n
646
         * se marca como eliminada (haya sido modificada o no). Si es una geometr?a
647
         * a?adida posteriormente se invalida en el fichero de expansi?n, para que
648
         * una futura compactaci?n termine con ella.
649 6212 fjp
         *
650 4792 fjp
         * @param index
651
         *            ?ndice de la geometr?a.
652 6212 fjp
         *
653 4792 fjp
         * @throws DriverIOException
654
         * @throws IOException
655
         */
656 6212 fjp
        public IRow doRemoveRow(int index, int sourceType)
657
                        throws DriverIOException, IOException {
658 5184 caballero
                boolean cancel = fireBeforeRemoveRow(index, sourceType);
659 5077 caballero
                if (cancel)
660
                        return null;
661 4792 fjp
                // Llega un calculatedIndex
662
                delRows.set(index, true);
663
                System.err.println("Elimina una Row en la posici?n: " + index);
664
                // TODO: Con tablas no es necesario devolver la anterior feature. Por
665
                // ahora.
666 5184 caballero
                fireAfterRemoveRow(index, sourceType);
667 4792 fjp
                return null;
668
        }
669 3940 caballero
670 4792 fjp
        /**
671
         * Si se intenta modificar una geometr?a original de la capa en edici?n se
672
         * a?ade al fichero de expansi?n y se registra la posici?n en la que se
673
         * a?adi?. Si se intenta modificar una geometria que se encuentra en el
674
         * fichero de expansi?n (por ser nueva o original pero modificada) se invoca
675
         * el m?todo modifyGeometry y se actualiza el ?ndice de la geometria en el
676
         * fichero.
677 6212 fjp
         *
678 4792 fjp
         * @param index
679
         *            DOCUMENT ME!
680
         * @param feat
681
         *            DOCUMENT ME!
682 6212 fjp
         *
683 4792 fjp
         * @return DOCUMENT ME!
684 6212 fjp
         *
685 4792 fjp
         * @throws IOException
686
         * @throws DriverIOException
687
         */
688 6212 fjp
        public int doModifyRow(int index, IRow feat, int sourceType)
689
                        throws IOException, DriverIOException {
690
                boolean cancel = fireBeforeModifyRow(feat, index, sourceType);
691 5077 caballero
                if (cancel)
692
                        return -1;
693
694 4792 fjp
                int pos = -1;
695
                Integer integer = new Integer(index);
696
                System.err.println("Modifica una Row en la posici?n: " + index);
697
                // Si la geometr?a no ha sido modificada
698
                if (!relations.containsKey(integer)) {
699 6212 fjp
                        int expansionIndex = expansionFile.addRow(feat,
700
                                        IRowEdited.STATUS_MODIFIED, actualIndexFields);
701 4792 fjp
                        relations.put(integer, new Integer(expansionIndex));
702
                } else {
703
                        // Obtenemos el ?ndice en el fichero de expansi?n
704
                        int num = ((Integer) relations.get(integer)).intValue();
705
                        pos = num;
706 3940 caballero
707 4792 fjp
                        /*
708
                         * Se modifica la geometr?a y nos guardamos el ?ndice dentro del
709
                         * fichero de expansi?n en el que se encuentra la geometr?a
710
                         * modificada
711
                         */
712 6212 fjp
                        num = expansionFile.modifyRow(num, feat, actualIndexFields);
713 3940 caballero
714 4792 fjp
                        /*
715
                         * Actualiza la relaci?n del ?ndice de la geometr?a al ?ndice en el
716
                         * fichero de expansi?n.
717
                         */
718
                        relations.put(integer, new Integer(num));
719
                }
720 5184 caballero
                fireAfterModifyRow(index, sourceType);
721 4792 fjp
                return pos;
722
        }
723 3940 caballero
724 4792 fjp
        /**
725
         * A?ade una geometria al fichero de expansi?n y guarda la correspondencia
726
         * en la tabla relations.
727 6212 fjp
         *
728 4792 fjp
         * @param feat
729
         *            geometr?a a guardar.
730 6212 fjp
         *
731 4792 fjp
         * @return calculatedIndex
732 6212 fjp
         *
733 4792 fjp
         * @throws DriverIOException
734
         * @throws IOException
735
         */
736 6212 fjp
        public int doAddRow(IRow feat, int sourceType) throws DriverIOException,
737
                        IOException {
738 5184 caballero
                boolean cancel = fireBeforeRowAdded(sourceType);
739 5077 caballero
                if (cancel)
740
                        return -1;
741 4792 fjp
                // A?ade la geometr?a
742
                // int virtualIndex = 0;
743
                int calculatedIndex = -1;
744
745
                try {
746
                        calculatedIndex = (int) ods.getRowCount() + numAdd;
747
                        // int externalIndex = getRowCount();
748
                        // calculatedIndex = getCalculatedIndex(externalIndex);
749
                } catch (DriverException e) {
750
                        throw new DriverIOException(e);
751 4368 caballero
                }
752 4792 fjp
753 6212 fjp
                int pos = expansionFile.addRow(feat, IRowEdited.STATUS_ADDED, actualIndexFields);
754 4792 fjp
                relations.put(new Integer(calculatedIndex), new Integer(pos));
755
                numAdd++;
756
                System.err.println("A?ade una Row en la posici?n: " + calculatedIndex);
757 5184 caballero
                fireAfterRowAdded(calculatedIndex, sourceType);
758 4792 fjp
                return calculatedIndex;
759 4061 caballero
        }
760 3996 caballero
761 4792 fjp
        /**
762
         * Se desmarca como invalidada en el fichero de expansion o como eliminada
763
         * en el fichero original
764 6212 fjp
         *
765 4792 fjp
         * @param index
766
         *            DOCUMENT ME!
767 6212 fjp
         *
768 4792 fjp
         * @throws IOException
769
         * @throws DriverIOException
770
         */
771 6212 fjp
        public void undoRemoveRow(int index, int sourceType) throws IOException,
772
                        DriverIOException {
773 5184 caballero
                boolean cancel = fireBeforeRowAdded(sourceType);
774 5077 caballero
                if (cancel)
775
                        return;
776 4792 fjp
                delRows.set(index, false);
777 5184 caballero
                fireAfterRowAdded(index, sourceType);
778 4792 fjp
        }
779 3996 caballero
780 4792 fjp
        /**
781
         * Se elimina del final del fichero de expansi?n poniendo el puntero de
782
         * escritura apuntando al final de la pen?ltima geometr?a. Deber? quitar la
783
         * relaci?n del mapa de relaciones
784 6212 fjp
         *
785 4792 fjp
         * @param index
786
         *            ?ndice de la geometr?a que se a?adi?
787 6212 fjp
         *
788 4792 fjp
         * @throws DriverIOException
789
         * @throws IOException
790
         */
791 6212 fjp
        public void undoAddRow(int calculatedIndex, int sourceType)
792
                        throws DriverIOException, IOException {
793
                boolean cancel = fireBeforeRemoveRow(calculatedIndex, sourceType);
794 5077 caballero
                if (cancel)
795
                        return;
796 4792 fjp
                expansionFile.deleteLastRow();
797
                relations.remove(new Integer(calculatedIndex));
798
                numAdd--;
799 6212 fjp
                fireAfterRemoveRow(calculatedIndex, sourceType);
800 4792 fjp
        }
801 3996 caballero
802 4792 fjp
        /*
803
         * (non-Javadoc)
804 6212 fjp
         *
805 4792 fjp
         * @see com.iver.cit.gvsig.fmap.layers.VectorialAdapter#getRecordset()
806
         */
807
        public SelectableDataSource getRecordset() throws DriverLoadException {
808
                if (isEditing) {
809
                        if (ds == null) {
810
                                String name = LayerFactory.getDataSourceFactory()
811
                                                .addDataSource((ObjectDriver) editingDriver);
812 3996 caballero
813 4792 fjp
                                try {
814
                                        ds = new SelectableDataSource(LayerFactory
815
                                                        .getDataSourceFactory().createRandomDataSource(
816 6313 fjp
                                                                        name, DataSourceFactory.MANUAL_OPENING));
817
                                        ds.start();
818 4792 fjp
                                        ds.setSelectionSupport(ods.getSelectionSupport());
819 3940 caballero
820 4792 fjp
                                } catch (NoSuchTableException e) {
821
                                        throw new RuntimeException(e);
822
                                } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
823
                                        throw new RuntimeException(e);
824
                                }
825
                        }
826 3940 caballero
827 4792 fjp
                        return ds;
828
                } else {
829
                        return ods;
830
                }
831
        }
832 3940 caballero
833
834 4792 fjp
        /**
835
         * DOCUMENT ME!
836 6212 fjp
         *
837 4792 fjp
         * @return
838
         */
839
        public FBitSet getSelection() {
840
                /*
841
                 * try { return getRecordset().getSelection(); } catch
842
                 * (DriverLoadException e) { // TODO Auto-generated catch block
843
                 * e.printStackTrace(); } return null;
844
                 */
845
                return getRecordset().getSelection();
846
        }
847 3940 caballero
848 4792 fjp
        public void setSelection(FBitSet selection) {
849
                /*
850
                 * try { getRecordset().setSelection(selection); } catch
851
                 * (DriverLoadException e) { // TODO Auto-generated catch block
852
                 * e.printStackTrace(); }
853
                 */
854
                getRecordset().setSelection(selection);
855
        }
856 3940 caballero
857 4792 fjp
        /**
858
         * DOCUMENT ME!
859 6212 fjp
         *
860 4792 fjp
         * @return DOCUMENT ME!
861
         */
862
        public boolean isEditing() {
863
                return isEditing;
864
        }
865 3996 caballero
866 5986 caballero
        public int getInversedIndex(long rowIndex) {
867 4792 fjp
                int intervalNotDeleted = 0;
868
                int antDeleted = -1;
869
                int idPedido = (int) rowIndex;
870
                int numNotDeleted = 0;
871
                int numBorradosAnt = 0;
872 3996 caballero
873 4792 fjp
                for (int i = delRows.nextSetBit(0); i >= 0; i = delRows
874
                                .nextSetBit(i + 1)) {
875
                        intervalNotDeleted = i - antDeleted - 1;
876
                        numNotDeleted += intervalNotDeleted;
877
                        if (i > idPedido) {
878
                                numNotDeleted = numNotDeleted + (i - idPedido);
879
                                break;
880
                        }
881
                        numBorradosAnt++;
882
                        antDeleted = i;
883
                }
884
                numNotDeleted = idPedido - numBorradosAnt;
885
                // System.out.println("Piden Viejo : "+ rowIndex + " y devuelvo como
886
                // nuevo " + (numNotDeleted));
887
                return numNotDeleted;
888
        }
889 3940 caballero
890 4792 fjp
        /**
891
         * DOCUMENT ME!
892 6212 fjp
         *
893 4792 fjp
         * @param rowIndex
894
         *            DOCUMENT ME!
895 6212 fjp
         *
896 4792 fjp
         * @return DOCUMENT ME!
897
         */
898 4954 caballero
        public int getCalculatedIndex(long rowIndex) {
899 4792 fjp
                int numNotDeleted = 0;
900
                int intervalNotDeleted = 0;
901
                int antDeleted = -1;
902
                int calculatedIndex;
903
                int idPedido = (int) rowIndex;
904
                int numBorradosAnt = 0;
905 3940 caballero
906 4792 fjp
                for (int i = delRows.nextSetBit(0); i >= 0; i = delRows
907
                                .nextSetBit(i + 1)) {
908
                        intervalNotDeleted = i - antDeleted - 1;
909
                        numNotDeleted += intervalNotDeleted;
910
                        if (numNotDeleted > idPedido) {
911
                                break;
912
                        }
913
                        numBorradosAnt++;
914
                        antDeleted = i;
915
                }
916
                calculatedIndex = numBorradosAnt + idPedido;
917
                // System.out.println("Piden Registro : "+ rowIndex + " y devuelvo el "
918
                // + (calculatedIndex));
919
                return calculatedIndex;
920
        }
921 3940 caballero
922 4792 fjp
        /**
923
         * DOCUMENT ME!
924 6212 fjp
         *
925 4792 fjp
         * @author Vicente Caballero Navarro
926
         */
927
        private class myObjectDriver implements ObjectDriver {
928
                /*
929
                 * (non-Javadoc)
930 6212 fjp
                 *
931 4792 fjp
                 * @see com.hardcode.gdbms.engine.data.driver.ObjectDriver#getPrimaryKeys()
932
                 */
933
                public int[] getPrimaryKeys() throws DriverException {
934
                        return ods.getPrimaryKeys();
935
                        // int[] pk=new int[1];
936
                        /*
937
                         * for (int i=0;i<getRowCount();i++){ pk[i]=i; }
938
                         */
939
                        // pk[0]=1;
940
                        // return pk;
941
                }
942 3996 caballero
943 4792 fjp
                /*
944
                 * (non-Javadoc)
945 6212 fjp
                 *
946 4792 fjp
                 * @see com.hardcode.gdbms.engine.data.driver.ObjectDriver#write(com.hardcode.gdbms.engine.data.edition.DataWare)
947
                 */
948
                public void write(DataWare dataWare) throws DriverException {
949
                        DataWare dataWareOrig = ods
950
                                        .getDataWare(DataSourceFactory.DATA_WARE_DIRECT_MODE);
951
                        dataWareOrig.commitTrans();
952
                }
953 3940 caballero
954 4792 fjp
                /*
955
                 * (non-Javadoc)
956 6212 fjp
                 *
957 4792 fjp
                 * @see com.hardcode.gdbms.engine.data.driver.GDBMSDriver#setDataSourceFactory(com.hardcode.gdbms.engine.data.DataSourceFactory)
958
                 */
959
                public void setDataSourceFactory(DataSourceFactory dsf) {
960
                        ods.setDataSourceFactory(dsf);
961
                }
962
963
                /*
964
                 * (non-Javadoc)
965 6212 fjp
                 *
966 4792 fjp
                 * @see com.hardcode.driverManager.Driver#getName()
967
                 */
968
                public String getName() {
969
                        return ods.getName();
970
                }
971
972
                /*
973
                 * (non-Javadoc)
974 6212 fjp
                 *
975 4792 fjp
                 * @see com.hardcode.gdbms.engine.data.driver.ReadAccess#getFieldValue(long,
976
                 *      int)
977
                 */
978
                public Value getFieldValue(long rowIndex, int fieldId)
979
                                throws DriverException {
980
                        // Si no est? en el fichero de expansi?n
981 6259 fjp
                        // Integer integer = new Integer(getCalculatedIndex(rowIndex));
982 4792 fjp
983 6259 fjp
984 4792 fjp
                        try {
985 6259 fjp
                                IRow row = getRow((int)rowIndex);
986
                                return row.getAttribute(fieldId);
987
//                                if (!relations.containsKey(integer)) {
988
//                                        return ods.getFieldValue(rowIndex, fieldId);
989
//                                } else {
990
//                                        int num = ((Integer) relations.get(integer)).intValue();
991
//                                        DefaultRowEdited feat = (DefaultRowEdited) expansionFile
992
//                                                        .getRow(num);
993
//
994
//                                        if (feat == null) {
995
//                                                return null;
996
//                                        }
997
//
998
//                                        return feat.getAttribute(fieldId);
999
//                                }
1000
//                        } catch (DriverException e) {
1001
//                                e.printStackTrace();
1002
//                                throw new DriverException(e);
1003
                        } catch (IOException e) {
1004 4792 fjp
                                e.printStackTrace();
1005
                                throw new DriverException(e);
1006 6259 fjp
                        } catch (DriverIOException e) {
1007 4792 fjp
                                e.printStackTrace();
1008
                                throw new DriverException(e);
1009
                        }
1010
1011
                        /**
1012
                         * try { if (!relations.containsKey(integer)) { // Si ha sido
1013
                         * eliminada if (delRows.get(integer.intValue())) { return null; }
1014
                         * else { return ods.getFieldValue(rowIndex, fieldId); }} else { int
1015
                         * num = ((Integer) relations.get(integer)).intValue();
1016
                         * DefaultRowEdited feat = (DefaultRowEdited)
1017
                         * expansionFile.getRow(num); if (feat==null)return null; return
1018
                         * feat.getAttribute(fieldId); }} catch (DriverException e) {
1019
                         * e.printStackTrace(); throw new DriverException(e); } catch
1020
                         * (IOException e) { e.printStackTrace(); throw new
1021
                         * DriverException(e); }
1022
                         */
1023
                }
1024
1025
                /*
1026
                 * (non-Javadoc)
1027 6212 fjp
                 *
1028 4792 fjp
                 * @see com.hardcode.gdbms.engine.data.driver.ReadAccess#getFieldCount()
1029
                 */
1030
                public int getFieldCount() throws DriverException {
1031 6483 fjp
                        return fastAccessFields.size();
1032 4792 fjp
                }
1033
1034
                /*
1035
                 * (non-Javadoc)
1036 6212 fjp
                 *
1037 4792 fjp
                 * @see com.hardcode.gdbms.engine.data.driver.ReadAccess#getFieldName(int)
1038
                 */
1039
                public String getFieldName(int fieldId) throws DriverException {
1040 6483 fjp
//                        int i=0;
1041
//                        for (Iterator iter = actualFields.values().iterator(); iter.hasNext();) {
1042
//                                InternalField fld = (InternalField) iter.next();
1043
//                                if (i == fieldId)
1044 6384 fjp
//                                        return fld.getFieldDesc().getFieldAlias();
1045 6483 fjp
//                                i++;
1046
//
1047
//                        }
1048
//                        throw new DriverException("FieldId " + fieldId + " not found ");
1049
                        FieldDescription aux = (FieldDescription) fastAccessFields.get(fieldId);
1050
                        return aux.getFieldAlias();
1051 6259 fjp
                        // return null;
1052
                        // return ods.getFieldName(fieldId);
1053 4792 fjp
                }
1054
1055
                /*
1056
                 * (non-Javadoc)
1057 6212 fjp
                 *
1058 4792 fjp
                 * @see com.hardcode.gdbms.engine.data.driver.ReadAccess#getRowCount()
1059
                 */
1060
                public long getRowCount() {
1061
                        try {
1062
                                return (int) (ods.getRowCount() + numAdd)
1063
                                                - delRows.cardinality();// -
1064 6212 fjp
                                // expansionFile.getInvalidRows().cardinality();
1065 4792 fjp
                        } catch (DriverException e) {
1066
                                // TODO Auto-generated catch block
1067
                                e.printStackTrace();
1068
                        }
1069
1070
                        return 0;
1071
                }
1072
1073
                /*
1074
                 * (non-Javadoc)
1075 6212 fjp
                 *
1076 4792 fjp
                 * @see com.hardcode.gdbms.engine.data.driver.ReadAccess#getFieldType(int)
1077
                 */
1078 6384 fjp
                public int getFieldType(int fieldId) throws DriverException {
1079 6483 fjp
//                        int i=0;
1080
//                        for (Iterator iter = actualFields.values().iterator(); iter.hasNext();) {
1081
//                                InternalField fld = (InternalField) iter.next();
1082
//                                if (i == fieldId)
1083 6384 fjp
//                                        return fld.getFieldDesc().getFieldType();
1084 6483 fjp
//                                i++;
1085
//
1086
//                        }
1087
                        FieldDescription aux = (FieldDescription) fastAccessFields.get(fieldId);
1088
                        return aux.getFieldType();
1089 6259 fjp
1090 6483 fjp
//                        return ods.getFieldType(i);
1091 4792 fjp
                }
1092 4863 fjp
1093 6384 fjp
                public int getFieldWidth(int fieldId) throws DriverException {
1094 6483 fjp
//                        int i=0;
1095
//                        for (Iterator iter = actualFields.values().iterator(); iter.hasNext();) {
1096
//                                InternalField fld = (InternalField) iter.next();
1097
////                                if (fld.getFieldIndex() == i)
1098
////                                        return fld.getFieldDesc().getFieldLength();
1099
//                                if (i == fieldId)
1100 6384 fjp
//                                        return fld.getFieldDesc().getFieldLength();
1101 6483 fjp
//                                i++;
1102
//
1103
//                        }
1104
//
1105
//                        return ods.getFieldWidth(i);
1106
                        FieldDescription aux = (FieldDescription) fastAccessFields.get(fieldId);
1107
                        return aux.getFieldLength();
1108 6259 fjp
1109 4863 fjp
                }
1110 6323 fjp
1111
                public void reload() throws IOException, DriverException {
1112
                        ods.reload();
1113
1114
                }
1115 4792 fjp
        }
1116
1117
        public CommandRecord getCommandRecord() {
1118
                return cr;
1119
        }
1120 4832 fjp
1121 6212 fjp
        protected void fireAfterRemoveRow(int index, int sourceType) {
1122
                AfterRowEditEvent event = new AfterRowEditEvent(this, index,
1123
                                EditionEvent.CHANGE_TYPE_DELETE, sourceType);
1124
                for (int i = 0; i < editionListeners.size(); i++) {
1125
                        IEditionListener listener = (IEditionListener) editionListeners
1126
                                        .get(i);
1127 4832 fjp
                        listener.afterRowEditEvent(event);
1128
                }
1129 4954 caballero
1130 4832 fjp
        }
1131
1132 6212 fjp
        protected boolean fireBeforeRemoveRow(int index, int sourceType) {
1133 4832 fjp
                Cancel cancel = new Cancel();
1134 6212 fjp
                BeforeRowEditEvent event = new BeforeRowEditEvent(this, index,
1135
                                EditionEvent.CHANGE_TYPE_DELETE, cancel, sourceType);
1136
                for (int i = 0; i < editionListeners.size(); i++) {
1137
                        IEditionListener listener = (IEditionListener) editionListeners
1138
                                        .get(i);
1139
                        listener.beforeRowEditEvent(null, event);
1140 4832 fjp
                        if (cancel.isCanceled())
1141
                                return true;
1142
                }
1143
                return false;
1144
        }
1145
1146 6212 fjp
        protected void fireAfterRowAdded(int calculatedIndex, int sourceType) {
1147
                AfterRowEditEvent event = new AfterRowEditEvent(this, calculatedIndex,
1148
                                EditionEvent.CHANGE_TYPE_ADD, sourceType);
1149
                for (int i = 0; i < editionListeners.size(); i++) {
1150
                        IEditionListener listener = (IEditionListener) editionListeners
1151
                                        .get(i);
1152 4832 fjp
                        listener.afterRowEditEvent(event);
1153 4954 caballero
                }
1154 4832 fjp
        }
1155
1156 6335 fjp
        protected void fireAfterFieldAdded(FieldDescription field) {
1157
                AfterFieldEditEvent event = new AfterFieldEditEvent(this,field,
1158
                                EditionEvent.CHANGE_TYPE_ADD);
1159
                for (int i = 0; i < editionListeners.size(); i++) {
1160
                        IEditionListener listener = (IEditionListener) editionListeners
1161
                                        .get(i);
1162
                        listener.afterFieldEditEvent(event);
1163
                }
1164
        }
1165
1166
        protected void fireAfterFieldRemoved(FieldDescription field) {
1167
                AfterFieldEditEvent event = new AfterFieldEditEvent(this,field,
1168
                                EditionEvent.CHANGE_TYPE_DELETE);
1169
                for (int i = 0; i < editionListeners.size(); i++) {
1170
                        IEditionListener listener = (IEditionListener) editionListeners
1171
                                        .get(i);
1172
                        listener.afterFieldEditEvent(event);
1173
                }
1174
        }
1175
1176 6399 fjp
        protected void fireAfterFieldModified(FieldDescription field) {
1177
                AfterFieldEditEvent event = new AfterFieldEditEvent(this,field,
1178
                                EditionEvent.CHANGE_TYPE_MODIFY);
1179
                for (int i = 0; i < editionListeners.size(); i++) {
1180
                        IEditionListener listener = (IEditionListener) editionListeners
1181
                                        .get(i);
1182
                        listener.afterFieldEditEvent(event);
1183
                }
1184
        }
1185
1186
1187 6212 fjp
        protected boolean fireBeforeRowAdded(int sourceType)
1188
                        throws DriverIOException, IOException {
1189 4832 fjp
                Cancel cancel = new Cancel();
1190 6212 fjp
                BeforeRowEditEvent event = new BeforeRowEditEvent(this, getRowCount(),
1191
                                EditionEvent.CHANGE_TYPE_ADD, cancel, sourceType);
1192
                for (int i = 0; i < editionListeners.size(); i++) {
1193
                        IEditionListener listener = (IEditionListener) editionListeners
1194
                                        .get(i);
1195
                        listener.beforeRowEditEvent(null, event);
1196 4832 fjp
                        if (cancel.isCanceled())
1197
                                return true;
1198
                }
1199
                return false;
1200
        }
1201
1202 6335 fjp
        protected boolean fireBeforeFieldAdded(FieldDescription field)
1203
        throws EditionException {
1204
                Cancel cancel = new Cancel();
1205
                BeforeFieldEditEvent event = new BeforeFieldEditEvent(this, field,
1206
                EditionEvent.CHANGE_TYPE_ADD, cancel);
1207
                for (int i = 0; i < editionListeners.size(); i++) {
1208
                        IEditionListener listener = (IEditionListener) editionListeners
1209
                        .get(i);
1210
                        listener.beforeFieldEditEvent(event);
1211
                        if (cancel.isCanceled())
1212
                                return true;
1213
                }
1214
                return false;
1215
        }
1216
1217
        protected boolean fireBeforeRemoveField(FieldDescription field)
1218
        throws EditionException {
1219
                Cancel cancel = new Cancel();
1220
                BeforeFieldEditEvent event = new BeforeFieldEditEvent(this, field,
1221
                EditionEvent.CHANGE_TYPE_DELETE, cancel);
1222
                for (int i = 0; i < editionListeners.size(); i++) {
1223
                        IEditionListener listener = (IEditionListener) editionListeners
1224
                        .get(i);
1225
                        listener.beforeFieldEditEvent(event);
1226
                        if (cancel.isCanceled())
1227
                                return true;
1228
                }
1229
                return false;
1230
        }
1231
1232
1233 6212 fjp
        protected boolean fireBeforeModifyRow(IRow feat, int index, int sourceType) {
1234 4832 fjp
                Cancel cancel = new Cancel();
1235 6212 fjp
                BeforeRowEditEvent event = new BeforeRowEditEvent(this, index,
1236
                                EditionEvent.CHANGE_TYPE_MODIFY, cancel, sourceType);
1237
                for (int i = 0; i < editionListeners.size(); i++) {
1238
                        IEditionListener listener = (IEditionListener) editionListeners
1239
                                        .get(i);
1240 5197 caballero
                        listener.beforeRowEditEvent(feat, event);
1241 4832 fjp
                        if (cancel.isCanceled())
1242
                                return true;
1243
                }
1244
                return false;
1245
        }
1246
1247 6212 fjp
        protected void fireAfterModifyRow(int index, int sourceType) {
1248
                AfterRowEditEvent event = new AfterRowEditEvent(this, index,
1249
                                EditionEvent.CHANGE_TYPE_MODIFY, sourceType);
1250
                for (int i = 0; i < editionListeners.size(); i++) {
1251
                        IEditionListener listener = (IEditionListener) editionListeners
1252
                                        .get(i);
1253 4832 fjp
                        listener.afterRowEditEvent(event);
1254 4954 caballero
                }
1255 4832 fjp
1256
        }
1257
1258 5184 caballero
        protected void fireStartEditionEvent(int sourceType) {
1259 6212 fjp
                EditionEvent ev = new EditionEvent(this, EditionEvent.START_EDITION,
1260
                                sourceType);
1261
                for (int i = 0; i < editionListeners.size(); i++) {
1262
                        IEditionListener listener = (IEditionListener) editionListeners
1263
                                        .get(i);
1264 4832 fjp
                        listener.processEvent(ev);
1265 4954 caballero
                }
1266
1267 4832 fjp
        }
1268
1269 5184 caballero
        protected void fireStopEditionEvent(int sourceType) {
1270 6212 fjp
                EditionEvent ev = new EditionEvent(this, EditionEvent.STOP_EDITION,
1271
                                sourceType);
1272
                for (int i = 0; i < editionListeners.size(); i++) {
1273
                        IEditionListener listener = (IEditionListener) editionListeners
1274
                                        .get(i);
1275 4832 fjp
                        listener.processEvent(ev);
1276 4954 caballero
                }
1277
1278 4832 fjp
        }
1279
1280 5184 caballero
        protected void fireCancelEditionEvent(int sourceType) {
1281 6212 fjp
                EditionEvent ev = new EditionEvent(this, EditionEvent.CANCEL_EDITION,
1282
                                sourceType);
1283
                for (int i = 0; i < editionListeners.size(); i++) {
1284
                        IEditionListener listener = (IEditionListener) editionListeners
1285
                                        .get(i);
1286 4832 fjp
                        listener.processEvent(ev);
1287 4954 caballero
                }
1288
1289 4832 fjp
        }
1290 4954 caballero
1291 6212 fjp
        public void addEditionListener(IEditionListener listener) {
1292 5111 caballero
                if (!editionListeners.contains(listener))
1293
                        editionListeners.add(listener);
1294 4832 fjp
        }
1295
1296 6212 fjp
        public void removeEditionListener(IEditionListener listener) {
1297 4832 fjp
                editionListeners.remove(listener);
1298
        }
1299 4954 caballero
1300 5549 fjp
        public IWriter getWriter() {
1301
                return writer;
1302
        }
1303
1304 6212 fjp
        protected void setWriter(IWriter writer) {
1305 5549 fjp
                this.writer = writer;
1306 5986 caballero
1307 5549 fjp
        }
1308
1309 6212 fjp
        public ITableDefinition getTableDefinition() throws DriverLoadException,
1310
                        DriverException {
1311 5558 fjp
                TableDefinition tableDef = new TableDefinition();
1312
                tableDef.setFieldsDesc(getRecordset().getFieldsDescription());
1313
                tableDef.setName(getRecordset().getSourceInfo().name);
1314
                return tableDef;
1315
        }
1316
1317 6002 fjp
        public void validateRow(IRow row) throws EditionException {
1318 6212 fjp
                for (int i = 0; i < rules.size(); i++) {
1319 5886 fjp
                        IRule rule = (IRule) rules.get(i);
1320
                        boolean bAux = rule.validate(row);
1321 6212 fjp
                        if (bAux == false) {
1322
                                EditionException ex = new EditionException(
1323
                                                "NOT follow the rule: " + rule.getDescription());
1324 6002 fjp
                                // TODO: Lanzar una RuleException con datos como el registro
1325
                                // que no cumple, la regla que no lo ha cumplido, etc.
1326 6071 caballero
                                throw ex;
1327 6002 fjp
                        }
1328 5886 fjp
                }
1329
        }
1330
1331
        public ArrayList getRules() {
1332
                return rules;
1333
        }
1334
1335
        public void setRules(ArrayList rules) {
1336
                this.rules = rules;
1337
        }
1338 6212 fjp
1339 6313 fjp
        private void clean() throws IOException, DriverException {
1340 6127 fjp
                expansionFile.close();
1341
                relations.clear();
1342
                numAdd = 0;
1343
                delRows.clear();
1344 6313 fjp
                // TODO: Es muy probable que necesitemos un reload de los datasources, al
1345
                // igual que lo tenemos en las capas. Por ahora, basta con retocar
1346
                // listInternalFields, pero casi seguro que lo correcto ser?a hacer un
1347
                // reload completo.
1348
                initalizeFields(ods);
1349
1350
//                listInternalFields.clear();
1351
//                listInternalFields.add(actualFields);
1352 6127 fjp
        }
1353 5886 fjp
1354 6212 fjp
        /*
1355
         * (non-Javadoc)
1356
         *
1357
         * @see com.iver.cit.gvsig.fmap.edition.IEditableSource#getFieldManager()
1358
         */
1359
        public IFieldManager getFieldManager() {
1360 6356 fjp
                if (ods.getDriver() instanceof IWriteable)
1361
                {
1362
                        IWriter writer = ((IWriteable)ods.getDriver()).getWriter();
1363
                        if ((writer != null) && (writer instanceof IFieldManager))
1364
                        {
1365
                                return (IFieldManager) writer;
1366
                        }
1367
                }
1368 6212 fjp
                return null;
1369
        }
1370
1371
        /**
1372
         * Tiene en cuenta los campos actuales para formatear una row con ellos. Le
1373
         * pasamos los campos que hab?a en el momento en que se cre? esa row.
1374
         *
1375
         * @param edRow
1376
         * @param indexInternalFields
1377
         * @return
1378
         */
1379
        public IRowEdited createExternalRow(IRowEdited edRow,
1380
                        int indexInternalFields) {
1381 6483 fjp
1382
                // para acelerar
1383
                if (bFieldsHasBeenChanged == false)
1384
                        return edRow;
1385
1386 6212 fjp
                Value[] att = edRow.getAttributes();
1387
                TreeMap ancientFields = (TreeMap) listInternalFields
1388
                                .get(indexInternalFields);
1389
                Value[] newAtt = new Value[actualFields.size()];
1390
                Collection aux = actualFields.values();
1391
                Iterator it = aux.iterator();
1392
                int i = 0;
1393
                Value val = null;
1394
                while (it.hasNext()) {
1395 6384 fjp
                        // Para cada campo de los actuales, miramos si ya estaba cuando
1396
                        // el registro estaba guardado.
1397
                        // Si estaba, cogemos el valor de ese campo en el registro
1398
                        // guardado. Si no estaba, ha sido a?adido despu?s y ponemos
1399
                        // su valor por defecto.
1400
                        // Nota importante: fieldIndex es el ?ndice del campo cuando
1401
                        // se guard?. NO es el ?ndice actual dentro de actualFields.
1402
                        // Se usa SOLO para recuperar el valor de los atributos
1403
                        // antiguos. Por eso no nos preocupamos de mantener actuallizados
1404
                        // el resto de campos cuando se borra o a?ade un nuevo campo.
1405 6212 fjp
                        InternalField fld = (InternalField) it.next();
1406 6483 fjp
                        // System.err.println("fld = " + fld.getFieldDesc().getFieldAlias() +  " id=" + fld.getFieldId());
1407 6212 fjp
                        if (ancientFields.containsKey(fld.getFieldId())) {
1408
                                InternalField ancientField = (InternalField) ancientFields
1409
                                                .get(fld.getFieldId());
1410 6384 fjp
                                // val = att[ancientField.getFieldIndex()];
1411
                                val = att[ancientField.getFieldId().intValue()];
1412 6483 fjp
                                // System.out.println("fld: " + fld.getFieldDesc().getFieldAlias() + " ancient:" + " val" + val);
1413 6212 fjp
                        } else
1414
                                val = fld.getFieldDesc().getDefaultValue();
1415 6227 fjp
                        newAtt[i++] = val;
1416 6212 fjp
                }
1417
                IRowEdited newRow = (IRowEdited) edRow.cloneRow();
1418
                newRow.setAttributes(newAtt);
1419
                return newRow;
1420
        }
1421
1422
        public void removeField(String fieldName) throws EditionException {
1423
1424
                InternalField fld = findFieldByName(fieldName);
1425 6259 fjp
                if (fld == null)
1426
                        throw new EditionException("Field " + fieldName + " not found when removing field");
1427 6212 fjp
                Command command = new RemoveFieldCommand(this, fld);
1428
                if (complex) {
1429
                        commands.add(command);
1430
                } else {
1431
                        cr.pushCommand(command);
1432
                }
1433
                doRemoveField(fld);
1434
1435
        }
1436
1437
        private InternalField findFieldByName(String fieldName) {
1438
                Collection aux = actualFields.values();
1439
                Iterator it = aux.iterator();
1440
                while (it.hasNext()) {
1441
                        InternalField fld = (InternalField) it.next();
1442 6399 fjp
                        if (fld.getFieldDesc().getFieldAlias().compareToIgnoreCase(fieldName) == 0)
1443 6212 fjp
                                return fld;
1444
                }
1445
1446
                return null;
1447
        }
1448
1449 6259 fjp
        public void undoRemoveField(InternalField field) throws EditionException {
1450 6384 fjp
                // field.setDeleted(false);
1451
//                field.setFieldIndex(actualFields.size());
1452 6212 fjp
                actualFields.put(field.getFieldId(), field);
1453
                fieldsChanged();
1454 6356 fjp
                fireAfterFieldAdded(field.getFieldDesc());
1455 6212 fjp
        }
1456
1457 6259 fjp
        public void doRemoveField(InternalField field) throws EditionException {
1458 6335 fjp
                boolean cancel = fireBeforeRemoveField(field.getFieldDesc());
1459
                if (cancel) return;
1460 6212 fjp
                actualFields.remove(field.getFieldId());
1461
                fieldsChanged();
1462 6335 fjp
                fireAfterFieldRemoved(field.getFieldDesc());
1463 6212 fjp
        }
1464
1465
        public void renameField(String antName, String newName) throws EditionException {
1466
1467
                InternalField fld = findFieldByName(antName);
1468
                Command command = new RenameFieldCommand(this, fld, newName);
1469
                if (complex) {
1470
                        commands.add(command);
1471
                } else {
1472
                        cr.pushCommand(command);
1473
                }
1474
                doRenameField(fld, newName);
1475
1476
        }
1477
1478 6399 fjp
        public void undoRenameField(InternalField field, String antName) throws EditionException  {
1479
                fieldsChanged();
1480
                fireAfterFieldModified(field.getFieldDesc());
1481
1482 6212 fjp
        }
1483
1484 6399 fjp
        public void doRenameField(InternalField field, String newName) throws EditionException  {
1485
                fieldsChanged();
1486
                fireAfterFieldModified(field.getFieldDesc());
1487
1488 6212 fjp
        }
1489
1490
1491
        public void addField(FieldDescription field) throws EditionException {
1492
1493
                InternalField fld = new InternalField(field, InternalField.ADDED, new Integer(listFields.size()));
1494
                Command command = new AddFieldCommand(this, fld);
1495
                if (complex) {
1496
                        commands.add(command);
1497
                } else {
1498
                        cr.pushCommand(command);
1499
                }
1500
                listFields.add(fld);
1501
                doAddField(fld);
1502
1503
        }
1504
1505 6259 fjp
        public void undoAddField(InternalField field) throws EditionException {
1506 6335 fjp
                boolean cancel = fireBeforeRemoveField(field.getFieldDesc());
1507
                if (cancel)
1508
                        return;
1509
1510 6384 fjp
                // field.setDeleted(true);
1511 6227 fjp
                actualFields.remove(field.getFieldId());
1512 6212 fjp
                fieldsChanged();
1513 6335 fjp
                fireAfterFieldRemoved(field.getFieldDesc());
1514 6212 fjp
1515
        }
1516
1517 6335 fjp
        public int doAddField(InternalField field) throws EditionException {
1518
                boolean cancel;
1519
                cancel = fireBeforeFieldAdded(field.getFieldDesc());
1520
                if (cancel)
1521
                        return -1;
1522
1523 6384 fjp
                // field.setDeleted(false);
1524
//                field.setFieldIndex(actualFields.size());
1525 6227 fjp
                actualFields.put(field.getFieldId(), field);
1526 6212 fjp
                fieldsChanged();
1527 6335 fjp
                fireAfterFieldAdded(field.getFieldDesc());
1528 6384 fjp
//                return field.getFieldIndex();
1529
                return field.getFieldId().intValue();
1530 6212 fjp
        }
1531
1532 6365 fjp
        public Driver getOriginalDriver()
1533 6356 fjp
        {
1534
                return ods.getDriver();
1535
        }
1536
1537 6478 fjp
        /**
1538
         * Use it to be sure the recordset will have the right fields. It forces a new SelectableDataSource
1539
         * to be created next time it is needed
1540
         */
1541
        public void cleanSelectableDatasource() {
1542
                ds = null;
1543
        }
1544
1545
1546 6384 fjp
//        private InternalField getInternalFieldByIndex(int fieldId)
1547
//        {
1548
//                for (Iterator iter = actualFields.values().iterator(); iter.hasNext();) {
1549
//                        InternalField fld = (InternalField) iter.next();
1550
//                        if (fld.getFieldIndex() == fieldId)
1551
//                                return fld;
1552
//                }
1553
//                return null;
1554
//        }
1555
1556 3940 caballero
}