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

History | View | Annotate | Download (27.9 KB)

1 40559 jjdelcerro
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6 41483 jjdelcerro
 * This program is free software; you can redistribute it and/or modify it under
7
 * the terms of the GNU General Public License as published by the Free Software
8
 * Foundation; either version 3 of the License, or (at your option) any later
9
 * version.
10 40559 jjdelcerro
 *
11 41483 jjdelcerro
 * This program is distributed in the hope that it will be useful, but WITHOUT
12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14
 * details.
15 40559 jjdelcerro
 *
16 41483 jjdelcerro
 * You should have received a copy of the GNU General Public License along with
17
 * this program; if not, write to the Free Software Foundation, Inc., 51
18
 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 40559 jjdelcerro
 *
20 41483 jjdelcerro
 * For any additional information, do not hesitate to contact us at info AT
21
 * gvsig.com, or visit our website www.gvsig.com.
22 40559 jjdelcerro
 */
23 40435 jjdelcerro
package org.gvsig.fmap.dal.store.dbf;
24
25
import java.io.File;
26
import java.io.IOException;
27 44669 jjdelcerro
import java.math.BigDecimal;
28 40435 jjdelcerro
import java.nio.charset.Charset;
29
import java.util.ArrayList;
30
import java.util.Iterator;
31
import java.util.List;
32 45387 omartinez
import java.util.logging.Level;
33 40435 jjdelcerro
34
import org.apache.commons.io.FileUtils;
35 45387 omartinez
import org.apache.commons.lang3.StringUtils;
36 42814 fdiaz
37 40435 jjdelcerro
import org.gvsig.fmap.dal.DALLocator;
38
import org.gvsig.fmap.dal.DataManager;
39
import org.gvsig.fmap.dal.DataServerExplorer;
40 44669 jjdelcerro
import org.gvsig.fmap.dal.DataStore;
41 40435 jjdelcerro
import org.gvsig.fmap.dal.DataStoreNotification;
42
import org.gvsig.fmap.dal.DataTypes;
43
import org.gvsig.fmap.dal.FileHelper;
44
import org.gvsig.fmap.dal.exception.CloseException;
45
import org.gvsig.fmap.dal.exception.DataException;
46
import org.gvsig.fmap.dal.exception.FileNotFoundException;
47
import org.gvsig.fmap.dal.exception.InitializeException;
48
import org.gvsig.fmap.dal.exception.OpenException;
49
import org.gvsig.fmap.dal.exception.ReadException;
50
import org.gvsig.fmap.dal.exception.UnsupportedVersionException;
51
import org.gvsig.fmap.dal.exception.ValidateDataParametersException;
52
import org.gvsig.fmap.dal.feature.EditableFeatureType;
53
import org.gvsig.fmap.dal.feature.Feature;
54
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
55
import org.gvsig.fmap.dal.feature.FeatureQuery;
56
import org.gvsig.fmap.dal.feature.FeatureSet;
57
import org.gvsig.fmap.dal.feature.FeatureStore;
58
import org.gvsig.fmap.dal.feature.FeatureType;
59 44871 jjdelcerro
import org.gvsig.fmap.dal.feature.FeatureType.FeatureTypeChanged;
60 40597 jldominguez
import org.gvsig.fmap.dal.feature.exception.AttributeNameException;
61
import org.gvsig.fmap.dal.feature.exception.AttributeNameTooLongException;
62 40435 jjdelcerro
import org.gvsig.fmap.dal.feature.exception.PerformEditingException;
63
import org.gvsig.fmap.dal.feature.spi.AbstractFeatureStoreProvider;
64
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
65
import org.gvsig.fmap.dal.feature.spi.FeatureReferenceProviderServices;
66
import org.gvsig.fmap.dal.feature.spi.FeatureSetProvider;
67 45387 omartinez
import org.gvsig.fmap.dal.feature.spi.FeatureStoreProviderServices;
68 40435 jjdelcerro
import org.gvsig.fmap.dal.resource.ResourceAction;
69
import org.gvsig.fmap.dal.resource.exception.ResourceException;
70
import org.gvsig.fmap.dal.resource.exception.ResourceExecuteException;
71
import org.gvsig.fmap.dal.resource.exception.ResourceNotifyChangesException;
72
import org.gvsig.fmap.dal.resource.exception.ResourceNotifyCloseException;
73
import org.gvsig.fmap.dal.resource.exception.ResourceNotifyOpenException;
74
import org.gvsig.fmap.dal.resource.file.FileResource;
75
import org.gvsig.fmap.dal.resource.spi.ResourceConsumer;
76
import org.gvsig.fmap.dal.resource.spi.ResourceProvider;
77
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorer;
78
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemServerExplorerParameters;
79
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
80
import org.gvsig.fmap.dal.store.dbf.utils.DbaseFile;
81 44669 jjdelcerro
import org.gvsig.fmap.dal.store.dbf.utils.FieldFormatter;
82 40435 jjdelcerro
import org.gvsig.metadata.MetadataLocator;
83
import org.gvsig.metadata.MetadataManager;
84
import org.gvsig.metadata.exceptions.MetadataException;
85 44472 jjdelcerro
import org.gvsig.tools.dataTypes.CoercionException;
86 40435 jjdelcerro
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 44669 jjdelcerro
import org.gvsig.tools.logger.FilteredLogger;
91 42814 fdiaz
92 42517 dmartinezizquierdo
import org.slf4j.Logger;
93
import org.slf4j.LoggerFactory;
94 40435 jjdelcerro
95
public class DBFStoreProvider extends AbstractFeatureStoreProvider implements
96 41483 jjdelcerro
        ResourceConsumer {
97 40435 jjdelcerro
98
    private static final Logger LOG = LoggerFactory.getLogger(DBFStoreProvider.class);
99
100 41746 jjdelcerro
    public static final int MAX_FIELD_NAME_LENGTH = DbaseFile.MAX_FIELD_NAME_LENGTH;
101 40435 jjdelcerro
102 44669 jjdelcerro
    public static final String NAME = DataStore.DBASE_PROVIDER_NAME;
103
    public static final String DESCRIPTION = "DBF file";
104 40435 jjdelcerro
105 41483 jjdelcerro
    public static final String METADATA_DEFINITION_NAME = NAME;
106
    private static final String METADATA_ENCODING = "Encoding";
107
    private static final String METADATA_CODEPAGE = "CodePage";
108 40435 jjdelcerro
109 41483 jjdelcerro
    private DbaseFile dbfFile = null;
110
    private ResourceProvider dbfResource;
111
    private long counterNewsOIDs = -1;
112
    private DBFFeatureWriter writer;
113 40435 jjdelcerro
114 42517 dmartinezizquierdo
    private boolean loTengoEnUso;
115
116 42814 fdiaz
    private boolean allowDuplicatedFieldNames;
117 44669 jjdelcerro
    private FilteredLogger logger;
118 45387 omartinez
119
    protected FeatureType featureType;
120 42814 fdiaz
121 45387 omartinez
122 41483 jjdelcerro
    protected static void registerMetadataDefinition() throws MetadataException {
123
        MetadataManager manager = MetadataLocator.getMetadataManager();
124
        if (manager.getDefinition(METADATA_DEFINITION_NAME) == null) {
125
            manager.addDefinition(
126
                    METADATA_DEFINITION_NAME,
127
                    DBFStoreParameters.class.getResourceAsStream("DBFStoreMetadata.xml"),
128
                    DBFStoreParameters.class.getClassLoader()
129
            );
130
        }
131
    }
132 40435 jjdelcerro
133 41483 jjdelcerro
    public DBFStoreProvider(DBFStoreParameters params,
134
            DataStoreProviderServices storeServices)
135
            throws InitializeException {
136 44840 jjdelcerro
        this(
137 41483 jjdelcerro
                params,
138
                storeServices,
139
                FileHelper.newMetadataContainer(METADATA_DEFINITION_NAME)
140
        );
141
    }
142 40435 jjdelcerro
143 41483 jjdelcerro
    protected DBFStoreProvider(DBFStoreParameters params,
144
            DataStoreProviderServices storeServices, DynObject metadata)
145
            throws InitializeException {
146
        super(params, storeServices, metadata);
147 44840 jjdelcerro
        this.logger = new FilteredLogger(LOG, "DBFStoreProvider", -1);
148
        this.logger.setInterval(2000);
149 41483 jjdelcerro
        this.init(params, storeServices);
150
    }
151 40435 jjdelcerro
152 41483 jjdelcerro
    protected void init(DBFStoreParameters params,
153
            DataStoreProviderServices storeServices) throws InitializeException {
154
        if (params == null) {
155
            throw new InitializeException(new NullPointerException("params is null"));
156
        }
157
        File theFile = getDBFParameters().getDBFFile();
158
        if (theFile == null) {
159
            throw new InitializeException(new NullPointerException("dbf file is null"));
160
        }
161
        initResource(params, storeServices);
162 40435 jjdelcerro
163 41483 jjdelcerro
        Charset charset = params.getEncoding();
164 42814 fdiaz
        allowDuplicatedFieldNames = params.allowDuplicatedFieldNames();
165
        this.dbfFile = new DbaseFile(theFile, charset, allowDuplicatedFieldNames);
166 40435 jjdelcerro
167 41483 jjdelcerro
        writer = new DBFFeatureWriter(this.getProviderName());
168 40435 jjdelcerro
169 41483 jjdelcerro
        this.initFeatureType();
170 40435 jjdelcerro
171 41483 jjdelcerro
    }
172 40435 jjdelcerro
173 41483 jjdelcerro
    public Object getDynValue(String name) throws DynFieldNotFoundException {
174
        try {
175
            this.open();
176
        } catch (OpenException e) {
177
            throw new RuntimeException(e);
178
        }
179 42517 dmartinezizquierdo
180 41483 jjdelcerro
        if (METADATA_ENCODING.equalsIgnoreCase(name)) {
181
            return this.dbfFile.getOriginalCharset();
182
        } else if (METADATA_CODEPAGE.equalsIgnoreCase(name)) {
183 44669 jjdelcerro
            return this.dbfFile.getCodePageInt();
184 41483 jjdelcerro
        }
185
        return super.getDynValue(name);
186
    }
187 40435 jjdelcerro
188 41483 jjdelcerro
    protected void initResource(DBFStoreParameters params,
189
            DataStoreProviderServices storeServices) throws InitializeException {
190 40435 jjdelcerro
191 41483 jjdelcerro
        File theFile = getDBFParameters().getDBFFile();
192
        dbfResource
193
                = this.createResource(FileResource.NAME,
194
                        new Object[]{theFile.getAbsolutePath()});
195
        dbfResource.addConsumer(this);
196
    }
197 40435 jjdelcerro
198 42814 fdiaz
    protected void initResource(ResourceProvider resource,
199
        DataStoreProviderServices storeServices){
200
        dbfResource = resource;
201
        dbfResource.addConsumer(this);
202
    }
203
204 41483 jjdelcerro
    public String getProviderName() {
205
        return NAME;
206
    }
207 40435 jjdelcerro
208 41483 jjdelcerro
    protected DBFStoreParameters getDBFParameters() {
209
        return (DBFStoreParameters) super.getParameters();
210
    }
211 40435 jjdelcerro
212 41483 jjdelcerro
    public DataServerExplorer getExplorer() throws ReadException {
213
        DataManager manager = DALLocator.getDataManager();
214
        FilesystemServerExplorerParameters params;
215
        try {
216
            params = (FilesystemServerExplorerParameters) manager
217
                    .createServerExplorerParameters(FilesystemServerExplorer.NAME);
218
            params.setRoot(this.getDBFParameters().getDBFFile().getParent());
219
            return manager.openServerExplorer(FilesystemServerExplorer.NAME, params);
220 44669 jjdelcerro
        } catch (DataException | ValidateDataParametersException e) {
221 42811 jjdelcerro
            throw new ReadException(this.getName(), e);
222 41483 jjdelcerro
        }
223
    }
224 40435 jjdelcerro
225 41483 jjdelcerro
    protected FeatureProvider internalGetFeatureProviderByReference(
226
            FeatureReferenceProviderServices reference, FeatureType featureType)
227
            throws DataException {
228
        return this.getFeatureProviderByIndex(
229 43356 fdiaz
                ((Number) reference.getOID()).longValue(), featureType);
230 41483 jjdelcerro
    }
231 40435 jjdelcerro
232 41483 jjdelcerro
    public void performChanges(Iterator deleteds, Iterator inserteds,
233
            Iterator updateds, Iterator originalFeatureTypesUpdated)
234
            throws PerformEditingException {
235 40435 jjdelcerro
236 41483 jjdelcerro
        /*
237
         * This will throw an exception if there are new fields
238
         * with names too long
239
         */
240
        checkNewFieldsNameSize(originalFeatureTypesUpdated);
241 40435 jjdelcerro
242 41483 jjdelcerro
        try {
243 42517 dmartinezizquierdo
            // TODO repasar el concepto de enUso de un recurso.
244
            loTengoEnUso = true;
245 44669 jjdelcerro
            final FeatureStore theStore = this.getStoreServices().getFeatureStore();
246 42517 dmartinezizquierdo
            resourceCloseRequest();
247 41483 jjdelcerro
            getResource().execute(new ResourceAction() {
248 40435 jjdelcerro
249 41483 jjdelcerro
                public Object run() throws Exception {
250
                    FeatureSet set = null;
251
                    DisposableIterator iter = null;
252
                    try {
253 44669 jjdelcerro
                        set = theStore.getFeatureSet();
254 41483 jjdelcerro
                        DBFStoreParameters tmpParams
255
                                = (DBFStoreParameters) getDBFParameters().getCopy();
256 40435 jjdelcerro
257 41483 jjdelcerro
                        File tmp_file = File.createTempFile(
258
                                "tmp_" + System.currentTimeMillis(), ".dbf");
259
                        tmp_file.deleteOnExit();
260 40435 jjdelcerro
261 41483 jjdelcerro
                        tmpParams.setDBFFile(tmp_file);
262 40435 jjdelcerro
263 44669 jjdelcerro
                        writer.begin(tmpParams, theStore.getDefaultFeatureType(),
264 41483 jjdelcerro
                                set.getSize());
265 40435 jjdelcerro
266 41483 jjdelcerro
                        iter = set.fastIterator();
267
                        while (iter.hasNext()) {
268
                            Feature feature = (Feature) iter.next();
269
                            writer.append(feature);
270
                        }
271 40435 jjdelcerro
272 41483 jjdelcerro
                        writer.end();
273 42517 dmartinezizquierdo
                        loTengoEnUso = false;
274 41483 jjdelcerro
                        try {
275
                            close();
276
                        } catch (CloseException e1) {
277
                            throw new PerformEditingException(getProviderName(), e1);
278
                        }
279
                        getDBFParameters().getDBFFile().delete();
280 40435 jjdelcerro
281 41483 jjdelcerro
                        File target_file = getDBFParameters().getDBFFile();
282
                        if (target_file.exists()) {
283
                            target_file.delete();
284
                        }
285
                        tmp_file.renameTo(target_file);
286 40435 jjdelcerro
287 41483 jjdelcerro
                        if (tmp_file.exists() && !target_file.exists()) {
288
                            // Renaming failed, let's simply copy.
289
                            // We assume we cannot delete it, but we
290
                            // used deleteOnExit and it's
291
                            // temporary, so no problem
292
                            LOG.info("Warning: copying tmp file instead of renaming: "
293
                                    + target_file.getName());
294
                            FileUtils.copyFile(tmp_file, target_file);
295
                        }
296 40435 jjdelcerro
297 41483 jjdelcerro
                        resourcesNotifyChanges();
298
                        initFeatureType();
299
                    } finally {
300 42517 dmartinezizquierdo
                        loTengoEnUso = false;
301 41483 jjdelcerro
                        if (set != null) {
302
                            set.dispose();
303
                        }
304
                        if (iter != null) {
305
                            iter.dispose();
306
                        }
307
                    }
308
                    return null;
309
                }
310
            });
311 42517 dmartinezizquierdo
        } catch (ResourceExecuteException | ResourceException e) {
312 44669 jjdelcerro
            throw new PerformEditingException(NAME, e);
313 41483 jjdelcerro
        }
314 40435 jjdelcerro
315 41483 jjdelcerro
        this.counterNewsOIDs = -1;
316
    }
317 40435 jjdelcerro
318 41483 jjdelcerro
    protected void checkNewFieldsNameSize(Iterator ft_upd) throws PerformEditingException {
319 40435 jjdelcerro
320 41483 jjdelcerro
        String long_fields = getNewFieldsWithNameTooLong(ft_upd);
321
        if (long_fields != null) {
322
            AttributeNameException ane = new AttributeNameTooLongException(
323
                    long_fields,
324
                    getProviderName(),
325
                    MAX_FIELD_NAME_LENGTH);
326
            throw new PerformEditingException(getProviderName(), ane);
327
        }
328
    }
329 40435 jjdelcerro
330 41483 jjdelcerro
    /**
331
     * Returns null or a string which is a comma-separated list
332
     *
333
     * @param ft_updated
334
     * @return
335
     */
336
    protected String getNewFieldsWithNameTooLong(Iterator ft_updated) {
337 40435 jjdelcerro
338 41483 jjdelcerro
        String resp = "";
339 44669 jjdelcerro
        FeatureTypeChanged item;
340
        FeatureType ft;
341
        FeatureAttributeDescriptor[] atts;
342 41483 jjdelcerro
        while (ft_updated.hasNext()) {
343
            item = (FeatureTypeChanged) ft_updated.next();
344
            ft = item.getTarget();
345
            atts = ft.getAttributeDescriptors();
346 44669 jjdelcerro
            for (FeatureAttributeDescriptor att : atts) {
347
                if (att.getName().length() > MAX_FIELD_NAME_LENGTH) {
348 41483 jjdelcerro
                    if (resp.length() == 0) {
349 44669 jjdelcerro
                        resp = att.getName();
350 41483 jjdelcerro
                    } else {
351 44669 jjdelcerro
                        resp = resp + ", " + att.getName();
352 41483 jjdelcerro
                    }
353
                }
354
            }
355
        }
356 40435 jjdelcerro
357 41483 jjdelcerro
        if (resp.length() == 0) {
358
            return null;
359
        } else {
360
            return "(" + resp + ")";
361
        }
362
    }
363 40435 jjdelcerro
364 41483 jjdelcerro
    public FeatureProvider createFeatureProvider(FeatureType type) throws DataException {
365
        return new DBFFeatureProvider(this, type);
366
    }
367 40435 jjdelcerro
368 41483 jjdelcerro
    protected void initFeatureType() throws InitializeException {
369 44669 jjdelcerro
        FeatureType defaultType = this.getTheFeatureType().getNotEditableCopy();
370 45387 omartinez
        this.setFeatureType(defaultType);
371 41483 jjdelcerro
    }
372 40435 jjdelcerro
373 45387 omartinez
    private void setFeatureType(FeatureType ftype) {
374
        FeatureStoreProviderServices store = this.getStoreServices();
375
        List<FeatureType> ftypes = new ArrayList<>();
376
        ftypes.add(ftype);
377
        this.featureType = ftype;
378
        store.setFeatureTypes(ftypes, ftype);
379
    }
380
381 44669 jjdelcerro
    protected EditableFeatureType getTheFeatureType() throws InitializeException {
382 41483 jjdelcerro
        try {
383
            this.open();
384
        } catch (DataException e) {
385
            throw new InitializeException(this.getProviderName(), e);
386
        }
387 44669 jjdelcerro
        EditableFeatureType featureType = (EditableFeatureType) getResource().execute(
388
            new ResourceAction() {
389
                public Object run() throws Exception {
390
                    EditableFeatureType featureType = getStoreServices().createFeatureType(getName());
391
                    featureType.setHasOID(true);
392
                    dbfFile.getHeader().toFeatureType(
393
                            featureType,
394
                            getDBFParameters().handleDatesAsStrings()
395
                    );
396
                    return featureType;
397 41483 jjdelcerro
                }
398 44669 jjdelcerro
            }
399 41483 jjdelcerro
        );
400 44669 jjdelcerro
        return featureType;
401 41483 jjdelcerro
    }
402 44669 jjdelcerro
403
404 44001 omartinez
    protected void loadValue(FeatureProvider featureProvider, long rowIndex,
405 41483 jjdelcerro
            FeatureAttributeDescriptor descriptor) throws ReadException {
406 40435 jjdelcerro
407 41483 jjdelcerro
        if (descriptor.getEvaluator() != null) {
408
            // Nothing to do
409
            return;
410
        }
411 40435 jjdelcerro
412 44669 jjdelcerro
        int dbfFieldIndex = this.dbfFile.getFieldIndex(descriptor.getName());
413 40435 jjdelcerro
414 44669 jjdelcerro
        if (dbfFieldIndex < 0) {
415 41483 jjdelcerro
            // Someone asked to load a field
416 42517 dmartinezizquierdo
            // which does not exist in the DBF file. This can happen
417 41483 jjdelcerro
            // in editing process when a field has been added
418
            // in the current editing session, so we simply do nothing.
419
            // The expansion manager is expected to manage those new fields
420
            // and their values.
421 44669 jjdelcerro
            this.logger.warn("The requested field ("+descriptor.getName()+") does not exist in the DBF file. Assumed it's a new field in editing mode.");
422 41483 jjdelcerro
            return;
423
        }
424 40435 jjdelcerro
425 41483 jjdelcerro
        String value = null;
426
        try {
427 44669 jjdelcerro
            value = this.dbfFile.getStringFieldValue(rowIndex, dbfFieldIndex);
428 41483 jjdelcerro
        } catch (DataException e) {
429 42811 jjdelcerro
            throw new ReadException(this.getName(), e);
430 41483 jjdelcerro
        }
431
        value = value.trim();
432 44669 jjdelcerro
        FieldFormatter formatter = new FieldFormatter();
433
434
        int index = descriptor.getIndex();
435
        Object defaultValue = descriptor.getDefaultValueCoerced();
436
437
        switch (descriptor.getType()) {
438 41483 jjdelcerro
            case DataTypes.STRING:
439 44669 jjdelcerro
                featureProvider.set(index, formatter.parseString(value, (String) defaultValue));
440 41483 jjdelcerro
                break;
441 40435 jjdelcerro
442 44669 jjdelcerro
            case DataTypes.DECIMAL:
443
                featureProvider.set(index,
444
                    formatter.parseDecimal(
445
                        value,
446
                        descriptor.getMathContext(),
447
                        descriptor.getScale(),
448
                        (BigDecimal) defaultValue
449
                  )
450
                );
451 41483 jjdelcerro
                break;
452 40435 jjdelcerro
453 44669 jjdelcerro
            case DataTypes.DOUBLE:
454
                featureProvider.set(index, formatter.parseDouble(value, (Double) defaultValue));
455 41483 jjdelcerro
                break;
456 40435 jjdelcerro
457 41483 jjdelcerro
            case DataTypes.FLOAT:
458 44669 jjdelcerro
                featureProvider.set(index, formatter.parseFloat(value, (Float) defaultValue));
459 41483 jjdelcerro
                break;
460 40435 jjdelcerro
461 41483 jjdelcerro
            case DataTypes.LONG:
462 44669 jjdelcerro
                featureProvider.set(index, formatter.parseLong(value, (Long) defaultValue));
463 41483 jjdelcerro
                break;
464 40435 jjdelcerro
465 44669 jjdelcerro
            case DataTypes.INT:
466
                featureProvider.set(index, formatter.parseInt(value, (Integer) defaultValue));
467 41483 jjdelcerro
                break;
468 40435 jjdelcerro
469 41483 jjdelcerro
            case DataTypes.BYTE:
470 44669 jjdelcerro
                featureProvider.set(index, formatter.parseByte(value, (Byte) defaultValue));
471 41483 jjdelcerro
                break;
472 40435 jjdelcerro
473 44669 jjdelcerro
            case DataTypes.BOOLEAN:
474
                featureProvider.set(index, formatter.parseBoolean(value, (Boolean) defaultValue));
475
                break;
476
477
            case DataTypes.TIMESTAMP:
478 44767 jjdelcerro
                featureProvider.set(index, formatter.parseTimestamp(value, (java.sql.Timestamp) defaultValue));
479 44669 jjdelcerro
                break;
480
481
            case DataTypes.TIME:
482 44767 jjdelcerro
                featureProvider.set(index, formatter.parseTime(value, (java.sql.Time) defaultValue));
483 44669 jjdelcerro
                break;
484
485 41483 jjdelcerro
            case DataTypes.DATE:
486 44767 jjdelcerro
                featureProvider.set(index, formatter.parseDate(value, (java.sql.Date) defaultValue));
487 41483 jjdelcerro
                break;
488 40435 jjdelcerro
489 44472 jjdelcerro
            default: {
490
                    Object v;
491
                    try {
492
                        v = descriptor.getDataType().coerce(value);
493
                    } catch (CoercionException ex) {
494 44669 jjdelcerro
                        v = defaultValue;
495 44472 jjdelcerro
                    }
496 44669 jjdelcerro
                    featureProvider.set(index, v);
497 44472 jjdelcerro
                }
498 41483 jjdelcerro
                break;
499
        }
500
    }
501 40435 jjdelcerro
502 41483 jjdelcerro
    protected FeatureProvider getFeatureProviderByIndex(long index) throws DataException {
503
        return this
504
                .getFeatureProviderByIndex(index, this.getStoreServices()
505
                        .getDefaultFeatureType());
506
    }
507 40435 jjdelcerro
508 41483 jjdelcerro
    public long getFeatureCount() throws ReadException, OpenException,
509
            ResourceNotifyChangesException {
510
        this.open();
511 44669 jjdelcerro
        return (long) getResource().execute(new ResourceAction() {
512 41483 jjdelcerro
            public Object run() throws Exception {
513 44669 jjdelcerro
                return (long) dbfFile.getRecordCount();
514 41483 jjdelcerro
            }
515 44669 jjdelcerro
        });
516 41483 jjdelcerro
    }
517 40435 jjdelcerro
518 41483 jjdelcerro
    public FeatureSetProvider createSet(FeatureQuery query, FeatureType featureType)
519
            throws DataException {
520
        return new DBFSetProvider(this, query, featureType);
521
    }
522 40435 jjdelcerro
523 41483 jjdelcerro
    public boolean canCreate() {
524
        return true;
525
    }
526 40435 jjdelcerro
527 41483 jjdelcerro
    public boolean canWriteGeometry(int geometryType, int geometrySubType) throws DataException {
528
        return false;
529
    }
530 40435 jjdelcerro
531 41483 jjdelcerro
    public void open() throws OpenException {
532
        if (this.dbfFile.isOpen()) {
533
            return;
534
        }
535
        try {
536
            getResource().execute(new ResourceAction() {
537
                public Object run() throws Exception {
538
                    openFile();
539
                    resourcesOpen();
540
                    return null;
541
                }
542
            });
543 40435 jjdelcerro
544 41483 jjdelcerro
        } catch (ResourceExecuteException e) {
545
            throw new OpenException(this.getProviderName(), e);
546
        }
547
    }
548 40435 jjdelcerro
549 41483 jjdelcerro
    protected void openFile() throws FileNotFoundException,
550
            UnsupportedVersionException, IOException, DataException {
551
        this.dbfFile.open();
552 43245 jjdelcerro
        // necessary when editing the file
553
        this.getDBFParameters().setEffectiveEncoding(this.dbfFile.getCharsetName());
554 41483 jjdelcerro
    }
555 40435 jjdelcerro
556 41483 jjdelcerro
    public void close() throws CloseException {
557 42517 dmartinezizquierdo
        if( loTengoEnUso ) {
558
            return;
559
        }
560 41483 jjdelcerro
        if (dbfFile == null || !this.dbfFile.isOpen()) {
561
            return;
562
        }
563
        super.close();
564 42517 dmartinezizquierdo
565 41483 jjdelcerro
        //Cerrar recurso
566
        try {
567
            getResource().execute(new ResourceAction() {
568
                public Object run() throws Exception {
569
                    closeFile();
570
                    resourcesNotifyClose();
571
                    return null;
572
                }
573
            });
574 42517 dmartinezizquierdo
        } catch (ResourceExecuteException  e) {
575 41483 jjdelcerro
            throw new CloseException(this.getProviderName(), e);
576
        }
577
    }
578
579
    protected void closeFile() throws CloseException {
580
        this.dbfFile.close();
581
    }
582
583
    @Override
584
    protected void doDispose() throws BaseException {
585
        this.close();
586
        dbfFile = null;
587
        disposeResource();
588
        super.doDispose();
589
    }
590
591
    protected void disposeResource() {
592
        this.dbfResource.removeConsumer(this);
593
        dbfResource = null;
594
    }
595
596
    public boolean closeResourceRequested(ResourceProvider resource) {
597
        try {
598
            this.close();
599
        } catch (CloseException e) {
600
            return false;
601
        }
602
        return true;
603
    }
604
605
    public boolean allowWrite() {
606 42814 fdiaz
        if(allowDuplicatedFieldNames){
607 41483 jjdelcerro
            return false;
608
        }
609 42814 fdiaz
        return this.dbfFile.isWritable();
610 41483 jjdelcerro
    }
611
612
    public void refresh() throws OpenException {
613
        try {
614
            this.close();
615
        } catch (CloseException e) {
616
            throw new OpenException(this.getProviderName(), e);
617
        }
618
        this.open();
619
        try {
620
            this.initFeatureType();
621
        } catch (InitializeException e) {
622
            throw new OpenException(this.getProviderName(), e);
623
        }
624
    }
625
626
    /**
627
     *
628
     * @param index
629
     * @param featureType
630
     * @return
631
     * @throws ReadException
632
     */
633
    protected FeatureProvider getFeatureProviderByIndex(long index,
634
            FeatureType featureType) throws DataException {
635
        FeatureProvider featureProvider = this.createFeatureProvider(featureType);
636 44669 jjdelcerro
        featureProvider.setOID(index);
637 41483 jjdelcerro
        return featureProvider;
638
    }
639
640
    protected void initFeatureProviderByIndex(FeatureProvider featureProvider,
641
            long index, FeatureType featureType) throws DataException {
642 44669 jjdelcerro
        featureProvider.setOID(index);
643 41483 jjdelcerro
    }
644
645
    /**
646
     *
647
     * @param featureProvider
648
     * @throws DataException
649
     */
650
    protected void loadFeatureProviderByIndex(FeatureProvider featureProvider)
651
            throws DataException {
652
653 44001 omartinez
        long index = ((Long) featureProvider.getOID());
654 40435 jjdelcerro
        int rec_count = this.dbfFile.getRecordCount();
655 41483 jjdelcerro
656 40435 jjdelcerro
        if (index >= rec_count) {
657
658 42811 jjdelcerro
            ReadException rex = new ReadException(this.getName(),
659 41483 jjdelcerro
                    new ArrayIndexOutOfBoundsException(
660
                            "Index of requested feature ("
661
                            + index + ") is >= record count (" + rec_count + ")"));
662
663 40435 jjdelcerro
            LOG.info("Error while loading feature. ", rex);
664
            throw rex;
665 41483 jjdelcerro
        }
666 40435 jjdelcerro
667 44669 jjdelcerro
        for (FeatureAttributeDescriptor desc : featureProvider.getType()) {
668
            this.loadValue(featureProvider, index, desc);
669 41483 jjdelcerro
        }
670
    }
671 40435 jjdelcerro
672 41483 jjdelcerro
    public int getOIDType() {
673
        return DataTypes.LONG;
674
    }
675 40435 jjdelcerro
676 41483 jjdelcerro
    public Object createNewOID() {
677
        if (this.counterNewsOIDs < 0) {
678
            try {
679
                this.counterNewsOIDs = this.getFeatureCount();
680
            } catch (DataException e) {
681 44669 jjdelcerro
                LOG.warn("Can't initialice counter for news OIDs.",e);
682 41483 jjdelcerro
            }
683 40435 jjdelcerro
684 41483 jjdelcerro
        } else {
685
            this.counterNewsOIDs++;
686
        }
687 44669 jjdelcerro
        return counterNewsOIDs;
688 41483 jjdelcerro
    }
689 40435 jjdelcerro
690 41483 jjdelcerro
    public boolean supportsAppendMode() {
691
        return true;
692
    }
693 40435 jjdelcerro
694 41483 jjdelcerro
    public void append(final FeatureProvider featureProvider)
695
            throws DataException {
696
        getResource().execute(new ResourceAction() {
697
            public Object run() throws Exception {
698
                writer.append(getStoreServices().createFeature(featureProvider));
699
                return null;
700
            }
701
        });
702
    }
703 40435 jjdelcerro
704 41483 jjdelcerro
    public void beginAppend() throws DataException {
705
        this.close();
706
        getResource().execute(new ResourceAction() {
707
            public Object run() throws Exception {
708
                writer.begin(getDBFParameters(),
709
                        getStoreServices().getDefaultFeatureType(),
710
                        getStoreServices().getFeatureStore().getFeatureCount());
711
                return null;
712
            }
713
        });
714
    }
715 40435 jjdelcerro
716 41483 jjdelcerro
    public void endAppend() throws DataException {
717
        getResource().execute(new ResourceAction() {
718
            public Object run() throws Exception {
719
                writer.end();
720
                resourcesNotifyChanges();
721
                counterNewsOIDs = -1;
722
                return null;
723
            }
724
        });
725
    }
726 40435 jjdelcerro
727 41483 jjdelcerro
    public void resourceChanged(ResourceProvider resource) {
728 42625 dmartinezizquierdo
        if (this.getStoreServices()!=null){
729
            this.getStoreServices().notifyChange(
730
                    DataStoreNotification.RESOURCE_CHANGED,
731
                    resource);
732
        }
733 41483 jjdelcerro
    }
734 40435 jjdelcerro
735 41483 jjdelcerro
    /**
736
     *
737
     * @throws ResourceNotifyChangesException
738
     */
739
    protected void resourcesNotifyChanges()
740
            throws ResourceNotifyChangesException {
741
        this.dbfResource.notifyChanges();
742
    }
743 40435 jjdelcerro
744 41483 jjdelcerro
    /**
745
     * @throws ResourceNotifyCloseException
746
     *
747
     */
748
    protected void resourcesNotifyClose() throws ResourceNotifyCloseException {
749
        this.dbfResource.notifyClose();
750
    }
751 40435 jjdelcerro
752 41483 jjdelcerro
    /**
753
     * @throws ResourceNotifyOpenException
754
     *
755
     */
756
    protected void resourcesOpen() throws ResourceNotifyOpenException {
757
        this.dbfResource.notifyOpen();
758
    }
759 40435 jjdelcerro
760 41483 jjdelcerro
    public Object getSourceId() {
761
        return this.getDBFParameters().getFile();
762
    }
763 40435 jjdelcerro
764 41483 jjdelcerro
    public String getName() {
765
        String name = this.getDBFParameters().getFile().getName();
766
        int n = name.lastIndexOf(".");
767
        if (n < 1) {
768
            return name;
769
        }
770
        return name.substring(0, n);
771
    }
772 40435 jjdelcerro
773 41483 jjdelcerro
    public String getFullName() {
774
        return this.getDBFParameters().getFile().getAbsolutePath();
775
    }
776
777
    protected void resourceCloseRequest() throws ResourceException {
778
        this.dbfResource.closeRequest();
779
    }
780
781
    public ResourceProvider getResource() {
782
        return dbfResource;
783
    }
784 45387 omartinez
785
    @Override
786
    public void fixFeatureTypeFromParameters() {
787
        FeatureStoreProviderServices store = this.getStoreServices();
788
        try {
789
            int sizeWithoutComputed = 0;
790
            for (FeatureAttributeDescriptor featureAttributeDescriptor : store.getDefaultFeatureType()) {
791
                if (featureAttributeDescriptor.isComputed()) {
792
                    continue;
793
                }
794
                sizeWithoutComputed +=1;
795
            }
796
            if(this.featureType.size()!=sizeWithoutComputed) {
797
                this.setFeatureType(featureType);
798
            }
799
        } catch (DataException ex) {
800
801
        }
802
    }
803 43245 jjdelcerro
804 41483 jjdelcerro
}