Statistics
| Revision:

root / branches / v10 / extensions / extOracleSpatial / src / es / prodevelop / cit / gvsig / fmap / drivers / jdbc / oracle / OracleSpatialWriter.java @ 13995

History | View | Annotate | Download (17 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2006 Prodevelop and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 *
19
 * For more information, contact:
20
 *
21
 *   Generalitat Valenciana
22
 *   Conselleria d'Infraestructures i Transport
23
 *   Av. Blasco Ib??ez, 50
24
 *   46010 VALENCIA
25
 *   SPAIN
26
 *
27
 *   +34 963862235
28
 *   gvsig@gva.es
29
 *   www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   Prodevelop Integraci?n de Tecnolog?as SL
34
 *   Conde Salvatierra de ?lava , 34-10
35
 *   46004 Valencia
36
 *   Spain
37
 *
38
 *   +34 963 510 612
39
 *   +34 963 510 968
40
 *   gis@prodevelop.es
41
 *   http://www.prodevelop.es
42
 */
43
package es.prodevelop.cit.gvsig.fmap.drivers.jdbc.oracle;
44

    
45
import com.iver.cit.gvsig.fmap.core.DefaultRow;
46
import com.iver.cit.gvsig.fmap.core.FShape;
47
import com.iver.cit.gvsig.fmap.core.IFeature;
48
import com.iver.cit.gvsig.fmap.core.IGeometry;
49
import com.iver.cit.gvsig.fmap.drivers.DBLayerDefinition;
50
import com.iver.cit.gvsig.fmap.drivers.FieldDescription;
51
import com.iver.cit.gvsig.fmap.edition.DefaultRowEdited;
52
import com.iver.cit.gvsig.fmap.edition.EditionException;
53
import com.iver.cit.gvsig.fmap.edition.IFieldManager;
54
import com.iver.cit.gvsig.fmap.edition.IRowEdited;
55
import com.iver.cit.gvsig.fmap.edition.ISpatialWriter;
56
import com.iver.cit.gvsig.fmap.edition.writers.AbstractWriter;
57

    
58
import oracle.sql.STRUCT;
59

    
60
import org.apache.log4j.Logger;
61

    
62
import java.awt.geom.Rectangle2D;
63

    
64
import java.sql.Connection;
65
import java.sql.SQLException;
66

    
67

    
68
/**
69
 * Oracle Spatial geometry writer. Used during editing and when a vectorial layer has to be
70
 * exported to Oracle.
71
 *
72
 * @author jldominguez
73
 *
74
 */
75
public class OracleSpatialWriter extends AbstractWriter
76
    implements ISpatialWriter, IFieldManager {
77
    public static final String NAME = "Oracle Spatial Writer";
78
    private static Logger logger = Logger.getLogger(OracleSpatialWriter.class.getName());
79
    private Rectangle2D bbox = null;
80
    private OracleSpatialDriver driver;
81
    private int rowIndex = 0;
82
    private String oracleSRID = "";
83
    private int lyrShapeType = FShape.NULL;
84
    private int dimensions = 2;
85
    private boolean aguBien = true;
86
    private boolean storeWithSrid = false;
87
    private boolean tableCreation = false;
88
    private boolean isGeoCS = false;
89
    private String geoColName = OracleSpatialDriver.DEFAULT_GEO_FIELD;
90

    
91
    /**
92
     * Constructor used when a whole layer is going to be exported.
93
     *
94
     */
95
    public OracleSpatialWriter() {
96
        tableCreation = true;
97
    }
98

    
99
    /**
100
     * Constructor used when a table is being edited.
101
     * @param rowcount the table's current row count
102
     */
103
    public OracleSpatialWriter(long rowcount) {
104
        rowIndex = (int) rowcount;
105
        tableCreation = false;
106
    }
107

    
108
    public boolean canWriteAttribute(int sqlType) {
109
        return true;
110
    }
111

    
112
    public boolean canWriteGeometry(int gvSIGgeometryType) {
113
        return true;
114
    }
115

    
116
    public void preProcess() throws EditionException {
117
        if (tableCreation) {
118
            String srid_epsg = ((DBLayerDefinition) tableDef).getSRID_EPSG();
119
            
120
            
121
            try {
122
                                oracleSRID = OracleSpatialDriver.epsgSridToOracleSrid(srid_epsg);
123
                        } catch (Exception e1) {
124
                                // not found
125
                                logger.error("unknown EPSG code: " + srid_epsg);
126
                                storeWithSrid = false;
127
                        }
128

    
129
            String _sql_rem_meta =
130
                    OracleSpatialDriver.getRemoveMetadataSql((DBLayerDefinition) tableDef);
131
            String _sql_drop =
132
                    OracleSpatialDriver.getDropTableSql((DBLayerDefinition) tableDef);
133
            String _sql_creation =
134
                    OracleSpatialDriver.getTableCreationSql((DBLayerDefinition) tableDef);
135
            String _sql_index =
136
                    OracleSpatialDriver.getIndexCreationSql((DBLayerDefinition) tableDef);
137

    
138
            int dim_aux = dimensions;
139

    
140
            String _sql_meta = OracleSpatialDriver.getMetadataUpdateSql(
141
                            driver.getUserName(),
142
                            ((DBLayerDefinition) tableDef).getTableName(),
143
                    oracleSRID, bbox, dim_aux, storeWithSrid);
144

    
145
            //dimensions);
146
            Connection conn = ((DBLayerDefinition) tableDef).getConnection();
147

    
148
            boolean removed = true;
149

    
150
            try {
151
                java.sql.PreparedStatement ps = conn.prepareStatement(_sql_drop);
152
                ps.execute();
153
                ps.close();
154
            }
155
            catch (SQLException ex) {
156
                logger.info("Table did not exist: " +
157
                    ((DBLayerDefinition) tableDef).getTableName());
158
                removed = false;
159
            }
160

    
161
            if (removed) {
162
                logger.info("Table existed and was deleted: " +
163
                    ((DBLayerDefinition) tableDef).getTableName());
164
            }
165

    
166
            try {
167
                java.sql.PreparedStatement ps = conn.prepareStatement(_sql_rem_meta);
168
                ps.execute();
169
                ps.close();
170
            }
171
            catch (SQLException ex) {
172
                logger.error("Error while executing SQL for metadata removal: " +
173
                    ex.getMessage(), ex);
174
            }
175

    
176
            try {
177
                java.sql.PreparedStatement ps = conn.prepareStatement(_sql_creation);
178
                ps.execute();
179
                ps.close();
180
            }
181
            catch (SQLException ex) {
182
                logger.error("Error while executing SQL for table creation: " +
183
                    ex.getMessage(), ex);
184
            }
185

    
186
            try {
187
                java.sql.PreparedStatement ps = conn.prepareStatement(_sql_meta);
188
                ps.execute();
189
                ps.close();
190
            }
191
            catch (SQLException ex) {
192
                logger.error(
193
                    "Error while executing SQL for metadata insertion: " +
194
                    ex.getMessage(), ex);
195
            }
196

    
197
            try {
198
                java.sql.PreparedStatement ps = conn.prepareStatement(_sql_index);
199
                ps.execute();
200
                ps.close();
201
            }
202
            catch (SQLException ex) {
203
                logger.error("Error while executing SQL for index creation: " +
204
                    ex.getMessage(), ex);
205
            }
206

    
207
            rowIndex = 0;
208

    
209
            try {
210
                conn.setAutoCommit(false);
211
            }
212
            catch (SQLException e) {
213
                logger.error("Error while setting auto commit FALSE: " +
214
                    e.getMessage());
215
            }
216
        }
217
        else {
218
        }
219
    }
220

    
221
    public void process(IRowEdited _row) throws EditionException {
222
        int status = _row.getStatus();
223

    
224
        switch (status) {
225
        case IRowEdited.STATUS_ADDED:
226
            addRow(_row);
227

    
228
            /*
229
             // TODO when addRowInCreation() is implemented:
230
            if (tableCreation) {
231
                    addRowInCreation(_row);
232
            } else {
233
                    addRow(_row);
234
            }
235
            */
236
            break;
237

    
238
        case IRowEdited.STATUS_DELETED:
239
            deleteRow(_row);
240

    
241
            break;
242

    
243
        case IRowEdited.STATUS_MODIFIED:
244
            updateRow(_row);
245

    
246
            break;
247

    
248
        case IRowEdited.STATUS_ORIGINAL:
249
            originalRow(_row);
250

    
251
            break;
252
        }
253
    }
254

    
255
    private void addRowInCreation(IRowEdited irow) throws EditionException {
256
        // TODO: Build value-independent SQL, then use addBatch()
257
        /*
258
        DefaultRowEdited row = (DefaultRowEdited) irow;
259
        IFeature ifeat = (IFeature) row.getLinkedRow();
260
        String _sql_insert = OracleSpatialDriver.getRowInsertSql(
261
                        ifeat, (DBLayerDefinition) tableDef, rowIndex, geoColName);
262
        
263
        Connection conn = ((DBLayerDefinition) tableDef).getConnection();
264
        
265
        try {
266
                // java.sql.PreparedStatement ps = conn.prepareStatement(_sql_insert);
267
                creationStatement = conn.prepareStatement(_sql_insert);
268
                // Shape shp = ifeat.getGeometry().getInternalShape();
269
                IGeometry _ig = ifeat.getGeometry();
270
                // STRUCT st = driver.shapeToStruct(shp, lyrShapeType, conn, oracleSRID, false);
271
                STRUCT st = OracleSpatialDriver.iGeometryToSTRUCT(_ig, lyrShapeType, conn,
272
                                oracleSRID, storeWithSrid, aguBien, isGeoCS);
273
        
274
                ps.setObject(1, st);
275
                ps.execute();
276
                ps.close();
277
                rowIndex++;
278
        
279
                // getDriver().addRow(irow.getID());
280
        } catch (Exception ex) {
281
                logger.error("Error while executing SQL for row insertion: " + ex.getMessage(), ex);
282
                throw new EditionException(ex.getMessage());
283
        }
284
        */
285
    }
286

    
287
    private void addRow(IRowEdited irow) throws EditionException {
288
        DefaultRowEdited row = (DefaultRowEdited) irow;
289
        IFeature ifeat = (IFeature) row.getLinkedRow();
290
        String _sql_insert = OracleSpatialDriver.getRowInsertSql(ifeat,
291
                (DBLayerDefinition) tableDef, rowIndex, geoColName);
292

    
293
        Connection conn = ((DBLayerDefinition) tableDef).getConnection();
294

    
295
        try {
296
            java.sql.PreparedStatement ps = conn.prepareStatement(_sql_insert);
297

    
298
            // Shape shp = ifeat.getGeometry().getInternalShape();
299
            IGeometry _ig = ifeat.getGeometry();
300

    
301
            // STRUCT st = driver.shapeToStruct(shp, lyrShapeType, conn, oracleSRID, false);
302
            STRUCT st;
303
            
304
            if (driver.getDestProjectionOracleCode().compareToIgnoreCase(oracleSRID) == 0) {
305
                    
306
                st = OracleSpatialDriver.iGeometryToSTRUCT(_ig,
307
                        lyrShapeType, conn, oracleSRID, storeWithSrid, aguBien,
308
                        isGeoCS);
309
                    
310
            } else {
311
                    String viewSrid = driver.getDestProjectionOracleCode();
312
                    boolean isViewSridGedetic = driver.getIsDestProjectionGeog();
313
                st = OracleSpatialDriver.iGeometryToSTRUCT(_ig,
314
                        lyrShapeType, conn, viewSrid, storeWithSrid, aguBien,
315
                        isViewSridGedetic);
316
                st = OracleSpatialUtils.reprojectGeometry(conn, st, oracleSRID);
317
            }
318

    
319
            ps.setObject(1, st);
320
            ps.execute();
321
            ps.close();
322
            rowIndex++;
323

    
324
            // getDriver().addRow(irow.getID());
325
        }
326
        catch (Exception ex) {
327
            logger.error("Error while executing SQL for row insertion: " +
328
                ex.getMessage() + " SQL: " + _sql_insert, ex);
329
            throw new EditionException(ex.getMessage());
330
        }
331
    }
332

    
333
    private void deleteRow(IRowEdited irow) throws EditionException {
334
        DefaultRowEdited _row = (DefaultRowEdited) irow;
335
        DefaultRow row = (DefaultRow) _row.getLinkedRow();
336

    
337
        String id = row.getAttribute(0).toString();
338

    
339
        String _sql_delete = OracleSpatialDriver.getRowDeleteSql((DBLayerDefinition) tableDef,
340
                id);
341

    
342
        Connection conn = ((DBLayerDefinition) tableDef).getConnection();
343

    
344
        try {
345
            java.sql.PreparedStatement ps = conn.prepareStatement(_sql_delete);
346
            ps.execute();
347
            ps.close();
348

    
349
            // rowIndex--;
350

    
351
            // getDriver().deleteRow(irow.getID());
352
        }
353
        catch (SQLException ex) {
354
            logger.error("Error while executing SQL for row insertion: " +
355
                ex.getMessage(), ex);
356
            throw new EditionException(ex.getMessage());
357
        }
358
    }
359

    
360
    private void updateRow(IRowEdited irow) throws EditionException {
361
        DefaultRowEdited row = (DefaultRowEdited) irow;
362
        IFeature ifeat = (IFeature) row.getLinkedRow();
363

    
364
        // ---------------------------------------------------------------
365
        // --------- DETECTS INSERTS THAT LOOK LIKE UPDATES    -----------
366
        // ---------------------------------------------------------------
367
        String aux_id = ifeat.getID();
368
        boolean is_actually_update = false;
369

    
370
        try {
371
            Integer.parseInt(aux_id);
372
        }
373
        catch (NumberFormatException nfe) {
374
            is_actually_update = true;
375
        }
376

    
377
        if (!is_actually_update) {
378
            addRow(irow);
379

    
380
            return;
381
        }
382

    
383
        // ---------------------------------------------------------------
384
        // ---------------------------------------------------------------
385
        // ---------------------------------------------------------------
386
        String _sql_update = OracleSpatialDriver.getRowUpdateSql(ifeat,
387
                (DBLayerDefinition) tableDef, rowIndex, geoColName);
388

    
389
        Connection conn = ((DBLayerDefinition) tableDef).getConnection();
390

    
391
        try {
392
            java.sql.PreparedStatement ps = conn.prepareStatement(_sql_update);
393

    
394
            // Shape shp = ifeat.getGeometry().getInternalShape();
395
            IGeometry _ig = ifeat.getGeometry();
396
            STRUCT st;
397
            
398
            if (driver.getDestProjectionOracleCode().compareToIgnoreCase(oracleSRID) == 0) {
399
                    
400
                st = OracleSpatialDriver.iGeometryToSTRUCT(_ig,
401
                        lyrShapeType, conn, oracleSRID, storeWithSrid, aguBien,
402
                        isGeoCS);
403
                    
404
            } else {
405
                    String viewSrid = driver.getDestProjectionOracleCode();
406
                    boolean isViewSridGedetic = driver.getIsDestProjectionGeog();
407
                st = OracleSpatialDriver.iGeometryToSTRUCT(_ig,
408
                        lyrShapeType, conn, viewSrid, storeWithSrid, aguBien,
409
                        isViewSridGedetic);
410
                st = OracleSpatialUtils.reprojectGeometry(conn, st, oracleSRID);
411
            }
412

    
413
            ps.setObject(1, st);
414
            ps.execute();
415
            ps.close();
416

    
417
            // rowIndex++;
418
        }
419
        catch (Exception ex) {
420
            logger.error("Error while executing SQL for row insertion: " +
421
                ex.getMessage(), ex);
422
            throw new EditionException(ex.getMessage());
423
        }
424
    }
425

    
426
    private void originalRow(IRowEdited irow) {
427
        logger.error("Original row called!");
428
    }
429

    
430
    public void postProcess() throws EditionException {
431
        if (tableCreation) {
432
            Connection conn = ((DBLayerDefinition) tableDef).getConnection();
433

    
434
            try {
435
                conn.commit();
436
                conn.setAutoCommit(true);
437
            }
438
            catch (SQLException e) {
439
                logger.error(
440
                    "!!! While performing table creation MAIN COMMIT: " +
441
                    e.getMessage());
442
            }
443
        }
444
    }
445

    
446
    public boolean canAlterTable() {
447
        // TODO Auto-generated method stub
448
        logger.info("can alter table? false");
449

    
450
        return false;
451
    }
452

    
453
    public boolean canSaveEdits() {
454
        // TODO Auto-generated method stub
455
        logger.info("can save edits? false");
456

    
457
        return false;
458
    }
459

    
460
    public String getName() {
461
        return NAME;
462
    }
463

    
464
    public FieldDescription[] getOriginalFields() {
465
        // TODO Auto-generated method stub
466
        return tableDef.getFieldsDesc();
467
    }
468

    
469
    public void addField(FieldDescription fieldDesc) {
470
        // TODO Auto-generated method stub
471
        logger.info("add field .. nothing done");
472
    }
473

    
474
    public FieldDescription removeField(String fieldName) {
475
        // TODO Auto-generated method stub
476
        logger.info("remove field? null");
477

    
478
        return null;
479
    }
480

    
481
    public void renameField(String antName, String newName) {
482
        // TODO Auto-generated method stub
483
        logger.info("rename field .. nothing done");
484
    }
485

    
486
    public boolean alterTable() throws EditionException {
487
        // TODO Auto-generated method stub
488
        logger.info("alter table? false");
489

    
490
        return false;
491
    }
492

    
493
    public FieldDescription[] getFields() {
494
        // TODO Auto-generated method stub
495
        logger.info("get fields? null");
496

    
497
        return tableDef.getFieldsDesc();
498
    }
499

    
500
    public void setBbox(Rectangle2D b) {
501
        bbox = b;
502
    }
503

    
504
    public void setDriver(OracleSpatialDriver d) {
505
        driver = d;
506
    }
507

    
508
    public void setLyrShapeType(int shptype) {
509
        lyrShapeType = shptype;
510
    }
511

    
512
    public void setDimensions(int dims) {
513
        dimensions = dims;
514
    }
515

    
516
    public void setAguBien(boolean agu_bien) {
517
        aguBien = agu_bien;
518
    }
519

    
520
    public void setStoreWithSrid(boolean with) {
521
        storeWithSrid = with;
522
    }
523

    
524
    public void setGeoCS(boolean g) {
525
        isGeoCS = g;
526
    }
527

    
528
    public void setGeoColName(String g) {
529
        geoColName = g;
530
    }
531

    
532
    public OracleSpatialDriver getDriver() {
533
        return driver;
534
    }
535

    
536
    public void setSRID(String s) {
537
        oracleSRID = s;
538
    }
539
}