Statistics
| Revision:

root / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / drivers / dbf / DBFDriver.java @ 10627

History | View | Annotate | Download (14.5 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.driver.exceptions.BadFieldDriverException;
21
import com.hardcode.gdbms.driver.exceptions.CloseDriverException;
22
import com.hardcode.gdbms.driver.exceptions.InitializeWriterException;
23
import com.hardcode.gdbms.driver.exceptions.OpenDriverException;
24
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
25
import com.hardcode.gdbms.driver.exceptions.WriteDriverException;
26
import com.hardcode.gdbms.engine.data.DataSourceFactory;
27
import com.hardcode.gdbms.engine.data.driver.FileDriver;
28
import com.hardcode.gdbms.engine.data.edition.DataWare;
29
import com.hardcode.gdbms.engine.data.file.FileDataWare;
30
import com.hardcode.gdbms.engine.values.Value;
31
import com.hardcode.gdbms.engine.values.ValueFactory;
32
import com.iver.cit.gvsig.exceptions.visitors.ProcessWriterVisitorException;
33
import com.iver.cit.gvsig.exceptions.visitors.StartWriterVisitorException;
34
import com.iver.cit.gvsig.exceptions.visitors.StopWriterVisitorException;
35
import com.iver.cit.gvsig.fmap.drivers.FieldDescription;
36
import com.iver.cit.gvsig.fmap.drivers.ITableDefinition;
37
import com.iver.cit.gvsig.fmap.drivers.TableDefinition;
38
import com.iver.cit.gvsig.fmap.drivers.shp.DbaseFileHeaderNIO;
39
import com.iver.cit.gvsig.fmap.drivers.shp.DbaseFileWriterNIO;
40
import com.iver.cit.gvsig.fmap.edition.IRowEdited;
41
import com.iver.cit.gvsig.fmap.edition.IWriteable;
42
import com.iver.cit.gvsig.fmap.edition.IWriter;
43
import com.iver.cit.gvsig.fmap.edition.fieldmanagers.AbstractFieldManager;
44
import com.iver.cit.gvsig.fmap.edition.writers.dbf.DbfWriter;
45
import com.iver.utiles.NumberUtilities;
46

    
47

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

    
65
    /**
66
     * @see com.hardcode.driverManager.Driver#getName()
67
     */
68
    public String getName() {
69
        return "gdbms dbf driver";
70
    }
71

    
72
    /**
73
     * @see com.hardcode.gdbms.engine.data.GDBMSDriver#open(java.io.File)
74
     */
75
    public void open(File file) throws OpenDriverException {
76
            this.file  = file;
77
        try {
78
                        dbf.open(file);
79
                    fieldTypes = new char[getFieldCount()];
80
            for (int i = 0; i < fieldTypes.length; i++) {
81
                fieldTypes[i] = dbf.getFieldType(i);
82
            }
83
                    int aux = (int)(Math.random() * 1000);
84
                    fTemp = new File(tempDirectoryPath + "/tmpDbf" + aux + ".dbf");
85
                    dbfWriter.setFile(fTemp);
86
        } catch (ReadDriverException e) {
87
                        throw new OpenDriverException(getName(),e);
88
                }
89

    
90
    }
91

    
92
    /**
93
     * @see com.hardcode.gdbms.engine.data.GDBMSDriver#close()
94
     */
95
    public void close() throws CloseDriverException {
96
        try {
97
                        dbf.close();
98
                } catch (IOException e) {
99
                        throw new CloseDriverException(getName(),e);
100
                }
101
    }
102

    
103
    /**
104
     * @see com.hardcode.gdbms.engine.data.driver.ReadAccess#getFieldValue(long,
105
     *      int)
106
     */
107
    public Value getFieldValue(long rowIndex, int fieldId)
108
        throws ReadDriverException {
109
        // Field Type (C  or M)
110
        char fieldType = fieldTypes[fieldId];
111

    
112
        if (fieldType == 'L') {
113
            return ValueFactory.createValue(dbf.getBooleanFieldValue(
114
                    (int) rowIndex, fieldId));
115

    
116
            /*                }else if (fieldType == 'N'){
117
               String strValue = dbf.getStringFieldValue(rowIndex, fieldId);
118
               long value = Long.parseLong(strValue);
119
               if ((value > Integer.MIN_VALUE) && (value < Integer.MAX_VALUE)){
120
                       return new IntValue((int) value);
121
               }else{
122
                       return new LongValue(value);
123
               }
124
             */
125
        } else if ((fieldType == 'F') || (fieldType == 'N')) {
126
            String strValue;
127
                        try {
128
                                strValue = dbf.getStringFieldValue((int) rowIndex, fieldId)
129
                                                     .trim();
130
                        } catch (UnsupportedEncodingException e1) {
131
                                throw new ReadDriverException(getName(),e1);
132
                        }
133

    
134
            if (strValue.length() == 0) {
135
                return null;
136
            }
137
            double value=0;
138
            try{
139
            value = Double.parseDouble(strValue);
140
            }catch (Exception e) {
141
                                return ValueFactory.createValue(0D);
142
                        }
143
            return ValueFactory.createValue(value);
144
        } else if (fieldType == 'C') {
145
            try {
146
                                return ValueFactory.createValue(dbf.getStringFieldValue(
147
                                        (int) rowIndex, fieldId).trim());
148
                        } catch (UnsupportedEncodingException e) {
149
                                throw new ReadDriverException(getName(),e);
150
                        }
151
        } else if (fieldType == 'D') {
152
            String date;
153
                        try {
154
                                date = dbf.getStringFieldValue((int) rowIndex, fieldId).trim();
155
                        } catch (UnsupportedEncodingException e1) {
156
                                throw new ReadDriverException(getName(),e1);
157
                        }
158
            // System.out.println(rowIndex + " data=" + date);
159
            if (date.length() == 0) {
160
                return null;
161
            }
162

    
163
            String year = date.substring(0, 4);
164
            String month = date.substring(4, 6);
165
            String day = date.substring(6, 8);
166
            DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, ukLocale);
167
            /* Calendar c = Calendar.getInstance();
168
            c.clear();
169
            c.set(Integer.parseInt(year), Integer.parseInt(month),
170
                Integer.parseInt(day));
171
            c.set(Calendar.MILLISECOND, 0); */
172
            String strAux = month + "/" + day + "/" + year;
173
            Date dat;
174
            try {
175
                dat = df.parse(strAux);
176
            } catch (ParseException e) {
177
                throw new ReadDriverException(getName(),e);
178
            }
179

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

    
182
            return ValueFactory.createValue(dat);
183
        } else {
184
            throw new BadFieldDriverException(getName(),null,String.valueOf(fieldType));
185
        }
186
    }
187

    
188
    /**
189
     * @see com.hardcode.gdbms.engine.data.driver.ReadAccess#getFieldCount()
190
     */
191
    public int getFieldCount() throws ReadDriverException {
192
        return dbf.getFieldCount();
193
    }
194

    
195
    /**
196
     * @see com.hardcode.gdbms.engine.data.driver.ReadAccess#getFieldName(int)
197
     */
198
    public String getFieldName(int fieldId) throws ReadDriverException {
199
        return dbf.getFieldName(fieldId);
200
    }
201

    
202
    /**
203
     * @see com.hardcode.gdbms.engine.data.driver.ReadAccess#getRowCount()
204
     */
205
    public long getRowCount() throws ReadDriverException {
206
        return dbf.getRecordCount();
207
    }
208

    
209
    /**
210
     * @see com.hardcode.gdbms.engine.data.driver.FileDriver#fileAccepted(java.io.File)
211
     */
212
    public boolean fileAccepted(File f) {
213
        return f.getAbsolutePath().toUpperCase().endsWith("DBF");
214
    }
215

    
216
    /**
217
     * @see com.hardcode.gdbms.engine.data.driver.ObjectDriver#getFieldType(int)
218
     */
219
    public int getFieldType(int i) throws ReadDriverException {
220
        char fieldType = fieldTypes[i];
221

    
222
        if (fieldType == 'L') {
223
            return Types.BOOLEAN;
224
        } else if ((fieldType == 'F') || (fieldType == 'N')) {
225
                if (dbf.getFieldDecimalLength(i)>0)
226
                        return Types.DOUBLE;
227
                else
228
                        return Types.INTEGER;
229
        } else if (fieldType == 'C') {
230
            return Types.VARCHAR;
231
        } else if (fieldType == 'D') {
232
            return Types.DATE;
233
        } else {
234
            throw new BadFieldDriverException(getName(),null,String.valueOf(fieldType));
235
        }
236
    }
237

    
238
    /**
239
     * @see com.hardcode.gdbms.engine.data.driver.DriverCommons#setDataSourceFactory(com.hardcode.gdbms.engine.data.DataSourceFactory)
240
     */
241
    public void setDataSourceFactory(DataSourceFactory dsf) {
242
        this.dsf = dsf;
243
    }
244

    
245
    private void writeToTemp(DataWare dataWare, File file) throws WriteDriverException, ReadDriverException {
246
        DbaseFileWriterNIO dbfWrite = null;
247
        DbaseFileHeaderNIO myHeader;
248
        Value[] record;
249

    
250
        try {
251
            myHeader = DbaseFileHeaderNIO.createDbaseHeader(dataWare);
252

    
253
            myHeader.setNumRecords((int) dataWare.getRowCount());
254
            dbfWrite = new DbaseFileWriterNIO(myHeader,
255
                    (FileChannel) getWriteChannel(file.getPath()));
256
            record = new Value[dataWare.getFieldCount()];
257

    
258
            for (int j = 0; j < dataWare.getRowCount(); j++) {
259
                for (int r = 0; r < dataWare.getFieldCount(); r++) {
260
                    record[r] = dataWare.getFieldValue(j, r);
261
                }
262

    
263
                dbfWrite.write(record);
264
            }
265

    
266
            dbfWrite.close();
267
        } catch (IOException e) {
268
            throw new WriteDriverException(getName(),e);
269
        }
270

    
271
    }
272

    
273
    /**
274
     * @throws ReadDriverException
275
     * @see com.hardcode.gdbms.engine.data.driver.FileDriver#writeFile(com.hardcode.gdbms.engine.data.file.FileDataWare,
276
     *      java.io.File)
277
     */
278
    public void writeFile(FileDataWare dataWare)
279
        throws WriteDriverException, ReadDriverException {
280

    
281
        String temp = dsf.getTempFile();
282

    
283
        writeToTemp(dataWare, new File(temp));
284

    
285
        try {
286
            FileChannel fcout = dbf.getWriteChannel();
287
            FileChannel fcin = new FileInputStream(temp).getChannel();
288

    
289
            DriverUtilities.copy(fcin, fcout);
290
        } catch (IOException e) {
291
            throw new WriteDriverException(getName(),e);
292
        }
293
    }
294

    
295
    /**
296
     * DOCUMENT ME!
297
     *
298
     * @param path DOCUMENT ME!
299
     *
300
     * @return DOCUMENT ME!
301
     *
302
     * @throws IOException DOCUMENT ME!
303
     */
304
    private WritableByteChannel getWriteChannel(String path)
305
        throws IOException {
306
        WritableByteChannel channel;
307

    
308
        File f = new File(path);
309

    
310
        if (!f.exists()) {
311
            System.out.println("Creando fichero " + f.getAbsolutePath());
312

    
313
            if (!f.createNewFile()) {
314
                throw new IOException("Cannot create file " + f);
315
            }
316
        }
317

    
318
        RandomAccessFile raf = new RandomAccessFile(f, "rw");
319
        channel = raf.getChannel();
320

    
321
        return channel;
322
    }
323

    
324
    /* (non-Javadoc)
325
     * @see com.hardcode.gdbms.engine.data.driver.FileDriver#createSource(java.lang.String, java.lang.String[], int[])
326
     */
327
    public void createSource(String arg0, String[] arg1, int[] arg2) throws ReadDriverException {
328
        DbaseFileHeaderNIO myHeader;
329

    
330
        int[] lengths = new int[arg2.length];
331
        for (int i = 0; i < arg2.length; i++) {
332
            lengths[i] = 100;
333
        }
334
        try {
335
                        myHeader = DbaseFileHeaderNIO.createDbaseHeader(arg1, arg2, lengths);
336

    
337
        myHeader.setNumRecords(0);
338
        DbaseFileWriterNIO dbfWrite = new DbaseFileWriterNIO(myHeader,
339
                (FileChannel) getWriteChannel(arg0));
340
        dbfWrite = new DbaseFileWriterNIO(myHeader,
341
                (FileChannel) getWriteChannel(arg0));
342
        } catch (IOException e) {
343
                        throw new ReadDriverException(getName(),e);
344
                }
345
    }
346

    
347
        public int getFieldWidth(int i) throws ReadDriverException {
348
                return dbf.getFieldLength(i);
349
        }
350

    
351
        public IWriter getWriter() {
352
                return this;
353
        }
354

    
355
        public void preProcess() throws StartWriterVisitorException {
356
                dbfWriter.preProcess();
357

    
358
        }
359

    
360
        public void process(IRowEdited row) throws ProcessWriterVisitorException {
361
                dbfWriter.process(row);
362

    
363
        }
364

    
365
        public void postProcess() throws StopWriterVisitorException {
366
                dbfWriter.postProcess();
367
                try {
368
                        // Dbf
369
                        File dbfFile = fTemp;
370
                        FileChannel fcinDbf = new FileInputStream(dbfFile).getChannel();
371
                        FileChannel fcoutDbf = new FileOutputStream(file).getChannel();
372
                        DriverUtilities.copy(fcinDbf, fcoutDbf);
373

    
374
                        // Borramos los temporales
375
                        fTemp.delete();
376

    
377
                        // Reload
378
                        close();
379
                        open(file);
380

    
381

    
382

    
383
                } catch (FileNotFoundException e) {
384
                        throw new StopWriterVisitorException(getName(),e);
385
                } catch (IOException e) {
386
                        throw new StopWriterVisitorException(getName(),e);
387
                } catch (CloseDriverException e) {
388
                        throw new StopWriterVisitorException(getName(),e);
389
                } catch (OpenDriverException e) {
390
                        throw new StopWriterVisitorException(getName(),e);
391
                }
392

    
393

    
394
        }
395

    
396
        public String getCapability(String capability) {
397
                return dbfWriter.getCapability(capability);
398
        }
399

    
400
        public void setCapabilities(Properties capabilities) {
401
                dbfWriter.setCapabilities(capabilities);
402

    
403
        }
404

    
405
        public boolean canWriteAttribute(int sqlType) {
406
                return dbfWriter.canWriteAttribute(sqlType);
407
        }
408

    
409
        public void initialize(ITableDefinition tableDefinition) throws InitializeWriterException {
410
                dbfWriter.initialize(tableDefinition);
411

    
412
        }
413

    
414
        public ITableDefinition getTableDefinition() throws ReadDriverException {
415
                tableDef = new TableDefinition();
416
                int numFields;
417
                        numFields = getFieldCount();
418
                        FieldDescription[] fieldsDescrip = new FieldDescription[numFields];
419
                        for (int i = 0; i < numFields; i++) {
420
                                fieldsDescrip[i] = new FieldDescription();
421
                                int type = getFieldType(i);
422
                                fieldsDescrip[i].setFieldType(type);
423
                                fieldsDescrip[i].setFieldName(getFieldName(i));
424
                                fieldsDescrip[i].setFieldLength(getFieldWidth(i));
425
                                if (NumberUtilities.isNumeric(type))
426
                                {
427
                                        if (!NumberUtilities.isNumericInteger(type))
428
                                                // TODO: If there is a lost in precision, this should be changed.
429
                                                fieldsDescrip[i].setFieldDecimalCount(6);
430
                                }
431
                                else
432
                                        fieldsDescrip[i].setFieldDecimalCount(0);
433
                                // TODO: ?DEFAULTVALUE?
434
                                // fieldsDescrip[i].setDefaultValue(get)
435
                        }
436

    
437
                        tableDef.setFieldsDesc(fieldsDescrip);
438
                        return tableDef;
439
//                return dbfWriter.getTableDefinition();
440
        }
441

    
442
        public boolean canAlterTable() {
443
                return true;
444
        }
445

    
446
        public boolean alterTable() {
447
                return true;
448
        }
449

    
450
        public boolean canSaveEdits() {
451
                if (file.canWrite()) return true;
452
                return false;
453

    
454
        }
455
        public boolean isWriteAll() {
456
                // TODO: DEVOLVER FALSE SI NO HA HABIDO CAMBIOS EN LOS CAMPOS.
457
                return true;
458
        }
459
        public void setFieldValue(int rowIndex, int fieldId, Object obj)
460
        throws IOException {
461
                dbf.setFieldValue(rowIndex,fieldId,obj);
462
        }
463
}