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 / CSVFeatureWriter.java @ 47420

History | View | Annotate | Download (10.3 KB)

1
/*
2
 * To change this license header, choose License Headers in Project Properties.
3
 * To change this template file, choose Tools | Templates
4
 * and open the template in the editor.
5
 */
6
package org.gvsig.fmap.dal.store.csv;
7

    
8
import java.io.File;
9
import java.io.FileOutputStream;
10
import java.io.IOException;
11
import java.io.OutputStreamWriter;
12
import java.io.Writer;
13
import java.nio.file.Files;
14
import java.util.Locale;
15
import org.apache.commons.lang3.ArrayUtils;
16
import org.apache.commons.lang3.StringUtils;
17
import org.apache.commons.text.StringEscapeUtils;
18
import org.gvsig.fmap.dal.DataTypes;
19
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
20
import org.gvsig.fmap.dal.feature.FeatureType;
21
import org.gvsig.fmap.dal.feature.exception.PerformEditingException;
22
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
23
import org.gvsig.fmap.dal.store.csv.simplereaders.CSVReaderSuperCSV;
24
import org.gvsig.fmap.geom.Geometry;
25
import org.gvsig.fmap.geom.GeometryLocator;
26
import org.gvsig.fmap.geom.GeometryManager;
27
import org.gvsig.fmap.geom.SpatialIndex;
28
import org.gvsig.fmap.geom.operation.GeometryOperationException;
29
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
30
import org.gvsig.fmap.geom.primitive.Envelope;
31
import org.gvsig.tools.ToolsLocator;
32
import org.gvsig.tools.dataTypes.CoercionException;
33
import org.gvsig.tools.dataTypes.Coercion;
34
import org.gvsig.tools.dynobject.Tags;
35
import org.slf4j.Logger;
36
import org.slf4j.LoggerFactory;
37
import org.supercsv.io.CsvListWriter;
38
import org.supercsv.prefs.CsvPreference;
39

    
40
/**
41
 *
42
 * @author osc
43
 */
44
@SuppressWarnings("UseSpecificCatch")
45
public class CSVFeatureWriter {
46

    
47
  private static final Logger LOGGER = LoggerFactory.getLogger(CSVFeatureWriter.class);
48

    
49
  private Envelope envelope = null;
50
  private boolean calculate_envelope = false;
51
  private CsvListWriter listWriter = null;
52
  private CsvPreference csvpreferences = null;
53
  private Writer writer = null;
54
  private FeatureType ftype;
55
  private File file;
56
  private String[] values;
57
  private FeatureAttributeDescriptor[] descriptors;
58
  private Coercion convert = null;
59
//  private CoercionContext converContext = null;
60
  private int errorcounts = 0;
61
  private Throwable lasterror = null;
62
  private CSVStoreParameters storeParameters;
63
  private String charset = null;
64
  private boolean includeMetadataInHeader;
65
    private Locale locale;
66
    private GeometryManager geometryManager;
67
    private SpatialIndex spatialIndex;
68

    
69
  public void initialize(
70
          CSVStoreParameters storeParameters, 
71
          File file, 
72
          FeatureType ftype, 
73
          CsvPreference csvpreferences
74
    ) {
75
      this.initialize(storeParameters, file, ftype, csvpreferences, null);
76
  }
77
  
78
  public void initialize(
79
          CSVStoreParameters storeParameters, 
80
          File file, 
81
          FeatureType ftype, 
82
          CsvPreference csvpreferences,
83
          SpatialIndex spatialIndex
84
    ) {
85
    this.file = file;
86
    this.ftype = ftype;
87
    this.storeParameters = storeParameters;
88
    if (csvpreferences == null) {
89
      this.csvpreferences = CSVStoreParameters.getPredefinedCSVPreferences(storeParameters);
90
    } else {
91
      this.csvpreferences = csvpreferences;
92
    }
93

    
94
    if (this.ftype != null) {
95
      this.descriptors = this.ftype.getAttributeDescriptors();
96
      if (ftype.getDefaultGeometryAttributeName() != null) {
97
        this.calculate_envelope = true;
98
      }
99
    }
100
    this.convert = ToolsLocator.getDataTypesManager().getCoercion(DataTypes.STRING);
101
//    this.converContext = DataTypeUtils.coerceContextLocale(CSVStoreParameters.getLocale(this.storeParameters));
102
    this.errorcounts = 0;
103
    this.charset = CSVStoreParameters.getCharset(storeParameters);
104
    this.includeMetadataInHeader = CSVStoreParameters.getIncludeMetadataInHeader(storeParameters);
105
    this.locale = CSVStoreParameters.getLocale(storeParameters);
106
    this.geometryManager = GeometryLocator.getGeometryManager();
107
    this.spatialIndex = spatialIndex;
108
    if( spatialIndex != null ) {
109
        spatialIndex.removeAll();
110
    }
111

    
112
  }
113

    
114
  public void beginAppend() {
115
    try {
116
      FileOutputStream fos = new FileOutputStream(file, true);
117
      if (this.charset != null) {
118
        this.writer = new OutputStreamWriter(fos, this.charset);
119
      } else {
120
        this.writer = new OutputStreamWriter(fos);
121
      }
122
      this.listWriter = new CsvListWriter(this.writer, this.csvpreferences);
123
      if (ftype != null) {
124
        this.descriptors = ftype.getAttributeDescriptors();
125
        int n = 0;
126
        for (FeatureAttributeDescriptor descriptor : descriptors) {
127
          if (descriptor.getEvaluator() == null) {
128
            n++;
129
          }
130
        }
131
        this.values = new String[n];
132
      }
133
    } catch (IOException e) {
134
      LOGGER.warn("Can't open file for write (" + file.getAbsolutePath() + ").", e);
135
      throw new RuntimeException(e);
136
    }
137
  }
138

    
139
  public void begin() {
140
    try {
141
      FileOutputStream fos = new FileOutputStream(file, false);
142
      if (this.charset != null) {
143
        this.writer = new OutputStreamWriter(fos, this.charset);
144
      } else {
145
        this.writer = new OutputStreamWriter(fos);
146
      }
147
    } catch (IOException e) {
148
      LOGGER.warn("Can't open file for write (" + file.getAbsolutePath() + ").", e);
149
      throw new RuntimeException(e);
150
    }
151
    this.listWriter = new CsvListWriter(this.writer, this.csvpreferences);
152
    int n = 0;
153
    for (FeatureAttributeDescriptor descriptor : descriptors) {
154
      if (!descriptor.isComputed()) { //descriptor.getEvaluator() == null) {
155
        n++;
156
      }
157
    }
158

    
159
    String[] header = new String[n];
160
    this.values = new String[n];
161
    n = 0;
162
      for (FeatureAttributeDescriptor descriptor : descriptors) {
163
          if (!descriptor.isComputed()) {
164
              if (includeMetadataInHeader) {
165
                header[n++] = (String) descriptor.get("all");
166
              } else {
167
                header[n++] = (String) descriptor.getName();
168
              }
169
          }
170
      }
171
      if (includeMetadataInHeader) {
172
        Tags tags = this.ftype.getTags();
173
        if( tags!=null && !tags.isEmpty() ) {
174
          String s = header[0];
175
            for (String tagName : tags) {
176
                String value = tags.getString(tagName, null);
177
                if( value!=null ) {
178
                    String sep = "/";
179
                    if(value.contains(sep)){
180
                        value = StringEscapeUtils.escapeHtml3(value);
181
                        value = StringUtils.replace(value, sep, "&#"+((int)(sep.charAt(0)))+";");
182
                        s += sep+"typetagesc"+sep+"html"+sep+tagName+"="+value;
183
                    } else {
184
                        s += sep+"typetag"+sep+tagName+"="+value;
185
                    }
186
                }
187
            }
188
            header[0] = s;
189
        }
190
      }
191
    try {
192
      listWriter.writeHeader(header);
193
    } catch (Exception e) {
194
      LOGGER.warn("Can't write header '" + ArrayUtils.toString(header) + "' file for write (" + file.getAbsolutePath() + ").", e);
195
      throw new RuntimeException(e);
196
    }
197
  }
198

    
199
  public void add(FeatureProvider feature) {
200
    if (this.calculate_envelope) {
201
      Geometry geom = feature.getDefaultGeometry();
202
      if (geom != null) {
203
        if (envelope == null) {
204
          try {
205
            envelope = (Envelope) geom.getEnvelope().clone();
206
          } catch (CloneNotSupportedException e) {
207
            LOGGER.warn("Este error no deberia pasar, siempre se puede hacer un clone de un envelope.", e);
208
          }
209
        } else {
210
          envelope.add(geom.getEnvelope());
211
        }
212
      }
213
    }
214
    if( spatialIndex!=null ) {
215
        Geometry geom = feature.getDefaultGeometry();
216
        this.spatialIndex.insert(geom, feature.getOID());
217
    }
218

    
219
    for (int i = 0; i < descriptors.length; i++) {
220
      FeatureAttributeDescriptor descriptor = descriptors[i];
221
      if (descriptor.getEvaluator() == null) {
222
        Object value = feature.get(i);
223
        try {
224
          if( descriptor.getType()==DataTypes.GEOMETRY ) {
225
              if(value != null){
226
                if( StringUtils.equalsIgnoreCase("WKT", CSVStoreParameters.getGeometryFormat(storeParameters))) {
227
                  values[i] = ((Geometry)value).convertToWKT();
228
                } else {
229
                  values[i] = ((Geometry)value).convertToHexWKB();
230
                }
231
              }
232
          } else {
233
            values[i] = (String) this.convert.coerce(value, descriptor.getCoercionContext());
234
          }
235
        } catch (CoercionException|GeometryOperationNotSupportedException|GeometryOperationException e) {
236
          try {
237
            values[i] = value.toString();
238
          } catch (Exception ex) {
239
            values[i] = "";
240
          }
241
          if (errorcounts++ <= 10) {
242
            this.lasterror = e;
243
            LOGGER.warn("Can't convert value of field " + i + " to string in CVS file '" + this.file.getAbsolutePath() + "'.", e);
244
            if (errorcounts == 10) {
245
              LOGGER.warn("Too many error writing CVS file '" + this.file.getAbsolutePath() + "', don't output more.");
246
            }
247
          }
248
        }
249
        values[i] = CSVReaderSuperCSV.escapeCRLF(values[i]);
250
      }
251
    }
252
    try {
253
      this.listWriter.write(values);
254
    } catch (IOException e) {
255
      if (errorcounts++ <= 10) {
256
        this.lasterror = e;
257
        LOGGER.warn("Can't write values to CVS file '" + this.file.getAbsolutePath() + "'.", e);
258
        if (errorcounts == 10) {
259
          LOGGER.warn("Too many error writing CVS file '" + this.file.getAbsolutePath() + "', don't output more.");
260
        }
261
      }
262
    }
263

    
264
  }
265

    
266
  public void end() throws PerformEditingException {
267
    if (this.errorcounts > 0) {
268
      throw new PerformEditingException(this.file.getAbsolutePath(), lasterror);
269
    }
270
    if (listWriter != null) {
271
      try {
272
        listWriter.close();
273
      } catch (Exception ex) {
274
        // Ignore error
275
      }
276
      listWriter = null;
277
    }
278
    if (writer != null) {
279
      try {
280
        writer.close();
281
      } catch (Exception ex) {
282
        // Ignore error
283
      }
284
      writer = null;
285
    }
286
    File indexFile = null;
287
    try {
288
        indexFile = CSVReaderSuperCSV.getIndexFile(this.file);
289
        if(indexFile != null){
290
            Files.deleteIfExists(indexFile.toPath());
291
        }
292
    } catch (Exception ex){
293
        LOGGER.warn("Can't delete index file '"+(indexFile == null?"null":indexFile.getAbsolutePath())+"'", ex);
294
    }
295
    if( spatialIndex!=null ) {
296
        spatialIndex.flush();
297
    }
298
  }
299

    
300
  public Envelope getEnvelope() {
301
    return this.envelope;
302
  }
303
}