1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package de.smartics.properties.spi.config.ds;
17
18 import java.io.PrintStream;
19 import java.sql.Connection;
20 import java.sql.PreparedStatement;
21 import java.sql.ResultSet;
22 import java.sql.SQLException;
23 import java.sql.Statement;
24 import java.util.Map;
25 import java.util.Map.Entry;
26
27 import org.apache.commons.lang.StringUtils;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30
31 import de.smartics.util.lang.Arguments;
32
33
34
35
36 public class DefaultDataSourceManager extends AbstractDataSourceDescriptor
37 implements PropertiesDataSourceManager
38 {
39
40
41
42
43
44
45
46 private static final long serialVersionUID = 1L;
47
48
49
50
51 private static final Logger LOG = LoggerFactory
52 .getLogger(DefaultDataSourceManager.class);
53
54
55
56
57
58
59
60
61 private final DataSourceProxy dataSourceProxy;
62
63
64
65
66
67
68 private final Map<String, String> initialProperties;
69
70
71
72
73
74
75 protected final boolean dropTable;
76
77
78
79
80
81
82
83
84 protected final boolean ignoreTableCreationProblems;
85
86
87
88
89 private final String createTableSqlStatement;
90
91
92
93
94
95
96
97
98
99
100 protected DefaultDataSourceManager(final Builder builder)
101 {
102 super(builder);
103
104 this.dataSourceProxy = builder.dataSourceProxy;
105 this.initialProperties = builder.initialProperties;
106 this.dropTable = builder.dropTable;
107 this.ignoreTableCreationProblems = builder.ignoreTableCreationProblems;
108 this.createTableSqlStatement =
109 createCreateTableSqlStatement(builder.createTableSqlStatementTemplate);
110 }
111
112
113
114
115
116
117 public static class Builder extends AbstractDataSourceDescriptor.Builder
118 {
119
120
121
122
123
124
125
126
127
128
129 public static final String DEFAULT_CREATE_TABLE_TEMPLATE =
130 "CREATE TABLE IF NOT EXISTS ${table}"
131 + " (${nameColumn} VARCHAR(64) PRIMARY KEY,"
132 + " ${valueColumn} VARCHAR(255))";
133
134
135
136
137
138
139 protected DataSourceProxy dataSourceProxy;
140
141
142
143
144 private Map<String, String> initialProperties;
145
146
147
148
149 private boolean dropTable = true;
150
151
152
153
154
155
156 private boolean ignoreTableCreationProblems = true;
157
158
159
160
161
162
163
164
165 private String createTableSqlStatementTemplate =
166 DEFAULT_CREATE_TABLE_TEMPLATE;
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195 public final void setCreateTableSqlStatementTemplate(
196 final String createTableSqlStatementTemplate)
197 {
198 this.createTableSqlStatementTemplate = createTableSqlStatementTemplate;
199 }
200
201
202
203
204
205
206
207
208 public final void setDataSourceProxy(final DataSourceProxy dataSourceProxy)
209 throws NullPointerException
210 {
211 Arguments.checkNotNull("dataSourceProxy", dataSourceProxy);
212 this.dataSourceProxy = dataSourceProxy;
213 }
214
215
216
217
218
219
220
221 public final void setInitialProperties(
222 final Map<String, String> initialProperties)
223 {
224 this.initialProperties = initialProperties;
225 }
226
227
228
229
230
231
232
233
234 public final void setDropTable(final boolean dropTable)
235 {
236 this.dropTable = dropTable;
237 }
238
239
240
241
242
243
244
245
246
247 public final void setIgnoreTableCreationProblems(
248 final boolean ignoreTableCreationProblems)
249 {
250 this.ignoreTableCreationProblems = ignoreTableCreationProblems;
251 }
252
253
254
255
256
257
258
259
260
261 public DefaultDataSourceManager build() throws NullPointerException
262 {
263 Arguments.checkNotNull("dataSourceProxy", dataSourceProxy);
264
265 return new DefaultDataSourceManager(this);
266 }
267
268
269 }
270
271
272
273
274
275 private String createCreateTableSqlStatement(final String template)
276 {
277 if (template == null)
278 {
279 return null;
280 }
281
282 final String sql =
283 StringUtils.replaceEach(template, new String[] { "${table}",
284 "${nameColumn}",
285 "${valueColumn}" },
286 new String[] { getTable(), getNameColumn(), getValueColumn() });
287 return sql;
288 }
289
290
291
292 @Override
293 public final String getDataSourceId()
294 {
295 return dataSourceProxy.getDataSourceId();
296 }
297
298 @Override
299 public final DataSourceProxy getDataSourceProxy()
300 {
301 return dataSourceProxy;
302 }
303
304
305
306 @Override
307 public final void createConfigTable() throws DataSourceException
308 {
309 try
310 {
311 initDataSource();
312 }
313 catch (final SQLException e)
314 {
315 throw new DataSourceException("Cannot create configuration table.", e,
316 getDataSourceId());
317 }
318 }
319
320 private void initDataSource() throws SQLException
321 {
322 if (createTableSqlStatement != null)
323 {
324 if (dropTable)
325 {
326 dropConfigTable();
327 }
328
329 initTables();
330 }
331 }
332
333 private void initTables() throws SQLException
334 {
335 final Connection connection =
336 dataSourceProxy.getDataSource().getConnection();
337
338 try
339 {
340 if (!initializedTableExists(connection))
341 {
342 initTable(connection);
343
344 initProperties(connection);
345 }
346 }
347 finally
348 {
349 connection.close();
350 }
351 }
352
353 private boolean initializedTableExists(final Connection connection)
354 throws SQLException
355 {
356 final Statement statement = connection.createStatement();
357 try
358 {
359
360 final String querySql = "SELECT COUNT(*) FROM " + getTable();
361 final ResultSet resultSet = statement.executeQuery(querySql);
362 if (resultSet.next())
363 {
364 final int count = resultSet.getInt(1);
365 return count > 0;
366 }
367
368 return false;
369 }
370 catch (final SQLException e)
371 {
372 return false;
373 }
374 finally
375 {
376 statement.close();
377 }
378 }
379
380 private void initTable(final Connection connection) throws SQLException
381 {
382 try
383 {
384 execute(connection, createTableSqlStatement);
385 }
386 catch (final SQLException e)
387 {
388 if (!ignoreTableCreationProblems)
389 {
390 throw e;
391 }
392 }
393 }
394
395 private void initProperties(final Connection connection) throws SQLException
396 {
397 if (initialProperties != null && !initialProperties.isEmpty())
398 {
399 final PreparedStatement statement =
400 connection.prepareStatement("INSERT INTO " + getTable()
401 + " VALUES (?, ?)");
402 for (final Entry<String, String> property : initialProperties.entrySet())
403 {
404 statement.setString(1, property.getKey());
405 statement.setString(2, property.getValue());
406 statement.execute();
407 }
408
409 statement.close();
410 }
411 }
412
413 private void execute(final Connection connection, final String createTableSql)
414 throws SQLException
415 {
416 final Statement statement = connection.createStatement();
417 try
418 {
419 statement.executeUpdate(createTableSql);
420 }
421 finally
422 {
423 statement.close();
424 }
425 }
426
427 @Override
428 public final void dropConfigTable() throws DataSourceException
429 {
430 try
431 {
432 final Connection connection =
433 dataSourceProxy.getDataSource().getConnection();
434
435 try
436 {
437 final Statement statement = connection.createStatement();
438
439 final String sql = "DROP TABLE " + getTable();
440 statement.executeUpdate(sql);
441 }
442 catch (final SQLException e)
443 {
444 LOG.warn("Dropping failed: " + e.getMessage());
445 }
446 finally
447 {
448 connection.close();
449 }
450 }
451 catch (final SQLException e)
452 {
453 throw new DataSourceException("Cannot drop config table.", e,
454 getDataSourceId());
455 }
456 }
457
458 @Override
459 public final void print(final PrintStream out) throws DataSourceException
460 {
461 try
462 {
463 final Connection connection =
464 dataSourceProxy.getDataSource().getConnection();
465
466 try
467 {
468 final Statement statement = connection.createStatement();
469
470 final String querySql =
471 "SELECT " + getNameColumn() + ", " + getValueColumn() + " FROM "
472 + getTable();
473 final ResultSet resultSet = statement.executeQuery(querySql);
474 while (resultSet.next())
475 {
476 final String name = resultSet.getString(1);
477 final String value = resultSet.getString(2);
478
479 out.println(" " + name + "=" + value);
480 }
481 }
482 finally
483 {
484 connection.close();
485 }
486 }
487 catch (final SQLException e)
488 {
489 throw new DataSourceException("Cannot print config table.", e,
490 getDataSourceId());
491 }
492 }
493
494
495
496 }