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.shp / src / main / java / org / gvsig / fmap / dal / store / shp / SHPStoreProvider.java @ 46897

History | View | Annotate | Download (24.4 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 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
 *
11
 * 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
 *
16
 * 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
 *
20
 * For any additional information, do not hesitate to contact us at info AT
21
 * gvsig.com, or visit our website www.gvsig.com.
22
 */
23
package org.gvsig.fmap.dal.store.shp;
24

    
25
import java.io.File;
26
import java.io.IOException;
27
import java.util.ArrayList;
28
import java.util.Iterator;
29
import java.util.List;
30
import java.util.logging.Level;
31

    
32
import org.apache.commons.io.FileUtils;
33
import org.apache.commons.io.FilenameUtils;
34
import org.cresques.cts.IProjection;
35
import org.slf4j.Logger;
36
import org.slf4j.LoggerFactory;
37

    
38
import org.gvsig.fmap.dal.DataStore;
39
import org.gvsig.fmap.dal.DataTypes;
40
import org.gvsig.fmap.dal.FileHelper;
41
import org.gvsig.fmap.dal.exception.CloseException;
42
import org.gvsig.fmap.dal.exception.DataException;
43
import org.gvsig.fmap.dal.exception.InitializeException;
44
import org.gvsig.fmap.dal.exception.ReadException;
45
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
46
import org.gvsig.fmap.dal.feature.EditableFeatureType;
47
import org.gvsig.fmap.dal.feature.Feature;
48
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
49
import org.gvsig.fmap.dal.feature.FeatureSet;
50
import org.gvsig.fmap.dal.feature.FeatureStore;
51
import org.gvsig.fmap.dal.feature.FeatureType;
52
import org.gvsig.fmap.dal.feature.exception.PerformEditingException;
53
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
54
import org.gvsig.fmap.dal.feature.spi.FeatureStoreProviderServices;
55
import org.gvsig.fmap.dal.resource.ResourceAction;
56
import org.gvsig.fmap.dal.resource.exception.ResourceException;
57
import org.gvsig.fmap.dal.resource.exception.ResourceExecuteException;
58
import org.gvsig.fmap.dal.resource.exception.ResourceNotifyChangesException;
59
import org.gvsig.fmap.dal.resource.exception.ResourceNotifyCloseException;
60
import org.gvsig.fmap.dal.resource.exception.ResourceNotifyOpenException;
61
import org.gvsig.fmap.dal.resource.file.FileResource;
62
import org.gvsig.fmap.dal.resource.spi.MultiResource;
63
import org.gvsig.fmap.dal.resource.spi.ResourceProvider;
64
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
65
import org.gvsig.fmap.dal.store.dbf.DBFStoreParameters;
66
import org.gvsig.fmap.dal.store.dbf.DBFStoreProvider;
67
import org.gvsig.fmap.dal.store.shp.utils.ISHPFile;
68
import org.gvsig.fmap.dal.store.shp.utils.SHP;
69
import org.gvsig.fmap.dal.store.shp.utils.SHPFile2;
70
import org.gvsig.fmap.geom.Geometry;
71
import org.gvsig.fmap.geom.GeometryLocator;
72
import org.gvsig.fmap.geom.GeometryManager;
73
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
74
import org.gvsig.fmap.geom.exception.CreateGeometryException;
75
import org.gvsig.fmap.geom.primitive.Envelope;
76
import org.gvsig.fmap.geom.type.GeometryType;
77
import org.gvsig.tools.dispose.DisposableIterator;
78
import org.gvsig.tools.dynobject.exception.DynFieldNotFoundException;
79
import org.gvsig.tools.exception.BaseException;
80

    
81
/**
82
 *
83
 */
84
public class SHPStoreProvider extends DBFStoreProvider {
85

    
86
    private static final GeometryManager GEOM_MANAGER = GeometryLocator.getGeometryManager();
87
    private static final Logger LOGGER = LoggerFactory.getLogger(SHPStoreProvider.class);
88
    
89
    public static String NAME = DataStore.SHAPE_PROVIDER_NAME;
90
    public static String DESCRIPTION = "Shape file";
91
    private ISHPFile shpFile;
92

    
93
    private MultiResource resource;
94

    
95
    public static final String GEOMETRY_ATTIBUTE_NAME = "GEOMETRY";
96

    
97
    public static final String METADATA_DEFINITION_NAME = NAME;
98

    
99
    private SHPFeatureWriter writer = null;
100

    
101
    private boolean loTengoEnUso;
102

    
103
    /**
104
     * @param params
105
     * @param storeServices
106
     * @throws InitializeException
107
     */
108
    public SHPStoreProvider(SHPStoreParameters params, DataStoreProviderServices storeServices)
109
        throws InitializeException {
110
        super(params, storeServices, FileHelper.newMetadataContainer(METADATA_DEFINITION_NAME));
111
    }
112

    
113
    protected void init(DBFStoreParameters params, DataStoreProviderServices storeServices) throws InitializeException {
114

    
115
        this.shpFile = new SHPFile2((SHPStoreParameters) params);
116
        super.init(params, storeServices);
117
        this.shpFile.setUseNullGeometry(this.getShpParameters().getUseNullGeometry());
118
    }
119

    
120
    @Override
121
    public SHPStoreParameters getParameters() {
122
        return (SHPStoreParameters) super.getParameters();
123
    }
124

    
125
    public IProjection getProjection() {
126
        return this.getShpParameters().getCRS();
127
    }
128
    
129
    @Override
130
    public Object getDynValue(String name) throws DynFieldNotFoundException {
131
        if (DataStore.METADATA_CRS.equalsIgnoreCase(name)) {
132

    
133
            return this.getShpParameters().getCRS();
134

    
135
        } else if (DataStore.METADATA_ENVELOPE.equalsIgnoreCase(name)) {
136
            try {
137
                return this.shpFile.getFullExtent();
138
            } catch (ReadException e) {
139
                return null;
140
            }
141
        }
142
        return super.getDynValue(name);
143
    }
144

    
145
    @Override
146
    public boolean hasDynValue(String name) throws DynFieldNotFoundException {
147
        if (DataStore.METADATA_CRS.equalsIgnoreCase(name)) {
148

    
149
            return this.getShpParameters().getCRS() != null;
150

    
151
        } else if (DataStore.METADATA_ENVELOPE.equalsIgnoreCase(name)) {
152
            try {
153
                return this.shpFile.getFullExtent() != null;
154
            } catch (ReadException e) {
155
                return false;
156
            }
157
        }
158
        return super.hasDynValue(name);
159
    }
160

    
161
    protected void initResource(DBFStoreParameters params, DataStoreProviderServices storeServices)
162
        throws InitializeException {
163

    
164
        SHPStoreParameters shpParams = (SHPStoreParameters) params;
165
        resource = (MultiResource) createResource(MultiResource.TYPE_NAME, new Object[] { shpParams.getSHPFileName() });
166

    
167
        resource.addResource(FileResource.NAME, new Object[] { shpParams.getSHPFileName() }, true);
168
        resource.addResource(FileResource.NAME, new Object[] { shpParams.getSHXFileName() }, true);
169
        resource.addResource(FileResource.NAME, new Object[] { shpParams.getDBFFileName() }, true);
170

    
171
        resource.frozen();
172
        resource.addMultiResourceConsumer(this);
173
        super.initResource(resource, storeServices);
174
    }
175

    
176
    ;
177

    
178
    public ResourceProvider getResource() {
179
        return resource;
180
    }
181

    
182
    /**
183
     *
184
     * @throws ResourceNotifyChangesException
185
     */
186
    protected void resourcesNotifyChanges() throws ResourceNotifyChangesException {
187
        getResource().notifyChanges();
188
        // TODO .prj
189

    
190
    }
191

    
192
    /**
193
     * @throws ResourceNotifyCloseException
194
     *
195
     */
196
    protected void resourcesNotifyClose() throws ResourceNotifyCloseException {
197
        getResource().notifyClose();
198
        // TODO .prj
199

    
200
    }
201

    
202
    @Override
203
    protected void doDispose() throws BaseException {
204
        super.doDispose();
205
        getResource().removeConsumer(this);
206
        this.writer = null;
207
        this.shpFile = null;
208
    }
209

    
210
    protected void disposeResource() {
211
        getResource().removeConsumer(this);
212
    }
213

    
214
    /**
215
     * @throws ResourceNotifyOpenException
216
     *
217
     */
218
    protected void resourcesOpen() throws ResourceNotifyOpenException {
219
        getResource().notifyOpen();
220
    }
221

    
222
    protected static EditableFeatureAttributeDescriptor addGeometryColumn(EditableFeatureType fType) {
223

    
224
        EditableFeatureAttributeDescriptor attrTmp = null;
225
        EditableFeatureAttributeDescriptor attr = null;
226
        Iterator<?> iter = fType.iterator();
227
        while (iter.hasNext()) {
228
            attrTmp = (EditableFeatureAttributeDescriptor) iter.next();
229
            if (attrTmp.getType() == DataTypes.GEOMETRY) {
230
                if (attr != null) {
231
                    // Two geom fields not allowed
232
                    fType.remove(attrTmp.getName());
233
                } else {
234
                    attr = attrTmp;
235
                }
236
            }
237
        }
238

    
239
        if (attr == null) {
240
            String geofield = createGeometryFieldName(fType);
241
            attr = fType.add(geofield, DataTypes.GEOMETRY);
242
            attr.setDefaultValue(null);
243
        }
244

    
245
        attr.setObjectClass(Geometry.class);
246
        attr.setAllowNull(true);
247
//        fType.setDefaultGeometryAttributeName(attr.getName());
248
        return attr;
249

    
250
    }
251

    
252
    private static String createGeometryFieldName(FeatureType ft) {
253

    
254
        if (ft.getAttributeDescriptor(GEOMETRY_ATTIBUTE_NAME) == null) {
255
            return GEOMETRY_ATTIBUTE_NAME;
256
        }
257

    
258
        int i = 0;
259
        String candidate = GEOMETRY_ATTIBUTE_NAME + i;
260
        while (ft.getAttributeDescriptor(candidate) != null) {
261
            i++;
262
            candidate = GEOMETRY_ATTIBUTE_NAME + i;
263
        }
264
        return candidate;
265
    }
266

    
267
    protected EditableFeatureType getTheFeatureType() throws InitializeException{
268
        try {
269
            this.open();
270
        } catch (DataException e) {
271
            throw new InitializeException(this.getProviderName(), e);
272
        }
273
        final EditableFeatureType fType = super.getTheFeatureType();
274
        try {
275
            getResource().execute(new ResourceAction() {
276

    
277
                public Object run() throws Exception {
278
                    EditableFeatureAttributeDescriptor attr = addGeometryColumn(fType);
279

    
280
                    attr.setGeometryType(GEOM_MANAGER.getGeometryType(
281
                        shpFile.getGeometryType(),
282
                        shpFile.getGeometrySubType()
283
                    ));
284

    
285
                    IProjection srs = getShpParameters().getCRS();
286
                    attr.setSRS(srs);
287

    
288
                    return null;
289
                }
290
            });
291
            return fType;
292
        } catch (ResourceExecuteException e) {
293
            throw new InitializeException(e);
294
        }
295
    }
296

    
297
    protected SHPStoreParameters getShpParameters() {
298
        return (SHPStoreParameters) getParameters();
299
    }
300

    
301
    public String getProviderName() {
302
        return NAME;
303
    }
304

    
305
    public boolean allowWrite() {
306
        return this.shpFile.isEditable() &&
307
            super.allowWrite() &&
308
            !this.getShpParameters().getLoadCorruptGeometriesAsNull() &&
309
            !this.getShpParameters().getAllowInconsistenciesInGeometryType() &&
310
            !this.getShpParameters().getFixLinearRings();
311
    }
312

    
313
    /**
314
     *
315
     * @param index
316
     * @param featureType
317
     * @return
318
     * @throws ReadException
319
     */
320
    protected FeatureProvider getFeatureProviderByIndex(long index, FeatureType featureType) throws DataException {
321
        this.open();
322
        try {
323

    
324
            FeatureProvider featureProvider = super.getFeatureProviderByIndex(index, featureType);
325
            featureProvider.setDefaultEnvelope(this.shpFile.getBoundingBox(index));
326
            return featureProvider;
327
        } catch (DataException e) {
328
            throw e;
329
        } catch (CreateEnvelopeException e) {
330
            throw new org.gvsig.fmap.dal.feature.exception.CreateGeometryException(e);
331
        } catch (CreateGeometryException e) {
332
            throw new org.gvsig.fmap.dal.feature.exception.CreateGeometryException(e);
333
        }
334

    
335
    }
336

    
337
    protected void initFeatureProviderByIndex(FeatureProvider featureProvider, long index, FeatureType featureType)
338
        throws DataException {
339
        try {
340
            super.initFeatureProviderByIndex(featureProvider, index, featureType);
341
            featureProvider.setDefaultEnvelope(this.shpFile.getBoundingBox(index));
342
        } catch (CreateEnvelopeException e) {
343
            throw new org.gvsig.fmap.dal.feature.exception.CreateGeometryException(e);
344
        } catch (CreateGeometryException e) {
345
            throw new org.gvsig.fmap.dal.feature.exception.CreateGeometryException(e);
346
        }
347
    }
348

    
349
    /**
350
     *
351
     * @param featureProvider
352
     * @throws DataException
353
     */
354
    @Override
355
    protected void loadFeatureProviderByIndex(FeatureProvider featureProvider) throws DataException {
356

    
357
        FeatureType featureType = featureProvider.getType();
358
        long index = ((Long) featureProvider.getOID());
359
        boolean hasGeometry = false;
360
        int i = featureType.getDefaultGeometryAttributeIndex();
361
        if (i >= 0) {
362
            if (!featureProvider.isReadOnly(i)) {
363
                Geometry geom;
364
                try {
365
                    geom = this.shpFile.getGeometry(index);
366
                } catch (Exception e) {
367
                    if( this.getShpParameters().getLoadCorruptGeometriesAsNull() ) {
368
                        geom = null;
369
                    } else {
370
                        throw new ReadGeometryException(getName(), featureProvider.getOID(), e);
371
                    }
372
                }
373
                featureProvider.set(i, geom);
374
            }
375
            hasGeometry = true;
376
        }
377
        if (hasDBFAttributes(featureType, hasGeometry)) {
378
            super.loadFeatureProviderByIndex(featureProvider);
379
        }
380

    
381
    }
382

    
383
    public class ReadGeometryException extends ReadException {
384

    
385
        private final static String MESSAGE_FORMAT = "There was errors loading a geometry from '%(store)'.\nCheck 'Load corrupt geometries as null' in the shape's properties of the add layer dialog to skip corrupt geometries. The layer will become read only.";
386
        private final static String MESSAGE_KEY = "_ReadGeometryException";
387
        private static final long serialVersionUID = 2626155328734197112L;
388

    
389
        public ReadGeometryException(String store, Object oid, Throwable cause) {
390
            super(MESSAGE_FORMAT, cause, MESSAGE_KEY, serialVersionUID);
391
            setValue("store", store);
392
            setValue("storeParameters",getParameters());
393
        }
394
    }
395

    
396
    private boolean hasDBFAttributes(FeatureType featureType, boolean hasGeometry) {
397
        FeatureAttributeDescriptor[] attributes = featureType.getAttributeDescriptors();
398
        // If there aren't any attributes, nor has any DBF attributes
399
        if (attributes == null || attributes.length == 0) {
400
            return false;
401
        }
402
        // If there is only one attribute and it is the geometry one
403
        if (attributes.length == 1 && hasGeometry) {
404
            return false;
405
        }
406
        // In any other case
407
        return true;
408
    }
409

    
410
    protected void loadValue(FeatureProvider featureProvider, long rowIndex, FeatureAttributeDescriptor descriptor)
411
        throws ReadException {
412
        if (descriptor.getType() == DataTypes.GEOMETRY) {
413
            return;
414
        } else {
415
            super.loadValue(featureProvider, rowIndex, descriptor);
416
        }
417
    }
418

    
419
    public FeatureProvider createFeatureProvider(FeatureType type) throws DataException {
420
        FeatureProvider data = new SHPFeatureProvider(this, type);
421
        return data;
422
    }
423

    
424
    protected void openFile() throws IOException, DataException {
425
        super.openFile();
426
        this.shpFile.open();
427

    
428
    }
429

    
430
    protected void closeFile() throws CloseException {
431
        super.closeFile();
432
        if (!this.shpFile.isOpen()) {
433
            return;
434
        }
435
        this.shpFile.close();
436
    }
437

    
438
    public boolean canWriteGeometry(final int geometryType, int geometrySubType) throws DataException {
439
        this.open();
440
        return ((Boolean) getResource().execute(new ResourceAction() {
441

    
442
            public Object run() throws Exception {
443
                boolean value = shpFile.canWriteGeometry(geometryType);
444
                return value ? Boolean.TRUE : Boolean.FALSE;
445
            }
446
        })).booleanValue();
447
    }
448

    
449
    @SuppressWarnings("rawtypes")
450
    public void performChanges(Iterator deleteds, Iterator inserteds, Iterator updateds,
451
        Iterator originalFeatureTypesUpdated) throws PerformEditingException {
452
        final List<Object> originalFeatureTypesUpdatedList = new ArrayList<>();
453
        while (originalFeatureTypesUpdated.hasNext()) {
454
            originalFeatureTypesUpdatedList.add(originalFeatureTypesUpdated.next());
455
        }
456
        
457
        /*
458
         * This will throw an exception if there are new fields
459
         * with names too long
460
         */
461
        checkNewFieldsNameSize(originalFeatureTypesUpdatedList.iterator());
462

    
463
        final FeatureType fType;
464
        try {
465
            fType = this.getStoreServices().getDefaultFeatureType();
466
        } catch (DataException e) {
467
            throw new PerformEditingException(this.getProviderName(), e);
468
        }
469
        try {
470
            // TODO repasar el concepto de enUso de un recurso.
471
            loTengoEnUso = true;
472
            resourceCloseRequest();
473

    
474
            getResource().execute(new ResourceAction() {
475

    
476
                public Object run() throws Exception {
477
                    FeatureSet set = null;
478
                    DisposableIterator iter = null;
479
                    try {
480
                        set = getFeatureStore().getFeatureSet();
481
                        writer = new SHPFeatureWriter(getProviderName());
482

    
483
                        SHPStoreParameters shpParams = getShpParameters();
484
                        SHPStoreParameters tmpParams = (SHPStoreParameters) shpParams.getCopy();
485

    
486
                        File tmp_base = File.createTempFile("tmp_" + System.currentTimeMillis(), null);
487
                        String str_base = tmp_base.getCanonicalPath();
488

    
489
                        tmpParams.setDBFFile(str_base + ".dbf");
490
                        tmpParams.setSHPFile(str_base + ".shp");
491
                        tmpParams.setSHXFile(str_base + ".shx");
492

    
493
                        writer.begin(tmpParams, fType, set.getSize());
494

    
495
                        iter = set.fastIterator();
496
                        while (iter.hasNext()) {
497
                            Feature feature = (Feature) iter.next();
498
                            writer.append(feature);
499
                        }
500

    
501
                        writer.end();
502
                        loTengoEnUso = false;
503
                        close();
504

    
505

    
506
                        if (!shpParams.getDBFFile().delete()) {
507
                            LOGGER.debug("Can't delete dbf file '" + shpParams.getDBFFile() + "'.");
508
                            throw new IOException("Can't delete dbf '"
509
                                + FilenameUtils.getBaseName(shpParams.getDBFFileName())
510
                                + "' file to replace with the new dbf.\nThe new dbf is in temporary file '" + str_base
511
                                + "'");
512
                        }
513
                        if (!shpParams.getSHPFile().delete()) {
514
                            LOGGER.debug("Can't delete dbf file '" + shpParams.getSHPFile() + "'.");
515
                            throw new IOException("Can't delete shp '"
516
                                + FilenameUtils.getBaseName(shpParams.getSHPFileName())
517
                                + "' file to replace with the new shp.\nThe new shp is in temporary file '" + str_base
518
                                + "'");
519
                        }
520
                        if (!shpParams.getSHXFile().delete()) {
521
                            LOGGER.debug("Can't delete dbf file '" + shpParams.getSHXFile() + "'.");
522
                            throw new IOException("Can't delete shx '"
523
                                + FilenameUtils.getBaseName(shpParams.getSHXFileName())
524
                                + "' file to replace with the new shx.\nThe new shx is in temporary file '" + str_base
525
                                + "'");
526
                        }
527
                        if (shpParams.getCPGFile().exists() && !shpParams.getCPGFile().delete()) {
528
                            LOGGER.debug("Can't delete cpg file '" + shpParams.getCPGFile() + "'.");
529
                            throw new IOException("Can't delete cpg '"
530
                                + FilenameUtils.getBaseName(shpParams.getCPGFileName())
531
                                + "' file to replace with the new cpg.\nThe new cpg is in temporary file '" + str_base
532
                                + "'");
533
                        }
534

    
535
                        File prjFile = SHP.getPrjFile(shpParams.getSHPFile());
536
                        if (prjFile.exists()) {
537
                            if (!prjFile.delete()) {
538
                                LOGGER.debug("Can't delete prj file '" + prjFile + "'.");
539
                                throw new IOException("Can't delete shx '"
540
                                    + FilenameUtils.getBaseName(prjFile.getPath())
541
                                    + "' file to replace with the new shx.\nThe new shx is in temporary file '"
542
                                    + str_base + "'");
543
                            }
544
                        }
545
                        FileUtils.moveFile(tmpParams.getDBFFile(), shpParams.getDBFFile());
546
                        FileUtils.moveFile(tmpParams.getSHPFile(), shpParams.getSHPFile());
547
                        FileUtils.moveFile(tmpParams.getSHXFile(), shpParams.getSHXFile());
548
                        FileUtils.moveFile(tmpParams.getCPGFile(), shpParams.getCPGFile());
549

    
550
                        savePrjFile(shpParams.getFile(), tmpParams.getCRS());
551

    
552
                        resourcesNotifyChanges();
553
                        if (!originalFeatureTypesUpdatedList.isEmpty()) {
554
                             initFeatureType();
555
                        }
556
                       
557
                        return null;
558
                    } finally {
559
                        loTengoEnUso = false;
560
                        dispose(set);
561
                        dispose(iter);
562
                    }
563
                }
564
            });
565

    
566
        } catch (Exception e) {
567
            throw new PerformEditingException(this.getProviderName(), e);
568
        }
569

    
570
    }
571

    
572
    protected void resourceCloseRequest() throws ResourceException {
573
        getResource().closeRequest();
574
    }
575

    
576
    public Envelope getEnvelope() throws DataException {
577
        this.open();
578
        return (Envelope) this.getDynValue("Envelope");
579
    }
580

    
581
    public void append(final FeatureProvider featureProvider) throws DataException {
582
        getResource().execute(new ResourceAction() {
583

    
584
            public Object run() throws Exception {
585
                writer.append(getStoreServices().createFeature(featureProvider));
586
                return null;
587
            }
588
        });
589
    }
590

    
591
    public void beginAppend() throws DataException {
592
        getResource().execute(new ResourceAction() {
593

    
594
            public Object run() throws Exception {
595
                FeatureStore store = getFeatureStore();
596
                FeatureType fType = store.getDefaultFeatureType();
597

    
598
                writer = new SHPFeatureWriter(getProviderName());
599
                writer.begin(getShpParameters(), fType, store.getFeatureCount());
600
                return null;
601
            }
602
        });
603
    }
604

    
605
    public void endAppend() throws DataException {
606
        getResource().execute(new ResourceAction() {
607

    
608
            public Object run() throws Exception {
609
                writer.end();
610
                close();
611

    
612
                SHPStoreParameters shpParameters = SHPStoreProvider.this.getShpParameters();
613

    
614
                savePrjFile(shpParameters.getFile(), shpParameters.getCRS());
615

    
616
                resourcesNotifyChanges();
617
                return null;
618
            }
619
        });
620
    }
621

    
622
    public Object getSourceId() {
623
        return this.getShpParameters().getFile();
624
    }
625

    
626
    @Override
627
    public void fixFeatureTypeFromParameters() {
628
        try {
629
            super.fixFeatureTypeFromParameters();
630
            FeatureStoreProviderServices store = this.getStoreServices();
631
            
632
            FeatureType ft = store.getDefaultFeatureType();
633
            FeatureAttributeDescriptor geomAttr = ft.getDefaultGeometryAttribute();
634
            
635
            GeometryType geomType = geomAttr.getGeomType();
636
            if(geomType.getType() != this.shpFile.getGeometryType() || geomType.getSubType() != this.shpFile.getGeometrySubType()) {
637
                EditableFeatureType eft = ft.getEditable();
638
                EditableFeatureAttributeDescriptor geomEditableAttr = (EditableFeatureAttributeDescriptor) eft.getDefaultGeometryAttribute();
639
                geomEditableAttr.setGeometryType(this.shpFile.getGeometryType(), this.shpFile.getGeometrySubType());
640
                this.setStoreFeatureType(eft.getNotEditableCopy());
641
            }
642
        } catch (DataException ex) {
643
            LOGGER.warn("Can't fix feture type.", ex);
644
        }
645

    
646
    }
647

    
648
    
649

    
650
}