Statistics
| Revision:

root / branches / Mobile_Compatible_Hito_1 / libFMap / src / es / prodevelop / gvsig / mobile / fmap / driver / vect / dbf / DbfDiskDataSource.java @ 21606

History | View | Annotate | Download (12.8 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2006 Prodevelop 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
 *   http://www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   Prodevelop Integraci?n de Tecnolog?as SL
34
 *   Conde Salvatierra de ?lava , 34-10
35
 *   46004 Valencia
36
 *   Spain
37
 *
38
 *   +34 963 510 612
39
 *   +34 963 510 968
40
 *   gis@prodevelop.es
41
 *   http://www.prodevelop.es
42
 *
43
 *    or
44
 *
45
 *   Instituto de Rob?tica
46
 *   Apartado de correos 2085
47
 *   46071 Valencia
48
 *   (Spain)
49
 *   
50
 *   +34 963 543 577
51
 *   jjordan@robotica.uv.es
52
 *   http://robotica.uv.es
53
 *   
54
 */
55

    
56
package es.prodevelop.gvsig.mobile.fmap.driver.vect.dbf;
57

    
58
import java.io.File;
59
import java.io.IOException;
60
import java.sql.Types;
61

    
62
import org.apache.log4j.Logger;
63
import org.gvsig.compatible.StringUtil;
64

    
65
import com.hardcode.driverManager.Driver;
66
import com.hardcode.gdbms.engine.data.DataSource;
67
import com.hardcode.gdbms.engine.data.DataSourceFactory;
68
import com.hardcode.gdbms.engine.data.IDataSourceListener;
69
import com.hardcode.gdbms.engine.data.SourceInfo;
70
import com.hardcode.gdbms.engine.data.driver.DriverException;
71
import com.hardcode.gdbms.engine.data.edition.DataWare;
72
import com.hardcode.gdbms.engine.data.persistence.Memento;
73
import com.hardcode.gdbms.engine.data.persistence.MementoException;
74
import com.hardcode.gdbms.engine.values.Value;
75
import com.hardcode.gdbms.engine.values.ValueCollection;
76
import com.hardcode.gdbms.engine.values.ValueFactory;
77

    
78
import es.prodevelop.gvsig.mobile.fmap.driver.vect.shp.ShpReader;
79
import es.prodevelop.gvsig.mobile.fmap.util.Utils;
80

    
81
/**
82
 * This class implements a JNI-based DataSource which is based on
83
 * a DBF file not loaded into memory.
84
 * 
85
 * @see es.prodevelop.gvsig.mobile.fmap.driver.vect.shp.ShpReader
86
 * @see java.sql.Types
87
 * 
88
 * @author jldominguez
89
 *
90
 */
91
public class DbfDiskDataSource implements DataSource {
92
        
93
        private static Logger logger = Logger.getLogger(DbfDiskDataSource.class);
94
        private File dbFile = null;
95
        // private DbaseFileNIO dbFileAccess = null;
96
        
97
        private int fieldCount = 0;
98
        private int[] fieldTypes = null;
99
        private int[] fieldWidths = null;
100
        private String[] fieldNames = null;
101
        private long fileHandler = -1;
102
        private int rowCount = 0; 
103

    
104
        /**
105
         * Constructor
106
         * @param _dbFile the DBF file to read
107
         */
108
        public DbfDiskDataSource(File _dbFile) {
109
                dbFile = _dbFile;
110
        }
111

    
112
        /**
113
         * Initializes the dfata source (reads the file metadata)
114
         */
115
        public void start() throws DriverException {
116
                
117
                try {
118
                        fileHandler = ShpReader.openDbfFile(dbFile.getCanonicalPath(), false);
119
                        if (fileHandler != 0) {
120
                                fieldCount = ShpReader.getDbfFileFieldCount(fileHandler);
121
                                fieldTypes = dbfTypesToSqlTypes(
122
                                                ShpReader.getDbfFileFieldTypes(fileHandler, fieldCount));
123
                                fieldNames = commaSeparatedToStringArray(
124
                                                ShpReader.getDbfFileFieldNames(fileHandler, fieldCount));
125
                                fieldWidths = ShpReader.getDbfFileFieldWidths(fileHandler, fieldCount);
126
                                rowCount  = ShpReader.getDbfFileRowCount(fileHandler);
127
                        }
128
                } catch (IOException e) {
129
                        logger.error("Error while opening db file " + dbFile.getAbsolutePath() + ": " + e.getMessage());
130
                        throw new DriverException(e.getMessage());
131
                }
132
        }
133

    
134
        /**
135
         * Utility conversion method.
136
         *  
137
         * @param commasep s comma separated list of values
138
         * @return the Strings in an array
139
         */
140
        public static String[] commaSeparatedToStringArray(String commasep) {
141
                String[] resp = StringUtil.splitString(commasep, ",");
142
                if (resp.length > 0) resp[0] = resp[0].substring(1);
143
                return resp;
144
        }
145

    
146
        private int[] dbfTypesToSqlTypes(char[] types) {
147
                int size = types.length;
148
                int[] resp = new int[size];
149

    
150
                for (int i=0; i<size; i++) {
151

    
152
                        resp[i] = Types.VARCHAR;
153
                        char c = types[i];
154
                        if (c == 'C') resp[i] = Types.VARCHAR;
155
                        if (c == 'D') resp[i] = Types.VARCHAR;
156
                        if (c == 'F') resp[i] = Types.DOUBLE;
157
                        if (c == 'N') resp[i] = Types.DOUBLE;
158
                        if (c == 'L') resp[i] = Types.BOOLEAN;
159
                }
160
                return resp;
161
        }
162

    
163
        /**
164
         * Stops the datasource. Tries to close the DBF file.
165
         */
166
        public void stop() throws DriverException {
167
                if (!ShpReader.closeDbfFile(fileHandler)) {
168
                        throw new DriverException("While closing DBF file: " + dbFile.getAbsolutePath());
169
                }
170
        }
171

    
172
        /**
173
         * @return the data source generic name
174
         */
175
        public String getName() {
176
                return "DBF Data Source";
177
        }
178

    
179
        /**
180
         * @return an array representing the WHERE filter. Currently unused.  
181
         */
182
        public long[] getWhereFilter() throws IOException {
183
                logger.warn("Method getWhereFilter() was called, returned new long[0]");
184
                return new long[0];
185
        }
186

    
187
        /**
188
         * @return the associated datasource factory. Currently unused.
189
         */
190
        public DataSourceFactory getDataSourceFactory() {
191
                logger.warn("Method getDataSourceFactory() was called, returned NULL");
192
                return null;
193
        }
194

    
195
        /**
196
         * @return the memento. Currently unused.
197
         */
198
        public Memento getMemento() throws MementoException {
199
                logger.warn("Method getMemento() was called, returned NULL");
200
                return null;
201
        }
202

    
203
        /**
204
         * Sets the datasource factory. Currently  unused.
205
         * 
206
         * @param arg0 the new data source factory
207
         */
208
        public void setDataSourceFactory(DataSourceFactory arg0) {
209
                logger.warn("Method setDataSourceFactory(...) was called, nothing done.");
210
        }
211

    
212
        /**
213
         * Sets the source info. Currently unused.
214
         * @param arg0 the new source info
215
         */
216
        public void setSourceInfo(SourceInfo arg0) {
217
                logger.warn("Method setSourceInfo(...) was called, nothing done.");
218
        }
219

    
220
        /**
221
         * @return the source info. Currently unused.
222
         */
223
        public SourceInfo getSourceInfo() {
224
                logger.warn("Method getSourceInfo() was called, returned NULL");
225
                return null;
226
        }
227

    
228
        /**
229
         * @return a string representing the datasource. Unused. Simply redirects to
230
         * <code>getName()</code>
231
         */
232
        public String getAsString() throws DriverException {
233
                logger.warn("Method getAsString() was called, returned getName()");
234
                return getName();
235
        }
236

    
237
        /**
238
         * Called when the layer is removed. Tries to prevent memory leaks.
239
         *  
240
         */
241
        public void remove() throws DriverException {
242
                logger.warn("Method remove() was called, nothing done.");
243
        }
244

    
245
        /**
246
         * @return an array with the indices of the primary keys.
247
         */
248
        public int[] getPrimaryKeys() throws DriverException {
249
                logger.warn("Method getPrimaryKeys() was called, returned all indices.");
250
                int[] resp = new int[fieldCount];
251
                for (int i=0; i<fieldCount; i++) resp[i] = i;
252
                return resp;
253
        }
254

    
255
        /**
256
         * Gets the primary key value for a row
257
         * @param arg0 the row of interest
258
         * @return a collection representing the primary key
259
         */
260
        public ValueCollection getPKValue(long arg0) throws DriverException {
261
                logger.warn("Method getPKValue(" + arg0 + ") was called, returned NULL");
262
                return null;
263
        }
264

    
265
        /**
266
         * Gets the name of one of the fields that compose the PK.
267
         * @param arg0 the index of the PK field of interest
268
         * @return the name of the field of interest
269
         */
270
        public String getPKName(int arg0) throws DriverException {
271
                logger.warn("Method getPKName(" + arg0 + ") was called, returned NULL");
272
                return null;
273
        }
274

    
275
        /**
276
         * @return the names of the fields that compose the PK.
277
         * 
278
         */
279
        public String[] getPKNames() throws DriverException {
280
                logger.warn("Method getPKNames() was called, returned NULL");
281
                return null;
282
        }
283

    
284
        /**
285
         * Gets the type of one of the fields that compose the PK.
286
         * 
287
         * @param arg0 the index of the field of interest
288
         * @return the type of the field of interest
289
         */
290
        public int getPKType(int arg0) throws DriverException {
291
                logger.warn("Method getPKType(" + arg0 + ") was called, returned getFieldType(...)");
292
                return fieldTypes[arg0];
293
        }
294

    
295
        /**
296
         * @return the cumber of fields that compose the PK.
297
         */
298
        public int getPKCardinality() throws DriverException {
299
                return fieldCount;
300
        }
301
        
302
        private Value getValueOfItsType(int fieldindex, int row) {
303
                
304
                Value resp = ValueFactory.createNullValue();
305
                
306
                int type = fieldTypes[fieldindex];
307
                switch (type) {
308

    
309
                case Types.DOUBLE:
310
                        double val = -81.112;
311
                        try {
312
                                val = ShpReader.getDbfNumberFieldValue(fileHandler, row, fieldindex);
313
                        } catch (Throwable th) {
314
                                logger.debug("Error: " + th.getMessage());
315
                        }
316
                        resp = ValueFactory.createValue(val);
317
                        break;
318
                        
319
                case Types.VARCHAR:
320
                        resp = ValueFactory.createValue(
321
                                        ShpReader.getDbfStringFieldValue(
322
                                                        fileHandler, row, fieldindex
323
                                                        ));
324
                        break;
325
                        
326
                case Types.DATE:
327
                        
328
                        resp = ValueFactory.createValue(
329
                                        ShpReader.getDbfStringFieldValue(
330
                                                        fileHandler, row, fieldindex
331
                                        ));
332
                        break;
333
                        
334
                case Types.BOOLEAN:
335

    
336
                        resp = ValueFactory.createValue(
337
                                        ShpReader.getDbfBooleanFieldValue(
338
                                                        fileHandler, row, fieldindex
339
                                                        ));
340
                        break;
341
                }
342
                
343
                return resp;
344
        }
345

    
346
        /**
347
         * Gets a row of this data source.
348
         * @param rowind the index of the row of interest
349
         * @return the row as an array of values
350
         */
351
        public Value[] getRow(long rowind) throws DriverException {
352
                Value[] resp = new Value[fieldCount];
353
                for (int i=0; i<fieldCount; i++) {
354
                        resp[i] = getValueOfItsType(i, (int) rowind);
355
                }
356
                return resp;
357
        }
358

    
359
        /**
360
         * @return an array with all the field names
361
         */
362
        public String[] getFieldNames() throws DriverException {
363
                return fieldNames;
364
        }
365

    
366
        /**
367
         * Gets the idnex of a field, provided its name.
368
         * @param arg0 the name of the field of interest
369
         * @return the index of the field of interest
370
         */
371
        public int getFieldIndexByName(String arg0) throws DriverException {
372
                for (int i=0; i<fieldCount; i++) {
373
                        if (arg0.compareToIgnoreCase(fieldNames[i]) == 0) return i;
374
                }
375
                logger.error("Field name not found: " + arg0);
376
                return -1;
377
        }
378

    
379
        /**
380
         * Gets the data ware associated with the given index.
381
         * Currently unused.
382
         * 
383
         * @param arg0 the index of interest
384
         * @return the associated data ware
385
         */
386
        public DataWare getDataWare(int arg0) throws DriverException {
387
                logger.warn("Method getDataWare(" + arg0 + ") returned NULL.");
388
                return null;
389
        }
390

    
391
        /**
392
         * Gets whether the referenced field is virtual or not.
393
         * 
394
         * @param arg0 the index of the field of interest
395
         * @return whether it is a virtual field.
396
         * 
397
         */
398
        public boolean isVirtualField(int arg0) throws DriverException {
399
                return false;
400
        }
401

    
402
        /**
403
         * @return the associated driver, currently unused.
404
         */
405
        public Driver getDriver() {
406
                logger.warn("Method getDriver() returned NULL.");
407
                return null;
408
        }
409

    
410
        /**
411
         * Reloads the data source (stops and starts)
412
         */
413
        public void reload() throws DriverException, IOException {
414
                stop();
415
                start();
416
        }
417

    
418
        /**
419
         * Adds a datasource listener. Currently unused.
420
         * @param arg0 the listener to be added.
421
         */
422
        public void addDataSourceListener(IDataSourceListener arg0) {
423
                logger.warn("Method addDataSourceListener(), nothing done.");
424
        }
425

    
426
        /**
427
         * Removes a datasource listener. Currently unused.
428
         * @param arg0 the listener to be removed.
429
         */
430
        public void removeDataSourceListener(IDataSourceListener arg0) {
431
                logger.warn("Method removeDataSourceListener(), nothing done.");
432
        }
433

    
434
        /**
435
         * Gets a value from thsi data source.
436
         * @param arg0 the row of interest
437
         * @param arg1 the index of the field of interest
438
         * 
439
         * @return the value of the given row and field
440
         */
441
        public Value getFieldValue(long arg0, int arg1) throws DriverException {
442
                return getValueOfItsType(arg1, (int) arg0);
443
        }
444

    
445
        /**
446
         * @return the number of fields in this datasource
447
         */
448
        public int getFieldCount() throws DriverException {
449
                return fieldCount;
450
        }
451

    
452
        /**
453
         * Gets the name of the field with the given index.
454
         * @param arg0 the index of the field of interest
455
         * @return the name of the field
456
         */
457
        public String getFieldName(int arg0) throws DriverException {
458
                return fieldNames[arg0];
459
        }
460

    
461
        /**
462
         * @return the number of rows in this data source
463
         */
464
        public long getRowCount() throws DriverException {
465
                return rowCount;
466
        }
467

    
468
        /**
469
         * Gets the type of the field with the given index.
470
         * @param arg0 the index of the field of interest
471
         * @return teh field type
472
         */
473
        public int getFieldType(int arg0) throws DriverException {
474
                return fieldTypes[arg0];
475
        }
476

    
477
        /**
478
         * Gets the width of the field with the given index.
479
         * @param arg0 the index of the field of interest
480
         * @return teh field width
481
         */
482
        public int getFieldWidth(int arg0) throws DriverException {
483
                return fieldWidths[arg0];
484
        }
485
}