1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.jumpmind.symmetric.service.impl;
22
23 import java.math.BigDecimal;
24 import java.sql.ResultSet;
25 import java.sql.SQLException;
26 import java.util.Date;
27 import java.util.HashMap;
28 import java.util.Map;
29 import java.util.Properties;
30 import java.util.Set;
31
32 import org.apache.commons.lang.StringUtils;
33 import org.apache.commons.logging.Log;
34 import org.apache.commons.logging.LogFactory;
35 import org.jumpmind.symmetric.common.Constants;
36 import org.jumpmind.symmetric.common.ParameterConstants;
37 import org.jumpmind.symmetric.config.IParameterFilter;
38 import org.jumpmind.symmetric.service.IParameterService;
39 import org.springframework.beans.BeansException;
40 import org.springframework.beans.factory.BeanFactory;
41 import org.springframework.beans.factory.BeanFactoryAware;
42 import org.springframework.jdbc.core.RowMapper;
43
44 public class ParameterService extends AbstractService implements IParameterService, BeanFactoryAware {
45
46 static final Log logger = LogFactory.getLog(ParameterService.class);
47
48 private Map<String, String> parameters;
49
50 private BeanFactory beanFactory;
51
52 private long cacheTimeoutInMs = 0;
53
54 private Date lastTimeParameterWereCached;
55
56 private IParameterFilter parameterFilter;
57
58 public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
59 this.beanFactory = beanFactory;
60 }
61
62 public BigDecimal getDecimal(String key) {
63 String val = getString(key);
64 if (val != null) {
65 return new BigDecimal(val);
66 }
67 return BigDecimal.ZERO;
68 }
69
70 public boolean is(String key) {
71 String val = getString(key);
72 if (val != null) {
73 if (val.equals("1")) {
74 return true;
75 } else {
76 return Boolean.parseBoolean(val);
77 }
78 } else {
79 return false;
80 }
81 }
82
83 public int getInt(String key) {
84 String val = getString(key);
85 if (val != null) {
86 return Integer.parseInt(val);
87 }
88 return 0;
89 }
90
91 public long getLong(String key) {
92 String val = getString(key);
93 if (val != null) {
94 return Long.parseLong(val);
95 }
96 return 0;
97 }
98
99 public String getString(String key) {
100 String value = null;
101
102 if (!key.startsWith("symmetric.")) {
103 value = getString("symmetric." + key);
104 if (StringUtils.isBlank(value) && !key.startsWith("symmetric.runtime.")) {
105 value = getString("symmetric.runtime." + key);
106 }
107 }
108
109 if (StringUtils.isBlank(value)) {
110 value = getParameters().get(key);
111 }
112
113 if (this.parameterFilter != null) {
114 value = this.parameterFilter.filterParameter(key, value);
115 }
116
117 return value;
118 }
119
120 public void saveParameter(String key, Object paramValue) {
121 this.saveParameter(getExternalId(), getNodeGroupId(), key, paramValue);
122 }
123
124 public void saveParameter(String externalId, String nodeGroupId, String key, Object paramValue) {
125
126 paramValue = paramValue != null ? paramValue.toString() : null;
127
128 int count = jdbcTemplate.update(getSql("updateParameterSql"), new Object[] { paramValue, externalId,
129 nodeGroupId, key });
130
131 if (count == 0) {
132 jdbcTemplate
133 .update(getSql("insertParameterSql"), new Object[] { externalId, nodeGroupId, key, paramValue });
134 }
135
136 rereadParameters();
137 }
138
139 public void saveParameters(String externalId, String nodeGroupId, Map<String, Object> parameters) {
140 Set<String> keys = parameters.keySet();
141 for (String key : keys) {
142 saveParameter(externalId, nodeGroupId, key, parameters.get(key));
143 }
144 }
145
146 public synchronized void rereadParameters() {
147 this.parameters = null;
148 getParameters();
149 }
150
151 /***
152 * Every time we pull the properties out of the bean factory they should get
153 * reread from the file system.
154 */
155 private Properties rereadFileParameters() {
156 return (Properties) beanFactory.getBean(Constants.PROPERTIES);
157 }
158
159 private Map<String, String> rereadDatabaseParameters(Properties p) {
160 try {
161 Map<String, String> map = rereadDatabaseParameters(ALL, ALL);
162 map.putAll(rereadDatabaseParameters(ALL, p.getProperty(ParameterConstants.NODE_GROUP_ID)));
163 map.putAll(rereadDatabaseParameters(p.getProperty(ParameterConstants.EXTERNAL_ID), p
164 .getProperty(ParameterConstants.NODE_GROUP_ID)));
165 return map;
166 } catch (Exception ex) {
167 logger.warn("Could not read the database parameters. We will try again later.");
168 return new HashMap<String, String>();
169 }
170 }
171
172 private Map<String, String> rereadDatabaseParameters(String externalId, String nodeGroupId) {
173 final Map<String, String> map = new HashMap<String, String>();
174 jdbcTemplate.query(getSql("selectParametersSql"), new Object[] { externalId, nodeGroupId }, new RowMapper() {
175 public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
176 map.put(rs.getString(1), rs.getString(2));
177 return null;
178 }
179 });
180 return map;
181 }
182
183 private Map<String, String> buildSystemParameters() {
184 final Map<String, String> map = new HashMap<String, String>();
185 Properties p = rereadFileParameters();
186 for (Object key : p.keySet()) {
187 map.put((String) key, p.getProperty((String) key));
188 }
189 map.putAll(rereadDatabaseParameters(p));
190 return map;
191
192 }
193
194 private Map<String, String> getParameters() {
195 if (parameters == null
196 || lastTimeParameterWereCached == null
197 || (cacheTimeoutInMs > 0 && lastTimeParameterWereCached.getTime() < (System.currentTimeMillis() - cacheTimeoutInMs))) {
198 lastTimeParameterWereCached = new Date();
199 parameters = buildSystemParameters();
200 cacheTimeoutInMs = getInt(ParameterConstants.PARAMETER_REFRESH_PERIOD_IN_MS);
201 createRuntimeConfigIfNecessary();
202 }
203 return parameters;
204 }
205
206 /***
207 * For backward compatibility only. Remove in 2.0.
208 */
209 @SuppressWarnings("deprecation")
210 private void createRuntimeConfigIfNecessary() {
211 String clazz = getString(ParameterConstants.RUNTIME_CONFIGURATION_CLASS);
212 if (parameterFilter == null && !StringUtils.isBlank(clazz)) {
213 try {
214 final org.jumpmind.symmetric.config.IRuntimeConfig runtimeConfig = (org.jumpmind.symmetric.config.IRuntimeConfig) Class
215 .forName(clazz).newInstance();
216 parameterFilter = new IParameterFilter() {
217 public String filterParameter(String key, String value) {
218 if (key.equals(ParameterConstants.EXTERNAL_ID)) {
219 return runtimeConfig.getExternalId();
220 } else if (key.equals(ParameterConstants.NODE_GROUP_ID)) {
221 return runtimeConfig.getNodeGroupId();
222 } else if (key.equals(ParameterConstants.REGISTRATION_URL)) {
223 return runtimeConfig.getRegistrationUrl();
224 } else if (key.equals(ParameterConstants.SCHEMA_VERSION)) {
225 return runtimeConfig.getSchemaVersion();
226 } else if (key.equals(ParameterConstants.MY_URL)) {
227 return runtimeConfig.getMyUrl();
228 } else {
229 return value;
230 }
231 }
232
233 public boolean isAutoRegister() {
234 return false;
235 }
236 };
237
238 } catch (Exception e) {
239 logger.error(e);
240 }
241 }
242 }
243
244 public Map<String, String> getAllParameters() {
245 return getParameters();
246 }
247
248 public Date getLastTimeParameterWereCached() {
249 return lastTimeParameterWereCached;
250 }
251
252 public void setParameterFilter(IParameterFilter parameterFilter) {
253 this.parameterFilter = parameterFilter;
254 }
255
256 public String getExternalId() {
257 return getString(ParameterConstants.EXTERNAL_ID);
258 }
259
260 public String getMyUrl() {
261 return getString(ParameterConstants.MY_URL);
262 }
263
264 public String getNodeGroupId() {
265 return getString(ParameterConstants.NODE_GROUP_ID);
266 }
267
268 public String getRegistrationUrl() {
269 return getString(ParameterConstants.REGISTRATION_URL);
270 }
271
272 }