1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package de.smartics.properties.impl.config.ds;
17
18 import java.sql.DatabaseMetaData;
19 import java.sql.SQLException;
20 import java.util.List;
21
22 import javax.annotation.concurrent.ThreadSafe;
23 import javax.naming.NamingException;
24
25 import de.smartics.properties.api.config.domain.ConfigurationException;
26 import de.smartics.properties.api.config.domain.ConfigurationPropertiesManagement;
27 import de.smartics.properties.api.config.domain.PropertyProvider;
28 import de.smartics.properties.api.config.domain.key.ConfigurationKey;
29 import de.smartics.properties.api.config.domain.key.ConfigurationKeyFactory;
30 import de.smartics.properties.api.config.ds.DataSourceConfiguration;
31 import de.smartics.properties.impl.config.cache.CacheConfigurationPropertiesManagement;
32 import de.smartics.properties.spi.config.domain.key.ConfigurationKeyContextManager;
33 import de.smartics.properties.spi.config.ds.DataSourceCode;
34 import de.smartics.properties.spi.config.ds.DataSourceConfigurationMessageBean;
35 import de.smartics.properties.spi.config.ds.DataSourceConfigurationPropertyProvider;
36 import de.smartics.properties.spi.config.ds.DataSourceConnector;
37 import de.smartics.properties.spi.config.ds.DataSourceException;
38 import de.smartics.properties.spi.config.ds.DataSourceProxy;
39 import de.smartics.properties.spi.config.ds.JndiDataSourceProxy;
40 import de.smartics.properties.spi.config.ds.PropertiesStore;
41 import de.smartics.properties.spi.config.support.AbstractConfigurationPropertiesFactory;
42 import de.smartics.properties.spi.config.support.ConfigurationPropertiesManagementSpi;
43
44
45
46
47
48
49
50
51
52 @ThreadSafe
53 public class AutodetectDataSourceConfigurationPropertiesFactory extends
54 AbstractConfigurationPropertiesFactory<ConfigurationPropertiesManagement>
55 {
56
57
58
59
60
61
62
63 private static final long serialVersionUID = 1L;
64
65
66
67
68
69
70 private volatile PropertiesStore manager;
71
72
73
74
75
76 private final DataSourceConfiguration configuration;
77
78
79
80
81
82
83
84
85 public AutodetectDataSourceConfigurationPropertiesFactory()
86 {
87 getFactoryConfiguration().setSkipClassPathPropertyLoading(true);
88 this.configuration = new DataSourceConfigurationLoader().load();
89 init();
90 }
91
92
93
94
95
96
97 public AutodetectDataSourceConfigurationPropertiesFactory(
98 final DataSourceConfiguration configuration)
99 {
100 this.configuration = configuration;
101 getFactoryConfiguration().setSkipClassPathPropertyLoading(true);
102 init();
103 }
104
105
106
107
108
109
110
111 private void init()
112 {
113
114 final DataSourceProxy dataSourceProxy =
115 createDataSourceProxy(configuration);
116
117 this.manager = createManager(configuration, dataSourceProxy);
118
119 if (configuration.isCreateTable())
120 {
121 manager.createConfigTable();
122 }
123
124 addProviders();
125 }
126
127 private DataSourceProxy createDataSourceProxy(
128 final DataSourceConfiguration config)
129 {
130 final JndiDataSourceProxy jndiProxy = createProxy(config);
131 final String databaseId = createDatabaseId(jndiProxy);
132 final DataSourceConnector connector =
133 DataSourceProxyManager.getConnectorFor(databaseId);
134 final DataSourceProxy dataSourceProxy = connector.create(jndiProxy);
135 return dataSourceProxy;
136 }
137
138 private PropertiesStore createManager(final DataSourceConfiguration config,
139 final DataSourceProxy dataSourceProxy)
140 {
141 final PropertiesStore.Builder builder = new PropertiesStore.Builder();
142 builder.setDataSourceProxy(dataSourceProxy);
143 builder.setIgnoreTableCreationProblems(false);
144 builder.setCreateTableSqlStatementTemplate(dataSourceProxy
145 .getCreateTableSqlTemplate());
146 builder.setInsertOrUpdateSqlStatementTemplate(dataSourceProxy
147 .getInsertOrUpdateSqlTemplate());
148 builder.setDropTable(config.isDropTable());
149 return builder.build();
150 }
151
152 private void addProviders()
153 {
154 final List<String> keys = manager.getConfigurationKeys();
155 for (final String key : keys)
156 {
157 final ConfigurationKey<?> configurationKey = parseKey(key);
158 final PropertyProvider provider =
159 new DataSourceConfigurationPropertyProvider(configurationKey, manager);
160 addPropertyProviders(provider);
161 }
162 }
163
164 private ConfigurationKey<?> parseKey(final String key)
165 {
166 final ConfigurationKeyFactory<?> factory =
167 ConfigurationKeyContextManager.INSTANCE.context()
168 .configurationKeyFactory();
169 try
170 {
171 final ConfigurationKey<?> configurationKey =
172 factory.createKeyFromString(key);
173 return configurationKey;
174
175 }
176 catch (final IllegalArgumentException e)
177 {
178 final DataSourceConfigurationMessageBean message =
179 new DataSourceConfigurationMessageBean(
180 DataSourceCode.INVALID_CONFIGURATION_KEY, e,
181 manager.getDataSourceId(), null);
182 throw new DataSourceException(message);
183 }
184 }
185
186 private JndiDataSourceProxy createProxy(final DataSourceConfiguration config)
187 {
188 try
189 {
190 return new JndiDataSourceProxy(config.getJndiName());
191 }
192 catch (final NamingException e)
193 {
194 throw new IllegalArgumentException("Cannot access JNDI context: "
195 + e.getMessage(), e);
196 }
197 }
198
199 private static String createDatabaseId(final JndiDataSourceProxy proxy)
200 {
201 try
202 {
203 final DatabaseMetaData metaData =
204 proxy.getDataSource().getConnection().getMetaData();
205 final String databaseId = metaData.getDatabaseProductName();
206 return databaseId;
207 }
208 catch (final SQLException e)
209 {
210 throw new IllegalArgumentException("Cannot read database metadata: "
211 + e.getMessage(), e);
212 }
213 }
214
215
216
217
218
219 @Override
220 protected ConfigurationPropertiesManagement createNewConfiguration(
221 final ConfigurationKey<?> key) throws NullPointerException,
222 ConfigurationException
223 {
224 final ConfigurationPropertiesManagement config = createCache(key);
225 return config;
226 }
227
228 private ConfigurationPropertiesManagement createCache(
229 final ConfigurationKey<?> key)
230 {
231 final ConfigurationPropertiesManagementSpi uncached =
232 new DataSourceConfigurationProperties(key, getRegistry(), manager,
233 getFactoryConfiguration().getDecrypter());
234 if (getFactoryConfiguration().isUseCache())
235 {
236 return new CacheConfigurationPropertiesManagement(uncached);
237 }
238 else
239 {
240 return uncached;
241 }
242 }
243
244
245
246 }