Statistics
| Revision:

root / branches / v10 / libraries / libFMap / src / com / iver / cit / gvsig / fmap / edition / EditableAdapter.java @ 8913

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