Statistics
| Revision:

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

History | View | Annotate | Download (15.3 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.DALLocator;
14
import org.gvsig.fmap.dal.DataManager;
15
import org.gvsig.fmap.dal.DataServerExplorer;
16
import org.gvsig.fmap.dal.DataTypes;
17
import org.gvsig.fmap.dal.exception.CloseException;
18
import org.gvsig.fmap.dal.exception.DataException;
19
import org.gvsig.fmap.dal.exception.FileNotFoundException;
20
import org.gvsig.fmap.dal.exception.InitializeException;
21
import org.gvsig.fmap.dal.exception.OpenException;
22
import org.gvsig.fmap.dal.exception.ReadException;
23
import org.gvsig.fmap.dal.exception.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.FeatureSet;
29
import org.gvsig.fmap.dal.feature.FeatureType;
30
import org.gvsig.fmap.dal.feature.exception.PerformEditingException;
31
import org.gvsig.fmap.dal.feature.exception.UnknowDataTypeException;
32
import org.gvsig.fmap.dal.feature.impl.DefaultFeatureType;
33
import org.gvsig.fmap.dal.feature.spi.AbstractFeatureStoreProvider;
34
import org.gvsig.fmap.dal.feature.spi.FeatureData;
35
import org.gvsig.fmap.dal.feature.spi.FeatureReferenceProviderServices;
36
import org.gvsig.fmap.dal.feature.spi.FeatureSetProvider;
37
import org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider;
38
import org.gvsig.fmap.dal.feature.spi.FeatureStoreProviderServices;
39
import org.gvsig.fmap.dal.resource.exception.AccessResourceException;
40
import org.gvsig.fmap.dal.resource.exception.ResourceBeginException;
41
import org.gvsig.fmap.dal.resource.exception.ResourceNotifyChangesException;
42
import org.gvsig.fmap.dal.resource.exception.ResourceNotifyCloseException;
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.serverexplorer.filesystem.FilesystemServerExplorer;
48
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorerParameters;
49
import org.gvsig.fmap.dal.store.dbf.utils.DbaseFile;
50
import org.gvsig.metadata.Metadata;
51
import org.gvsig.tools.exception.NotYetImplemented;
52
import org.gvsig.tools.persistence.PersistenceException;
53
import org.gvsig.tools.persistence.PersistentState;
54

    
55
public class DBFStoreProvider extends AbstractFeatureStoreProvider implements
56
                ResourceConsumer {
57

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

    
68
        public DBFStoreProvider() throws InitializeException {
69
                super();
70
        }
71

    
72
        public DBFStoreProvider(DBFStoreParameters params)
73
                        throws InitializeException {
74
                super();
75
                this.init(params);
76

    
77
        }
78

    
79
        protected void init(DBFStoreParameters params) throws InitializeException {
80
                this.dbfParams = params;
81

    
82
                File theFile = getDBFParameters().getDBFFile();
83
                dbfResource = this.createResource(FileResource.NAME,
84
                                new Object[] { theFile.getAbsolutePath() });
85
                dbfResource.addConsumer(this);
86

    
87
                //DBFResource tmpResource = new DBFResource(dbfParameters);
88
                //
89
                //try {
90
                //        this.dbf = (DBFResource) this.store.addResource(tmpResource);
91
                //} catch (DataException e1) {
92
                //        throw new InitializeException(this.getName(), e1);
93
                //}
94

    
95

    
96
                this.dbfFile = new DbaseFile(theFile);
97
        }
98

    
99
        public FeatureStoreProvider initialize(FeatureStoreProviderServices store)
100
                        throws InitializeException {
101
                super.initialize(store);
102
                this.initFeatureType();
103
                return this;
104
        }
105

    
106
        public String getName() {
107
                return NAME;
108
        }
109

    
110
        protected DBFStoreParameters getDBFParameters() {
111
                return dbfParams;
112
        }
113

    
114

    
115
        public DataServerExplorer getExplorer() throws ReadException {
116
                DataManager manager = DALLocator.getDataManager();
117
                FilesystemServerExplorerParameters params;
118
                try {
119
                        params = (FilesystemServerExplorerParameters) manager
120
                                        .createServerExplorerParameters(FilesystemServerExplorer.NAME);
121
                        params.setRoot(this.getDBFParameters().getDBFFile().getParent());
122
                        return manager.createServerExplorer(params);
123
                } catch (DataException e) {
124
                        throw new ReadException(this.getName(), e);
125
                }
126
        }
127

    
128
        public FeatureData getFeatureDataByReference(
129
                        FeatureReferenceProviderServices reference, FeatureType featureType)
130
                        throws DataException {
131

    
132
                return this.getFeatureDataByIndex(((Integer) reference.getOID())
133
                                .intValue(),
134
                                featureType);
135
        }
136

    
137

    
138
        public FeatureData getFeatureDataByReference(
139
                        FeatureReferenceProviderServices reference) throws DataException {
140
                return this.getFeatureDataByReference(reference, this.store
141
                                .getDefaultFeatureType());
142
        }
143

    
144
        public void performEditing(Iterator deleteds, Iterator inserteds,
145
                        Iterator updateds)
146
                        throws PerformEditingException {
147
                try {
148
                        this.close();
149
                } catch (CloseException e1) {
150
                        throw new PerformEditingException(this.getName(), e1);
151
                }
152

    
153
                try {
154
                        this.dbfResource.begin();
155
                        DBFFeatureWriter writer = new DBFFeatureWriter(this.getName());
156
                        FeatureSet set = this.store.getFeatureSet();
157
                        writer.begin(this.getDBFParameters(), this.store
158
                                        .getDefaultFeatureType(), set.getSize());
159

    
160
                        Iterator iter = set.iterator();
161
                        while (iter.hasNext()) {
162
                                writer.write((Feature) iter.next());
163
                        }
164

    
165
                        writer.end();
166

    
167
                        this.dbfResource.notifyChanges();
168
                } catch (Exception e) {
169
                        throw new PerformEditingException(this.getName(), e);
170
                } finally {
171
                        this.dbfResource.end();
172
                        this.dbfResource.removeConsumer(this);
173
                }
174

    
175
                this.counterNewsOIDs = -1;
176
        }
177

    
178
        /*
179
         * ==================================================
180
         */
181

    
182
        public FeatureData createFeatureData(FeatureType type) throws DataException {
183
                return new DBFFeatureData(this, (DefaultFeatureType) type);
184
        }
185

    
186

    
187
        /*
188
         * ===================================================
189
         */
190

    
191
        FeatureStoreProviderServices getProviderServices() {
192
                return this.store;
193
        }
194

    
195

    
196
        protected void initFeatureType() throws InitializeException {
197
                FeatureType defaultType = this.getTheFeatureType().getNotEditableCopy();
198
                List types = new ArrayList(1);
199
                types.add(defaultType);
200
                this.store.setFeatureTypes(types, defaultType);
201
        }
202

    
203
        protected EditableFeatureType getTheFeatureType() throws InitializeException {
204
                try {
205
                        this.open();
206
                        this.dbfResource.begin();
207
                } catch (DataException e) {
208
                        throw new InitializeException(this.getName(), e);
209
                }
210
                try {
211
                        int fieldCount = -1;
212
                        fieldCount = dbfFile.getFieldCount();
213

    
214
                        EditableFeatureType fType = this.store.createFeatureType();
215

    
216
                        for (int i = 0; i < fieldCount; i++) {
217
                                char fieldType = dbfFile.getFieldType(i);
218
                                int attrType;
219
                                int precision = 0;
220

    
221
                                if (fieldType == 'L') {
222
                                        attrType = DataTypes.BOOLEAN;
223

    
224
                                } else if ((fieldType == 'F') || (fieldType == 'N')) {
225
                                        precision = dbfFile.getFieldDecimalLength(i);
226
                                        if (precision > 0) {
227
                                                attrType = DataTypes.DOUBLE;
228
                                        } else {
229
                                                attrType = DataTypes.INT;
230
                                        }
231
                                } else if (fieldType == 'C') {
232
                                        attrType = DataTypes.STRING;
233
                                } else if (fieldType == 'D') {
234
                                        attrType = DataTypes.DATE;
235
                                } else {
236
                                        throw new InitializeException(this.getName(),
237
                                                        new UnknowDataTypeException(
238
                                                                        dbfFile.getFieldName(i), "" + fieldType,
239
                                                                        this.getName()));
240
                                }
241
                                fType.add(dbfFile.getFieldName(i), attrType,
242
                                                dbfFile.getFieldLength(i)).setPrecision(precision);
243
                        }
244
                        return fType;
245
                } finally {
246
                        this.dbfResource.end();
247
                }
248
        }
249

    
250

    
251
        protected void loadValue(FeatureData featureData, int rowIndex,
252
                        FeatureAttributeDescriptor descriptor) throws ReadException {
253
                if (descriptor.getEvaluator() != null) {
254
                        // Nothing to do
255
                        return;
256
                }
257

    
258
                int fieldIndex = descriptor.getIndex();
259
                String value = null;
260
                try {
261
                        value = this.dbfFile.getStringFieldValue(rowIndex, fieldIndex);
262
                } catch (DataException e) {
263
                        throw new ReadException(this.store.getName(), e);
264
                }
265
                value = value.trim();
266
                int fieldType = descriptor.getDataType();
267
                switch (fieldType) {
268
                case DataTypes.STRING:
269
                        featureData.set(fieldIndex, value);
270
                        break;
271

    
272
                case DataTypes.DOUBLE:
273
                        try {
274
                                featureData.set(fieldIndex, new Double(value));
275
                        } catch (NumberFormatException e) {
276
                                featureData.set(fieldIndex, null);
277
                        }
278
                        break;
279

    
280
                case DataTypes.INT:
281
                        try {
282
                                featureData.set(fieldIndex, new Integer(value));
283
                        } catch (NumberFormatException e) {
284
                                featureData.set(fieldIndex, null);
285
                        }
286
                        break;
287

    
288
                case DataTypes.FLOAT:
289
                        try {
290
                                featureData.set(fieldIndex, new Float(value));
291
                        } catch (NumberFormatException e) {
292
                                featureData.set(fieldIndex, null);
293
                        }
294
                        break;
295

    
296
                case DataTypes.LONG:
297
                        try {
298
                                featureData.set(fieldIndex, new Long(value));
299
                        } catch (NumberFormatException e) {
300
                                featureData.set(fieldIndex, null);
301
                        }
302
                        break;
303

    
304
                case DataTypes.BOOLEAN:
305
                        featureData.set(fieldIndex, new Boolean(value));
306
                        break;
307

    
308
                case DataTypes.BYTE:
309
                        try {
310
                                featureData.set(fieldIndex, new Byte(value));
311
                        } catch (NumberFormatException e) {
312
                                featureData.set(fieldIndex, null);
313
                        }
314
                        break;
315

    
316
                case DataTypes.DATE:
317
                        String year = value.substring(0, 4);
318
                        String month = value.substring(4, 6);
319
                        String day = value.substring(6, 8);
320
                        DateFormat df;
321
                        if (descriptor.getDateFormat() == null){
322
                                df = DateFormat.getDateInstance(DateFormat.SHORT,
323
                                                ukLocale);
324
                        } else{
325
                                df = descriptor.getDateFormat();
326
                        }
327
                        /*
328
                         * Calendar c = Calendar.getInstance(); c.clear();
329
                         * c.set(Integer.parseInt(year), Integer.parseInt(month),
330
                         * Integer.parseInt(day)); c.set(Calendar.MILLISECOND, 0);
331
                         */
332
                        String strAux = month + "/" + day + "/" + year;
333
                        Date dat = null;
334
                        try {
335
                                dat = df.parse(strAux);
336
                        } catch (ParseException e) {
337
                                throw new ReadException(this.store.getName(), e);
338
                        }
339
                        featureData.set(fieldIndex, dat);
340
                        break;
341

    
342

    
343
                default:
344
                        featureData.set(fieldIndex, descriptor.getDefaultValue());
345
                        break;
346
                }
347
        }
348

    
349

    
350
        /***
351
         * NOT supported in Alter Mode
352
         *
353
         * @param index
354
         * @return
355
         * @throws ReadException
356
         */
357
        protected FeatureData getFeatureDataByIndex(long index) throws DataException {
358
                return this
359
                                .getFeatureDataByIndex(index, this.store
360
                                .getDefaultFeatureType());
361
        }
362

    
363
        protected int getFeatureCount() throws ReadException, OpenException,
364
                        ResourceNotifyChangesException {
365
                this.open();
366
                try {
367
                        this.dbfResource.begin();
368
                } catch (ResourceBeginException e) {
369
                        throw new ReadException(this.getName(), e);
370
                }
371
                try {
372
                        return this.dbfFile.getRecordCount();
373
                } finally {
374
                        this.dbfResource.end();
375
                }
376
        }
377

    
378
        public FeatureSetProvider createSet(FeatureQuery query)
379
                        throws DataException {
380
                return new DBFSetProvider(this, query);
381
        }
382

    
383
        public boolean canCreate() {
384
                return true;
385
        }
386

    
387
        public boolean canWriteGeometry(int geometryType) throws DataException {
388
                return false;
389
        }
390

    
391
        public void open() throws OpenException {
392
                if (this.dbfFile.isOpen()) {
393
                        return;
394
                }
395
                try {
396
                        this.dbfResource.begin();
397
                } catch (ResourceBeginException e) {
398
                        throw new OpenException(this.getName(), e);
399
                }
400
                try {
401
                        this.dbfFile.open();
402
                        this.dbfResource.notifyOpen();
403

    
404
                } catch (UnsupportedVersionException e) {
405
                        throw new OpenException(this.getName(), e);
406
                } catch (ResourceNotifyOpenException e) {
407
                        throw new OpenException(this.getName(), e);
408
                } catch (FileNotFoundException e) {
409
                        throw new OpenException(this.getName(), e);
410
                } catch (IOException e) {
411
                        throw new OpenException(this.getName(), e);
412
                } finally {
413
                        this.dbfResource.end();
414
                }
415
        }
416

    
417
        public void close() throws CloseException {
418
                super.close();
419
                if (!this.dbfFile.isOpen()) {
420
                        return;
421
                }
422
                //Cerrar recurso
423
                try {
424
                        this.dbfResource.begin();
425
                } catch (ResourceBeginException e) {
426
                        throw new CloseException(this.getName(), e);
427
                }
428
                try {
429
                        this.dbfFile.close();
430
                        this.dbfResource.notifyClose();
431

    
432
                } catch (ResourceNotifyCloseException e) {
433
                        throw new CloseException(this.getName(), e);
434
                } finally {
435
                        this.dbfResource.end();
436
                }
437
        }
438

    
439
        public void dispose() throws CloseException {
440
                this.close();
441
                dbfFile = null;
442
                this.dbfResource.removeConsumer(this);
443
                dbfResource = null;
444
                metadata = null;
445
                super.dispose();
446
        }
447

    
448
        public boolean closeResourceRequested(ResourceProvider resource) {
449
                try {
450
                        this.close();
451
                } catch (CloseException e) {
452
                        return false;
453
                }
454
                return true;
455
        }
456

    
457
        public boolean allowWrite() {
458
                File file;
459
                try {
460
                        file = new File((String) this.dbfResource.get());
461
                } catch (AccessResourceException e) {
462
                        return false;
463
                }
464
                return super.allowWrite() && file.canWrite();
465
        }
466

    
467
        public void refresh() throws OpenException {
468
                try {
469
                        this.close();
470
                } catch (CloseException e) {
471
                        throw new OpenException(this.getName(), e);
472
                }
473
                this.open();
474
                try {
475
                        this.getTheFeatureType();
476
                } catch (InitializeException e) {
477
                        throw new OpenException(this.getName(), e);
478
                }
479
        }
480

    
481
        /**
482
         *
483
         * @param index
484
         * @param featureType
485
         * @return
486
         * @throws ReadException
487
         */
488
        protected FeatureData getFeatureDataByIndex(long index,
489
                        FeatureType featureType) throws DataException {
490
                FeatureData featureData = this.createFeatureData(featureType);
491
                featureData.setOID(new Long(index));
492
                return featureData;
493
        }
494

    
495
        protected void initFeatureDataByIndex(FeatureData featureData,
496
                        long index, FeatureType featureType) throws DataException {
497
                featureData.setOID(new Long(index));
498
        }
499

    
500
        /**
501
         *
502
         * @param featureData
503
         * @throws DataException
504
         */
505
        protected void loadFeatureDataByIndex(FeatureData featureData)
506
                        throws DataException {
507
                this.open();
508
                this.dbfResource.begin();
509
                long index = ((Long) featureData.getOID()).longValue();
510
                try {
511
                        if (index >= this.dbfFile.getRecordCount()) {
512
                                // FIXME
513
                                throw new ArrayIndexOutOfBoundsException("" + index);
514
                        }
515
                        Iterator iterator = featureData.getType().iterator();
516
                        while (iterator.hasNext()) {
517
                                FeatureAttributeDescriptor descriptor = (FeatureAttributeDescriptor) iterator
518
                                                .next();
519
                                this.loadValue(featureData, (int) index, descriptor);
520
                        }
521

    
522

    
523
                } finally {
524
                        this.dbfResource.end();
525
                }
526
        }
527

    
528
        public int getFeatureReferenceOIDType() {
529
                return DataTypes.LONG;
530
        }
531

    
532
        public Object createNewOID() {
533
                if (this.counterNewsOIDs < 0) {
534
                        try {
535
                                this.counterNewsOIDs = this.getFeatureCount();
536
                        } catch (DataException e) {
537
                                e.printStackTrace();
538
                        }
539

    
540
                }
541
                this.counterNewsOIDs++;
542
                return null;
543
        }
544

    
545
        public boolean supportsAppendMode() {
546
                return false;
547
        }
548

    
549

    
550
        public void append(Feature feature) {
551
                // TODO Auto-generated method stub
552
                throw new NotYetImplemented();
553

    
554
        }
555

    
556
        public void beginAppend() {
557
                // TODO Auto-generated method stub
558
                throw new NotYetImplemented();
559
        }
560

    
561
        public void endAppend() {
562
                // TODO Auto-generated method stub
563
                throw new NotYetImplemented();
564

    
565
        }
566

    
567
        public PersistentState getState() throws PersistenceException {
568
                // Nothing to do
569
                return null;
570
        }
571

    
572
        public void loadState(PersistentState state) throws PersistenceException {
573
                try {
574
                        this.init((DBFStoreParameters) this.store.getParameters());
575
                } catch (InitializeException e) {
576
                        throw new PersistenceException(e);
577
                }
578
        }
579

    
580
        public void setState(PersistentState state) throws PersistenceException {
581
                try {
582
                        this.init((DBFStoreParameters) this.store.getParameters());
583
                } catch (InitializeException e) {
584
                        throw new PersistenceException(e);
585
                }
586
        }
587

    
588

    
589
}