Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / extensions / org.gvsig.oracle / src / org / gvsig / fmap / dal / store / oracle / OracleHelper.java @ 37896

History | View | Annotate | Download (32.1 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
                StringBuilder strb = new StringBuilder();
191
                strb.append("SELECT * FROM "
192
                                + OracleValues.USER_ORACLE_GEOMETADATA_VIEW);
193
                strb.append(" WHERE "
194
                                + OracleValues.USER_ORACLE_GEOMETADATA_VIEW_TABLE_NAME
195
                                + " = '" + storeParams.getTable() + "'");
196
                strb.append(" AND "
197
                                + OracleValues.USER_ORACLE_GEOMETADATA_VIEW_COLUMN_NAME
198
                                + " = '" + geometryAttrName + "'");
199
                String sql = strb.toString();
200

    
201
                ResultSet rs = null;
202
                Statement st = null;
203
                String schema = null;
204
                Connection conn = null;
205

    
206
                Envelope fullEnvelope = null;
207
                this.open();
208
                try {
209
                        conn = getConnection();
210
                        st = conn.createStatement();
211
                        try {
212
                                rs = st.executeQuery(sql);
213
                        } catch (java.sql.SQLException e) {
214
                                throw new JDBCExecuteSQLException(sql, e);
215
                        }
216
                        if (!rs.next()) {
217
                                return null;
218
                        }
219

    
220
                        // DIMINFO (ARRAY)
221
                        ARRAY dim_info_array = (ARRAY) rs.getObject("DIMINFO");
222

    
223
                        Datum[] da = dim_info_array.getOracleArray();
224
                        int dim = da.length;
225

    
226
                        STRUCT sx = (STRUCT) da[0];
227
                        STRUCT sy = (STRUCT) da[1];
228
                        double minx = Double.parseDouble(sx.getAttributes()[1].toString());
229
                        double maxx = Double.parseDouble(sx.getAttributes()[2].toString());
230
                        double miny = Double.parseDouble(sy.getAttributes()[1].toString());
231
                        double maxy = Double.parseDouble(sy.getAttributes()[2].toString());
232
                        if (minx > maxx) {
233
                                double aux = minx;
234
                                minx = maxx;
235
                                maxx = aux;
236
                        }
237

    
238
                        if (miny > maxy) {
239
                                double aux = miny;
240
                                miny = maxy;
241
                                maxy = aux;
242
                        }
243

    
244
                        // dim 3
245
                        STRUCT sz = null;
246
                        double minz = 0;
247
                        double maxz = 0;
248
                        if (dim == 2) {
249
                                fullEnvelope = new Envelope2D(minx, miny, maxx, maxy);
250
                        } else if (dim == 3) {
251
                                sz = (STRUCT) da[2];
252
                                minz = Double.parseDouble(sz.getAttributes()[1].toString());
253
                                maxz = Double.parseDouble(sz.getAttributes()[2].toString());
254

    
255
                                Point minPto = new Point2DZ(minx, miny, minz);
256
                                Point maxPto = new Point2DZ(maxx, maxy, maxz);
257

    
258
                                fullEnvelope = new Envelope3D(minPto, maxPto);
259
                        }
260

    
261
                        return fullEnvelope;
262

    
263
                } catch (Exception e) {
264
                        return null;
265
                }
266

    
267
                finally {
268
                        try {
269
                                rs.close();
270
                        } catch (Exception e) {
271
                        }
272

    
273
                        try {
274
                                st.close();
275
                        } catch (Exception e) {
276
                        }
277

    
278
                        /*
279
                        try {
280
                                conn.close();
281
                        } catch (Exception e) {
282
                        }
283
                        */
284

    
285
                        finally {
286
                                rs = null;
287
                                st = null;
288
                                conn = null;
289
                        }
290
                }
291
        }
292

    
293
        /**
294
         * 
295
         */
296
//        protected void initializeFromWKBOperation() throws BaseException {
297
//                // TODO
298
//                if (fromWKB == null) {
299
//                        fromWKB = (FromWKB) GeometryLocator.getGeometryManager()
300
//                                        .getGeometryOperation(FromWKB.CODE,
301
//                                                        Geometry.TYPES.GEOMETRY, Geometry.SUBTYPES.GEOM2D);
302
//                        fromWKBContext = new FromWKBGeometryOperationContext();
303
//                }
304
//        }
305

    
306
        /**
307
         * 
308
         */
309
        public Geometry getGeometry(byte[] buffer) throws BaseException {
310
                // TODO BLOB format in Oracle?
311
                logger.error("Unsupported: binary Geometry format");
312
                return null;
313
        }
314

    
315
        /**
316
         * get geometry column name "SDO_GEOMETRY"
317
         * 
318
         * @param attr
319
         * @return
320
         */
321
        public String getSqlColumnTypeDescription(FeatureAttributeDescriptor attr) {
322

    
323
                switch (attr.getDataType().getType()) {
324

    
325
                case DataTypes.GEOMETRY:
326
                        return "\"MDSYS\".\"SDO_GEOMETRY\"";
327

    
328
                case DataTypes.STRING:
329
                        return "NVARCHAR2(" + attr.getSize() + ")";
330

    
331
                case DataTypes.BOOLEAN:
332
                        return "NUMBER(1, 0)";
333

    
334
                case DataTypes.BYTE:
335
                        return "NUMBER";
336

    
337
                case DataTypes.DATE:
338
                        return "DATE";
339

    
340
                case DataTypes.TIMESTAMP:
341
                        return "TIMESTAMP";
342

    
343
                case DataTypes.TIME:
344
                        return "TIMESTAMP";
345

    
346
                case DataTypes.BYTEARRAY:
347

    
348
                case DataTypes.DOUBLE:
349
                        return "FLOAT";
350

    
351
                case DataTypes.FLOAT:
352
                        return "FLOAT";
353

    
354
                case DataTypes.INT:
355
                        return "NUMBER(12, 0)";
356

    
357
                case DataTypes.LONG:
358
                        return "NUMBER(38, 0)";
359

    
360
                default:
361
                        String typeName = (String) attr.getAdditionalInfo("SQLTypeName");
362
                        if (typeName != null) {
363
                                return typeName;
364
                        }
365
                        throw new UnsupportedDataTypeException(attr.getDataTypeName(), attr
366
                                        .getDataType().getType());
367
                }
368

    
369
        }
370

    
371
        /**
372
         * Get oracle geometry dimension
373
         * 
374
         * @param geometrySubType
375
         * @return
376
         */
377
        public int getOraGeomDimensions(int geometrySubType) {
378

    
379
                switch (geometrySubType) {
380
                case Geometry.SUBTYPES.GEOM2D:
381
                        return 2;
382
                case Geometry.SUBTYPES.GEOM2DM:
383
                case Geometry.SUBTYPES.GEOM3D:
384
                        return 3;
385
                case Geometry.SUBTYPES.GEOM3DM:
386
                        return 4;
387
                default:
388
                        throw new UnsupportedDataTypeException(
389
                                        "GEOMETRY field",
390
                                        DataTypes.GEOMETRY);
391
                }
392
        }
393

    
394
        /**
395
         * Get Oracle geometry type
396
         * 
397
         * @param geometryType
398
         * @param geometrySubType
399
         * @return
400
         */
401
        public String getOraGeomType(int geometryType, int geometrySubType) {
402
                String oraGeomType;
403
                switch (geometryType) {
404
                case Geometry.TYPES.GEOMETRY:
405
                        oraGeomType = OracleValues.OraGeometry_GTYPE_GEOMETRY;
406
                        break;
407
                case Geometry.TYPES.POINT:
408
                        oraGeomType = OracleValues.OraGeometry_GTYPE_POINT;
409
                        break;
410
                case Geometry.TYPES.CURVE:
411
                        oraGeomType = OracleValues.OraGeometry_GTYPE_CURVE;
412
                        break;
413
                /*
414
                case Geometry.TYPES..TEXT:
415
                        oraGeomType = OracleValues.OraGeometry_GTYPE_GEOMETRY;
416
                        break;
417
                */
418
                case Geometry.TYPES.SOLID:
419
                        oraGeomType = OracleValues.OraGeometry_GTYPE_GEOMETRY;
420
                        break;
421
                case Geometry.TYPES.AGGREGATE:
422
                        oraGeomType = OracleValues.OraGeometry_GTYPE_GEOMETRY;
423
                        break;
424
                case Geometry.TYPES.SURFACE:
425
                        oraGeomType = OracleValues.OraGeometry_GTYPE_POLYGON;
426
                        break;
427
                case Geometry.TYPES.MULTIPOINT:
428
                        oraGeomType = OracleValues.OraGeometry_GTYPE_MULTIPOINT;
429
                        break;
430
                case Geometry.TYPES.MULTICURVE:
431
                        oraGeomType = OracleValues.OraGeometry_GTYPE_MULTICURVE;
432
                        break;
433
                case Geometry.TYPES.MULTISURFACE:
434
                        oraGeomType = OracleValues.OraGeometry_GTYPE_MULTIPOLYGON;
435
                        break;
436
                case Geometry.TYPES.MULTISOLID:
437
                        oraGeomType = OracleValues.OraGeometry_GTYPE_GEOMETRY;
438
                        break;
439
                case Geometry.TYPES.CIRCLE:
440
                        oraGeomType = OracleValues.OraGeometry_GTYPE_GEOMETRY;
441
                        break;
442
                case Geometry.TYPES.ARC:
443
                        oraGeomType = OracleValues.OraGeometry_GTYPE_GEOMETRY;
444
                        break;
445
                case Geometry.TYPES.ELLIPSE:
446
                        oraGeomType = OracleValues.OraGeometry_GTYPE_GEOMETRY;
447
                        break;
448
                case Geometry.TYPES.SPLINE:
449
                        oraGeomType = OracleValues.OraGeometry_GTYPE_GEOMETRY;
450
                        break;
451
                case Geometry.TYPES.ELLIPTICARC:
452
                        oraGeomType = OracleValues.OraGeometry_GTYPE_GEOMETRY;
453
                        break;
454
                default:
455
                        throw new UnsupportedGeometryException(geometryType,
456
                                        geometrySubType);
457
                }
458
                return oraGeomType;
459
        }
460

    
461
        /**
462
         * 
463
         */
464
        public String getSqlFieldName(FeatureAttributeDescriptor attribute) {
465
                /*
466
                if (attribute.getDataType() == DataTypes.GEOMETRY) {
467
                        return "asBinary(" + super.getSqlFieldName(attribute) + ")";
468
                }
469
                */
470
                return super.getSqlFieldName(attribute);
471
        }
472
        
473
        protected String getIdentifierQuoteString() {
474
                return IDENTIFIER_QUOTE_STRING;
475
        }
476

    
477
        /**
478
         * 
479
         */
480
        protected EditableFeatureAttributeDescriptor createAttributeFromJDBC(
481
                        EditableFeatureType fType, Connection conn,
482
                        ResultSetMetaData rsMetadata, int colIndex) throws SQLException {
483
                
484
                String rstypename = rsMetadata.getColumnTypeName(colIndex);
485
                if (rstypename
486
                                .equalsIgnoreCase(OracleValues.OraGeometry_GTYPE_GEOMETRY)) {
487

    
488
                        return fType.add(rsMetadata.getColumnName(colIndex),
489
                                        DataTypes.GEOMETRY);
490
                }
491

    
492
                EditableFeatureAttributeDescriptor column;
493
                switch (rsMetadata.getColumnType(colIndex)) {
494
                case java.sql.Types.INTEGER:
495
                        column = fType.add(rsMetadata.getColumnName(colIndex),
496
                                        DataTypes.INT);
497
                        break;
498
                case java.sql.Types.BIGINT:
499
                        column = fType.add(rsMetadata.getColumnName(colIndex),
500
                                        DataTypes.LONG);
501
                        break;
502
                case java.sql.Types.REAL:
503
                        column = fType.add(rsMetadata.getColumnName(colIndex),
504
                                        DataTypes.DOUBLE);
505
                        break;
506
                case java.sql.Types.DOUBLE:
507
                        column = fType.add(rsMetadata.getColumnName(colIndex),
508
                                        DataTypes.DOUBLE);
509
                        break;
510
                case java.sql.Types.CHAR:
511
                        column = fType.add(rsMetadata.getColumnName(colIndex),
512
                                        DataTypes.STRING);
513
                        break;
514
                case java.sql.Types.VARCHAR:
515
                case java.sql.Types.LONGVARCHAR:
516
                        column = fType.add(rsMetadata.getColumnName(colIndex),
517
                                        DataTypes.STRING);
518
                        break;
519
                case java.sql.Types.FLOAT:
520
                        column = fType.add(rsMetadata.getColumnName(colIndex),
521
                                        DataTypes.FLOAT);
522
                        break;
523
                case java.sql.Types.DECIMAL:
524
                        column = fType.add(rsMetadata.getColumnName(colIndex),
525
                                        DataTypes.FLOAT);
526
                        break;
527
                case java.sql.Types.DATE:
528
                        column = fType.add(rsMetadata.getColumnName(colIndex),
529
                                        DataTypes.DATE);
530
                        break;
531
                case java.sql.Types.TIME:
532
                        column = fType.add(rsMetadata.getColumnName(colIndex),
533
                                        DataTypes.TIME);
534
                        break;
535
                case java.sql.Types.TIMESTAMP:
536
                        column = fType.add(rsMetadata.getColumnName(colIndex),
537
                                        DataTypes.TIMESTAMP);
538
                        break;
539
                case java.sql.Types.BOOLEAN:
540
                        column = fType.add(rsMetadata.getColumnName(colIndex),
541
                                        DataTypes.BOOLEAN);
542
                        break;
543
                case java.sql.Types.BLOB:
544
                case java.sql.Types.BINARY:
545
                case java.sql.Types.LONGVARBINARY:
546
                        column = fType.add(rsMetadata.getColumnName(colIndex),
547
                                        DataTypes.BYTEARRAY);
548
                        break;
549

    
550
                case java.sql.Types.NUMERIC:
551
                        
552
                        // decimal positions to the right of point
553
                        int scale = rsMetadata.getScale(colIndex);
554
                        // decimal positions to the right of point
555
                        // int leftdigits = rsMetadata.getPrecision(colIndex);
556
                        
557
                        if (scale == 0) { 
558
                                column = fType.add(rsMetadata.getColumnName(colIndex),
559
                                                DataTypes.LONG);
560
                        } else {
561
                                column = fType.add(rsMetadata.getColumnName(colIndex),
562
                                                DataTypes.DOUBLE);
563
                        }
564
                        
565
                        break;
566

    
567
                default:
568
                        column = fType.add(rsMetadata.getColumnName(colIndex),
569
                                        DataTypes.OBJECT);
570
                        column.setAdditionalInfo("SQLType", new Integer(rsMetadata
571
                                        .getColumnType(colIndex)));
572
                        column.setAdditionalInfo("SQLTypeName", rsMetadata
573
                                        .getColumnTypeName(colIndex));
574

    
575
                        break;
576
                }
577

    
578
                return column;
579

    
580

    
581
                // return super.createAttributeFromJDBC(type, conn, rsMetadata, colIndex);
582
        }
583

    
584
        /**
585
         * 
586
         */
587
        public boolean allowAutomaticValues() {
588
                return Boolean.TRUE;
589
        }
590

    
591
        /**
592
         * 
593
         */
594
        public boolean supportOffset() {
595
                return true;
596
        }
597

    
598
        /**
599
         * 
600
         */
601
        public boolean supportsUnion() {
602
                return true;
603
        }
604

    
605
        /**
606
         * get sql with fields description
607
         * 
608
         * @param attr
609
         * @return
610
         */
611
        public String getSqlFieldDescription(FeatureAttributeDescriptor attr)
612
                        throws DataException {
613

    
614
                StringBuilder strb = new StringBuilder();
615
                // name
616
                strb.append("\"" + attr.getName() + "\" ");
617

    
618
                // Type
619
                strb.append(this.getSqlColumnTypeDescription(attr));
620

    
621
                // Primary key
622
                if (attr.isPrimaryKey()) {
623
                        strb.append(" PRIMARY KEY");
624
                }
625

    
626
                return strb.toString();
627
        }
628

    
629
        /**
630
         * UTility method to get the SQL sentence needed to update the geographic
631
         * metadata table with a new bounding box and SRS
632
         * 
633
         * @param tName
634
         *            table name
635
         * @param ora_srid
636
         *            new SRS
637
         * @param bbox
638
         *            new bounding box
639
         * @param dim
640
         *            geometries dimension
641
         * @param withsrid
642
         *            False if the SRS is set to NULL. True otherwise.
643
         * @return the SQL sentence to perform the update
644
         */
645
        public String getSqlUpdateMetadata(OracleStoreParameters params,
646
                        String ora_srid, Rectangle2D bbox, int dim, boolean withsrid) {
647

    
648
                String[] dim_name = new String[dim];
649
                // double tolerance = ORACLE_SPATIAL_DEFAULT_TOLERANCE;
650

    
651
                String _ora_srid = ora_srid;
652
                if (_ora_srid == null)
653
                        _ora_srid = "NULL";
654

    
655
                if (_ora_srid.compareTo(OracleValues.GEODETIC_SRID) == 0) {
656
                        dim_name[0] = "LONGITUDE";
657
                        dim_name[1] = "LATITUDE";
658
                } else {
659
                        dim_name[0] = "X";
660
                        dim_name[1] = "Y";
661

    
662
                        if (dim > 2) {
663
                                dim_name[2] = "Z";
664

    
665
                                if (dim > 3) {
666
                                        dim_name[3] = "T";
667
                                }
668
                        }
669
                }
670

    
671
                double minx = bbox.getMinX();
672
                double miny = bbox.getMinY();
673
                double maxx = bbox.getMaxX();
674
                double maxy = bbox.getMaxY();
675

    
676
                String resp = "INSERT INTO "
677
                                + OracleValues.USER_ORACLE_GEOMETADATA_VIEW + " "
678
                                + " ( TABLE_NAME, COLUMN_NAME, DIMINFO, SRID ) " + " VALUES ("
679
                                + "'" + params.getTable() + "', " + "'"
680
                                + OracleValues.DEFAULT_GEO_FIELD + "', "
681
                                + "MDSYS.SDO_DIM_ARRAY( " + "MDSYS.SDO_DIM_ELEMENT ('"
682
                                + dim_name[0] + "', " + minx + ", " + maxx + ", " + ORACLE_SPATIAL_DEFAULT_TOLERANCE
683
                                + " ), " + "MDSYS.SDO_DIM_ELEMENT ('" + dim_name[1] + "', "
684
                                + miny + ", " + maxy + ", " + ORACLE_SPATIAL_DEFAULT_TOLERANCE + " ))";
685

    
686
                if (dim > 2) {
687
                        resp = resp.substring(0, resp.length() - 1) + ",";
688
                        resp = resp + "MDSYS.SDO_DIM_ELEMENT ('" + dim_name[2]
689
                                        + "', 0.0, 100.0, " + ORACLE_SPATIAL_DEFAULT_TOLERANCE + " ))";
690

    
691
                        if (dim > 3) {
692
                                resp = resp.substring(0, resp.length() - 1) + ",";
693
                                resp = resp + "MDSYS.SDO_DIM_ELEMENT ('" + dim_name[3]
694
                                                + "', 0.0, 100.0, " + ORACLE_SPATIAL_DEFAULT_TOLERANCE + " ))";
695
                        }
696
                }
697

    
698
                if (withsrid) {
699
                        resp = resp + ", " + _ora_srid + " )";
700
                } else {
701
                        resp = resp + ", NULL )";
702
                }
703

    
704
                return resp;
705
        }
706

    
707

    
708
        
709
        
710
        /**
711
         * 
712
         */
713
        public void loadFeatureType(EditableFeatureType featureType,
714
                        JDBCStoreParameters storeParams) throws DataException {
715
                
716
                if ((storeParams.getDefaultGeometryField() == null) && (storeParams instanceof OracleNewStoreParameters)) {
717
                        OracleNewStoreParameters osp = (OracleNewStoreParameters) storeParams;
718
                        String geoname = osp.getDefaultFeatureType().getDefaultGeometryAttributeName();
719
                        storeParams.setDefaultGeometryField(geoname);
720
                }
721

    
722
                String sqlstr = storeParams.getSQL();
723
                
724
                if (sqlstr != null && sqlstr.trim().length() > 0) {
725
                        // loadFeatureType(featureType, storeParams, sqlstr);
726
                } else {
727
                        sqlstr = "SELECT * FROM " + storeParams.tableID() + " WHERE ROWID = NULL";
728
                        storeParams.setSQL(sqlstr);
729
                }
730
                
731
                loadFeatureType(featureType, storeParams, sqlstr, storeParams
732
                                .getSchema(), storeParams.getTable());
733
                
734
                storeParams.setSQL(null);
735
                // super.loadFeatureType(featureType, storeParams);
736
        }
737

    
738
        /**
739
         * Fill <code>featureType</code> geometry attributes with ShapeType
740
         * information stored in the table USER_SDO_GEOMETRY_METADATA
741
         * 
742
         * @param conn
743
         * @param rsMetadata
744
         * @param featureType
745
         * @throws ReadException
746
         */
747
        protected void loadSRS_and_shapeType(Connection conn,
748
                        ResultSetMetaData rs_Metadata, EditableFeatureType featureType,
749
                        String baseSchema, String baseTable) throws JDBCException {
750

    
751
                Statement st = null;
752
                ResultSet rs = null;
753
                String reserved_geocolname = null;
754
                
755
                try {
756
                        // Sacamos la lista de los attributos geometricos
757

    
758
                        EditableFeatureAttributeDescriptor attr;
759
                        ArrayList geoAttrs = new ArrayList();
760

    
761
                        Iterator iter = featureType.iterator();
762
                        while (iter.hasNext()) {
763
                                attr = (EditableFeatureAttributeDescriptor) iter.next();
764
                                if (attr.getDataType().getType() == DataTypes.GEOMETRY) {
765
                                        geoAttrs.add(attr);
766
                                }
767
                        }
768
                        if (geoAttrs.size() < 1) {
769
                                return;
770
                        }
771

    
772
                        // Preparamos una sql para que nos saque el resultado
773
                        StringBuilder strb = new StringBuilder();
774
                        strb.append("SELECT * FROM "
775
                                        + OracleValues.USER_ORACLE_GEOMETADATA_VIEW + " WHERE "
776
                                        + OracleValues.USER_ORACLE_GEOMETADATA_VIEW_TABLE_NAME
777
                                        + " = '" + baseTable + "'");
778
                        String sql = strb.toString();
779

    
780
                        st = conn.createStatement();
781
                        try {
782
                                rs = st.executeQuery(sql);
783
                        } catch (SQLException e) {
784
                                throw new JDBCExecuteSQLException(sql, e);
785
                        }
786
                        
787
                        String srID;
788

    
789
                        EditableFeatureAttributeDescriptor auxdesc;
790
                        
791

    
792
                                while (rs.next()) {
793
                                        String rsName =
794
                                                rs.getString(OracleValues.USER_ORACLE_GEOMETADATA_VIEW_COLUMN_NAME);
795
                                        reserved_geocolname = rsName;
796
                                        auxdesc = getAttrDescForCol(geoAttrs, rsName);
797
                                        if (auxdesc != null) {
798
                                                Object sridobj = rs.getObject("SRID");
799
                                                if (sridobj == null) {
800
                                                        if (getViewProjection() != null) {
801
                                                                // ora table has no srid, use SRS of the view
802
                                                                auxdesc.setSRS(getViewProjection());
803
                                                        }
804
                                                } else {
805
                                                        srID = sridobj.toString();
806
                                                        int epsg = OracleUtils.oracleSridToEpsg(srID);
807
                                                        String sepsg = "EPSG:" + Integer.toString(epsg);
808
                                                        auxdesc.setSRS(CRSFactory.getCRS(sepsg));
809
                                                }
810
                                        }
811
                                        if (featureType.getDefaultGeometryAttribute() == null) {
812
                                                ((DefaultEditableFeatureType) featureType).setDefaultGeometryAttributeName(reserved_geocolname);
813
                                        }
814
                                        
815
                        }
816
                } catch (java.sql.SQLException e) {
817
                        throw new JDBCSQLException(e);
818
                } finally {
819
                        try { rs.close(); } catch (Exception e) { };
820
                        try { st.close(); } catch (Exception e) { };
821
                }
822
                
823
                // guess shape type
824
                String geoColName = featureType.getDefaultGeometryAttributeName();
825
                if (geoColName == null) {
826
                        geoColName = reserved_geocolname; 
827
                }
828
                
829
                try {
830
                        String str_geo = "SELECT " + geoColName + " FROM " + baseTable +
831
                        " WHERE (" + geoColName + " IS NOT NULL) AND " + OracleUtils.EXPONENTIAL_INDICES_CONDITION; 
832

    
833
                        st = conn.createStatement();
834
                        try {
835
                                rs = st.executeQuery(str_geo);
836
                        } catch (SQLException e) {
837
                                throw new JDBCExecuteSQLException(str_geo, e);
838
                        }
839
                        
840
            int aux = 0;
841
            int guess_type = TYPES.GEOMETRY;
842
            int guess_subtype = SUBTYPES.GEOM2D;
843
            
844
            STRUCT sample_geo;
845
            ArrayList shptypes = new ArrayList();
846
            int[] ty_subty;
847
            while (rs.next()) {
848
                sample_geo = (STRUCT) rs.getObject(1);
849
                ty_subty = OracleUtils.getGeoTypeSubTypeOfStruct(sample_geo); 
850
                aux = ty_subty[0];
851
                guess_subtype = ty_subty[1];
852
                shptypes.add(new Integer(aux));
853
            }
854

    
855
            if (shptypes.size() > 0) {
856
                    guess_type = OracleUtils.getShapeTypeFromArray(shptypes);
857
            } else {
858
                    logger.warn("Did not find geometries to sample. Assumed TYPE = GEOMETRY, SUBTYPE = 2D");
859
            }
860

    
861
            DefaultEditableFeatureAttributeDescriptor dfad = null;
862
            try {
863
                dfad = (DefaultEditableFeatureAttributeDescriptor) featureType.getDefaultGeometryAttribute();
864
                dfad.setGeometryType(guess_type);
865
                dfad.setGeometrySubType(guess_subtype);
866
            } catch (ClassCastException cce) {
867
                    logger.error("Unexpected non editable feature type. Did not set geo types.");
868
            }
869
                } catch (java.sql.SQLException e) {
870
                        throw new JDBCSQLException(e);
871
                } finally {
872
                        try {rs.close();} catch (Exception e) {        };
873
                        try {st.close();} catch (Exception e) { };
874
                }
875
        }
876

    
877
        private EditableFeatureAttributeDescriptor getAttrDescForCol(ArrayList list, String name) {
878
                
879
                int sz = list.size();
880
                for (int i=0; i<sz; i++) {
881
                        EditableFeatureAttributeDescriptor aux = (EditableFeatureAttributeDescriptor) list.get(i);
882
                        if (aux.getName().compareToIgnoreCase(name) == 0) {
883
                                return aux;
884
                        }
885
                }
886
                // not found
887
                return null;
888
        }
889

    
890
        /**
891
         * Add oracle geometry field and add spatial index
892
         * 
893
         * @param attr
894
         * @param table
895
         * @param schema
896
         * @return
897
         */
898
        public List<String> getSqlGeometryFieldAdd(FeatureAttributeDescriptor attr,
899
                        String table, String schema) {
900

    
901
                List<String> sqls = new ArrayList<String>();
902

    
903
                StringBuilder strb1 = new StringBuilder();
904
                strb1.append("Alter table ");
905
                if (schema != null && schema.length() > 0) {
906
                        strb1.append(schema);
907
                        strb1.append(".");
908
                }
909
                strb1.append(table);
910
                strb1.append(" add (");
911
                strb1.append(attr.getName());
912
                strb1.append(" SDO_GEOMETRY)");
913

    
914
                sqls.add(strb1.toString());
915

    
916
                String sqlindex = "CREATE INDEX "
917
                                + OracleUtils.getDerivedName(table, "SX") + " ON " + table
918
                                + " (\"" + attr.getName()
919
                                + "\") INDEXTYPE IS \"MDSYS\".\"SPATIAL_INDEX\" ";
920

    
921
                sqls.add(sqlindex);
922

    
923
                return sqls;
924
        }
925
        
926
        
927
        /**
928
         * Executes an atomic action that uses an DB Connection.<br>
929
         *
930
         * This methos prepares a connection and close it at the end of execution of
931
         * action.<br>
932
         *
933
         * if <code>action</code> is an instance of {@link TransactionalAction} the
934
         * action will be execute inside of a DB transaction.
935
         *
936
         *
937
         * @param action
938
         * @throws Exception
939
         */
940
        public Object doConnectionAction(final ConnectionAction action)
941
                        throws Exception {
942
                this.open();
943
//                this.begin();
944
                return getResource().execute(new ResourceAction() {
945
                        public Object run() throws Exception {
946
                                Object result = null;
947
                                Connection conn = null;
948
                                boolean beginTrans = false;
949
                                try {
950
                                        conn = getConnection();
951
                                        if (action instanceof TransactionalAction) {
952
                                                /*
953
                                                // XXX OJO esta condicion NO ES FIABLE
954
                                                if (!conn.getAutoCommit()) {
955
                                                        if (!((TransactionalAction) action)
956
                                                                        .continueTransactionAllowed()) {
957
                                                                // FIXME exception
958
                                                                throw new Exception();
959
                                                        }
960
                                                }
961
                                                */
962
                                                try {
963
                                                        conn.setAutoCommit(false);
964
                                                } catch (SQLException e) {
965
                                                        logger.warn("Unable to set auto commit = false when starting update in Oracle layer.");
966
                                                        // throw new JDBCSQLException(e);
967
                                                }
968
                                                beginTrans = true;
969
                                        }
970

    
971
                                        result = action.action(conn);
972

    
973
                                        if (beginTrans) {
974
                                                try {
975
                                                        conn.commit();
976
                                                } catch (SQLException e) {
977
                                                        throw new JDBCTransactionCommitException(e);
978
                                                }
979
                                        }
980

    
981
                                        return result;
982

    
983
                                } catch (Exception e) {
984

    
985
                                        if (beginTrans) {
986
                                                try {
987
                                                        conn.rollback();
988
                                                } catch (Exception e1) {
989
                                                        throw new JDBCTransactionRollbackException(e1, e);
990
                                                }
991
                                        }
992
                                        throw e;
993

    
994
                                /*
995
                                } finally {
996
                                        try {
997
                                                conn.close();
998
                                        } catch (Exception e1) {
999
                                                logger.error("Exception on close connection", e1);
1000
                                        }
1001
                                */
1002
                                }
1003
                        }
1004
                });
1005
        }
1006
        
1007
        public void loadFeatureType(final EditableFeatureType featureType,
1008
                        final JDBCStoreParameters storeParams, final String sql,
1009
                        final String schema, final String table) throws DataException {
1010
                this.open();
1011
                
1012
                if (storeParams.getCRS() != null) {
1013
                        this.setViewProjection(storeParams.getCRS());
1014
                }
1015
//                this.begin();
1016
                getResource().execute(new ResourceAction() {
1017
                        public Object run() throws Exception {
1018
                                Connection conn = null;
1019
                                // try {
1020
                                        conn = getConnection();
1021
                                        
1022
                                        String[] pks = storeParams.getPkFields();
1023
                                        if (pks == null || pks.length < 1) {
1024
                                                if (storeParams.getTable() != null
1025
                                                                && storeParams.getTable().trim().length() > 0) {
1026
                                                        pks = getPksFrom(conn, storeParams);
1027
                                                        
1028
                                                }
1029
                                        }
1030
                                        
1031
                                        loadFeatureType(conn, featureType, sql, pks, storeParams
1032
                                                        .getDefaultGeometryField(), schema, table);
1033
                                        
1034
                                        featureType.setHasOID(true);
1035
                                        
1036
                                
1037
                                /*
1038
                                } finally {
1039
                                        try {
1040
                                                conn.close();
1041
                                        } catch (Exception e) {
1042
                                        }
1043
                                */
1044
                                // }
1045
                                return null;
1046
                        }
1047
                });
1048
        }
1049

    
1050
        public String getOraTableSrid(OracleStoreParameters params,
1051
                        String geo_field) {
1052
                
1053
                StringBuilder strb = new StringBuilder();
1054
                strb.append("SELECT SRID FROM "
1055
                                + OracleValues.ALL_ORACLE_GEOMETADATA_VIEW);
1056
                strb.append(" WHERE "
1057
                                + OracleValues.USER_ORACLE_GEOMETADATA_VIEW_TABLE_NAME
1058
                                + " = '" + params.getTable() + "'");
1059
                strb.append(" AND "
1060
                                + OracleValues.USER_ORACLE_GEOMETADATA_VIEW_COLUMN_NAME
1061
                                + " = '" + geo_field + "'");
1062
                strb.append(" AND "
1063
                                + OracleValues.USER_ORACLE_GEOMETADATA_VIEW_OWNER
1064
                                + " = '" + params.getSchema() + "'");
1065
                String sql = strb.toString();
1066

    
1067
                ResultSet rs = null;
1068
                Statement st = null;
1069
                Connection conn = null;
1070
                String srid_str = "";
1071

    
1072
                try {
1073
                        this.open();
1074
                        
1075
                        conn = getConnection();
1076
                        st = conn.createStatement();
1077
                        try {
1078
                                rs = st.executeQuery(sql);
1079
                        } catch (java.sql.SQLException e) {
1080
                                throw new JDBCExecuteSQLException(sql, e);
1081
                        }
1082
                        if (!rs.next()) {
1083
                                return null;
1084
                        }
1085

    
1086
                        Object srid_obj = rs.getObject(1);
1087
                        if (srid_obj == null) {
1088
                                srid_str = null;
1089
                        } else {
1090
                                if (srid_obj instanceof Integer) {
1091
                                        srid_str = ((Integer) srid_obj).toString();
1092
                                } else {
1093
                                        srid_str = srid_obj.toString();
1094
                                }
1095
                        }
1096

    
1097
                } catch (Exception e) {
1098
                        logger.error("While getting SRID from Oracle view: " + e.getMessage());
1099
                        return null;
1100
                } finally {
1101
                        try {
1102
                                rs.close();
1103
                        } catch (Exception e) {
1104
                        }
1105

    
1106
                        try {
1107
                                st.close();
1108
                        } catch (Exception e) {
1109
                        }
1110

    
1111
                        rs = null;
1112
                        st = null;
1113
                        conn = null;
1114
                }
1115
                
1116
                return srid_str;
1117
                
1118
                
1119
        }
1120
        
1121
        
1122
        public IProjection getViewProjection() {
1123
                return viewProjection;
1124
        }
1125

    
1126
        public void setViewProjection(IProjection p) {
1127
                this.viewProjection = p;
1128
        }
1129
        
1130
        
1131
//        protected void loadFeatureType(Connection conn,
1132
//                        EditableFeatureType featureType, String sql, String[] pks,
1133
//                        String defGeomName, String schema, String table)
1134
//                        throws DataException {
1135
//
1136
//                Statement stAux = null;
1137
//                ResultSet rs = null;
1138
//                try {
1139
//
1140
//                        stAux = conn.createStatement();
1141
//                        stAux.setFetchSize(1);
1142
//
1143
//                        try {
1144
//                                rs = stAux.executeQuery(sql);
1145
//                        } catch (SQLException e) {
1146
//                                throw new JDBCExecuteSQLException(sql, e);
1147
//                        }
1148
//                        ResultSetMetaData rsMetadata = rs.getMetaData();
1149
//
1150
//                        List pksList = null;
1151
//                        if (pks != null) {
1152
//                                pksList = Arrays.asList(pks);
1153
//                        }
1154
//
1155
//                        int i;
1156
//                        int geometriesColumns = 0;
1157
//                        String lastGeometry = null;
1158
//
1159
//                        EditableFeatureAttributeDescriptor attr;
1160
//                        for (i = 1; i <= rsMetadata.getColumnCount(); i++) {
1161
//                                attr = getAttributeFromJDBC(featureType, conn, rsMetadata, i);
1162
//                                if (pksList != null && pksList.contains(attr.getName())) {
1163
//                                        attr.setIsPrimaryKey(true);
1164
//                                }
1165
//                                if (attr.getDataType() == DataTypes.GEOMETRY) {
1166
//                                        geometriesColumns++;
1167
//                                        lastGeometry = attr.getName();
1168
//                                        if (lastGeometry.equals(defGeomName)) {
1169
//                                                featureType.setDefaultGeometryAttributeName(defGeomName);
1170
//                                        }
1171
//                                }
1172
//                        }
1173
//
1174
//                        if (geometriesColumns > 0) {
1175
//                                loadSRS_and_shapeType(conn, rsMetadata, featureType, schema,
1176
//                                                table);
1177
//                        }
1178
//
1179
//                        if (defGeomName == null && geometriesColumns == 1) {
1180
//                                featureType.setDefaultGeometryAttributeName(lastGeometry);
1181
//                                defGeomName = lastGeometry;
1182
//                        }
1183
//
1184
//                } catch (java.sql.SQLException e) {
1185
//                        throw new JDBCSQLException(e); // FIXME exception
1186
//                } finally {
1187
//                        try {
1188
//                                rs.close();
1189
//                        } catch (Exception e) {
1190
//                        }
1191
//                        try {
1192
//                                stAux.close();
1193
//                        } catch (Exception e) {
1194
//                        }
1195
//
1196
//                }
1197
//
1198
//        }
1199

    
1200

    
1201
}