Statistics
| Revision:

root / branches / v2_0_0_prep / libraries / libFMap_dalfile / src / org / gvsig / fmap / dal / store / dbf / DBFStoreProvider.java @ 24498

History | View | Annotate | Download (14 KB)

1
package org.gvsig.fmap.dal.store.dbf;
2

    
3
import java.io.File;
4
import java.io.IOException;
5
import java.text.DateFormat;
6
import java.text.ParseException;
7
import java.util.ArrayList;
8
import java.util.Date;
9
import java.util.Iterator;
10
import java.util.List;
11
import java.util.Locale;
12

    
13
import org.gvsig.fmap.dal.DataExplorer;
14
import org.gvsig.fmap.dal.DataStoreParameters;
15
import org.gvsig.fmap.dal.DataTypes;
16
import org.gvsig.fmap.dal.exceptions.CloseException;
17
import org.gvsig.fmap.dal.exceptions.CreateException;
18
import org.gvsig.fmap.dal.exceptions.DataException;
19
import org.gvsig.fmap.dal.exceptions.FileNotFoundException;
20
import org.gvsig.fmap.dal.exceptions.InitializeException;
21
import org.gvsig.fmap.dal.exceptions.OpenException;
22
import org.gvsig.fmap.dal.exceptions.ReadException;
23
import org.gvsig.fmap.dal.exceptions.UnsupportedVersionException;
24
import org.gvsig.fmap.dal.feature.EditableFeatureType;
25
import org.gvsig.fmap.dal.feature.Feature;
26
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
27
import org.gvsig.fmap.dal.feature.FeatureQuery;
28
import org.gvsig.fmap.dal.feature.FeatureType;
29
import org.gvsig.fmap.dal.feature.exceptions.PerformEditingException;
30
import org.gvsig.fmap.dal.feature.exceptions.UnknowDataTypeException;
31
import org.gvsig.fmap.dal.feature.impl.DefaultFeatureType;
32
import org.gvsig.fmap.dal.feature.spi.AbstractFeatureStoreProvider;
33
import org.gvsig.fmap.dal.feature.spi.FeatureData;
34
import org.gvsig.fmap.dal.feature.spi.FeatureReferenceProviderServices;
35
import org.gvsig.fmap.dal.feature.spi.FeatureSetProvider;
36
import org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider;
37
import org.gvsig.fmap.dal.feature.spi.FeatureStoreProviderServices;
38
import org.gvsig.fmap.dal.resource.exception.AccessResourceException;
39
import org.gvsig.fmap.dal.resource.exception.ResourceBeginException;
40
import org.gvsig.fmap.dal.resource.exception.ResourceNotifyChangesException;
41
import org.gvsig.fmap.dal.resource.exception.ResourceNotifyCloseException;
42
import org.gvsig.fmap.dal.resource.exception.ResourceNotifyDisposeException;
43
import org.gvsig.fmap.dal.resource.exception.ResourceNotifyOpenException;
44
import org.gvsig.fmap.dal.resource.file.FileResource;
45
import org.gvsig.fmap.dal.resource.spi.ResourceConsumer;
46
import org.gvsig.fmap.dal.resource.spi.ResourceProvider;
47
import org.gvsig.fmap.dal.store.dbf.utils.DbaseFile;
48
import org.gvsig.metadata.Metadata;
49
import org.gvsig.tools.exception.NotYetImplemented;
50
import org.gvsig.tools.persistence.PersistenceException;
51
import org.gvsig.tools.persistence.PersistentState;
52

    
53
public class DBFStoreProvider extends AbstractFeatureStoreProvider implements
54
                ResourceConsumer {
55

    
56
        public static String NAME = "DBFStore";
57
        public static String DESCRIPTION = "DBF file";
58
        //        private DBFResource dbf = null;
59
        private DbaseFile dbfFile = null;
60
        private ResourceProvider dbfResource;
61
        protected Metadata metadata;
62
        private static final Locale ukLocale = new Locale("en", "UK");
63
        private DBFStoreParameters dbfParams;
64
        private long counterNewsOIDs = -1;
65

    
66
        public DBFStoreProvider(DBFStoreParameters params)
67
                        throws InitializeException {
68
                super();
69
                this.dbfParams = params;
70

    
71
                dbfResource = this.createResource(FileResource.NAME,
72
                                new Object[] { this.dbfParams
73
                                .getDBFFile() });
74
                dbfResource.addConsumer(this);
75

    
76
                //DBFResource tmpResource = new DBFResource(dbfParameters);
77
                //
78
                //try {
79
                //        this.dbf = (DBFResource) this.store.addResource(tmpResource);
80
                //} catch (DataException e1) {
81
                //        throw new InitializeException(this.getName(), e1);
82
                //}
83
                File theFile = getDBFParameters().getDBFFileObject();
84

    
85
                this.dbfFile = new DbaseFile(theFile);
86
        }
87

    
88
        public FeatureStoreProvider initialize(FeatureStoreProviderServices store)
89
                        throws InitializeException {
90
                super.initialize(store);
91
                this.initFeatureType();
92
                return this;
93
        }
94

    
95
        public String getName() {
96
                return NAME;
97
        }
98

    
99
        protected DBFStoreParameters getDBFParameters() {
100
                return dbfParams;
101
        }
102

    
103

    
104
        public DataExplorer getExplorer() throws ReadException {
105
                // TODO Auto-generated method stub
106
                return null;
107
        }
108

    
109
        public FeatureData getFeatureDataByReference(
110
                        FeatureReferenceProviderServices reference, FeatureType featureType)
111
                        throws DataException {
112

    
113
                return this.getFeatureDataByIndex(((Integer) reference.getOID())
114
                                .intValue(),
115
                                featureType);
116
        }
117

    
118

    
119
        public FeatureData getFeatureDataByReference(
120
                        FeatureReferenceProviderServices reference) throws DataException {
121
                return this.getFeatureDataByReference(reference, this.store
122
                                .getDefaultFeatureType());
123
        }
124

    
125
        public void performEditing(Iterator deleteds, Iterator inserteds, Iterator updateds) throws PerformEditingException {
126
                // TODO Auto-generated method stub
127

    
128
                this.counterNewsOIDs = -1;
129
        }
130

    
131
        /*
132
         * ==================================================
133
         */
134

    
135
        public FeatureData createFeatureData(FeatureType type) throws DataException {
136
                return new DBFFeatureData(this, (DefaultFeatureType) type);
137
        }
138

    
139

    
140
        /*
141
         * ===================================================
142
         */
143

    
144
        FeatureStoreProviderServices getProviderServices() {
145
                return this.store;
146
        }
147

    
148

    
149
        protected void initFeatureType() throws InitializeException {
150
                FeatureType defaultType = this.getTheFeatureType().getNotEditableCopy();
151
                List types = new ArrayList(1);
152
                types.add(defaultType);
153
                this.store.setFeatureTypes(types, defaultType);
154
        }
155

    
156
        protected EditableFeatureType getTheFeatureType() throws InitializeException {
157
                try {
158
                        this.open();
159
                        this.dbfResource.begin();
160
                } catch (DataException e) {
161
                        throw new InitializeException(this.getName(), e);
162
                }
163
                try {
164
                        int fieldCount = -1;
165
                        fieldCount = dbfFile.getFieldCount();
166

    
167
                        EditableFeatureType fType = this.store.createFeatureType();
168

    
169
                        for (int i = 0; i < fieldCount; i++) {
170
                                char fieldType = dbfFile.getFieldType(i);
171
                                int attrType;
172
                                int precision = 0;
173

    
174
                                if (fieldType == 'L') {
175
                                        attrType = DataTypes.BOOLEAN;
176

    
177
                                } else if ((fieldType == 'F') || (fieldType == 'N')) {
178
                                        precision = dbfFile.getFieldDecimalLength(i);
179
                                        if (precision > 0) {
180
                                                attrType = DataTypes.DOUBLE;
181
                                        } else {
182
                                                attrType = DataTypes.INT;
183
                                        }
184
                                } else if (fieldType == 'C') {
185
                                        attrType = DataTypes.STRING;
186
                                } else if (fieldType == 'D') {
187
                                        attrType = DataTypes.DATE;
188
                                } else {
189
                                        throw new InitializeException(this.getName(),
190
                                                        new UnknowDataTypeException(
191
                                                                        dbfFile.getFieldName(i), "" + fieldType,
192
                                                                        this.getName()));
193
                                }
194
                                fType.add(dbfFile.getFieldName(i), attrType,
195
                                                dbfFile.getFieldLength(i)).setPrecision(precision);
196
                        }
197
                        return fType;
198
                } finally {
199
                        this.dbfResource.end();
200
                }
201
        }
202

    
203

    
204
        protected void loadValue(FeatureData featureData, int rowIndex,
205
                        FeatureAttributeDescriptor descriptor) throws ReadException {
206
                if (descriptor.getEvaluator() != null) {
207
                        // Nothing to do
208
                        return;
209
                }
210

    
211
                int fieldIndex = descriptor.getIndex();
212
                String value = null;
213
                try {
214
                        value = this.dbfFile.getStringFieldValue(rowIndex, fieldIndex);
215
                } catch (DataException e) {
216
                        throw new ReadException(this.store.getName(), e);
217
                }
218
                value = value.trim();
219
                int fieldType = descriptor.getDataType();
220
                switch (fieldType) {
221
                case DataTypes.STRING:
222
                        featureData.set(fieldIndex, value);
223
                        break;
224

    
225
                case DataTypes.DOUBLE:
226
                        try {
227
                                featureData.set(fieldIndex, new Double(value));
228
                        } catch (NumberFormatException e) {
229
                                featureData.set(fieldIndex, null);
230
                        }
231
                        break;
232

    
233
                case DataTypes.INT:
234
                        try {
235
                                featureData.set(fieldIndex, new Integer(value));
236
                        } catch (NumberFormatException e) {
237
                                featureData.set(fieldIndex, null);
238
                        }
239
                        break;
240

    
241
                case DataTypes.FLOAT:
242
                        try {
243
                                featureData.set(fieldIndex, new Float(value));
244
                        } catch (NumberFormatException e) {
245
                                featureData.set(fieldIndex, null);
246
                        }
247
                        break;
248

    
249
                case DataTypes.LONG:
250
                        try {
251
                                featureData.set(fieldIndex, new Long(value));
252
                        } catch (NumberFormatException e) {
253
                                featureData.set(fieldIndex, null);
254
                        }
255
                        break;
256

    
257
                case DataTypes.BOOLEAN:
258
                        featureData.set(fieldIndex, new Boolean(value));
259
                        break;
260

    
261
                case DataTypes.BYTE:
262
                        try {
263
                                featureData.set(fieldIndex, new Byte(value));
264
                        } catch (NumberFormatException e) {
265
                                featureData.set(fieldIndex, null);
266
                        }
267
                        break;
268

    
269
                case DataTypes.DATE:
270
                        String year = value.substring(0, 4);
271
                        String month = value.substring(4, 6);
272
                        String day = value.substring(6, 8);
273
                        DateFormat df;
274
                        if (descriptor.getDateFormat() == null){
275
                                df = DateFormat.getDateInstance(DateFormat.SHORT,
276
                                                ukLocale);
277
                        } else{
278
                                df = descriptor.getDateFormat();
279
                        }
280
                        /*
281
                         * Calendar c = Calendar.getInstance(); c.clear();
282
                         * c.set(Integer.parseInt(year), Integer.parseInt(month),
283
                         * Integer.parseInt(day)); c.set(Calendar.MILLISECOND, 0);
284
                         */
285
                        String strAux = month + "/" + day + "/" + year;
286
                        Date dat = null;
287
                        try {
288
                                dat = df.parse(strAux);
289
                        } catch (ParseException e) {
290
                                throw new ReadException(this.store.getName(), e);
291
                        }
292
                        featureData.set(fieldIndex, dat);
293
                        break;
294

    
295

    
296
                default:
297
                        featureData.set(fieldIndex, descriptor.getDefaultValue());
298
                        break;
299
                }
300
        }
301

    
302

    
303
        /***
304
         * NOT supported in Alter Mode
305
         *
306
         * @param index
307
         * @return
308
         * @throws ReadException
309
         */
310
        protected FeatureData getFeatureDataByIndex(long index) throws DataException {
311
                return this
312
                                .getFeatureDataByIndex(index, this.store
313
                                .getDefaultFeatureType());
314
        }
315

    
316
        protected int getFeatureCount() throws ReadException, OpenException,
317
                        ResourceNotifyChangesException {
318
                this.open();
319
                try {
320
                        this.dbfResource.begin();
321
                } catch (ResourceBeginException e) {
322
                        throw new ReadException(this.getName(), e);
323
                }
324
                try {
325
                        return this.dbfFile.getRecordCount();
326
                } finally {
327
                        this.dbfResource.end();
328
                }
329
        }
330

    
331
        public FeatureSetProvider createSet(FeatureQuery query)
332
                        throws DataException {
333
                return new DBFSetProvider(this, query);
334
        }
335

    
336
        public boolean canCreate() {
337
                return true;
338
        }
339

    
340
        public boolean canWriteGeometry(int geometryType) throws DataException {
341
                return false;
342
        }
343

    
344
        public void create(DataStoreParameters parameters, FeatureType featureType,
345
                        boolean overwrite) throws CreateException {
346
                //TODO
347
                throw new NotYetImplemented();
348
        }
349

    
350
        public void open() throws OpenException {
351
                if (this.dbfFile.isOpen()) {
352
                        return;
353
                }
354
                try {
355
                        this.dbfResource.begin();
356
                } catch (ResourceBeginException e) {
357
                        throw new OpenException(this.getName(), e);
358
                }
359
                try {
360
                        this.dbfFile.open();
361
                        this.dbfResource.notifyOpen();
362

    
363
                } catch (UnsupportedVersionException e) {
364
                        throw new OpenException(this.getName(), e);
365
                } catch (ResourceNotifyOpenException e) {
366
                        throw new OpenException(this.getName(), e);
367
                } catch (FileNotFoundException e) {
368
                        throw new OpenException(this.getName(), e);
369
                } catch (IOException e) {
370
                        throw new OpenException(this.getName(), e);
371
                } finally {
372
                        this.dbfResource.end();
373
                }
374
        }
375

    
376
        public void close() throws CloseException {
377
                super.close();
378
                if (!this.dbfFile.isOpen()) {
379
                        return;
380
                }
381
                //Cerrar recurso
382
                try {
383
                        this.dbfResource.begin();
384
                } catch (ResourceBeginException e) {
385
                        throw new CloseException(this.getName(), e);
386
                }
387
                try {
388
                        this.dbfFile.close();
389
                        this.dbfResource.notifyClose();
390

    
391
                } catch (ResourceNotifyCloseException e) {
392
                        throw new CloseException(this.getName(), e);
393
                } finally {
394
                        this.dbfResource.end();
395
                }
396
        }
397

    
398
        public void dispose() throws CloseException {
399
                this.close();
400
                try {
401
                        this.dbfResource.notifyDispose();
402
                } catch (ResourceNotifyDisposeException e) {
403
                        throw new CloseException(this.getName(), e);
404
                }
405
                dbfFile = null;
406
                this.dbfResource.removeConsumer(this);
407
                dbfResource = null;
408
                metadata = null;
409
                super.dispose();
410
        }
411

    
412
        public boolean closeResourceRequested(ResourceProvider resource) {
413
                try {
414
                        this.close();
415
                } catch (CloseException e) {
416
                        return false;
417
                }
418
                return true;
419
        }
420

    
421
        public boolean allowWrite() {
422
                File file;
423
                try {
424
                        file = (File) this.dbfResource.get();
425
                } catch (AccessResourceException e) {
426
                        return false;
427
                }
428
                return super.allowWrite() && file.canWrite();
429
        }
430

    
431
        public void refresh() throws OpenException {
432
                try {
433
                        this.close();
434
                } catch (CloseException e) {
435
                        throw new OpenException(this.getName(), e);
436
                }
437
                this.open();
438
                try {
439
                        this.getTheFeatureType();
440
                } catch (InitializeException e) {
441
                        throw new OpenException(this.getName(), e);
442
                }
443
        }
444

    
445
        /**
446
         *
447
         * @param index
448
         * @param featureType
449
         * @return
450
         * @throws ReadException
451
         */
452
        protected FeatureData getFeatureDataByIndex(long index,
453
                        FeatureType featureType) throws DataException {
454
                FeatureData featureData = this.createFeatureData(featureType);
455
                featureData.setOID(new Long(index));
456
                return featureData;
457
        }
458

    
459
        protected void initFeatureDataByIndex(FeatureData featureData,
460
                        long index, FeatureType featureType) throws DataException {
461
                featureData.setOID(new Long(index));
462
        }
463

    
464
        /**
465
         *
466
         * @param featureData
467
         * @throws DataException
468
         */
469
        protected void loadFeatureDataByIndex(FeatureData featureData)
470
                        throws DataException {
471
                this.open();
472
                this.dbfResource.begin();
473
                long index = ((Long) featureData.getOID()).longValue();
474
                try {
475
                        if (index >= this.dbfFile.getRecordCount()) {
476
                                // FIXME
477
                                throw new ArrayIndexOutOfBoundsException("" + index);
478
                        }
479
                        Iterator iterator = featureData.getType().iterator();
480
                        while (iterator.hasNext()) {
481
                                FeatureAttributeDescriptor descriptor = (FeatureAttributeDescriptor) iterator
482
                                                .next();
483
                                this.loadValue(featureData, (int) index, descriptor);
484
                        }
485

    
486

    
487
                } finally {
488
                        this.dbfResource.end();
489
                }
490
        }
491

    
492
        public int getFeatureReferenceOIDType() {
493
                return DataTypes.LONG;
494
        }
495

    
496
        public Object createNewOID() {
497
                if (this.counterNewsOIDs < 0) {
498
                        try {
499
                                this.counterNewsOIDs = this.getFeatureCount();
500
                        } catch (DataException e) {
501
                                e.printStackTrace();
502
                        }
503

    
504
                }
505
                this.counterNewsOIDs++;
506
                return null;
507
        }
508

    
509

    
510
        public void append(Feature feature) {
511
                // TODO Auto-generated method stub
512

    
513
        }
514

    
515
        public void beginAppend() {
516
                // TODO Auto-generated method stub
517

    
518
        }
519

    
520
        public void endAppend() {
521
                // TODO Auto-generated method stub
522

    
523
        }
524

    
525
        public PersistentState getState() throws PersistenceException {
526
                // TODO Auto-generated method stub
527
                return null;
528
        }
529

    
530
        public void loadState(PersistentState state) throws PersistenceException {
531
                // TODO Auto-generated method stub
532

    
533
        }
534

    
535
        public void setState(PersistentState state) throws PersistenceException {
536
                // TODO Auto-generated method stub
537

    
538
        }
539

    
540
        public boolean supportsAppendMode() {
541
                return false;
542
        }
543

    
544
}