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

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

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

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

    
69
    private FeatureType targetFeatureType;
70

    
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

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

    
108
            boolean preferNotToUseNonNullRestrictions = factory.preferNotToUseNonNullRestrictions();
109

    
110
            targetTempFeatureType = getParameters().getSourceFeatureType().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 x = (EditableFeatureAttributeDescriptor) targetEditableFeatureType.get(i);
117
                x.setIsPrimaryKey(false);
118
                if( preferNotToUseNonNullRestrictions ) {
119
                    x.setAllowNull(true);
120
                }
121
            }
122

    
123
            if (this.getParameters().getTranslateIdentifiersToLowerCase()
124
                    || this.getParameters().getRemoveSpacesInIdentifiers() 
125
                    || this.getParameters().getTranslateHyphens()) {
126
                for (int i = 0; i < targetEditableFeatureType.size(); i++) {
127
                    EditableFeatureAttributeDescriptor x = (EditableFeatureAttributeDescriptor) targetEditableFeatureType.get(i);
128
                    x.setName(getTranslatedIdentifier(x.getName()));
129
                }
130
            }
131

    
132
            if (this.getParameters().getPrimaryKey() != null) {
133
                EditableFeatureAttributeDescriptor pk = (EditableFeatureAttributeDescriptor) targetEditableFeatureType.get(getTranslatedIdentifier(getParameters().getPrimaryKey()));
134
                if (pk == null) {
135
                    pk = targetEditableFeatureType.add(
136
                            getTranslatedIdentifier(this.getParameters().getPrimaryKey()),
137
                            DataTypes.LONG
138
                    );
139
                    pk.setIsPrimaryKey(true);
140
                    pk.setIsAutomatic(true);
141
                } else {
142
                    pk.setIsPrimaryKey(true);
143
                }
144
            }
145

    
146
            if (this.getParameters().getCreateIndexInGeometryRow()) {
147
                EditableFeatureAttributeDescriptor x = (EditableFeatureAttributeDescriptor) targetEditableFeatureType.getDefaultGeometryAttribute();
148
                x.setIsIndexed(true);
149
            }
150

    
151
            // ======================================================
152
            // Reprojection: set SRS of geometry field to target SRS
153
            EditableFeatureAttributeDescriptor attrdescriptor
154
                    = (EditableFeatureAttributeDescriptor) targetEditableFeatureType.getDefaultGeometryAttribute();
155
            if (attrdescriptor != null) {
156
                attrdescriptor.setSRS(this.getParameters().getTargetProjection());
157
            }
158

    
159
            // ======================================
160
            // Remove index to improve performance
161
            this.targetFeatureType = targetEditableFeatureType.getNotEditableCopy();
162
            for (int i = 0; i < targetEditableFeatureType.size(); i++) {
163
                EditableFeatureAttributeDescriptor x = (EditableFeatureAttributeDescriptor) targetEditableFeatureType.get(i);
164
                //x.setIsPrimaryKey(false);
165
                x.setIsIndexed(false);
166
            }
167

    
168
            // ======================================
169

    
170

    
171
            JDBCNewStoreParameters createTableParams = (JDBCNewStoreParameters) explorer.getAddParameters();
172

    
173
            createTableParams.setSelectRole(this.getParameters().getSelectRole());
174
            createTableParams.setInsertRole(this.getParameters().getInsertRole());
175
            createTableParams.setUpdateRole(this.getParameters().getUpdateRole());
176
            createTableParams.setDeleteRole(this.getParameters().getDeleteRole());
177
            createTableParams.setTruncateRole(this.getParameters().getTruncateRole());
178
            createTableParams.setReferenceRole(this.getParameters().getReferenceRole());
179
            createTableParams.setTriggerRole(this.getParameters().getTriggerRole());
180
            createTableParams.setAllRole(this.getParameters().getAllRole());
181

    
182
            createTableParams.setSchema(this.getParameters().getSchema());
183
            createTableParams.setPostCreatingStatement(this.getParameters().getPostCreatingStatement());
184

    
185
            createTableParams.setDefaultFeatureType(targetEditableFeatureType);
186
            createTableParams.setTable(this.getParameters().getTableName());
187
            
188
            return createTableParams;
189
            
190
        } catch (Exception ex) {
191
            throw new ExportException(ex);
192
        }
193
    }
194

    
195
    @Override
196
    public OpenDataStoreParameters createTargetOpenStoreParameters() throws ExportException {
197
        try {
198
            DataManager dataManager = DALLocator.getDataManager();
199
            JDBCServerExplorer explorer = this.createServerExplorer();
200

    
201
            JDBCStoreParameters openStoreParameters = (JDBCStoreParameters) explorer.getOpenParameters();
202
            openStoreParameters.setSchema(this.getParameters().getSchema());
203
            openStoreParameters.setTable(this.getParameters().getTableName());
204
            openStoreParameters.setCRS(this.getParameters().getTargetProjection());
205
            openStoreParameters.setDefaultGeometryField(
206
                    this.getParameters().getSourceFeatureType().getDefaultGeometryAttributeName()
207
            );
208
            return openStoreParameters;
209
        } catch (DataException ex) {
210
            throw new ExportException(ex);
211
        }
212
    }
213

    
214
    protected String getTranslatedIdentifier(String identifier) {
215
        String s = identifier;
216
        if (this.getParameters().getTranslateIdentifiersToLowerCase()) {
217
            s = s.toLowerCase();
218
        }
219
        if( this.getParameters().getTranslateHyphens()) {
220
            s = s.replace("-", "_");
221
        }
222
        if (this.getParameters().getRemoveSpacesInIdentifiers()) {
223
            s = StringUtils.normalizeSpace(s).replace(" ", "_");
224
        }
225
        return s;
226
    }
227

    
228
    private int getGeometryColumnCount(FeatureType featureType) {
229
        int count = 0;
230
        for( int i=0; i<featureType.size(); i++ ) {
231
            if( featureType.getAttributeDescriptor(i).getType()==DataTypes.GEOMETRY ) {
232
                count++;
233
            }
234
        }
235
        return count;
236
    }
237
    @Override
238
    public void export(FeatureSet featureSet) throws ExportException {
239
        Geometry.ValidationStatus geometryCheck;
240

    
241
        DisposableIterator it = null;
242
        EditableFeature targetFeature = null;
243
        FeatureStore target = null;
244

    
245
        try {
246
            ExportServiceManager serviceManager = ExportLocator.getServiceManager();
247

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

    
266
            DataManager dataManager = DALLocator.getDataManager();
267

    
268
            
269
            JDBCServerExplorer explorer = this.createServerExplorer();
270

    
271
            if (this.getParameters().canCreatetable()) {
272
                LOG.debug("Creating table");
273
                getTaskStatus().message("Creating table");
274
                NewDataStoreParameters targetNewStoreParameters = this.createTargetNewStoreParameters();
275
                explorer.add(
276
                        targetNewStoreParameters.getDataStoreName(),
277
                        targetNewStoreParameters,
278
                        true
279
                );
280
            }
281

    
282
            JDBCStoreParameters openParams = (JDBCStoreParameters) this.createTargetOpenStoreParameters();
283
            target = (FeatureStore) explorer.open(openParams);
284

    
285
            FeatureType theTargetFeatureType = target.getDefaultFeatureType();
286
            FeatureType theSourceFeatureType = featureSet.getDefaultFeatureType();
287

    
288
            target.edit(FeatureStore.MODE_APPEND);
289

    
290
            long featureCount = 1;
291
            getTaskStatus().setRangeOfValues(0, featureSet.getSize());
292

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

    
307
            LOG.debug("Inserting rows");
308
            getTaskStatus().message("Inserting rows");
309
            it = featureSet.fastIterator();
310
            while (it.hasNext()) {
311
                Feature feature = (Feature) it.next();
312
                this.getTaskStatus().setCurValue(featureCount);
313

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

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

    
344
                target.insert(targetFeature);
345

    
346
                if (this.getTaskStatus().isCancellationRequested()) {
347
                    return;
348
                }
349
                featureCount++;
350
            }
351
            String msgRowCount = MessageFormat.format(" ({0,number, #,###} rows)",featureCount);
352
            targetFeature = null;
353
            getTaskStatus().setIndeterminate();
354
            LOG.debug("Finish editing"+msgRowCount);
355
            if( featureCount > 50000 ) {
356
                getTaskStatus().message("Finishing insertion of records, may take a while" + msgRowCount);
357
            } else {
358
                getTaskStatus().message("Finishing insertion of records"+msgRowCount);
359
            }
360
            target.finishEditing();
361
            
362
             if (this.getParameters().canCreatetable()) {
363
                getTaskStatus().message("Preparing the update of the indices"+msgRowCount);
364
                target.edit();
365
                EditableFeatureType ft = target.getDefaultFeatureType().getEditable();
366
                for( FeatureAttributeDescriptor attr : this.targetFeatureType) {
367
                    EditableFeatureAttributeDescriptor attr2 = (EditableFeatureAttributeDescriptor) ft.getAttributeDescriptor(attr.getName());
368
                    if( attr2!=null ) {
369
                        //attr2.setIsPrimaryKey(attr.isPrimaryKey());
370
                        attr2.setIsIndexed(attr.isIndexed());
371
                        attr2.setIsAutomatic(attr.isAutomatic());
372
                    }
373
                }
374
                target.update(ft);
375
                getTaskStatus().message("Updating the indices"+msgRowCount);
376
                target.finishEditing();
377
            }
378
            if (this.getParameters().getUpdateTableStatistics()) {
379
                LOG.debug("Updating statistics");
380
                getTaskStatus().message("Updating statistics"+msgRowCount);
381
                explorer.updateTableStatistics(
382
                        openParams.getDBName(),
383
                        openParams.getSchema(),
384
                        openParams.getTable()
385
                );
386
            }
387
            LOG.debug("finish");
388
            getTaskStatus().message("Exportation finished");
389
            getTaskStatus().terminate();
390

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

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