Statistics
| Revision:

root / branches / v2_0_0_prep / extensions / org.gvsig.oracle / src / org / gvsig / fmap / dal / store / oracle / OracleHelper.java @ 38081

History | View | Annotate | Download (33.3 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
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 2
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
 */
22

    
23
/*
24
 * AUTHORS (In addition to CIT):
25
 * 2009 Prodevelop S.L. main development
26
 */
27

    
28
package org.gvsig.fmap.dal.store.oracle;
29

    
30
import java.awt.geom.Rectangle2D;
31
import java.sql.Connection;
32
import java.sql.ResultSet;
33
import java.sql.ResultSetMetaData;
34
import java.sql.SQLException;
35
import java.sql.Statement;
36
import java.util.ArrayList;
37
import java.util.Iterator;
38
import java.util.List;
39

    
40
import oracle.sql.ARRAY;
41
import oracle.sql.Datum;
42
import oracle.sql.STRUCT;
43

    
44
import org.cresques.cts.IProjection;
45
import org.gvsig.fmap.crs.CRSFactory;
46
import org.gvsig.fmap.dal.DALLocator;
47
import org.gvsig.fmap.dal.DataTypes;
48
import org.gvsig.fmap.dal.exception.DataException;
49
import org.gvsig.fmap.dal.exception.InitializeException;
50
import org.gvsig.fmap.dal.exception.ReadException;
51
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
52
import org.gvsig.fmap.dal.feature.EditableFeatureType;
53
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
54
import org.gvsig.fmap.dal.feature.exception.UnsupportedDataTypeException;
55
import org.gvsig.fmap.dal.feature.exception.UnsupportedGeometryException;
56
import org.gvsig.fmap.dal.feature.impl.DefaultEditableFeatureAttributeDescriptor;
57
import org.gvsig.fmap.dal.feature.impl.DefaultEditableFeatureType;
58
import org.gvsig.fmap.dal.resource.ResourceAction;
59
import org.gvsig.fmap.dal.resource.spi.ResourceManagerProviderServices;
60
import org.gvsig.fmap.dal.store.jdbc.ConnectionAction;
61
import org.gvsig.fmap.dal.store.jdbc.JDBCHelper;
62
import org.gvsig.fmap.dal.store.jdbc.JDBCHelperUser;
63
import org.gvsig.fmap.dal.store.jdbc.JDBCStoreParameters;
64
import org.gvsig.fmap.dal.store.jdbc.TransactionalAction;
65
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCException;
66
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCExecuteSQLException;
67
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCSQLException;
68
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCTransactionCommitException;
69
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCTransactionRollbackException;
70
import org.gvsig.fmap.geom.Geometry;
71
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
72
import org.gvsig.fmap.geom.Geometry.TYPES;
73
import org.gvsig.fmap.geom.primitive.Envelope;
74
import org.gvsig.fmap.geom.primitive.Point;
75
import org.gvsig.fmap.geom.primitive.impl.Envelope2D;
76
import org.gvsig.fmap.geom.primitive.impl.Envelope3D;
77
import org.gvsig.fmap.geom.primitive.impl.Point2DZ;
78
import org.gvsig.tools.exception.BaseException;
79
import org.slf4j.Logger;
80
import org.slf4j.LoggerFactory;
81

    
82
/**
83
 * Oracle helper
84
 * 
85
 * @author vsanjaime
86
 * 
87
 */
88
public class OracleHelper extends JDBCHelper {
89

    
90

    
91
        private static final double ORACLE_SPATIAL_DEFAULT_TOLERANCE = 0.0005;
92

    
93
        private static final String IDENTIFIER_QUOTE_STRING = "\"";
94

    
95
        private static Logger logger = LoggerFactory.getLogger(OracleHelper.class);
96

    
97
        // private boolean tableHasSrid = true;
98
        // private String oracleSRID;
99
        private IProjection viewProjection = null;
100

    
101

    
102

    
103
        /**
104
         * Constructor
105
         * 
106
         * @param consumer
107
         * @param params
108
         * @throws InitializeException
109
         */
110
        public OracleHelper(JDBCHelperUser consumer,
111
                        OracleConnectionParameters params) throws InitializeException {
112

    
113
                super(consumer, params);
114
        }
115

    
116
        /**
117
         * Initialize resource
118
         * 
119
         * @throws InitializeException
120
         */
121
        protected void initializeResource() throws InitializeException {
122
                ResourceManagerProviderServices manager = (ResourceManagerProviderServices) DALLocator
123
                                .getResourceManager();
124
                OracleResource resource = (OracleResource) manager.createResource(
125
                                OracleResource.NAME, new Object[] {
126
                                                params.getUrl(),
127
                                                params.getHost(),
128
                                                params.getPort(),
129
                                                params.getDBName(),
130
                                                params.getUser(),
131
                                                params.getPassword(),
132
                                                params.getJDBCDriverClassName(),
133
                                                ((OracleConnectionParameters) params).getUseSSL(),
134
                                                ((OracleConnectionParameters) params)
135
                                                                .getOraDriverType() });
136
                this.setResource(resource);
137
        }
138

    
139
        /**
140
         * Get default schema name
141
         * 
142
         * @param conn
143
         * @return
144
         */
145
        protected String getDefaultSchema(Connection conn) throws JDBCException {
146
                if (defaultSchema == null) {
147
                        String sql = "SELECT sys_context('USERENV', 'CURRENT_SCHEMA') FROM dual";
148
                        ResultSet rs = null;
149
                        Statement st = null;
150
                        String schema = null;
151
                        try {
152
                                st = conn.createStatement();
153
                                try {
154
                                        rs = st.executeQuery(sql);
155
                                } catch (java.sql.SQLException e) {
156
                                        throw new JDBCExecuteSQLException(sql, e);
157
                                }
158
                                rs.next();
159
                                schema = rs.getString(1);
160
                        } catch (java.sql.SQLException e) {
161
                                throw new JDBCSQLException(e);
162
                        } finally {
163
                                try {
164
                                        rs.close();
165
                                } catch (Exception e) {
166
                                        logger.error("Exception clossing resulset", e);
167
                                }
168
                                ;
169
                                try {
170
                                        st.close();
171
                                } catch (Exception e) {
172
                                        logger.error("Exception clossing statement", e);
173
                                }
174
                                ;
175
                                rs = null;
176
                                st = null;
177
                        }
178
                        defaultSchema = schema;
179
                }
180

    
181
                return defaultSchema;
182
        }
183

    
184
        /**
185
         * get full envelope of geometry field
186
         */
187
        public Envelope getFullEnvelopeOfField(JDBCStoreParameters storeParams,
188
                        String geometryAttrName, Envelope limit) throws DataException {
189
                
190
                Object filterobj = storeParams.getDynValue("filterarea");
191
                if (filterobj != null && filterobj instanceof Geometry) {
192
                        Geometry filtergeom = (Geometry) filterobj;
193
                        return filtergeom.getEnvelope();
194
                }
195
                
196
                if (limit != null) {
197
                        return limit; 
198
                }
199

    
200
                String _schema = (String) ((OracleStoreParameters) storeParams).getDynValue("schema");
201
                
202
                StringBuilder strb = new StringBuilder();
203
                strb.append("SELECT * FROM "
204
                                + OracleValues.ALL_ORACLE_GEOMETADATA_VIEW);
205
                strb.append(" WHERE "
206
                                + OracleValues.USER_ORACLE_GEOMETADATA_VIEW_TABLE_NAME
207
                                + " = '" + storeParams.getTable() + "'");
208
                strb.append(" AND "
209
                                + OracleValues.USER_ORACLE_GEOMETADATA_VIEW_COLUMN_NAME
210
                                + " = '" + geometryAttrName + "'");
211
                strb.append(" AND "
212
                                + OracleValues.USER_ORACLE_GEOMETADATA_VIEW_OWNER
213
                                + " = '" + _schema + "'");
214
                String sql = strb.toString();
215

    
216
                ResultSet rs = null;
217
                Statement st = null;
218
                // String schema = null;
219
                Connection conn = null;
220

    
221
                Envelope fullEnvelope = null;
222
                this.open();
223
                try {
224
                        conn = getConnection();
225
                        st = conn.createStatement();
226
                        try {
227
                                rs = st.executeQuery(sql);
228
                        } catch (java.sql.SQLException e) {
229
                                throw new JDBCExecuteSQLException(sql, e);
230
                        }
231
                        if (!rs.next()) {
232
                                return null;
233
                        }
234

    
235
                        // DIMINFO (ARRAY)
236
                        ARRAY dim_info_array = (ARRAY) rs.getObject("DIMINFO");
237

    
238
                        Datum[] da = dim_info_array.getOracleArray();
239
                        int dim = da.length;
240

    
241
                        STRUCT sx = (STRUCT) da[0];
242
                        STRUCT sy = (STRUCT) da[1];
243
                        double minx = Double.parseDouble(sx.getAttributes()[1].toString());
244
                        double maxx = Double.parseDouble(sx.getAttributes()[2].toString());
245
                        double miny = Double.parseDouble(sy.getAttributes()[1].toString());
246
                        double maxy = Double.parseDouble(sy.getAttributes()[2].toString());
247
                        if (minx > maxx) {
248
                                double aux = minx;
249
                                minx = maxx;
250
                                maxx = aux;
251
                        }
252

    
253
                        if (miny > maxy) {
254
                                double aux = miny;
255
                                miny = maxy;
256
                                maxy = aux;
257
                        }
258

    
259
                        // dim 3
260
                        STRUCT sz = null;
261
                        double minz = 0;
262
                        double maxz = 0;
263
                        if (dim == 2) {
264
                                fullEnvelope = new Envelope2D(minx, miny, maxx, maxy);
265
                        } else if (dim == 3) {
266
                                sz = (STRUCT) da[2];
267
                                minz = Double.parseDouble(sz.getAttributes()[1].toString());
268
                                maxz = Double.parseDouble(sz.getAttributes()[2].toString());
269

    
270
                                Point minPto = new Point2DZ(minx, miny, minz);
271
                                Point maxPto = new Point2DZ(maxx, maxy, maxz);
272

    
273
                                fullEnvelope = new Envelope3D(minPto, maxPto);
274
                        }
275

    
276
                        return fullEnvelope;
277

    
278
                } catch (Exception e) {
279
                        return null;
280
                }
281

    
282
                finally {
283
                        try {
284
                                rs.close();
285
                        } catch (Exception e) {
286
                        }
287

    
288
                        try {
289
                                st.close();
290
                        } catch (Exception e) {
291
                        }
292

    
293
                        /*
294
                        try {
295
                                conn.close();
296
                        } catch (Exception e) {
297
                        }
298
                        */
299

    
300
                        finally {
301
                                rs = null;
302
                                st = null;
303
                                conn = null;
304
                        }
305
                }
306
        }
307

    
308
        /**
309
         * 
310
         */
311
//        protected void initializeFromWKBOperation() throws BaseException {
312
//                // TODO
313
//                if (fromWKB == null) {
314
//                        fromWKB = (FromWKB) GeometryLocator.getGeometryManager()
315
//                                        .getGeometryOperation(FromWKB.CODE,
316
//                                                        Geometry.TYPES.GEOMETRY, Geometry.SUBTYPES.GEOM2D);
317
//                        fromWKBContext = new FromWKBGeometryOperationContext();
318
//                }
319
//        }
320

    
321
        /**
322
         * 
323
         */
324
        public Geometry getGeometry(byte[] buffer) throws BaseException {
325
                // TODO BLOB format in Oracle?
326
                logger.error("Unsupported: binary Geometry format");
327
                return null;
328
        }
329

    
330
        /**
331
         * get geometry column name "SDO_GEOMETRY"
332
         * 
333
         * @param attr
334
         * @return
335
         */
336
        public String getSqlColumnTypeDescription(FeatureAttributeDescriptor attr) {
337

    
338
                switch (attr.getDataType().getType()) {
339

    
340
                case DataTypes.GEOMETRY:
341
                        return "\"MDSYS\".\"SDO_GEOMETRY\"";
342

    
343
                case DataTypes.STRING:
344
                        return "NVARCHAR2(" + attr.getSize() + ")";
345

    
346
                case DataTypes.BOOLEAN:
347
                        return "NUMBER(1, 0)";
348

    
349
                case DataTypes.BYTE:
350
                        return "NUMBER";
351

    
352
                case DataTypes.DATE:
353
                        return "DATE";
354

    
355
                case DataTypes.TIMESTAMP:
356
                        return "TIMESTAMP";
357

    
358
                case DataTypes.TIME:
359
                        return "TIMESTAMP";
360

    
361
                case DataTypes.BYTEARRAY:
362

    
363
                case DataTypes.DOUBLE:
364
                        return "FLOAT";
365

    
366
                case DataTypes.FLOAT:
367
                        return "FLOAT";
368

    
369
                case DataTypes.INT:
370
                        return "NUMBER(12, 0)";
371

    
372
                case DataTypes.LONG:
373
                        return "NUMBER(38, 0)";
374

    
375
                default:
376
                        String typeName = (String) attr.getAdditionalInfo("SQLTypeName");
377
                        if (typeName != null) {
378
                                return typeName;
379
                        }
380
                        throw new UnsupportedDataTypeException(attr.getDataTypeName(), attr
381
                                        .getDataType().getType());
382
                }
383

    
384
        }
385

    
386
        /**
387
         * Get oracle geometry dimension
388
         * 
389
         * @param geometrySubType
390
         * @return
391
         */
392
        public int getOraGeomDimensions(int geometrySubType) {
393

    
394
                switch (geometrySubType) {
395
                case Geometry.SUBTYPES.GEOM2D:
396
                        return 2;
397
                case Geometry.SUBTYPES.GEOM2DM:
398
                case Geometry.SUBTYPES.GEOM3D:
399
                        return 3;
400
                case Geometry.SUBTYPES.GEOM3DM:
401
                        return 4;
402
                default:
403
                        throw new UnsupportedDataTypeException(
404
                                        "GEOMETRY field",
405
                                        DataTypes.GEOMETRY);
406
                }
407
        }
408

    
409
        /**
410
         * Get Oracle geometry type
411
         * 
412
         * @param geometryType
413
         * @param geometrySubType
414
         * @return
415
         */
416
        public String getOraGeomType(int geometryType, int geometrySubType) {
417
                String oraGeomType;
418
                switch (geometryType) {
419
                case Geometry.TYPES.GEOMETRY:
420
                        oraGeomType = OracleValues.OraGeometry_GTYPE_GEOMETRY;
421
                        break;
422
                case Geometry.TYPES.POINT:
423
                        oraGeomType = OracleValues.OraGeometry_GTYPE_POINT;
424
                        break;
425
                case Geometry.TYPES.CURVE:
426
                        oraGeomType = OracleValues.OraGeometry_GTYPE_CURVE;
427
                        break;
428
                /*
429
                case Geometry.TYPES..TEXT:
430
                        oraGeomType = OracleValues.OraGeometry_GTYPE_GEOMETRY;
431
                        break;
432
                */
433
                case Geometry.TYPES.SOLID:
434
                        oraGeomType = OracleValues.OraGeometry_GTYPE_GEOMETRY;
435
                        break;
436
                case Geometry.TYPES.AGGREGATE:
437
                        oraGeomType = OracleValues.OraGeometry_GTYPE_GEOMETRY;
438
                        break;
439
                case Geometry.TYPES.SURFACE:
440
                        oraGeomType = OracleValues.OraGeometry_GTYPE_POLYGON;
441
                        break;
442
                case Geometry.TYPES.MULTIPOINT:
443
                        oraGeomType = OracleValues.OraGeometry_GTYPE_MULTIPOINT;
444
                        break;
445
                case Geometry.TYPES.MULTICURVE:
446
                        oraGeomType = OracleValues.OraGeometry_GTYPE_MULTICURVE;
447
                        break;
448
                case Geometry.TYPES.MULTISURFACE:
449
                        oraGeomType = OracleValues.OraGeometry_GTYPE_MULTIPOLYGON;
450
                        break;
451
                case Geometry.TYPES.MULTISOLID:
452
                        oraGeomType = OracleValues.OraGeometry_GTYPE_GEOMETRY;
453
                        break;
454
                case Geometry.TYPES.CIRCLE:
455
                        oraGeomType = OracleValues.OraGeometry_GTYPE_GEOMETRY;
456
                        break;
457
                case Geometry.TYPES.ARC:
458
                        oraGeomType = OracleValues.OraGeometry_GTYPE_GEOMETRY;
459
                        break;
460
                case Geometry.TYPES.ELLIPSE:
461
                        oraGeomType = OracleValues.OraGeometry_GTYPE_GEOMETRY;
462
                        break;
463
                case Geometry.TYPES.SPLINE:
464
                        oraGeomType = OracleValues.OraGeometry_GTYPE_GEOMETRY;
465
                        break;
466
                case Geometry.TYPES.ELLIPTICARC:
467
                        oraGeomType = OracleValues.OraGeometry_GTYPE_GEOMETRY;
468
                        break;
469
                default:
470
                        throw new UnsupportedGeometryException(geometryType,
471
                                        geometrySubType);
472
                }
473
                return oraGeomType;
474
        }
475

    
476
        /**
477
         * 
478
         */
479
        public String getSqlFieldName(FeatureAttributeDescriptor attribute) {
480
                /*
481
                if (attribute.getDataType() == DataTypes.GEOMETRY) {
482
                        return "asBinary(" + super.getSqlFieldName(attribute) + ")";
483
                }
484
                */
485
                return super.getSqlFieldName(attribute);
486
        }
487
        
488
        protected String getIdentifierQuoteString() {
489
                return IDENTIFIER_QUOTE_STRING;
490
        }
491

    
492
        /**
493
         * 
494
         */
495
        protected EditableFeatureAttributeDescriptor createAttributeFromJDBC(
496
                        EditableFeatureType fType, Connection conn,
497
                        ResultSetMetaData rsMetadata, int colIndex) throws SQLException {
498
                
499
                String rstypename = rsMetadata.getColumnTypeName(colIndex);
500
                if (rstypename
501
                                .equalsIgnoreCase(OracleValues.OraGeometry_GTYPE_GEOMETRY)) {
502

    
503
                        return fType.add(rsMetadata.getColumnName(colIndex),
504
                                        DataTypes.GEOMETRY);
505
                }
506

    
507
                EditableFeatureAttributeDescriptor column;
508
                switch (rsMetadata.getColumnType(colIndex)) {
509
                case java.sql.Types.INTEGER:
510
                        column = fType.add(rsMetadata.getColumnName(colIndex),
511
                                        DataTypes.INT);
512
                        break;
513
                case java.sql.Types.BIGINT:
514
                        column = fType.add(rsMetadata.getColumnName(colIndex),
515
                                        DataTypes.LONG);
516
                        break;
517
                case java.sql.Types.REAL:
518
                        column = fType.add(rsMetadata.getColumnName(colIndex),
519
                                        DataTypes.DOUBLE);
520
                        break;
521
                case java.sql.Types.DOUBLE:
522
                        column = fType.add(rsMetadata.getColumnName(colIndex),
523
                                        DataTypes.DOUBLE);
524
                        break;
525
                case java.sql.Types.CHAR:
526
                        column = fType.add(rsMetadata.getColumnName(colIndex),
527
                                        DataTypes.STRING);
528
                        break;
529
                case java.sql.Types.VARCHAR:
530
                case java.sql.Types.LONGVARCHAR:
531
                        column = fType.add(rsMetadata.getColumnName(colIndex),
532
                                        DataTypes.STRING);
533
                        break;
534
                case java.sql.Types.FLOAT:
535
                        column = fType.add(rsMetadata.getColumnName(colIndex),
536
                                        DataTypes.FLOAT);
537
                        break;
538
                case java.sql.Types.DECIMAL:
539
                        column = fType.add(rsMetadata.getColumnName(colIndex),
540
                                        DataTypes.FLOAT);
541
                        break;
542
                case java.sql.Types.DATE:
543
                        column = fType.add(rsMetadata.getColumnName(colIndex),
544
                                        DataTypes.DATE);
545
                        break;
546
                case java.sql.Types.TIME:
547
                        column = fType.add(rsMetadata.getColumnName(colIndex),
548
                                        DataTypes.TIME);
549
                        break;
550
                case java.sql.Types.TIMESTAMP:
551
                        column = fType.add(rsMetadata.getColumnName(colIndex),
552
                                        DataTypes.TIMESTAMP);
553
                        break;
554
                case java.sql.Types.BOOLEAN:
555
                        column = fType.add(rsMetadata.getColumnName(colIndex),
556
                                        DataTypes.BOOLEAN);
557
                        break;
558
                case java.sql.Types.BLOB:
559
                case java.sql.Types.BINARY:
560
                case java.sql.Types.LONGVARBINARY:
561
                        column = fType.add(rsMetadata.getColumnName(colIndex),
562
                                        DataTypes.BYTEARRAY);
563
                        break;
564

    
565
                case java.sql.Types.NUMERIC:
566
                        
567
                        // decimal positions to the right of point
568
                        int scale = rsMetadata.getScale(colIndex);
569
                        // decimal positions to the right of point
570
                        // int leftdigits = rsMetadata.getPrecision(colIndex);
571
                        
572
                        if (scale == 0) { 
573
                                column = fType.add(rsMetadata.getColumnName(colIndex),
574
                                                DataTypes.LONG);
575
                        } else {
576
                                column = fType.add(rsMetadata.getColumnName(colIndex),
577
                                                DataTypes.DOUBLE);
578
                        }
579
                        
580
                        break;
581

    
582
                default:
583
                        column = fType.add(rsMetadata.getColumnName(colIndex),
584
                                        DataTypes.OBJECT);
585
                        column.setAdditionalInfo("SQLType", new Integer(rsMetadata
586
                                        .getColumnType(colIndex)));
587
                        column.setAdditionalInfo("SQLTypeName", rsMetadata
588
                                        .getColumnTypeName(colIndex));
589

    
590
                        break;
591
                }
592

    
593
                return column;
594

    
595

    
596
                // return super.createAttributeFromJDBC(type, conn, rsMetadata, colIndex);
597
        }
598

    
599
        /**
600
         * 
601
         */
602
        public boolean allowAutomaticValues() {
603
                return Boolean.TRUE;
604
        }
605

    
606
        /**
607
         * 
608
         */
609
        public boolean supportOffset() {
610
                return true;
611
        }
612

    
613
        /**
614
         * 
615
         */
616
        public boolean supportsUnion() {
617
                return true;
618
        }
619

    
620
        /**
621
         * get sql with fields description
622
         * 
623
         * @param attr
624
         * @return
625
         */
626
        public String getSqlFieldDescription(FeatureAttributeDescriptor attr)
627
                        throws DataException {
628

    
629
                StringBuilder strb = new StringBuilder();
630
                // name
631
                strb.append("\"" + attr.getName() + "\" ");
632

    
633
                // Type
634
                strb.append(this.getSqlColumnTypeDescription(attr));
635

    
636
                // Primary key
637
                if (attr.isPrimaryKey()) {
638
                        strb.append(" PRIMARY KEY");
639
                }
640

    
641
                return strb.toString();
642
        }
643

    
644
        /**
645
         * UTility method to get the SQL sentence needed to update the geographic
646
         * metadata table with a new bounding box and SRS
647
         * 
648
         * @param tName
649
         *            table name
650
         * @param ora_srid
651
         *            new SRS
652
         * @param bbox
653
         *            new bounding box
654
         * @param dim
655
         *            geometries dimension
656
         * @param withsrid
657
         *            False if the SRS is set to NULL. True otherwise.
658
         * @return the SQL sentence to perform the update
659
         */
660
        public String getSqlUpdateMetadata(OracleStoreParameters params,
661
                        String ora_srid, Rectangle2D bbox, int dim, boolean withsrid) {
662

    
663
                String[] dim_name = new String[dim];
664
                // double tolerance = ORACLE_SPATIAL_DEFAULT_TOLERANCE;
665

    
666
                String _ora_srid = ora_srid;
667
                if (_ora_srid == null)
668
                        _ora_srid = "NULL";
669

    
670
                if (_ora_srid.compareTo(OracleValues.GEODETIC_SRID) == 0) {
671
                        dim_name[0] = "LONGITUDE";
672
                        dim_name[1] = "LATITUDE";
673
                } else {
674
                        dim_name[0] = "X";
675
                        dim_name[1] = "Y";
676

    
677
                        if (dim > 2) {
678
                                dim_name[2] = "Z";
679

    
680
                                if (dim > 3) {
681
                                        dim_name[3] = "T";
682
                                }
683
                        }
684
                }
685

    
686
                double minx = bbox.getMinX();
687
                double miny = bbox.getMinY();
688
                double maxx = bbox.getMaxX();
689
                double maxy = bbox.getMaxY();
690

    
691
                String resp = "INSERT INTO "
692
                                + OracleValues.USER_ORACLE_GEOMETADATA_VIEW + " "
693
                                + " ( TABLE_NAME, COLUMN_NAME, DIMINFO, SRID ) " + " VALUES ("
694
                                + "'" + params.getTable() + "', " + "'"
695
                                + OracleValues.DEFAULT_GEO_FIELD + "', "
696
                                + "MDSYS.SDO_DIM_ARRAY( " + "MDSYS.SDO_DIM_ELEMENT ('"
697
                                + dim_name[0] + "', " + minx + ", " + maxx + ", " + ORACLE_SPATIAL_DEFAULT_TOLERANCE
698
                                + " ), " + "MDSYS.SDO_DIM_ELEMENT ('" + dim_name[1] + "', "
699
                                + miny + ", " + maxy + ", " + ORACLE_SPATIAL_DEFAULT_TOLERANCE + " ))";
700

    
701
                if (dim > 2) {
702
                        resp = resp.substring(0, resp.length() - 1) + ",";
703
                        resp = resp + "MDSYS.SDO_DIM_ELEMENT ('" + dim_name[2]
704
                                        + "', 0.0, 100.0, " + ORACLE_SPATIAL_DEFAULT_TOLERANCE + " ))";
705

    
706
                        if (dim > 3) {
707
                                resp = resp.substring(0, resp.length() - 1) + ",";
708
                                resp = resp + "MDSYS.SDO_DIM_ELEMENT ('" + dim_name[3]
709
                                                + "', 0.0, 100.0, " + ORACLE_SPATIAL_DEFAULT_TOLERANCE + " ))";
710
                        }
711
                }
712

    
713
                if (withsrid) {
714
                        resp = resp + ", " + _ora_srid + " )";
715
                } else {
716
                        resp = resp + ", NULL )";
717
                }
718

    
719
                return resp;
720
        }
721

    
722

    
723
        
724
        
725
        /**
726
         * 
727
         */
728
        public void loadFeatureType(EditableFeatureType featureType,
729
                        JDBCStoreParameters storeParams) throws DataException {
730
                
731
                if ((storeParams.getDefaultGeometryField() == null) && (storeParams instanceof OracleNewStoreParameters)) {
732
                        OracleNewStoreParameters osp = (OracleNewStoreParameters) storeParams;
733
                        String geoname = osp.getDefaultFeatureType().getDefaultGeometryAttributeName();
734
                        storeParams.setDefaultGeometryField(geoname);
735
                }
736

    
737
                String sqlstr = storeParams.getSQL();
738
                
739
                if (sqlstr != null && sqlstr.trim().length() > 0) {
740
                        // loadFeatureType(featureType, storeParams, sqlstr);
741
                } else {
742
                        sqlstr = "SELECT * FROM " + storeParams.tableID() + " WHERE ROWID = NULL";
743
                        storeParams.setSQL(sqlstr);
744
                }
745
                
746
                loadFeatureType(featureType, storeParams, sqlstr, storeParams
747
                                .getSchema(), storeParams.getTable());
748
                
749
                storeParams.setSQL(null);
750
                // super.loadFeatureType(featureType, storeParams);
751
        }
752

    
753
        /**
754
         * Fill <code>featureType</code> geometry attributes with ShapeType
755
         * information stored in the table USER_SDO_GEOMETRY_METADATA
756
         * 
757
         * @param conn
758
         * @param rsMetadata
759
         * @param featureType
760
         * @throws ReadException
761
         */
762
        protected void loadSRS_and_shapeType(Connection conn,
763
                        ResultSetMetaData rs_Metadata, EditableFeatureType featureType,
764
                        String baseSchema, String baseTable) throws JDBCException {
765

    
766
                Statement st = null;
767
                ResultSet rs = null;
768
                String reserved_geocolname = null;
769
                
770
                try {
771
                        // Sacamos la lista de los attributos geometricos
772

    
773
                        EditableFeatureAttributeDescriptor attr;
774
                        ArrayList geoAttrs = new ArrayList();
775

    
776
                        Iterator iter = featureType.iterator();
777
                        while (iter.hasNext()) {
778
                                attr = (EditableFeatureAttributeDescriptor) iter.next();
779
                                if (attr.getDataType().getType() == DataTypes.GEOMETRY) {
780
                                        geoAttrs.add(attr);
781
                                }
782
                        }
783
                        if (geoAttrs.size() < 1) {
784
                                return;
785
                        }
786

    
787
                        // Preparamos una sql para que nos saque el resultado
788
                        StringBuilder strb = new StringBuilder();
789
                        strb.append("SELECT * FROM "
790
                                        + OracleValues.ALL_ORACLE_GEOMETADATA_VIEW + " WHERE "
791
                                        + OracleValues.USER_ORACLE_GEOMETADATA_VIEW_TABLE_NAME
792
                                        + " = '" + baseTable + "' AND "
793
                                        + OracleValues.USER_ORACLE_GEOMETADATA_VIEW_OWNER
794
                                        + " = '" + baseSchema + "'");
795
                                        
796
                        String sql = strb.toString();
797

    
798
                        st = conn.createStatement();
799
                        try {
800
                                rs = st.executeQuery(sql);
801
                        } catch (SQLException e) {
802
                                throw new JDBCExecuteSQLException(sql, e);
803
                        }
804
                        
805
                        String srID;
806

    
807
                        EditableFeatureAttributeDescriptor auxdesc;
808
                        
809

    
810
                                while (rs.next()) {
811
                                        String rsName =
812
                                                rs.getString(OracleValues.USER_ORACLE_GEOMETADATA_VIEW_COLUMN_NAME);
813
                                        reserved_geocolname = rsName;
814
                                        auxdesc = getAttrDescForCol(geoAttrs, rsName);
815
                                        if (auxdesc != null) {
816
                                                Object sridobj = rs.getObject("SRID");
817
                                                if (sridobj == null) {
818
                                                        if (getViewProjection() != null) {
819
                                                                // ora table has no srid, use SRS of the view
820
                                                                auxdesc.setSRS(getViewProjection());
821
                                                        }
822
                                                } else {
823
                                                        srID = sridobj.toString();
824
                                                        int epsg = OracleUtils.oracleSridToEpsg(srID);
825
                                                        String sepsg = "EPSG:" + Integer.toString(epsg);
826
                                                        auxdesc.setSRS(CRSFactory.getCRS(sepsg));
827
                                                }
828
                                        }
829
                                        if (featureType.getDefaultGeometryAttribute() == null) {
830
                                                ((DefaultEditableFeatureType) featureType).setDefaultGeometryAttributeName(reserved_geocolname);
831
                                        }
832
                                        
833
                        }
834
                } catch (java.sql.SQLException e) {
835
                        throw new JDBCSQLException(e);
836
                } finally {
837
                        try { rs.close(); } catch (Exception e) { };
838
                        try { st.close(); } catch (Exception e) { };
839
                }
840
                
841
                // guess shape type
842
                String geoColName = featureType.getDefaultGeometryAttributeName();
843
                if (geoColName == null) {
844
                        geoColName = reserved_geocolname; 
845
                }
846
                
847
                try {
848
                        String str_geo = "SELECT " + geoColName + " FROM " +  
849
                        ((baseSchema != null) ? (baseSchema + "." + baseTable) : baseTable) +
850
                        " WHERE (" + geoColName + " IS NOT NULL) AND " + OracleUtils.EXPONENTIAL_INDICES_CONDITION; 
851

    
852
                        st = conn.createStatement();
853
                        try {
854
                                rs = st.executeQuery(str_geo);
855
                        } catch (SQLException e) {
856
                                throw new JDBCExecuteSQLException(str_geo, e);
857
                        }
858
                        
859
            int aux = 0;
860
            int guess_type = TYPES.GEOMETRY;
861
            int guess_subtype = SUBTYPES.GEOM2D;
862
            
863
            STRUCT sample_geo;
864
            ArrayList shptypes = new ArrayList();
865
            int[] ty_subty;
866
            while (rs.next()) {
867
                sample_geo = (STRUCT) rs.getObject(1);
868
                ty_subty = OracleUtils.getGeoTypeSubTypeOfStruct(sample_geo); 
869
                aux = ty_subty[0];
870
                guess_subtype = ty_subty[1];
871
                shptypes.add(new Integer(aux));
872
            }
873

    
874
            if (shptypes.size() > 0) {
875
                    guess_type = OracleUtils.getShapeTypeFromArray(shptypes);
876
            } else {
877
                    logger.warn("Did not find geometries to sample. Assumed TYPE = GEOMETRY, SUBTYPE = 2D");
878
            }
879

    
880
            DefaultEditableFeatureAttributeDescriptor dfad = null;
881
            try {
882
                dfad = (DefaultEditableFeatureAttributeDescriptor) featureType.getDefaultGeometryAttribute();
883
                dfad.setGeometryType(guess_type);
884
                dfad.setGeometrySubType(guess_subtype);
885
            } catch (ClassCastException cce) {
886
                    logger.error("Unexpected non editable feature type. Did not set geo types.");
887
            }
888
                } catch (java.sql.SQLException e) {
889
                        throw new JDBCSQLException(e);
890
                } finally {
891
                        try {rs.close();} catch (Exception e) {        };
892
                        try {st.close();} catch (Exception e) { };
893
                }
894
        }
895

    
896
        private EditableFeatureAttributeDescriptor getAttrDescForCol(ArrayList list, String name) {
897
                
898
                int sz = list.size();
899
                for (int i=0; i<sz; i++) {
900
                        EditableFeatureAttributeDescriptor aux = (EditableFeatureAttributeDescriptor) list.get(i);
901
                        if (aux.getName().compareToIgnoreCase(name) == 0) {
902
                                return aux;
903
                        }
904
                }
905
                // not found
906
                return null;
907
        }
908

    
909
        /**
910
         * Add oracle geometry field and add spatial index
911
         * 
912
         * @param attr
913
         * @param table
914
         * @param schema
915
         * @return
916
         */
917
        public List<String> getSqlGeometryFieldAdd(FeatureAttributeDescriptor attr,
918
                        String table, String schema) {
919

    
920
                List<String> sqls = new ArrayList<String>();
921

    
922
                StringBuilder strb1 = new StringBuilder();
923
                strb1.append("Alter table ");
924
                if (schema != null && schema.length() > 0) {
925
                        strb1.append(schema);
926
                        strb1.append(".");
927
                }
928
                strb1.append(table);
929
                strb1.append(" add (");
930
                strb1.append(attr.getName());
931
                strb1.append(" SDO_GEOMETRY)");
932

    
933
                sqls.add(strb1.toString());
934

    
935
                String sqlindex = "CREATE INDEX "
936
                                + OracleUtils.getDerivedName(table, "SX") + " ON " + table
937
                                + " (\"" + attr.getName()
938
                                + "\") INDEXTYPE IS \"MDSYS\".\"SPATIAL_INDEX\" ";
939

    
940
                sqls.add(sqlindex);
941

    
942
                return sqls;
943
        }
944
        
945
        
946
        /**
947
         * Executes an atomic action that uses an DB Connection.<br>
948
         *
949
         * This methos prepares a connection and close it at the end of execution of
950
         * action.<br>
951
         *
952
         * if <code>action</code> is an instance of {@link TransactionalAction} the
953
         * action will be execute inside of a DB transaction.
954
         *
955
         *
956
         * @param action
957
         * @throws Exception
958
         */
959
        public Object doConnectionAction(final ConnectionAction action)
960
                        throws Exception {
961
                this.open();
962
//                this.begin();
963
                return getResource().execute(new ResourceAction() {
964
                        public Object run() throws Exception {
965
                                Object result = null;
966
                                Connection conn = null;
967
                                boolean beginTrans = false;
968
                                try {
969
                                        conn = getConnection();
970
                                        if (action instanceof TransactionalAction) {
971
                                                /*
972
                                                // XXX OJO esta condicion NO ES FIABLE
973
                                                if (!conn.getAutoCommit()) {
974
                                                        if (!((TransactionalAction) action)
975
                                                                        .continueTransactionAllowed()) {
976
                                                                // FIXME exception
977
                                                                throw new Exception();
978
                                                        }
979
                                                }
980
                                                */
981
                                                try {
982
                                                        conn.setAutoCommit(false);
983
                                                } catch (SQLException e) {
984
                                                        logger.warn("Unable to set auto commit = false when starting update in Oracle layer.");
985
                                                        // throw new JDBCSQLException(e);
986
                                                }
987
                                                beginTrans = true;
988
                                        }
989

    
990
                                        result = action.action(conn);
991

    
992
                                        if (beginTrans) {
993
                                                try {
994
                                                        conn.commit();
995
                                                } catch (SQLException e) {
996
                                                        throw new JDBCTransactionCommitException(e);
997
                                                }
998
                                        }
999

    
1000
                                        return result;
1001

    
1002
                                } catch (Exception e) {
1003

    
1004
                                        if (beginTrans) {
1005
                                                try {
1006
                                                        conn.rollback();
1007
                                                } catch (Exception e1) {
1008
                                                        throw new JDBCTransactionRollbackException(e1, e);
1009
                                                }
1010
                                        }
1011
                                        throw e;
1012

    
1013
                                /*
1014
                                } finally {
1015
                                        try {
1016
                                                conn.close();
1017
                                        } catch (Exception e1) {
1018
                                                logger.error("Exception on close connection", e1);
1019
                                        }
1020
                                */
1021
                                }
1022
                        }
1023
                });
1024
        }
1025
        
1026
        public void loadFeatureType(final EditableFeatureType featureType,
1027
                        final JDBCStoreParameters storeParams, final String sql,
1028
                        final String schema, final String table) throws DataException {
1029
                this.open();
1030
                
1031
                if (storeParams.getCRS() != null) {
1032
                        this.setViewProjection(storeParams.getCRS());
1033
                }
1034
//                this.begin();
1035
                getResource().execute(new ResourceAction() {
1036
                        public Object run() throws Exception {
1037
                                Connection conn = null;
1038
                                // try {
1039
                                        conn = getConnection();
1040
                                        
1041
                                        String[] pks = storeParams.getPkFields();
1042
                                        if (pks == null || pks.length < 1) {
1043
                                                if (storeParams.getTable() != null
1044
                                                                && storeParams.getTable().trim().length() > 0) {
1045
                                                        pks = getPksFrom(conn, storeParams);
1046
                                                        
1047
                                                }
1048
                                        }
1049
                                        
1050
                                        loadFeatureType(conn, featureType, sql, pks, storeParams
1051
                                                        .getDefaultGeometryField(), schema, table);                                        
1052
                                        
1053
                                /*
1054
                                } finally {
1055
                                        try {
1056
                                                conn.close();
1057
                                        } catch (Exception e) {
1058
                                        }
1059
                                */
1060
                                // }
1061
                                return null;
1062
                        }
1063
                });
1064
        }
1065
        
1066
        protected EditableFeatureAttributeDescriptor getAttributeFromJDBC(
1067
                        EditableFeatureType fType, Connection conn,
1068
                        ResultSetMetaData rsMetadata, int colIndex) throws JDBCException {
1069
                EditableFeatureAttributeDescriptor column;
1070
                try {
1071

    
1072
                        column = createAttributeFromJDBC(fType, conn, rsMetadata, colIndex);
1073
                        column.setAllowNull(true);
1074
                        column.setIsAutomatic(rsMetadata.isAutoIncrement(colIndex));
1075
                        column.setIsReadOnly(rsMetadata.isReadOnly(colIndex));
1076
                        column.setPrecision(rsMetadata.getPrecision(colIndex));
1077
                        column.setSize(rsMetadata.getColumnDisplaySize(colIndex));
1078

    
1079
                } catch (java.sql.SQLException e) {
1080
                        throw new JDBCSQLException(e);
1081
                }
1082

    
1083
                return column;
1084

    
1085
        }
1086

    
1087
        public String getOraTableSrid(OracleStoreParameters params,
1088
                        String geo_field) {
1089
                
1090
                StringBuilder strb = new StringBuilder();
1091
                strb.append("SELECT SRID FROM "
1092
                                + OracleValues.ALL_ORACLE_GEOMETADATA_VIEW);
1093
                strb.append(" WHERE "
1094
                                + OracleValues.USER_ORACLE_GEOMETADATA_VIEW_TABLE_NAME
1095
                                + " = '" + params.getTable() + "'");
1096
                strb.append(" AND "
1097
                                + OracleValues.USER_ORACLE_GEOMETADATA_VIEW_COLUMN_NAME
1098
                                + " = '" + geo_field + "'");
1099
                strb.append(" AND "
1100
                                + OracleValues.USER_ORACLE_GEOMETADATA_VIEW_OWNER
1101
                                + " = '" + params.getSchema() + "'");
1102
                String sql = strb.toString();
1103

    
1104
                ResultSet rs = null;
1105
                Statement st = null;
1106
                Connection conn = null;
1107
                String srid_str = "";
1108

    
1109
                try {
1110
                        this.open();
1111
                        
1112
                        conn = getConnection();
1113
                        st = conn.createStatement();
1114
                        try {
1115
                                rs = st.executeQuery(sql);
1116
                        } catch (java.sql.SQLException e) {
1117
                                throw new JDBCExecuteSQLException(sql, e);
1118
                        }
1119
                        if (!rs.next()) {
1120
                                return null;
1121
                        }
1122

    
1123
                        Object srid_obj = rs.getObject(1);
1124
                        if (srid_obj == null) {
1125
                                srid_str = null;
1126
                        } else {
1127
                                if (srid_obj instanceof Integer) {
1128
                                        srid_str = ((Integer) srid_obj).toString();
1129
                                } else {
1130
                                        srid_str = srid_obj.toString();
1131
                                }
1132
                        }
1133

    
1134
                } catch (Exception e) {
1135
                        logger.error("While getting SRID from Oracle view: " + e.getMessage());
1136
                        return null;
1137
                } finally {
1138
                        try {
1139
                                rs.close();
1140
                        } catch (Exception e) {
1141
                        }
1142

    
1143
                        try {
1144
                                st.close();
1145
                        } catch (Exception e) {
1146
                        }
1147

    
1148
                        rs = null;
1149
                        st = null;
1150
                        conn = null;
1151
                }
1152
                
1153
                return srid_str;
1154
                
1155
                
1156
        }
1157
        
1158
        
1159
        public IProjection getViewProjection() {
1160
                return viewProjection;
1161
        }
1162

    
1163
        public void setViewProjection(IProjection p) {
1164
                this.viewProjection = p;
1165
        }
1166
        
1167
        
1168
//        protected void loadFeatureType(Connection conn,
1169
//                        EditableFeatureType featureType, String sql, String[] pks,
1170
//                        String defGeomName, String schema, String table)
1171
//                        throws DataException {
1172
//
1173
//                Statement stAux = null;
1174
//                ResultSet rs = null;
1175
//                try {
1176
//
1177
//                        stAux = conn.createStatement();
1178
//                        stAux.setFetchSize(1);
1179
//
1180
//                        try {
1181
//                                rs = stAux.executeQuery(sql);
1182
//                        } catch (SQLException e) {
1183
//                                throw new JDBCExecuteSQLException(sql, e);
1184
//                        }
1185
//                        ResultSetMetaData rsMetadata = rs.getMetaData();
1186
//
1187
//                        List pksList = null;
1188
//                        if (pks != null) {
1189
//                                pksList = Arrays.asList(pks);
1190
//                        }
1191
//
1192
//                        int i;
1193
//                        int geometriesColumns = 0;
1194
//                        String lastGeometry = null;
1195
//
1196
//                        EditableFeatureAttributeDescriptor attr;
1197
//                        for (i = 1; i <= rsMetadata.getColumnCount(); i++) {
1198
//                                attr = getAttributeFromJDBC(featureType, conn, rsMetadata, i);
1199
//                                if (pksList != null && pksList.contains(attr.getName())) {
1200
//                                        attr.setIsPrimaryKey(true);
1201
//                                }
1202
//                                if (attr.getDataType() == DataTypes.GEOMETRY) {
1203
//                                        geometriesColumns++;
1204
//                                        lastGeometry = attr.getName();
1205
//                                        if (lastGeometry.equals(defGeomName)) {
1206
//                                                featureType.setDefaultGeometryAttributeName(defGeomName);
1207
//                                        }
1208
//                                }
1209
//                        }
1210
//
1211
//                        if (geometriesColumns > 0) {
1212
//                                loadSRS_and_shapeType(conn, rsMetadata, featureType, schema,
1213
//                                                table);
1214
//                        }
1215
//
1216
//                        if (defGeomName == null && geometriesColumns == 1) {
1217
//                                featureType.setDefaultGeometryAttributeName(lastGeometry);
1218
//                                defGeomName = lastGeometry;
1219
//                        }
1220
//
1221
//                } catch (java.sql.SQLException e) {
1222
//                        throw new JDBCSQLException(e); // FIXME exception
1223
//                } finally {
1224
//                        try {
1225
//                                rs.close();
1226
//                        } catch (Exception e) {
1227
//                        }
1228
//                        try {
1229
//                                stAux.close();
1230
//                        } catch (Exception e) {
1231
//                        }
1232
//
1233
//                }
1234
//
1235
//        }
1236

    
1237

    
1238
}