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

History | View | Annotate | Download (18.3 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.cresques.cts.ICoordTrans;
28
import org.gvsig.export.ExportAttributes;
29

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

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

    
69
    private FeatureType targetFeatureType;
70

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

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

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

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

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

    
101
            JDBCServerExplorer explorer = this.createServerExplorer();
102

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

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

    
109

    
110
            targetTempFeatureType = exportAttributes.getTargetFeatureType().getCopy();
111
            targetEditableFeatureType = targetTempFeatureType.getEditable();
112

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

    
123

    
124
            String pkname = getParameters().getPrimaryKey();
125
            if (pkname != null) {
126
                // pkname it's not part of exportattributes list.
127
                pkname = getParameters().getExportAttributes().getNamesTranslator().getSuggestion(pkname);
128
                EditableFeatureAttributeDescriptor pk = (EditableFeatureAttributeDescriptor) targetEditableFeatureType.get(pkname);
129
                if (pk == null) {
130
                    pk = targetEditableFeatureType.add(pkname, DataTypes.LONG);
131
                    pk.setIsPrimaryKey(true);
132
                    pk.setIsAutomatic(true);
133
                } else {
134
                    pk.setIsPrimaryKey(true);
135
                }
136
            }
137

    
138
            EditableFeatureAttributeDescriptor attrdescriptor = (EditableFeatureAttributeDescriptor) targetEditableFeatureType.getDefaultGeometryAttribute();
139
            if (attrdescriptor != null && this.getParameters().getCreateIndexInGeometryRow()) {
140
                attrdescriptor.setIsIndexed(true);
141
            }
142

    
143
            // ======================================================
144
            // Reprojection: set SRS of geometry field to target SRS
145
            if (attrdescriptor != null) {
146
                attrdescriptor.setSRS(this.getParameters().getTargetProjection());
147
                attrdescriptor.setGeometryType(this.getParameters().getTargetGeometryType());
148
            }
149

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

    
159
            // ======================================
160
            JDBCNewStoreParameters createTableParams = (JDBCNewStoreParameters) explorer.getAddParameters();
161

    
162
            createTableParams.setSelectRole(this.getParameters().getSelectRole());
163
            createTableParams.setInsertRole(this.getParameters().getInsertRole());
164
            createTableParams.setUpdateRole(this.getParameters().getUpdateRole());
165
            createTableParams.setDeleteRole(this.getParameters().getDeleteRole());
166
            createTableParams.setTruncateRole(this.getParameters().getTruncateRole());
167
            createTableParams.setReferenceRole(this.getParameters().getReferenceRole());
168
            createTableParams.setTriggerRole(this.getParameters().getTriggerRole());
169
            createTableParams.setAllRole(this.getParameters().getAllRole());
170

    
171
            createTableParams.setSchema(this.getParameters().getSchema());
172
            createTableParams.setPostCreatingStatement(this.getParameters().getPostCreatingStatement());
173

    
174
            createTableParams.setDefaultFeatureType(targetEditableFeatureType);
175
            createTableParams.setTable(this.getParameters().getTableName());
176

    
177
            return createTableParams;
178

    
179
        } catch (Exception ex) {
180
            throw new ExportException(ex);
181
        }
182
    }
183

    
184
    @Override
185
    public OpenDataStoreParameters createTargetOpenStoreParameters() throws ExportException {
186
        try {
187
            DataManager dataManager = DALLocator.getDataManager();
188
            JDBCServerExplorer explorer = this.createServerExplorer();
189

    
190
            JDBCStoreParameters openStoreParameters = (JDBCStoreParameters) explorer.getOpenParameters();
191
            openStoreParameters.setSchema(this.getParameters().getSchema());
192
            openStoreParameters.setTable(this.getParameters().getTableName());
193
            openStoreParameters.setCRS(this.getParameters().getTargetProjection());
194
            openStoreParameters.setDefaultGeometryField(
195
                    this.getParameters().getTargetFeatureType().getDefaultGeometryAttributeName()
196
            );
197
            return openStoreParameters;
198
        } catch (DataException ex) {
199
            throw new ExportException(ex);
200
        }
201
    }
202

    
203

    
204

    
205
    private int getGeometryColumnCount(FeatureType featureType) {
206
        int count = 0;
207
        for (int i = 0; i < featureType.size(); i++) {
208
            if (featureType.getAttributeDescriptor(i).getType() == DataTypes.GEOMETRY) {
209
                count++;
210
            }
211
        }
212
        return count;
213
    }
214

    
215
    @Override
216
    public void export(FeatureSet featureSet) throws ExportException {
217
        Geometry.ValidationStatus geometryCheck;
218

    
219
        DisposableIterator it = null;
220
        EditableFeature targetFeature = null;
221
        FeatureStore target = null;
222
        Feature feature = null;
223

    
224
        try {
225
            ExportServiceManager serviceManager = ExportLocator.getServiceManager();
226

    
227
            // ======================================
228
            // Reprojection
229
            ICoordTrans coord_trans = this.getParameters().getTransformationToUse();
230
            // ============================================
231

    
232
            DataManager dataManager = DALLocator.getDataManager();
233

    
234
            JDBCServerExplorer explorer = this.createServerExplorer();
235

    
236
            if (this.getParameters().canCreatetable()) {
237
                LOG.debug("Creating table");
238
                getTaskStatus().message("Creating table");
239
                NewDataStoreParameters targetNewStoreParameters = this.createTargetNewStoreParameters();
240
                explorer.add(
241
                        targetNewStoreParameters.getDataStoreName(),
242
                        targetNewStoreParameters,
243
                        true
244
                );
245
                
246
                //We collect the name of the table of targetNewStoreParameters 
247
                //because the provider has been able to make changes to it
248
                this.getParameters().setTableName(((JDBCNewStoreParameters)targetNewStoreParameters).getTable());
249
            }
250

    
251
            JDBCStoreParameters openParams = (JDBCStoreParameters) this.createTargetOpenStoreParameters();
252
            target = (FeatureStore) explorer.open(openParams);
253

    
254
            FeatureType theTargetFeatureType = target.getDefaultFeatureType();
255
            FeatureType theSourceFeatureType = featureSet.getDefaultFeatureType();
256

    
257
            target.edit(FeatureStore.MODE_APPEND);
258

    
259
            long featureCount = 1;
260
            getTaskStatus().setRangeOfValues(0, featureSet.getSize());
261

    
262
            int targetGeometryIndex = -1;
263
            int sourceGeometryIndex = -1;
264
            if (getGeometryColumnCount(theSourceFeatureType) == 1
265
                    && getGeometryColumnCount(theTargetFeatureType) == 1) {
266
                // Si solo hay una columna de geometria asignaremos las geometrias
267
                // independientemente de como se llamen los campos.
268
                targetGeometryIndex = theTargetFeatureType.getDefaultGeometryAttributeIndex();
269
                sourceGeometryIndex = theSourceFeatureType.getDefaultGeometryAttributeIndex();
270
            } else {
271
                FeatureAttributeDescriptor attr = theSourceFeatureType.getDefaultGeometryAttribute();
272
                if (attr!=null && theTargetFeatureType.getAttributeDescriptor(attr.getName())!=null) {
273
                    sourceGeometryIndex = attr.getIndex();
274
                    targetGeometryIndex = theTargetFeatureType.getAttributeDescriptor(attr.getName()).getIndex();
275
                }
276
            }
277

    
278
            if(targetGeometryIndex != -1){
279
                GeometryCoercionContext coercionContext = (GeometryCoercionContext) theTargetFeatureType.getAttributeDescriptor(targetGeometryIndex).getCoercionContext();
280
                if(coercionContext!=null){
281
                    coercionContext.setMode(GeometryCoercionContext.MODE_ONERROR_NULL);
282
                }
283
            }
284
            LOG.debug("Inserting rows");
285
            getTaskStatus().message("Inserting rows");
286
            it = featureSet.fastIterator();
287
            while (it.hasNext()) {
288
                feature = (Feature) it.next();
289
                this.getTaskStatus().setCurValue(featureCount);
290

    
291
                targetFeature = target.createNewFeature(theTargetFeatureType, true);
292
                targetFeature.copyFrom(feature);
293
                for (int i = 0; i < theSourceFeatureType.size(); i++) {
294
                    if (i == sourceGeometryIndex) {
295
                        // Es facil que los campos geometria no se llamen igual, asi que
296
                        // el campo geometria lo asignamos a capon.
297
                        // Esto puede ocasionar problemas cuando la tabla destino no tenga
298
                        // geometria o tenga mas de una.
299
                        targetFeature.set(targetGeometryIndex, feature.get(sourceGeometryIndex));
300
                    } else {
301
                        FeatureAttributeDescriptor sourceField = theSourceFeatureType.getAttributeDescriptor(i);
302
//                        String name = getTranslatedIdentifier(x.getName());
303
                        if (!this.getParameters().getExportAttributes().getExportAttribute(sourceField.getName()).isExported()) {
304
                            continue;
305
                        }
306
                        String targetField = this.getParameters().getExportAttributes().getTargetName(sourceField.getName());
307
                        int targetAttributeIndex = theTargetFeatureType.getIndex(targetField);
308
                        if (targetAttributeIndex < 0 ) {
309
                            continue;
310
                            //throw new RuntimeException("Can't locate column '" + x.getName() + "' in the target table.");
311
                        }
312
                        if (theTargetFeatureType.getAttributeDescriptor(targetField).isReadOnly() ) {
313
                            continue;
314
                        }
315
                        targetFeature.set(targetAttributeIndex, feature.get(sourceField.getName()));
316
                    }
317
                }
318

    
319
                if (targetGeometryIndex!=-1) {
320
                    Geometry geometry = targetFeature.getGeometry(targetGeometryIndex);
321
                
322
                    FixGeometryStatus check = serviceManager.fixGeometry(getParameters(), coord_trans, geometry);
323
                    switch (check.getState()) {
324
                        case FixGeometryStatus.STATE_OK:
325
                            targetFeature.setDefaultGeometry(check.getGeometry());
326
                            break;
327
                        case FixGeometryStatus.STATE_SKIP:
328
                            continue;
329
                        case FixGeometryStatus.STATE_ABORT:
330
                            throw new InvalidGeometryException(targetFeature, check.getMessage());
331
                    }
332
                }
333

    
334
                target.insert(targetFeature);
335

    
336
                if (this.getTaskStatus().isCancellationRequested()) {
337
                    return;
338
                }
339
                featureCount++;
340
            }
341
            String msgRowCount = MessageFormat.format(" ({0,number, #,###} rows)", featureCount);
342
            targetFeature = null;
343
            getTaskStatus().setIndeterminate();
344
            LOG.debug("Finish editing" + msgRowCount);
345
            if (featureCount > 50000) {
346
                getTaskStatus().message("Finishing insertion of records, may take a while" + msgRowCount);
347
            } else {
348
                getTaskStatus().message("Finishing insertion of records" + msgRowCount);
349
            }
350
            target.finishEditing();
351

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

    
381
        } catch (Exception e) {
382
            LOG.warn("Can't export data.", e);
383
            getTaskStatus().message("Problems exporting data");
384
            throw new ExportException(e, targetFeature);
385

    
386
        } finally {
387
            if (it != null) {
388
                it.dispose();
389
            }
390
            featureSet.dispose();
391
            if (target != null) {
392
                if (target.isAppending()) {
393
                    try {
394
                        target.cancelEditing();
395
                    } catch (Exception ex) {
396
                        LOG.warn("Can't cancel editing.", ex);
397
                    }
398
                }
399
                target.dispose();
400
            }
401
            this.getTaskStatus().terminate();
402
            this.getTaskStatus().remove();
403
        }
404
    }
405

    
406
}