Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.file / org.gvsig.fmap.dal.file.dbf / src / main / java / org / gvsig / fmap / dal / store / dbf / DBFStoreProvider.java @ 40435

History | View | Annotate | Download (22.6 KB)

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

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

    
14
import org.apache.commons.io.FileUtils;
15
import org.slf4j.Logger;
16
import org.slf4j.LoggerFactory;
17

    
18
import org.gvsig.fmap.dal.DALLocator;
19
import org.gvsig.fmap.dal.DataManager;
20
import org.gvsig.fmap.dal.DataServerExplorer;
21
import org.gvsig.fmap.dal.DataStoreNotification;
22
import org.gvsig.fmap.dal.DataTypes;
23
import org.gvsig.fmap.dal.FileHelper;
24
import org.gvsig.fmap.dal.exception.CloseException;
25
import org.gvsig.fmap.dal.exception.DataException;
26
import org.gvsig.fmap.dal.exception.FileNotFoundException;
27
import org.gvsig.fmap.dal.exception.InitializeException;
28
import org.gvsig.fmap.dal.exception.OpenException;
29
import org.gvsig.fmap.dal.exception.ReadException;
30
import org.gvsig.fmap.dal.exception.UnsupportedVersionException;
31
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
32
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
33
import org.gvsig.fmap.dal.feature.EditableFeatureType;
34
import org.gvsig.fmap.dal.feature.Feature;
35
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
36
import org.gvsig.fmap.dal.feature.FeatureQuery;
37
import org.gvsig.fmap.dal.feature.FeatureSet;
38
import org.gvsig.fmap.dal.feature.FeatureStore;
39
import org.gvsig.fmap.dal.feature.FeatureType;
40
import org.gvsig.fmap.dal.feature.exception.PerformEditingException;
41
import org.gvsig.fmap.dal.feature.exception.UnknownDataTypeException;
42
import org.gvsig.fmap.dal.feature.spi.AbstractFeatureStoreProvider;
43
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
44
import org.gvsig.fmap.dal.feature.spi.FeatureReferenceProviderServices;
45
import org.gvsig.fmap.dal.feature.spi.FeatureSetProvider;
46
import org.gvsig.fmap.dal.resource.ResourceAction;
47
import org.gvsig.fmap.dal.resource.exception.AccessResourceException;
48
import org.gvsig.fmap.dal.resource.exception.ResourceException;
49
import org.gvsig.fmap.dal.resource.exception.ResourceExecuteException;
50
import org.gvsig.fmap.dal.resource.exception.ResourceNotifyChangesException;
51
import org.gvsig.fmap.dal.resource.exception.ResourceNotifyCloseException;
52
import org.gvsig.fmap.dal.resource.exception.ResourceNotifyOpenException;
53
import org.gvsig.fmap.dal.resource.file.FileResource;
54
import org.gvsig.fmap.dal.resource.spi.ResourceConsumer;
55
import org.gvsig.fmap.dal.resource.spi.ResourceProvider;
56
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorer;
57
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorerParameters;
58
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
59
import org.gvsig.fmap.dal.store.dbf.utils.DbaseFile;
60
import org.gvsig.metadata.MetadataLocator;
61
import org.gvsig.metadata.MetadataManager;
62
import org.gvsig.metadata.exceptions.MetadataException;
63
import org.gvsig.tools.dispose.DisposableIterator;
64
import org.gvsig.tools.dynobject.DynObject;
65
import org.gvsig.tools.dynobject.exception.DynFieldNotFoundException;
66
import org.gvsig.tools.exception.BaseException;
67

    
68
public class DBFStoreProvider extends AbstractFeatureStoreProvider implements
69
                ResourceConsumer {
70

    
71
    private static final Logger LOG = LoggerFactory.getLogger(DBFStoreProvider.class);
72

    
73
        public static String NAME = "DBF";
74
        public static String DESCRIPTION = "DBF file";
75
        private static final Locale ukLocale = new Locale("en", "UK");
76
        
77
        public static final String METADATA_DEFINITION_NAME = NAME;
78
        private static final String METADATA_ENCODING = "Encoding";
79
        private static final String METADATA_CODEPAGE = "CodePage";
80
                
81
        private DbaseFile dbfFile = null;
82
        private ResourceProvider dbfResource;
83
        private long counterNewsOIDs = -1;
84
        private DBFFeatureWriter writer;
85
        
86
        private static long lastLogTime = 0;
87

    
88

    
89
        protected static void registerMetadataDefinition() throws MetadataException {
90
                MetadataManager manager = MetadataLocator.getMetadataManager();
91
                if( manager.getDefinition(METADATA_DEFINITION_NAME)==null ) {
92
                        manager.addDefinition(
93
                                        METADATA_DEFINITION_NAME, 
94
                                        DBFStoreParameters.class.getResourceAsStream("DBFStoreMetadata.xml"),
95
                                        DBFStoreParameters.class.getClassLoader()
96
                        );
97
                }
98
        }
99

    
100
        public DBFStoreProvider(DBFStoreParameters params,
101
                        DataStoreProviderServices storeServices)
102
                        throws InitializeException {
103
                super(
104
                                params, 
105
                                storeServices,
106
                                FileHelper.newMetadataContainer(METADATA_DEFINITION_NAME)
107
                );
108
                this.init(params, storeServices);
109
        }
110

    
111
        protected DBFStoreProvider(DBFStoreParameters params,
112
                        DataStoreProviderServices storeServices, DynObject metadata)
113
                        throws InitializeException {
114
                super(params, storeServices, metadata);
115
                this.init(params, storeServices);
116
        }
117

    
118
        protected void init(DBFStoreParameters params,
119
                        DataStoreProviderServices storeServices) throws InitializeException {
120
                if( params == null ) {
121
                        throw new InitializeException( new NullPointerException("params is null") );
122
                }
123
                File theFile = getDBFParameters().getDBFFile();
124
                if( theFile == null ) {
125
                        throw new InitializeException( new NullPointerException("dbf file is null") );
126
                }
127
                initResource(params, storeServices);
128

    
129
                Charset charset = params.getEncoding();
130
                this.dbfFile = new DbaseFile(theFile, charset);
131

    
132
                writer = new DBFFeatureWriter(this.getProviderName());
133

    
134
                this.initFeatureType();
135

    
136
        }
137

    
138
        public Object getDynValue(String name) throws DynFieldNotFoundException {
139
                try {
140
                        this.open();
141
                } catch (OpenException e) {
142
                        throw new RuntimeException(e);
143
                }
144
                if( METADATA_ENCODING.equalsIgnoreCase(name) ) {
145
                        return this.dbfFile.getOriginalCharset();
146
                } else if( METADATA_CODEPAGE.equalsIgnoreCase(name) ) {
147
                        return new Byte(this.dbfFile.getCodePage());
148
                }
149
                return super.getDynValue(name);
150
        }
151

    
152
        protected void initResource(DBFStoreParameters params,
153
                        DataStoreProviderServices storeServices) throws InitializeException {
154

    
155
                File theFile = getDBFParameters().getDBFFile();
156
                dbfResource =
157
                                this.createResource(FileResource.NAME,
158
                                                new Object[] { theFile.getAbsolutePath() });
159
                dbfResource.addConsumer(this);
160
        }
161

    
162
        public String getProviderName() {
163
                return NAME;
164
        }
165

    
166
        protected DBFStoreParameters getDBFParameters() {
167
                return (DBFStoreParameters) super.getParameters();
168
        }
169

    
170

    
171
        public DataServerExplorer getExplorer() throws ReadException {
172
                DataManager manager = DALLocator.getDataManager();
173
                FilesystemServerExplorerParameters params;
174
                try {
175
                        params = (FilesystemServerExplorerParameters) manager
176
                                        .createServerExplorerParameters(FilesystemServerExplorer.NAME);
177
                        params.setRoot(this.getDBFParameters().getDBFFile().getParent());
178
                        return manager.openServerExplorer(FilesystemServerExplorer.NAME,params);
179
                } catch (DataException e) {
180
                        throw new ReadException(this.getProviderName(), e);
181
                } catch (ValidateDataParametersException e) {
182
                        // TODO Auto-generated catch block
183
                        throw new ReadException(this.getProviderName(), e);
184
                }
185
        }
186

    
187
        protected FeatureProvider internalGetFeatureProviderByReference(
188
                        FeatureReferenceProviderServices reference, FeatureType featureType)
189
                        throws DataException {
190
                return this.getFeatureProviderByIndex(
191
                                ((Long) reference.getOID()).longValue(), featureType);
192
        }
193

    
194
        public void performChanges(Iterator deleteds, Iterator inserteds,
195
                        Iterator updateds, Iterator originalFeatureTypesUpdated)
196
                        throws PerformEditingException {
197

    
198
                try {
199
                        final FeatureStore store =
200
                                        this.getStoreServices().getFeatureStore();
201
                        getResource().execute(new ResourceAction() {
202

    
203
                                public Object run() throws Exception {
204
                                        FeatureSet set = null;
205
                                        DisposableIterator iter = null;
206
                                        try {
207
                                                set = store.getFeatureSet();
208
                                                DBFStoreParameters tmpParams =
209
                                                                (DBFStoreParameters) getDBFParameters().getCopy();
210

    
211
                                                File tmp_file = File.createTempFile(
212
                                                    "tmp_" + System.currentTimeMillis(), ".dbf");
213
                                                tmp_file.deleteOnExit();
214
                                                
215
                                                tmpParams.setDBFFile(tmp_file);
216

    
217
                                                writer.begin(tmpParams, store.getDefaultFeatureType(),
218
                                                                set.getSize());
219

    
220
                                                iter = set.fastIterator();
221
                                                while (iter.hasNext()) {
222
                                                        Feature feature = (Feature) iter.next();
223
                                                        writer.append(feature);
224
                                                }
225

    
226
                                                writer.end();
227

    
228
                                                try {
229
                                                        close();
230
                                                } catch (CloseException e1) {
231
                                                        throw new PerformEditingException(getProviderName(), e1);
232
                                                }
233
                                                getDBFParameters().getDBFFile().delete();
234
                                                
235
                                                File target_file = getDBFParameters().getDBFFile();
236
                                                if (target_file.exists()) {
237
                                                    target_file.delete();
238
                                                }
239
                                                tmp_file.renameTo(target_file);
240
                                                
241
                                                if (tmp_file.exists() && !target_file.exists()) {
242
                                                    // Renaming failed, let's simply copy.
243
                                                    // We assume we cannot delete it, but we
244
                                                    // used deleteOnExit and it's
245
                                                    // temporary, so no problem
246
                                                    LOG.info("Warning: copying tmp file instead of renaming: "
247
                                        + target_file.getName());
248
                                                    FileUtils.copyFile(tmp_file, target_file);
249
                                                }
250

    
251
                                                resourcesNotifyChanges();
252
                                                initFeatureType();
253
                                        } finally {
254
                                                if (set != null) {
255
                                                        set.dispose();
256
                                                }
257
                                                if (iter != null) {
258
                                                        iter.dispose();
259
                                                }
260
                                        }
261
                                        return null;
262
                                }
263
                        });
264
                } catch (ResourceExecuteException e) {
265
                        throw new PerformEditingException(this.getProviderName(), e);
266
                }
267

    
268
                this.counterNewsOIDs = -1;
269
        }
270

    
271
        /*
272
         * ==================================================
273
         */
274

    
275
        public FeatureProvider createFeatureProvider(FeatureType type) throws DataException {
276
                return new DBFFeatureProvider(this, type);
277
        }
278

    
279

    
280
        /*
281
         * ===================================================
282
         */
283

    
284

    
285

    
286
        protected void initFeatureType() throws InitializeException {
287
                try {
288
                        FeatureType defaultType =
289
                                        this.getTheFeatureType().getNotEditableCopy();
290
                        List types = new ArrayList(1);
291
                        types.add(defaultType);
292
                        this.getStoreServices().setFeatureTypes(types, defaultType);
293
                } catch (OpenException e) {
294
                        throw new InitializeException(getResource().toString(), e);
295
                }
296
        }
297

    
298
        protected EditableFeatureType getTheFeatureType()
299
                        throws InitializeException, OpenException {
300
                try {
301
                        this.open();
302
                } catch (DataException e) {
303
                        throw new InitializeException(this.getProviderName(), e);
304
                }
305
                return (EditableFeatureType) getResource().execute(
306
                                new ResourceAction() {
307

    
308
                                        public Object run() throws Exception {
309
                                                int fieldCount = -1;
310
                                                fieldCount = dbfFile.getFieldCount();
311

    
312
                                                EditableFeatureType fType =
313
                                                                getStoreServices().createFeatureType();
314

    
315
                                                fType.setHasOID(true);
316
                                                int precision;
317
                                                for (int i = 0; i < fieldCount; i++) {
318
                                                        char fieldType = dbfFile.getFieldType(i);
319
                                                        EditableFeatureAttributeDescriptor attr;
320

    
321
                                                        if (fieldType == 'L') {
322
                                                                attr =
323
                                                                                fType.add(dbfFile.getFieldName(i),
324
                                                                                                DataTypes.BOOLEAN);
325
                                                                attr.setDefaultValue(new Boolean(false));
326
                                                                attr.setAllowNull(false);
327

    
328
                                                        } else if ((fieldType == 'F') || (fieldType == 'N')) {
329
                                                                precision = dbfFile.getFieldDecimalLength(i);
330
                                                                if (precision > 0) {
331
                                                                        attr =
332
                                                                                        fType.add(dbfFile.getFieldName(i),
333
                                                                                                        DataTypes.DOUBLE,
334
                                                                                                        dbfFile.getFieldLength(i));
335
                                                                        attr.setPrecision(precision);
336
                                                                        attr.setDefaultValue(new Double(0));
337

    
338
                                                                } else {
339
                                                                    int length = dbfFile.getFieldLength(i);
340
                                                                    int type = DataTypes.INT;
341
                                                                    if (length > 9){
342
                                                                        type = DataTypes.LONG;
343
                                                                    }
344
                                                                        attr =
345
                                                                                        fType.add(dbfFile.getFieldName(i),
346
                                                                                                type,
347
                                                                                                        length);
348
                                                                        attr.setDefaultValue(new Integer(0));
349
                                                                }
350
                                                                attr.setAllowNull(false);
351

    
352
                                                        } else if (fieldType == 'C') {
353
                                                                attr =
354
                                                                                fType.add(dbfFile.getFieldName(i),
355
                                                                                                DataTypes.STRING);
356
                                                                attr.setSize(dbfFile.getFieldLength(i));
357
                                                                attr.setDefaultValue("");
358
                                                                
359
                                                                
360
                                                                attr.setAllowNull(false);
361

    
362
                                                        } else if (fieldType == 'D') {
363
                                                                attr =
364
                                                                                fType.add(dbfFile.getFieldName(i),
365
                                                                                                DataTypes.DATE);
366
                                                                /*
367
                                                                 * def value 1-1-1970
368
                                                                 */
369
                                                                attr.setDefaultValue(new Date(0));
370
                                                                attr.setAllowNull(false);
371
                                                        } else {
372
                                                                throw new InitializeException(getProviderName(),
373
                                                                                new UnknownDataTypeException(
374
                                                                                                dbfFile.getFieldName(i), ""
375
                                                                                                                + fieldType, getProviderName()));
376
                                                        }
377
                                                }
378
                                                
379
                                                // FeatureRules rules = fType.getRules();
380
                                                // rules.add(new DBFRowValidator());
381
                                                return fType;
382
                                        }
383
                                });
384
        }
385

    
386

    
387
        protected void loadValue(FeatureProvider featureProvider, int rowIndex,
388
                        FeatureAttributeDescriptor descriptor) throws ReadException {
389
            
390
                if (descriptor.getEvaluator() != null) {
391
                        // Nothing to do
392
                        return;
393
                }
394

    
395
                int dbfIndex = this.dbfFile.getFieldIndex(descriptor.getName());
396
                
397
                if (dbfIndex < 0) {
398
                    // Someone asked to load a field
399
                    // which does not exist in the DBF file. This can happen 
400
                    // in editing process when a field has been added
401
                    // in the current editing session, so we simply do nothing.
402
                    // The expansion manager is expected to manage those new fields
403
                    // and their values.
404
                    long curr_time = System.currentTimeMillis();
405
                    // This ensures not more than one log every 2 seconds
406
                    if (curr_time - lastLogTime > 2000) {
407
                        LOG.info("Warning: The requested field does not exist in the DBF file. Assumed it's a new field in editing mode.");
408
                        lastLogTime = curr_time;
409
                    }
410
                    return;
411
                }
412
                
413
                String value = null;
414
                try {
415
                        value = this.dbfFile.getStringFieldValue(rowIndex, dbfIndex);
416
                } catch (DataException e) {
417
                        throw new ReadException(this.getProviderName(), e);
418
                }
419
                value = value.trim();
420
                int fieldType = descriptor.getType();
421
                switch (fieldType) {
422
                case DataTypes.STRING:
423
                        featureProvider.set(descriptor.getIndex(), value);
424
                        break;
425

    
426
                case DataTypes.DOUBLE:
427
                        try {
428
                                featureProvider.set(descriptor.getIndex(), new Double(value));
429
                        } catch (NumberFormatException e) {
430
                                featureProvider.set(descriptor.getIndex(), null);
431
                        }
432
                        break;
433

    
434
                case DataTypes.INT:
435
                        try {
436
                                featureProvider.set(descriptor.getIndex(), new Integer(value));
437
                        } catch (NumberFormatException e) {
438
                                featureProvider.set(descriptor.getIndex(), null);
439
                        }
440
                        break;
441

    
442
                case DataTypes.FLOAT:
443
                        try {
444
                                featureProvider.set(descriptor.getIndex(), new Float(value));
445
                        } catch (NumberFormatException e) {
446
                                featureProvider.set(descriptor.getIndex(), null);
447
                        }
448
                        break;
449

    
450
                case DataTypes.LONG:
451
                        try {
452
                                featureProvider.set(descriptor.getIndex(), new Long(value));
453
                        } catch (NumberFormatException e) {
454
                                featureProvider.set(descriptor.getIndex(), null);
455
                        }
456
                        break;
457

    
458
                case DataTypes.BOOLEAN:
459
                        if (value.equalsIgnoreCase("T")){
460
                                featureProvider.set(descriptor.getIndex(), Boolean.TRUE);
461
                        } else {
462
                                featureProvider.set(descriptor.getIndex(), Boolean.FALSE);
463
                                
464
                        }
465
                        break;
466

    
467
                case DataTypes.BYTE:
468
                        try {
469
                                featureProvider.set(descriptor.getIndex(), new Byte(value));
470
                        } catch (NumberFormatException e) {
471
                                featureProvider.set(descriptor.getIndex(), null);
472
                        }
473
                        break;
474

    
475
                case DataTypes.DATE:
476
                        if (value.equals("")){
477
                                value=null;
478
                                return;
479
                        }
480
                        String year = value.substring(0, 4);
481
                        String month = value.substring(4, 6);
482
                        String day = value.substring(6, 8);
483
                        DateFormat df;
484
                        if (descriptor.getDateFormat() == null){
485
                                df = DateFormat.getDateInstance(DateFormat.SHORT,
486
                                                ukLocale);
487
                        } else{
488
                                df = descriptor.getDateFormat();
489
                        }
490
                        /*
491
                         * Calendar c = Calendar.getInstance(); c.clear();
492
                         * c.set(Integer.parseInt(year), Integer.parseInt(month),
493
                         * Integer.parseInt(day)); c.set(Calendar.MILLISECOND, 0);
494
                         */
495
                        String strAux = month + "/" + day + "/" + year;
496
                        Date dat = null;
497
                        try {
498
                                dat = df.parse(strAux);
499
                        } catch (ParseException e) {
500
                                throw new ReadException(this.getProviderName(), e);
501
                        }
502
                        featureProvider.set(descriptor.getIndex(), dat);
503
                        break;
504

    
505

    
506
                default:
507
                        featureProvider
508
                                        .set(descriptor.getIndex(), descriptor.getDefaultValue());
509
                        break;
510
                }
511
        }
512

    
513

    
514
        /***
515
         * NOT supported in Alter Mode
516
         *
517
         * @param index
518
         * @return
519
         * @throws ReadException
520
         */
521
        protected FeatureProvider getFeatureProviderByIndex(long index) throws DataException {
522
                return this
523
                                .getFeatureProviderByIndex(index, this.getStoreServices()
524
                                .getDefaultFeatureType());
525
        }
526

    
527
        public long getFeatureCount() throws ReadException, OpenException,
528
                        ResourceNotifyChangesException {
529
                this.open();
530
                return ((Long) getResource().execute(new ResourceAction() {
531
                        public Object run() throws Exception {
532
                                return Long.valueOf(dbfFile.getRecordCount());
533
                        }
534
                })).longValue();
535
        }
536

    
537
        public FeatureSetProvider createSet(FeatureQuery query, FeatureType featureType)
538
                        throws DataException {
539
                return new DBFSetProvider(this, query, featureType);
540
        }
541

    
542
        public boolean canCreate() {
543
                return true;
544
        }
545

    
546
        public boolean canWriteGeometry(int geometryType, int geometrySubType) throws DataException {
547
                return false;
548
        }
549

    
550
        public void open() throws OpenException {
551
                if (this.dbfFile.isOpen()) {
552
                        return;
553
                }
554
                try {
555
                        getResource().execute(new ResourceAction() {
556
                                public Object run() throws Exception {
557
                                        openFile();
558
                                        resourcesOpen();
559
                                        return null;
560
                                }
561
                        });
562

    
563
                } catch (ResourceExecuteException e) {
564
                        throw new OpenException(this.getProviderName(), e);
565
                }
566
        }
567

    
568
        protected void openFile() throws FileNotFoundException,
569
                        UnsupportedVersionException, IOException, DataException {
570
                this.dbfFile.open();
571
        }
572

    
573
        public void close() throws CloseException {
574
                if (dbfFile == null || !this.dbfFile.isOpen()) {
575
                        return;
576
                }
577
                super.close();
578
                //Cerrar recurso
579
                try {
580
                        getResource().execute(new ResourceAction() {
581
                                public Object run() throws Exception {
582
                                        closeFile();
583
                                        resourcesNotifyClose();
584
                                        return null;
585
                                }
586
                        });
587
                } catch (ResourceExecuteException e) {
588
                        throw new CloseException(this.getProviderName(), e);
589
                }
590
        }
591

    
592
        protected void closeFile() throws CloseException {
593
                this.dbfFile.close();
594
        }
595

    
596
        @Override
597
        protected void doDispose() throws BaseException {
598
                this.close();
599
                dbfFile = null;
600
                disposeResource();
601
                super.doDispose();
602
        }
603

    
604
        protected void disposeResource() {
605
                this.dbfResource.removeConsumer(this);
606
                dbfResource = null;
607
        }
608

    
609
        public boolean closeResourceRequested(ResourceProvider resource) {
610
                try {
611
                        this.close();
612
                } catch (CloseException e) {
613
                        return false;
614
                }
615
                return true;
616
        }
617

    
618
        public boolean allowWrite() {
619
                File file;
620
                try {
621
                        file = ((File) this.dbfResource.get());
622
                } catch (AccessResourceException e) {
623
                        return false;
624
                }
625
                return file.canWrite();
626
        }
627

    
628
        public void refresh() throws OpenException {
629
                try {
630
                        this.close();
631
                } catch (CloseException e) {
632
                        throw new OpenException(this.getProviderName(), e);
633
                }
634
                this.open();
635
                try {
636
                        this.initFeatureType();
637
                } catch (InitializeException e) {
638
                        throw new OpenException(this.getProviderName(), e);
639
                }
640
        }
641

    
642
        /**
643
         *
644
         * @param index
645
         * @param featureType
646
         * @return
647
         * @throws ReadException
648
         */
649
        protected FeatureProvider getFeatureProviderByIndex(long index,
650
                        FeatureType featureType) throws DataException {
651
                FeatureProvider featureProvider = this.createFeatureProvider(featureType);
652
                featureProvider.setOID(new Long(index));
653
                return featureProvider;
654
        }
655

    
656
        protected void initFeatureProviderByIndex(FeatureProvider featureProvider,
657
                        long index, FeatureType featureType) throws DataException {
658
                featureProvider.setOID(new Long(index));
659
        }
660

    
661
        /**
662
         *
663
         * @param featureProvider
664
         * @throws DataException
665
         */
666
        protected void loadFeatureProviderByIndex(FeatureProvider featureProvider)
667
                        throws DataException {
668
            
669
                long index = ((Long) featureProvider.getOID()).longValue();
670
        int rec_count = this.dbfFile.getRecordCount();
671
        
672
        if (index >= rec_count) {
673

    
674
            ReadException rex = new ReadException(NAME,
675
                new ArrayIndexOutOfBoundsException(
676
                "Index of requested feature (" +
677
                index + ") is >= record count (" + rec_count + ")"));
678
            
679
            LOG.info("Error while loading feature. ", rex);
680
            throw rex;
681
        }                
682
                
683
                Iterator iterator = featureProvider.getType().iterator();
684
                while (iterator.hasNext()) {
685
                        FeatureAttributeDescriptor descriptor =
686
                                        (FeatureAttributeDescriptor) iterator.next();
687
                        this.loadValue(featureProvider, (int) index, descriptor);
688
                }
689
        }
690

    
691
        public int getOIDType() {
692
                return DataTypes.LONG;
693
        }
694

    
695
        public Object createNewOID() {
696
                if (this.counterNewsOIDs < 0) {
697
                        try {
698
                                this.counterNewsOIDs = this.getFeatureCount();
699
                        } catch (DataException e) {
700
                                e.printStackTrace();
701
                        }
702

    
703
                }else{
704
                        this.counterNewsOIDs++;
705
                }
706
                return new Long(counterNewsOIDs);
707
        }
708

    
709
        public boolean supportsAppendMode() {
710
                return true;
711
        }
712

    
713

    
714
        public void append(final FeatureProvider featureProvider)
715
                        throws DataException {
716
                getResource().execute(new ResourceAction() {
717
                        public Object run() throws Exception {
718
                                writer.append(getStoreServices().createFeature(featureProvider));
719
                                return null;
720
                        }
721
                });
722
        }
723

    
724
        public void beginAppend() throws DataException {
725
                this.close();
726
                getResource().execute(new ResourceAction() {
727
                        public Object run() throws Exception {
728
                                writer.begin(getDBFParameters(),
729
                                                getStoreServices().getDefaultFeatureType(),
730
                                                getStoreServices().getFeatureStore().getFeatureCount());
731
                                return null;
732
                        }
733
                });
734
        }
735

    
736
        public void endAppend() throws DataException {
737
                getResource().execute(new ResourceAction() {
738
                        public Object run() throws Exception {
739
                                writer.end();
740
                            resourcesNotifyChanges();
741
                                counterNewsOIDs = -1;
742
                                return null;
743
                        }
744
                });
745
        }
746

    
747
        /*
748
         * (non-Javadoc)
749
         *
750
         * @see
751
         * org.gvsig.fmap.dal.resource.spi.ResourceConsumer#resourceChanged(org.
752
         * gvsig.fmap.dal.resource.spi.ResourceProvider)
753
         */
754
        public void resourceChanged(ResourceProvider resource) {
755
                this.getStoreServices().notifyChange(
756
                                DataStoreNotification.RESOURCE_CHANGED,
757
                                resource);
758
        }
759

    
760
        /**
761
         *
762
         * @throws ResourceNotifyChangesException
763
         */
764
        protected void resourcesNotifyChanges()
765
                        throws ResourceNotifyChangesException {
766
                this.dbfResource.notifyChanges();
767
        }
768

    
769
        /**
770
         * @throws ResourceNotifyCloseException
771
         *
772
         */
773
        protected void resourcesNotifyClose() throws ResourceNotifyCloseException {
774
                this.dbfResource.notifyClose();
775
        }
776

    
777
        /**
778
         * @throws ResourceNotifyOpenException
779
         *
780
         */
781
        protected void resourcesOpen() throws ResourceNotifyOpenException {
782
                this.dbfResource.notifyOpen();
783
        }
784

    
785
        public Object getSourceId() {
786
                return this.getDBFParameters().getFile();
787
        }
788
        
789
        public String getName() {
790
                String name = this.getDBFParameters().getFile().getName();
791
                int n = name.lastIndexOf(".");
792
                if( n<1 ) {
793
                        return name;
794
                }
795
                return name.substring(0, n);
796
        }
797
        
798
        public String getFullName() {
799
                return this.getDBFParameters().getFile().getAbsolutePath();
800
        }
801

    
802
        protected void resourceCloseRequest() throws ResourceException {
803
                this.dbfResource.closeRequest();
804
        }
805

    
806
        public ResourceProvider getResource() {
807
                return dbfResource;
808
        }
809
}