Statistics
| Revision:

root / branches / v10 / libraries / libFMap / src / com / iver / cit / gvsig / fmap / layers / SelectableDataSource.java @ 13405

History | View | Annotate | Download (15.8 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.engine.data.DataSource;
51
import com.hardcode.gdbms.engine.data.DataSourceFactory;
52
import com.hardcode.gdbms.engine.data.IDataSourceListener;
53
import com.hardcode.gdbms.engine.data.NoSuchTableException;
54
import com.hardcode.gdbms.engine.data.SourceInfo;
55
import com.hardcode.gdbms.engine.data.driver.DriverException;
56
import com.hardcode.gdbms.engine.data.edition.DataWare;
57
import com.hardcode.gdbms.engine.data.persistence.Memento;
58
import com.hardcode.gdbms.engine.data.persistence.MementoContentHandler;
59
import com.hardcode.gdbms.engine.data.persistence.MementoException;
60
import com.hardcode.gdbms.engine.instruction.EvaluationException;
61
import com.hardcode.gdbms.engine.instruction.FieldNotFoundException;
62
import com.hardcode.gdbms.engine.instruction.SemanticException;
63
import com.hardcode.gdbms.engine.values.Value;
64
import com.hardcode.gdbms.engine.values.ValueCollection;
65
import com.hardcode.gdbms.parser.ParseException;
66
import com.iver.cit.gvsig.fmap.drivers.FieldDescription;
67
import com.iver.cit.gvsig.fmap.layers.layerOperations.Selectable;
68
import com.iver.utiles.NumberUtilities;
69
import com.iver.utiles.XMLEntity;
70

    
71

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

    
82
        private int[] mapping = null;
83

    
84
        /**
85
         * Crea un nuevo SelectableDataSource.
86
         *
87
         * @param name
88
         * @param ds
89
         * @throws DriverException
90
         */
91
        public SelectableDataSource(DataSource ds) throws DriverException {
92
                dataSource = ds;
93
                // CHEMA: No deberiamos abrir el dataSource porque si
94
                // Lo tiene que hacer quien lo va a usar
95
                //dataSource.start();
96

    
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 DriverException
106
         */
107
        public void mapExternalFields() throws DriverException {
108
                //CHEMA: Abrimos y cerramos el dataSource para preparar
109
                //                el mapping
110
                this.dataSource.start();
111
                int numExternalFields = 0;
112
                for (int i=0; i < dataSource.getFieldCount(); i++)
113
                {
114
                        if (!dataSource.isVirtualField(i))
115
                                numExternalFields++;
116

    
117
                }
118

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

    
126
                }
127
                this.dataSource.stop();
128
        }
129

    
130
        public static SelectableDataSource createSelectableDataSource(XMLEntity xml) throws NoSuchTableException, ParseException, DriverLoadException, DriverException, SemanticException, IOException, XMLException{
131

    
132
                SelectionSupport ss = new SelectionSupport();
133
                ss.setXMLEntity(xml.getChild(0));
134
                XMLEntity xmlDS = xml.getChild(1);
135
                GDBMSParser parser = new GDBMSParser(xmlDS);
136
                MementoContentHandler gdbmsHandler = new MementoContentHandler();
137
                parser.setContentHandler(gdbmsHandler);
138
                try {
139
                        parser.parse();
140
                } catch (SAXException e) {
141
                        throw new XMLException(e);
142
                }
143
                SelectableDataSource sds;
144
        try {
145
//                 CHEMA: AUTOMATIC DATA SOURCE
146
            //sds = new SelectableDataSource(gdbmsHandler.getDataSource(LayerFactory.getDataSourceFactory(), DataSourceFactory.MANUAL_OPENING));
147
            sds = new SelectableDataSource(gdbmsHandler.getDataSource(LayerFactory.getDataSourceFactory(), DataSourceFactory.AUTOMATIC_OPENING));
148
        } catch (EvaluationException e1) {
149
            throw new XMLException(e1);
150
        }
151
        sds.selectionSupport=ss;
152
                return sds;
153
        }
154

    
155
        public void setDataSourceFactory(DataSourceFactory dsf) {
156
                dataSource.setDataSourceFactory(dsf);
157
        }
158
        public void setSourceInfo(SourceInfo sourceInfo) {
159
                dataSource.setSourceInfo(sourceInfo);
160
        }
161
        /**
162
         * A?ade el soporte para la selecci?n.
163
         *
164
         * @param selectionSupport
165
         */
166
        public void setSelectionSupport(SelectionSupport selectionSupport) {
167
                this.selectionSupport = selectionSupport;
168
        }
169

    
170
        /**
171
         * Devuelve el n?mero de campos.
172
         *
173
         * @return N?mero de campos.
174
         *
175
         * @throws DriverException
176
         */
177
        public int getFieldCount() throws DriverException {
178
                // return dataSource.getFieldCount()-numVirtual;
179
//                if (mapping.length != dataSource.getFieldCount())
180
//                {
181
//                        mapExternalFields();
182
//                        RuntimeException e = new RuntimeException("Recalculamos los campos de recordset!!");
183
//                        e.printStackTrace();
184
//                }
185
                return mapping.length;
186
        }
187

    
188
        /**
189
         * Return index field searching by its name
190
         *
191
         * @param arg0 field name.
192
         *
193
         * @return field index. -1 if not found
194
         *
195
         * @throws DriverException
196
         * @throws FieldNotFoundException
197
         */
198
        public int getFieldIndexByName(String arg0)
199
                throws DriverException {
200
                int internal = dataSource.getFieldIndexByName(arg0);
201
                for (int i=0; i < mapping.length; i++)
202
                {
203
                        if (mapping[i] == internal)
204
                                return i;
205
                }
206
                //OJO Parche para rodear poblema de gdbms + FileDriver
207
                // Cuando en le fichero existe un campo de nombre 'PK'
208
                if (arg0.equalsIgnoreCase("pk")){
209
                        for (int i=0; i < mapping.length; i++)
210
                        {
211
                                if (dataSource.getFieldName(mapping[i]).equalsIgnoreCase(arg0)){
212
                                        return i;
213
                                }
214
                        }
215

    
216
                }
217
                return -1;
218
        }
219

    
220
        /**
221
         * Devuelve el nombre del campo a partir del ?ndice.
222
         *
223
         * @param arg0 ?ndice.
224
         *
225
         * @return nombre del campo.
226
         *
227
         * @throws DriverException
228
         */
229
        public String getFieldName(int arg0) throws DriverException {
230
            // return dataSource.getFieldName(arg0);
231
                return dataSource.getFieldName(mapping[arg0]);
232
        }
233

    
234
        /**
235
         * Devuelve el valor a partir del n?mro de fila y columna.
236
         *
237
         * @param arg0 n?mero de registro.
238
         * @param arg1 n?mero de campo.
239
         *
240
         * @return Valor.
241
         *
242
         * @throws DriverException
243
         */
244
        public Value getFieldValue(long arg0, int arg1) throws DriverException {
245
                return dataSource.getFieldValue(arg0, mapping[arg1]);
246
                // return dataSource.getFieldValue(arg0, arg1);
247
        }
248

    
249
        /**
250
         * Devuelve el nombre del DataSource.
251
         *
252
         * @return Nombre.
253
         */
254
        public String getName() {
255
                return dataSource.getName();
256
        }
257

    
258
        /**
259
         * Devuelve el n?mero de filas en total.
260
         *
261
         * @return n?mero de filas.
262
         *
263
         * @throws DriverException
264
         */
265
        public long getRowCount() throws DriverException {
266
                return dataSource.getRowCount();
267
        }
268

    
269
        /**
270
         * Inicializa el dataSource.
271
         *
272
         * @throws DriverException
273
         */
274
        public void start() throws DriverException {
275
                // logger.debug("dataSource.start()");
276
                dataSource.start();
277
        }
278

    
279
        /**
280
         * Finaliza el DataSource.
281
         *
282
         * @throws DriverException
283
         */
284
        public void stop() throws DriverException {
285
                // logger.debug("dataSource.stop()");
286
                dataSource.stop();
287
        }
288

    
289
        /**
290
         * A partir del XMLEntity se rellenan los atributos del DataSource.
291
         *
292
         * @param child
293
         */
294
        public void setXMLEntity03(XMLEntity child) {
295
                selectionSupport.setXMLEntity(child.getChild(0));
296
        }
297

    
298
        /**
299
         * Cuando ocurre un evento de cambio en la selecci?n, ?ste puede ser uno de
300
         * una gran cantidad de eventos. Con el fin de no propagar todos estos
301
         * eventos, se realiza la propagaci?n de manera manual al final de la
302
         * "r?faga" de eventos
303
         */
304
        public void fireSelectionEvents() {
305
                selectionSupport.fireSelectionEvents();
306
        }
307

    
308
        /**
309
         * A?ade un nuevo Listener al SelectionSupport.
310
         *
311
         * @param listener SelectionListener.
312
         */
313
        public void addSelectionListener(SelectionListener listener) {
314
                selectionSupport.addSelectionListener(listener);
315
        }
316

    
317
        /**
318
         * Borra un Listener al SelectionSupport.
319
         *
320
         * @param listener Listener a borrar.
321
         */
322
        public void removeSelectionListener(SelectionListener listener) {
323
                selectionSupport.removeSelectionListener(listener);
324
        }
325

    
326
        /**
327
         * Borra la selecci?n.
328
         */
329
        public void clearSelection() {
330
                selectionSupport.clearSelection();
331
        }
332

    
333
        /**
334
         * Develve un FBitSet con los ?ndices de los elementos seleccionados.
335
         *
336
         * @return FBitset con los elementos seleccionados.
337
         */
338
        public FBitSet getSelection() {
339
                return selectionSupport.getSelection();
340
        }
341

    
342
        /**
343
         * Devuelve el SelectionSupport.
344
         *
345
         * @return SelectinSuport.
346
         */
347
        public SelectionSupport getSelectionSupport() {
348
                return selectionSupport;
349
        }
350

    
351
        /**
352
         * Devuelve true si el elemento est? seleccionado.
353
         *
354
         * @param recordIndex ?ndice del registro.
355
         *
356
         * @return True si el registro est? seleccionado.
357
         */
358
        public boolean isSelected(int recordIndex) {
359
                return selectionSupport.isSelected(recordIndex);
360
        }
361

    
362
        /**
363
         * Inserta una nueva selecci?n.
364
         *
365
         * @param selection FBitSet.
366
         */
367
        public void setSelection(FBitSet selection) {
368
                selectionSupport.setSelection(selection);
369
        }
370

    
371
        private void putMemento(XMLEntity xml) throws XMLException {
372
                try {
373
                        GDBMSHandler handler = new GDBMSHandler();
374
                        Memento m = getMemento();
375
                        m.setContentHandler(handler);
376
                        m.getXML();
377
                        XMLEntity child = handler.getXMLEntity();
378

    
379
                        xml.addChild(child);
380
                } catch (MementoException e) {
381
                        throw new XMLException(e);
382
                } catch (SAXException e) {
383
                        throw new XMLException(e);
384
                }
385
        }
386

    
387
        /**
388
         * Devuelve el XMLEntity con la informaci?n necesaria para reproducir el
389
         * DataSource.
390
         *
391
         * @return XMLEntity.
392
         * @throws XMLException
393
         */
394
        public XMLEntity getXMLEntity() throws XMLException {
395
                XMLEntity xml = new XMLEntity();
396
                xml.putProperty("className",this.getClass().getName());
397
                xml.addChild(selectionSupport.getXMLEntity());
398
                putMemento(xml);
399

    
400
                return xml;
401
        }
402

    
403
        /**
404
         * @see com.hardcode.gdbms.engine.data.DataSource#getWhereFilter()
405
         */
406
        public long[] getWhereFilter() throws IOException {
407
                return dataSource.getWhereFilter();
408
        }
409

    
410
        /**
411
         * @see com.hardcode.gdbms.engine.data.ReadDriver#getFieldType(int)
412
         */
413
        public int getFieldType(int i) throws DriverException {
414
                // return dataSource.getFieldType(i);
415
                return dataSource.getFieldType(mapping[i]);
416
        }
417

    
418
        /**
419
         * @see com.hardcode.gdbms.engine.data.DataSource#getDataSourceFactory()
420
         */
421
        public DataSourceFactory getDataSourceFactory() {
422
                return dataSource.getDataSourceFactory();
423
        }
424

    
425
        /**
426
         * @see com.hardcode.gdbms.engine.data.DataSource#getAsString()
427
         */
428
        public String getAsString() throws DriverException {
429
                return dataSource.getAsString();
430
        }
431

    
432
        /**
433
         * @throws DriverException
434
         * @see com.hardcode.gdbms.engine.data.DataSource#remove()
435
         */
436
        public void remove() throws DriverException {
437
                dataSource.remove();
438
        }
439

    
440
        /**
441
         * @see com.hardcode.gdbms.engine.data.DataSource#getMemento()
442
         */
443
        public Memento getMemento() throws MementoException {
444
                return dataSource.getMemento();
445
        }
446

    
447
        /**
448
         * @see com.hardcode.gdbms.engine.data.DataSource#getSourceInfo()
449
         */
450
        public SourceInfo getSourceInfo() {
451
                return dataSource.getSourceInfo();
452
        }
453

    
454
    /**
455
     * @see com.hardcode.gdbms.engine.data.DataSource#getPrimaryKeys()
456
     */
457
    public int[] getPrimaryKeys() throws DriverException {
458
            return dataSource.getPrimaryKeys();
459
    }
460

    
461
    /**
462
     * @see com.hardcode.gdbms.engine.data.DataSource#getPKValue(long)
463
     */
464
    public ValueCollection getPKValue(long rowIndex) throws DriverException {
465
        return dataSource.getPKValue(rowIndex);
466
    }
467

    
468
    /**
469
     * @see com.hardcode.gdbms.engine.data.DataSource#getPKName(int)
470
     */
471
    public String getPKName(int fieldId) throws DriverException {
472
        return dataSource.getPKName(fieldId);
473
    }
474

    
475
    /**
476
     * @see com.hardcode.gdbms.engine.data.DataSource#getPKType(int)
477
     */
478
    public int getPKType(int i) throws DriverException {
479
        return dataSource.getPKType(i);
480
    }
481

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

    
490
    /**
491
     * @see com.hardcode.gdbms.engine.data.DataSource#getRow(long)
492
     */
493
    public Value[] getRow(long rowIndex) throws DriverException {
494
            Value[] withoutVirtuals = new Value[mapping.length];
495
            Value[] internal = dataSource.getRow(rowIndex);
496
            for (int i=0; i < mapping.length; i++)
497
            {
498
                    withoutVirtuals[i] = internal[mapping[i]];
499

    
500
            }
501
        return withoutVirtuals;
502
    }
503

    
504
    /**
505
     * @see com.hardcode.gdbms.engine.data.DataSource#getFieldNames()
506
     */
507
    public String[] getFieldNames() throws DriverException {
508
            String[] fieldNames = new String[getFieldCount()];
509
                int j=0;
510
                for (int i=0; i < dataSource.getFieldCount(); i++)
511
                {
512
                        if (!dataSource.isVirtualField(i))
513
                                fieldNames[j++] = dataSource.getFieldName(i);
514

    
515
                }
516
        // return dataSource.getFieldNames();
517
            return fieldNames;
518
    }
519

    
520
    /**
521
     * @see com.hardcode.gdbms.engine.data.DataSource#getPKNames()
522
     */
523
    public String[] getPKNames() throws DriverException {
524
        return dataSource.getPKNames();
525
    }
526

    
527
        public void removeLinksSelectionListener() {
528
                selectionSupport.removeLinkSelectionListener();
529
        }
530

    
531
    /**
532
     * @throws DriverException
533
     * @see com.hardcode.gdbms.engine.data.DataSource#getDataWare(int)
534
     */
535
    public DataWare getDataWare(int arg0) throws DriverException {
536
        return dataSource.getDataWare(arg0);
537
    }
538

    
539
        public int getFieldWidth(int i) throws DriverException {
540
                return dataSource.getFieldWidth(mapping[i]);
541
                // return dataSource.getFieldWidth(i);
542
        }
543

    
544
        public boolean isVirtualField(int fieldId) throws DriverException {
545
                return dataSource.isVirtualField(fieldId);
546
        }
547

    
548
        /**
549
         * Useful to writers, to know the field definitions.
550
         * NOTE: Maximun precision: 6 decimals. (We may need to change this)
551
         * @return Description of non virtual fields
552
         * @throws DriverException
553
         */
554
        public FieldDescription[] getFieldsDescription() throws DriverException
555
        {
556
                int numFields = getFieldCount();
557
                FieldDescription[] fieldsDescrip = new FieldDescription[numFields];
558
                for (int i = 0; i < numFields; i++) {
559
                        fieldsDescrip[i] = new FieldDescription();
560
                        int type = getFieldType(i);
561
                        fieldsDescrip[i].setFieldType(type);
562
                        fieldsDescrip[i].setFieldName(getFieldName(i));
563
                        fieldsDescrip[i].setFieldLength(getFieldWidth(i));
564
                        if (NumberUtilities.isNumeric(type))
565
                        {
566
                                if (!NumberUtilities.isNumericInteger(type))
567
                                        // TODO: If there is a lost in precision, this should be changed.
568
                                        fieldsDescrip[i].setFieldDecimalCount(6);
569
                        }
570
                        else
571
                                fieldsDescrip[i].setFieldDecimalCount(0);
572
                        // TODO: ?DEFAULTVALUE?
573
                        // fieldsDescrip[i].setDefaultValue(get)
574
                }
575
                return fieldsDescrip;
576
        }
577

    
578
        public Driver getDriver() {
579
                return this.dataSource.getDriver();
580
        }
581

    
582
        public void reload() throws DriverException, IOException {
583
                dataSource.reload();
584
                mapExternalFields();
585

    
586
        }
587

    
588
        public void addDataSourceListener(IDataSourceListener listener) {
589
                dataSource.addDataSourceListener(listener);
590

    
591
        }
592

    
593
        public void removeDataSourceListener(IDataSourceListener listener) {
594
                dataSource.removeDataSourceListener(listener);
595

    
596
        }
597
}