Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.db / org.gvsig.fmap.dal.db.h2 / src / main / java / org / gvsig / fmap / dal / store / h2 / H2SpatialHelper.java @ 43377

History | View | Annotate | Download (13.8 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2016 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 3
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
package org.gvsig.fmap.dal.store.h2;
23

    
24
import java.sql.Connection;
25
import java.sql.SQLException;
26
import java.text.MessageFormat;
27
import org.apache.commons.dbcp.BasicDataSource;
28
import org.apache.commons.io.FilenameUtils;
29
import org.apache.commons.lang3.StringUtils;
30
import org.cresques.cts.IProjection;
31
import org.gvsig.fmap.dal.SQLBuilder;
32
import org.gvsig.fmap.dal.resource.exception.AccessResourceException;
33
import org.gvsig.fmap.dal.store.h2.operations.H2SpatialOperationsFactory;
34
import org.gvsig.fmap.dal.store.jdbc.JDBCConnectionParameters;
35
import org.gvsig.fmap.dal.store.jdbc.JDBCNewStoreParameters;
36
import org.gvsig.fmap.dal.store.jdbc.JDBCServerExplorerParameters;
37
import org.gvsig.fmap.dal.store.jdbc.JDBCStoreParameters;
38
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCDriverClassNotFoundException;
39
import org.gvsig.fmap.dal.store.jdbc2.OperationsFactory;
40
import org.gvsig.fmap.dal.store.jdbc2.spi.JDBCHelperBase;
41
import org.gvsig.fmap.dal.store.jdbc2.spi.JDBCSQLBuilderBase;
42
import org.gvsig.fmap.dal.store.jdbc2.spi.JDBCSRSsBase;
43
import org.gvsig.fmap.geom.Geometry;
44
import org.gvsig.fmap.geom.aggregate.MultiLine;
45
import org.gvsig.fmap.geom.aggregate.MultiPoint;
46
import org.gvsig.fmap.geom.aggregate.MultiPolygon;
47
import org.gvsig.fmap.geom.exception.CreateGeometryException;
48
import org.gvsig.fmap.geom.primitive.Primitive;
49
import org.gvsig.fmap.geom.type.GeometryType;
50
import org.h2gis.ext.H2GISExtension;
51
import org.slf4j.Logger;
52
import org.slf4j.LoggerFactory;
53

    
54
public class H2SpatialHelper extends JDBCHelperBase {
55

    
56
    static final Logger logger = LoggerFactory.getLogger(H2SpatialHelper.class);
57

    
58
    public static final String H2SpatialJDBCDriver = "org.h2.Driver";
59

    
60
    public static String getConnectionURL(H2SpatialConnectionParameters params) {
61
        String connectionURL;
62
        if( StringUtils.isEmpty(params.getHost()) ) {
63
            // Asumimos que es una conexion directa sobre el filesystem
64
            String dbname = params.getFile().getAbsolutePath().replace("\\","/");
65
            if( StringUtils.equalsIgnoreCase(FilenameUtils.getExtension(params.getFile().getName()),"zip") ) {
66
                connectionURL =  MessageFormat.format(
67
                    "jdbc:h2:zip:{0}!/{1};MODE=PostgreSQL",
68
                    dbname,
69
                    params.getDBName()
70
                );
71
            } else {
72
                if( dbname.endsWith(".mv.db") ) {
73
                    dbname = dbname.substring(0, dbname.length()-6);
74
                }
75
                connectionURL =  MessageFormat.format(
76
                    "jdbc:h2:file:{0};MODE=PostgreSQL",
77
                    dbname
78
                );
79
            }
80
        } else if( params.getPort() == null ) {
81
            connectionURL =  MessageFormat.format(
82
                "jdbc:h2:tcp://{0}/{1};MODE=PostgreSQL",
83
                params.getHost(),
84
                params.getDBName()
85
            );            
86
        } else {
87
            connectionURL =  MessageFormat.format(
88
                "jdbc:h2:tcp://{0}:{1,number,#######}/{2};MODE=PostgreSQL",
89
                params.getHost(),
90
                params.getPort().intValue(),
91
                params.getDBName()
92
            );
93
        }
94
        logger.debug("connectionURL: {}", connectionURL);
95
        return connectionURL;
96
    }
97

    
98
    private static class ConnectionProvider {
99

    
100
        private static boolean needRegisterDriver = true;
101

    
102
        private BasicDataSource dataSource = null;
103

    
104
        private final H2SpatialConnectionParameters connectionParameters;
105

    
106
        public ConnectionProvider(H2SpatialConnectionParameters connectionParameters) {
107
            this.connectionParameters = connectionParameters;
108
        }
109

    
110
        public Connection getConnection() throws SQLException {
111
            if (this.dataSource == null) {
112
                this.dataSource = this.createDataSource();               
113
            }
114
            Connection conn = this.dataSource.getConnection();
115
            try {
116
                conn.createStatement().execute("SELECT TOP 1 SRID FROM SPATIAL_REF_SYS");
117
            } catch(SQLException ex) {
118
                H2GISExtension.load(conn);
119
            }
120
            return conn;
121
        }
122

    
123
        private BasicDataSource createDataSource() throws SQLException {
124
            if (!this.isRegistered()) {
125
                this.registerDriver();
126
            }
127
            H2SpatialConnectionParameters params = connectionParameters;
128

    
129
            BasicDataSource ds = new BasicDataSource();
130
            ds.setDriverClassName(params.getJDBCDriverClassName());
131
            if( !StringUtils.isEmpty(params.getUser()) ) {
132
                ds.setUsername(params.getUser());
133
            }
134
            if( !StringUtils.isEmpty(params.getPassword()) ) {
135
                ds.setPassword(params.getPassword());
136
            }
137
            ds.setUrl(params.getUrl());
138

    
139
            ds.setMaxWait(60L * 1000);
140
            return ds;
141
        }
142

    
143
        private boolean isRegistered() {
144
            return needRegisterDriver;
145
        }
146

    
147
        public void registerDriver() throws SQLException {
148
            String className = this.connectionParameters.getJDBCDriverClassName();
149
            if (className == null) {
150
                return;
151
            }
152
            try {
153
                Class theClass = Class.forName(className);
154
                if (theClass == null) {
155
                    throw new JDBCDriverClassNotFoundException(H2SpatialLibrary.NAME, className);
156
                }
157
            } catch (Exception e) {
158
                throw new SQLException("Can't register JDBC driver '" + className + "'.", e);
159
            }
160
            needRegisterDriver = false;
161
        }
162

    
163
    }
164

    
165
//    private static class ConnectionProvider {
166
//
167
//        private static boolean needRegisterDriver = true;
168
//
169
//
170
//        private final H2SpatialConnectionParameters connectionParameters;
171
//
172
//        public ConnectionProvider(H2SpatialConnectionParameters connectionParameters) {
173
//            this.connectionParameters = connectionParameters;
174
//        }
175
//
176
//        public Connection getConnection() throws SQLException {
177
//            if (!this.isRegistered()) {
178
//                this.registerDriver();
179
//            }
180
//            Connection conn;
181
//            if( !StringUtils.isEmpty(connectionParameters.getUser()) ) {
182
//                conn = DriverManager.getConnection(
183
//                    connectionParameters.getUrl(),
184
//                    connectionParameters.getUser(),
185
//                    connectionParameters.getPassword()
186
//                );
187
//            } else {
188
//                conn = DriverManager.getConnection(connectionParameters.getUrl());
189
//            }
190
//            try {
191
//                conn.createStatement().execute("SELECT TOP 1 SRID FROM SPATIAL_REF_SYS");
192
//            } catch(SQLException ex) {
193
//                H2GISExtension.load(conn);
194
//            }
195
//            return conn;
196
//        }
197
//
198
//        private boolean isRegistered() {
199
//            return needRegisterDriver;
200
//        }
201
//
202
//        public void registerDriver() throws SQLException {
203
//            String className = this.connectionParameters.getJDBCDriverClassName();
204
//            if (className == null) {
205
//                return;
206
//            }
207
//            try {
208
//                Class theClass = Class.forName(className);
209
//                if (theClass == null) {
210
//                    throw new JDBCDriverClassNotFoundException(H2SpatialLibrary.NAME, className);
211
//                }
212
//            } catch (Exception e) {
213
//                throw new SQLException("Can't register JDBC driver '" + className + "'.", e);
214
//            }
215
//            needRegisterDriver = false;
216
//        }
217
//
218
//    }
219

    
220
    private ConnectionProvider connectionProvider = null;
221
   
222
    public H2SpatialHelper(JDBCConnectionParameters connectionParameters) {
223
        super(connectionParameters);
224
        this.srss = new JDBCSRSsBase(this);
225
    }
226

    
227
    @Override
228
    public synchronized Connection  getConnection() throws AccessResourceException {
229
        try {
230
            if (this.connectionProvider == null) {
231
                this.connectionProvider = new ConnectionProvider(this.getConnectionParameters());
232
            }
233
            Connection connection = this.connectionProvider.getConnection();
234
            logger.debug("getConnection: connection = "+connection.hashCode());
235
            return connection;
236
        } catch (SQLException ex) {
237
            throw new AccessResourceException(H2SpatialLibrary.NAME, ex);
238
        }
239
    }
240

    
241
    @Override
242
    public void closeConnection(Connection connection) {
243
        logger.debug("closeConnection: connection = "+connection.hashCode());
244
        super.closeConnection(connection);
245
    }
246
    
247
    @Override
248
    public H2SpatialConnectionParameters getConnectionParameters() {
249
        return (H2SpatialConnectionParameters) super.getConnectionParameters();
250
    }
251
    
252
    @Override
253
    public String getConnectionURL() {
254
        return getConnectionURL(this.getConnectionParameters());
255
    }
256

    
257
    @Override
258
    protected String getResourceType() {
259
        return H2SpatialLibrary.NAME;
260
    }
261

    
262
    @Override
263
    public String getProviderName() {
264
        return H2SpatialLibrary.NAME;
265
    }
266

    
267
    @Override
268
    public JDBCSQLBuilderBase createSQLBuilder() {
269
        return new H2SpatialSQLBuilder(this);
270
    }
271
    
272
    @Override
273
    public OperationsFactory getOperations() {
274
        if (this.operationsFactory == null) {
275
            this.operationsFactory = new H2SpatialOperationsFactory(this);
276
        }
277
        return operationsFactory;
278
    }
279

    
280
    @Override
281
    public SQLBuilder.GeometrySupportType getGeometrySupportType() {
282
        return SQLBuilder.GeometrySupportType.WKB;
283
    }
284

    
285
    @Override
286
    public boolean hasSpatialFunctions() {
287
        return true;
288
    }
289

    
290
    @Override
291
    public boolean canWriteGeometry(int geometryType, int geometrySubtype) {
292
        return true;
293
    }
294

    
295
    @Override
296
    public String getQuoteForIdentifiers() {
297
        return "\"";
298
    }
299

    
300
    @Override
301
    public boolean allowAutomaticValues() {
302
        return true;
303
    }
304

    
305
    @Override
306
    public boolean supportOffsetInSelect() {
307
        return true;
308
    }
309

    
310
    @Override
311
    public String getQuoteForStrings() {
312
        return "'";
313
    }
314

    
315
    @Override
316
    public int getSRSCode(IProjection crs) {
317
        // TODO: ir a buscarlo a la BBDD a ver donde puede estar
318
        return super.getSRSCode(crs);
319
    }
320
    
321
    @Override
322
    public IProjection getProjectionFromSRSId(int srsid) {
323
        // TODO: ir a buscarlo a la BBDD a ver donde puede estar
324
        return super.getProjectionFromSRSId(srsid);
325
    }
326

    
327
    @Override
328
    public String getSourceId(JDBCStoreParameters parameters) {
329
        return parameters.getDBName() + "." + 
330
               parameters.getSchema()+ "." + 
331
               parameters.getTable();
332
    }
333

    
334
    @Override
335
    public JDBCNewStoreParameters createNewStoreParameters() {
336
        return new H2SpatialNewStoreParameters();
337
    }
338

    
339
    @Override
340
    public JDBCStoreParameters createOpenStoreParameters() {
341
        return new H2SpatialStoreParameters();
342
    }
343

    
344
    @Override
345
    public JDBCServerExplorerParameters createServerExplorerParameters() {
346
        return new H2SpatialExplorerParameters();
347
    }
348

    
349
    public Geometry forceGeometryType(GeometryType geomtype, Geometry geom) throws CreateGeometryException {
350
        switch( geomtype.getType() ) {
351
        case Geometry.TYPES.MULTIPOLYGON:
352
            if( geom.getType()==Geometry.TYPES.POLYGON ) {
353
                MultiPolygon x = getGeometryManager().createMultiPolygon(geomtype.getSubType());
354
                x.addPrimitive((Primitive) geom);
355
                geom = x;
356
            }
357
            break;
358
        case Geometry.TYPES.MULTILINE:
359
            if( geom.getType()==Geometry.TYPES.LINE ) {
360
                MultiLine x = getGeometryManager().createMultiLine(geomtype.getSubType());
361
                x.addPrimitive((Primitive) geom);
362
                geom = x;
363
            }
364
            break;
365
        case Geometry.TYPES.MULTIPOINT:
366
            if( geom.getType()==Geometry.TYPES.POINT ) {
367
                MultiLine x = getGeometryManager().createMultiLine(geomtype.getSubType());
368
                x.addPrimitive((Primitive) geom);
369
                geom = x;
370
            }
371
            break;
372
        case Geometry.TYPES.POLYGON:
373
            if( geom.getType()==Geometry.TYPES.MULTIPOLYGON ) {
374
                MultiPolygon x = (MultiPolygon) geom;
375
                if( x.getPrimitivesNumber()==1 ) {
376
                    geom = x.getPrimitiveAt(0);
377
                }
378
            }
379
            break;
380
        case Geometry.TYPES.LINE:
381
            if( geom.getType()==Geometry.TYPES.MULTILINE ) {
382
                MultiLine x = (MultiLine) geom;
383
                if( x.getPrimitivesNumber()==1 ) {
384
                    geom = x.getPrimitiveAt(0);
385
                }
386
            }
387
            break;
388
        case Geometry.TYPES.POINT:
389
            if( geom.getType()==Geometry.TYPES.MULTIPOINT ) {
390
                MultiPoint x = (MultiPoint) geom;
391
                if( x.getPrimitivesNumber()==1 ) {
392
                    geom = x.getPrimitiveAt(0);
393
                }
394
            }
395
        }
396
        return geom;
397
    }
398
    
399
}