Statistics
| Revision:

svn-gvsig-desktop / branches / simbologia / libraries / libFMap / src / com / iver / cit / gvsig / fmap / drivers / dbf / DBFDriver.java @ 10450

History | View | Annotate | Download (13.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.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
 * @author   Fernando Gonz?lez Cort?s
44
 */
45
public class DBFDriver extends AbstractFieldManager implements FileDriver, IWriteable, IWriter {
46
    //private File file;
47
    private static Locale ukLocale = new Locale("en", "UK"); // English, UK version
48
    private DbaseFile dbf = new DbaseFile();
49
    private char[] fieldTypes;
50
    private DataSourceFactory dsf;
51
    private DbfWriter dbfWriter = new DbfWriter();
52
        private File file = null;
53
        private static String tempDirectoryPath = System.getProperty("java.io.tmpdir");
54
        private File fTemp;
55
    private ITableDefinition tableDef;
56

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

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

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

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

    
84
    }
85

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
254
                dbfWrite.write(record);
255
            }
256

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

    
262
    }
263

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

    
271
        String temp = dsf.getTempFile();
272

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

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

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

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

    
298
        File f = new File(path);
299

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

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

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

    
311
        return channel;
312
    }
313

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

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

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

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

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

    
343
        }
344

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

    
348
        }
349

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

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

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

    
366

    
367

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

    
374

    
375
        }
376

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

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

    
384
        }
385

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

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

    
393
        }
394

    
395
        public ITableDefinition getTableDefinition() {
396
                tableDef = new TableDefinition();
397
                int numFields;
398
                try {
399
                        numFields = getFieldCount();
400
                        FieldDescription[] fieldsDescrip = new FieldDescription[numFields];
401
                        for (int i = 0; i < numFields; i++) {
402
                                fieldsDescrip[i] = new FieldDescription();
403
                                int type = getFieldType(i);
404
                                fieldsDescrip[i].setFieldType(type);
405
                                fieldsDescrip[i].setFieldName(getFieldName(i));
406
                                fieldsDescrip[i].setFieldLength(getFieldWidth(i));
407
                                if (NumberUtilities.isNumeric(type))
408
                                {
409
                                        if (!NumberUtilities.isNumericInteger(type))
410
                                                // TODO: If there is a lost in precision, this should be changed.
411
                                                fieldsDescrip[i].setFieldDecimalCount(6);
412
                                }
413
                                else
414
                                        fieldsDescrip[i].setFieldDecimalCount(0);
415
                                // TODO: ?DEFAULTVALUE?
416
                                // fieldsDescrip[i].setDefaultValue(get)
417
                        }
418

    
419
                        tableDef.setFieldsDesc(fieldsDescrip);
420
                        return tableDef;
421
                } catch (DriverException e) {
422
                        // TODO Auto-generated catch block
423
                        e.printStackTrace();
424
                }
425
                return null;
426
//                return dbfWriter.getTableDefinition();
427
        }
428

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

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

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

    
441
        }
442
        public boolean isWriteAll() {
443
                // TODO: DEVOLVER FALSE SI NO HA HABIDO CAMBIOS EN LOS CAMPOS.
444
                return true;
445
        }
446
        public void setFieldValue(int rowIndex, int fieldId, Object obj)
447
        throws IOException {
448
                dbf.setFieldValue(rowIndex,fieldId,obj);
449
        }
450
}