root / trunk / org.gvsig.postgresql / org.gvsig.postgresql.provider / src / main / java / org / gvsig / postgresql / dal / PostgreSQLHelper.java @ 510
History | View | Annotate | Download (10.7 KB)
1 | 362 | jjdelcerro | |
---|---|---|---|
2 | package org.gvsig.postgresql.dal; |
||
3 | |||
4 | import java.sql.Connection; |
||
5 | import java.sql.SQLException; |
||
6 | import org.apache.commons.dbcp.BasicDataSource; |
||
7 | import org.apache.commons.lang3.BooleanUtils; |
||
8 | import org.apache.commons.lang3.StringUtils; |
||
9 | import org.gvsig.fmap.dal.SQLBuilder; |
||
10 | import org.gvsig.fmap.dal.resource.exception.AccessResourceException; |
||
11 | import org.gvsig.fmap.dal.store.jdbc.JDBCConnectionParameters; |
||
12 | import org.gvsig.fmap.dal.store.jdbc.JDBCNewStoreParameters; |
||
13 | import org.gvsig.fmap.dal.store.jdbc.JDBCServerExplorerParameters; |
||
14 | import org.gvsig.fmap.dal.store.jdbc.JDBCStoreParameters; |
||
15 | import org.gvsig.fmap.dal.store.jdbc.exception.JDBCDriverClassNotFoundException; |
||
16 | import org.gvsig.fmap.dal.store.jdbc2.OperationsFactory; |
||
17 | import org.gvsig.fmap.dal.store.jdbc2.spi.JDBCHelperBase; |
||
18 | import org.gvsig.fmap.dal.store.jdbc2.spi.JDBCSQLBuilderBase; |
||
19 | 433 | jjdelcerro | import org.gvsig.fmap.dal.store.jdbc2.spi.SRSSolverBase; |
20 | 362 | jjdelcerro | import org.gvsig.postgresql.dal.operations.PostgreSQLOperationsFactory; |
21 | import org.slf4j.Logger; |
||
22 | import org.slf4j.LoggerFactory; |
||
23 | |||
24 | public class PostgreSQLHelper extends JDBCHelperBase { |
||
25 | |||
26 | static final Logger logger = LoggerFactory.getLogger(PostgreSQLHelper.class); |
||
27 | |||
28 | public static final String POSTGRESQL_JDBC_DRIVER = "org.postgresql.Driver"; |
||
29 | |||
30 | public static String getConnectionURL(PostgreSQLConnectionParameters params) { |
||
31 | return getConnectionURL(
|
||
32 | params.getHost(), |
||
33 | params.getPort(), |
||
34 | params.getDBName() |
||
35 | ); |
||
36 | } |
||
37 | |||
38 | public static String getConnectionURL(String host, Integer port, String db) { |
||
39 | if( StringUtils.isEmpty(host) ) {
|
||
40 | throw new IllegalArgumentException("Parameter 'host' can't be null."); |
||
41 | } |
||
42 | String connectionURL = "jdbc:postgresql://" + host; |
||
43 | if (port != null) { |
||
44 | connectionURL = connectionURL + ":" + port;
|
||
45 | } |
||
46 | connectionURL = connectionURL + "/" + db;
|
||
47 | logger.debug("connectionURL: {}", connectionURL);
|
||
48 | return connectionURL;
|
||
49 | } |
||
50 | |||
51 | private static class ConnectionProvider { |
||
52 | |||
53 | private static boolean needRegisterDriver = true; |
||
54 | |||
55 | private BasicDataSource dataSource = null; |
||
56 | |||
57 | private final PostgreSQLConnectionParameters connectionParameters; |
||
58 | |||
59 | public ConnectionProvider(PostgreSQLConnectionParameters connectionParameters) {
|
||
60 | this.connectionParameters = connectionParameters;
|
||
61 | } |
||
62 | |||
63 | public Connection getConnection() throws SQLException { |
||
64 | if (this.dataSource == null) { |
||
65 | this.dataSource = this.createDataSource(); |
||
66 | } |
||
67 | 433 | jjdelcerro | if( logger.isDebugEnabled() ) {
|
68 | logger.debug("getConnection:\n" + getStatusInformation());
|
||
69 | } |
||
70 | Connection conn;
|
||
71 | try {
|
||
72 | conn = this.dataSource.getConnection();
|
||
73 | } catch(Throwable ex) { |
||
74 | logger.debug("Error getting connection from pool.",ex);
|
||
75 | throw ex;
|
||
76 | } |
||
77 | if( logger.isDebugEnabled() ) {
|
||
78 | logger.debug("Created connection: {}\n NumActive: {}\n NumIdle: {}",
|
||
79 | new Object[] { |
||
80 | conn.hashCode(), |
||
81 | this.dataSource.getNumActive(),
|
||
82 | this.dataSource.getNumIdle()
|
||
83 | } |
||
84 | ); |
||
85 | } |
||
86 | 362 | jjdelcerro | return conn;
|
87 | } |
||
88 | 433 | jjdelcerro | |
89 | public void closeConnection(Connection connection) { |
||
90 | if( connection != null ) { |
||
91 | int connectionId = connection.hashCode();
|
||
92 | try {
|
||
93 | connection.close(); |
||
94 | } catch(Throwable ex) { |
||
95 | logger.warn("Can't close connection.", ex);
|
||
96 | } |
||
97 | if( logger.isDebugEnabled() ) {
|
||
98 | Boolean isClosed;
|
||
99 | try {
|
||
100 | isClosed = connection.isClosed(); |
||
101 | } catch(Throwable th) { |
||
102 | isClosed = null;
|
||
103 | } |
||
104 | logger.debug("Closed connection: {}\n isClosed: {}\n NumActive: {}\n NumIdle: {}",
|
||
105 | new Object[] { |
||
106 | connectionId, |
||
107 | isClosed, |
||
108 | this.dataSource.getNumActive(),
|
||
109 | this.dataSource.getNumIdle()
|
||
110 | } |
||
111 | ); |
||
112 | } |
||
113 | } else if( logger.isDebugEnabled() ) { |
||
114 | logger.debug("Close connection: null");
|
||
115 | } |
||
116 | } |
||
117 | |||
118 | public String getStatusInformation() { |
||
119 | StringBuilder builder = new StringBuilder(); |
||
120 | builder.append("BasicDataSource pool status:\n");
|
||
121 | builder.append(" Connection URL: '").append(this.dataSource.getUrl()).append("'\n"); |
||
122 | if( this.dataSource.getInitialSize()>0 ) { |
||
123 | builder.append(" InitialSize: ").append(this.dataSource.getInitialSize()).append(" (The initial number of connections that are created when the pool is started)\n"); |
||
124 | } |
||
125 | if( this.dataSource.isPoolPreparedStatements() ) { |
||
126 | builder.append(" PoolPreparedStatements: ").append(this.dataSource.isPoolPreparedStatements()).append("\n"); |
||
127 | builder.append(" MaxOpenPreparedStatements: ").append(this.dataSource.getMaxOpenPreparedStatements()).append(" (The maximum number of open statements that can be allocated from the statement pool at the same time, or non-positive for no limit)\n"); |
||
128 | } |
||
129 | builder.append(" MaxActive: ").append(this.dataSource.getMaxActive()).append(" (The maximum number of active connections that can be allocated from this pool at the same time)\n"); |
||
130 | builder.append(" MaxIdle: ").append(this.dataSource.getMaxIdle()).append(" (The maximum number of connections that can remain idle in the pool)\n"); |
||
131 | builder.append(" NumActive:").append(this.dataSource.getNumActive()).append(" (the current number of active connections)\n"); |
||
132 | builder.append(" NumIdle:").append(this.dataSource.getNumIdle()).append(" (the current number of idle connections)\n"); |
||
133 | return builder.toString();
|
||
134 | } |
||
135 | 362 | jjdelcerro | |
136 | private BasicDataSource createDataSource() throws SQLException { |
||
137 | if (!this.isRegistered()) { |
||
138 | this.registerDriver();
|
||
139 | } |
||
140 | PostgreSQLConnectionParameters params = connectionParameters; |
||
141 | |||
142 | BasicDataSource ds = new BasicDataSource();
|
||
143 | 433 | jjdelcerro | ds.setMaxIdle(params.getMaxIdle()); |
144 | 362 | jjdelcerro | ds.setDriverClassName(params.getJDBCDriverClassName()); |
145 | if( params.getUseSSL() ) {
|
||
146 | String s = BooleanUtils.toStringTrueFalse(params.getUseSSL());
|
||
147 | ds.addConnectionProperty("ssl", s );
|
||
148 | } |
||
149 | if( !StringUtils.isEmpty(params.getUser()) ) {
|
||
150 | ds.setUsername(params.getUser()); |
||
151 | } |
||
152 | if( !StringUtils.isEmpty(params.getPassword()) ) {
|
||
153 | ds.setPassword(params.getPassword()); |
||
154 | } |
||
155 | ds.setUrl(params.getUrl()); |
||
156 | |||
157 | ds.setMaxWait(60L * 1000); |
||
158 | return ds;
|
||
159 | } |
||
160 | |||
161 | private boolean isRegistered() { |
||
162 | return needRegisterDriver;
|
||
163 | } |
||
164 | |||
165 | public void registerDriver() throws SQLException { |
||
166 | String className = this.connectionParameters.getJDBCDriverClassName(); |
||
167 | if (className == null) { |
||
168 | return;
|
||
169 | } |
||
170 | try {
|
||
171 | Class theClass = Class.forName(className); |
||
172 | if (theClass == null) { |
||
173 | 364 | jjdelcerro | throw new JDBCDriverClassNotFoundException(PostgreSQLLibrary.NAME, className); |
174 | 362 | jjdelcerro | } |
175 | } catch (Exception e) { |
||
176 | throw new SQLException("Can't register JDBC driver '" + className + "'.", e); |
||
177 | } |
||
178 | needRegisterDriver = false;
|
||
179 | } |
||
180 | |||
181 | } |
||
182 | |||
183 | private ConnectionProvider connectionProvider = null; |
||
184 | |||
185 | public PostgreSQLHelper(JDBCConnectionParameters connectionParameters) {
|
||
186 | super(connectionParameters);
|
||
187 | 433 | jjdelcerro | this.srssolver = new SRSSolverBase(this); |
188 | 362 | jjdelcerro | } |
189 | |||
190 | @Override
|
||
191 | public Connection getConnection() throws AccessResourceException { |
||
192 | try {
|
||
193 | if (this.connectionProvider == null) { |
||
194 | this.connectionProvider = new ConnectionProvider(this.getConnectionParameters()); |
||
195 | } |
||
196 | return this.connectionProvider.getConnection(); |
||
197 | } catch (SQLException ex) { |
||
198 | 364 | jjdelcerro | throw new AccessResourceException(PostgreSQLLibrary.NAME, ex); |
199 | 362 | jjdelcerro | } |
200 | } |
||
201 | 433 | jjdelcerro | |
202 | @Override
|
||
203 | public void closeConnection(Connection connection) { |
||
204 | this.connectionProvider.closeConnection(connection);
|
||
205 | } |
||
206 | 362 | jjdelcerro | |
207 | @Override
|
||
208 | public PostgreSQLConnectionParameters getConnectionParameters() {
|
||
209 | return (PostgreSQLConnectionParameters) super.getConnectionParameters(); |
||
210 | } |
||
211 | |||
212 | @Override
|
||
213 | public String getConnectionURL() { |
||
214 | return getConnectionURL(this.getConnectionParameters()); |
||
215 | } |
||
216 | |||
217 | @Override
|
||
218 | protected String getResourceType() { |
||
219 | 364 | jjdelcerro | return PostgreSQLLibrary.NAME;
|
220 | 362 | jjdelcerro | } |
221 | |||
222 | @Override
|
||
223 | public String getProviderName() { |
||
224 | 364 | jjdelcerro | return PostgreSQLLibrary.NAME;
|
225 | 362 | jjdelcerro | } |
226 | |||
227 | @Override
|
||
228 | public JDBCSQLBuilderBase createSQLBuilder() {
|
||
229 | return new PostgreSQLBuilder(this); |
||
230 | } |
||
231 | |||
232 | @Override
|
||
233 | public OperationsFactory getOperations() {
|
||
234 | if (this.operationsFactory == null) { |
||
235 | this.operationsFactory = new PostgreSQLOperationsFactory(this); |
||
236 | } |
||
237 | return operationsFactory;
|
||
238 | } |
||
239 | |||
240 | @Override
|
||
241 | public SQLBuilder.GeometrySupportType getGeometrySupportType() {
|
||
242 | return SQLBuilder.GeometrySupportType.WKB;
|
||
243 | } |
||
244 | |||
245 | @Override
|
||
246 | public boolean hasSpatialFunctions() { |
||
247 | return true; |
||
248 | } |
||
249 | |||
250 | @Override
|
||
251 | public boolean canWriteGeometry(int geometryType, int geometrySubtype) { |
||
252 | return true; |
||
253 | } |
||
254 | |||
255 | @Override
|
||
256 | public String getQuoteForIdentifiers() { |
||
257 | return "\""; |
||
258 | } |
||
259 | |||
260 | @Override
|
||
261 | public boolean allowAutomaticValues() { |
||
262 | return true; |
||
263 | } |
||
264 | |||
265 | @Override
|
||
266 | public boolean supportOffsetInSelect() { |
||
267 | return true; |
||
268 | } |
||
269 | |||
270 | @Override
|
||
271 | public String getQuoteForStrings() { |
||
272 | return "'"; |
||
273 | } |
||
274 | |||
275 | @Override
|
||
276 | public String getSourceId(JDBCStoreParameters parameters) { |
||
277 | return parameters.getDBName() + "." + |
||
278 | parameters.getSchema()+ "." +
|
||
279 | parameters.getTable(); |
||
280 | } |
||
281 | |||
282 | @Override
|
||
283 | public JDBCNewStoreParameters createNewStoreParameters() {
|
||
284 | return new PostgreSQLNewStoreParameters(); |
||
285 | } |
||
286 | |||
287 | @Override
|
||
288 | public JDBCStoreParameters createOpenStoreParameters() {
|
||
289 | return new PostgreSQLStoreParameters(); |
||
290 | } |
||
291 | |||
292 | @Override
|
||
293 | public JDBCServerExplorerParameters createServerExplorerParameters() {
|
||
294 | 385 | jjdelcerro | return new PostgreSQLServerExplorerParameters(); |
295 | 362 | jjdelcerro | } |
296 | } |