Statistics
| Revision:

root / branches / piloto3d / libraries / libFMap / src / com / iver / cit / gvsig / fmap / drivers / dbf / DBFDriver.java @ 9524

History | View | Annotate | Download (13.3 KB)

1
package com.iver.cit.gvsig.fmap.drivers.dbf;
2

    
3
import java.io.File;
4
import java.io.FileInputStream;
5
import java.io.FileNotFoundException;
6
import java.io.FileOutputStream;
7
import java.io.IOException;
8
import java.io.RandomAccessFile;
9
import java.io.UnsupportedEncodingException;
10
import java.nio.channels.FileChannel;
11
import java.nio.channels.WritableByteChannel;
12
import java.sql.Types;
13
import java.text.DateFormat;
14
import java.text.ParseException;
15
import java.util.Date;
16
import java.util.Locale;
17
import java.util.Properties;
18

    
19
import com.hardcode.gdbms.driver.DriverUtilities;
20
import com.hardcode.gdbms.engine.data.DataSourceFactory;
21
import com.hardcode.gdbms.engine.data.driver.DriverException;
22
import com.hardcode.gdbms.engine.data.driver.FileDriver;
23
import com.hardcode.gdbms.engine.data.edition.DataWare;
24
import com.hardcode.gdbms.engine.data.file.FileDataWare;
25
import com.hardcode.gdbms.engine.values.Value;
26
import com.hardcode.gdbms.engine.values.ValueFactory;
27
import com.iver.cit.gvsig.fmap.drivers.FieldDescription;
28
import com.iver.cit.gvsig.fmap.drivers.ITableDefinition;
29
import com.iver.cit.gvsig.fmap.drivers.TableDefinition;
30
import com.iver.cit.gvsig.fmap.drivers.shp.DbaseFileHeaderNIO;
31
import com.iver.cit.gvsig.fmap.drivers.shp.DbaseFileWriterNIO;
32
import com.iver.cit.gvsig.fmap.edition.EditionException;
33
import com.iver.cit.gvsig.fmap.edition.IRowEdited;
34
import com.iver.cit.gvsig.fmap.edition.IWriteable;
35
import com.iver.cit.gvsig.fmap.edition.IWriter;
36
import com.iver.cit.gvsig.fmap.edition.fieldmanagers.AbstractFieldManager;
37
import com.iver.cit.gvsig.fmap.edition.writers.dbf.DbfWriter;
38
import com.iver.utiles.NumberUtilities;
39

    
40

    
41
/**
42
 * DOCUMENT ME!
43
 *
44
 * @author Fernando Gonz?lez Cort?s
45
 */
46
public class DBFDriver extends AbstractFieldManager implements FileDriver, IWriteable, IWriter {
47
    //private File file;
48
    private static Locale ukLocale = new Locale("en", "UK"); // English, UK version
49
    private DbaseFile dbf = new DbaseFile();
50
    private char[] fieldTypes;
51
    private DataSourceFactory dsf;
52
    private DbfWriter dbfWriter = new DbfWriter();
53
        private File file = null;
54
        private static String tempDirectoryPath = System.getProperty("java.io.tmpdir");
55
        private File fTemp;
56
    private ITableDefinition tableDef;
57

    
58
    /**
59
     * @see com.hardcode.driverManager.Driver#getName()
60
     */
61
    public String getName() {
62
        return "gdbms dbf driver";
63
    }
64

    
65
    /**
66
     * @see com.hardcode.gdbms.engine.data.GDBMSDriver#open(java.io.File)
67
     */
68
    public void open(File file) throws IOException {
69
            this.file  = file;
70
        dbf.open(file);
71

    
72
        try {
73
            fieldTypes = new char[getFieldCount()];
74

    
75
            for (int i = 0; i < fieldTypes.length; i++) {
76
                fieldTypes[i] = dbf.getFieldType(i);
77
            }
78
                    int aux = (int)(Math.random() * 1000);
79
                    fTemp = new File(tempDirectoryPath + "/tmpDbf" + aux + ".dbf");            
80
                    dbfWriter.setFile(fTemp);
81
        } catch (DriverException e) {
82
            throw new IOException(e.getMessage());
83
        }
84

    
85
    }
86

    
87
    /**
88
     * @see com.hardcode.gdbms.engine.data.GDBMSDriver#close()
89
     */
90
    public void close() throws IOException {
91
        dbf.close();
92
    }
93

    
94
    /**
95
     * @see com.hardcode.gdbms.engine.data.driver.ReadAccess#getFieldValue(long,
96
     *      int)
97
     */
98
    public Value getFieldValue(long rowIndex, int fieldId)
99
        throws DriverException {
100
        // Field Type (C  or M)
101
        char fieldType = fieldTypes[fieldId];
102

    
103
        if (fieldType == 'L') {
104
            return ValueFactory.createValue(dbf.getBooleanFieldValue(
105
                    (int) rowIndex, fieldId));
106

    
107
            /*                }else if (fieldType == 'N'){
108
               String strValue = dbf.getStringFieldValue(rowIndex, fieldId);
109
               long value = Long.parseLong(strValue);
110
               if ((value > Integer.MIN_VALUE) && (value < Integer.MAX_VALUE)){
111
                       return new IntValue((int) value);
112
               }else{
113
                       return new LongValue(value);
114
               }
115
             */
116
        } else if ((fieldType == 'F') || (fieldType == 'N')) {
117
            String strValue;
118
                        try {
119
                                strValue = dbf.getStringFieldValue((int) rowIndex, fieldId)
120
                                                     .trim();
121
                        } catch (UnsupportedEncodingException e1) {
122
                                e1.printStackTrace();
123
                                throw new DriverException(e1);
124
                        }
125

    
126
            if (strValue.length() == 0) {
127
                return null;
128
            }
129
            double value=0;
130
            try{
131
            value = Double.parseDouble(strValue);
132
            }catch (Exception e) {
133
                                return ValueFactory.createValue(0D);
134
                        }
135
            return ValueFactory.createValue(value);
136
        } else if (fieldType == 'C') {
137
            try {
138
                                return ValueFactory.createValue(dbf.getStringFieldValue(
139
                                        (int) rowIndex, fieldId).trim());
140
                        } catch (UnsupportedEncodingException e) {
141
                                throw new DriverException(e);
142
                        }
143
        } else if (fieldType == 'D') {
144
            String date;
145
                        try {
146
                                date = dbf.getStringFieldValue((int) rowIndex, fieldId).trim();
147
                        } catch (UnsupportedEncodingException e1) {
148
                                throw new DriverException(e1);
149
                        }
150
            // System.out.println(rowIndex + " data=" + date);
151
            if (date.length() == 0) {
152
                return null;
153
            }
154

    
155
            String year = date.substring(0, 4);
156
            String month = date.substring(4, 6);
157
            String day = date.substring(6, 8);
158
            DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, ukLocale);
159
            /* Calendar c = Calendar.getInstance();
160
            c.clear();
161
            c.set(Integer.parseInt(year), Integer.parseInt(month),
162
                Integer.parseInt(day));
163
            c.set(Calendar.MILLISECOND, 0); */
164
            String strAux = month + "/" + day + "/" + year;
165
            Date dat;
166
            try {
167
                dat = df.parse(strAux);
168
            } catch (ParseException e) {
169
                throw new DriverException("Bad Date Format");
170
            }
171

    
172
            // System.out.println("numReg = " + rowIndex + " date:" + dat.getTime());
173

    
174
            return ValueFactory.createValue(dat);
175
        } else {
176
            throw new DriverException("Unknown field type");
177
        }
178
    }
179

    
180
    /**
181
     * @see com.hardcode.gdbms.engine.data.driver.ReadAccess#getFieldCount()
182
     */
183
    public int getFieldCount() throws DriverException {
184
        return dbf.getFieldCount();
185
    }
186

    
187
    /**
188
     * @see com.hardcode.gdbms.engine.data.driver.ReadAccess#getFieldName(int)
189
     */
190
    public String getFieldName(int fieldId) throws DriverException {
191
        return dbf.getFieldName(fieldId);
192
    }
193

    
194
    /**
195
     * @see com.hardcode.gdbms.engine.data.driver.ReadAccess#getRowCount()
196
     */
197
    public long getRowCount() throws DriverException {
198
        return dbf.getRecordCount();
199
    }
200

    
201
    /**
202
     * @see com.hardcode.gdbms.engine.data.driver.FileDriver#fileAccepted(java.io.File)
203
     */
204
    public boolean fileAccepted(File f) {
205
        return f.getAbsolutePath().toUpperCase().endsWith("DBF");
206
    }
207

    
208
    /**
209
     * @see com.hardcode.gdbms.engine.data.driver.ObjectDriver#getFieldType(int)
210
     */
211
    public int getFieldType(int i) throws DriverException {
212
        char fieldType = fieldTypes[i];
213

    
214
        if (fieldType == 'L') {
215
            return Types.BOOLEAN;
216
        } else if ((fieldType == 'F') || (fieldType == 'N')) {
217
                if (dbf.getFieldDecimalLength(i)>0)
218
                        return Types.DOUBLE;
219
                else
220
                        return Types.INTEGER;
221
        } else if (fieldType == 'C') {
222
            return Types.VARCHAR;
223
        } else if (fieldType == 'D') {
224
            return Types.DATE;
225
        } else {
226
            throw new DriverException("Unknown field type");
227
        }
228
    }
229

    
230
    /**
231
     * @see com.hardcode.gdbms.engine.data.driver.DriverCommons#setDataSourceFactory(com.hardcode.gdbms.engine.data.DataSourceFactory)
232
     */
233
    public void setDataSourceFactory(DataSourceFactory dsf) {
234
        this.dsf = dsf;
235
    }
236

    
237
    private void writeToTemp(DataWare dataWare, File file) throws DriverException {
238
        DbaseFileWriterNIO dbfWrite = null;
239
        DbaseFileHeaderNIO myHeader;
240
        Value[] record;
241

    
242
        try {
243
            myHeader = DbaseFileHeaderNIO.createDbaseHeader(dataWare);
244

    
245
            myHeader.setNumRecords((int) dataWare.getRowCount());
246
            dbfWrite = new DbaseFileWriterNIO(myHeader,
247
                    (FileChannel) getWriteChannel(file.getPath()));
248
            record = new Value[dataWare.getFieldCount()];
249

    
250
            for (int j = 0; j < dataWare.getRowCount(); j++) {
251
                for (int r = 0; r < dataWare.getFieldCount(); r++) {
252
                    record[r] = dataWare.getFieldValue(j, r);
253
                }
254

    
255
                dbfWrite.write(record);
256
            }
257

    
258
            dbfWrite.close();
259
        } catch (IOException e) {
260
            throw new DriverException(e);
261
        }
262

    
263
    }
264

    
265
    /**
266
     * @see com.hardcode.gdbms.engine.data.driver.FileDriver#writeFile(com.hardcode.gdbms.engine.data.file.FileDataWare,
267
     *      java.io.File)
268
     */
269
    public void writeFile(FileDataWare dataWare)
270
        throws DriverException {
271

    
272
        String temp = dsf.getTempFile();
273

    
274
        writeToTemp(dataWare, new File(temp));
275

    
276
        try {
277
            FileChannel fcout = dbf.getWriteChannel();
278
            FileChannel fcin = new FileInputStream(temp).getChannel();
279

    
280
            DriverUtilities.copy(fcin, fcout);
281
        } catch (IOException e) {
282
            throw new DriverException(e);
283
        }
284
    }
285

    
286
    /**
287
     * DOCUMENT ME!
288
     *
289
     * @param path DOCUMENT ME!
290
     *
291
     * @return DOCUMENT ME!
292
     *
293
     * @throws IOException DOCUMENT ME!
294
     */
295
    private WritableByteChannel getWriteChannel(String path)
296
        throws IOException {
297
        WritableByteChannel channel;
298

    
299
        File f = new File(path);
300

    
301
        if (!f.exists()) {
302
            System.out.println("Creando fichero " + f.getAbsolutePath());
303

    
304
            if (!f.createNewFile()) {
305
                throw new IOException("Cannot create file " + f);
306
            }
307
        }
308

    
309
        RandomAccessFile raf = new RandomAccessFile(f, "rw");
310
        channel = raf.getChannel();
311

    
312
        return channel;
313
    }
314

    
315
    /* (non-Javadoc)
316
     * @see com.hardcode.gdbms.engine.data.driver.FileDriver#createSource(java.lang.String, java.lang.String[], int[])
317
     */
318
    public void createSource(String arg0, String[] arg1, int[] arg2) throws IOException {
319
        DbaseFileHeaderNIO myHeader;
320

    
321
        int[] lengths = new int[arg2.length];
322
        for (int i = 0; i < arg2.length; i++) {
323
            lengths[i] = 100;
324
        }
325
        myHeader = DbaseFileHeaderNIO.createDbaseHeader(arg1, arg2, lengths);
326
        myHeader.setNumRecords(0);
327
        DbaseFileWriterNIO dbfWrite = new DbaseFileWriterNIO(myHeader,
328
                (FileChannel) getWriteChannel(arg0));
329
        dbfWrite = new DbaseFileWriterNIO(myHeader,
330
                (FileChannel) getWriteChannel(arg0));
331
    }
332

    
333
        public int getFieldWidth(int i) throws DriverException {
334
                return dbf.getFieldLength(i);
335
        }
336

    
337
        public IWriter getWriter() {
338
                return this;
339
        }
340

    
341
        public void preProcess() throws EditionException {
342
                dbfWriter.preProcess();
343

    
344
        }
345

    
346
        public void process(IRowEdited row) throws EditionException {
347
                dbfWriter.process(row);
348

    
349
        }
350

    
351
        public void postProcess() throws EditionException {
352
                dbfWriter.postProcess();
353
                try {
354
                        // Dbf
355
                        File dbfFile = fTemp;
356
                        FileChannel fcinDbf = new FileInputStream(dbfFile).getChannel();
357
                        FileChannel fcoutDbf = new FileOutputStream(file).getChannel();
358
                        DriverUtilities.copy(fcinDbf, fcoutDbf);
359

    
360
                        // Borramos los temporales
361
                        fTemp.delete();
362

    
363
                        // Reload
364
                        close();
365
                        open(file);
366

    
367

    
368

    
369
                } catch (FileNotFoundException e) {
370
                        throw new EditionException(e);
371
                } catch (IOException e) {
372
                        throw new EditionException(e);
373
                }
374

    
375

    
376
        }
377

    
378
        public String getCapability(String capability) {
379
                return dbfWriter.getCapability(capability);
380
        }
381

    
382
        public void setCapabilities(Properties capabilities) {
383
                dbfWriter.setCapabilities(capabilities);
384

    
385
        }
386

    
387
        public boolean canWriteAttribute(int sqlType) {
388
                return dbfWriter.canWriteAttribute(sqlType);
389
        }
390

    
391
        public void initialize(ITableDefinition tableDefinition) throws EditionException {
392
                dbfWriter.initialize(tableDefinition);
393

    
394
        }
395

    
396
        public ITableDefinition getTableDefinition() {
397
                tableDef = new TableDefinition();
398
                int numFields; 
399
                try {
400
                        numFields = getFieldCount();
401
                        FieldDescription[] fieldsDescrip = new FieldDescription[numFields];
402
                        for (int i = 0; i < numFields; i++) {
403
                                fieldsDescrip[i] = new FieldDescription();
404
                                int type = getFieldType(i);
405
                                fieldsDescrip[i].setFieldType(type);
406
                                fieldsDescrip[i].setFieldName(getFieldName(i));
407
                                fieldsDescrip[i].setFieldLength(getFieldWidth(i));
408
                                if (NumberUtilities.isNumeric(type))
409
                                {
410
                                        if (!NumberUtilities.isNumericInteger(type))
411
                                                // TODO: If there is a lost in precision, this should be changed.
412
                                                fieldsDescrip[i].setFieldDecimalCount(6);
413
                                }
414
                                else
415
                                        fieldsDescrip[i].setFieldDecimalCount(0);
416
                                // TODO: ?DEFAULTVALUE?
417
                                // fieldsDescrip[i].setDefaultValue(get)
418
                        }
419
        
420
                        tableDef.setFieldsDesc(fieldsDescrip);
421
                        return tableDef;
422
                } catch (DriverException e) {
423
                        // TODO Auto-generated catch block
424
                        e.printStackTrace();
425
                }
426
                return null;
427
//                return dbfWriter.getTableDefinition();
428
        }
429

    
430
        public boolean canAlterTable() {
431
                return true;
432
        }
433

    
434
        public boolean alterTable() throws EditionException {
435
                return true;
436
        }
437

    
438
        public boolean canSaveEdits() {
439
                if (file.canWrite()) return true;
440
                return false;
441

    
442
        }
443

    
444
        public boolean isWriteAll() {
445
                // TODO: DEVOLVER FALSE SI NO HA HABIDO CAMBIOS EN LOS CAMPOS.
446
                return true;
447
        }
448

    
449
}