Statistics
| Revision:

svn-gvsig-desktop / trunk / extensions / extOracleSpatial / src / es / prodevelop / cit / gvsig / fmap / drivers / jdbc / oracle / OracleSpatialWriter.java @ 17624

History | View | Annotate | Download (17.5 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 java.awt.geom.Rectangle2D;
46
import java.sql.SQLException;
47
import java.sql.Types;
48

    
49
import oracle.sql.STRUCT;
50

    
51
import org.apache.log4j.Logger;
52

    
53
import com.hardcode.gdbms.driver.exceptions.WriteDriverException;
54
import com.iver.cit.gvsig.exceptions.visitors.StartWriterVisitorException;
55
import com.iver.cit.gvsig.exceptions.visitors.StopWriterVisitorException;
56
import com.iver.cit.gvsig.exceptions.visitors.VisitorException;
57
import com.iver.cit.gvsig.fmap.core.DefaultRow;
58
import com.iver.cit.gvsig.fmap.core.FShape;
59
import com.iver.cit.gvsig.fmap.core.IFeature;
60
import com.iver.cit.gvsig.fmap.core.IGeometry;
61
import com.iver.cit.gvsig.fmap.drivers.ConnectionJDBC;
62
import com.iver.cit.gvsig.fmap.drivers.DBLayerDefinition;
63
import com.iver.cit.gvsig.fmap.drivers.FieldDescription;
64
import com.iver.cit.gvsig.fmap.drivers.IConnection;
65
import com.iver.cit.gvsig.fmap.edition.DefaultRowEdited;
66
import com.iver.cit.gvsig.fmap.edition.IFieldManager;
67
import com.iver.cit.gvsig.fmap.edition.IRowEdited;
68
import com.iver.cit.gvsig.fmap.edition.ISpatialWriter;
69
import com.iver.cit.gvsig.fmap.edition.writers.AbstractWriter;
70

    
71

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

    
96
    /**
97
     * Constructor used when a whole layer is going to be exported.
98
     *
99
     */
100
    public OracleSpatialWriter() {
101
        tableCreation = true;
102
    }
103

    
104
    /**
105
     * Constructor used when a table is being edited.
106
     * @param rowcount the table's current row count
107
     */
108
    public OracleSpatialWriter(long rowcount) {
109
        rowIndex = (int) rowcount;
110
        tableCreation = false;
111
    }
112

    
113
    public boolean canWriteAttribute(int sqlType) {
114
        return true;
115
    }
116

    
117
    public boolean canWriteGeometry(int gvSIGgeometryType) {
118
        return true;
119
    }
120

    
121
    public void preProcess() throws StartWriterVisitorException {
122
            
123
            IConnection conn = ((DBLayerDefinition) tableDef).getConnection();;
124
            
125
        if (tableCreation) {
126
            String srid_epsg = ((DBLayerDefinition) tableDef).getSRID_EPSG();
127

    
128

    
129
            try {
130
                                oracleSRID = OracleSpatialDriver.epsgSridToOracleSrid(srid_epsg);
131
                        } catch (Exception e1) {
132
                                // not found
133
                                logger.error("unknown EPSG code: " + srid_epsg);
134
                                storeWithSrid = false;
135
                        }
136

    
137
            String _sql_rem_meta =
138
                    OracleSpatialDriver.getRemoveMetadataSql((DBLayerDefinition) tableDef);
139
            String _sql_drop =
140
                    OracleSpatialDriver.getDropTableSql((DBLayerDefinition) tableDef);
141
            String _sql_creation =
142
                    OracleSpatialDriver.getTableCreationSql((DBLayerDefinition) tableDef);
143
            String _sql_index =
144
                    OracleSpatialDriver.getIndexCreationSql((DBLayerDefinition) tableDef);
145

    
146
            int dim_aux = dimensions;
147

    
148
            String _sql_meta = OracleSpatialDriver.getMetadataUpdateSql(
149
                            driver.getUserName(),
150
                            ((DBLayerDefinition) tableDef).getTableName(),
151
                    oracleSRID, bbox, dim_aux, storeWithSrid);
152

    
153
            //dimensions);
154
            boolean removed = true;
155

    
156
            try {
157
                java.sql.PreparedStatement ps = ((ConnectionJDBC)conn).getConnection().prepareStatement(_sql_drop);
158
                ps.execute();
159
                ps.close();
160
            }
161
            catch (SQLException ex) {
162
                logger.info("Table did not exist: " +
163
                    ((DBLayerDefinition) tableDef).getTableName());
164
                removed = false;
165
            }
166

    
167
            if (removed) {
168
                logger.info("Table existed and was deleted: " +
169
                    ((DBLayerDefinition) tableDef).getTableName());
170
            }
171
            
172
            try {
173
                java.sql.PreparedStatement ps = ((ConnectionJDBC)conn).getConnection().prepareStatement(_sql_creation);
174
                ps.execute();
175
                ps.close();
176
            }
177
            catch (SQLException ex) {
178
                logger.error("Error while executing SQL for table creation: " +
179
                    ex.getMessage(), ex);
180
                                throw new StartWriterVisitorException("Oracle layer for table: " + tableDef.getName(), ex);
181
            }
182

    
183
            try {
184
                java.sql.PreparedStatement ps = ((ConnectionJDBC)conn).getConnection().prepareStatement(_sql_rem_meta);
185
                ps.execute();
186
                ps.close();
187
            }
188
            catch (SQLException ex) {
189
                logger.error("Error while executing SQL for metadata removal: " +
190
                    ex.getMessage(), ex);
191
                                throw new StartWriterVisitorException("Oracle layer for table: " + tableDef.getName(), ex);
192
            }
193

    
194
            try {
195
                java.sql.PreparedStatement ps = ((ConnectionJDBC)conn).getConnection().prepareStatement(_sql_meta);
196
                ps.execute();
197
                ps.close();
198
            }
199
            catch (SQLException ex) {
200
                logger.error(
201
                    "Error while executing SQL for metadata insertion: " +
202
                    ex.getMessage(), ex);
203
                                throw new StartWriterVisitorException("Oracle layer for table: " + tableDef.getName(), ex);
204
            }
205

    
206
            try {
207
                java.sql.PreparedStatement ps = ((ConnectionJDBC)conn).getConnection().prepareStatement(_sql_index);
208
                ps.execute();
209
                ps.close();
210
            }
211
            catch (SQLException ex) {
212
                logger.error("Error while executing SQL for index creation: " +
213
                    ex.getMessage(), ex);
214
                                throw new StartWriterVisitorException("Oracle layer for table: " + tableDef.getName(), ex);
215
            }
216

    
217
            rowIndex = 0;
218

    
219
        }
220
        else {
221
                
222
        }
223
        
224
        try {
225
                ((ConnectionJDBC)conn).getConnection().setAutoCommit(false);
226
                ((ConnectionJDBC)conn).getConnection().commit();
227
        }
228
        catch (SQLException e) {
229
            logger.error("Error while setting auto commit FALSE: " +
230
                e.getMessage());
231
                        throw new StartWriterVisitorException("Oracle layer for table: " + tableDef.getName(), e);
232
        }
233
        
234
    }
235

    
236
    public void process(IRowEdited _row) throws VisitorException {
237
        int status = _row.getStatus();
238

    
239
        switch (status) {
240
        case IRowEdited.STATUS_ADDED:
241
            addRow(_row);
242

    
243
            /*
244
             // TODO when addRowInCreation() is implemented:
245
            if (tableCreation) {
246
                    addRowInCreation(_row);
247
            } else {
248
                    addRow(_row);
249
            }
250
            */
251
            break;
252

    
253
        case IRowEdited.STATUS_DELETED:
254
            deleteRow(_row);
255

    
256
            break;
257

    
258
        case IRowEdited.STATUS_MODIFIED:
259
            updateRow(_row);
260

    
261
            break;
262

    
263
        case IRowEdited.STATUS_ORIGINAL:
264
            originalRow(_row);
265

    
266
            break;
267
        }
268
    }
269

    
270
    private void addRow(IRowEdited irow) throws VisitorException {
271
        DefaultRowEdited row = (DefaultRowEdited) irow;
272
        IFeature ifeat = (IFeature) row.getLinkedRow();
273
        String _sql_insert = "";
274

    
275
        IConnection conn = ((DBLayerDefinition) tableDef).getConnection();
276
        try {
277
            java.sql.PreparedStatement ps = null; 
278
            // Shape shp = ifeat.getGeometry().getInternalShape();
279
            IGeometry _ig = ifeat.getGeometry();
280
            // STRUCT st = driver.shapeToStruct(shp, lyrShapeType, conn, oracleSRID, false);
281
            STRUCT st;
282

    
283
            if ((oracleSRID == null) || (driver.getDestProjectionOracleCode().compareToIgnoreCase(oracleSRID) == 0)) {
284

    
285
                st = OracleSpatialDriver.iGeometryToSTRUCT(_ig,
286
                        lyrShapeType, conn, oracleSRID, storeWithSrid, aguBien,
287
                        isGeoCS);
288
            } else {
289
                    String viewSrid = driver.getDestProjectionOracleCode();
290
                    boolean isViewSridGedetic = driver.getIsDestProjectionGeog();
291
                st = OracleSpatialDriver.iGeometryToSTRUCT(_ig,
292
                        lyrShapeType, conn, viewSrid, storeWithSrid, aguBien,
293
                        isViewSridGedetic);
294
                st = OracleSpatialUtils.reprojectGeometry(conn, st, oracleSRID);
295
            }
296

    
297
            if (st == null) {
298
                _sql_insert = OracleSpatialDriver.getRowInsertSql(ifeat,
299
                        (DBLayerDefinition) tableDef, rowIndex, geoColName, "NULL");            
300
                    // ps.setObject(1, Types.NULL);
301
                    ps = ((ConnectionJDBC)conn).getConnection().prepareStatement(_sql_insert);
302
            } else {
303
                _sql_insert = OracleSpatialDriver.getRowInsertSql(ifeat,
304
                        (DBLayerDefinition) tableDef, rowIndex, geoColName, "?");   
305
                ps = ((ConnectionJDBC)conn).getConnection().prepareStatement(_sql_insert);
306
                    ps.setObject(1, st);
307
            }
308
            
309
            ps.execute();
310
            ps.close();
311
            rowIndex++;
312
        }
313
        catch (Exception ex) {
314
            logger.error("Error while executing SQL for row insertion: " +
315
                ex.getMessage() + " SQL: " + _sql_insert, ex);
316
                        throw new VisitorException("Oracle layer for table: " + tableDef.getName(), ex);
317
        }
318
    }
319

    
320
    private void deleteRow(IRowEdited irow) throws VisitorException {
321
        DefaultRowEdited _row = (DefaultRowEdited) irow;
322
        DefaultRow row = (DefaultRow) _row.getLinkedRow();
323

    
324
        String id = row.getAttribute(0).toString();
325

    
326
        String _sql_delete = OracleSpatialDriver.getRowDeleteSql((DBLayerDefinition) tableDef,
327
                id);
328

    
329
        IConnection conn = ((DBLayerDefinition) tableDef).getConnection();
330

    
331
        try {
332
            java.sql.PreparedStatement ps = ((ConnectionJDBC)conn).getConnection().prepareStatement(_sql_delete);
333
            ps.execute();
334
            ps.close();
335

    
336
            // rowIndex--;
337

    
338
            // getDriver().deleteRow(irow.getID());
339
        }
340
        catch (SQLException ex) {
341
            logger.error("Error while executing SQL for row deletion: " +
342
                ex.getMessage(), ex);
343
                        throw new VisitorException("Oracle layer for table: " + tableDef.getName(), ex);
344
        }
345
    }
346

    
347
    private void updateRow(IRowEdited irow) throws VisitorException {
348
        DefaultRowEdited row = (DefaultRowEdited) irow;
349
        IFeature ifeat = (IFeature) row.getLinkedRow();
350

    
351
        // ---------------------------------------------------------------
352
        // --------- DETECTS INSERTS THAT LOOK LIKE UPDATES    -----------
353
        // ---------------------------------------------------------------
354
        String aux_id = ifeat.getID();
355
        boolean is_actually_update = false;
356

    
357
        try {
358
            Integer.parseInt(aux_id);
359
        }
360
        catch (NumberFormatException nfe) {
361
            is_actually_update = true;
362
        }
363

    
364
        if (!is_actually_update) {
365
            addRow(irow);
366

    
367
            return;
368
        }
369

    
370
        // ---------------------------------------------------------------
371
        // ---------------------------------------------------------------
372
        // ---------------------------------------------------------------
373
        String _sql_update = OracleSpatialDriver.getRowUpdateSql(ifeat,
374
                (DBLayerDefinition) tableDef, rowIndex, geoColName);
375
        
376
        logger.debug("############ SQL UPDATE = " + _sql_update);
377

    
378
        IConnection conn = ((DBLayerDefinition) tableDef).getConnection();
379

    
380
        try {
381
            java.sql.PreparedStatement ps = ((ConnectionJDBC)conn).getConnection().prepareStatement(_sql_update);
382

    
383
            // Shape shp = ifeat.getGeometry().getInternalShape();
384
            IGeometry _ig = ifeat.getGeometry();
385
            STRUCT st;
386
            
387
            logger.debug("############ driver.getDestProjectionOracleCode() = "
388
                            + driver.getDestProjectionOracleCode());
389
            logger.debug("############ oracleSRID = " + oracleSRID);
390

    
391
            if ((oracleSRID == null) || (driver.getDestProjectionOracleCode().compareToIgnoreCase(oracleSRID) == 0)) {
392

    
393
                st = OracleSpatialDriver.iGeometryToSTRUCT(_ig,
394
                        lyrShapeType, conn, oracleSRID, storeWithSrid, aguBien,
395
                        isGeoCS);
396

    
397
            } else {
398
                    
399
                    String viewSrid = driver.getDestProjectionOracleCode();
400
                    boolean isViewSridGedetic = driver.getIsDestProjectionGeog();
401
                st = OracleSpatialDriver.iGeometryToSTRUCT(_ig,
402
                        lyrShapeType, conn, viewSrid, storeWithSrid, aguBien,
403
                        isViewSridGedetic);
404
                st = OracleSpatialUtils.reprojectGeometry(conn, st, oracleSRID);
405
            }
406

    
407
            ps.setObject(1, st);
408
            ps.execute();
409
            ps.close();
410

    
411
            // rowIndex++;
412
        }
413
        catch (Exception ex) {
414
            logger.error("Error while executing SQL for row update: " +
415
                ex.getMessage(), ex);
416
                        throw new VisitorException("Oracle layer for table: " + tableDef.getName(), ex);
417
        }
418
    }
419

    
420
    private void originalRow(IRowEdited irow) {
421
        logger.error("Original row called!");
422
    }
423

    
424
    public void postProcess() throws StopWriterVisitorException {
425
        if (tableCreation) {
426
            IConnection conn = ((DBLayerDefinition) tableDef).getConnection();
427

    
428
            try {
429
                    ((ConnectionJDBC)conn).getConnection().commit();
430
            } catch (SQLException e) {
431
                logger.error(
432
                    "!!! While performing table creation MAIN COMMIT: " +
433
                    e.getMessage());
434
                throw new StopWriterVisitorException("Oracle layer for table: " + tableDef.getName(), e);                
435
            }
436
        }
437
    }
438

    
439
    public boolean canAlterTable() {
440
        // TODO Auto-generated method stub
441
        logger.info("can alter table? false");
442

    
443
        return false;
444
    }
445

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

    
450
        return false;
451
    }
452

    
453
    public String getName() {
454
        return NAME;
455
    }
456

    
457
    public FieldDescription[] getOriginalFields() {
458
        // TODO Auto-generated method stub
459
        return tableDef.getFieldsDesc();
460
    }
461

    
462
    public void addField(FieldDescription fieldDesc) {
463
        // TODO Auto-generated method stub
464
        logger.info("add field .. nothing done");
465
    }
466

    
467
    public FieldDescription removeField(String fieldName) {
468
        // TODO Auto-generated method stub
469
        logger.info("remove field? null");
470

    
471
        return null;
472
    }
473

    
474
    public void renameField(String antName, String newName) {
475
        // TODO Auto-generated method stub
476
        logger.info("rename field .. nothing done");
477
    }
478

    
479
    public boolean alterTable() throws WriteDriverException {
480
        logger.info("alter table? false");
481
        return false;
482
    }
483

    
484
    public FieldDescription[] getFields() {
485
        // TODO Auto-generated method stub
486
        logger.info("get fields? null");
487

    
488
        return tableDef.getFieldsDesc();
489
    }
490

    
491
    public void setBbox(Rectangle2D b) {
492
        bbox = b;
493
    }
494

    
495
    public void setDriver(OracleSpatialDriver d) {
496
        driver = d;
497
    }
498

    
499
    public void setLyrShapeType(int shptype) {
500
        lyrShapeType = shptype;
501
    }
502

    
503
    public void setDimensions(int dims) {
504
        dimensions = dims;
505
    }
506

    
507
    public void setAguBien(boolean agu_bien) {
508
        aguBien = agu_bien;
509
    }
510

    
511
    public void setStoreWithSrid(boolean with) {
512
        storeWithSrid = with;
513
    }
514

    
515
    public void setGeoCS(boolean g) {
516
        isGeoCS = g;
517
    }
518

    
519
    public void setGeoColName(String g) {
520
        geoColName = g;
521
    }
522

    
523
    public OracleSpatialDriver getDriver() {
524
        return driver;
525
    }
526

    
527
    public void setSRID(String s) {
528
        oracleSRID = s;
529
    }
530
}