Statistics
| Revision:

root / trunk / org.gvsig.postgresql / org.gvsig.postgresql.provider / src / main / java / org / gvsig / fmap / dal / store / postgresql / PostgreSQLHelper.java @ 23

History | View | Annotate | Download (23.3 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
*
3
* Copyright (C) 2007-2008 Infrastructures and Transports Department
4
* of the Valencian Government (CIT)
5
*
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* as published by the Free Software Foundation; either version 2
9
* of the License, or (at your option) any later version.
10
*
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
* GNU General Public License for more details.
15
*
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
* MA  02110-1301, USA.
20
*
21
*/
22

    
23
/*
24
* AUTHORS (In addition to CIT):
25
* 2009 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.CreateGeometryException;
64
import org.gvsig.fmap.dal.feature.exception.UnsupportedDataTypeException;
65
import org.gvsig.fmap.dal.feature.exception.UnsupportedGeometryException;
66
import org.gvsig.fmap.dal.resource.ResourceAction;
67
import org.gvsig.fmap.dal.resource.spi.ResourceManagerProviderServices;
68
import org.gvsig.fmap.dal.store.jdbc.ConnectionAction;
69
import org.gvsig.fmap.dal.store.jdbc.JDBCHelper;
70
import org.gvsig.fmap.dal.store.jdbc.JDBCHelperUser;
71
import org.gvsig.fmap.dal.store.jdbc.JDBCStoreParameters;
72
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCException;
73
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCExecutePreparedSQLException;
74
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCExecuteSQLException;
75
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCPreparingSQLException;
76
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCSQLException;
77
import org.gvsig.fmap.geom.Geometry;
78
import org.gvsig.fmap.geom.GeometryLocator;
79
import org.gvsig.fmap.geom.GeometryManager;
80
import org.gvsig.fmap.geom.operation.GeometryOperationException;
81
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
82
import org.gvsig.fmap.geom.operation.fromwkb.FromWKB;
83
import org.gvsig.fmap.geom.operation.fromwkb.FromWKBGeometryOperationContext;
84
import org.gvsig.fmap.geom.primitive.Envelope;
85
import org.gvsig.tools.ToolsLocator;
86
import org.gvsig.tools.exception.BaseException;
87

    
88
/**
89
 * @author jmvivo
90
 *
91
 */
92
public class PostgreSQLHelper extends JDBCHelper {
93

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

    
97
        private Map pgSR2SRSID = new TreeMap();
98
        private Map srsID2pgSR = new TreeMap();
99

    
100

    
101
        PostgreSQLHelper(JDBCHelperUser consumer,
102
                        PostgreSQLConnectionParameters params)
103
                        throws InitializeException {
104

    
105
                super(consumer, params);
106
        }
107

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

    
122

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

    
150
                return defaultSchema;
151
        }
152

    
153
        public Envelope getFullEnvelopeOfField(
154
                        JDBCStoreParameters storeParams,
155
                        String geometryAttrName, Envelope limit)
156
                        throws DataException {
157

    
158
                StringBuilder strb = new StringBuilder();
159
                strb.append("Select ST_asbinary(ST_extent(");
160
                strb.append(escapeFieldName(geometryAttrName));
161
                strb.append(")) from ");
162

    
163
                if (storeParams.getSQL() != null
164
                                && storeParams.getSQL().trim().length() > 0) {
165
                        strb.append('(');
166
                        strb.append(storeParams.getSQL());
167
                        strb.append(") as _subquery_alias_ ");
168
                } else {
169
                        strb.append(storeParams.tableID());
170
                }
171

    
172
                if (limit != null){
173
                        strb.append(" where  ST_intersects(ST_GeomFromText('");
174
                        String workAreaWkt = null;
175
                        try {
176
                                workAreaWkt = limit.getGeometry().convertToWKT();
177
                        } catch (Exception e) {
178
                                throw new CreateGeometryException(e);
179
                        }
180
                        strb.append(workAreaWkt);
181
                        strb.append("', ");
182
                        
183
                        IProjection proj = storeParams.getCRS();
184
                        int sridInt = this.getProviderSRID(proj); 
185
                        if (sridInt == -1) {
186
                                throw new CreateGeometryException(
187
                                                new Exception("CRS is null or unknown."));
188
                        } else {
189
                                strb.append(Integer.toString(sridInt));
190
                        }
191
                        strb.append("), ST_envelope(");
192
                        strb.append(escapeFieldName(geometryAttrName));
193
                        strb.append(")) ");
194
                }
195

    
196
                final String sql = strb.toString();
197

    
198
                GeometryManager geoMan = GeometryLocator.getGeometryManager();
199

    
200
                this.open();
201

    
202
                return (Envelope) getResource().execute(new ResourceAction() {
203
                        public Object run() throws Exception {
204
                                ResultSet rs = null;
205
                                Statement st = null;
206
                                String schema = null;
207
                                Connection conn = null;
208
                                Envelope fullEnvelope = null;
209
                                
210
                                Envelope emptyEnv =
211
                                                geomManager.createEnvelope(Geometry.SUBTYPES.GEOM2D);
212
                                
213
                                try {
214

    
215
                                        conn = getConnection();
216
                                        st = conn.createStatement();
217
                                        try {
218
                                                rs = st.executeQuery(sql);
219
                                        } catch (java.sql.SQLException e) {
220
                                                throw new JDBCExecuteSQLException(sql, e);
221
                                        }
222
                                        if (!rs.next()) {
223
                                                return emptyEnv;
224
                                        }
225

    
226
                                        byte[] data = rs.getBytes(1);
227
                                        if (data == null) {
228
                                                return emptyEnv;
229
                                        }
230

    
231
                                        Geometry geom = geomManager.createFrom(data);
232

    
233
                                        fullEnvelope = geom.getEnvelope();
234

    
235
                                        return fullEnvelope;
236
                                } catch (java.sql.SQLException e) {
237
                                        throw new JDBCSQLException(e);
238
                                } catch (BaseException e) {
239
                                        throw new ReadException(user.getProviderName(), e);
240
                                } finally {
241
                                        try {
242
                                                rs.close();
243
                                        } catch (Exception e) {
244
                                        }
245
                                        try {
246
                                                st.close();
247
                                        } catch (Exception e) {
248
                                        }
249
                                        try {
250
                                                conn.close();
251
                                        } catch (Exception e) {
252
                                        }
253
                                        rs = null;
254
                                        st = null;
255
                                        conn = null;
256
                                }
257
                        }
258
                });
259
        }
260

    
261
        @Override
262
        protected boolean supportsGeometry() {
263
                return true;
264
        }
265

    
266
        /**
267
         * Fill <code>featureType</code> geometry attributes with SRS and ShapeType
268
         * information stored in the table GEOMETRY_COLUMNS
269
         *
270
         * @param conn
271
         * @param rsMetadata
272
         * @param featureType
273
         * @throws ReadException
274
         */
275
        protected void loadSRS_and_shapeType(Connection conn,
276
                        ResultSetMetaData rsMetadata, EditableFeatureType featureType,
277
                        String baseSchema, String baseTable)
278
                        throws JDBCException {
279

    
280
                Statement st = null;
281
                ResultSet rs = null;
282
                try {
283
                        // Sacamos la lista de los attributos geometricos
284
                        EditableFeatureAttributeDescriptor attr;
285
                        List geoAttrs = new ArrayList();
286

    
287
                        Iterator iter = featureType.iterator();
288
                        while (iter.hasNext()) {
289
                                attr = (EditableFeatureAttributeDescriptor) iter.next();
290
                                if (attr.getType() == DataTypes.GEOMETRY) {
291
                                        geoAttrs.add(attr);
292
                                }
293
                        }
294
                        if (geoAttrs.size() < 1) {
295
                                return;
296
                        }
297

    
298

    
299
                        // preparamos un set con las lista de tablas de origen
300
                        // de los campos
301
                        class TableId {
302
                                public String schema=null;
303
                                public String table=null;
304
                                public String field = null;
305

    
306
                                public void appendToSQL(StringBuilder strb) {
307
                                        if (schema == null || schema.length() == 0) {
308
                                                strb
309
                                                                .append("( F_TABLE_SCHEMA = current_schema() AND F_TABLE_NAME = '");
310
                                        } else {
311
                                                strb.append("( F_TABLE_SCHEMA = '");
312
                                                strb.append(schema);
313
                                                strb.append("' AND F_TABLE_NAME = '");
314
                                        }
315
                                        strb.append(table);
316
                                        strb.append("' AND F_GEOMETRY_COLUMN = '");
317
                                        strb.append(field);
318
                                        strb.append("' )");
319
                                }
320

    
321
                        }
322
                        Comparator cmp = new Comparator(){
323
                                public int compare(Object arg0, Object arg1) {
324
                                        TableId a0 = (TableId) arg0;
325
                                        TableId a1 = (TableId) arg1;
326

    
327
                                        int aux = a0.field.compareTo(a1.field);
328
                                        if (aux != 0) {
329
                                            return aux;
330
                                        }
331

    
332
                                        aux = a0.table.compareTo(a1.table);
333
                    if (aux != 0) {
334
                        return aux;
335
                    }
336
                                        
337
                    if (a0.schema == null) {
338
                        if (a1.schema == null) {
339
                            aux = 0;
340
                        } else {
341
                            aux = -1;
342
                        }
343
                    } else {
344
                        if (a1.schema == null) {
345
                            aux = -1;
346
                        } else {
347
                            aux = a0.schema.compareTo(a1.schema);
348
                        }
349
                    }
350
                                        return aux;
351
                                }
352
                        };
353
                        TreeSet set = new TreeSet(cmp);
354
                        TableId tableId;
355
                        iter = geoAttrs.iterator();
356
                        int rsIndex;
357
                        while (iter.hasNext()) {
358
                                attr = (EditableFeatureAttributeDescriptor) iter.next();
359
                                tableId = new TableId();
360
                                rsIndex = attr.getIndex() + 1;
361

    
362
                                if (baseSchema == null && baseTable == null) {
363
                                        if (rsMetadata instanceof PGResultSetMetaData) {
364
                                                tableId.schema = ((PGResultSetMetaData) rsMetadata)
365
                                                                .getBaseSchemaName(rsIndex);
366
                                                tableId.table = ((PGResultSetMetaData) rsMetadata)
367
                                                                .getBaseTableName(rsIndex);
368
                                                tableId.field = ((PGResultSetMetaData) rsMetadata)
369
                                                                .getBaseColumnName(rsIndex);
370

    
371
                                        } else {
372
                                                tableId.schema = rsMetadata.getSchemaName(rsIndex);
373
                                                tableId.table = rsMetadata.getTableName(rsIndex);
374
                                                tableId.field = rsMetadata.getColumnName(rsIndex);
375
                                        }
376
                                } else {
377
                                        tableId.schema = baseSchema;
378
                                        tableId.table = baseTable;
379
                                        tableId.field = rsMetadata.getColumnName(rsIndex);
380
                                }
381
                                if (tableId.table == null || tableId.table.length() == 0) {
382
                                        // Si no tiene tabla origen (viene de algun calculo por ej.)
383
                                        // lo saltamos ya que no estara en la tabla GEOMETRY_COLUMNS
384
                                        continue;
385
                                }
386
                                set.add(tableId);
387
                        }
388

    
389
                        if (set.size() == 0) {
390
                                return;
391
                        }
392

    
393
                        // Preparamos una sql para que nos saque el resultado
394
                        StringBuilder strb = new StringBuilder();
395
                        strb.append("Select geometry_columns.*,auth_name || ':' || auth_srid as SRSID ");
396
                        strb.append("from geometry_columns left join spatial_ref_sys on ");
397
                        strb.append("geometry_columns.srid = spatial_ref_sys.srid WHERE ");
398
                        iter = set.iterator();
399
                        for (int i=0;i<set.size()-1;i++) {
400
                                tableId = (TableId) iter.next();
401
                                tableId.appendToSQL(strb);
402
                                strb.append(" OR ");
403
                        }
404
                        tableId = (TableId) iter.next();
405
                        tableId.appendToSQL(strb);
406
                        String sql = strb.toString();
407

    
408

    
409
                        st = conn.createStatement();
410
                        try {
411
                                rs = st.executeQuery(sql);
412
                        } catch (SQLException e) {
413
                                throw new JDBCExecuteSQLException(sql, e);
414
                        }
415
                        String srsID;
416
                        int pgSrid;
417
                        int geometryType;
418
                        int geometrySubtype;
419
                        String geomTypeStr;
420
                        int dimensions;
421
                        IProjection srs;
422

    
423
                        while (rs.next()){
424
                                srsID = rs.getString("SRSID");
425
                                pgSrid = rs.getInt("SRID");
426
                                geomTypeStr = rs.getString("TYPE").toUpperCase();
427
                                geometryType = Geometry.TYPES.GEOMETRY;
428
                                if (geomTypeStr.startsWith("POINT")) {
429
                                        geometryType = Geometry.TYPES.POINT;
430
                                } else if (geomTypeStr.startsWith("LINESTRING")) {
431
                                        geometryType = Geometry.TYPES.CURVE;
432
                                } else if (geomTypeStr.startsWith("POLYGON")) {
433
                                        geometryType = Geometry.TYPES.SURFACE;
434
                                } else if (geomTypeStr.startsWith("MULTIPOINT")) {
435
                                        geometryType = Geometry.TYPES.MULTIPOINT;
436
                                } else if (geomTypeStr.startsWith("MULTILINESTRING")) {
437
                                        geometryType = Geometry.TYPES.MULTICURVE;
438
                                } else if (geomTypeStr.startsWith("MULTIPOLYGON")) {
439
                                        geometryType = Geometry.TYPES.MULTISURFACE;
440
                                }
441
                                dimensions = rs.getInt("coord_dimension");
442
                                geometrySubtype = Geometry.SUBTYPES.GEOM2D;
443
                                if (dimensions > 2) {
444
                                        if (dimensions == 3) {
445
                                                if (geomTypeStr.endsWith("M")) {
446
                                                        geometrySubtype = Geometry.SUBTYPES.GEOM2DM;
447
                                                } else {
448
                                                        geometrySubtype = Geometry.SUBTYPES.GEOM3D;
449
                                                }
450

    
451
                                        } else {
452
                                                geometrySubtype = Geometry.SUBTYPES.GEOM3DM;
453
                                        }
454
                                }
455
                                addToPgSRToSRSID(pgSrid, srsID);
456

    
457

    
458
                                iter = geoAttrs.iterator();
459
                                while (iter.hasNext()) {
460
                                        attr = (EditableFeatureAttributeDescriptor) iter.next();
461
                                        rsIndex = attr.getIndex() + 1;
462
                                        if (!rsMetadata.getColumnName(rsIndex).equals(
463
                                                        rs.getString("f_geometry_column"))) {
464
                                                continue;
465
                                        }
466

    
467
                                        if (baseSchema == null && baseTable == null) {
468

    
469
                                                if (rsMetadata instanceof PGResultSetMetaData) {
470
                                                        if (!((PGResultSetMetaData) rsMetadata)
471
                                                                        .getBaseTableName(rsIndex).equals(
472
                                                                                        rs.getString("f_table_name"))) {
473
                                                                continue;
474
                                                        }
475
                                                        String curSchema = rs.getString("f_table_schema");
476
                                                        String metaSchema = ((PGResultSetMetaData) rsMetadata)
477
                                                                        .getBaseSchemaName(rsIndex);
478
                                                        if (!metaSchema.equals(curSchema)) {
479
                                                                if (metaSchema.length() == 0
480
                                                                                && metaSchema == getDefaultSchema(conn)) {
481
                                                                } else {
482
                                                                        continue;
483
                                                                }
484
                                                        }
485

    
486
                                                } else {
487

    
488
                                                        if (!rsMetadata.getTableName(rsIndex).equals(
489
                                                                        rs.getString("f_table_name"))) {
490
                                                                continue;
491
                                                        }
492
                                                        String curSchema = rs.getString("f_table_schema");
493
                                                        String metaSchema = rsMetadata
494
                                                                        .getSchemaName(rsIndex);
495
                                                        if (!metaSchema.equals(curSchema)) {
496
                                                                if (metaSchema.length() == 0
497
                                                                                && metaSchema == getDefaultSchema(conn)) {
498
                                                                } else {
499
                                                                        continue;
500
                                                                }
501
                                                        }
502
                                                }
503
                                        }
504
                                        attr.setGeometryType(geometryType);
505
                                        attr.setGeometrySubType(geometrySubtype);
506
                                        if (srsID != null && srsID.length() > 0) {
507
                                                attr.setSRS(CRSFactory.getCRS(srsID));
508
                                        }
509
                                        iter.remove();
510
                                }
511
                                iter = geoAttrs.iterator();
512
                                while (iter.hasNext()) {
513
                                        attr = (EditableFeatureAttributeDescriptor) iter.next();
514
                                        attr.setSRS(null);
515
                                        attr.setGeometryType(Geometry.TYPES.GEOMETRY);
516

    
517
                                }
518
                        }
519

    
520
                } catch (java.sql.SQLException e) {
521
                        throw new JDBCSQLException(e);
522
                } finally {
523
                        try {rs.close();} catch (Exception e) {        };
524
                        try {st.close();} catch (Exception e) {        };
525
                }
526

    
527
        }
528

    
529

    
530
        public String getSqlColumnTypeDescription(FeatureAttributeDescriptor attr) {
531
                if (attr.getType() == DataTypes.GEOMETRY) {
532
                        return "geometry";
533
                }
534
                return super.getSqlColumnTypeDescription(attr);
535
        }
536

    
537

    
538
        public int getPostgisGeomDimensions(int geometrySubType) {
539
                switch (geometrySubType) {
540
                case Geometry.SUBTYPES.GEOM2D:
541
                        return 2;
542
                case Geometry.SUBTYPES.GEOM2DM:
543
                case Geometry.SUBTYPES.GEOM3D:
544
                        return 3;
545

    
546
                case Geometry.SUBTYPES.GEOM3DM:
547
                        return 4;
548
                default:
549
                        throw new UnsupportedDataTypeException(
550
                                        ToolsLocator.getDataTypesManager().getTypeName(DataTypes.GEOMETRY),
551
                                        DataTypes.GEOMETRY);
552
                }
553
        }
554

    
555
        public String getPostgisGeomType(int geometryType, int geometrySubType) {
556
                String pgGeomType;
557
                switch (geometryType) {
558
                case Geometry.TYPES.GEOMETRY:
559
                        pgGeomType = "GEOMETRY";
560
                        break;
561
                case Geometry.TYPES.POINT:
562
                        pgGeomType = "POINT";
563
                        break;
564
                case Geometry.TYPES.CURVE:
565
                        pgGeomType = "LINESTRING";
566
                        break;
567
                case Geometry.TYPES.SURFACE:
568
                        pgGeomType = "POLYGON";
569
                        break;
570
                case Geometry.TYPES.MULTIPOINT:
571
                        pgGeomType = "MULTIPOINT";
572
                        break;
573
                case Geometry.TYPES.MULTICURVE:
574
                        pgGeomType = "MULTILINESTRING";
575
                        break;
576
                case Geometry.TYPES.MULTISURFACE:
577
                        pgGeomType = "MULTIPOLYGON";
578
                        break;
579
                default:
580
                        throw new UnsupportedGeometryException(geometryType,
581
                                        geometrySubType);
582
                }
583
                if (geometrySubType == Geometry.SUBTYPES.GEOM2DM
584
                                || geometrySubType == Geometry.SUBTYPES.GEOM3DM) {
585
                        pgGeomType = pgGeomType + "M";
586
                } else if (geometrySubType == Geometry.SUBTYPES.GEOM3D) {
587
                        throw new UnsupportedGeometryException(geometryType,
588
                                        geometrySubType);
589
                }
590
                return pgGeomType;
591
        }
592

    
593
        public int getProviderSRID(String srs) {
594
                if (srs != null) {
595
                        Integer pgSRID = (Integer) srsID2pgSR.get(srs);
596
                        if (pgSRID != null) {
597
                                return pgSRID.intValue();
598
                        }
599

    
600
                        return searchpgSRID(srs);
601

    
602
                }
603
                return -1;
604
        }
605

    
606

    
607
        public int getProviderSRID(IProjection srs) {
608
                if (srs != null) {
609
                        Integer pgSRID = (Integer) srsID2pgSR.get(srs.getAbrev());
610
                        if (pgSRID != null) {
611
                                return pgSRID.intValue();
612
                        }
613

    
614
                        return searchpgSRID(srs);
615

    
616
                }
617
                return -1;
618
        }
619

    
620
        private int searchpgSRID(final IProjection srs) {
621
                if (srs == null) {
622
                        return -1;
623
                }
624
                return searchpgSRID(srs.getAbrev());
625
        }
626

    
627
        private int searchpgSRID(final String srsID) {
628
                if (srsID == null) {
629
                        return -1;
630
                }
631

    
632
                ConnectionAction action = new ConnectionAction(){
633

    
634
                        public Object action(Connection conn) throws DataException {
635

    
636
                                String[] abrev = srsID.split(":");
637
                                StringBuilder sqlb = new StringBuilder();
638
                                sqlb.append("select srid from spatial_ref_sys where ");
639
                                if (abrev.length > 1) {
640
                                        sqlb.append("auth_name = ? and ");
641
                                }
642
                                sqlb.append("auth_srid = ?");
643

    
644
                                String sql = sqlb.toString();
645
                                PreparedStatement st;
646
                                try {
647
                                        st = conn.prepareStatement(sql);
648
                                } catch (SQLException e){
649
                                        throw new JDBCPreparingSQLException(sql,e);
650
                                }
651
                                ResultSet rs = null;
652
                                try{
653
                                        int i=0;
654
                                        if (abrev.length > 1){
655
                                                st.setString(i+1, abrev[i]);
656
                                                i++;
657
                                        }
658
                                        st.setInt(i + 1, Integer.parseInt(abrev[i]));
659

    
660
                                        try{
661
                                                rs = st.executeQuery();
662
                                        } catch (SQLException e){
663
                                                throw new JDBCExecutePreparedSQLException(sql, abrev, e);
664
                                        }
665

    
666
                                        if (!rs.next()) {
667
                                                return null;
668
                                        }
669

    
670
                                        return new Integer(rs.getInt(1));
671

    
672
                                } catch (SQLException e){
673
                                        throw new JDBCSQLException(e);
674
                                } finally{
675
                                        try {rs.close(); } catch (Exception e) {};
676
                                        try {st.close(); } catch (Exception e) {};
677
                                }
678

    
679
                        }
680

    
681
                };
682

    
683
                Integer pgSRSID = null;
684
                try {
685
                        pgSRSID = (Integer) doConnectionAction(action);
686
                } catch (Exception e) {
687
                        logger.error("Excetion searching pgSRS", e);
688
                        return -1;
689
                }
690

    
691
                if (pgSRSID != null) {
692
                        addToPgSRToSRSID(pgSRSID.intValue(), srsID);
693
                        return pgSRSID.intValue();
694
                }
695
                return -1;
696

    
697
        }
698

    
699
        private void addToPgSRToSRSID(int pgSRID, String srsId) {
700
                if (pgSRID < 0 || srsId == null || srsId.length() == 0) {
701
                        return;
702
                }
703
                Integer pgSRIDInteger = new Integer(pgSRID);
704
                pgSR2SRSID.put(pgSRIDInteger, srsId);
705
                srsID2pgSR.put(srsId, pgSRIDInteger);
706
        }
707

    
708
        public List<String> getSqlGeometyFieldAdd(FeatureAttributeDescriptor attr,
709
                        String table, String schema) {
710
                // SELECT AddGeometryColumn({schema}, {table}, {field}, {srid}(int),
711
                // {geomType}(Str), {dimensions}(int))
712

    
713
                // gemoType:
714
                /*
715
                 * POINT, LINESTRING, POLYGON, MULTIPOINT, MULTILINESTRING,
716
                 * MULTIPOLYGON, GEOMETRYCOLLECTION POINTM, LINESTRINGM, POLYGONM,
717
                 * MULTIPOINTM, MULTILINESTRINGM, MULTIPOLYGONM, GEOMETRYCOLLECTIONM
718
                 */
719

    
720
                List<String> sqls = new ArrayList<String>();
721

    
722
                StringBuilder strb = new StringBuilder();
723
                strb.append("SELECT AddGeometryColumn('");
724
                if (schema != null && schema.length() > 0) {
725
                        strb.append(schema);
726
                        strb.append("', '");
727
                }
728
                strb.append(table);
729
                strb.append("', '");
730
                strb.append(attr.getName().toLowerCase());
731
                strb.append("', ");
732
                // strb.append("-1");
733
                strb.append(getProviderSRID(attr.getSRS()));
734
                strb.append(", '");
735
                
736
                // ===========================================================================
737
            // TODO Improve this. Keep in mind that MULTIPOLYGON will not accept POLYGON
738
        strb.append("GEOMETRY");
739
                /*
740
                strb.append(getPostgisGeomType(attr.getGeometryType(), attr
741
                                .getGeometrySubType()));
742
                                */
743
        // ===========================================================================
744
                strb.append("', ");
745
                strb.append(getPostgisGeomDimensions(attr.getGeometrySubType()));
746
                strb.append(")");
747

    
748

    
749
                sqls.add(strb.toString());
750

    
751
                /*ALTER TABLE muni10000_peq_test DROP CONSTRAINT enforce_srid_the_geom;*/
752
                /*
753
                strb = new StringBuilder();
754
                strb.append("Alter table ");
755
                if (schema != null && schema.length() > 0) {
756
                        strb.append(schema);
757
                        strb.append(".");
758
                }
759
                strb.append("f_table_name = '");
760
                strb.append(table);
761
                strb.append("' AND f_geometry_column = '");
762
                strb.append(attr.getName());
763
                strb.append("' AND srid = -1");
764

765

766
                sqls.add(strb.toString());
767
                */
768
                return sqls;
769
        }
770

    
771
        public String getSqlFieldName(FeatureAttributeDescriptor attribute) {
772
                if (attribute.getType() == DataTypes.GEOMETRY) {
773
                        return "asBinary(" + super.getSqlFieldName(attribute) + ")";
774
                }
775
                return super.getSqlFieldName(attribute);
776
        }
777

    
778
        protected EditableFeatureAttributeDescriptor createAttributeFromJDBC(
779
                        EditableFeatureType type, Connection conn,
780
                        ResultSetMetaData rsMetadata, int colIndex) throws SQLException {
781
                if (rsMetadata.getColumnType(colIndex) == java.sql.Types.OTHER) {
782
                        if (rsMetadata.getColumnTypeName(colIndex).equalsIgnoreCase(
783
                                        "geometry")) {
784
                                EditableFeatureAttributeDescriptor attr = type.add(rsMetadata.getColumnName(colIndex),
785
                                                DataTypes.GEOMETRY);
786
                                // Set default values for geometry type
787
                                attr.setGeometryType(Geometry.TYPES.GEOMETRY);
788
                                attr.setGeometrySubType(Geometry.SUBTYPES.GEOM2D);
789
                                return attr;
790

    
791
                        }
792
                }
793

    
794
                return super.createAttributeFromJDBC(type, conn, rsMetadata, colIndex);
795
        }
796

    
797
        public List getAdditionalSqlToCreate(NewDataStoreParameters ndsp,
798
                        FeatureType fType) {
799
                FeatureAttributeDescriptor attr;
800
                Iterator iter = fType.iterator();
801
                List result = new ArrayList();
802
                PostgreSQLNewStoreParameters pgNdsp = (PostgreSQLNewStoreParameters) ndsp;
803
                while (iter.hasNext()){
804
                        attr = (FeatureAttributeDescriptor) iter.next();
805
                        if (attr.getType() == DataTypes.GEOMETRY){
806
                                result.addAll(getSqlGeometyFieldAdd(attr, pgNdsp.getTable(),
807
                                                pgNdsp
808
                                                .getSchema()));
809
                        }
810
                }
811

    
812
                return result;
813
        }
814

    
815
        public String getSqlFieldDescription(FeatureAttributeDescriptor attr)
816
                        throws DataException {
817
                if (attr.getType() == DataTypes.GEOMETRY){
818
                        return null;
819
                }
820
                return super.getSqlFieldDescription(attr);
821
        }
822

    
823

    
824
        public boolean allowAutomaticValues() {
825
                return Boolean.TRUE;
826
        }
827

    
828
        public boolean supportOffset() {
829
                return true;
830
        }
831

    
832
        public boolean supportsUnion() {
833
                return true;
834
        }
835
        
836
        public String escapeFieldName(String field) {
837
                /*
838
                if (!reservedWord(field) && 
839
                                field.matches("[a-z][a-z0-9_]*")) {
840
                        return field;
841
                }
842
                */
843
                String quote = getIdentifierQuoteString();
844
                return quote + field + quote;
845
        }
846
}