Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||||||
PropertiesProvider |
|
| 0.0;0 |
1 | package com.sourceforge.jpatterns.core.configuration; |
|
2 | ||
3 | import com.sourceforge.jpatterns.core.configuration.exceptions.JPInitializationException; |
|
4 | import com.zmicer.utils.InputArgumentUtils; |
|
5 | import com.zmicer.utils.StringUtils; |
|
6 | import org.apache.log4j.Logger; |
|
7 | ||
8 | import java.util.HashMap; |
|
9 | import java.util.Map; |
|
10 | import java.util.Set; |
|
11 | ||
12 | /** |
|
13 | * This class would store the properties per the key. The values are defined at the properties file of the JPatterns. |
|
14 | * <br/> |
|
15 | * The storage would be the Map, the initialization of the properties would be performed at this class (method #init). |
|
16 | * <br/> |
|
17 | * Please remember that the priority has custom properties files |
|
18 | * ({@link com.sourceforge.jpatterns.core.configuration.PropertiesManagerImpl#m_customBundle}), |
|
19 | * and then the default bundle is asked to provide the property: |
|
20 | * ({@link com.sourceforge.jpatterns.core.configuration.PropertiesManagerImpl#m_defaultBundle}). |
|
21 | * <br/> |
|
22 | * Please review properly the following Java Docs - it is important for understanding of the algorithm of working of the JPatterns |
|
23 | * configuration functionality. |
|
24 | * {@link com.sourceforge.jpatterns.core.configuration.PropertiesProvider.JPProperties.USE_ONLY_CUSTOM_FRAMEWORK_PROPERTIES} |
|
25 | * |
|
26 | * todo: [zmicer] think over the moving this functionality to the common utility/framework. |
|
27 | * <br/> |
|
28 | * <strong>Also important feature in the behaviour of this class is: it won't store the keys/values which define the implementations of the |
|
29 | * interfaces/abstract classes. It is done in the following way. We would check the values of the properties trying to instantiate the |
|
30 | * appropriate classes instances. If it is done succesfully - we would exclude such values.</strong> |
|
31 | * |
|
32 | * $Author:: zmicer $<br/> |
|
33 | * $Rev:: 67 $<br/> * $Date:: 2007-08-28 21:37:07 #$<br/> |
|
34 | * $Date:: 2007-08-28 21:37:07 #$<br/> |
|
35 | */ |
|
36 | public class PropertiesProvider |
|
37 | { |
|
38 | /** |
|
39 | * Logger instance. |
|
40 | */ |
|
41 | 5 | final public static Logger LOG = Logger.getLogger(PropertiesProvider.class); |
42 | ||
43 | /** |
|
44 | * The singleton instance of the property provider. |
|
45 | */ |
|
46 | 5 | final private static PropertiesProvider PROVIDER = new PropertiesProvider(); |
47 | ||
48 | /** |
|
49 | * Signs of the initialization took place. |
|
50 | */ |
|
51 | 5 | private boolean m_isInitialized = false; |
52 | ||
53 | /** |
|
54 | * This map stores all the important properties we need (which values are the <code>Boolean</code> objects). |
|
55 | */ |
|
56 | 5 | private Map<String, Boolean> m_booleanProperties = new HashMap<String, Boolean>(); |
57 | ||
58 | /** |
|
59 | * This map stores all the important properties we need (which values are the <code>String</code> objects). |
|
60 | */ |
|
61 | 5 | private Map<String, String> m_stringProperties = new HashMap<String, String>(); |
62 | ||
63 | /** |
|
64 | * This interface stores the keys for necessary and important for the JPatterns properties. |
|
65 | * <br/> |
|
66 | * Please extend this interface with the values you would add to the properties files (default one). In the case new properties would |
|
67 | * be added to the custom framework properties - create your own interface somewhere else. |
|
68 | */ |
|
69 | public interface JPProperties |
|
70 | { |
|
71 | /** |
|
72 | * If the custom properties would be found only its value would be used. Please be noticed that this property is very important |
|
73 | * as defines the behaviour of all the configuration sub-system. The following rule takes power with it. This property is seached |
|
74 | * at the both default and custom properties, the custom has the priority. The further loading of the props is done using its |
|
75 | * value. |
|
76 | * <br/> |
|
77 | * If both the properties files do not specify this property - we would use the custom ones if custom file presents and has these |
|
78 | * properties, otherwise the default values would be used. |
|
79 | */ |
|
80 | String USE_ONLY_CUSTOM_FRAMEWORK_PROPERTIES = "jpatterns.configuration.props.use.only.custom.if.present"; |
|
81 | ||
82 | /** |
|
83 | * this settings in the case its value is true defines that *custom* *framework* configuration would override all the *default* |
|
84 | * *framework* configuration (it won't be used at all) in the case this is false - when merging default and custom settings firstly |
|
85 | * default would be written to the result, and then all the settings from custom would override default one. |
|
86 | */ |
|
87 | String USE_ONLY_CUSTOM_FRAMEWORK_XML = "jpatterns.configuration.xml.use.only.custom.framework.settings.if.present"; |
|
88 | ||
89 | /** |
|
90 | * this settings in the case its value is true defines that *custom* *consumer* configuration would override all the *default* |
|
91 | * *consumer* configuration (it won't be used at all) in the case this is false - when merging default and custom settings firstly |
|
92 | * default would be written to the result, and then all the settings from custom would override default one. |
|
93 | * a. default consumer settings - appropriate xml files were found at the classpath and all the dirs of the classpath |
|
94 | * b. custom consumer configuration was provided by the properties framework configuration (it also could be provided as JVM |
|
95 | * parameter, in this case JVM value would have the sense of custom consumer config). |
|
96 | */ |
|
97 | String USE_ONLY_CUSTOM_CONSUMER_XML = "jpatterns.configuration.xml.use.only.custom.consumer.settings.if.present"; |
|
98 | ||
99 | /** |
|
100 | * Defines the depth for the validating/overriding the JPatterns configuration. |
|
101 | * <br/> |
|
102 | * the default value is |
|
103 | * <code>com.sourceforge.jpatterns.core.configuration.PropertiesProvider.OverridingDepths.OVERRIDING_LEVEL_SECTION</code> |
|
104 | * |
|
105 | */ |
|
106 | String XML_CONFIG_OVERRIDING_DEPTH = "jpatterns.configuration.xml.overriding.depth"; |
|
107 | ||
108 | /** |
|
109 | * <code>XML_CONFIG_CUSTOM_OVERRIDES_NOT_DEPENDING_ON_PRIORITY</code> |
|
110 | * <br/> |
|
111 | * Default value is <code>false</code> |
|
112 | */ |
|
113 | String XML_CONFIG_CUSTOM_OVERRIDES_NOT_DEPENDING_ON_PRIORITY = |
|
114 | "jpatterns.configuration.xml.custom.overrides.not.depending.on.priorities"; |
|
115 | } |
|
116 | ||
117 | /** |
|
118 | * This enum defines the depths we could use for the defining the overriding types. |
|
119 | * <br/> |
|
120 | * Consider the idea of the common stuff for the converting possible types of the properties files to the enum (check how it is done |
|
121 | * fore the castor - may be it is worth to use castor for it) - idea of <strong>Prosper</strong>!!! |
|
122 | * <br/> |
|
123 | * Please review the comments to the <strong>jpatterns.configuration.xml.overriding.depth</strong> property in the |
|
124 | * <strong>jpatterns.properties</strong> properties file. |
|
125 | */ |
|
126 | 15 | public enum OverridingDepths |
127 | { |
|
128 | /** |
|
129 | * Says that it is incorrect case when the sections contains two section with identical pathes (scopes, section names, priorities). |
|
130 | */ |
|
131 | 5 | OVERRIDING_LEVEL_SECTION, |
132 | /** |
|
133 | * Says it is correct case of existence of two section objects with identical path (scope, section name, priorities) - just because |
|
134 | * it is allowed to extend the existed sections items configuration by the additional items. |
|
135 | */ |
|
136 | 5 | OVERRIDING_LEVEL_ITEM |
137 | } |
|
138 | ||
139 | /** |
|
140 | * Default public constructor |
|
141 | * <br/> |
|
142 | * Please be carefull in adding some initialization functionality at this constructor - this is singleton, and the call of the |
|
143 | * constructor is done at the static initialization level. |
|
144 | */ |
|
145 | private PropertiesProvider() |
|
146 | { |
|
147 | 5 | super(); |
148 | 5 | } |
149 | ||
150 | /** |
|
151 | * Init method - initializes the provided. |
|
152 | * todo [zmicer]: think over the adjustment here!!! we should initialize the objects just to check they are working |
|
153 | * |
|
154 | * |
|
155 | * @param manager the manager, entry point to the properties values. |
|
156 | * Can not be null (otherwise <code>IllegalArgumentException</code> would appear). |
|
157 | */ |
|
158 | protected void init(final IPropertiesManager manager) |
|
159 | { |
|
160 | 40 | PROVIDER.m_isInitialized = false; //[Silent.codeChangies] value changed from true to false. |
161 | 40 | if (null == manager) |
162 | { |
|
163 | 0 | throw new IllegalArgumentException("IPropertiesManager can not be null."); |
164 | } |
|
165 | 40 | final Set<String> mergedKeys = manager.getMergedKeys(); |
166 | 40 | if (null == mergedKeys || mergedKeys.isEmpty()) |
167 | { |
|
168 | 0 | throw new JPInitializationException("The properties manager doesn't contain the bundles at all."); |
169 | } |
|
170 | 40 | for (final String key : mergedKeys) |
171 | { |
|
172 | 400 | final String value = manager.getBundle(key); |
173 | 400 | final Boolean boolValue = StringUtils.getBoolean(value); |
174 | 400 | if ((key.contains("I") && value.contains(key.substring(1)) && value.contains("."))) |
175 | { |
|
176 | 165 | continue; |
177 | } |
|
178 | 235 | if (null != boolValue) |
179 | { |
|
180 | 125 | m_booleanProperties.put(key, boolValue); |
181 | 125 | } |
182 | else |
|
183 | { |
|
184 | 110 | m_stringProperties.put(key, value); |
185 | } |
|
186 | 235 | } |
187 | 40 | PROVIDER.m_isInitialized = true; |
188 | 40 | } |
189 | ||
190 | /** |
|
191 | * Get instance of the PropertiesProvider. |
|
192 | * todo: [zmicer] seems to be not the best way (because IPropertiesProvider is passed.) |
|
193 | * |
|
194 | * @param manager is necessary for the initializing properties values (if they are initialized already - it is just skipped.) |
|
195 | * Can not be null (otherwise <code>IllegalArgumentException</code> would appear). |
|
196 | * @param reloadAnyWay says to reload the properties anyway. It could be used at the unit tests. In the normal life - it should |
|
197 | * be set to false; |
|
198 | * |
|
199 | * @return the PropertiesProvider instance. |
|
200 | */ |
|
201 | public static PropertiesProvider getInstance(final IPropertiesManager manager, final boolean reloadAnyWay) |
|
202 | { |
|
203 | 1162 | if (null == manager) |
204 | { |
|
205 | 0 | throw new IllegalArgumentException("IPropertiesManager can not be null."); |
206 | } |
|
207 | 1162 | if (!PROVIDER.m_isInitialized || reloadAnyWay) |
208 | { |
|
209 | 35 | PROVIDER.init(manager); |
210 | } |
|
211 | 1162 | return PROVIDER; |
212 | } |
|
213 | ||
214 | /** |
|
215 | * @param key The key to retrieve the appropriate value. Can not be null (otherwise <code>IllegalArgumentException</code> would appear). |
|
216 | * Please use the values of JPProperties (surely having the boolean sense). |
|
217 | * |
|
218 | * @return the boolean property. |
|
219 | */ |
|
220 | public Boolean getBooleanProperty(final String key) |
|
221 | { |
|
222 | 1339 | InputArgumentUtils.checkStrings(true, key); |
223 | 1329 | checkIfInitialized(); |
224 | 1329 | return m_booleanProperties.get(key); |
225 | } |
|
226 | ||
227 | /** |
|
228 | * @param key The key to retrieve the appropriate value. Can not be null (otherwise <code>IllegalArgumentException</code> would appear). |
|
229 | * Please use the values of JPProperties (surely having the boolean sense). |
|
230 | * |
|
231 | * @return the String property. |
|
232 | */ |
|
233 | public String getStringProperty(final String key) |
|
234 | { |
|
235 | 1030 | InputArgumentUtils.checkStrings(true, key); |
236 | 1020 | checkIfInitialized(); |
237 | 1020 | return m_stringProperties.get(key); |
238 | } |
|
239 | ||
240 | /** |
|
241 | * Check if the <code>PropertiesProvider</code> was iinitialized. |
|
242 | */ |
|
243 | protected void checkIfInitialized() |
|
244 | { |
|
245 | 2354 | if (!m_isInitialized) |
246 | { |
|
247 | 0 | throw new IllegalStateException("The propertis provider was not initialized."); |
248 | } |
|
249 | 2354 | } |
250 | } |