Statistics
| Revision:

svn-gvsig-desktop / tags / J2ME_compat_v1_2_Build_1209 / libraries / libFMap / src / com / iver / cit / gvsig / fmap / drivers / dbf / DBFDriver.java @ 19509

History | View | Annotate | Download (14.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.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 cfieldType = fieldTypes[fieldId];
111
        int fieldType = getFieldType(fieldId);
112

    
113
            String strValue;
114

    
115

    
116
            if (cfieldType == 'D') {
117
            String date;
118
                        try {
119
                                date = dbf.getStringFieldValue((int) rowIndex, fieldId).trim();
120
                        } catch (UnsupportedEncodingException e1) {
121
                                throw new ReadDriverException(getName(),e1);
122
                        }
123
            // System.out.println(rowIndex + " data=" + date);
124
            if (date.length() == 0) {
125
                return null;
126
            }
127

    
128
            String year = date.substring(0, 4);
129
            String month = date.substring(4, 6);
130
            String day = date.substring(6, 8);
131
            DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, ukLocale);
132
            /* Calendar c = Calendar.getInstance();
133
            c.clear();
134
            c.set(Integer.parseInt(year), Integer.parseInt(month),
135
                Integer.parseInt(day));
136
            c.set(Calendar.MILLISECOND, 0); */
137
            String strAux = month + "/" + day + "/" + year;
138
            Date dat;
139
            try {
140
                dat = df.parse(strAux);
141
            } catch (ParseException e) {
142
                throw new ReadDriverException(getName(),e);
143
            }
144

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

    
147
            return ValueFactory.createValue(dat);
148
        } else {
149

    
150
                try {
151
                        strValue = dbf.getStringFieldValue((int) rowIndex, fieldId);
152
                    } catch (UnsupportedEncodingException e1) {
153
                            throw new BadFieldDriverException(getName(),e1);
154
                    }
155
                           strValue = strValue.trim();
156
                           if (fieldType == Types.BOOLEAN){
157
                                   strValue = strValue.toLowerCase();
158
                                 strValue = Boolean.toString(strValue.equals("t") || strValue.equals("y"));
159
                           }
160

    
161
                    try {
162
                                return ValueFactory.createValueByType(strValue, fieldType);
163
                        } catch (Exception e) {
164
                                if (fieldType == Types.INTEGER){
165
                                        //Habria que quejarse???
166
                                        return ValueFactory.createValue(0);
167
                                } else {
168
                                        // OJO: Habria que revisar el resto de tipos
169
                                        // De momento lanzamos la excepcion
170
                                        throw new BadFieldDriverException(getName(),null,String.valueOf(fieldType));
171
                                }
172
                        }
173

    
174

    
175
        }
176
    }
177

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

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

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

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

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

    
212
        if (fieldType == 'L') {
213
            return Types.BOOLEAN;
214
        } else if ((fieldType == 'F') || (fieldType == 'N')) {
215
                if (dbf.getFieldDecimalLength(i)>0)
216
                        return Types.DOUBLE;
217
                else
218
                        return Types.INTEGER;
219
        } else if (fieldType == 'C') {
220
            return Types.VARCHAR;
221
        } else if (fieldType == 'D') {
222
            return Types.DATE;
223
        } else {
224
            throw new BadFieldDriverException(getName(),null,String.valueOf(fieldType));
225
        }
226
    }
227

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

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

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

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

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

    
253
                dbfWrite.write(record);
254
            }
255

    
256
            dbfWrite.close();
257
        } catch (IOException e) {
258
            throw new WriteDriverException(getName(),e);
259
        }
260

    
261
    }
262

    
263
    /**
264
     * @throws ReadDriverException
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 WriteDriverException, ReadDriverException {
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 WriteDriverException(getName(),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 ReadDriverException {
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
        try {
325
                        myHeader = DbaseFileHeaderNIO.createDbaseHeader(arg1, arg2, lengths);
326

    
327
        myHeader.setNumRecords(0);
328
        DbaseFileWriterNIO dbfWrite = new DbaseFileWriterNIO(myHeader,
329
                (FileChannel) getWriteChannel(arg0));
330
        dbfWrite = new DbaseFileWriterNIO(myHeader,
331
                (FileChannel) getWriteChannel(arg0));
332
        } catch (IOException e) {
333
                        throw new ReadDriverException(getName(),e);
334
                }
335
    }
336

    
337
        public int getFieldWidth(int i) throws ReadDriverException {
338
                return dbf.getFieldLength(i);
339
        }
340

    
341
        public IWriter getWriter() {
342
                return this;
343
        }
344

    
345
        public void preProcess() throws StartWriterVisitorException {
346
                dbfWriter.preProcess();
347

    
348
        }
349

    
350
        public void process(IRowEdited row) throws ProcessWriterVisitorException {
351
                dbfWriter.process(row);
352

    
353
        }
354

    
355
        public void postProcess() throws StopWriterVisitorException {
356
                dbfWriter.postProcess();
357
                try {
358
                        // Dbf
359
                        File dbfFile = fTemp;
360
                        FileChannel fcinDbf = new FileInputStream(dbfFile).getChannel();
361
                        FileChannel fcoutDbf = new FileOutputStream(file).getChannel();
362
                        DriverUtilities.copy(fcinDbf, fcoutDbf);
363

    
364
                        // Borramos los temporales
365
                        fTemp.delete();
366

    
367
                        // Reload
368
                        close();
369
                        open(file);
370

    
371

    
372

    
373
                } catch (FileNotFoundException e) {
374
                        throw new StopWriterVisitorException(getName(),e);
375
                } catch (IOException e) {
376
                        throw new StopWriterVisitorException(getName(),e);
377
                } catch (CloseDriverException e) {
378
                        throw new StopWriterVisitorException(getName(),e);
379
                } catch (OpenDriverException e) {
380
                        throw new StopWriterVisitorException(getName(),e);
381
                }
382

    
383

    
384
        }
385

    
386
        public String getCapability(String capability) {
387
                return dbfWriter.getCapability(capability);
388
        }
389

    
390
        public void setCapabilities(Properties capabilities) {
391
                dbfWriter.setCapabilities(capabilities);
392

    
393
        }
394

    
395
        public boolean canWriteAttribute(int sqlType) {
396
                return dbfWriter.canWriteAttribute(sqlType);
397
        }
398

    
399
        public void initialize(ITableDefinition tableDefinition) throws InitializeWriterException {
400
                dbfWriter.initialize(tableDefinition);
401

    
402
        }
403

    
404
        public ITableDefinition getTableDefinition() throws ReadDriverException {
405
                tableDef = new TableDefinition();
406
                int numFields;
407
                        numFields = getFieldCount();
408
                        FieldDescription[] fieldsDescrip = new FieldDescription[numFields];
409
                        for (int i = 0; i < numFields; i++) {
410
                                fieldsDescrip[i] = new FieldDescription();
411
                                int type = getFieldType(i);
412
                                fieldsDescrip[i].setFieldType(type);
413
                                fieldsDescrip[i].setFieldName(getFieldName(i));
414
                                fieldsDescrip[i].setFieldLength(getFieldWidth(i));
415
                                if (NumberUtilities.isNumeric(type))
416
                                {
417
                                        if (!NumberUtilities.isNumericInteger(type))
418
                                                // TODO: If there is a lost in precision, this should be changed.
419
                                                fieldsDescrip[i].setFieldDecimalCount(6);
420
                                }
421
                                else
422
                                        fieldsDescrip[i].setFieldDecimalCount(0);
423
                                // TODO: ?DEFAULTVALUE?
424
                                // fieldsDescrip[i].setDefaultValue(get)
425
                        }
426

    
427
                        tableDef.setFieldsDesc(fieldsDescrip);
428
                        return tableDef;
429
//                return dbfWriter.getTableDefinition();
430
        }
431

    
432
        public boolean canAlterTable() {
433
                return true;
434
        }
435

    
436
        public boolean alterTable() {
437
                return true;
438
        }
439

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

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