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

History | View | Annotate | Download (17.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

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

    
67
    private FeatureType targetFeatureType;
68

    
69
    protected ExportJDBCService(ExportServiceFactory factory, ExportJDBCParameters parameters) {
70
        super(factory, parameters);
71
    }
72

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

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

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

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

    
99
            JDBCServerExplorer explorer = this.createServerExplorer();
100

    
101
            DataManager manager = DALLocator.getDataManager();
102
            FeatureStoreProviderFactory factory = (FeatureStoreProviderFactory) manager.getStoreProviderFactory(explorer.getStoreName());
103

    
104
            boolean preferNotToUseNonNullRestrictions = factory.preferNotToUseNonNullRestrictions();
105
            ExportAttributes exportAttributes = getParameters().getExportAttributes();
106

    
107

    
108
            targetTempFeatureType = exportAttributes.getTargetFeatureType().getCopy();
109
            targetEditableFeatureType = targetTempFeatureType.getEditable();
110

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

    
121

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

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

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

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

    
156
            // ======================================
157
            JDBCNewStoreParameters createTableParams = (JDBCNewStoreParameters) explorer.getAddParameters();
158

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

    
168
            createTableParams.setSchema(this.getParameters().getSchema());
169
            createTableParams.setPostCreatingStatement(this.getParameters().getPostCreatingStatement());
170

    
171
            createTableParams.setDefaultFeatureType(targetEditableFeatureType);
172
            createTableParams.setTable(this.getParameters().getTableName());
173

    
174
            return createTableParams;
175

    
176
        } catch (Exception ex) {
177
            throw new ExportException(ex);
178
        }
179
    }
180

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

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

    
200

    
201

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

    
212
    @Override
213
    public void export(FeatureSet featureSet) throws ExportException {
214
        Geometry.ValidationStatus geometryCheck;
215

    
216
        DisposableIterator it = null;
217
        EditableFeature targetFeature = null;
218
        FeatureStore target = null;
219

    
220
        try {
221
            ExportServiceManager serviceManager = ExportLocator.getServiceManager();
222

    
223
            // ======================================
224
            // Reprojection
225
            ICoordTrans coord_trans = this.getParameters().getTransformationToUse();
226
            // ============================================
227

    
228
            DataManager dataManager = DALLocator.getDataManager();
229

    
230
            JDBCServerExplorer explorer = this.createServerExplorer();
231

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

    
247
            JDBCStoreParameters openParams = (JDBCStoreParameters) this.createTargetOpenStoreParameters();
248
            target = (FeatureStore) explorer.open(openParams);
249

    
250
            FeatureType theTargetFeatureType = target.getDefaultFeatureType();
251
            FeatureType theSourceFeatureType = featureSet.getDefaultFeatureType();
252

    
253
            target.edit(FeatureStore.MODE_APPEND);
254

    
255
            long featureCount = 1;
256
            getTaskStatus().setRangeOfValues(0, featureSet.getSize());
257

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

    
274
            LOG.debug("Inserting rows");
275
            getTaskStatus().message("Inserting rows");
276
            it = featureSet.fastIterator();
277
            while (it.hasNext()) {
278
                Feature feature = (Feature) it.next();
279
                this.getTaskStatus().setCurValue(featureCount);
280

    
281
                targetFeature = target.createNewFeature(theTargetFeatureType, feature);
282
                for (int i = 0; i < theSourceFeatureType.size(); i++) {
283
                    if (i == sourceGeometryIndex) {
284
                        // Es facil que los campos geometria no se llamen igual, asi que
285
                        // el campo geometria lo asignamos a capon.
286
                        // Esto puede ocasionar problemas cuando la tabla destino no tenga
287
                        // geometria o tenga mas de una.
288
                        targetFeature.set(targetGeometryIndex, feature.get(sourceGeometryIndex));
289
                    } else {
290
                        FeatureAttributeDescriptor sourceField = theSourceFeatureType.getAttributeDescriptor(i);
291
//                        String name = getTranslatedIdentifier(x.getName());
292
                        String targetField = this.getParameters().getExportAttributes().getTargetName(sourceField.getName());
293
                        int targetAttributeIndex = theTargetFeatureType.getIndex(targetField);
294
                        if (targetAttributeIndex < 0) {
295
                            continue;
296
                            //throw new RuntimeException("Can't locate column '" + x.getName() + "' in the target table.");
297
                        }
298
                        targetFeature.set(targetAttributeIndex, feature.get(sourceField.getName()));
299
                    }
300
                }
301

    
302
                if (targetGeometryIndex!=-1) {
303
                    Geometry geometry = targetFeature.getGeometry(targetGeometryIndex);
304
                
305
                    FixGeometryStatus check = serviceManager.fixGeometry(getParameters(), coord_trans, geometry);
306
                    switch (check.getState()) {
307
                        case FixGeometryStatus.STATE_OK:
308
                            targetFeature.setDefaultGeometry(check.getGeometry());
309
                            break;
310
                        case FixGeometryStatus.STATE_SKIP:
311
                            continue;
312
                        case FixGeometryStatus.STATE_ABORT:
313
                            throw new InvalidGeometryException(targetFeature, check.getMessage());
314
                    }
315
                }
316

    
317
                target.insert(targetFeature);
318

    
319
                if (this.getTaskStatus().isCancellationRequested()) {
320
                    return;
321
                }
322
                featureCount++;
323
            }
324
            String msgRowCount = MessageFormat.format(" ({0,number, #,###} rows)", featureCount);
325
            targetFeature = null;
326
            getTaskStatus().setIndeterminate();
327
            LOG.debug("Finish editing" + msgRowCount);
328
            if (featureCount > 50000) {
329
                getTaskStatus().message("Finishing insertion of records, may take a while" + msgRowCount);
330
            } else {
331
                getTaskStatus().message("Finishing insertion of records" + msgRowCount);
332
            }
333
            target.finishEditing();
334

    
335
            if (this.getParameters().canCreatetable()) {
336
                getTaskStatus().message("Preparing the update of the indices" + msgRowCount);
337
                target.edit();
338
                EditableFeatureType ft = target.getDefaultFeatureType().getEditable();
339
                for (FeatureAttributeDescriptor attr : this.targetFeatureType) {
340
                    EditableFeatureAttributeDescriptor attr2 = (EditableFeatureAttributeDescriptor) ft.getAttributeDescriptor(attr.getName());
341
                    if (attr2 != null) {
342
                        //attr2.setIsPrimaryKey(attr.isPrimaryKey());
343
                        attr2.setIsIndexed(attr.isIndexed());
344
                        attr2.setIsAutomatic(attr.isAutomatic());
345
                    }
346
                }
347
                target.update(ft);
348
                getTaskStatus().message("Updating the indices" + msgRowCount);
349
                target.finishEditing();
350
            }
351
            if (this.getParameters().getUpdateTableStatistics()) {
352
                LOG.debug("Updating statistics");
353
                getTaskStatus().message("Updating statistics" + msgRowCount);
354
                explorer.updateTableStatistics(
355
                        openParams.getDBName(),
356
                        openParams.getSchema(),
357
                        openParams.getTable()
358
                );
359
            }
360
            LOG.debug("finish");
361
            getTaskStatus().message("Exportation finished");
362
            getTaskStatus().terminate();
363

    
364
        } catch (Exception e) {
365
            LOG.warn("Can't export data.", e);
366
            getTaskStatus().message("Problems exporting data");
367
            throw new ExportException(e, targetFeature);
368

    
369
        } finally {
370
            if (it != null) {
371
                it.dispose();
372
            }
373
            featureSet.dispose();
374
            if (target != null) {
375
                if (target.isAppending()) {
376
                    try {
377
                        target.cancelEditing();
378
                    } catch (Exception ex) {
379
                        LOG.warn("Can't cancel editing.", ex);
380
                    }
381
                }
382
                target.dispose();
383
            }
384
            this.getTaskStatus().terminate();
385
            this.getTaskStatus().remove();
386
        }
387
    }
388

    
389
}