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.csv / src / main / java / org / gvsig / fmap / dal / store / csv / CSVStoreProvider.java @ 47638

History | View | Annotate | Download (13.2 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.csv;
24

    
25
import java.io.File;
26
import java.io.IOException;
27
import java.io.Reader;
28
import java.util.ArrayList;
29
import java.util.Iterator;
30
import java.util.List;
31
import org.apache.commons.io.FileUtils;
32
import org.apache.commons.io.FilenameUtils;
33
import org.gvsig.fmap.dal.DataStore;
34
import org.gvsig.fmap.dal.FileHelper;
35
import org.gvsig.fmap.dal.exception.DataException;
36
import org.gvsig.fmap.dal.exception.InitializeException;
37
import org.gvsig.fmap.dal.feature.FeatureSet;
38
import org.gvsig.fmap.dal.feature.FeatureType;
39
import org.gvsig.fmap.dal.feature.exception.PerformEditingException;
40
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
41
import org.gvsig.fmap.dal.resource.ResourceAction;
42
import org.gvsig.fmap.dal.resource.spi.ResourceConsumer;
43
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
44
import org.gvsig.fmap.dal.store.csv.simplereaders.CSVReaderSuperCSV;
45
import org.gvsig.fmap.dal.store.csv.simplereaders.FixedLenReader;
46
import org.gvsig.fmap.dal.store.simplereader.simplereaders.SimpleReader;
47
import org.gvsig.fmap.dal.store.simplereader.SimpleReaderFeatureTypeLoader;
48
import org.gvsig.fmap.dal.store.simplereader.SimpleReaderStoreParameters;
49
import org.gvsig.fmap.dal.store.simplereader.SimpleReaderStoreProvider;
50
import org.gvsig.tools.ToolsLocator;
51
import org.gvsig.tools.dispose.DisposableIterator;
52
import org.gvsig.tools.i18n.I18nManager;
53
import org.slf4j.Logger;
54
import org.slf4j.LoggerFactory;
55
import org.supercsv.prefs.CsvPreference;
56

    
57
@SuppressWarnings("UseSpecificCatch")
58
public class CSVStoreProvider extends SimpleReaderStoreProvider implements
59
        ResourceConsumer {
60

    
61
    private static final Logger LOGGER = LoggerFactory.getLogger(CSVStoreProvider.class);
62

    
63
    public static final String NAME = DataStore.CSV_PROVIDER_NAME;
64
    public static final String DESCRIPTION = "CSV file";
65

    
66
    public static final String METADATA_DEFINITION_NAME = NAME;
67

    
68
    protected final CSVFeatureWriter writer;
69

    
70
    @SuppressWarnings({"OverridableMethodCallInConstructor", "LeakingThisInConstructor"})
71
    public CSVStoreProvider(
72
            CSVStoreParameters parameters,
73
            DataStoreProviderServices storeServices
74
        ) throws InitializeException {
75
        super(
76
                parameters,
77
                storeServices,
78
                FileHelper.newMetadataContainer(METADATA_DEFINITION_NAME)
79
        );
80
        this.writer = new CSVFeatureWriter();
81
    }
82

    
83
    private CSVStoreParameters getCSVParameters() {
84
        return (CSVStoreParameters) this.getParameters();
85
    }
86

    
87
    @Override
88
    public String getProviderName() {
89
        return NAME;
90
    }
91

    
92
    @Override
93
    public boolean allowWrite() {
94
        return true;
95
    }
96

    
97
    @Override
98
    @SuppressWarnings("Convert2Lambda")
99
    public void performChanges(Iterator deleteds, Iterator inserteds, Iterator updateds, Iterator originalFeatureTypesUpdated) throws PerformEditingException {
100

    
101
        try {
102
            I18nManager i18n = ToolsLocator.getI18nManager();
103
            this.taskStatus.add();
104
            taskStatus.message(i18n.getTranslation("_Preparing_writing"));
105
            this.getResource().closeRequest();
106
            getResource().execute(new ResourceAction() {
107
                @Override
108
                public Object run() throws Exception {
109
                    FeatureSet features = null;
110
                    DisposableIterator it = null;
111
                    try {
112
                        File file = (File) resource.get();
113
                        features = getStoreServices().getFeatureStore().getFeatureSet();
114

    
115
                        taskStatus.message(i18n.getTranslation("_Writing_records"));
116
                        if (virtualrows == null) {
117
                            List<FeatureProvider> newdata = new ArrayList<>();
118
                            FeatureType ftype = getStoreServices().getDefaultFeatureType();
119
                            writer.initialize(getCSVParameters(), file, ftype, getCSVPreferences());
120
                            writer.begin();
121
                            it = features.fastIterator();
122
                            taskStatus.setRangeOfValues(0, features.getSize());
123
                            taskStatus.setCurValue(0);
124
                            while (it.hasNext()) {
125
                                taskStatus.incrementCurrentValue();
126
                                FeatureProvider feature = getStoreServices().getFeatureProviderFromFeature(
127
                                        (org.gvsig.fmap.dal.feature.Feature) it.next());
128
                                writer.add(feature);
129
                                if (feature.getOID() == null) {
130
                                    LOGGER.warn("feature without OID");
131
                                    feature.setOID(createNewOID());
132
                                }
133
                                newdata.add(feature);
134
                            }
135
                            data = newdata;
136
                            if (writer.getEnvelope() != null) {
137
                                envelope = writer.getEnvelope();
138
                            } else {
139
                                envelope = null;
140
                            }
141
                            resource.notifyChanges();
142
                            writer.end();
143
                            bboxFileSave(envelope);
144
                        } else {
145

    
146
                            CSVStoreParameters csvParams = getCSVParameters();
147
                            CSVStoreParameters tmpParams = (CSVStoreParameters) csvParams.getCopy();
148

    
149
                            String tmpBase = File.createTempFile("tmp_" + System.currentTimeMillis(), null).getAbsolutePath();
150
                            File tmpFile = new File(tmpBase + ".csv");
151
                            tmpParams.setFile(tmpFile);
152

    
153
                            FeatureType ftype = getStoreServices().getDefaultFeatureType();
154
                            writer.initialize(tmpParams, tmpFile, ftype, getCSVPreferences(),spatialIndex);
155
                            writer.begin();
156
                            it = features.fastIterator();
157
                            taskStatus.setIndeterminate();
158
                            taskStatus.setCurValue(0);
159
                            while (it.hasNext()) {
160
                                taskStatus.incrementCurrentValue();
161
                                if( taskStatus.isCancellationRequested() ) {
162
                                    taskStatus.cancel();
163
                                    LOGGER.info("CSV writing canceled ("+getFullFileName()+")");
164
                                    break;
165
                                }
166
                                FeatureProvider feature = getStoreServices().getFeatureProviderFromFeature(
167
                                        (org.gvsig.fmap.dal.feature.Feature) it.next());
168
                                writer.add(feature);
169
                                if (feature.getOID() == null) {
170
                                    LOGGER.warn("feature without OID");
171
                                    feature.setOID(createNewOID());
172
                                }
173
                            }
174
                            if (writer.getEnvelope() != null) {
175
                                envelope = writer.getEnvelope();
176
                            } else {
177
                                envelope = null;
178
                            }
179
                            resource.notifyChanges();
180
                            writer.end();
181
                            if( !taskStatus.isCancelled() ) {
182
                                if (!csvParams.getFile().delete()) {
183
                                    LOGGER.debug("Can't delete csv file '" + csvParams.getFile() + "'.");
184
                                    throw new IOException("Can't delete csv '"
185
                                            + FilenameUtils.getBaseName(csvParams.getFile().getAbsolutePath())
186
                                            + "' file to replace with the new csv.\nThe new csv is in temporary file '" + tmpFile.getAbsolutePath()
187
                                            + "'");
188
                                }
189

    
190
                                File csvFile = csvParams.getFile();
191
                                FileUtils.moveFile(tmpParams.getFile(), csvFile);
192
                                FileUtils.delete(new File(FilenameUtils.removeExtension(csvFile.getAbsolutePath())+".idx"));
193

    
194
                                bboxFileSave(envelope);
195

    
196
                                loadFeatures();
197
                            }
198
                        }
199
                    } finally {
200
                        if (it != null) {
201
                            it.dispose();
202
                        }
203
                        if (features != null) {
204
                            features.dispose();
205
                        }
206
                    }
207
                    return null;
208
                }
209

    
210
            });
211
            this.taskStatus.terminate();
212
        } catch (Exception e) {
213
            this.taskStatus.abort();
214
            throw new PerformEditingException(getResource().toString(), e);
215
        }
216
    }
217

    
218
    private CsvPreference getCSVPreferences() {
219
        CSVReaderSuperCSV reader = new CSVReaderSuperCSV(getCSVParameters());
220
        return reader.getCSVPreferences();
221
    }
222

    
223
    @Override
224
    public boolean supportsAppendMode() {
225
        return true;
226
    }
227

    
228
    @Override
229
    @SuppressWarnings("Convert2Lambda")
230
    public void append(final FeatureProvider featureProvider) {
231
        //todo
232
        getResource().execute(new ResourceAction() {
233
            @Override
234
            public Object run() throws Exception {
235
                //writer.append(getStoreServices().createFeature(featureProvider));
236
                writer.add(featureProvider);
237
                return null;
238
            }
239
        });
240
    }
241

    
242
    @Override
243
    @SuppressWarnings("Convert2Lambda")
244
    public void beginAppend() throws DataException {
245
        getResource().execute(new ResourceAction() {
246
            @Override
247
            public Object run() throws Exception {
248
                writer.initialize(
249
                        getCSVParameters(),
250
                        getCSVParameters().getFile(),
251
                        getFeatureStore().getDefaultFeatureType(),
252
                        getCSVPreferences()
253
                );
254
                writer.beginAppend();
255
                return null;
256
            }
257
        });
258

    
259
    }
260

    
261
    @Override
262
    @SuppressWarnings("Convert2Lambda")
263
    public void endAppend() {
264
        try {
265
            getResource().execute(new ResourceAction() {
266
                @Override
267
                public Object run() throws Exception {
268
                    writer.end();
269
                    resource.notifyChanges(); //resourcesNotifyChanges();
270
                    counterNewsOIDs = -1;
271
                    return null;
272
                }
273
            });
274
            if (writer.getEnvelope() != null) {
275
                envelope = writer.getEnvelope();
276
            } else {
277
                envelope = null;
278
            }
279
            writer.end();
280
            this.close();
281
            bboxFileSave(envelope);            
282
            
283
        } catch (Exception ex) {
284
            LOGGER.warn("Not been able to end append '" + this.getFullName() + "'.", ex);
285
        }
286
    }
287

    
288
    @Override
289
    protected SimpleReader getSimpleReader(SimpleReaderStoreParameters parameters, Reader in) throws IOException {
290
        SimpleReader reader;
291
        if (CSVStoreParameters.getRawFieldsDefinition(parameters) != null) {
292
            reader = new FixedLenReader(in, (CSVStoreParameters) parameters);
293
        } else {
294
            reader = new CSVReaderSuperCSV(in, (CSVStoreParameters) parameters);
295
        }
296
        return reader;
297
    }
298

    
299
    @Override
300
    protected SimpleReaderFeatureTypeLoader getFeatureTypeLoader() {
301
        return new CSVFeatureTypeLoader(getCSVParameters());
302
    }
303

    
304
    @Override
305
    public List<String> getRowByIndex(long index) {
306
        try {
307
            this.open();
308
        } catch(Exception ex) {
309
            throw new RuntimeException("Can't get row by index", ex);
310
        }
311
        if (this.virtualrows == null) {
312
            return null;
313
        }
314
        List<String> line = this.virtualrows.get64(index);
315
        if( line!=null ) {
316
            for (int i = 0; i < line.size(); i++) {
317
                String s = line.get(i);
318
                line.set(i, CSVReaderSuperCSV.unescapeCRLF(s));
319
            }
320
        }      
321
        return line;
322
    }
323

    
324
}