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

History | View | Annotate | Download (23 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.Iterator;
28

    
29
import org.apache.commons.io.FileUtils;
30
import org.apache.commons.io.FilenameUtils;
31
import org.cresques.cts.ICRSFactory;
32
import org.cresques.cts.IProjection;
33
import org.slf4j.Logger;
34
import org.slf4j.LoggerFactory;
35

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

    
78
public class SHPStoreProvider extends DBFStoreProvider {
79

    
80
    private static final GeometryManager geomManager = GeometryLocator.getGeometryManager();
81
    private static final Logger logger = LoggerFactory.getLogger(GeometryManager.class);
82
    public static String NAME = "Shape";
83
    public static String DESCRIPTION = "Shape file";
84
    private ISHPFile shpFile;
85

    
86
    private MultiResource resource;
87

    
88
    protected static final String GEOMETRY_ATTIBUTE_NAME = "GEOMETRY";
89

    
90
    public static final String METADATA_DEFINITION_NAME = NAME;
91

    
92
    private SHPFeatureWriter writer = null;
93

    
94
    private boolean loTengoEnUso;
95

    
96
    public SHPStoreProvider(SHPStoreParameters params,
97
            DataStoreProviderServices storeServices)
98
            throws InitializeException {
99
        super(
100
                params,
101
                storeServices,
102
                FileHelper.newMetadataContainer(METADATA_DEFINITION_NAME)
103
        );
104
    }
105

    
106
    protected void init(DBFStoreParameters params,
107
            DataStoreProviderServices storeServices) throws InitializeException {
108

    
109
        this.shpFile = new SHPFile2((SHPStoreParameters) params);
110
        super.init(params, storeServices);
111
        this.shpFile.setUseNullGeometry(this.getShpParameters().getUseNullGeometry());
112
    }
113

    
114
    public Object getDynValue(String name) throws DynFieldNotFoundException {
115
        if (DataStore.METADATA_CRS.equalsIgnoreCase(name)) {
116

    
117
            return this.getShpParameters().getCRS();
118

    
119
        } else if (DataStore.METADATA_ENVELOPE.equalsIgnoreCase(name)) {
120
            try {
121
                return this.shpFile.getFullExtent();
122
            } catch (ReadException e) {
123
                return null;
124
            }
125
        }
126
        return super.getDynValue(name);
127
    }
128

    
129
    protected void initResource(DBFStoreParameters params,
130
            DataStoreProviderServices storeServices) throws InitializeException {
131

    
132
        SHPStoreParameters shpParams = (SHPStoreParameters) params;
133
        resource
134
                = (MultiResource) createResource(MultiResource.TYPE_NAME,
135
                        new Object[]{shpParams.getSHPFileName()});
136

    
137
        resource.addResource(FileResource.NAME,
138
                new Object[]{shpParams.getSHPFileName()}, true);
139
        resource.addResource(FileResource.NAME,
140
                new Object[]{shpParams.getSHXFileName()}, true);
141
        resource.addResource(FileResource.NAME,
142
                new Object[]{shpParams.getDBFFileName()}, true);
143

    
144
        resource.frozen();
145
        resource.addMultiResourceConsumer(this);
146
    }
147

    
148
    ;
149

    
150
        public ResourceProvider getResource() {
151
        return resource;
152
    }
153

    
154
    /**
155
     *
156
     * @throws ResourceNotifyChangesException
157
     */
158
    protected void resourcesNotifyChanges()
159
            throws ResourceNotifyChangesException {
160
                // super.resourcesNotifyChanges();
161
        // this.shpResource.notifyChanges();
162
        // this.shxResource.notifyChanges();
163
        getResource().notifyChanges();
164
        // TODO .prj
165

    
166
    }
167

    
168
    /**
169
     * @throws ResourceNotifyCloseException
170
     *
171
     */
172
    protected void resourcesNotifyClose() throws ResourceNotifyCloseException {
173
//                super.resourcesNotifyClose();
174
//                this.shpResource.notifyClose();
175
//                this.shxResource.notifyClose();
176
        getResource().notifyClose();
177
        // TODO .prj
178

    
179
    }
180

    
181
    @Override
182
    protected void doDispose() throws BaseException {
183
        super.doDispose();
184
        getResource().removeConsumer(this);
185
        this.writer = null;
186
        this.shpFile = null;
187
    }
188

    
189
    protected void disposeResource() {
190
        getResource().removeConsumer(this);
191
    }
192

    
193
    /**
194
     * @throws ResourceNotifyOpenException
195
     *
196
     */
197
    protected void resourcesOpen() throws ResourceNotifyOpenException {
198
                // super.resourcesOpen();
199
        // this.shpResource.notifyOpen();
200
        // this.shxResource.notifyOpen();
201
        getResource().notifyOpen();
202
    }
203

    
204
    protected static EditableFeatureAttributeDescriptor addGeometryColumn(
205
            EditableFeatureType fType) {
206

    
207
        EditableFeatureAttributeDescriptor attrTmp = null;
208
        EditableFeatureAttributeDescriptor attr = null;
209
        Iterator iter = fType.iterator();
210
        while (iter.hasNext()) {
211
            attrTmp = (EditableFeatureAttributeDescriptor) iter.next();
212
            if (attrTmp.getType() == DataTypes.GEOMETRY) {
213
                if (attr != null) {
214
                    // Two geom fields not allowed
215
                    fType.remove(attrTmp.getName());
216
                } else {
217
                    attr = attrTmp;
218
                    // attr.setName(GEOMETRY_ATTIBUTE_NAME);
219
                }
220
            }
221
        }
222

    
223
        if (attr == null) {
224
            String geofield = createGeometryFieldName(fType);
225
            attr = fType.add(geofield, DataTypes.GEOMETRY);
226
            attr.setDefaultValue(null);
227
        }
228

    
229
        attr.setObjectClass(Geometry.class);
230
        fType.setDefaultGeometryAttributeName(attr.getName());
231
        return attr;
232

    
233
    }
234

    
235
    private static String createGeometryFieldName(FeatureType ft) {
236

    
237
        if (ft.getAttributeDescriptor(GEOMETRY_ATTIBUTE_NAME) == null) {
238
            return GEOMETRY_ATTIBUTE_NAME;
239
        }
240

    
241
        int i = 0;
242
        String candidate = GEOMETRY_ATTIBUTE_NAME + i;
243
        while (ft.getAttributeDescriptor(candidate) != null) {
244
            i++;
245
            candidate = GEOMETRY_ATTIBUTE_NAME + i;
246
        }
247
        return candidate;
248
    }
249

    
250
    protected static FeatureType removeGeometryColumn(
251
            EditableFeatureType fType) {
252
        Iterator iter = fType.iterator();
253
        FeatureAttributeDescriptor attr;
254
        while (iter.hasNext()) {
255
            attr = (FeatureAttributeDescriptor) iter.next();
256
            if (attr.getType() == DataTypes.GEOMETRY) {
257
                iter.remove();
258
            }
259
        }
260
        fType.setDefaultGeometryAttributeName(null);
261
        return fType.getNotEditableCopy();
262
    }
263

    
264
    protected EditableFeatureType getTheFeatureType()
265
            throws InitializeException, OpenException {
266
        final EditableFeatureType fType = super.getTheFeatureType();
267
        this.open();
268
                // try {
269
        // this.resourcesBegin();
270
        // } catch (DataException e) {
271
        // throw new InitializeException(this.getName(), e);
272
        // }
273
        try {
274
            getResource().execute(new ResourceAction() {
275
                public Object run() throws Exception {
276
                    EditableFeatureAttributeDescriptor attr
277
                            = addGeometryColumn(fType);
278
                    attr.setGeometryType(shpFile.getGeometryType());
279
                    attr.setGeometrySubType(shpFile.getGeometrySubType());
280

    
281
                    IProjection srs = getShpParameters().getCRS();
282
                    attr.setSRS(srs);
283

    
284
                    return null;
285
                }
286
            });
287
            return fType;
288
        } catch (ResourceExecuteException e) {
289
            throw new InitializeException(e);
290
                        // } finally {
291
            // this.resourcesEnd();
292
        }
293
    }
294

    
295
//        private String getSRSFromPrj(String srsParameters) {
296
//                // TODO identificar que SRS hay que usar, ya sea
297
//                // el que se recibe de los parametros o el que
298
//                // conicida con el que se ha encontrado en el
299
//                // prg... y si ninguna de las dos que?
300
//                return null;
301
//        }
302
    protected SHPStoreParameters getShpParameters() {
303
        return (SHPStoreParameters) getParameters();
304
    }
305

    
306
    public String getProviderName() {
307
        return NAME;
308
    }
309

    
310
    public boolean allowWrite() {
311
        return this.shpFile.isEditable();
312
    }
313

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

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

    
339
    }
340

    
341
    protected void initFeatureProviderByIndex(FeatureProvider featureProvider,
342
            long index, FeatureType featureType) throws DataException {
343
                // this.open();
344
        // this.resourcesBegin();
345
        try {
346
            super.initFeatureProviderByIndex(featureProvider, index, featureType);
347
            featureProvider.setDefaultEnvelope(this.shpFile.getBoundingBox(index));
348
        } catch (CreateEnvelopeException e) {
349
            throw new org.gvsig.fmap.dal.feature.exception.CreateGeometryException(e);
350
        } catch (CreateGeometryException e) {
351
            throw new org.gvsig.fmap.dal.feature.exception.CreateGeometryException(e);
352
        }
353
    }
354

    
355
    /**
356
     *
357
     * @param featureProvider
358
     * @throws DataException
359
     */
360
    protected void loadFeatureProviderByIndex(FeatureProvider featureProvider)
361
            throws DataException {
362

    
363
        FeatureType featureType = featureProvider.getType();
364
        long index = ((Long) featureProvider.getOID()).longValue();
365
        boolean hasGeometry = false;
366
        int i = featureType.getDefaultGeometryAttributeIndex();
367
        if (i >= 0) {
368
            if (!featureProvider.isReadOnly(i)) {
369
                try {
370
                    Geometry geom = this.shpFile.getGeometry(index);
371
                    featureProvider.set(i, geom);
372
                } catch (CreateGeometryException e) {
373
                    throw new ReadException(getProviderName(), e);
374
                }
375
            }
376
            hasGeometry = true;
377
        }
378
        if (hasDBFAttributes(featureType, hasGeometry)) {
379
            super.loadFeatureProviderByIndex(featureProvider);
380
        }
381

    
382
    }
383

    
384
    private boolean hasDBFAttributes(FeatureType featureType,
385
            boolean hasGeometry) {
386
        FeatureAttributeDescriptor[] attributes
387
                = featureType.getAttributeDescriptors();
388
        // If there aren't any attributes, nor has any DBF attributes
389
        if (attributes == null || attributes.length == 0) {
390
            return false;
391
        }
392
        // If there is only one attribute and it is the geometry one
393
        if (attributes.length == 1 && hasGeometry) {
394
            return false;
395
        }
396
        // In any other case
397
        return true;
398
    }
399

    
400
    protected void loadValue(FeatureProvider featureProvider, int rowIndex,
401
            FeatureAttributeDescriptor descriptor) throws ReadException {
402
        if (descriptor.getType() == DataTypes.GEOMETRY) {
403
            return;
404
        } else {
405
            super.loadValue(featureProvider, rowIndex, descriptor);
406
        }
407
    }
408

    
409
    public FeatureProvider createFeatureProvider(FeatureType type) throws DataException {
410
        FeatureProvider data = new SHPFeatureProvider(this, type);
411
        return data;
412
    }
413

    
414
    protected void openFile() throws IOException, DataException {
415
        super.openFile();
416
        this.shpFile.open();
417

    
418
    }
419

    
420
    protected void closeFile() throws CloseException {
421
        super.closeFile();
422
        if (!this.shpFile.isOpen()) {
423
            return;
424
        }
425
        this.shpFile.close();
426
    }
427

    
428
    public boolean canWriteGeometry(final int geometryType, int geometrySubType)
429
            throws DataException {
430
        this.open();
431
        return ((Boolean) getResource().execute(new ResourceAction() {
432
            public Object run() throws Exception {
433
                boolean value = shpFile.canWriteGeometry(geometryType);
434
                return value ? Boolean.TRUE : Boolean.FALSE;
435
            }
436
        })).booleanValue();
437
//                this.resourcesBegin();
438
//                try {
439
//                        return this.shpFile.canWriteGeometry(geometryType);
440
//
441
//                } finally {
442
//                        this.resourcesEnd();
443
//                }
444
    }
445

    
446
    public void performChanges(Iterator deleteds, Iterator inserteds,
447
            Iterator updateds, Iterator originalFeatureTypesUpdated)
448
            throws PerformEditingException {
449

    
450
        /*
451
         * This will throw an exception if there are new fields
452
         * with names too long
453
         */
454
        checkNewFieldsNameSize(originalFeatureTypesUpdated);
455

    
456
        final FeatureType fType;
457
        try {
458
            fType = this.getStoreServices().getDefaultFeatureType();
459
        } catch (DataException e) {
460
            throw new PerformEditingException(this.getProviderName(), e);
461
        }
462
        // TODO Comprobar el campo de geometria
463

    
464
        final EditableFeatureType dbfFtype = fType.getEditable();
465

    
466
        removeGeometryColumn(dbfFtype);
467

    
468
                // try {
469
        // this.resourcesBegin();
470
        // } catch (ResourceExecuteException e1) {
471
        // throw new PerformEditingException(this.getName(), e1);
472
        // }
473
        try {
474
            // TODO repasar el concepto de enUso de un recurso.
475
            loTengoEnUso = true;
476
            resourceCloseRequest();
477

    
478
            getResource().execute(new ResourceAction() {
479
                public Object run() throws Exception {
480
                    FeatureSet set = null;
481
                    DisposableIterator iter = null;
482
                    try {
483
                        set = getFeatureStore().getFeatureSet();
484
                        writer = new SHPFeatureWriter(getProviderName());
485

    
486
                        SHPStoreParameters shpParams = getShpParameters();
487
                        SHPStoreParameters tmpParams
488
                                = (SHPStoreParameters) shpParams.getCopy();
489

    
490
                        File tmp_base = File.createTempFile(
491
                                "tmp_" + System.currentTimeMillis(), null);
492
                        String str_base = tmp_base.getCanonicalPath();
493

    
494
                        tmpParams.setDBFFile(str_base + ".dbf");
495
                        tmpParams.setSHPFile(str_base + ".shp");
496
                        tmpParams.setSHXFile(str_base + ".shx");
497

    
498
                        writer.begin(tmpParams, fType, dbfFtype, set.getSize());
499

    
500
                        iter = set.fastIterator();
501
                        while (iter.hasNext()) {
502
                            Feature feature = (Feature) iter.next();
503
                            writer.append(feature);
504
                        }
505

    
506
                        writer.end();
507
                        loTengoEnUso = false;
508
                        close();
509

    
510

    
511
                        File tmpPrjFile = SHP.getPrjFile(tmpParams.getSHPFile());
512
                        try {
513
                        FileUtils.writeStringToFile(tmpPrjFile, tmpParams.getCRS().export(ICRSFactory.FORMAT_WKT_ESRI));
514
                        } catch(Exception e) {
515
                            logger.info("Can't write prj file '"+tmpPrjFile.getAbsolutePath()+"'.");
516
                        }
517

    
518
                        if (!shpParams.getDBFFile().delete()) {
519
                            logger.debug("Can't delete dbf file '"+shpParams.getDBFFile()+"'.");
520
                            throw new IOException("Can't delete dbf '"+FilenameUtils.getBaseName(shpParams.getDBFFileName())+"' file to replace with the new dbf.\nThe new dbf is in temporary file '"+str_base+"'");
521
                        }
522
                        if (!shpParams.getSHPFile().delete()) {
523
                            logger.debug("Can't delete dbf file '"+shpParams.getSHPFile()+"'.");
524
                            throw new IOException("Can't delete shp '"+FilenameUtils.getBaseName(shpParams.getSHPFileName())+"' file to replace with the new shp.\nThe new shp is in temporary file '"+str_base+"'");
525
                        }
526
                        if (!shpParams.getSHXFile().delete()) {
527
                            logger.debug("Can't delete dbf file '"+shpParams.getSHXFile()+"'.");
528
                            throw new IOException("Can't delete shx '"+FilenameUtils.getBaseName(shpParams.getSHXFileName())+"' file to replace with the new shx.\nThe new shx is in temporary file '"+str_base+"'");
529
                        }
530

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

    
551
                        FileUtils.moveFile(
552
                            tmpPrjFile,
553
                            SHP.getPrjFile(shpParams.getSHPFile()));
554

    
555
                        resourcesNotifyChanges();
556
                        initFeatureType();
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

    
573
    protected void resourceCloseRequest() throws ResourceException {
574
                // super.resourceCloseRequest();
575
        // this.shpResource.closeRequest();
576
        // this.shxResource.closeRequest();
577
        getResource().closeRequest();
578
    }
579

    
580
    public Envelope getEnvelope() throws DataException {
581
        this.open();
582
        return (Envelope) this.getDynValue("Envelope");
583
    }
584

    
585
    public void append(final FeatureProvider featureProvider) throws DataException {
586
//                this.resourcesBegin();
587
//                try {
588

    
589
        getResource().execute(new ResourceAction() {
590
            public Object run() throws Exception {
591
                writer.append(getStoreServices().createFeature(featureProvider));
592
                return null;
593
            }
594
        });
595
//                } finally {
596
//                        this.resourcesEnd();
597
//                }
598

    
599
    }
600

    
601
    public void beginAppend() throws DataException {
602
                // this.resourcesBegin();
603
        // try {
604

    
605
        getResource().execute(new ResourceAction() {
606
            public Object run() throws Exception {
607
                FeatureStore store = getFeatureStore();
608
                FeatureType fType = store.getDefaultFeatureType();
609

    
610
                                // TODO Comprobar el campo de geometria
611
                EditableFeatureType dbfFtype = fType.getEditable();
612

    
613
                removeGeometryColumn(dbfFtype);
614
                FeatureSet set = store.getFeatureSet();
615

    
616
                writer = new SHPFeatureWriter(getProviderName());
617

    
618
                writer.begin(getShpParameters(), fType, dbfFtype, set.getSize());
619
                return null;
620
            }
621
        });
622
                // } finally {
623
        // this.resourcesEnd();
624
        // }
625

    
626
    }
627

    
628
    public void endAppend() throws DataException {
629
//                this.resourcesBegin();
630
//                try {
631
        getResource().execute(new ResourceAction() {
632
            public Object run() throws Exception {
633
                writer.end();
634
                close();
635
                resourcesNotifyChanges();
636
                return null;
637
            }
638
        });
639
//                } finally {
640
//                        this.resourcesEnd();
641
//                }
642

    
643
    }
644

    
645
    public Object getSourceId() {
646
        return this.getShpParameters().getFile();
647
    }
648
}