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