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 @ 40559

History | View | Annotate | Download (23.5 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.fmap.dal.store.dbf;
25

    
26
import java.io.File;
27
import java.io.IOException;
28
import java.nio.charset.Charset;
29
import java.text.DateFormat;
30
import java.text.ParseException;
31
import java.util.ArrayList;
32
import java.util.Date;
33
import java.util.Iterator;
34
import java.util.List;
35
import java.util.Locale;
36

    
37
import org.apache.commons.io.FileUtils;
38
import org.slf4j.Logger;
39
import org.slf4j.LoggerFactory;
40

    
41
import org.gvsig.fmap.dal.DALLocator;
42
import org.gvsig.fmap.dal.DataManager;
43
import org.gvsig.fmap.dal.DataServerExplorer;
44
import org.gvsig.fmap.dal.DataStoreNotification;
45
import org.gvsig.fmap.dal.DataTypes;
46
import org.gvsig.fmap.dal.FileHelper;
47
import org.gvsig.fmap.dal.exception.CloseException;
48
import org.gvsig.fmap.dal.exception.DataException;
49
import org.gvsig.fmap.dal.exception.FileNotFoundException;
50
import org.gvsig.fmap.dal.exception.InitializeException;
51
import org.gvsig.fmap.dal.exception.OpenException;
52
import org.gvsig.fmap.dal.exception.ReadException;
53
import org.gvsig.fmap.dal.exception.UnsupportedVersionException;
54
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
55
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
56
import org.gvsig.fmap.dal.feature.EditableFeatureType;
57
import org.gvsig.fmap.dal.feature.Feature;
58
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
59
import org.gvsig.fmap.dal.feature.FeatureQuery;
60
import org.gvsig.fmap.dal.feature.FeatureSet;
61
import org.gvsig.fmap.dal.feature.FeatureStore;
62
import org.gvsig.fmap.dal.feature.FeatureType;
63
import org.gvsig.fmap.dal.feature.exception.PerformEditingException;
64
import org.gvsig.fmap.dal.feature.exception.UnknownDataTypeException;
65
import org.gvsig.fmap.dal.feature.spi.AbstractFeatureStoreProvider;
66
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
67
import org.gvsig.fmap.dal.feature.spi.FeatureReferenceProviderServices;
68
import org.gvsig.fmap.dal.feature.spi.FeatureSetProvider;
69
import org.gvsig.fmap.dal.resource.ResourceAction;
70
import org.gvsig.fmap.dal.resource.exception.AccessResourceException;
71
import org.gvsig.fmap.dal.resource.exception.ResourceException;
72
import org.gvsig.fmap.dal.resource.exception.ResourceExecuteException;
73
import org.gvsig.fmap.dal.resource.exception.ResourceNotifyChangesException;
74
import org.gvsig.fmap.dal.resource.exception.ResourceNotifyCloseException;
75
import org.gvsig.fmap.dal.resource.exception.ResourceNotifyOpenException;
76
import org.gvsig.fmap.dal.resource.file.FileResource;
77
import org.gvsig.fmap.dal.resource.spi.ResourceConsumer;
78
import org.gvsig.fmap.dal.resource.spi.ResourceProvider;
79
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorer;
80
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorerParameters;
81
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
82
import org.gvsig.fmap.dal.store.dbf.utils.DbaseFile;
83
import org.gvsig.metadata.MetadataLocator;
84
import org.gvsig.metadata.MetadataManager;
85
import org.gvsig.metadata.exceptions.MetadataException;
86
import org.gvsig.tools.dispose.DisposableIterator;
87
import org.gvsig.tools.dynobject.DynObject;
88
import org.gvsig.tools.dynobject.exception.DynFieldNotFoundException;
89
import org.gvsig.tools.exception.BaseException;
90

    
91
public class DBFStoreProvider extends AbstractFeatureStoreProvider implements
92
                ResourceConsumer {
93

    
94
    private static final Logger LOG = LoggerFactory.getLogger(DBFStoreProvider.class);
95

    
96
        public static String NAME = "DBF";
97
        public static String DESCRIPTION = "DBF file";
98
        private static final Locale ukLocale = new Locale("en", "UK");
99
        
100
        public static final String METADATA_DEFINITION_NAME = NAME;
101
        private static final String METADATA_ENCODING = "Encoding";
102
        private static final String METADATA_CODEPAGE = "CodePage";
103
                
104
        private DbaseFile dbfFile = null;
105
        private ResourceProvider dbfResource;
106
        private long counterNewsOIDs = -1;
107
        private DBFFeatureWriter writer;
108
        
109
        private static long lastLogTime = 0;
110

    
111

    
112
        protected static void registerMetadataDefinition() throws MetadataException {
113
                MetadataManager manager = MetadataLocator.getMetadataManager();
114
                if( manager.getDefinition(METADATA_DEFINITION_NAME)==null ) {
115
                        manager.addDefinition(
116
                                        METADATA_DEFINITION_NAME, 
117
                                        DBFStoreParameters.class.getResourceAsStream("DBFStoreMetadata.xml"),
118
                                        DBFStoreParameters.class.getClassLoader()
119
                        );
120
                }
121
        }
122

    
123
        public DBFStoreProvider(DBFStoreParameters params,
124
                        DataStoreProviderServices storeServices)
125
                        throws InitializeException {
126
                super(
127
                                params, 
128
                                storeServices,
129
                                FileHelper.newMetadataContainer(METADATA_DEFINITION_NAME)
130
                );
131
                this.init(params, storeServices);
132
        }
133

    
134
        protected DBFStoreProvider(DBFStoreParameters params,
135
                        DataStoreProviderServices storeServices, DynObject metadata)
136
                        throws InitializeException {
137
                super(params, storeServices, metadata);
138
                this.init(params, storeServices);
139
        }
140

    
141
        protected void init(DBFStoreParameters params,
142
                        DataStoreProviderServices storeServices) throws InitializeException {
143
                if( params == null ) {
144
                        throw new InitializeException( new NullPointerException("params is null") );
145
                }
146
                File theFile = getDBFParameters().getDBFFile();
147
                if( theFile == null ) {
148
                        throw new InitializeException( new NullPointerException("dbf file is null") );
149
                }
150
                initResource(params, storeServices);
151

    
152
                Charset charset = params.getEncoding();
153
                this.dbfFile = new DbaseFile(theFile, charset);
154

    
155
                writer = new DBFFeatureWriter(this.getProviderName());
156

    
157
                this.initFeatureType();
158

    
159
        }
160

    
161
        public Object getDynValue(String name) throws DynFieldNotFoundException {
162
                try {
163
                        this.open();
164
                } catch (OpenException e) {
165
                        throw new RuntimeException(e);
166
                }
167
                if( METADATA_ENCODING.equalsIgnoreCase(name) ) {
168
                        return this.dbfFile.getOriginalCharset();
169
                } else if( METADATA_CODEPAGE.equalsIgnoreCase(name) ) {
170
                        return new Byte(this.dbfFile.getCodePage());
171
                }
172
                return super.getDynValue(name);
173
        }
174

    
175
        protected void initResource(DBFStoreParameters params,
176
                        DataStoreProviderServices storeServices) throws InitializeException {
177

    
178
                File theFile = getDBFParameters().getDBFFile();
179
                dbfResource =
180
                                this.createResource(FileResource.NAME,
181
                                                new Object[] { theFile.getAbsolutePath() });
182
                dbfResource.addConsumer(this);
183
        }
184

    
185
        public String getProviderName() {
186
                return NAME;
187
        }
188

    
189
        protected DBFStoreParameters getDBFParameters() {
190
                return (DBFStoreParameters) super.getParameters();
191
        }
192

    
193

    
194
        public DataServerExplorer getExplorer() throws ReadException {
195
                DataManager manager = DALLocator.getDataManager();
196
                FilesystemServerExplorerParameters params;
197
                try {
198
                        params = (FilesystemServerExplorerParameters) manager
199
                                        .createServerExplorerParameters(FilesystemServerExplorer.NAME);
200
                        params.setRoot(this.getDBFParameters().getDBFFile().getParent());
201
                        return manager.openServerExplorer(FilesystemServerExplorer.NAME,params);
202
                } catch (DataException e) {
203
                        throw new ReadException(this.getProviderName(), e);
204
                } catch (ValidateDataParametersException e) {
205
                        // TODO Auto-generated catch block
206
                        throw new ReadException(this.getProviderName(), e);
207
                }
208
        }
209

    
210
        protected FeatureProvider internalGetFeatureProviderByReference(
211
                        FeatureReferenceProviderServices reference, FeatureType featureType)
212
                        throws DataException {
213
                return this.getFeatureProviderByIndex(
214
                                ((Long) reference.getOID()).longValue(), featureType);
215
        }
216

    
217
        public void performChanges(Iterator deleteds, Iterator inserteds,
218
                        Iterator updateds, Iterator originalFeatureTypesUpdated)
219
                        throws PerformEditingException {
220

    
221
                try {
222
                        final FeatureStore store =
223
                                        this.getStoreServices().getFeatureStore();
224
                        getResource().execute(new ResourceAction() {
225

    
226
                                public Object run() throws Exception {
227
                                        FeatureSet set = null;
228
                                        DisposableIterator iter = null;
229
                                        try {
230
                                                set = store.getFeatureSet();
231
                                                DBFStoreParameters tmpParams =
232
                                                                (DBFStoreParameters) getDBFParameters().getCopy();
233

    
234
                                                File tmp_file = File.createTempFile(
235
                                                    "tmp_" + System.currentTimeMillis(), ".dbf");
236
                                                tmp_file.deleteOnExit();
237
                                                
238
                                                tmpParams.setDBFFile(tmp_file);
239

    
240
                                                writer.begin(tmpParams, store.getDefaultFeatureType(),
241
                                                                set.getSize());
242

    
243
                                                iter = set.fastIterator();
244
                                                while (iter.hasNext()) {
245
                                                        Feature feature = (Feature) iter.next();
246
                                                        writer.append(feature);
247
                                                }
248

    
249
                                                writer.end();
250

    
251
                                                try {
252
                                                        close();
253
                                                } catch (CloseException e1) {
254
                                                        throw new PerformEditingException(getProviderName(), e1);
255
                                                }
256
                                                getDBFParameters().getDBFFile().delete();
257
                                                
258
                                                File target_file = getDBFParameters().getDBFFile();
259
                                                if (target_file.exists()) {
260
                                                    target_file.delete();
261
                                                }
262
                                                tmp_file.renameTo(target_file);
263
                                                
264
                                                if (tmp_file.exists() && !target_file.exists()) {
265
                                                    // Renaming failed, let's simply copy.
266
                                                    // We assume we cannot delete it, but we
267
                                                    // used deleteOnExit and it's
268
                                                    // temporary, so no problem
269
                                                    LOG.info("Warning: copying tmp file instead of renaming: "
270
                                        + target_file.getName());
271
                                                    FileUtils.copyFile(tmp_file, target_file);
272
                                                }
273

    
274
                                                resourcesNotifyChanges();
275
                                                initFeatureType();
276
                                        } finally {
277
                                                if (set != null) {
278
                                                        set.dispose();
279
                                                }
280
                                                if (iter != null) {
281
                                                        iter.dispose();
282
                                                }
283
                                        }
284
                                        return null;
285
                                }
286
                        });
287
                } catch (ResourceExecuteException e) {
288
                        throw new PerformEditingException(this.getProviderName(), e);
289
                }
290

    
291
                this.counterNewsOIDs = -1;
292
        }
293

    
294
        /*
295
         * ==================================================
296
         */
297

    
298
        public FeatureProvider createFeatureProvider(FeatureType type) throws DataException {
299
                return new DBFFeatureProvider(this, type);
300
        }
301

    
302

    
303
        /*
304
         * ===================================================
305
         */
306

    
307

    
308

    
309
        protected void initFeatureType() throws InitializeException {
310
                try {
311
                        FeatureType defaultType =
312
                                        this.getTheFeatureType().getNotEditableCopy();
313
                        List types = new ArrayList(1);
314
                        types.add(defaultType);
315
                        this.getStoreServices().setFeatureTypes(types, defaultType);
316
                } catch (OpenException e) {
317
                        throw new InitializeException(getResource().toString(), e);
318
                }
319
        }
320

    
321
        protected EditableFeatureType getTheFeatureType()
322
                        throws InitializeException, OpenException {
323
                try {
324
                        this.open();
325
                } catch (DataException e) {
326
                        throw new InitializeException(this.getProviderName(), e);
327
                }
328
                return (EditableFeatureType) getResource().execute(
329
                                new ResourceAction() {
330

    
331
                                        public Object run() throws Exception {
332
                                                int fieldCount = -1;
333
                                                fieldCount = dbfFile.getFieldCount();
334

    
335
                                                EditableFeatureType fType =
336
                                                                getStoreServices().createFeatureType();
337

    
338
                                                fType.setHasOID(true);
339
                                                int precision;
340
                                                for (int i = 0; i < fieldCount; i++) {
341
                                                        char fieldType = dbfFile.getFieldType(i);
342
                                                        EditableFeatureAttributeDescriptor attr;
343

    
344
                                                        if (fieldType == 'L') {
345
                                                                attr =
346
                                                                                fType.add(dbfFile.getFieldName(i),
347
                                                                                                DataTypes.BOOLEAN);
348
                                                                attr.setDefaultValue(new Boolean(false));
349
                                                                attr.setAllowNull(false);
350

    
351
                                                        } else if ((fieldType == 'F') || (fieldType == 'N')) {
352
                                                                precision = dbfFile.getFieldDecimalLength(i);
353
                                                                if (precision > 0) {
354
                                                                        attr =
355
                                                                                        fType.add(dbfFile.getFieldName(i),
356
                                                                                                        DataTypes.DOUBLE,
357
                                                                                                        dbfFile.getFieldLength(i));
358
                                                                        attr.setPrecision(precision);
359
                                                                        attr.setDefaultValue(new Double(0));
360

    
361
                                                                } else {
362
                                                                    int length = dbfFile.getFieldLength(i);
363
                                                                    int type = DataTypes.INT;
364
                                                                    if (length > 9){
365
                                                                        type = DataTypes.LONG;
366
                                                                    }
367
                                                                        attr =
368
                                                                                        fType.add(dbfFile.getFieldName(i),
369
                                                                                                type,
370
                                                                                                        length);
371
                                                                        attr.setDefaultValue(new Integer(0));
372
                                                                }
373
                                                                attr.setAllowNull(false);
374

    
375
                                                        } else if (fieldType == 'C') {
376
                                                                attr =
377
                                                                                fType.add(dbfFile.getFieldName(i),
378
                                                                                                DataTypes.STRING);
379
                                                                attr.setSize(dbfFile.getFieldLength(i));
380
                                                                attr.setDefaultValue("");
381
                                                                
382
                                                                
383
                                                                attr.setAllowNull(false);
384

    
385
                                                        } else if (fieldType == 'D') {
386
                                                                attr =
387
                                                                                fType.add(dbfFile.getFieldName(i),
388
                                                                                                DataTypes.DATE);
389
                                                                /*
390
                                                                 * def value 1-1-1970
391
                                                                 */
392
                                                                attr.setDefaultValue(new Date(0));
393
                                                                attr.setAllowNull(false);
394
                                                        } else {
395
                                                                throw new InitializeException(getProviderName(),
396
                                                                                new UnknownDataTypeException(
397
                                                                                                dbfFile.getFieldName(i), ""
398
                                                                                                                + fieldType, getProviderName()));
399
                                                        }
400
                                                }
401
                                                
402
                                                // FeatureRules rules = fType.getRules();
403
                                                // rules.add(new DBFRowValidator());
404
                                                return fType;
405
                                        }
406
                                });
407
        }
408

    
409

    
410
        protected void loadValue(FeatureProvider featureProvider, int rowIndex,
411
                        FeatureAttributeDescriptor descriptor) throws ReadException {
412
            
413
                if (descriptor.getEvaluator() != null) {
414
                        // Nothing to do
415
                        return;
416
                }
417

    
418
                int dbfIndex = this.dbfFile.getFieldIndex(descriptor.getName());
419
                
420
                if (dbfIndex < 0) {
421
                    // Someone asked to load a field
422
                    // which does not exist in the DBF file. This can happen 
423
                    // in editing process when a field has been added
424
                    // in the current editing session, so we simply do nothing.
425
                    // The expansion manager is expected to manage those new fields
426
                    // and their values.
427
                    long curr_time = System.currentTimeMillis();
428
                    // This ensures not more than one log every 2 seconds
429
                    if (curr_time - lastLogTime > 2000) {
430
                        LOG.info("Warning: The requested field does not exist in the DBF file. Assumed it's a new field in editing mode.");
431
                        lastLogTime = curr_time;
432
                    }
433
                    return;
434
                }
435
                
436
                String value = null;
437
                try {
438
                        value = this.dbfFile.getStringFieldValue(rowIndex, dbfIndex);
439
                } catch (DataException e) {
440
                        throw new ReadException(this.getProviderName(), e);
441
                }
442
                value = value.trim();
443
                int fieldType = descriptor.getType();
444
                switch (fieldType) {
445
                case DataTypes.STRING:
446
                        featureProvider.set(descriptor.getIndex(), value);
447
                        break;
448

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

    
457
                case DataTypes.INT:
458
                        try {
459
                                featureProvider.set(descriptor.getIndex(), new Integer(value));
460
                        } catch (NumberFormatException e) {
461
                                featureProvider.set(descriptor.getIndex(), null);
462
                        }
463
                        break;
464

    
465
                case DataTypes.FLOAT:
466
                        try {
467
                                featureProvider.set(descriptor.getIndex(), new Float(value));
468
                        } catch (NumberFormatException e) {
469
                                featureProvider.set(descriptor.getIndex(), null);
470
                        }
471
                        break;
472

    
473
                case DataTypes.LONG:
474
                        try {
475
                                featureProvider.set(descriptor.getIndex(), new Long(value));
476
                        } catch (NumberFormatException e) {
477
                                featureProvider.set(descriptor.getIndex(), null);
478
                        }
479
                        break;
480

    
481
                case DataTypes.BOOLEAN:
482
                        if (value.equalsIgnoreCase("T")){
483
                                featureProvider.set(descriptor.getIndex(), Boolean.TRUE);
484
                        } else {
485
                                featureProvider.set(descriptor.getIndex(), Boolean.FALSE);
486
                                
487
                        }
488
                        break;
489

    
490
                case DataTypes.BYTE:
491
                        try {
492
                                featureProvider.set(descriptor.getIndex(), new Byte(value));
493
                        } catch (NumberFormatException e) {
494
                                featureProvider.set(descriptor.getIndex(), null);
495
                        }
496
                        break;
497

    
498
                case DataTypes.DATE:
499
                        if (value.equals("")){
500
                                value=null;
501
                                return;
502
                        }
503
                        String year = value.substring(0, 4);
504
                        String month = value.substring(4, 6);
505
                        String day = value.substring(6, 8);
506
                        DateFormat df;
507
                        if (descriptor.getDateFormat() == null){
508
                                df = DateFormat.getDateInstance(DateFormat.SHORT,
509
                                                ukLocale);
510
                        } else{
511
                                df = descriptor.getDateFormat();
512
                        }
513
                        /*
514
                         * Calendar c = Calendar.getInstance(); c.clear();
515
                         * c.set(Integer.parseInt(year), Integer.parseInt(month),
516
                         * Integer.parseInt(day)); c.set(Calendar.MILLISECOND, 0);
517
                         */
518
                        String strAux = month + "/" + day + "/" + year;
519
                        Date dat = null;
520
                        try {
521
                                dat = df.parse(strAux);
522
                        } catch (ParseException e) {
523
                                throw new ReadException(this.getProviderName(), e);
524
                        }
525
                        featureProvider.set(descriptor.getIndex(), dat);
526
                        break;
527

    
528

    
529
                default:
530
                        featureProvider
531
                                        .set(descriptor.getIndex(), descriptor.getDefaultValue());
532
                        break;
533
                }
534
        }
535

    
536

    
537
        /***
538
         * NOT supported in Alter Mode
539
         *
540
         * @param index
541
         * @return
542
         * @throws ReadException
543
         */
544
        protected FeatureProvider getFeatureProviderByIndex(long index) throws DataException {
545
                return this
546
                                .getFeatureProviderByIndex(index, this.getStoreServices()
547
                                .getDefaultFeatureType());
548
        }
549

    
550
        public long getFeatureCount() throws ReadException, OpenException,
551
                        ResourceNotifyChangesException {
552
                this.open();
553
                return ((Long) getResource().execute(new ResourceAction() {
554
                        public Object run() throws Exception {
555
                                return Long.valueOf(dbfFile.getRecordCount());
556
                        }
557
                })).longValue();
558
        }
559

    
560
        public FeatureSetProvider createSet(FeatureQuery query, FeatureType featureType)
561
                        throws DataException {
562
                return new DBFSetProvider(this, query, featureType);
563
        }
564

    
565
        public boolean canCreate() {
566
                return true;
567
        }
568

    
569
        public boolean canWriteGeometry(int geometryType, int geometrySubType) throws DataException {
570
                return false;
571
        }
572

    
573
        public void open() throws OpenException {
574
                if (this.dbfFile.isOpen()) {
575
                        return;
576
                }
577
                try {
578
                        getResource().execute(new ResourceAction() {
579
                                public Object run() throws Exception {
580
                                        openFile();
581
                                        resourcesOpen();
582
                                        return null;
583
                                }
584
                        });
585

    
586
                } catch (ResourceExecuteException e) {
587
                        throw new OpenException(this.getProviderName(), e);
588
                }
589
        }
590

    
591
        protected void openFile() throws FileNotFoundException,
592
                        UnsupportedVersionException, IOException, DataException {
593
                this.dbfFile.open();
594
        }
595

    
596
        public void close() throws CloseException {
597
                if (dbfFile == null || !this.dbfFile.isOpen()) {
598
                        return;
599
                }
600
                super.close();
601
                //Cerrar recurso
602
                try {
603
                        getResource().execute(new ResourceAction() {
604
                                public Object run() throws Exception {
605
                                        closeFile();
606
                                        resourcesNotifyClose();
607
                                        return null;
608
                                }
609
                        });
610
                } catch (ResourceExecuteException e) {
611
                        throw new CloseException(this.getProviderName(), e);
612
                }
613
        }
614

    
615
        protected void closeFile() throws CloseException {
616
                this.dbfFile.close();
617
        }
618

    
619
        @Override
620
        protected void doDispose() throws BaseException {
621
                this.close();
622
                dbfFile = null;
623
                disposeResource();
624
                super.doDispose();
625
        }
626

    
627
        protected void disposeResource() {
628
                this.dbfResource.removeConsumer(this);
629
                dbfResource = null;
630
        }
631

    
632
        public boolean closeResourceRequested(ResourceProvider resource) {
633
                try {
634
                        this.close();
635
                } catch (CloseException e) {
636
                        return false;
637
                }
638
                return true;
639
        }
640

    
641
        public boolean allowWrite() {
642
                File file;
643
                try {
644
                        file = ((File) this.dbfResource.get());
645
                } catch (AccessResourceException e) {
646
                        return false;
647
                }
648
                return file.canWrite();
649
        }
650

    
651
        public void refresh() throws OpenException {
652
                try {
653
                        this.close();
654
                } catch (CloseException e) {
655
                        throw new OpenException(this.getProviderName(), e);
656
                }
657
                this.open();
658
                try {
659
                        this.initFeatureType();
660
                } catch (InitializeException e) {
661
                        throw new OpenException(this.getProviderName(), e);
662
                }
663
        }
664

    
665
        /**
666
         *
667
         * @param index
668
         * @param featureType
669
         * @return
670
         * @throws ReadException
671
         */
672
        protected FeatureProvider getFeatureProviderByIndex(long index,
673
                        FeatureType featureType) throws DataException {
674
                FeatureProvider featureProvider = this.createFeatureProvider(featureType);
675
                featureProvider.setOID(new Long(index));
676
                return featureProvider;
677
        }
678

    
679
        protected void initFeatureProviderByIndex(FeatureProvider featureProvider,
680
                        long index, FeatureType featureType) throws DataException {
681
                featureProvider.setOID(new Long(index));
682
        }
683

    
684
        /**
685
         *
686
         * @param featureProvider
687
         * @throws DataException
688
         */
689
        protected void loadFeatureProviderByIndex(FeatureProvider featureProvider)
690
                        throws DataException {
691
            
692
                long index = ((Long) featureProvider.getOID()).longValue();
693
        int rec_count = this.dbfFile.getRecordCount();
694
        
695
        if (index >= rec_count) {
696

    
697
            ReadException rex = new ReadException(NAME,
698
                new ArrayIndexOutOfBoundsException(
699
                "Index of requested feature (" +
700
                index + ") is >= record count (" + rec_count + ")"));
701
            
702
            LOG.info("Error while loading feature. ", rex);
703
            throw rex;
704
        }                
705
                
706
                Iterator iterator = featureProvider.getType().iterator();
707
                while (iterator.hasNext()) {
708
                        FeatureAttributeDescriptor descriptor =
709
                                        (FeatureAttributeDescriptor) iterator.next();
710
                        this.loadValue(featureProvider, (int) index, descriptor);
711
                }
712
        }
713

    
714
        public int getOIDType() {
715
                return DataTypes.LONG;
716
        }
717

    
718
        public Object createNewOID() {
719
                if (this.counterNewsOIDs < 0) {
720
                        try {
721
                                this.counterNewsOIDs = this.getFeatureCount();
722
                        } catch (DataException e) {
723
                                e.printStackTrace();
724
                        }
725

    
726
                }else{
727
                        this.counterNewsOIDs++;
728
                }
729
                return new Long(counterNewsOIDs);
730
        }
731

    
732
        public boolean supportsAppendMode() {
733
                return true;
734
        }
735

    
736

    
737
        public void append(final FeatureProvider featureProvider)
738
                        throws DataException {
739
                getResource().execute(new ResourceAction() {
740
                        public Object run() throws Exception {
741
                                writer.append(getStoreServices().createFeature(featureProvider));
742
                                return null;
743
                        }
744
                });
745
        }
746

    
747
        public void beginAppend() throws DataException {
748
                this.close();
749
                getResource().execute(new ResourceAction() {
750
                        public Object run() throws Exception {
751
                                writer.begin(getDBFParameters(),
752
                                                getStoreServices().getDefaultFeatureType(),
753
                                                getStoreServices().getFeatureStore().getFeatureCount());
754
                                return null;
755
                        }
756
                });
757
        }
758

    
759
        public void endAppend() throws DataException {
760
                getResource().execute(new ResourceAction() {
761
                        public Object run() throws Exception {
762
                                writer.end();
763
                            resourcesNotifyChanges();
764
                                counterNewsOIDs = -1;
765
                                return null;
766
                        }
767
                });
768
        }
769

    
770
        /*
771
         * (non-Javadoc)
772
         *
773
         * @see
774
         * org.gvsig.fmap.dal.resource.spi.ResourceConsumer#resourceChanged(org.
775
         * gvsig.fmap.dal.resource.spi.ResourceProvider)
776
         */
777
        public void resourceChanged(ResourceProvider resource) {
778
                this.getStoreServices().notifyChange(
779
                                DataStoreNotification.RESOURCE_CHANGED,
780
                                resource);
781
        }
782

    
783
        /**
784
         *
785
         * @throws ResourceNotifyChangesException
786
         */
787
        protected void resourcesNotifyChanges()
788
                        throws ResourceNotifyChangesException {
789
                this.dbfResource.notifyChanges();
790
        }
791

    
792
        /**
793
         * @throws ResourceNotifyCloseException
794
         *
795
         */
796
        protected void resourcesNotifyClose() throws ResourceNotifyCloseException {
797
                this.dbfResource.notifyClose();
798
        }
799

    
800
        /**
801
         * @throws ResourceNotifyOpenException
802
         *
803
         */
804
        protected void resourcesOpen() throws ResourceNotifyOpenException {
805
                this.dbfResource.notifyOpen();
806
        }
807

    
808
        public Object getSourceId() {
809
                return this.getDBFParameters().getFile();
810
        }
811
        
812
        public String getName() {
813
                String name = this.getDBFParameters().getFile().getName();
814
                int n = name.lastIndexOf(".");
815
                if( n<1 ) {
816
                        return name;
817
                }
818
                return name.substring(0, n);
819
        }
820
        
821
        public String getFullName() {
822
                return this.getDBFParameters().getFile().getAbsolutePath();
823
        }
824

    
825
        protected void resourceCloseRequest() throws ResourceException {
826
                this.dbfResource.closeRequest();
827
        }
828

    
829
        public ResourceProvider getResource() {
830
                return dbfResource;
831
        }
832
}