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.mdb / src / main / java / org / gvsig / fmap / dal / store / mdb / MDBHelper.java @ 44951

History | View | Annotate | Download (13.5 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.mdb;
23

    
24
import java.io.File;
25
import java.sql.Connection;
26
import java.sql.SQLException;
27
import java.text.MessageFormat;
28
import org.apache.commons.dbcp.BasicDataSource;
29
import org.apache.commons.io.FilenameUtils;
30
import org.apache.commons.lang3.StringUtils;
31
import org.gvsig.expressionevaluator.GeometryExpressionBuilderHelper.GeometrySupportType;
32
import org.gvsig.fmap.dal.exception.InitializeException;
33
import org.gvsig.fmap.dal.resource.exception.AccessResourceException;
34
import org.gvsig.fmap.dal.spi.DataServerExplorerProviderServices;
35
import org.gvsig.fmap.dal.store.mdb.operations.MDBOperationsFactory;
36
import org.gvsig.fmap.dal.store.jdbc.JDBCConnectionParameters;
37
import org.gvsig.fmap.dal.store.jdbc.JDBCNewStoreParameters;
38
import org.gvsig.fmap.dal.store.jdbc.JDBCServerExplorerParameters;
39
import org.gvsig.fmap.dal.store.jdbc.JDBCStoreParameters;
40
import org.gvsig.fmap.dal.store.jdbc.exception.JDBCDriverClassNotFoundException;
41
import org.gvsig.fmap.dal.store.jdbc2.JDBCServerExplorer;
42
import org.gvsig.fmap.dal.store.jdbc2.OperationsFactory;
43
import org.gvsig.fmap.dal.store.jdbc2.spi.JDBCHelperBase;
44
import org.gvsig.fmap.dal.store.jdbc2.spi.JDBCSQLBuilderBase;
45
import org.gvsig.fmap.dal.store.jdbc2.spi.JDBCServerExplorerBase;
46
import org.gvsig.fmap.dal.store.jdbc2.spi.SRSSolverBase;
47
import org.gvsig.fmap.dal.store.jdbc2.spi.SRSSolverDumb;
48
//import org.h2.tools.Server;
49
//import org.h2gis.ext.H2GISExtension;
50
import org.slf4j.Logger;
51
import org.slf4j.LoggerFactory;
52

    
53
@SuppressWarnings("UseSpecificCatch")
54
public class MDBHelper extends JDBCHelperBase {
55

    
56
    static final Logger LOGGER = LoggerFactory.getLogger(MDBHelper.class);
57

    
58
    public static final String MDB_JDBC_DRIVER = "net.ucanaccess.jdbc.UcanaccessDriver";
59

    
60
    public static String getConnectionURL(MDBConnectionParameters params) {
61
        String connectionURL;
62
        String dbfilename = params.getFile().getAbsolutePath().replace("\\","/");
63
//        if( dbfilename!=null && dbfilename.endsWith(".mdb") ) {
64
//            dbfilename = dbfilename.substring(0, dbfilename.length()-3);
65
//        }
66
        StringBuilder commonParameters = new StringBuilder();
67
//        commonParameters.append(";MODE=PostgreSQL");
68
//        commonParameters.append(";SCHEMA=PUBLIC");
69
        
70
//        Integer LOCK_TIMEOUT = (Integer) params.getDynValue("LOCK_TIMEOUT");
71
//        if( LOCK_TIMEOUT!=null ) {
72
//            commonParameters.append(";LOCK_TIMEOUT=").append(LOCK_TIMEOUT);
73
//        }
74
//        Integer MULTI_THREADED = (Integer) params.getDynValue("MULTI_THREADED");
75
//        if( MULTI_THREADED!=null ) {
76
//            commonParameters.append(";MULTI_THREADED=").append(MULTI_THREADED);
77
//        }
78
//        Integer CHACHE_SIZE = (Integer) params.getDynValue("CHACHE_SIZE");
79
//        if( LOCK_TIMEOUT!=null ) {
80
//            commonParameters.append(";CHACHE_SIZE=").append(CHACHE_SIZE);
81
//        }
82
//        Integer LOG = (Integer) params.getDynValue("LOG");
83
//        if( LOCK_TIMEOUT!=null ) {
84
//            commonParameters.append(";LOG=").append(LOG);
85
//        }
86
//        Integer LOCK_MODE = (Integer) params.getDynValue("LOCK_MODE");
87
//        if( LOCK_TIMEOUT!=null ) {
88
//            commonParameters.append(";LOCK_MODE=").append(LOCK_MODE);
89
//        }
90
        if (!params.getFile().exists()) {
91
            commonParameters.append("newdatabaseversion=V2010;");
92
        }
93
        commonParameters.append("showSchema=true;");
94
        
95
        // http://ucanaccess.sourceforge.net/site.html#examples
96
        connectionURL =  MessageFormat.format(                
97
                "jdbc:ucanaccess://{0};"+commonParameters.toString(),
98
                dbfilename
99
        );
100
        
101
        LOGGER.debug("connectionURL: {}", connectionURL);
102
        return connectionURL;
103
    }
104

    
105
    public static class ConnectionProvider {
106

    
107
        private static boolean needRegisterDriver = true;
108

    
109
        private BasicDataSource dataSource = null;
110

    
111
        private final MDBConnectionParameters connectionParameters;
112

    
113
//        private static Server server = null;
114
        private static String server = null;
115
        private static boolean startServer = true;
116

    
117
        public ConnectionProvider(MDBConnectionParameters connectionParameters) {
118
            this.connectionParameters = connectionParameters;
119
        }
120
        
121
        public static void stopServer() {
122
          try {
123
//            server.shutdown();
124
          } catch(Throwable th) {
125
            
126
          }
127
          try {
128
//            server.stop();
129
          } catch(Throwable th) {
130
            
131
          }
132
//          server = null;
133
          startServer = true;
134
          LOGGER.info("MDB Server stopped" );
135
        }
136
        
137
        private void startServer() {
138
        
139
            if( startServer && server == null ) {
140
                String port = "9123";
141
//                Server theServer;
142
                String s = System.getProperty("MDBPort");
143
                if( s!=null ) {
144
                    try {
145
                        int n = Integer.parseInt(s);
146
                        port = String.valueOf(n);
147
                    } catch(Throwable th) {
148
                        // Ignore port number, use default.
149
                    }
150
                }
151
                if( System.getProperty("MDBAllowOthers")!=null ) {
152
//                    theServer = Server.createTcpServer("-tcpPort", port, "-tcpAllowOthers", "-ifExists");
153
                } else {
154
//                    theServer = Server.createTcpServer("-tcpPort", port, "-ifExists");
155
                }
156
//                theServer.start();
157
//                server = theServer;
158
                LOGGER.info("MDB Server started" );
159
//                LOGGER.info("  port  :"+ server.getPort());
160
//                LOGGER.info("  URL  :"+ server.getURL());
161
//                LOGGER.info("  status:"+ server.getStatus());
162
                // Tanto si consigue lanzar el server como si no, no lo vuelve a intentar
163
                startServer = false;
164
            }
165

    
166
        }
167

    
168
        @Override
169
        public String toString() {
170
            StringBuilder builder = new StringBuilder();
171
            builder.append(" url=").append(connectionParameters.getUrl());
172
            builder.append(" driver name=").append(connectionParameters.getJDBCDriverClassName());
173
            builder.append(" user=").append(connectionParameters.getUser());
174
            return builder.toString();
175
        }
176
        
177
        public Connection getConnection() throws SQLException {
178
            File f = this.connectionParameters.getFile();
179
            boolean newdb = f!=null && !f.exists();
180
            
181
            if (this.dataSource == null) {
182
                this.dataSource = this.createDataSource();               
183
            }
184
            Connection conn = this.dataSource.getConnection();
185
////            try {
186
//////                conn.createStatement().execute("SELECT TOP 1 SRID FROM SPATIAL_REF_SYS");
187
////            } catch(SQLException ex) {
188
//////                H2GISExtension.load(conn);
189
////            }
190
//            try {
191
////                conn.createStatement().execute("CREATE SCHEMA IF NOT EXISTS PUBLIC;SET SCHEMA PUBLIC");
192
//            } catch(SQLException ex) {
193
//                // Ignore this error.
194
//            }
195
            if (newdb) {
196
                //crea tablas
197
                //
198
            }
199
            return conn;
200
        }
201

    
202
        private BasicDataSource createDataSource() throws SQLException {
203
            if (!this.isRegistered()) {
204
                this.registerDriver();
205
            }
206
            startServer();
207
            MDBConnectionParameters params = connectionParameters;
208

    
209
            BasicDataSource ds = new BasicDataSource();
210
            ds.setDriverClassName(params.getJDBCDriverClassName());
211
            if( !StringUtils.isEmpty(params.getUser()) ) {
212
                ds.setUsername(params.getUser());
213
            }
214
            if( !StringUtils.isEmpty(params.getPassword()) ) {
215
                ds.setPassword(params.getPassword());
216
            }
217
            ds.setUrl(params.getUrl());
218

    
219
            ds.setMaxWait(60L * 1000);
220
            return ds;
221
        }
222

    
223
        private boolean isRegistered() {
224
            return needRegisterDriver;
225
        }
226

    
227
        public void registerDriver() throws SQLException {
228
            String className = this.connectionParameters.getJDBCDriverClassName();
229
            if (className == null) {
230
                return;
231
            }
232
            try {
233
                Class theClass = Class.forName(className);
234
                if (theClass == null) {
235
                    throw new JDBCDriverClassNotFoundException(MDBLibrary.NAME, className);
236
                }
237
            } catch (Exception e) {
238
                throw new SQLException("Can't register JDBC driver '" + className + "'.", e);
239
            }
240
            needRegisterDriver = false;
241
        }
242

    
243
    }
244

    
245
    private ConnectionProvider connectionProvider = null;
246
 
247
    /**
248
     * Constructor for use only for testing purposes.
249
     */
250
    public MDBHelper() { 
251
        super(null);
252
    }
253
  
254
    public MDBHelper(JDBCConnectionParameters connectionParameters) {
255
        super(connectionParameters);
256
        this.srssolver = new SRSSolverDumb(this);
257
    }
258

    
259
    @Override
260
    public synchronized Connection  getConnection() throws AccessResourceException {
261
        try {
262
            if (this.connectionProvider == null) {
263
              MDBConnectionParameters connectionParameters = this.getConnectionParameters();
264
              if( connectionParameters==null ) {
265
                return null; // Testing mode?
266
              }
267
              this.connectionProvider = new ConnectionProvider(connectionParameters);
268
            }
269
            Connection connection = this.connectionProvider.getConnection();
270
            if( LOGGER.isDebugEnabled() ) {
271
                LOGGER.debug("getConnection: connection = "+connection.hashCode()+ connectionProvider.toString());
272
            }
273
            return connection;
274
        } catch (SQLException ex) {
275
            throw new AccessResourceException(MDBLibrary.NAME, ex);
276
        }
277
    }
278

    
279
    @Override
280
    public void closeConnection(Connection connection) {
281
      if( connection!=null ) { // In test ???
282
        LOGGER.debug("closeConnection: connection = "+connection.hashCode());
283
      }
284
      super.closeConnection(connection);
285
    }
286
    
287
    @Override
288
    public MDBConnectionParameters getConnectionParameters() {
289
        return (MDBConnectionParameters) super.getConnectionParameters();
290
    }
291
    
292
    @Override
293
    public String getConnectionURL() {
294
        return getConnectionURL(this.getConnectionParameters());
295
    }
296

    
297
    @Override
298
    protected String getResourceType() {
299
        return MDBLibrary.NAME;
300
    }
301

    
302
    @Override
303
    public String getProviderName() {
304
        return MDBLibrary.NAME;
305
    }
306

    
307
    @Override
308
    public JDBCSQLBuilderBase createSQLBuilder() {
309
        return new MDBSQLBuilder(this);
310
    }
311
    
312
    @Override
313
    public OperationsFactory getOperations() {
314
        if (this.operationsFactory == null) {
315
            this.operationsFactory = new MDBOperationsFactory(this);
316
        }
317
        return operationsFactory;
318
    }
319

    
320
    @Override
321
    public GeometrySupportType getGeometrySupportType() {
322
        return GeometrySupportType.WKB;
323
    }
324

    
325
    @Override
326
    public boolean hasSpatialFunctions() {
327
        return false;
328
    }
329

    
330
    @Override
331
    public boolean canWriteGeometry(int geometryType, int geometrySubtype) {
332
        return true;
333
    }
334

    
335
    @Override
336
    public String getQuoteForIdentifiers() {
337
        return "\"";
338
    }
339

    
340
    @Override
341
    public boolean allowAutomaticValues() {
342
        return true;
343
    }
344

    
345
    @Override
346
    public boolean supportOffsetInSelect() {
347
        return true;
348
    }
349

    
350
    @Override
351
    public String getQuoteForStrings() {
352
        return "'";
353
    }
354

    
355
    @Override
356
    public String getSourceId(JDBCStoreParameters parameters) {
357
        return parameters.getDBName() + "." + 
358
               parameters.getSchema()+ "." + 
359
               parameters.getTable();
360
    }
361

    
362
    @Override
363
    public JDBCNewStoreParameters createNewStoreParameters() {
364
        return new MDBNewStoreParameters();
365
    }
366

    
367
    @Override
368
    public JDBCStoreParameters createOpenStoreParameters() {
369
        return new MDBStoreParameters();
370
    }
371

    
372
    @Override
373
    public JDBCServerExplorerParameters createServerExplorerParameters() {
374
        return new MDBExplorerParameters();
375
    }
376

    
377
    @Override
378
    public JDBCServerExplorer createServerExplorer(
379
            JDBCServerExplorerParameters parameters, 
380
            DataServerExplorerProviderServices providerServices
381
        ) throws InitializeException {
382
        
383
        JDBCServerExplorer explorer = new JDBCServerExplorerBase(
384
                parameters, 
385
                providerServices, 
386
                this
387
        );
388
        this.initialize(explorer, parameters, null);
389
        return explorer;
390
    }
391
}