Statistics
| Revision:

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

History | View | Annotate | Download (37.8 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.Arrays;
41
import java.util.Comparator;
42
import java.util.Iterator;
43
import java.util.List;
44
import java.util.Map;
45
import java.util.TreeMap;
46
import java.util.TreeSet;
47

    
48
import org.cresques.cts.IProjection;
49
import org.gvsig.fmap.crs.CRSFactory;
50
import org.gvsig.fmap.dal.DALLocator;
51
import org.gvsig.fmap.dal.DataTypes;
52
import org.gvsig.fmap.dal.exception.CloseException;
53
import org.gvsig.fmap.dal.exception.DataException;
54
import org.gvsig.fmap.dal.exception.InitializeException;
55
import org.gvsig.fmap.dal.exception.OpenException;
56
import org.gvsig.fmap.dal.exception.ReadException;
57
import org.gvsig.fmap.dal.exception.WriteException;
58
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
59
import org.gvsig.fmap.dal.feature.EditableFeatureType;
60
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
61
import org.gvsig.fmap.dal.feature.FeatureType;
62
import org.gvsig.fmap.dal.feature.exception.UnsupportedDataTypeException;
63
import org.gvsig.fmap.dal.feature.exception.UnsupportedGeometryException;
64
import org.gvsig.fmap.dal.resource.exception.AccessResourceException;
65
import org.gvsig.fmap.dal.resource.exception.ResourceBeginException;
66
import org.gvsig.fmap.dal.resource.spi.ResourceConsumer;
67
import org.gvsig.fmap.dal.resource.spi.ResourceManagerProviderServices;
68
import org.gvsig.fmap.dal.resource.spi.ResourceProvider;
69
import org.gvsig.fmap.dal.store.jdbc.JDBCException;
70
import org.gvsig.fmap.dal.store.jdbc.JDBCExecutePreparedSQLException;
71
import org.gvsig.fmap.dal.store.jdbc.JDBCExecuteSQLException;
72
import org.gvsig.fmap.dal.store.jdbc.JDBCPreparingSQLException;
73
import org.gvsig.fmap.dal.store.jdbc.JDBCSQLException;
74
import org.gvsig.fmap.dal.store.jdbc.JDBCTransactionCommitException;
75
import org.gvsig.fmap.dal.store.jdbc.JDBCTransactionRollbackException;
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.Geometry.SUBTYPES;
80
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
81
import org.gvsig.fmap.geom.operation.fromwkb.FromWKB;
82
import org.gvsig.fmap.geom.operation.fromwkb.FromWKBGeometryOperationContext;
83
import org.gvsig.fmap.geom.operation.towkb.ToWKB;
84
import org.gvsig.fmap.geom.operation.towkb.ToWKBOperationContext;
85
import org.gvsig.fmap.geom.primitive.Envelope;
86
import org.gvsig.tools.exception.BaseException;
87
import org.postgis.PGbox2d;
88
import org.postgis.PGbox3d;
89
import org.postgresql.PGResultSetMetaData;
90
import org.postgresql.util.PGobject;
91
import org.slf4j.Logger;
92
import org.slf4j.LoggerFactory;
93

    
94
/**
95
 * @author jmvivo
96
 *
97
 */
98
class PostgreSQLHelper implements ResourceConsumer {
99

    
100
        private static Logger logger = LoggerFactory
101
                        .getLogger(PostgreSQLHelper.class);
102

    
103
        private PostgreSQLConnectionParameters params;
104
        private PostgreSQLResource resource;
105
        private PostgreSQLHelperUser user;
106
        private boolean isOpen;
107
        private String name;
108

    
109
        private Map pgSR2SRSID = new TreeMap();
110
        private Map srsID2pgSR = new TreeMap();
111

    
112
        private String defaultSchema;
113

    
114
        private FromWKB fromWKB = null;
115
        private FromWKBGeometryOperationContext fromWKBContext = null;
116
        private ToWKBOperationContext toWKBContext = new ToWKBOperationContext();
117

    
118
        PostgreSQLHelper(PostgreSQLHelperUser consumer,
119
                        PostgreSQLConnectionParameters params)
120
                        throws InitializeException {
121

    
122
                this.user = consumer;
123
                this.name = user.getName();
124
                this.params = params;
125

    
126
                ResourceManagerProviderServices manager = (ResourceManagerProviderServices) DALLocator
127
                                .getResourceManager();
128
                resource = (PostgreSQLResource) manager.createResource(
129
                                PostgreSQLResource.NAME, new Object[] { params.getHost(),
130
                                                params.getPort(), params.getDBName(), params.getUser(),
131
                                                params.getPassword(),
132
                                                PostgreSQLLibrary.DEFAULT_JDCB_DRIVER_NAME,
133
                                                params.getUseSSL() });
134
                resource.addConsumer(this);
135

    
136
        }
137

    
138
        /* (non-Javadoc)
139
         * @see org.gvsig.fmap.dal.resource.spi.ResourceConsumer#closeResourceRequested(org.gvsig.fmap.dal.resource.spi.ResourceProvider)
140
         */
141
        public boolean closeResourceRequested(ResourceProvider resource) {
142
                return user.closeResourceRequested(resource);
143
        }
144

    
145
        /* (non-Javadoc)
146
         * @see org.gvsig.fmap.dal.resource.spi.ResourceConsumer#resourceChanged(org.gvsig.fmap.dal.resource.spi.ResourceProvider)
147
         */
148
        public void resourceChanged(ResourceProvider resource) {
149
                user.resourceChanged(resource);
150

    
151
        }
152

    
153
        /**
154
         * open the resource
155
         *
156
         * @return true if the resourse was open in this call
157
         * @throws OpenException
158
         */
159
        public boolean open() throws OpenException {
160
                if (isOpen) {
161
                        return false;
162
                }
163
                try {
164
                        begin();
165
                } catch (ResourceBeginException e1) {
166
                        throw new OpenException(name, e1);
167
                }
168
                try {
169
                        resource.connect();
170
                        resource.notifyOpen();
171

    
172
                        this.user.opendDone();
173

    
174
                        isOpen = true;
175

    
176
                        return true;
177
                } catch (DataException e) {
178
                        throw new OpenException(name, e);
179
                } finally {
180
                        end();
181
                }
182

    
183
        }
184

    
185
        public void close() throws CloseException {
186
                if (!isOpen) {
187
                        return;
188
                }
189
                try {
190
                        begin();
191
                } catch (ResourceBeginException e) {
192
                        throw new CloseException(name, e);
193
                }
194
                try {
195

    
196
                        isOpen = false;
197

    
198
                        resource.notifyClose();
199
                        this.user.closeDone();
200
                } catch (DataException e) {
201
                        throw new CloseException(this.name, e);
202
                } finally {
203
                        end();
204
                }
205
        }
206

    
207
        public void end() {
208
                resource.end();
209
        }
210

    
211
        public void begin() throws ResourceBeginException {
212
                this.resource.begin();
213
        }
214

    
215
        public Connection getConnection() throws AccessResourceException {
216
                return resource.getJDBCConnection();
217

    
218
        }
219

    
220
        public void dispose() {
221
                resource.removeConsumer(this);
222
        }
223

    
224
        public void loadFeatureType(EditableFeatureType featureType,
225
                        PostgreSQLStoreParameters storeParams) throws DataException {
226
                if (storeParams.getSQL() != null && storeParams.getSQL().trim().length() == 0) {
227
                        loadFeatureType(featureType, storeParams, storeParams.getSQL(),
228
                                        null, null);
229
                } else {
230
                        String sql = "Select * from " + storeParams.tableID()
231
                                        + " where false";
232
                        loadFeatureType(featureType, storeParams, sql, storeParams
233
                                        .getSchema(), storeParams.getTable());
234
                }
235
        }
236

    
237

    
238
        public void loadFeatureType(EditableFeatureType featureType,
239
                        PostgreSQLStoreParameters storeParams, String sql, String schema,
240
                        String table)
241
                        throws DataException {
242
                Connection conn = null;
243
                this.open();
244
                this.begin();
245
                try{
246
                        conn = getConnection();
247

    
248
                        String[] pks = storeParams.getPkFields();
249
                        if (pks == null || pks.length < 1) {
250
                                if (storeParams.getTable() != null
251
                                        && storeParams.getTable().trim().length() > 0) {
252
                                        pks = getPksFrom(conn, storeParams);
253

    
254
                                }
255
                        }
256

    
257
                        loadFeatureType(conn, featureType, sql, pks,
258
                                        storeParams
259
                                .getDefaultGeometry(), schema, table);
260

    
261

    
262
                } finally{
263
                        try {conn.close();} catch (Exception e){};
264
                        this.end();
265
                }
266
        }
267

    
268
        private String[] getPksFrom(Connection conn,
269
                        PostgreSQLStoreParameters params) throws JDBCException {
270
                Statement st;
271
                StringBuffer sql = new StringBuffer();
272
                ResultSet rs;
273
                ArrayList list = new ArrayList();
274
                /*
275
                 * SELECT column_name FROM INFORMATION_SCHEMA.constraint_column_usage
276
                 * left join INFORMATION_SCHEMA.table_constraints on
277
                 * (INFORMATION_SCHEMA.table_constraints.constraint_name =
278
                 * INFORMATION_SCHEMA.constraint_column_usage.constraint_name and
279
                 * INFORMATION_SCHEMA.table_constraints.table_name =
280
                 * INFORMATION_SCHEMA.constraint_column_usage.table_name and
281
                 * INFORMATION_SCHEMA.table_constraints.table_schema =
282
                 * INFORMATION_SCHEMA.constraint_column_usage.table_schema) WHERE
283
                 * INFORMATION_SCHEMA.constraint_column_usage.table_name like
284
                 * 'muni10000_peq' AND
285
                 * INFORMATION_SCHEMA.constraint_column_usage.table_schema like 'public'
286
                 * AND INFORMATION_SCHEMA.constraint_column_usage.table_catalog like
287
                 * 'gis' AND constraint_type='PRIMARY KEY'
288
                 */
289

    
290
                sql.append("SELECT column_name FROM INFORMATION_SCHEMA.constraint_column_usage ");
291
                sql.append("left join INFORMATION_SCHEMA.table_constraints on ");
292
                sql.append("(INFORMATION_SCHEMA.table_constraints.constraint_name = ");
293
                sql.append("INFORMATION_SCHEMA.constraint_column_usage.constraint_name ");
294
                sql.append("and INFORMATION_SCHEMA.table_constraints.table_name = ");
295
                sql.append("INFORMATION_SCHEMA.constraint_column_usage.table_name ");
296
                sql.append("and INFORMATION_SCHEMA.table_constraints.table_schema = ");
297
                sql.append("INFORMATION_SCHEMA.constraint_column_usage.table_schema) ");
298
                sql.append("WHERE INFORMATION_SCHEMA.constraint_column_usage.table_name like '");
299

    
300
                sql.append(params.getTable());
301
                sql.append("' AND INFORMATION_SCHEMA.constraint_column_usage.table_schema like '");
302

    
303
                if (params.getSchema() == null || params.getSchema() == "") {
304
                        sql.append(getDefaultSchema(conn));
305
                } else {
306
                        sql.append(params.getSchema());
307
                }
308

    
309
                if (params.getCatalog() == null || params.getCatalog() == "") {
310
                        if (params.getDBName() != null && params.getDBName() != "") {
311
                                sql.append("' AND INFORMATION_SCHEMA.constraint_column_usage.table_catalog like '");
312
                                sql.append(params.getDBName());
313
                        }
314
                } else {
315
                        sql.append("' AND INFORMATION_SCHEMA.constraint_column_usage.table_catalog like '");
316
                        sql.append(params.getCatalog());
317
                }
318

    
319
                sql.append("' AND constraint_type='PRIMARY KEY'");
320

    
321
                // System.out.println(sql.toString());
322
                try {
323
                        st = conn.createStatement();
324
                        try {
325
                                rs = st.executeQuery(sql.toString());
326
                        } catch (java.sql.SQLException e) {
327
                                throw new JDBCExecuteSQLException(sql.toString(), e);
328
                        }
329
                        while (rs.next()) {
330
                                list.add(rs.getString(1));
331
                        }
332
                        rs.close();
333
                        st.close();
334

    
335
                } catch (java.sql.SQLException e) {
336
                        throw new JDBCSQLException(e);
337
                }
338
                if (list.size() == 0) {
339
                        return null;
340
                }
341

    
342
                return (String[]) list.toArray(new String[0]);
343

    
344
        }
345

    
346

    
347
        private void loadFeatureType(Connection conn,
348
                        EditableFeatureType featureType, String sql, String[] pks,
349
                        String defGeomName, String schema, String table)
350
                        throws DataException {
351

    
352
                Statement stAux = null;
353
                ResultSet rs = null;
354
                try {
355

    
356
                        stAux = conn.createStatement();
357
                        stAux.setFetchSize(1);
358

    
359
                        try {
360
                                rs = stAux.executeQuery(sql);
361
                        } catch (SQLException e) {
362
                                throw new JDBCExecuteSQLException(sql, e);
363
                        }
364
                        ResultSetMetaData rsMetadata = rs.getMetaData();
365

    
366
                        List pksList = null;
367
                        if (pks != null) {
368
                                pksList = Arrays.asList(pks);
369

    
370
                        }
371

    
372
                        int i;
373
                        int geometriesColumns = 0;
374
                        String lastGeometry=null;
375

    
376
                        EditableFeatureAttributeDescriptor attr;
377
                        for (i = 1; i <= rsMetadata.getColumnCount(); i++) {
378
                                attr = getAttributeFromJDBC(featureType, conn, rsMetadata, i);
379
                                if (pksList != null && pksList.contains(attr.getName())) {
380
                                        attr.setIsPrimaryKey(true);
381
                                }
382
                                if (attr.getDataType() == DataTypes.GEOMETRY) {
383
                                        geometriesColumns++;
384
                                        lastGeometry=attr.getName();
385
                                        if (lastGeometry.equals(defGeomName)) {
386
                                                featureType
387
                                                                .setDefaultGeometryAttributeName(defGeomName);
388
                                        }
389

    
390

    
391
                                }
392

    
393

    
394
                        }
395

    
396
                        if (geometriesColumns > 0) {
397
                                loadSRS_and_shapeType(conn, rsMetadata, featureType, schema,
398
                                                table);
399
                        }
400

    
401

    
402
                        if (defGeomName == null && geometriesColumns == 1) {
403
                                featureType.setDefaultGeometryAttributeName(lastGeometry);
404
                                defGeomName = lastGeometry;
405
                        }
406

    
407
                } catch (java.sql.SQLException e) {
408
                        throw new JDBCSQLException(e); // FIXME exception
409
                } finally {
410
                        try{ rs.close(); } catch (Exception e){}
411
                        try{ stAux.close(); } catch (Exception e){}
412

    
413
                }
414

    
415
        }
416

    
417

    
418
        private EditableFeatureAttributeDescriptor getAttributeFromJDBC(
419
                        EditableFeatureType fType, Connection conn,
420
                        ResultSetMetaData rsMetadata, int colIndex) throws JDBCException {
421
                EditableFeatureAttributeDescriptor column;
422
                try {
423

    
424
                        switch (rsMetadata.getColumnType(colIndex)) {
425
                        case java.sql.Types.INTEGER:
426
                                column = fType.add(rsMetadata.getColumnName(colIndex),
427
                                                DataTypes.INT);
428
                                break;
429
                        case java.sql.Types.BIGINT:
430
                                column = fType.add(rsMetadata.getColumnName(colIndex),
431
                                                DataTypes.LONG);
432
                                break;
433
                        case java.sql.Types.REAL:
434
                                column = fType.add(rsMetadata.getColumnName(colIndex),
435
                                                DataTypes.DOUBLE);
436
                                break;
437
                        case java.sql.Types.DOUBLE:
438
                                column = fType.add(rsMetadata.getColumnName(colIndex),
439
                                                DataTypes.DOUBLE);
440
                                break;
441
                        case java.sql.Types.CHAR:
442
                                column = fType.add(rsMetadata.getColumnName(colIndex),
443
                                                DataTypes.STRING);
444
                                break;
445
                        case java.sql.Types.VARCHAR:
446
                                column = fType.add(rsMetadata.getColumnName(colIndex),
447
                                                DataTypes.STRING);
448
                                break;
449
                        case java.sql.Types.FLOAT:
450
                                column = fType.add(rsMetadata.getColumnName(colIndex),
451
                                                DataTypes.FLOAT);
452
                                break;
453
                        case java.sql.Types.DECIMAL:
454
                                column = fType.add(rsMetadata.getColumnName(colIndex),
455
                                                DataTypes.FLOAT);
456
                                break;
457
                        case java.sql.Types.DATE:
458
                                column = fType.add(rsMetadata.getColumnName(colIndex),
459
                                                DataTypes.DATE);
460
                                break;
461
                        case java.sql.Types.TIME:
462
                                column = fType.add(rsMetadata.getColumnName(colIndex),
463
                                                DataTypes.TIME);
464
                                break;
465
                        case java.sql.Types.TIMESTAMP:
466
                                column = fType.add(rsMetadata.getColumnName(colIndex),
467
                                                DataTypes.TIMESTAMP);
468
                                break;
469
                        case java.sql.Types.BOOLEAN:
470
                                column = fType.add(rsMetadata.getColumnName(colIndex),
471
                                                DataTypes.BOOLEAN);
472
                                break;
473
                        case java.sql.Types.OTHER:
474
                                if (rsMetadata.getColumnTypeName(colIndex).equalsIgnoreCase(
475
                                                "geometry")) {
476
                                        column = fType.add(rsMetadata.getColumnName(colIndex),
477
                                                        DataTypes.GEOMETRY);
478
                                        break;
479
                                }
480
                                // No hacemos break para que se quede en default
481

    
482
                        default:
483
                                column = fType.add(rsMetadata.getColumnName(colIndex),
484
                                                DataTypes.OBJECT);
485
                                break;
486
                        }
487
                        // column.setCaseSensitive(rsMetadata.isCaseSensitive(colIndex));
488
                        // column.setSqlType(rsMetadata.getColumnType(colIndex));
489
                        column
490
                                        .setAllowNull(rsMetadata.isNullable(colIndex) == ResultSetMetaData.columnNullable);
491
                        column.setIsAutomatic(rsMetadata.isAutoIncrement(colIndex));
492
                        column.setIsReadOnly(rsMetadata.isReadOnly(colIndex));
493
                        // column.setWritable(rsMetadata.isWritable(colIndex));
494
                        // column.setClassName(rsMetadata.getColumnClassName(colIndex));
495
                        // column.setCatalogName(rsMetadata.getCatalogName(colIndex));
496
                        // column.setDefinitelyWritable(rsMetadata
497
                        // .isDefinitelyWritable(colIndex));
498
                        // column.setLabel(rsMetadata.getColumnLabel(colIndex));
499
                        // column.setSchemaName(rsMetadata.getSchemaName(colIndex));
500
                        // column.setTableName(rsMetadata.getTableName(colIndex));
501
                        // column.setCatalogName(rsMetadata.getCatalogName(colIndex));
502
                        // column.setSqlTypeName();
503
                        // column.setSearchable(rsMetadata.isSearchable(colIndex));
504
                        // column.setSigned(rsMetadata.isSigned(colIndex));
505
                        // column.setCurrency(rsMetadata.isCurrency(colIndex));
506
                        column.setPrecision(rsMetadata.getPrecision(colIndex));
507
                        column.setSize(rsMetadata.getColumnDisplaySize(colIndex));
508

    
509
                } catch (java.sql.SQLException e) {
510
                        throw new JDBCSQLException(e);
511
                }
512

    
513
                return column;
514

    
515
        }
516

    
517
        private String getDefaultSchema(Connection conn)
518
                        throws JDBCException {
519
                if (defaultSchema == null) {
520
                        String sql = "Select current_schema()";
521
                        ResultSet rs = null;
522
                        Statement st = null;
523
                        String schema = null;
524
                        try {
525
                                st = conn.createStatement();
526
                                try {
527
                                        rs = st.executeQuery(sql);
528
                                } catch (java.sql.SQLException e) {
529
                                        throw new JDBCExecuteSQLException(sql, e);
530
                                }
531
                                rs.next();
532
                                schema = rs.getString(1);
533
                        } catch (java.sql.SQLException e) {
534
                                throw new JDBCSQLException(e);
535
                        } finally {
536
                                try {rs.close();} catch (Exception e) {logger.error("Exception clossing resulset", e);};
537
                                try {st.close();} catch (Exception e) {logger.error("Exception clossing statement", e);};
538
                                rs = null;
539
                                st = null;
540
                        }
541
                        defaultSchema = schema;
542
                }
543

    
544
                return defaultSchema;
545
        }
546

    
547
        public Envelope getFullEnvelopeOfField(
548
                        PostgreSQLStoreParameters storeParams,
549
                        String geometryAttrName, Envelope limit)
550
                        throws DataException {
551

    
552
                StringBuilder strb = new StringBuilder();
553
                strb.append("Select extent(");
554
                strb.append(geometryAttrName);
555
                strb.append(") from ");
556

    
557
                if (storeParams.getSQL() != null
558
                                && storeParams.getSQL().trim().length() == 0) {
559
                        strb.append('(');
560
                        strb.append(storeParams.getSQL());
561
                        strb.append(") as __tmp__ ");
562
                } else {
563
                        strb.append(storeParams.tableID());
564
                }
565

    
566

    
567
                if (limit != null){
568
                        strb.append(" where  intersects(GeomFromText('");
569
                        strb.append(limit.toString());
570
                        strb.append("')), boundary(");
571
                        strb.append(geometryAttrName);
572
                        strb.append(")) ");
573
                }
574

    
575
                String sql = strb.toString();
576

    
577

    
578
                ResultSet rs = null;
579
                Statement st = null;
580
                String schema = null;
581
                Connection conn = null;
582

    
583
                GeometryManager geoMan = GeometryLocator.getGeometryManager();
584

    
585
                Envelope fullEnvelope = null;
586
                this.open();
587
                this.begin();
588
                try{
589
                        conn = getConnection();
590
                        st = conn.createStatement();
591
                        try {
592
                                rs = st.executeQuery(sql);
593
                        } catch (java.sql.SQLException e) {
594
                                throw new JDBCExecuteSQLException(sql, e);
595
                        }
596
                        if (!rs.next()) {
597
                                return null;
598
                        }
599

    
600
                        PGobject data = (PGobject) rs.getObject(1);
601
                        if (data == null) {
602
                                return null;
603
                        }
604
                        if (data instanceof PGbox3d) {
605
                                PGbox3d box3d = (PGbox3d) data;
606
                                fullEnvelope = geoMan.createEnvelope(SUBTYPES.GEOM3D);
607
                                fullEnvelope.getLowerCorner().setCoordinates(new double[]{
608
                                                box3d.getLLB().x,
609
                                                box3d.getLLB().y, box3d.getLLB().z});
610
                                fullEnvelope.getUpperCorner().setCoordinates(new double[]{box3d.getURT().x,
611
                                                box3d
612
                                                .getURT().y,
613
                                                                box3d.getURT().z });
614

    
615
                        } else {
616
                                PGbox2d box2d = (PGbox2d) data;
617
                                fullEnvelope = geoMan.createEnvelope(SUBTYPES.GEOM2D);
618
                                fullEnvelope.getLowerCorner().setX(box2d.getLLB().x);
619
                                fullEnvelope.getLowerCorner().setY(box2d.getLLB().y);
620
                                fullEnvelope.getUpperCorner().setX(box2d.getURT().x);
621
                                fullEnvelope.getUpperCorner().setY(box2d.getURT().y);
622
                        }
623
                        return fullEnvelope;
624
                } catch (java.sql.SQLException e) {
625
                        throw new JDBCSQLException(e);
626
                } catch (CreateEnvelopeException e) {
627
                        throw new InitializeException(e);
628
                } finally {
629
                        try{ rs.close(); } catch (Exception e){};
630
                        try{ st.close(); } catch (Exception e){};
631
                        try{ conn.close(); } catch (Exception e){};
632
                        rs = null;
633
                        st = null;
634
                        conn = null;
635
                        end();
636
                }
637

    
638

    
639
        }
640

    
641
        public Geometry getGeometry(byte[] buffer)
642
                        throws BaseException {
643
                if (buffer == null) {
644
                        return null;
645
                }
646
                if (fromWKB == null) {
647
                        fromWKB = (FromWKB) GeometryLocator.getGeometryManager()
648
                                        .getGeometryOperation(FromWKB.CODE,
649
                                                        Geometry.TYPES.GEOMETRY, Geometry.SUBTYPES.GEOM2D);
650
                        fromWKBContext = new FromWKBGeometryOperationContext();
651

    
652
                }
653
                Geometry geom;
654
                try {
655
                        fromWKBContext.setData(buffer);
656

    
657
                        geom = (Geometry) fromWKB.invoke(null, fromWKBContext);
658
                } finally {
659
                        fromWKBContext.setData(null);
660
                }
661
                return geom;
662
        }
663

    
664
        /**
665
         * Fill <code>featureType</code> geometry attributes with SRS and ShapeType
666
         * information stored in the table GEOMETRY_COLUMNS
667
         *
668
         * @param conn
669
         * @param rsMetadata
670
         * @param featureType
671
         * @throws ReadException
672
         */
673
        private void loadSRS_and_shapeType(Connection conn,
674
                        ResultSetMetaData rsMetadata, EditableFeatureType featureType,
675
                        String baseSchema, String baseTable)
676
                        throws JDBCException {
677

    
678
                Statement st = null;
679
                ResultSet rs = null;
680
                try {
681
                        // Sacamos la lista de los attributos geometricos
682
                        EditableFeatureAttributeDescriptor attr;
683
                        List geoAttrs = new ArrayList();
684

    
685
                        Iterator iter = featureType.iterator();
686
                        while (iter.hasNext()) {
687
                                attr = (EditableFeatureAttributeDescriptor) iter.next();
688
                                if (attr.getDataType() == DataTypes.GEOMETRY) {
689
                                        geoAttrs.add(attr);
690
                                }
691
                        }
692
                        if (geoAttrs.size() < 1) {
693
                                return;
694
                        }
695

    
696

    
697
                        // preparamos un set con las lista de tablas de origen
698
                        // de los campos
699
                        class TableId {
700
                                public String schema=null;
701
                                public String table=null;
702
                                public String field = null;
703

    
704
                                public void appendToSQL(StringBuilder strb) {
705
                                        if (schema == null || schema.length() == 0) {
706
                                                strb
707
                                                                .append("( F_TABLE_SCHEMA = current_schema() AND F_TABLE_NAME = '");
708
                                        } else {
709
                                                strb.append("( F_TABLE_SCHEMA = '");
710
                                                strb.append(schema);
711
                                                strb.append("' AND F_TABLE_NAME = '");
712
                                        }
713
                                        strb.append(table);
714
                                        strb.append("' AND F_GEOMETRY_COLUMN = '");
715
                                        strb.append(field);
716
                                        strb.append("' )");
717
                                }
718

    
719
                        }
720
                        Comparator cmp = new Comparator(){
721
                                public int compare(Object arg0, Object arg1) {
722
                                        TableId a0 = (TableId) arg0;
723
                                        TableId a1 = (TableId) arg1;
724

    
725
                                        if (!a0.field.equals(a1.field)) {
726
                                                return -1;
727
                                        }
728
                                        if (!a0.table.equals(a1.table)) {
729
                                                return -1;
730
                                        }
731
                                        if (!a0.schema.equals(a1.schema)) {
732
                                                return -1;
733
                                        }
734
                                        return 0;
735
                                }
736
                        };
737
                        TreeSet set = new TreeSet(cmp);
738
                        TableId tableId;
739
                        iter = geoAttrs.iterator();
740
                        int rsIndex;
741
                        while (iter.hasNext()) {
742
                                attr = (EditableFeatureAttributeDescriptor) iter.next();
743
                                tableId = new TableId();
744
                                rsIndex = attr.getIndex() + 1;
745

    
746
                                if (baseSchema == null && baseTable == null) {
747
                                        if (rsMetadata instanceof PGResultSetMetaData) {
748
                                                tableId.schema = ((PGResultSetMetaData) rsMetadata)
749
                                                                .getBaseSchemaName(rsIndex);
750
                                                tableId.table = ((PGResultSetMetaData) rsMetadata)
751
                                                                .getBaseTableName(rsIndex);
752
                                                tableId.field = ((PGResultSetMetaData) rsMetadata)
753
                                                                .getBaseColumnName(rsIndex);
754

    
755
                                        } else {
756
                                                tableId.schema = rsMetadata.getSchemaName(rsIndex);
757
                                                tableId.table = rsMetadata.getTableName(rsIndex);
758
                                                tableId.field = rsMetadata.getColumnName(rsIndex);
759
                                        }
760
                                } else {
761
                                        tableId.schema = baseSchema;
762
                                        tableId.table = baseTable;
763
                                        tableId.field = rsMetadata.getColumnName(rsIndex);
764
                                }
765
                                if (tableId.table == null || tableId.table.length() == 0) {
766
                                        // Si no tiene tabla origen (viene de algun calculo por ej.)
767
                                        // lo saltamos ya que no estara en la tabla GEOMETRY_COLUMNS
768
                                        continue;
769
                                }
770
                                set.add(tableId);
771
                        }
772

    
773
                        if (set.size() == 0) {
774
                                return;
775
                        }
776

    
777
                        // Preparamos una sql para que nos saque el resultado
778
                        StringBuilder strb = new StringBuilder();
779
                        strb.append("Select geometry_columns.*,auth_name || ':' || auth_srid as SRSID ");
780
                        strb.append("from geometry_columns left join spatial_ref_sys on ");
781
                        strb.append("geometry_columns.srid = spatial_ref_sys.srid WHERE ");
782
                        iter = set.iterator();
783
                        for (int i=0;i<set.size()-1;i++) {
784
                                tableId = (TableId) iter.next();
785
                                tableId.appendToSQL(strb);
786
                                strb.append(" OR ");
787
                        }
788
                        tableId = (TableId) iter.next();
789
                        tableId.appendToSQL(strb);
790
                        String sql = strb.toString();
791

    
792

    
793
                        st = conn.createStatement();
794
                        try {
795
                                rs = st.executeQuery(sql);
796
                        } catch (SQLException e) {
797
                                throw new JDBCExecuteSQLException(sql, e);
798
                        }
799
                        String srsID;
800
                        int pgSrid;
801
                        int geometryType;
802
                        int geometrySubtype;
803
                        String geomTypeStr;
804
                        int dimensions;
805
                        IProjection srs;
806

    
807
                        while (rs.next()){
808
                                srsID = rs.getString("SRSID");
809
                                pgSrid = rs.getInt("SRID");
810
                                geomTypeStr = rs.getString("TYPE").toUpperCase();
811
                                geometryType = Geometry.TYPES.GEOMETRY;
812
                                if (geomTypeStr.startsWith("POINT")) {
813
                                        geometryType = Geometry.TYPES.POINT;
814
                                } else if (geomTypeStr.startsWith("LINESTRING")) {
815
                                        geometryType = Geometry.TYPES.CURVE;
816
                                } else if (geomTypeStr.startsWith("POLYGON")) {
817
                                        geometryType = Geometry.TYPES.SURFACE;
818
                                } else if (geomTypeStr.startsWith("MULTIPOINT")) {
819
                                        geometryType = Geometry.TYPES.MULTIPOINT;
820
                                } else if (geomTypeStr.startsWith("MULTILINESTRING")) {
821
                                        geometryType = Geometry.TYPES.MULTICURVE;
822
                                } else if (geomTypeStr.startsWith("MULTIPOLYGON")) {
823
                                        geometryType = Geometry.TYPES.MULTISURFACE;
824
                                }
825
                                dimensions = rs.getInt("coord_dimension");
826
                                geometrySubtype = Geometry.SUBTYPES.GEOM2D;
827
                                if (dimensions > 2) {
828
                                        if (dimensions == 3) {
829
                                                if (geomTypeStr.endsWith("M")) {
830
                                                        geometrySubtype = Geometry.SUBTYPES.GEOM2DM;
831
                                                } else {
832
                                                        geometrySubtype = Geometry.SUBTYPES.GEOM3D;
833
                                                }
834

    
835
                                        } else {
836
                                                geometrySubtype = Geometry.SUBTYPES.GEOM3DM;
837
                                        }
838
                                }
839
                                addToPgSRToSRSID(pgSrid, srsID);
840

    
841

    
842
                                iter = geoAttrs.iterator();
843
                                while (iter.hasNext()) {
844
                                        attr = (EditableFeatureAttributeDescriptor) iter.next();
845
                                        rsIndex = attr.getIndex() + 1;
846
                                        if (!rsMetadata.getColumnName(rsIndex).equals(
847
                                                        rs.getString("f_geometry_column"))) {
848
                                                continue;
849
                                        }
850

    
851
                                        if (baseSchema == null && baseTable == null) {
852

    
853
                                                if (rsMetadata instanceof PGResultSetMetaData) {
854
                                                        if (!((PGResultSetMetaData) rsMetadata)
855
                                                                        .getBaseTableName(rsIndex).equals(
856
                                                                                        rs.getString("f_table_name"))) {
857
                                                                continue;
858
                                                        }
859
                                                        String curSchema = rs.getString("f_table_schema");
860
                                                        String metaSchema = ((PGResultSetMetaData) rsMetadata)
861
                                                                        .getBaseSchemaName(rsIndex);
862
                                                        if (!metaSchema.equals(curSchema)) {
863
                                                                if (metaSchema.length() == 0
864
                                                                                && metaSchema == getDefaultSchema(conn)) {
865
                                                                } else {
866
                                                                        continue;
867
                                                                }
868
                                                        }
869

    
870
                                                } else {
871

    
872
                                                        if (!rsMetadata.getTableName(rsIndex).equals(
873
                                                                        rs.getString("f_table_name"))) {
874
                                                                continue;
875
                                                        }
876
                                                        String curSchema = rs.getString("f_table_schema");
877
                                                        String metaSchema = rsMetadata
878
                                                                        .getSchemaName(rsIndex);
879
                                                        if (!metaSchema.equals(curSchema)) {
880
                                                                if (metaSchema.length() == 0
881
                                                                                && metaSchema == getDefaultSchema(conn)) {
882
                                                                } else {
883
                                                                        continue;
884
                                                                }
885
                                                        }
886
                                                }
887
                                        }
888
                                        attr.setGeometryType(geometryType);
889
                                        attr.setGeometrySubType(geometrySubtype);
890
                                        if (srsID != null && srsID.length() > 0) {
891
                                                attr.setSRS(CRSFactory.getCRS(srsID));
892
                                        }
893
                                        iter.remove();
894
                                }
895
                                iter = geoAttrs.iterator();
896
                                while (iter.hasNext()) {
897
                                        attr = (EditableFeatureAttributeDescriptor) iter.next();
898
                                        attr.setSRS(null);
899
                                        attr.setGeometryType(Geometry.TYPES.GEOMETRY);
900

    
901
                                }
902
                        }
903

    
904
                } catch (java.sql.SQLException e) {
905
                        throw new JDBCSQLException(e);
906
                } finally {
907
                        try {rs.close();} catch (Exception e) {        };
908
                        try {st.close();} catch (Exception e) {        };
909
                }
910

    
911
        }
912

    
913
        public String escapeFieldName(String field) {
914
                if (field.matches("[a-z][a-z0-9_]*")) {
915
                        return field;
916
                }
917
                return "\"" + field + "\"";
918

    
919
        }
920

    
921
        public Object dalValueToJDBC(
922
                        FeatureAttributeDescriptor attributeDescriptor, Object object)
923
                                throws WriteException {
924
                if (object == null) {
925
                        return null;
926
                }
927

    
928
                if (attributeDescriptor.getDataType() != DataTypes.GEOMETRY) {
929
                        return object;
930
                }
931
                try {
932
                        Geometry geom = (Geometry) object;
933

    
934
                        toWKBContext.setSrID(-1);
935
                        IProjection srs = attributeDescriptor.getSRS();
936
                        if (srs != null) {
937
                                toWKBContext.setSrID(getPostgisSRID(srs));
938
                        }
939

    
940
                        // TODO optimize this building PGGeometry by code
941
                        byte[] wkb = (byte[]) geom
942
                                        .invokeOperation(ToWKB.CODE, toWKBContext);
943
                        if (wkb == null) {
944
                                // FIXME excpetion
945
                                throw new IllegalArgumentException();
946
                        }
947

    
948
                        return wkb;
949
                } catch (Exception e) {
950
                        throw new WriteException(this.name, e);
951
                }
952
        }
953

    
954
        /**
955
         * Contains an action to execute with
956
         * {@link PostgreSQLHelper#doConnectionAction(ConnectionAction)}
957
         *
958
         * @see {@link PostgreSQLHelper#doConnectionAction(ConnectionAction)},
959
         *      {@link TransactionalAction}
960
         */
961
        public interface ConnectionAction {
962
                Object action(Connection conn) throws DataException;
963
        }
964

    
965
        /**
966
         * Contains an action to execute with
967
         * {@link PostgreSQLHelper#doConnectionAction(ConnectionAction)} inside of a
968
         * DB transaction.
969
         *
970
         * @see {@link PostgreSQLHelper#doConnectionAction(ConnectionAction)},
971
         *      {@link ConnectionAction}
972
         */
973
        public interface TransactionalAction extends ConnectionAction {
974

    
975
                /**
976
                 * If before run <code>action</code> there's a transaction open and this
977
                 * methos returns <code>false</code> an exception will be throwed
978
                 *
979
                 * @return
980
                 */
981
                boolean continueTransactionAllowed();
982

    
983
        }
984

    
985
        /**
986
         * Executes an atomic action that uses an DB Connection.<br>
987
         *
988
         * This methos prepares a connection and close it at the end of execution of
989
         * action.<br>
990
         *
991
         * if <code>action</code> is an instance of {@link TransactionalAction} the
992
         * action will be execute inside of a DB transaction.
993
         *
994
         *
995
         * @param action
996
         * @throws Exception
997
         */
998
        public Object doConnectionAction(ConnectionAction action)
999
                        throws Exception {
1000
                Object result = null;
1001
                Connection conn = null;
1002
                boolean beginTrans = false;
1003
                this.open();
1004
                this.begin();
1005
                try {
1006

    
1007

    
1008
                        conn = this.getConnection();
1009
                        if (action instanceof TransactionalAction){
1010
                                // XXX OJO esta condicion NO ES FIABLE
1011
                                if (!conn.getAutoCommit()) {
1012
                                        if (!((TransactionalAction) action)
1013
                                                        .continueTransactionAllowed()) {
1014
                                                // FIXME exception
1015
                                                throw new Exception();
1016
                                        }
1017
                                }
1018
                                try {
1019
                                        conn.setAutoCommit(false);
1020
                                } catch (SQLException e) {
1021
                                        throw new JDBCSQLException(e);
1022
                                }
1023
                                beginTrans = true;
1024
                        }
1025

    
1026
                        result = action.action(conn);
1027

    
1028
                        if (beginTrans) {
1029
                                try {
1030
                                        conn.commit();
1031
                                } catch (SQLException e) {
1032
                                        throw new JDBCTransactionCommitException(e);
1033
                                }
1034
                        }
1035

    
1036
                        return result;
1037

    
1038

    
1039
                } catch (Exception e) {
1040

    
1041
                        if (beginTrans) {
1042
                                try {
1043
                                        conn.rollback();
1044
                                } catch (Exception e1) {
1045
                                        throw new JDBCTransactionRollbackException(e1, e);
1046
                                }
1047
                        }
1048
                        throw e;
1049

    
1050
                } finally {
1051
                        try {
1052
                                conn.close();
1053
                        } catch (Exception e1) {
1054
                                logger.error("Exception on close connection", e1);
1055
                        }
1056
                        this.end();
1057
                }
1058

    
1059
        }
1060

    
1061
        public String getSqlColumnTypeDescription(FeatureAttributeDescriptor attr) {
1062
                switch (attr.getDataType()) {
1063
                case DataTypes.STRING:
1064
                        if (attr.getSize() < 1 || attr.getSize() > 255) {
1065
                                return "text";
1066
                        } else {
1067
                                return "varchar(" + attr.getSize() + ")";
1068
                        }
1069
                case DataTypes.BOOLEAN:
1070
                        return "bool";
1071

    
1072
                case DataTypes.BYTE:
1073
                        return "smallint";
1074

    
1075
                case DataTypes.DATE:
1076
                        return "date";
1077

    
1078
                case DataTypes.TIMESTAMP:
1079
                        return "timestamp";
1080

    
1081
                case DataTypes.TIME:
1082
                        return "time";
1083

    
1084
                case DataTypes.DOUBLE:
1085
                        if (attr.getPrecision() > 0) {
1086
                                return "double precision" + attr.getPrecision();
1087
                        } else {
1088
                                return "double precision";
1089
                        }
1090
                case DataTypes.FLOAT:
1091
                        return "real";
1092

    
1093
                case DataTypes.GEOMETRY:
1094
                        return "geometry";
1095

    
1096
                case DataTypes.INT:
1097
                        if (attr.isAutomatic()) {
1098
                                return "serial";
1099
                        } else {
1100
                                return "integer";
1101
                        }
1102
                case DataTypes.LONG:
1103
                        if (attr.isAutomatic()) {
1104
                                return "bigserial";
1105
                        } else {
1106
                                return "bigint";
1107
                        }
1108

    
1109
                default:
1110
                        throw new UnsupportedDataTypeException(attr.getDataTypeName(), attr
1111
                                        .getDataType());
1112
                }
1113
        }
1114

    
1115
        public void addSqlFiledDescription(FeatureAttributeDescriptor attr,
1116
                        StringBuilder strb) {
1117

    
1118
                /**
1119
                 * column_name data_type [ DEFAULT default_expr ] [ column_constraint [
1120
                 * ... ] ]
1121
                 *
1122
                 * where column_constraint is:
1123
                 *
1124
                 * [ CONSTRAINT constraint_name ] { NOT NULL | NULL | UNIQUE | PRIMARY
1125
                 * KEY | CHECK (expression) | REFERENCES reftable [ ( refcolumn ) ] [
1126
                 * MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE action ] [ ON
1127
                 * UPDATE action ] } [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY
1128
                 * DEFERRED | INITIALLY IMMEDIATE ]
1129
                 */
1130

    
1131
                // name
1132
                strb.append(attr.getName());
1133
                strb.append(" ");
1134

    
1135
                // Type
1136
                strb.append(this.getSqlColumnTypeDescription(attr));
1137
                strb.append(" ");
1138

    
1139
                // Null
1140
                if (attr.allowNull()) {
1141
                        strb.append("NOT NULL ");
1142
                } else {
1143
                        strb.append("NULL ");
1144
                }
1145

    
1146
                // Primery key
1147
                if (attr.isPrimaryKey()) {
1148
                        strb.append("PRIMARY KEY ");
1149
                }
1150
        }
1151

    
1152
        public int getPostgisGeomDimensions(int geometrySubType) {
1153
                switch (geometrySubType) {
1154
                case Geometry.SUBTYPES.GEOM2D:
1155
                        return 2;
1156
                case Geometry.SUBTYPES.GEOM2DM:
1157
                case Geometry.SUBTYPES.GEOM3D:
1158
                        return 3;
1159

    
1160
                case Geometry.SUBTYPES.GEOM3DM:
1161
                        return 4;
1162
                default:
1163
                        throw new UnsupportedDataTypeException(
1164
                                        DataTypes.TYPE_NAMES[DataTypes.GEOMETRY],
1165
                                        DataTypes.GEOMETRY);
1166
                }
1167
        }
1168

    
1169
        public String getPostgisGeomType(int geometryType, int geometrySubType) {
1170
                String pgGeomType;
1171
                switch (geometryType) {
1172
                case Geometry.TYPES.GEOMETRY:
1173
                        pgGeomType = "GEOMETRY";
1174
                        break;
1175
                case Geometry.TYPES.POINT:
1176
                        pgGeomType = "POINT";
1177
                        break;
1178
                case Geometry.TYPES.CURVE:
1179
                        pgGeomType = "LINESTRING";
1180
                        break;
1181
                case Geometry.TYPES.SURFACE:
1182
                        pgGeomType = "POLYGON";
1183
                        break;
1184
                case Geometry.TYPES.MULTIPOINT:
1185
                        pgGeomType = "MULTIPOINT";
1186
                        break;
1187
                case Geometry.TYPES.MULTICURVE:
1188
                        pgGeomType = "MULTILINESTRING";
1189
                        break;
1190
                case Geometry.TYPES.MULTISURFACE:
1191
                        pgGeomType = "MULTIPOLYGON";
1192
                        break;
1193
                default:
1194
                        throw new UnsupportedGeometryException(geometryType,
1195
                                        geometrySubType);
1196
                }
1197
                if (geometrySubType == Geometry.SUBTYPES.GEOM2DM
1198
                                || geometrySubType == Geometry.SUBTYPES.GEOM3DM) {
1199
                        pgGeomType = pgGeomType + "M";
1200
                } else if (geometrySubType == Geometry.SUBTYPES.GEOM2DZ) {
1201
                        throw new UnsupportedGeometryException(geometryType,
1202
                                        geometrySubType);
1203
                }
1204
                return pgGeomType;
1205
        }
1206

    
1207
        public int getPostgisSRID(String srs) {
1208
                if (srs != null) {
1209
                        Integer pgSRID = (Integer) srsID2pgSR.get(srs);
1210
                        if (pgSRID != null) {
1211
                                return pgSRID.intValue();
1212
                        }
1213

    
1214
                        return searchpgSRID(srs);
1215

    
1216
                }
1217
                return -1;
1218
        }
1219

    
1220

    
1221
        public int getPostgisSRID(IProjection srs) {
1222
                if (srs != null) {
1223
                        Integer pgSRID = (Integer) srsID2pgSR.get(srs.getAbrev());
1224
                        if (pgSRID != null) {
1225
                                return pgSRID.intValue();
1226
                        }
1227

    
1228
                        return searchpgSRID(srs);
1229

    
1230
                }
1231
                return -1;
1232
        }
1233

    
1234
        private int searchpgSRID(final IProjection srs) {
1235
                if (srs == null) {
1236
                        return -1;
1237
                }
1238
                return searchpgSRID(srs.getAbrev());
1239
        }
1240

    
1241
        private int searchpgSRID(final String srsID) {
1242
                if (srsID == null) {
1243
                        return -1;
1244
                }
1245

    
1246
                ConnectionAction action = new ConnectionAction(){
1247

    
1248
                        public Object action(Connection conn) throws DataException {
1249
                                // select srid from spatial_ref_sys where auth_name = 'EPSG' and
1250
                                // auth_srid = 23030
1251
                                String[] abrev = srsID.split(":");
1252
                                StringBuilder sqlb = new StringBuilder();
1253
                                sqlb.append("select srid from spatial_ref_sys where ");
1254
                                if (abrev.length > 1) {
1255
                                        sqlb.append("auth_name = ? and ");
1256
                                }
1257
                                sqlb.append("auth_srid = ?");
1258

    
1259
                                String sql = sqlb.toString();
1260
                                PreparedStatement st;
1261
                                try {
1262
                                        st = conn.prepareStatement(sql);
1263
                                } catch (SQLException e){
1264
                                        throw new JDBCPreparingSQLException(sql,e);
1265
                                }
1266
                                ResultSet rs = null;
1267
                                try{
1268
                                        int i=0;
1269
                                        if (abrev.length > 1){
1270
                                                st.setString(i+1, abrev[i]);
1271
                                                i++;
1272
                                        }
1273
                                        st.setInt(i + 1, Integer.parseInt(abrev[i]));
1274

    
1275
                                        try{
1276
                                                rs = st.executeQuery();
1277
                                        } catch (SQLException e){
1278
                                                throw new JDBCExecutePreparedSQLException(sql, abrev, e);
1279
                                        }
1280

    
1281
                                        if (!rs.next()) {
1282
                                                return null;
1283
                                        }
1284

    
1285
                                        return new Integer(rs.getInt(1));
1286

    
1287
                                } catch (SQLException e){
1288
                                        throw new JDBCSQLException(e);
1289
                                } finally{
1290
                                        try {rs.close(); } catch (Exception e) {};
1291
                                        try {st.close(); } catch (Exception e) {};
1292
                                }
1293

    
1294
                        }
1295

    
1296
                };
1297

    
1298
                Integer pgSRSID = null;
1299
                try {
1300
                        pgSRSID = (Integer) doConnectionAction(action);
1301
                } catch (Exception e) {
1302
                        logger.error("Excetion searching pgSRS", e);
1303
                        return -1;
1304
                }
1305

    
1306
                if (pgSRSID != null) {
1307
                        addToPgSRToSRSID(pgSRSID.intValue(), srsID);
1308
                        return pgSRSID.intValue();
1309
                }
1310
                return -1;
1311

    
1312
        }
1313

    
1314
        private void addToPgSRToSRSID(int pgSRID, String srsId) {
1315
                if (pgSRID < 0 || srsId == null || srsId.length() == 0) {
1316
                        return;
1317
                }
1318
                Integer pgSRIDInteger = new Integer(pgSRID);
1319
                pgSR2SRSID.put(pgSRIDInteger, srsId);
1320
                srsID2pgSR.put(srsId, pgSRIDInteger);
1321
        }
1322

    
1323
        public boolean isOpen() {
1324
                return isOpen;
1325
        }
1326

    
1327
        public String[] getSqlGeometyFieldAdd(FeatureAttributeDescriptor attr,
1328
                        String table, String schema) {
1329
                // SELECT AddGeometryColumn({schema}, {table}, {field}, {srid}(int),
1330
                // {geomType}(Str), {dimensions}(int))
1331

    
1332
                // gemoType:
1333
                /*
1334
                 * POINT, LINESTRING, POLYGON, MULTIPOINT, MULTILINESTRING,
1335
                 * MULTIPOLYGON, GEOMETRYCOLLECTION POINTM, LINESTRINGM, POLYGONM,
1336
                 * MULTIPOINTM, MULTILINESTRINGM, MULTIPOLYGONM, GEOMETRYCOLLECTIONM
1337
                 */
1338

    
1339
                List sqls = new ArrayList();
1340

    
1341
                StringBuilder strb = new StringBuilder();
1342
                strb.append("SELECT AddGeometryColumn('");
1343
                if (schema != null && schema.length() > 0) {
1344
                        strb.append(schema);
1345
                        strb.append("', '");
1346
                }
1347
                strb.append(table);
1348
                strb.append("', '");
1349
                strb.append(attr.getName());
1350
                strb.append("', ");
1351
                // strb.append("-1");
1352
                 strb.append(getPostgisSRID(attr.getSRS()));
1353
                strb.append(", '");
1354
                strb.append(getPostgisGeomType(attr.getGeometryType(), attr
1355
                                .getGeometrySubType()));
1356
                strb.append("', ");
1357
                strb.append(getPostgisGeomDimensions(attr.getGeometrySubType()));
1358
                strb.append(")");
1359

    
1360

    
1361
                sqls.add(strb.toString());
1362

    
1363
                /*ALTER TABLE muni10000_peq_test DROP CONSTRAINT enforce_srid_the_geom;*/
1364
                /*
1365
                strb = new StringBuilder();
1366
                strb.append("Alter table ");                
1367
                if (schema != null && schema.length() > 0) {
1368
                        strb.append(schema);
1369
                        strb.append(".");
1370
                }
1371
                strb.append("f_table_name = '");
1372
                strb.append(table);
1373
                strb.append("' AND f_geometry_column = '");
1374
                strb.append(attr.getName());
1375
                strb.append("' AND srid = -1");
1376

1377

1378
                sqls.add(strb.toString());
1379
                */
1380
                return (String[]) sqls.toArray(new String[sqls.size()]);
1381
        }
1382

    
1383
        public String getSqlFieldName(FeatureAttributeDescriptor attribute) {
1384
                if (attribute.getDataType() == DataTypes.GEOMETRY) {
1385
                        return "asBinary(" + escapeFieldName(attribute.getName()) + ")";
1386
                }
1387
                return escapeFieldName(attribute.getName());
1388
        }
1389

    
1390
        public FeatureAttributeDescriptor[] getPkFromFType(FeatureType fType) {
1391
                List pk = new ArrayList();
1392
                Iterator iter = fType.iterator();
1393
                FeatureAttributeDescriptor attr;
1394
                while (iter.hasNext()) {
1395
                        attr = (FeatureAttributeDescriptor) iter.next();
1396
                        if (attr.isPrimaryKey()) {
1397
                                pk.add(attr);
1398
                        }
1399
                }
1400
                return (FeatureAttributeDescriptor[]) pk
1401
                                .toArray(new FeatureAttributeDescriptor[0]);
1402
        }
1403
}