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

History | View | Annotate | Download (18.5 KB)

1 40559 jjdelcerro
/**
2
 * gvSIG. Desktop Geographic Information System.
3 40435 jjdelcerro
 *
4 40559 jjdelcerro
 * Copyright (C) 2007-2013 gvSIG Association.
5 40435 jjdelcerro
 *
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 40559 jjdelcerro
 * as published by the Free Software Foundation; either version 3
9 40435 jjdelcerro
 * 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 40559 jjdelcerro
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23 40435 jjdelcerro
 */
24 43925 jjdelcerro
package org.gvsig.export.jdbc.service;
25 40435 jjdelcerro
26 43925 jjdelcerro
import java.text.MessageFormat;
27
import org.cresques.cts.ICoordTrans;
28 44270 omartinez
import org.gvsig.export.ExportAttributes;
29 40435 jjdelcerro
30
import org.gvsig.fmap.dal.exception.DataException;
31 43504 jjdelcerro
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
32
import org.gvsig.fmap.dal.feature.EditableFeatureType;
33 43925 jjdelcerro
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 43504 jjdelcerro
import org.gvsig.fmap.dal.feature.Feature;
41
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
42 43925 jjdelcerro
import org.gvsig.fmap.dal.feature.FeatureSet;
43 40435 jjdelcerro
import org.gvsig.fmap.dal.feature.FeatureStore;
44 43925 jjdelcerro
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 45690 fdiaz
import org.gvsig.fmap.geom.GeometryCoercionContext;
58
import org.gvsig.tools.dataTypes.CoercionContext;
59 40435 jjdelcerro
60
/**
61
 * @author gvSIG Team
62
 * @version $Id$
63 44300 omartinez
 *
64 40435 jjdelcerro
 */
65 44300 omartinez
public class ExportJDBCService
66
        extends AbstractExportService
67
        implements ExportService {
68 40435 jjdelcerro
69 43925 jjdelcerro
    private FeatureType targetFeatureType;
70
71
    protected ExportJDBCService(ExportServiceFactory factory, ExportJDBCParameters parameters) {
72
        super(factory, parameters);
73
    }
74 40435 jjdelcerro
75 43925 jjdelcerro
    @Override
76
    public ExportJDBCParameters getParameters() {
77 44300 omartinez
        return (ExportJDBCParameters) super.getParameters();
78 40435 jjdelcerro
    }
79
80 43364 jjdelcerro
    @Override
81 44300 omartinez
    protected JDBCServerExplorer createServerExplorer() throws ExportException {
82 43925 jjdelcerro
        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 44300 omartinez
101 43925 jjdelcerro
            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 44270 omartinez
            ExportAttributes exportAttributes = getParameters().getExportAttributes();
108 43925 jjdelcerro
109 44300 omartinez
110 44270 omartinez
            targetTempFeatureType = exportAttributes.getTargetFeatureType().getCopy();
111 43925 jjdelcerro
            targetEditableFeatureType = targetTempFeatureType.getEditable();
112 45808 omartinez
            targetEditableFeatureType.setHasOID(false);
113 43925 jjdelcerro
114
            // Remove inherited primary keys from the data source and remove NotNull
115
            // restrictions if proceed.
116
            for (int i = 0; i < targetEditableFeatureType.size(); i++) {
117 44270 omartinez
                EditableFeatureAttributeDescriptor eAttr = (EditableFeatureAttributeDescriptor) targetEditableFeatureType.get(i);
118
                eAttr.setIsPrimaryKey(false);
119 44300 omartinez
                if (preferNotToUseNonNullRestrictions) {
120 44270 omartinez
                    eAttr.setAllowNull(true);
121 43504 jjdelcerro
                }
122
            }
123 43925 jjdelcerro
124 44386 omartinez
125
            String pkname = getParameters().getPrimaryKey();
126
            if (pkname != null) {
127
                // pkname it's not part of exportattributes list.
128 44860 omartinez
                pkname = getParameters().getExportAttributes().getNamesTranslator().getSuggestion(pkname);
129 44386 omartinez
                EditableFeatureAttributeDescriptor pk = (EditableFeatureAttributeDescriptor) targetEditableFeatureType.get(pkname);
130 43925 jjdelcerro
                if (pk == null) {
131 44386 omartinez
                    pk = targetEditableFeatureType.add(pkname, DataTypes.LONG);
132 43925 jjdelcerro
                    pk.setIsPrimaryKey(true);
133
                    pk.setIsAutomatic(true);
134 45914 jjdelcerro
                    pk.setIsReadOnly(true);
135 43925 jjdelcerro
                } else {
136
                    pk.setIsPrimaryKey(true);
137 45914 jjdelcerro
                    pk.setIsReadOnly(true);
138 43925 jjdelcerro
                }
139
            }
140
141 45009 omartinez
            EditableFeatureAttributeDescriptor attrdescriptor = (EditableFeatureAttributeDescriptor) targetEditableFeatureType.getDefaultGeometryAttribute();
142
            if (attrdescriptor != null && this.getParameters().getCreateIndexInGeometryRow()) {
143
                attrdescriptor.setIsIndexed(true);
144 43925 jjdelcerro
            }
145
146
            // ======================================================
147
            // Reprojection: set SRS of geometry field to target SRS
148
            if (attrdescriptor != null) {
149
                attrdescriptor.setSRS(this.getParameters().getTargetProjection());
150 45690 fdiaz
                attrdescriptor.setGeometryType(this.getParameters().getTargetGeometryType());
151 43925 jjdelcerro
            }
152
153
            // ======================================
154
            // Remove index to improve performance
155
            this.targetFeatureType = targetEditableFeatureType.getNotEditableCopy();
156
            for (int i = 0; i < targetEditableFeatureType.size(); i++) {
157
                EditableFeatureAttributeDescriptor x = (EditableFeatureAttributeDescriptor) targetEditableFeatureType.get(i);
158
                //x.setIsPrimaryKey(false);
159
                x.setIsIndexed(false);
160
            }
161
162
            // ======================================
163
            JDBCNewStoreParameters createTableParams = (JDBCNewStoreParameters) explorer.getAddParameters();
164
165
            createTableParams.setSelectRole(this.getParameters().getSelectRole());
166
            createTableParams.setInsertRole(this.getParameters().getInsertRole());
167
            createTableParams.setUpdateRole(this.getParameters().getUpdateRole());
168
            createTableParams.setDeleteRole(this.getParameters().getDeleteRole());
169
            createTableParams.setTruncateRole(this.getParameters().getTruncateRole());
170
            createTableParams.setReferenceRole(this.getParameters().getReferenceRole());
171
            createTableParams.setTriggerRole(this.getParameters().getTriggerRole());
172
            createTableParams.setAllRole(this.getParameters().getAllRole());
173
174
            createTableParams.setSchema(this.getParameters().getSchema());
175
            createTableParams.setPostCreatingStatement(this.getParameters().getPostCreatingStatement());
176
177
            createTableParams.setDefaultFeatureType(targetEditableFeatureType);
178
            createTableParams.setTable(this.getParameters().getTableName());
179 44300 omartinez
180 43925 jjdelcerro
            return createTableParams;
181 44300 omartinez
182 43925 jjdelcerro
        } catch (Exception ex) {
183
            throw new ExportException(ex);
184 43504 jjdelcerro
        }
185 40435 jjdelcerro
    }
186
187 43364 jjdelcerro
    @Override
188 43925 jjdelcerro
    public OpenDataStoreParameters createTargetOpenStoreParameters() throws ExportException {
189
        try {
190
            DataManager dataManager = DALLocator.getDataManager();
191
            JDBCServerExplorer explorer = this.createServerExplorer();
192
193
            JDBCStoreParameters openStoreParameters = (JDBCStoreParameters) explorer.getOpenParameters();
194
            openStoreParameters.setSchema(this.getParameters().getSchema());
195
            openStoreParameters.setTable(this.getParameters().getTableName());
196
            openStoreParameters.setCRS(this.getParameters().getTargetProjection());
197
            openStoreParameters.setDefaultGeometryField(
198 45009 omartinez
                    this.getParameters().getTargetFeatureType().getDefaultGeometryAttributeName()
199 43925 jjdelcerro
            );
200
            return openStoreParameters;
201
        } catch (DataException ex) {
202
            throw new ExportException(ex);
203
        }
204 43364 jjdelcerro
    }
205
206 43504 jjdelcerro
207 44386 omartinez
208 43925 jjdelcerro
    private int getGeometryColumnCount(FeatureType featureType) {
209
        int count = 0;
210 44300 omartinez
        for (int i = 0; i < featureType.size(); i++) {
211
            if (featureType.getAttributeDescriptor(i).getType() == DataTypes.GEOMETRY) {
212 43925 jjdelcerro
                count++;
213
            }
214
        }
215
        return count;
216
    }
217 44300 omartinez
218 43504 jjdelcerro
    @Override
219 43925 jjdelcerro
    public void export(FeatureSet featureSet) throws ExportException {
220
        Geometry.ValidationStatus geometryCheck;
221
222
        DisposableIterator it = null;
223
        EditableFeature targetFeature = null;
224
        FeatureStore target = null;
225 45690 fdiaz
        Feature feature = null;
226 43925 jjdelcerro
227
        try {
228
            ExportServiceManager serviceManager = ExportLocator.getServiceManager();
229
230
            // ======================================
231
            // Reprojection
232 44469 omartinez
            ICoordTrans coord_trans = this.getParameters().getTransformationToUse();
233 43925 jjdelcerro
            // ============================================
234
235
            DataManager dataManager = DALLocator.getDataManager();
236
237
            JDBCServerExplorer explorer = this.createServerExplorer();
238
239
            if (this.getParameters().canCreatetable()) {
240
                LOG.debug("Creating table");
241
                getTaskStatus().message("Creating table");
242
                NewDataStoreParameters targetNewStoreParameters = this.createTargetNewStoreParameters();
243
                explorer.add(
244
                        targetNewStoreParameters.getDataStoreName(),
245
                        targetNewStoreParameters,
246
                        true
247
                );
248 45152 fdiaz
249
                //We collect the name of the table of targetNewStoreParameters
250
                //because the provider has been able to make changes to it
251
                this.getParameters().setTableName(((JDBCNewStoreParameters)targetNewStoreParameters).getTable());
252 43925 jjdelcerro
            }
253
254
            JDBCStoreParameters openParams = (JDBCStoreParameters) this.createTargetOpenStoreParameters();
255
            target = (FeatureStore) explorer.open(openParams);
256
257
            FeatureType theTargetFeatureType = target.getDefaultFeatureType();
258
            FeatureType theSourceFeatureType = featureSet.getDefaultFeatureType();
259
260
            target.edit(FeatureStore.MODE_APPEND);
261
262
            long featureCount = 1;
263
            getTaskStatus().setRangeOfValues(0, featureSet.getSize());
264
265 45009 omartinez
            int targetGeometryIndex = -1;
266
            int sourceGeometryIndex = -1;
267 44300 omartinez
            if (getGeometryColumnCount(theSourceFeatureType) == 1
268
                    && getGeometryColumnCount(theTargetFeatureType) == 1) {
269 43925 jjdelcerro
                // Si solo hay una columna de geometria asignaremos las geometrias
270
                // independientemente de como se llamen los campos.
271
                targetGeometryIndex = theTargetFeatureType.getDefaultGeometryAttributeIndex();
272
                sourceGeometryIndex = theSourceFeatureType.getDefaultGeometryAttributeIndex();
273
            } else {
274
                FeatureAttributeDescriptor attr = theSourceFeatureType.getDefaultGeometryAttribute();
275 45077 omartinez
                if (attr!=null && theTargetFeatureType.getAttributeDescriptor(attr.getName())!=null) {
276 45009 omartinez
                    sourceGeometryIndex = attr.getIndex();
277
                    targetGeometryIndex = theTargetFeatureType.getAttributeDescriptor(attr.getName()).getIndex();
278
                }
279 43925 jjdelcerro
            }
280
281 45690 fdiaz
            if(targetGeometryIndex != -1){
282
                GeometryCoercionContext coercionContext = (GeometryCoercionContext) theTargetFeatureType.getAttributeDescriptor(targetGeometryIndex).getCoercionContext();
283
                if(coercionContext!=null){
284
                    coercionContext.setMode(GeometryCoercionContext.MODE_ONERROR_NULL);
285
                }
286
            }
287 43925 jjdelcerro
            LOG.debug("Inserting rows");
288
            getTaskStatus().message("Inserting rows");
289
            it = featureSet.fastIterator();
290
            while (it.hasNext()) {
291 45690 fdiaz
                feature = (Feature) it.next();
292 43925 jjdelcerro
                this.getTaskStatus().setCurValue(featureCount);
293
294 45609 omartinez
                targetFeature = target.createNewFeature(theTargetFeatureType, true);
295
                targetFeature.copyFrom(feature);
296 43925 jjdelcerro
                for (int i = 0; i < theSourceFeatureType.size(); i++) {
297
                    if (i == sourceGeometryIndex) {
298
                        // Es facil que los campos geometria no se llamen igual, asi que
299
                        // el campo geometria lo asignamos a capon.
300
                        // Esto puede ocasionar problemas cuando la tabla destino no tenga
301
                        // geometria o tenga mas de una.
302
                        targetFeature.set(targetGeometryIndex, feature.get(sourceGeometryIndex));
303
                    } else {
304 44270 omartinez
                        FeatureAttributeDescriptor sourceField = theSourceFeatureType.getAttributeDescriptor(i);
305
//                        String name = getTranslatedIdentifier(x.getName());
306 45772 omartinez
                        if (!this.getParameters().getExportAttributes().getExportAttribute(sourceField.getName()).isExported()) {
307
                            continue;
308
                        }
309 44270 omartinez
                        String targetField = this.getParameters().getExportAttributes().getTargetName(sourceField.getName());
310
                        int targetAttributeIndex = theTargetFeatureType.getIndex(targetField);
311 45758 omartinez
                        if (targetAttributeIndex < 0 ) {
312 44270 omartinez
                            continue;
313
                            //throw new RuntimeException("Can't locate column '" + x.getName() + "' in the target table.");
314 43925 jjdelcerro
                        }
315 45758 omartinez
                        if (theTargetFeatureType.getAttributeDescriptor(targetField).isReadOnly() ) {
316
                            continue;
317
                        }
318 44270 omartinez
                        targetFeature.set(targetAttributeIndex, feature.get(sourceField.getName()));
319 43504 jjdelcerro
                    }
320
                }
321 43925 jjdelcerro
322 45009 omartinez
                if (targetGeometryIndex!=-1) {
323
                    Geometry geometry = targetFeature.getGeometry(targetGeometryIndex);
324
325
                    FixGeometryStatus check = serviceManager.fixGeometry(getParameters(), coord_trans, geometry);
326
                    switch (check.getState()) {
327
                        case FixGeometryStatus.STATE_OK:
328
                            targetFeature.setDefaultGeometry(check.getGeometry());
329
                            break;
330
                        case FixGeometryStatus.STATE_SKIP:
331
                            continue;
332
                        case FixGeometryStatus.STATE_ABORT:
333
                            throw new InvalidGeometryException(targetFeature, check.getMessage());
334
                    }
335 43925 jjdelcerro
                }
336
337
                target.insert(targetFeature);
338
339
                if (this.getTaskStatus().isCancellationRequested()) {
340
                    return;
341
                }
342
                featureCount++;
343 43504 jjdelcerro
            }
344 44300 omartinez
            String msgRowCount = MessageFormat.format(" ({0,number, #,###} rows)", featureCount);
345 43925 jjdelcerro
            targetFeature = null;
346
            getTaskStatus().setIndeterminate();
347 44300 omartinez
            LOG.debug("Finish editing" + msgRowCount);
348
            if (featureCount > 50000) {
349 43925 jjdelcerro
                getTaskStatus().message("Finishing insertion of records, may take a while" + msgRowCount);
350
            } else {
351 44300 omartinez
                getTaskStatus().message("Finishing insertion of records" + msgRowCount);
352 43925 jjdelcerro
            }
353
            target.finishEditing();
354 44300 omartinez
355
            if (this.getParameters().canCreatetable()) {
356
                getTaskStatus().message("Preparing the update of the indices" + msgRowCount);
357 43925 jjdelcerro
                target.edit();
358
                EditableFeatureType ft = target.getDefaultFeatureType().getEditable();
359 44300 omartinez
                for (FeatureAttributeDescriptor attr : this.targetFeatureType) {
360 43925 jjdelcerro
                    EditableFeatureAttributeDescriptor attr2 = (EditableFeatureAttributeDescriptor) ft.getAttributeDescriptor(attr.getName());
361 44300 omartinez
                    if (attr2 != null) {
362 43925 jjdelcerro
                        //attr2.setIsPrimaryKey(attr.isPrimaryKey());
363
                        attr2.setIsIndexed(attr.isIndexed());
364
                        attr2.setIsAutomatic(attr.isAutomatic());
365 45914 jjdelcerro
                        attr2.setIsReadOnly(attr.isReadOnly());
366 43925 jjdelcerro
                    }
367
                }
368
                target.update(ft);
369 44300 omartinez
                getTaskStatus().message("Updating the indices" + msgRowCount);
370 43925 jjdelcerro
                target.finishEditing();
371
            }
372
            if (this.getParameters().getUpdateTableStatistics()) {
373
                LOG.debug("Updating statistics");
374 44300 omartinez
                getTaskStatus().message("Updating statistics" + msgRowCount);
375 43925 jjdelcerro
                explorer.updateTableStatistics(
376
                        openParams.getDBName(),
377
                        openParams.getSchema(),
378
                        openParams.getTable()
379
                );
380
            }
381
            LOG.debug("finish");
382
            getTaskStatus().message("Exportation finished");
383
            getTaskStatus().terminate();
384
385
        } catch (Exception e) {
386
            LOG.warn("Can't export data.", e);
387
            getTaskStatus().message("Problems exporting data");
388
            throw new ExportException(e, targetFeature);
389
390
        } finally {
391
            if (it != null) {
392
                it.dispose();
393
            }
394
            featureSet.dispose();
395
            if (target != null) {
396 44300 omartinez
                if (target.isAppending()) {
397 43925 jjdelcerro
                    try {
398
                        target.cancelEditing();
399 44300 omartinez
                    } catch (Exception ex) {
400
                        LOG.warn("Can't cancel editing.", ex);
401 43925 jjdelcerro
                    }
402
                }
403
                target.dispose();
404
            }
405
            this.getTaskStatus().terminate();
406
            this.getTaskStatus().remove();
407 43504 jjdelcerro
        }
408
    }
409 44300 omartinez
410 40435 jjdelcerro
}