Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / libraries / libFMap_daldb / src / org / gvsig / fmap / dal / store / postgresql / PostgreSQLHelper.java @ 40417

History | View | Annotate | Download (23.4 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 IVER T.I   {{Task}}
26
*/
27

    
28
/**
29
 *
30
 */
31
package org.gvsig.fmap.dal.store.postgresql;
32

    
33
import java.sql.Connection;
34
import java.sql.PreparedStatement;
35
import java.sql.ResultSet;
36
import java.sql.ResultSetMetaData;
37
import java.sql.SQLException;
38
import java.sql.Statement;
39
import java.util.ArrayList;
40
import java.util.Comparator;
41
import java.util.Iterator;
42
import java.util.List;
43
import java.util.Map;
44
import java.util.TreeMap;
45
import java.util.TreeSet;
46

    
47
import org.cresques.cts.IProjection;
48
import org.postgresql.PGResultSetMetaData;
49
import org.slf4j.Logger;
50
import org.slf4j.LoggerFactory;
51

    
52
import org.gvsig.fmap.crs.CRSFactory;
53
import org.gvsig.fmap.dal.DALLocator;
54
import org.gvsig.fmap.dal.DataTypes;
55
import org.gvsig.fmap.dal.NewDataStoreParameters;
56
import org.gvsig.fmap.dal.exception.DataException;
57
import org.gvsig.fmap.dal.exception.InitializeException;
58
import org.gvsig.fmap.dal.exception.ReadException;
59
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
60
import org.gvsig.fmap.dal.feature.EditableFeatureType;
61
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
62
import org.gvsig.fmap.dal.feature.FeatureType;
63
import org.gvsig.fmap.dal.feature.exception.UnsupportedDataTypeException;
64
import org.gvsig.fmap.dal.feature.exception.UnsupportedGeometryException;
65
import org.gvsig.fmap.dal.resource.ResourceAction;
66
import org.gvsig.fmap.dal.resource.spi.ResourceManagerProviderServices;
67
import org.gvsig.fmap.dal.store.jdbc.ConnectionAction;
68
import org.gvsig.fmap.dal.store.jdbc.JDBCHelper;
69
import org.gvsig.fmap.dal.store.jdbc.JDBCHelperUser;
70
import org.gvsig.fmap.dal.store.jdbc.JDBCStoreParameters;
71
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCException;
72
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCExecutePreparedSQLException;
73
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCExecuteSQLException;
74
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCPreparingSQLException;
75
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCSQLException;
76
import org.gvsig.fmap.geom.Geometry;
77
import org.gvsig.fmap.geom.GeometryLocator;
78
import org.gvsig.fmap.geom.GeometryManager;
79
import org.gvsig.fmap.geom.operation.fromwkb.FromWKB;
80
import org.gvsig.fmap.geom.operation.fromwkb.FromWKBGeometryOperationContext;
81
import org.gvsig.fmap.geom.primitive.Envelope;
82
import org.gvsig.tools.ToolsLocator;
83
import org.gvsig.tools.exception.BaseException;
84

    
85
/**
86
 * @author jmvivo
87
 *
88
 */
89
public class PostgreSQLHelper extends JDBCHelper {
90

    
91
        private static Logger logger = LoggerFactory
92
                        .getLogger(PostgreSQLHelper.class);
93

    
94
        private Map pgSR2SRSID = new TreeMap();
95
        private Map srsID2pgSR = new TreeMap();
96

    
97

    
98
        PostgreSQLHelper(JDBCHelperUser consumer,
99
                        PostgreSQLConnectionParameters params)
100
                        throws InitializeException {
101

    
102
                super(consumer, params);
103
        }
104

    
105
        protected void initializeResource() throws InitializeException {
106
                ResourceManagerProviderServices manager = (ResourceManagerProviderServices) DALLocator
107
                .getResourceManager();
108
                PostgreSQLResource resource = (PostgreSQLResource) manager
109
                .createAddResource(
110
                                PostgreSQLResource.NAME, new Object[] {
111
                                                params.getUrl(), params.getHost(),
112
                                                params.getPort(), params.getDBName(), params.getUser(),
113
                                                params.getPassword(),
114
                                                params.getJDBCDriverClassName(),
115
                                                ((PostgreSQLConnectionParameters) params).getUseSSL() });
116
                this.setResource(resource);
117
        }
118

    
119

    
120
        protected String getDefaultSchema(Connection conn)
121
                        throws JDBCException {
122
                if (defaultSchema == null) {
123
                        String sql = "Select current_schema()";
124
                        ResultSet rs = null;
125
                        Statement st = null;
126
                        String schema = null;
127
                        try {
128
                                st = conn.createStatement();
129
                                try {
130
                                        rs = st.executeQuery(sql);
131
                                } catch (java.sql.SQLException e) {
132
                                        throw new JDBCExecuteSQLException(sql, e);
133
                                }
134
                                rs.next();
135
                                schema = rs.getString(1);
136
                        } catch (java.sql.SQLException e) {
137
                                throw new JDBCSQLException(e);
138
                        } finally {
139
                                try {rs.close();} catch (Exception e) {logger.error("Exception clossing resulset", e);};
140
                                try {st.close();} catch (Exception e) {logger.error("Exception clossing statement", e);};
141
                                rs = null;
142
                                st = null;
143
                        }
144
                        defaultSchema = schema;
145
                }
146

    
147
                return defaultSchema;
148
        }
149

    
150
        public Envelope getFullEnvelopeOfField(
151
                        JDBCStoreParameters storeParams,
152
                        String geometryAttrName, Envelope limit)
153
                        throws DataException {
154

    
155
                StringBuilder strb = new StringBuilder();
156
                strb.append("Select ST_asBinary(ST_extent(");
157
                strb.append(escapeFieldName(geometryAttrName));
158
                strb.append(")) from ");
159

    
160
                if (storeParams.getSQL() != null
161
                                && storeParams.getSQL().trim().length() == 0) {
162
                        strb.append('(');
163
                        strb.append(storeParams.getSQL());
164
                        strb.append(") as __extentfield__ ");
165
                } else {
166
                        strb.append(storeParams.tableID());
167
                }
168

    
169

    
170
                if (limit != null){
171
                        strb.append(" where  ST_intersects(ST_GeometryFromText('");
172
                        strb.append(limit.toString());
173
                        strb.append("')), ST_envelope(");
174
                        strb.append(escapeFieldName(geometryAttrName));
175
                        strb.append(")) ");
176
                }
177

    
178
                final String sql = strb.toString();
179

    
180
                GeometryManager geoMan = GeometryLocator.getGeometryManager();
181

    
182
                this.open();
183

    
184
                return (Envelope) getResource().execute(new ResourceAction() {
185
                        public Object run() throws Exception {
186
                                ResultSet rs = null;
187
                                Statement st = null;
188
                                String schema = null;
189
                                Connection conn = null;
190
                                Envelope fullEnvelope = null;
191
                                try {
192

    
193
                                        conn = getConnection();
194
                                        st = conn.createStatement();
195
                                        try {
196
                                                rs = st.executeQuery(sql);
197
                                        } catch (java.sql.SQLException e) {
198
                                                throw new JDBCExecuteSQLException(sql, e);
199
                                        }
200
                                        if (!rs.next()) {
201
                                                return null;
202
                                        }
203

    
204
                                        byte[] data = rs.getBytes(1);
205
                                        if (data == null) {
206
                                                return null;
207
                                        }
208
                                        Geometry geom = GeometryLocator.getGeometryManager().createFrom(data);
209

    
210
                                        fullEnvelope = geom.getEnvelope();
211

    
212
                                        return fullEnvelope;
213
                                } catch (java.sql.SQLException e) {
214
                                        throw new JDBCSQLException(e);
215
                                } catch (BaseException e) {
216
                                        throw new ReadException(user.getProviderName(), e);
217
                                } finally {
218
                                        try {
219
                                                rs.close();
220
                                        } catch (Exception e) {
221
                                        }
222
                                        try {
223
                                                st.close();
224
                                        } catch (Exception e) {
225
                                        }
226
                                        try {
227
                                                conn.close();
228
                                        } catch (Exception e) {
229
                                        }
230
                                        rs = null;
231
                                        st = null;
232
                                        conn = null;
233
                                }
234
                        }
235
                });
236
        }
237
        
238
        public String getVersion() throws DataException {
239
                final String sql = "Select PostGIS_lib_version()";
240
                
241
                this.open();
242

    
243
                return (String) getResource().execute(new ResourceAction() {
244
                        public Object run() throws Exception {
245
                                ResultSet rs = null;
246
                                Statement st = null;
247
                                Connection conn = null;
248
                                try {
249
                                        conn = getConnection();
250
                                        st = conn.createStatement();
251
                                        try {
252
                                                rs = st.executeQuery(sql);
253
                                        } catch (java.sql.SQLException e) {
254
                                                throw new JDBCExecuteSQLException(sql, e);
255
                                        }
256
                                        if (!rs.next()) {
257
                                                return null;
258
                                        }
259

    
260
                                        String data = rs.getString(1);
261
                                        if (data == null) {
262
                                                return null;
263
                                        }
264
                                        return data;
265
                                } catch (java.sql.SQLException e) {
266
                                        throw new JDBCSQLException(e);
267
                                } catch (BaseException e) {
268
                                        throw new ReadException(user.getProviderName(), e);
269
                                } finally {
270
                                        try {
271
                                                rs.close();
272
                                        } catch (Exception e) {
273
                                        }
274
                                        try {
275
                                                st.close();
276
                                        } catch (Exception e) {
277
                                        }
278
                                        try {
279
                                                conn.close();
280
                                        } catch (Exception e) {
281
                                        }
282
                                        rs = null;
283
                                        st = null;
284
                                        conn = null;
285
                                }
286
                        }
287
                });
288
        }
289

    
290
        @Override
291
        protected boolean supportsGeometry() {
292
                return true;
293
        }
294

    
295
        /**
296
         * Fill <code>featureType</code> geometry attributes with SRS and ShapeType
297
         * information stored in the table GEOMETRY_COLUMNS
298
         *
299
         * @param conn
300
         * @param rsMetadata
301
         * @param featureType
302
         * @throws ReadException
303
         */
304
        protected void loadSRS_and_shapeType(Connection conn,
305
                        ResultSetMetaData rsMetadata, EditableFeatureType featureType,
306
                        String baseSchema, String baseTable)
307
                        throws JDBCException {
308

    
309
                Statement st = null;
310
                ResultSet rs = null;
311
                try {
312
                        // Sacamos la lista de los attributos geometricos
313
                        EditableFeatureAttributeDescriptor attr;
314
                        List geoAttrs = new ArrayList();
315

    
316
                        Iterator iter = featureType.iterator();
317
                        while (iter.hasNext()) {
318
                                attr = (EditableFeatureAttributeDescriptor) iter.next();
319
                                if (attr.getType() == DataTypes.GEOMETRY) {
320
                                        geoAttrs.add(attr);
321
                                }
322
                        }
323
                        if (geoAttrs.size() < 1) {
324
                                return;
325
                        }
326

    
327

    
328
                        // preparamos un set con las lista de tablas de origen
329
                        // de los campos
330
                        class TableId {
331
                                public String schema=null;
332
                                public String table=null;
333
                                public String field = null;
334

    
335
                                public void appendToSQL(StringBuilder strb) {
336
                                        if (schema == null || schema.length() == 0) {
337
                                                strb
338
                                                                .append("( F_TABLE_SCHEMA = current_schema() AND F_TABLE_NAME = '");
339
                                        } else {
340
                                                strb.append("( F_TABLE_SCHEMA = '");
341
                                                strb.append(schema);
342
                                                strb.append("' AND F_TABLE_NAME = '");
343
                                        }
344
                                        strb.append(table);
345
                                        strb.append("' AND F_GEOMETRY_COLUMN = '");
346
                                        strb.append(field);
347
                                        strb.append("' )");
348
                                }
349

    
350
                        }
351
                        Comparator cmp = new Comparator(){
352
                                public int compare(Object arg0, Object arg1) {
353
                                        TableId a0 = (TableId) arg0;
354
                                        TableId a1 = (TableId) arg1;
355

    
356
                                        int aux = a0.field.compareTo(a1.field);
357
                                        if (aux != 0) {
358
                                            return aux;
359
                                        }
360

    
361
                                        aux = a0.table.compareTo(a1.table);
362
                    if (aux != 0) {
363
                        return aux;
364
                    }
365
                                        
366
                    if (a0.schema == null) {
367
                        if (a1.schema == null) {
368
                            aux = 0;
369
                        } else {
370
                            aux = -1;
371
                        }
372
                    } else {
373
                        if (a1.schema == null) {
374
                            aux = -1;
375
                        } else {
376
                            aux = a0.schema.compareTo(a1.schema);
377
                        }
378
                    }
379
                                        return aux;
380
                                }
381
                        };
382
                        TreeSet set = new TreeSet(cmp);
383
                        TableId tableId;
384
                        iter = geoAttrs.iterator();
385
                        int rsIndex;
386
                        while (iter.hasNext()) {
387
                                attr = (EditableFeatureAttributeDescriptor) iter.next();
388
                                tableId = new TableId();
389
                                rsIndex = attr.getIndex() + 1;
390

    
391
                                if (baseSchema == null && baseTable == null) {
392
                                        if (rsMetadata instanceof PGResultSetMetaData) {
393
                                                tableId.schema = ((PGResultSetMetaData) rsMetadata)
394
                                                                .getBaseSchemaName(rsIndex);
395
                                                tableId.table = ((PGResultSetMetaData) rsMetadata)
396
                                                                .getBaseTableName(rsIndex);
397
                                                tableId.field = ((PGResultSetMetaData) rsMetadata)
398
                                                                .getBaseColumnName(rsIndex);
399

    
400
                                        } else {
401
                                                tableId.schema = rsMetadata.getSchemaName(rsIndex);
402
                                                tableId.table = rsMetadata.getTableName(rsIndex);
403
                                                tableId.field = rsMetadata.getColumnName(rsIndex);
404
                                        }
405
                                } else {
406
                                        tableId.schema = baseSchema;
407
                                        tableId.table = baseTable;
408
                                        tableId.field = rsMetadata.getColumnName(rsIndex);
409
                                }
410
                                if (tableId.table == null || tableId.table.length() == 0) {
411
                                        // Si no tiene tabla origen (viene de algun calculo por ej.)
412
                                        // lo saltamos ya que no estara en la tabla GEOMETRY_COLUMNS
413
                                        continue;
414
                                }
415
                                set.add(tableId);
416
                        }
417

    
418
                        if (set.size() == 0) {
419
                                return;
420
                        }
421

    
422
                        // Preparamos una sql para que nos saque el resultado
423
                        StringBuilder strb = new StringBuilder();
424
                        strb.append("Select geometry_columns.*,auth_name || ':' || auth_srid as SRSID ");
425
                        strb.append("from geometry_columns left join spatial_ref_sys on ");
426
                        strb.append("geometry_columns.srid = spatial_ref_sys.srid WHERE ");
427
                        iter = set.iterator();
428
                        for (int i=0;i<set.size()-1;i++) {
429
                                tableId = (TableId) iter.next();
430
                                tableId.appendToSQL(strb);
431
                                strb.append(" OR ");
432
                        }
433
                        tableId = (TableId) iter.next();
434
                        tableId.appendToSQL(strb);
435
                        String sql = strb.toString();
436

    
437

    
438
                        st = conn.createStatement();
439
                        try {
440
                                rs = st.executeQuery(sql);
441
                        } catch (SQLException e) {
442
                                throw new JDBCExecuteSQLException(sql, e);
443
                        }
444
                        String srsID;
445
                        int pgSrid;
446
                        int geometryType;
447
                        int geometrySubtype;
448
                        String geomTypeStr;
449
                        int dimensions;
450
                        IProjection srs;
451

    
452
                        while (rs.next()){
453
                                srsID = rs.getString("SRSID");
454
                                pgSrid = rs.getInt("SRID");
455
                                geomTypeStr = rs.getString("TYPE").toUpperCase();
456
                                geometryType = Geometry.TYPES.GEOMETRY;
457
                                if (geomTypeStr.startsWith("POINT")) {
458
                                        geometryType = Geometry.TYPES.POINT;
459
                                } else if (geomTypeStr.startsWith("LINESTRING")) {
460
                                        geometryType = Geometry.TYPES.CURVE;
461
                                } else if (geomTypeStr.startsWith("POLYGON")) {
462
                                        geometryType = Geometry.TYPES.SURFACE;
463
                                } else if (geomTypeStr.startsWith("MULTIPOINT")) {
464
                                        geometryType = Geometry.TYPES.MULTIPOINT;
465
                                } else if (geomTypeStr.startsWith("MULTILINESTRING")) {
466
                                        geometryType = Geometry.TYPES.MULTICURVE;
467
                                } else if (geomTypeStr.startsWith("MULTIPOLYGON")) {
468
                                        geometryType = Geometry.TYPES.MULTISURFACE;
469
                                }
470
                                dimensions = rs.getInt("coord_dimension");
471
                                geometrySubtype = Geometry.SUBTYPES.GEOM2D;
472
                                if (dimensions > 2) {
473
                                        if (dimensions == 3) {
474
                                                if (geomTypeStr.endsWith("M")) {
475
                                                        geometrySubtype = Geometry.SUBTYPES.GEOM2DM;
476
                                                } else {
477
                                                        geometrySubtype = Geometry.SUBTYPES.GEOM3D;
478
                                                }
479

    
480
                                        } else {
481
                                                //TODO:Support for M. Now GEOM3DM is converted to GEOM3D
482
                                                //geometrySubtype = Geometry.SUBTYPES.GEOM3DM;
483
                                                if (dimensions > 3)
484
                                                        geometrySubtype = Geometry.SUBTYPES.GEOM3D; 
485
                                        }
486
                                }
487
                                addToPgSRToSRSID(pgSrid, srsID);
488

    
489

    
490
                                iter = geoAttrs.iterator();
491
                                while (iter.hasNext()) {
492
                                        attr = (EditableFeatureAttributeDescriptor) iter.next();
493
                                        rsIndex = attr.getIndex() + 1;
494
                                        if (!rsMetadata.getColumnName(rsIndex).equals(
495
                                                        rs.getString("f_geometry_column"))) {
496
                                                continue;
497
                                        }
498

    
499
                                        if (baseSchema == null && baseTable == null) {
500

    
501
                                                if (rsMetadata instanceof PGResultSetMetaData) {
502
                                                        if (!((PGResultSetMetaData) rsMetadata)
503
                                                                        .getBaseTableName(rsIndex).equals(
504
                                                                                        rs.getString("f_table_name"))) {
505
                                                                continue;
506
                                                        }
507
                                                        String curSchema = rs.getString("f_table_schema");
508
                                                        String metaSchema = ((PGResultSetMetaData) rsMetadata)
509
                                                                        .getBaseSchemaName(rsIndex);
510
                                                        if (!metaSchema.equals(curSchema)) {
511
                                                                if (metaSchema.length() == 0
512
                                                                                && metaSchema == getDefaultSchema(conn)) {
513
                                                                } else {
514
                                                                        continue;
515
                                                                }
516
                                                        }
517

    
518
                                                } else {
519

    
520
                                                        if (!rsMetadata.getTableName(rsIndex).equals(
521
                                                                        rs.getString("f_table_name"))) {
522
                                                                continue;
523
                                                        }
524
                                                        String curSchema = rs.getString("f_table_schema");
525
                                                        String metaSchema = rsMetadata
526
                                                                        .getSchemaName(rsIndex);
527
                                                        if (!metaSchema.equals(curSchema)) {
528
                                                                if (metaSchema.length() == 0
529
                                                                                && metaSchema == getDefaultSchema(conn)) {
530
                                                                } else {
531
                                                                        continue;
532
                                                                }
533
                                                        }
534
                                                }
535
                                        }
536
                                        attr.setGeometryType(geometryType);
537
                                        attr.setGeometrySubType(geometrySubtype);
538
                                        if (srsID != null && srsID.length() > 0) {
539
                                                attr.setSRS(CRSFactory.getCRS(srsID));
540
                                        }
541
                                        iter.remove();
542
                                }
543
                                iter = geoAttrs.iterator();
544
                                while (iter.hasNext()) {
545
                                        attr = (EditableFeatureAttributeDescriptor) iter.next();
546
                                        attr.setSRS(null);
547
                                        attr.setGeometryType(Geometry.TYPES.GEOMETRY);
548

    
549
                                }
550
                        }
551

    
552
                } catch (java.sql.SQLException e) {
553
                        throw new JDBCSQLException(e);
554
                } finally {
555
                        try {rs.close();} catch (Exception e) {        };
556
                        try {st.close();} catch (Exception e) {        };
557
                }
558

    
559
        }
560

    
561

    
562
        public String getSqlColumnTypeDescription(FeatureAttributeDescriptor attr) {
563
                if (attr.getType() == DataTypes.GEOMETRY) {
564
                        return "geometry";
565
                }
566
                return super.getSqlColumnTypeDescription(attr);
567
        }
568

    
569

    
570
        public int getPostgisGeomDimensions(int geometrySubType) {
571
                switch (geometrySubType) {
572
                case Geometry.SUBTYPES.GEOM2D:
573
                        return 2;
574
                case Geometry.SUBTYPES.GEOM2DM:
575
                case Geometry.SUBTYPES.GEOM3D:
576
                        return 3;
577

    
578
                case Geometry.SUBTYPES.GEOM3DM:
579
                        return 4;
580
                default:
581
                        throw new UnsupportedDataTypeException(
582
                                        ToolsLocator.getDataTypesManager().getTypeName(DataTypes.GEOMETRY),
583
                                        DataTypes.GEOMETRY);
584
                }
585
        }
586

    
587
        public String getPostgisGeomType(int geometryType, int geometrySubType) {
588
                String pgGeomType;
589
                switch (geometryType) {
590
                case Geometry.TYPES.GEOMETRY:
591
                        pgGeomType = "GEOMETRY";
592
                        break;
593
                case Geometry.TYPES.POINT:
594
                        pgGeomType = "POINT";
595
                        break;
596
                case Geometry.TYPES.CURVE:
597
                        pgGeomType = "LINESTRING";
598
                        break;
599
                case Geometry.TYPES.SURFACE:
600
                        pgGeomType = "POLYGON";
601
                        break;
602
                case Geometry.TYPES.MULTIPOINT:
603
                        pgGeomType = "MULTIPOINT";
604
                        break;
605
                case Geometry.TYPES.MULTICURVE:
606
                        pgGeomType = "MULTILINESTRING";
607
                        break;
608
                case Geometry.TYPES.MULTISURFACE:
609
                        pgGeomType = "MULTIPOLYGON";
610
                        break;
611
                default:
612
                        throw new UnsupportedGeometryException(geometryType,
613
                                        geometrySubType);
614
                }
615
                if (geometrySubType == Geometry.SUBTYPES.GEOM2DM
616
                                || geometrySubType == Geometry.SUBTYPES.GEOM3DM) {
617
                        pgGeomType = pgGeomType + "M";
618
                } else if (geometrySubType == Geometry.SUBTYPES.GEOM3D) {
619
                        throw new UnsupportedGeometryException(geometryType,
620
                                        geometrySubType);
621
                }
622
                return pgGeomType;
623
        }
624

    
625
        public int getProviderSRID(String srs) {
626
                if (srs != null) {
627
                        Integer pgSRID = (Integer) srsID2pgSR.get(srs);
628
                        if (pgSRID != null) {
629
                                return pgSRID.intValue();
630
                        }
631

    
632
                        return searchpgSRID(srs);
633

    
634
                }
635
                return -1;
636
        }
637

    
638

    
639
        public int getProviderSRID(IProjection srs) {
640
                if (srs != null) {
641
                        Integer pgSRID = (Integer) srsID2pgSR.get(srs.getAbrev());
642
                        if (pgSRID != null) {
643
                                return pgSRID.intValue();
644
                        }
645

    
646
                        return searchpgSRID(srs);
647

    
648
                }
649
                return -1;
650
        }
651

    
652
        private int searchpgSRID(final IProjection srs) {
653
                if (srs == null) {
654
                        return -1;
655
                }
656
                return searchpgSRID(srs.getAbrev());
657
        }
658

    
659
        private int searchpgSRID(final String srsID) {
660
                if (srsID == null) {
661
                        return -1;
662
                }
663

    
664
                ConnectionAction action = new ConnectionAction(){
665

    
666
                        public Object action(Connection conn) throws DataException {
667

    
668
                                String[] abrev = srsID.split(":");
669
                                StringBuilder sqlb = new StringBuilder();
670
                                sqlb.append("select srid from spatial_ref_sys where ");
671
                                if (abrev.length > 1) {
672
                                        sqlb.append("auth_name = ? and ");
673
                                }
674
                                sqlb.append("auth_srid = ?");
675

    
676
                                String sql = sqlb.toString();
677
                                PreparedStatement st;
678
                                try {
679
                                        st = conn.prepareStatement(sql);
680
                                } catch (SQLException e){
681
                                        throw new JDBCPreparingSQLException(sql,e);
682
                                }
683
                                ResultSet rs = null;
684
                                try{
685
                                        int i=0;
686
                                        if (abrev.length > 1){
687
                                                st.setString(i+1, abrev[i]);
688
                                                i++;
689
                                        }
690
                                        st.setInt(i + 1, Integer.parseInt(abrev[i]));
691

    
692
                                        try{
693
                                                rs = st.executeQuery();
694
                                        } catch (SQLException e){
695
                                                throw new JDBCExecutePreparedSQLException(sql, abrev, e);
696
                                        }
697

    
698
                                        if (!rs.next()) {
699
                                                return null;
700
                                        }
701

    
702
                                        return new Integer(rs.getInt(1));
703

    
704
                                } catch (SQLException e){
705
                                        throw new JDBCSQLException(e);
706
                                } finally{
707
                                        try {rs.close(); } catch (Exception e) {};
708
                                        try {st.close(); } catch (Exception e) {};
709
                                }
710

    
711
                        }
712

    
713
                };
714

    
715
                Integer pgSRSID = null;
716
                try {
717
                        pgSRSID = (Integer) doConnectionAction(action);
718
                } catch (Exception e) {
719
                        logger.error("Excetion searching pgSRS", e);
720
                        return -1;
721
                }
722

    
723
                if (pgSRSID != null) {
724
                        addToPgSRToSRSID(pgSRSID.intValue(), srsID);
725
                        return pgSRSID.intValue();
726
                }
727
                return -1;
728

    
729
        }
730

    
731
        private void addToPgSRToSRSID(int pgSRID, String srsId) {
732
                if (pgSRID < 0 || srsId == null || srsId.length() == 0) {
733
                        return;
734
                }
735
                Integer pgSRIDInteger = new Integer(pgSRID);
736
                pgSR2SRSID.put(pgSRIDInteger, srsId);
737
                srsID2pgSR.put(srsId, pgSRIDInteger);
738
        }
739

    
740
        public List<String> getSqlGeometyFieldAdd(FeatureAttributeDescriptor attr,
741
                        String table, String schema) {
742
                // SELECT AddGeometryColumn({schema}, {table}, {field}, {srid}(int),
743
                // {geomType}(Str), {dimensions}(int))
744

    
745
                // gemoType:
746
                /*
747
                 * POINT, LINESTRING, POLYGON, MULTIPOINT, MULTILINESTRING,
748
                 * MULTIPOLYGON, GEOMETRYCOLLECTION POINTM, LINESTRINGM, POLYGONM,
749
                 * MULTIPOINTM, MULTILINESTRINGM, MULTIPOLYGONM, GEOMETRYCOLLECTIONM
750
                 */
751

    
752
                List<String> sqls = new ArrayList<String>();
753

    
754
                StringBuilder strb = new StringBuilder();
755
                strb.append("SELECT AddGeometryColumn('");
756
                if (schema != null && schema.length() > 0) {
757
                        strb.append(schema);
758
                        strb.append("', '");
759
                }
760
                strb.append(table);
761
                strb.append("', '");
762
                strb.append(attr.getName().toLowerCase());
763
                strb.append("', ");
764
                // strb.append("-1");
765
                strb.append(getProviderSRID(attr.getSRS()));
766
                strb.append(", '");
767
                
768
                // ===========================================================================
769
            // TODO Improve this. Keep in mind that MULTIPOLYGON will not accept POLYGON
770
        strb.append("GEOMETRY");
771
                /*
772
                strb.append(getPostgisGeomType(attr.getGeometryType(), attr
773
                                .getGeometrySubType()));
774
                                */
775
        // ===========================================================================
776
                strb.append("', ");
777
                strb.append(getPostgisGeomDimensions(attr.getGeometrySubType()));
778
                strb.append(")");
779

    
780

    
781
                sqls.add(strb.toString());
782

    
783
                /*ALTER TABLE muni10000_peq_test DROP CONSTRAINT enforce_srid_the_geom;*/
784
                /*
785
                strb = new StringBuilder();
786
                strb.append("Alter table ");
787
                if (schema != null && schema.length() > 0) {
788
                        strb.append(schema);
789
                        strb.append(".");
790
                }
791
                strb.append("f_table_name = '");
792
                strb.append(table);
793
                strb.append("' AND f_geometry_column = '");
794
                strb.append(attr.getName());
795
                strb.append("' AND srid = -1");
796

797

798
                sqls.add(strb.toString());
799
                */
800
                return sqls;
801
        }
802

    
803
        public String getSqlFieldName(FeatureAttributeDescriptor attribute) {
804
                if (attribute.getType() == DataTypes.GEOMETRY) {
805
                        return "ST_AsEWKB(\"" + super.getSqlFieldName(attribute) + "\", 'XDR')";
806
                }
807
                return super.getSqlFieldName(attribute);
808
        }
809

    
810
        protected EditableFeatureAttributeDescriptor createAttributeFromJDBC(
811
                        EditableFeatureType type, Connection conn,
812
                        ResultSetMetaData rsMetadata, int colIndex) throws SQLException {
813
                if (rsMetadata.getColumnType(colIndex) == java.sql.Types.OTHER) {
814
                        if (rsMetadata.getColumnTypeName(colIndex).equalsIgnoreCase(
815
                                        "geometry")) {
816
                                return type.add(rsMetadata.getColumnName(colIndex),
817
                                                DataTypes.GEOMETRY);
818

    
819
                        }
820
                }
821

    
822
                return super.createAttributeFromJDBC(type, conn, rsMetadata, colIndex);
823
        }
824

    
825
        public List getAdditionalSqlToCreate(NewDataStoreParameters ndsp,
826
                        FeatureType fType) {
827
                FeatureAttributeDescriptor attr;
828
                Iterator iter = fType.iterator();
829
                List result = new ArrayList();
830
                PostgreSQLNewStoreParameters pgNdsp = (PostgreSQLNewStoreParameters) ndsp;
831
                while (iter.hasNext()){
832
                        attr = (FeatureAttributeDescriptor) iter.next();
833
                        if (attr.getType() == DataTypes.GEOMETRY){
834
                                result.addAll(getSqlGeometyFieldAdd(attr, pgNdsp.getTable(),
835
                                                pgNdsp
836
                                                .getSchema()));
837
                        }
838
                }
839

    
840
                return result;
841
        }
842

    
843
        public String getSqlFieldDescription(FeatureAttributeDescriptor attr)
844
                        throws DataException {
845
                if (attr.getType() == DataTypes.GEOMETRY){
846
                        return null;
847
                }
848
                return super.getSqlFieldDescription(attr);
849
        }
850

    
851
        public boolean allowAutomaticValues() {
852
                return Boolean.TRUE;
853
        }
854

    
855
        public boolean supportOffset() {
856
                return true;
857
        }
858

    
859
        public boolean supportsUnion() {
860
                return true;
861
        }
862

    
863
}