Statistics
| Revision:

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

History | View | Annotate | Download (14.9 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.dbfParams = params;
76

    
77
                File theFile = getDBFParameters().getDBFFile();
78
                dbfResource = this.createResource(FileResource.NAME,
79
                                new Object[] { theFile.getAbsolutePath() });
80
                dbfResource.addConsumer(this);
81

    
82
                //DBFResource tmpResource = new DBFResource(dbfParameters);
83
                //
84
                //try {
85
                //        this.dbf = (DBFResource) this.store.addResource(tmpResource);
86
                //} catch (DataException e1) {
87
                //        throw new InitializeException(this.getName(), e1);
88
                //}
89

    
90

    
91
                this.dbfFile = new DbaseFile(theFile);
92
        }
93

    
94
        public FeatureStoreProvider initialize(FeatureStoreProviderServices store)
95
                        throws InitializeException {
96
                super.initialize(store);
97
                this.initFeatureType();
98
                return this;
99
        }
100

    
101
        public String getName() {
102
                return NAME;
103
        }
104

    
105
        protected DBFStoreParameters getDBFParameters() {
106
                return dbfParams;
107
        }
108

    
109

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

    
123
        public FeatureData getFeatureDataByReference(
124
                        FeatureReferenceProviderServices reference, FeatureType featureType)
125
                        throws DataException {
126

    
127
                return this.getFeatureDataByIndex(((Integer) reference.getOID())
128
                                .intValue(),
129
                                featureType);
130
        }
131

    
132

    
133
        public FeatureData getFeatureDataByReference(
134
                        FeatureReferenceProviderServices reference) throws DataException {
135
                return this.getFeatureDataByReference(reference, this.store
136
                                .getDefaultFeatureType());
137
        }
138

    
139
        public void performEditing(Iterator deleteds, Iterator inserteds,
140
                        Iterator updateds)
141
                        throws PerformEditingException {
142
                try {
143
                        this.close();
144
                } catch (CloseException e1) {
145
                        throw new PerformEditingException(this.getName(), e1);
146
                }
147

    
148
                try {
149
                        this.dbfResource.begin();
150
                        DBFFeatureWriter writer = new DBFFeatureWriter(this.getName());
151
                        FeatureSet set = this.store.getFeatureSet();
152
                        writer.begin(this.getDBFParameters(), this.store
153
                                        .getDefaultFeatureType(), set.getSize());
154

    
155
                        Iterator iter = set.iterator();
156
                        while (iter.hasNext()) {
157
                                writer.write((Feature) iter.next());
158
                        }
159

    
160
                        writer.end();
161

    
162
                        this.dbfResource.notifyChanges();
163
                } catch (Exception e) {
164
                        throw new PerformEditingException(this.getName(), e);
165
                } finally {
166
                        this.dbfResource.end();
167
                        this.dbfResource.removeConsumer(this);
168
                }
169

    
170
                this.counterNewsOIDs = -1;
171
        }
172

    
173
        /*
174
         * ==================================================
175
         */
176

    
177
        public FeatureData createFeatureData(FeatureType type) throws DataException {
178
                return new DBFFeatureData(this, (DefaultFeatureType) type);
179
        }
180

    
181

    
182
        /*
183
         * ===================================================
184
         */
185

    
186
        FeatureStoreProviderServices getProviderServices() {
187
                return this.store;
188
        }
189

    
190

    
191
        protected void initFeatureType() throws InitializeException {
192
                FeatureType defaultType = this.getTheFeatureType().getNotEditableCopy();
193
                List types = new ArrayList(1);
194
                types.add(defaultType);
195
                this.store.setFeatureTypes(types, defaultType);
196
        }
197

    
198
        protected EditableFeatureType getTheFeatureType() throws InitializeException {
199
                try {
200
                        this.open();
201
                        this.dbfResource.begin();
202
                } catch (DataException e) {
203
                        throw new InitializeException(this.getName(), e);
204
                }
205
                try {
206
                        int fieldCount = -1;
207
                        fieldCount = dbfFile.getFieldCount();
208

    
209
                        EditableFeatureType fType = this.store.createFeatureType();
210

    
211
                        for (int i = 0; i < fieldCount; i++) {
212
                                char fieldType = dbfFile.getFieldType(i);
213
                                int attrType;
214
                                int precision = 0;
215

    
216
                                if (fieldType == 'L') {
217
                                        attrType = DataTypes.BOOLEAN;
218

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

    
245

    
246
        protected void loadValue(FeatureData featureData, int rowIndex,
247
                        FeatureAttributeDescriptor descriptor) throws ReadException {
248
                if (descriptor.getEvaluator() != null) {
249
                        // Nothing to do
250
                        return;
251
                }
252

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

    
267
                case DataTypes.DOUBLE:
268
                        try {
269
                                featureData.set(fieldIndex, new Double(value));
270
                        } catch (NumberFormatException e) {
271
                                featureData.set(fieldIndex, null);
272
                        }
273
                        break;
274

    
275
                case DataTypes.INT:
276
                        try {
277
                                featureData.set(fieldIndex, new Integer(value));
278
                        } catch (NumberFormatException e) {
279
                                featureData.set(fieldIndex, null);
280
                        }
281
                        break;
282

    
283
                case DataTypes.FLOAT:
284
                        try {
285
                                featureData.set(fieldIndex, new Float(value));
286
                        } catch (NumberFormatException e) {
287
                                featureData.set(fieldIndex, null);
288
                        }
289
                        break;
290

    
291
                case DataTypes.LONG:
292
                        try {
293
                                featureData.set(fieldIndex, new Long(value));
294
                        } catch (NumberFormatException e) {
295
                                featureData.set(fieldIndex, null);
296
                        }
297
                        break;
298

    
299
                case DataTypes.BOOLEAN:
300
                        featureData.set(fieldIndex, new Boolean(value));
301
                        break;
302

    
303
                case DataTypes.BYTE:
304
                        try {
305
                                featureData.set(fieldIndex, new Byte(value));
306
                        } catch (NumberFormatException e) {
307
                                featureData.set(fieldIndex, null);
308
                        }
309
                        break;
310

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

    
337

    
338
                default:
339
                        featureData.set(fieldIndex, descriptor.getDefaultValue());
340
                        break;
341
                }
342
        }
343

    
344

    
345
        /***
346
         * NOT supported in Alter Mode
347
         *
348
         * @param index
349
         * @return
350
         * @throws ReadException
351
         */
352
        protected FeatureData getFeatureDataByIndex(long index) throws DataException {
353
                return this
354
                                .getFeatureDataByIndex(index, this.store
355
                                .getDefaultFeatureType());
356
        }
357

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

    
373
        public FeatureSetProvider createSet(FeatureQuery query)
374
                        throws DataException {
375
                return new DBFSetProvider(this, query);
376
        }
377

    
378
        public boolean canCreate() {
379
                return true;
380
        }
381

    
382
        public boolean canWriteGeometry(int geometryType) throws DataException {
383
                return false;
384
        }
385

    
386
        public void open() throws OpenException {
387
                if (this.dbfFile.isOpen()) {
388
                        return;
389
                }
390
                try {
391
                        this.dbfResource.begin();
392
                } catch (ResourceBeginException e) {
393
                        throw new OpenException(this.getName(), e);
394
                }
395
                try {
396
                        this.dbfFile.open();
397
                        this.dbfResource.notifyOpen();
398

    
399
                } catch (UnsupportedVersionException e) {
400
                        throw new OpenException(this.getName(), e);
401
                } catch (ResourceNotifyOpenException e) {
402
                        throw new OpenException(this.getName(), e);
403
                } catch (FileNotFoundException e) {
404
                        throw new OpenException(this.getName(), e);
405
                } catch (IOException e) {
406
                        throw new OpenException(this.getName(), e);
407
                } finally {
408
                        this.dbfResource.end();
409
                }
410
        }
411

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

    
427
                } catch (ResourceNotifyCloseException e) {
428
                        throw new CloseException(this.getName(), e);
429
                } finally {
430
                        this.dbfResource.end();
431
                }
432
        }
433

    
434
        public void dispose() throws CloseException {
435
                this.close();
436
                dbfFile = null;
437
                this.dbfResource.removeConsumer(this);
438
                dbfResource = null;
439
                metadata = null;
440
                super.dispose();
441
        }
442

    
443
        public boolean closeResourceRequested(ResourceProvider resource) {
444
                try {
445
                        this.close();
446
                } catch (CloseException e) {
447
                        return false;
448
                }
449
                return true;
450
        }
451

    
452
        public boolean allowWrite() {
453
                File file;
454
                try {
455
                        file = (File) this.dbfResource.get();
456
                } catch (AccessResourceException e) {
457
                        return false;
458
                }
459
                return super.allowWrite() && file.canWrite();
460
        }
461

    
462
        public void refresh() throws OpenException {
463
                try {
464
                        this.close();
465
                } catch (CloseException e) {
466
                        throw new OpenException(this.getName(), e);
467
                }
468
                this.open();
469
                try {
470
                        this.getTheFeatureType();
471
                } catch (InitializeException e) {
472
                        throw new OpenException(this.getName(), e);
473
                }
474
        }
475

    
476
        /**
477
         *
478
         * @param index
479
         * @param featureType
480
         * @return
481
         * @throws ReadException
482
         */
483
        protected FeatureData getFeatureDataByIndex(long index,
484
                        FeatureType featureType) throws DataException {
485
                FeatureData featureData = this.createFeatureData(featureType);
486
                featureData.setOID(new Long(index));
487
                return featureData;
488
        }
489

    
490
        protected void initFeatureDataByIndex(FeatureData featureData,
491
                        long index, FeatureType featureType) throws DataException {
492
                featureData.setOID(new Long(index));
493
        }
494

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

    
517

    
518
                } finally {
519
                        this.dbfResource.end();
520
                }
521
        }
522

    
523
        public int getFeatureReferenceOIDType() {
524
                return DataTypes.LONG;
525
        }
526

    
527
        public Object createNewOID() {
528
                if (this.counterNewsOIDs < 0) {
529
                        try {
530
                                this.counterNewsOIDs = this.getFeatureCount();
531
                        } catch (DataException e) {
532
                                e.printStackTrace();
533
                        }
534

    
535
                }
536
                this.counterNewsOIDs++;
537
                return null;
538
        }
539

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

    
544

    
545
        public void append(Feature feature) {
546
                // TODO Auto-generated method stub
547
                throw new NotYetImplemented();
548

    
549
        }
550

    
551
        public void beginAppend() {
552
                // TODO Auto-generated method stub
553
                throw new NotYetImplemented();
554
        }
555

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

    
560
        }
561

    
562
        public PersistentState getState() throws PersistenceException {
563
                // Nothing to do
564
                return null;
565
        }
566

    
567
        public void loadState(PersistentState state) throws PersistenceException {
568
                // Nothing to do
569
        }
570

    
571
        public void setState(PersistentState state) throws PersistenceException {
572
                // Nothing to do
573
        }
574

    
575

    
576
}