Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.library / org.gvsig.exportto / org.gvsig.exportto.swing / org.gvsig.exportto.swing.prov / org.gvsig.exportto.swing.prov.jdbc / src / main / java / org / gvsig / export / jdbc / service / ExportJDBCService.java @ 44300

History | View | Annotate | Download (18.6 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
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.export.jdbc.service;
25

    
26
import java.text.MessageFormat;
27
import org.apache.commons.lang3.StringUtils;
28
import org.cresques.cts.ICoordTrans;
29
import org.cresques.cts.IProjection;
30
import org.gvsig.export.ExportAttributes;
31

    
32
import org.gvsig.fmap.dal.exception.DataException;
33
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
34
import org.gvsig.fmap.dal.feature.EditableFeatureType;
35
import org.gvsig.fmap.dal.feature.FeatureType;
36
import org.gvsig.fmap.dal.DALLocator;
37
import org.gvsig.fmap.dal.DataManager;
38
import org.gvsig.fmap.dal.DataTypes;
39
import org.gvsig.fmap.dal.NewDataStoreParameters;
40
import org.gvsig.fmap.dal.OpenDataStoreParameters;
41
import org.gvsig.fmap.dal.feature.EditableFeature;
42
import org.gvsig.fmap.dal.feature.Feature;
43
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
44
import org.gvsig.fmap.dal.feature.FeatureSet;
45
import org.gvsig.fmap.dal.feature.FeatureStore;
46
import org.gvsig.fmap.dal.feature.FeatureStoreProviderFactory;
47
import org.gvsig.fmap.dal.store.jdbc.JDBCNewStoreParameters;
48
import org.gvsig.fmap.dal.store.jdbc.JDBCServerExplorer;
49
import org.gvsig.fmap.dal.store.jdbc.JDBCStoreParameters;
50
import org.gvsig.fmap.geom.Geometry;
51
import org.gvsig.tools.dispose.DisposableIterator;
52
import org.gvsig.export.ExportException;
53
import org.gvsig.export.ExportLocator;
54
import org.gvsig.export.spi.ExportService;
55
import org.gvsig.export.spi.AbstractExportService;
56
import org.gvsig.export.spi.AttributeNamesTranslator;
57
import org.gvsig.export.spi.ExportServiceFactory;
58
import org.gvsig.export.spi.ExportServiceManager;
59
import org.gvsig.export.spi.ExportServiceManager.FixGeometryStatus;
60

    
61
/**
62
 * @author gvSIG Team
63
 * @version $Id$
64
 *
65
 */
66
public class ExportJDBCService
67
        extends AbstractExportService
68
        implements ExportService {
69

    
70
    private FeatureType targetFeatureType;
71

    
72
    protected ExportJDBCService(ExportServiceFactory factory, ExportJDBCParameters parameters) {
73
        super(factory, parameters);
74
    }
75

    
76
    @Override
77
    public ExportJDBCParameters getParameters() {
78
        return (ExportJDBCParameters) super.getParameters();
79
    }
80

    
81
    @Override
82
    protected JDBCServerExplorer createServerExplorer() throws ExportException {
83
        try {
84
            DataManager dataManager = DALLocator.getDataManager();
85

    
86
            JDBCServerExplorer explorer = (JDBCServerExplorer) dataManager.openServerExplorer(
87
                    this.getParameters().getExplorerParameters().getExplorerName(),
88
                    this.getParameters().getExplorerParameters()
89
            );
90
            return explorer;
91
        } catch (Exception e) {
92
            throw new ExportException(e);
93
        }
94
    }
95

    
96
    @Override
97
    protected NewDataStoreParameters createTargetNewStoreParameters() throws ExportException {
98
        try {
99
            FeatureType targetTempFeatureType;
100
            EditableFeatureType targetEditableFeatureType;
101

    
102
            JDBCServerExplorer explorer = this.createServerExplorer();
103

    
104
            DataManager manager = DALLocator.getDataManager();
105
            FeatureStoreProviderFactory factory = (FeatureStoreProviderFactory) manager.getStoreProviderFactory(explorer.getStoreName());
106

    
107
            boolean preferNotToUseNonNullRestrictions = factory.preferNotToUseNonNullRestrictions();
108
            ExportAttributes exportAttributes = getParameters().getExportAttributes();
109

    
110
            AttributeNamesTranslator nameTranslator = this.getFactory().createAttributeNamesTranslator();
111
            ExportAttributes exportAttr = this.getParameters().getExportAttributes();
112
            exportAttr.setNamesTranslator(nameTranslator);
113

    
114
            targetTempFeatureType = exportAttributes.getTargetFeatureType().getCopy();
115
            targetEditableFeatureType = targetTempFeatureType.getEditable();
116

    
117
            // Remove inherited primary keys from the data source and remove NotNull
118
            // restrictions if proceed.
119
            for (int i = 0; i < targetEditableFeatureType.size(); i++) {
120
                EditableFeatureAttributeDescriptor eAttr = (EditableFeatureAttributeDescriptor) targetEditableFeatureType.get(i);
121
                eAttr.setIsPrimaryKey(false);
122
                if (preferNotToUseNonNullRestrictions) {
123
                    eAttr.setAllowNull(true);
124
                }
125
            }
126

    
127
            if (this.getParameters().getPrimaryKey() != null) {
128
                EditableFeatureAttributeDescriptor pk = (EditableFeatureAttributeDescriptor) targetEditableFeatureType.get(getTranslatedIdentifier(getParameters().getPrimaryKey()));
129
                if (pk == null) {
130
                    pk = targetEditableFeatureType.add(
131
                            getTranslatedIdentifier(this.getParameters().getPrimaryKey()),
132
                            DataTypes.LONG
133
                    );
134
                    pk.setIsPrimaryKey(true);
135
                    pk.setIsAutomatic(true);
136
                } else {
137
                    pk.setIsPrimaryKey(true);
138
                }
139
            }
140

    
141
            if (this.getParameters().getCreateIndexInGeometryRow()) {
142
                EditableFeatureAttributeDescriptor x = (EditableFeatureAttributeDescriptor) targetEditableFeatureType.getDefaultGeometryAttribute();
143
                x.setIsIndexed(true);
144
            }
145

    
146
            // ======================================================
147
            // Reprojection: set SRS of geometry field to target SRS
148
            EditableFeatureAttributeDescriptor attrdescriptor
149
                    = (EditableFeatureAttributeDescriptor) targetEditableFeatureType.getDefaultGeometryAttribute();
150
            if (attrdescriptor != null) {
151
                attrdescriptor.setSRS(this.getParameters().getTargetProjection());
152
            }
153

    
154
            // ======================================
155
            // Remove index to improve performance
156
            this.targetFeatureType = targetEditableFeatureType.getNotEditableCopy();
157
            for (int i = 0; i < targetEditableFeatureType.size(); i++) {
158
                EditableFeatureAttributeDescriptor x = (EditableFeatureAttributeDescriptor) targetEditableFeatureType.get(i);
159
                //x.setIsPrimaryKey(false);
160
                x.setIsIndexed(false);
161
            }
162

    
163
            // ======================================
164
            JDBCNewStoreParameters createTableParams = (JDBCNewStoreParameters) explorer.getAddParameters();
165

    
166
            createTableParams.setSelectRole(this.getParameters().getSelectRole());
167
            createTableParams.setInsertRole(this.getParameters().getInsertRole());
168
            createTableParams.setUpdateRole(this.getParameters().getUpdateRole());
169
            createTableParams.setDeleteRole(this.getParameters().getDeleteRole());
170
            createTableParams.setTruncateRole(this.getParameters().getTruncateRole());
171
            createTableParams.setReferenceRole(this.getParameters().getReferenceRole());
172
            createTableParams.setTriggerRole(this.getParameters().getTriggerRole());
173
            createTableParams.setAllRole(this.getParameters().getAllRole());
174

    
175
            createTableParams.setSchema(this.getParameters().getSchema());
176
            createTableParams.setPostCreatingStatement(this.getParameters().getPostCreatingStatement());
177

    
178
            createTableParams.setDefaultFeatureType(targetEditableFeatureType);
179
            createTableParams.setTable(this.getParameters().getTableName());
180

    
181
            return createTableParams;
182

    
183
        } catch (Exception ex) {
184
            throw new ExportException(ex);
185
        }
186
    }
187

    
188
    @Override
189
    public OpenDataStoreParameters createTargetOpenStoreParameters() throws ExportException {
190
        try {
191
            DataManager dataManager = DALLocator.getDataManager();
192
            JDBCServerExplorer explorer = this.createServerExplorer();
193

    
194
            JDBCStoreParameters openStoreParameters = (JDBCStoreParameters) explorer.getOpenParameters();
195
            openStoreParameters.setSchema(this.getParameters().getSchema());
196
            openStoreParameters.setTable(this.getParameters().getTableName());
197
            openStoreParameters.setCRS(this.getParameters().getTargetProjection());
198
            openStoreParameters.setDefaultGeometryField(
199
                    this.getParameters().getSourceFeatureType().getDefaultGeometryAttributeName()
200
            );
201
            return openStoreParameters;
202
        } catch (DataException ex) {
203
            throw new ExportException(ex);
204
        }
205
    }
206

    
207
    protected String getTranslatedIdentifier(String identifier) {
208
        String s = identifier;
209
        ExportJDBCAttributeNamesTranslator nameTranslator = (ExportJDBCAttributeNamesTranslator) this.getParameters().getExportAttributes().getNamesTranslator();
210
        if (nameTranslator.getTranslateIdentifiersToLowerCase()) {
211
            s = s.toLowerCase();
212
        }
213
        if (nameTranslator.getTranslateHyphens()) {
214
            s = s.replace("-", "_");
215
        }
216
        if (nameTranslator.getRemoveSpacesInIdentifiers()) {
217
            s = StringUtils.normalizeSpace(s).replace(" ", "_");
218
        }
219
        return s;
220
    }
221

    
222
    private int getGeometryColumnCount(FeatureType featureType) {
223
        int count = 0;
224
        for (int i = 0; i < featureType.size(); i++) {
225
            if (featureType.getAttributeDescriptor(i).getType() == DataTypes.GEOMETRY) {
226
                count++;
227
            }
228
        }
229
        return count;
230
    }
231

    
232
    @Override
233
    public void export(FeatureSet featureSet) throws ExportException {
234
        Geometry.ValidationStatus geometryCheck;
235

    
236
        DisposableIterator it = null;
237
        EditableFeature targetFeature = null;
238
        FeatureStore target = null;
239

    
240
        try {
241
            ExportServiceManager serviceManager = ExportLocator.getServiceManager();
242

    
243
            // ======================================
244
            // Reprojection
245
            FeatureAttributeDescriptor geo_att = this.getParameters().getSourceFeatureType().getDefaultGeometryAttribute();
246
            IProjection sourceProjection;
247
            ICoordTrans coord_trans = null;
248
            Geometry reproj_geom;
249
            IProjection targetProjection = this.getParameters().getTargetProjection();
250
            if (geo_att != null) {
251
                sourceProjection = geo_att.getSRS();
252
                // this comparison is perhaps too preventive
253
                // we could  have two instances of same projection
254
                // so we would do more computations than needed
255
                if (sourceProjection != null && targetProjection != null && sourceProjection != targetProjection) {
256
                    coord_trans = sourceProjection.getCT(targetProjection);
257
                }
258
            }
259
            // ============================================
260

    
261
            DataManager dataManager = DALLocator.getDataManager();
262

    
263
            JDBCServerExplorer explorer = this.createServerExplorer();
264

    
265
            if (this.getParameters().canCreatetable()) {
266
                LOG.debug("Creating table");
267
                getTaskStatus().message("Creating table");
268
                NewDataStoreParameters targetNewStoreParameters = this.createTargetNewStoreParameters();
269
                explorer.add(
270
                        targetNewStoreParameters.getDataStoreName(),
271
                        targetNewStoreParameters,
272
                        true
273
                );
274
            }
275

    
276
            JDBCStoreParameters openParams = (JDBCStoreParameters) this.createTargetOpenStoreParameters();
277
            target = (FeatureStore) explorer.open(openParams);
278

    
279
            FeatureType theTargetFeatureType = target.getDefaultFeatureType();
280
            FeatureType theSourceFeatureType = featureSet.getDefaultFeatureType();
281

    
282
            target.edit(FeatureStore.MODE_APPEND);
283

    
284
            long featureCount = 1;
285
            getTaskStatus().setRangeOfValues(0, featureSet.getSize());
286

    
287
            int targetGeometryIndex;
288
            int sourceGeometryIndex;
289
            if (getGeometryColumnCount(theSourceFeatureType) == 1
290
                    && getGeometryColumnCount(theTargetFeatureType) == 1) {
291
                // Si solo hay una columna de geometria asignaremos las geometrias
292
                // independientemente de como se llamen los campos.
293
                targetGeometryIndex = theTargetFeatureType.getDefaultGeometryAttributeIndex();
294
                sourceGeometryIndex = theSourceFeatureType.getDefaultGeometryAttributeIndex();
295
            } else {
296
                FeatureAttributeDescriptor attr = theSourceFeatureType.getDefaultGeometryAttribute();
297
                sourceGeometryIndex = attr.getIndex();
298
                targetGeometryIndex = theTargetFeatureType.getAttributeDescriptor(attr.getName()).getIndex();
299
            }
300

    
301
            LOG.debug("Inserting rows");
302
            getTaskStatus().message("Inserting rows");
303
            it = featureSet.fastIterator();
304
            while (it.hasNext()) {
305
                Feature feature = (Feature) it.next();
306
                this.getTaskStatus().setCurValue(featureCount);
307

    
308
                targetFeature = target.createNewFeature(theTargetFeatureType, feature);
309
                for (int i = 0; i < theSourceFeatureType.size(); i++) {
310
                    if (i == sourceGeometryIndex) {
311
                        // Es facil que los campos geometria no se llamen igual, asi que
312
                        // el campo geometria lo asignamos a capon.
313
                        // Esto puede ocasionar problemas cuando la tabla destino no tenga
314
                        // geometria o tenga mas de una.
315
                        targetFeature.set(targetGeometryIndex, feature.get(sourceGeometryIndex));
316
                    } else {
317
                        FeatureAttributeDescriptor sourceField = theSourceFeatureType.getAttributeDescriptor(i);
318
//                        String name = getTranslatedIdentifier(x.getName());
319
                        String targetField = this.getParameters().getExportAttributes().getTargetName(sourceField.getName());
320
                        int targetAttributeIndex = theTargetFeatureType.getIndex(targetField);
321
                        if (targetAttributeIndex < 0) {
322
                            continue;
323
                            //throw new RuntimeException("Can't locate column '" + x.getName() + "' in the target table.");
324
                        }
325
                        targetFeature.set(targetAttributeIndex, feature.get(sourceField.getName()));
326
                    }
327
                }
328

    
329
                Geometry geometry = targetFeature.getGeometry(targetGeometryIndex);
330
                FixGeometryStatus check = serviceManager.fixGeometry(getParameters(), coord_trans, geometry);
331
                switch (check.getState()) {
332
                    case FixGeometryStatus.STATE_OK:
333
                        targetFeature.setDefaultGeometry(check.getGeometry());
334
                        break;
335
                    case FixGeometryStatus.STATE_SKIP:
336
                        continue;
337
                    case FixGeometryStatus.STATE_ABORT:
338
                        throw new InvalidGeometryException(targetFeature, check.getMessage());
339
                }
340

    
341
                target.insert(targetFeature);
342

    
343
                if (this.getTaskStatus().isCancellationRequested()) {
344
                    return;
345
                }
346
                featureCount++;
347
            }
348
            String msgRowCount = MessageFormat.format(" ({0,number, #,###} rows)", featureCount);
349
            targetFeature = null;
350
            getTaskStatus().setIndeterminate();
351
            LOG.debug("Finish editing" + msgRowCount);
352
            if (featureCount > 50000) {
353
                getTaskStatus().message("Finishing insertion of records, may take a while" + msgRowCount);
354
            } else {
355
                getTaskStatus().message("Finishing insertion of records" + msgRowCount);
356
            }
357
            target.finishEditing();
358

    
359
            if (this.getParameters().canCreatetable()) {
360
                getTaskStatus().message("Preparing the update of the indices" + msgRowCount);
361
                target.edit();
362
                EditableFeatureType ft = target.getDefaultFeatureType().getEditable();
363
                for (FeatureAttributeDescriptor attr : this.targetFeatureType) {
364
                    EditableFeatureAttributeDescriptor attr2 = (EditableFeatureAttributeDescriptor) ft.getAttributeDescriptor(attr.getName());
365
                    if (attr2 != null) {
366
                        //attr2.setIsPrimaryKey(attr.isPrimaryKey());
367
                        attr2.setIsIndexed(attr.isIndexed());
368
                        attr2.setIsAutomatic(attr.isAutomatic());
369
                    }
370
                }
371
                target.update(ft);
372
                getTaskStatus().message("Updating the indices" + msgRowCount);
373
                target.finishEditing();
374
            }
375
            if (this.getParameters().getUpdateTableStatistics()) {
376
                LOG.debug("Updating statistics");
377
                getTaskStatus().message("Updating statistics" + msgRowCount);
378
                explorer.updateTableStatistics(
379
                        openParams.getDBName(),
380
                        openParams.getSchema(),
381
                        openParams.getTable()
382
                );
383
            }
384
            LOG.debug("finish");
385
            getTaskStatus().message("Exportation finished");
386
            getTaskStatus().terminate();
387

    
388
        } catch (Exception e) {
389
            LOG.warn("Can't export data.", e);
390
            getTaskStatus().message("Problems exporting data");
391
            throw new ExportException(e, targetFeature);
392

    
393
        } finally {
394
            if (it != null) {
395
                it.dispose();
396
            }
397
            featureSet.dispose();
398
            if (target != null) {
399
                if (target.isAppending()) {
400
                    try {
401
                        target.cancelEditing();
402
                    } catch (Exception ex) {
403
                        LOG.warn("Can't cancel editing.", ex);
404
                    }
405
                }
406
                target.dispose();
407
            }
408
            this.getTaskStatus().terminate();
409
            this.getTaskStatus().remove();
410
        }
411
    }
412

    
413
}