Statistics
| Revision:

root / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / layers / SelectableDataSource.java @ 31024

History | View | Annotate | Download (16.3 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 *
19
 * For more information, contact:
20
 *
21
 *  Generalitat Valenciana
22
 *   Conselleria d'Infraestructures i Transport
23
 *   Av. Blasco Ib??ez, 50
24
 *   46010 VALENCIA
25
 *   SPAIN
26
 *
27
 *      +34 963862235
28
 *   gvsig@gva.es
29
 *      www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   IVER T.I. S.A
34
 *   Salamanca 50
35
 *   46005 Valencia
36
 *   Spain
37
 *
38
 *   +34 963163400
39
 *   dac@iver.es
40
 */
41
package com.iver.cit.gvsig.fmap.layers;
42

    
43
import java.io.IOException;
44

    
45
import org.apache.log4j.Logger;
46
import org.xml.sax.SAXException;
47

    
48
import com.hardcode.driverManager.Driver;
49
import com.hardcode.driverManager.DriverLoadException;
50
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
51
import com.hardcode.gdbms.driver.exceptions.ReloadDriverException;
52
import com.hardcode.gdbms.driver.exceptions.WriteDriverException;
53
import com.hardcode.gdbms.engine.data.DataSource;
54
import com.hardcode.gdbms.engine.data.DataSourceFactory;
55
import com.hardcode.gdbms.engine.data.IDataSourceListener;
56
import com.hardcode.gdbms.engine.data.NoSuchTableException;
57
import com.hardcode.gdbms.engine.data.SourceInfo;
58
import com.hardcode.gdbms.engine.data.driver.DriverException;
59
import com.hardcode.gdbms.engine.data.edition.DataWare;
60
import com.hardcode.gdbms.engine.data.persistence.Memento;
61
import com.hardcode.gdbms.engine.data.persistence.MementoContentHandler;
62
import com.hardcode.gdbms.engine.data.persistence.MementoException;
63
import com.hardcode.gdbms.engine.instruction.EvaluationException;
64
import com.hardcode.gdbms.engine.instruction.FieldNotFoundException;
65
import com.hardcode.gdbms.engine.instruction.SemanticException;
66
import com.hardcode.gdbms.engine.values.Value;
67
import com.hardcode.gdbms.engine.values.ValueCollection;
68
import com.hardcode.gdbms.parser.ParseException;
69
import com.iver.cit.gvsig.fmap.drivers.FieldDescription;
70
import com.iver.cit.gvsig.fmap.layers.layerOperations.Selectable;
71
import com.iver.utiles.NumberUtilities;
72
import com.iver.utiles.XMLEntity;
73

    
74

    
75
/**
76
 * DataSource seleccionable.
77
 *
78
 * @author Fernando Gonz?lez Cort?s
79
 */
80
public class SelectableDataSource implements DataSource,Selectable {
81
        private static Logger logger = Logger.getLogger(SelectableDataSource.class.getName());
82
        private SelectionSupport selectionSupport = new SelectionSupport();
83
        private DataSource dataSource;
84

    
85
        private int[] mapping = null;
86

    
87
        /**
88
         * Crea un nuevo SelectableDataSource.
89
         *
90
         * @param name
91
         * @param ds
92
         * @throws ReadDriverException TODO
93
         */
94
        public SelectableDataSource(DataSource ds) throws ReadDriverException {
95
                dataSource = ds;
96
                dataSource.start();
97
                // Creamos el mapping de campos externos que no muestran el PK.
98
                mapExternalFields();
99

    
100

    
101
        }
102

    
103
        /**
104
         * Maps real fields or "external" fields. We don't want to see virtual fields.
105
         * @throws ReadDriverException
106
         */
107
        public void mapExternalFields() throws ReadDriverException {
108
                int numExternalFields = 0;
109
//                this.dataSource.start();
110
                int fieldCount=dataSource.getFieldCount();
111
                for (int i=0; i < fieldCount; i++)
112
                {
113
                        if (!dataSource.isVirtualField(i))
114
                                numExternalFields++;
115

    
116
                }
117

    
118
                mapping = new int[numExternalFields];
119
                int j=0;
120
                for (int i=0; i < fieldCount; i++)
121
                {
122
                        if (!dataSource.isVirtualField(i))
123
                                mapping[j++] = i;
124

    
125
                }
126
//                this.dataSource.stop();
127
        }
128

    
129
        public static SelectableDataSource createSelectableDataSource(XMLEntity xml) throws DriverLoadException, XMLException{
130

    
131
                SelectionSupport ss = new SelectionSupport();
132
                ss.setXMLEntity(xml.getChild(0));
133
                XMLEntity xmlDS = xml.getChild(1);
134
                GDBMSParser parser = new GDBMSParser(xmlDS);
135
                MementoContentHandler gdbmsHandler = new MementoContentHandler();
136
                parser.setContentHandler(gdbmsHandler);
137
                try {
138
                        parser.parse();
139
                } catch (SAXException e) {
140
                        throw new XMLException(e);
141
                }
142
                SelectableDataSource sds;
143
        try {
144
            sds = new SelectableDataSource(gdbmsHandler.getDataSource(LayerFactory.getDataSourceFactory(), DataSourceFactory.AUTOMATIC_OPENING));
145
        } catch (EvaluationException e1) {
146
            throw new XMLException(e1);
147
        } catch (ReadDriverException e) {
148
                 throw new XMLException(e);
149
                } catch (DriverLoadException e) {
150
                         throw new XMLException(e);
151
                } catch (SemanticException e) {
152
                         throw new XMLException(e);
153
                } catch (ParseException e) {
154
                         throw new XMLException(e);
155
                } catch (NoSuchTableException e) {
156
                         throw new XMLException(e);
157
                }
158
        sds.selectionSupport=ss;
159
                return sds;
160
        }
161

    
162
        public void setDataSourceFactory(DataSourceFactory dsf) {
163
                dataSource.setDataSourceFactory(dsf);
164
        }
165
        public void setSourceInfo(SourceInfo sourceInfo) {
166
                dataSource.setSourceInfo(sourceInfo);
167
        }
168
        /**
169
         * A?ade el soporte para la selecci?n.
170
         *
171
         * @param selectionSupport
172
         */
173
        public void setSelectionSupport(SelectionSupport selectionSupport) {
174
                this.selectionSupport = selectionSupport;
175
        }
176

    
177
        /**
178
         * Devuelve el n?mero de campos.
179
         *
180
         * @return N?mero de campos.
181
         *
182
         * @throws DriverException
183
         */
184
        public int getFieldCount() throws ReadDriverException {
185
                // return dataSource.getFieldCount()-numVirtual;
186
//                if (mapping.length != dataSource.getFieldCount())
187
//                {
188
//                        mapExternalFields();
189
//                        RuntimeException e = new RuntimeException("Recalculamos los campos de recordset!!");
190
//                        e.printStackTrace();
191
//                }
192
                if (mapping.length!=dataSource.getFieldCount()){
193
                        mapExternalFields();
194
                }
195
                return mapping.length;
196
        }
197

    
198
        /**
199
         * Return index field searching by its name
200
         *
201
         * @param arg0 field name.
202
         *
203
         * @return field index. -1 if not found
204
         *
205
         * @throws DriverException
206
         * @throws FieldNotFoundException
207
         */
208
        public int getFieldIndexByName(String arg0)
209
                throws ReadDriverException {
210
                int internal = dataSource.getFieldIndexByName(arg0);
211
                for (int i=0; i < mapping.length; i++)
212
                {
213
                        if (mapping[i] == internal)
214
                                return i;
215
                }
216
                //OJO Parche para rodear poblema de gdbms + FileDriver
217
                // Cuando en le fichero existe un campo de nombre 'PK'
218
                if (arg0.equalsIgnoreCase("pk")){
219
                        for (int i=0; i < mapping.length; i++)
220
                        {
221
                                if (dataSource.getFieldName(mapping[i]).equalsIgnoreCase(arg0)){
222
                                        return i;
223
                                }
224
                        }
225

    
226
                }
227
                return -1;
228
        }
229

    
230
        /**
231
         * Devuelve el nombre del campo a partir del ?ndice.
232
         *
233
         * @param arg0 ?ndice.
234
         *
235
         * @return nombre del campo.
236
         *
237
         * @throws DriverException
238
         */
239
        public String getFieldName(int arg0) throws ReadDriverException {
240
            // return dataSource.getFieldName(arg0);
241
                return dataSource.getFieldName(mapping[arg0]);
242
        }
243

    
244
        /**
245
         * Devuelve el valor a partir del n?mro de fila y columna.
246
         *
247
         * @param arg0 n?mero de registro.
248
         * @param arg1 n?mero de campo.
249
         *
250
         * @return Valor.
251
         *
252
         * @throws DriverException
253
         */
254
        public Value getFieldValue(long arg0, int arg1) throws ReadDriverException {
255
                if (arg1==-1)
256
                        return null;
257
                return dataSource.getFieldValue(arg0, mapping[arg1]);
258
                // return dataSource.getFieldValue(arg0, arg1);
259
        }
260

    
261
        /**
262
         * Devuelve el nombre del DataSource.
263
         *
264
         * @return Nombre.
265
         */
266
        public String getName() {
267
                return dataSource.getName();
268
        }
269

    
270
        /**
271
         * Devuelve el n?mero de filas en total.
272
         *
273
         * @return n?mero de filas.
274
         *
275
         * @throws DriverException
276
         */
277
        public long getRowCount() throws ReadDriverException {
278
                return dataSource.getRowCount();
279
        }
280

    
281
        /**
282
         * Inicializa el dataSource.
283
         *
284
         * @throws DriverException
285
         */
286
        public void start() throws ReadDriverException {
287
                // logger.debug("dataSource.start()");
288
                dataSource.start();
289
        }
290

    
291
        /**
292
         * Finaliza el DataSource.
293
         *
294
         * @throws DriverException
295
         */
296
        public void stop() throws ReadDriverException {
297
                // logger.debug("dataSource.stop()");
298
                dataSource.stop();
299
        }
300

    
301
        /**
302
         * A partir del XMLEntity se rellenan los atributos del DataSource.
303
         *
304
         * @param child
305
         */
306
        public void setXMLEntity03(XMLEntity child) {
307
                selectionSupport.setXMLEntity(child.getChild(0));
308
        }
309

    
310
        /**
311
         * Cuando ocurre un evento de cambio en la selecci?n, ?ste puede ser uno de
312
         * una gran cantidad de eventos. Con el fin de no propagar todos estos
313
         * eventos, se realiza la propagaci?n de manera manual al final de la
314
         * "r?faga" de eventos
315
         */
316
        public void fireSelectionEvents() {
317
                selectionSupport.fireSelectionEvents();
318
        }
319

    
320
        /**
321
         * A?ade un nuevo Listener al SelectionSupport.
322
         *
323
         * @param listener SelectionListener.
324
         */
325
        public void addSelectionListener(SelectionListener listener) {
326
                selectionSupport.addSelectionListener(listener);
327
        }
328

    
329
        /**
330
         * Borra un Listener al SelectionSupport.
331
         *
332
         * @param listener Listener a borrar.
333
         */
334
        public void removeSelectionListener(SelectionListener listener) {
335
                selectionSupport.removeSelectionListener(listener);
336
        }
337

    
338
        /**
339
         * Borra la selecci?n.
340
         */
341
        public void clearSelection() {
342
                selectionSupport.clearSelection();
343
        }
344

    
345
        /**
346
         * Develve un FBitSet con los ?ndices de los elementos seleccionados.
347
         *
348
         * @return FBitset con los elementos seleccionados.
349
         */
350
        public FBitSet getSelection() {
351
                return selectionSupport.getSelection();
352
        }
353

    
354
        /**
355
         * Devuelve el SelectionSupport.
356
         *
357
         * @return SelectinSuport.
358
         */
359
        public SelectionSupport getSelectionSupport() {
360
                return selectionSupport;
361
        }
362

    
363
        /**
364
         * Devuelve true si el elemento est? seleccionado.
365
         *
366
         * @param recordIndex ?ndice del registro.
367
         *
368
         * @return True si el registro est? seleccionado.
369
         */
370
        public boolean isSelected(int recordIndex) {
371
                return selectionSupport.isSelected(recordIndex);
372
        }
373

    
374
        /**
375
         * Inserta una nueva selecci?n.
376
         *
377
         * @param selection FBitSet.
378
         */
379
        public void setSelection(FBitSet selection) {
380
                selectionSupport.setSelection(selection);
381
        }
382

    
383
        private void putMemento(XMLEntity xml) throws XMLException {
384
                try {
385
                        GDBMSHandler handler = new GDBMSHandler();
386
                        Memento m = getMemento();
387
                        m.setContentHandler(handler);
388
                        m.getXML();
389
                        XMLEntity child = handler.getXMLEntity();
390

    
391
                        xml.addChild(child);
392
                } catch (MementoException e) {
393
                        throw new XMLException(e);
394
                } catch (SAXException e) {
395
                        throw new XMLException(e);
396
                }
397
        }
398

    
399
        /**
400
         * Devuelve el XMLEntity con la informaci?n necesaria para reproducir el
401
         * DataSource.
402
         *
403
         * @return XMLEntity.
404
         * @throws XMLException
405
         */
406
        public XMLEntity getXMLEntity() throws XMLException {
407
                XMLEntity xml = new XMLEntity();
408
                xml.putProperty("className",this.getClass().getName());
409
                xml.addChild(selectionSupport.getXMLEntity());
410
                putMemento(xml);
411

    
412
                return xml;
413
        }
414

    
415
        /**
416
         * @see com.hardcode.gdbms.engine.data.DataSource#getWhereFilter()
417
         */
418
        public long[] getWhereFilter() throws IOException {
419
                return dataSource.getWhereFilter();
420
        }
421

    
422
        /*
423
         * @see com.hardcode.gdbms.engine.data.ReadDriver#getFieldType(int)
424
         */
425
        public int getFieldType(int i) throws ReadDriverException {
426
                // return dataSource.getFieldType(i);
427
                if (i>mapping.length-1)
428
                        return dataSource.getFieldType(i);
429
                return dataSource.getFieldType(mapping[i]);
430
        }
431

    
432
        /*
433
         * @see com.hardcode.gdbms.engine.data.DataSource#getDataSourceFactory()
434
         */
435
        public DataSourceFactory getDataSourceFactory() {
436
                return dataSource.getDataSourceFactory();
437
        }
438

    
439
        /*
440
         * @see com.hardcode.gdbms.engine.data.DataSource#getAsString()
441
         */
442
        public String getAsString() throws ReadDriverException {
443
                return dataSource.getAsString();
444
        }
445

    
446
        /*
447
         * @throws DriverException
448
         * @see com.hardcode.gdbms.engine.data.DataSource#remove()
449
         */
450
        public void remove() throws WriteDriverException {
451
                dataSource.remove();
452
        }
453

    
454
        /*
455
         * @see com.hardcode.gdbms.engine.data.DataSource#getMemento()
456
         */
457
        public Memento getMemento() throws MementoException {
458
                return dataSource.getMemento();
459
        }
460

    
461
        /*
462
         * @see com.hardcode.gdbms.engine.data.DataSource#getSourceInfo()
463
         */
464
        public SourceInfo getSourceInfo() {
465
                return dataSource.getSourceInfo();
466
        }
467

    
468
    /*
469
     * @see com.hardcode.gdbms.engine.data.DataSource#getPrimaryKeys()
470
     */
471
    public int[] getPrimaryKeys() throws ReadDriverException {
472
            return dataSource.getPrimaryKeys();
473
    }
474

    
475
    /*
476
     * @see com.hardcode.gdbms.engine.data.DataSource#getPKValue(long)
477
     */
478
    public ValueCollection getPKValue(long rowIndex) throws ReadDriverException {
479
        return dataSource.getPKValue(rowIndex);
480
    }
481

    
482
    /*
483
     * @see com.hardcode.gdbms.engine.data.DataSource#getPKName(int)
484
     */
485
    public String getPKName(int fieldId) throws ReadDriverException {
486
        return dataSource.getPKName(fieldId);
487
    }
488

    
489
    /*
490
     * @see com.hardcode.gdbms.engine.data.DataSource#getPKType(int)
491
     */
492
    public int getPKType(int i) throws ReadDriverException {
493
        return dataSource.getPKType(i);
494
    }
495

    
496
    /*
497
     * @throws DriverException
498
     * @see com.hardcode.gdbms.engine.data.DataSource#getPKCardinality()
499
     */
500
    public int getPKCardinality() throws ReadDriverException {
501
        return dataSource.getPKCardinality();
502
    }
503

    
504
    /*
505
     * @see com.hardcode.gdbms.engine.data.DataSource#getRow(long)
506
     */
507
    public Value[] getRow(long rowIndex) throws ReadDriverException {
508
            Value[] withoutVirtuals = new Value[mapping.length];
509
            Value[] internal = dataSource.getRow(rowIndex);
510
            for (int i=0; i < mapping.length; i++)
511
            {
512
                    withoutVirtuals[i] = internal[mapping[i]];
513

    
514
            }
515
        return withoutVirtuals;
516
    }
517

    
518
    /*
519
     * @see com.hardcode.gdbms.engine.data.DataSource#getFieldNames()
520
     */
521
    public String[] getFieldNames() throws ReadDriverException {
522
            String[] fieldNames = new String[getFieldCount()];
523
                int j=0;
524
                int fieldCount=dataSource.getFieldCount();
525
                for (int i=0; i < fieldCount; i++)
526
                {
527
                        if (!dataSource.isVirtualField(i))
528
                                fieldNames[j++] = dataSource.getFieldName(i);
529

    
530
                }
531
        // return dataSource.getFieldNames();
532
            return fieldNames;
533
    }
534

    
535
    /*
536
     * @see com.hardcode.gdbms.engine.data.DataSource#getPKNames()
537
     */
538
    public String[] getPKNames() throws ReadDriverException {
539
        return dataSource.getPKNames();
540
    }
541

    
542
        public void removeLinksSelectionListener() {
543
                selectionSupport.removeLinkSelectionListener();
544
        }
545

    
546
    /*
547
     * @throws DriverException
548
     * @see com.hardcode.gdbms.engine.data.DataSource#getDataWare(int)
549
     */
550
    public DataWare getDataWare(int arg0) throws ReadDriverException {
551
        return dataSource.getDataWare(arg0);
552
    }
553

    
554
        public int getFieldWidth(int i) throws ReadDriverException {
555
                return dataSource.getFieldWidth(mapping[i]);
556
                // return dataSource.getFieldWidth(i);
557
        }
558

    
559
        public boolean isVirtualField(int fieldId) throws ReadDriverException {
560
                return dataSource.isVirtualField(fieldId);
561
        }
562

    
563
        /**
564
         * Useful to writers, to know the field definitions.
565
         * NOTE: Maximun precision: 6 decimals. (We may need to change this)
566
         * @return Description of non virtual fields
567
         * @throws DriverException
568
         */
569
        public FieldDescription[] getFieldsDescription() throws ReadDriverException{
570
                int numFields = getFieldCount();
571
                FieldDescription[] fieldsDescrip = new FieldDescription[numFields];
572
                for (int i = 0; i < numFields; i++) {
573
                        fieldsDescrip[i] = new FieldDescription();
574
                        int type = getFieldType(i);
575
                        fieldsDescrip[i].setFieldType(type);
576
                        fieldsDescrip[i].setFieldName(getFieldName(i));
577
                        fieldsDescrip[i].setFieldLength(getFieldWidth(i));
578
                        if (NumberUtilities.isNumeric(type))
579
                        {
580
                                if (!NumberUtilities.isNumericInteger(type))
581
                                        // TODO: If there is a lost in precision, this should be changed.
582
                                        fieldsDescrip[i].setFieldDecimalCount(6);
583
                        }
584
                        else
585
                                fieldsDescrip[i].setFieldDecimalCount(0);
586
                        // TODO: ?DEFAULTVALUE?
587
                        // fieldsDescrip[i].setDefaultValue(get)
588
                }
589
                return fieldsDescrip;
590
        }
591

    
592
        public Driver getDriver() {
593
                return this.dataSource.getDriver();
594
        }
595

    
596
        public void reload() throws ReloadDriverException {
597
                dataSource.reload();
598
                try {
599
                        mapExternalFields();
600
                } catch (ReadDriverException e) {
601
                        throw new ReloadDriverException(getDriver().getName(),e);
602
                }
603

    
604
        }
605

    
606
        public void addDataSourceListener(IDataSourceListener listener) {
607
                dataSource.addDataSourceListener(listener);
608

    
609
        }
610

    
611
        public void removeDataSourceListener(IDataSourceListener listener) {
612
                dataSource.removeDataSourceListener(listener);
613

    
614
        }
615
}