%line | %branch | |||||||||
---|---|---|---|---|---|---|---|---|---|---|
org.apache.jcs.config.OptionConverter |
|
|
1 | package org.apache.jcs.config; |
|
2 | ||
3 | /* |
|
4 | * Licensed to the Apache Software Foundation (ASF) under one |
|
5 | * or more contributor license agreements. See the NOTICE file |
|
6 | * distributed with this work for additional information |
|
7 | * regarding copyright ownership. The ASF licenses this file |
|
8 | * to you under the Apache License, Version 2.0 (the |
|
9 | * "License"); you may not use this file except in compliance |
|
10 | * with the License. You may obtain a copy of the License at |
|
11 | * |
|
12 | * http://www.apache.org/licenses/LICENSE-2.0 |
|
13 | * |
|
14 | * Unless required by applicable law or agreed to in writing, |
|
15 | * software distributed under the License is distributed on an |
|
16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
|
17 | * KIND, either express or implied. See the License for the |
|
18 | * specific language governing permissions and limitations |
|
19 | * under the License. |
|
20 | */ |
|
21 | ||
22 | import java.util.Properties; |
|
23 | ||
24 | import org.apache.commons.logging.Log; |
|
25 | import org.apache.commons.logging.LogFactory; |
|
26 | ||
27 | /** |
|
28 | * This class is based on the log4j class |
|
29 | * org.apache.log4j.helpers.OptionConverter that was made by Ceki |
|
30 | * Gülcü Simon Kitching; Avy Sharell (sharell@online.fr) Anders |
|
31 | * Kristensen Matthieu Verbert (mve@zurich.ibm.com) A convenience class to |
|
32 | * convert property values to specific types. |
|
33 | * |
|
34 | */ |
|
35 | 6 | public class OptionConverter |
36 | { |
|
37 | 396 | private final static Log log = LogFactory.getLog( OptionConverter.class ); |
38 | ||
39 | 201 | static String DELIM_START = "${"; |
40 | ||
41 | 201 | static char DELIM_STOP = '}'; |
42 | ||
43 | 201 | static int DELIM_START_LEN = 2; |
44 | ||
45 | 201 | static int DELIM_STOP_LEN = 1; |
46 | ||
47 | 201 | static StringBuffer sbuf = new StringBuffer(); |
48 | ||
49 | /** No instances please. */ |
|
50 | private OptionConverter() |
|
51 | { |
|
52 | 0 | super(); |
53 | 0 | } |
54 | ||
55 | /** |
|
56 | * Combines two arrays. |
|
57 | * |
|
58 | * @param l |
|
59 | * @param r |
|
60 | * @return String[] |
|
61 | */ |
|
62 | public static String[] concatanateArrays( String[] l, String[] r ) |
|
63 | { |
|
64 | 0 | int len = l.length + r.length; |
65 | 0 | String[] a = new String[len]; |
66 | ||
67 | 0 | System.arraycopy( l, 0, a, 0, l.length ); |
68 | 0 | System.arraycopy( r, 0, a, l.length, r.length ); |
69 | ||
70 | 0 | return a; |
71 | } |
|
72 | ||
73 | /** |
|
74 | * Escapes special cahracters/ |
|
75 | * |
|
76 | * @param s |
|
77 | * @return String |
|
78 | */ |
|
79 | public static String convertSpecialChars( String s ) |
|
80 | { |
|
81 | char c; |
|
82 | 0 | int len = s.length(); |
83 | 0 | StringBuffer sbuf = new StringBuffer( len ); |
84 | ||
85 | 0 | int i = 0; |
86 | 0 | while ( i < len ) |
87 | { |
|
88 | 0 | c = s.charAt( i++ ); |
89 | 0 | if ( c == '\\' ) |
90 | { |
|
91 | 0 | c = s.charAt( i++ ); |
92 | 0 | if ( c == 'n' ) |
93 | { |
|
94 | 0 | c = '\n'; |
95 | 0 | } |
96 | 0 | else if ( c == 'r' ) |
97 | { |
|
98 | 0 | c = '\r'; |
99 | 0 | } |
100 | 0 | else if ( c == 't' ) |
101 | { |
|
102 | 0 | c = '\t'; |
103 | 0 | } |
104 | 0 | else if ( c == 'f' ) |
105 | { |
|
106 | 0 | c = '\f'; |
107 | 0 | } |
108 | 0 | else if ( c == '\b' ) |
109 | { |
|
110 | 0 | c = '\b'; |
111 | 0 | } |
112 | 0 | else if ( c == '\"' ) |
113 | { |
|
114 | 0 | c = '\"'; |
115 | 0 | } |
116 | 0 | else if ( c == '\'' ) |
117 | { |
|
118 | 0 | c = '\''; |
119 | 0 | } |
120 | 0 | else if ( c == '\\' ) |
121 | { |
|
122 | 0 | c = '\\'; |
123 | } |
|
124 | } |
|
125 | 0 | sbuf.append( c ); |
126 | 0 | } |
127 | 0 | return sbuf.toString(); |
128 | } |
|
129 | ||
130 | /** |
|
131 | * Very similar to <code>System.getProperty</code> except that the {@link |
|
132 | * SecurityException} is hidden. |
|
133 | * |
|
134 | * @param key |
|
135 | * The key to search for. |
|
136 | * @param def |
|
137 | * The default value to return. |
|
138 | * @return the string value of the system property, or the default value if |
|
139 | * there is no property with that key. |
|
140 | * @since 1.1 |
|
141 | */ |
|
142 | ||
143 | public static String getSystemProperty( String key, String def ) |
|
144 | { |
|
145 | try |
|
146 | { |
|
147 | 47 | return System.getProperty( key, def ); |
148 | } |
|
149 | 0 | catch ( Throwable e ) |
150 | { |
|
151 | // MS-Java throws com.ms.security.SecurityExceptionEx |
|
152 | 0 | log.debug( "Was not allowed to read system property \"" + key + "\"." ); |
153 | 0 | return def; |
154 | } |
|
155 | } |
|
156 | ||
157 | /** |
|
158 | * Creates an object for the className value of the key. |
|
159 | * |
|
160 | * @param props |
|
161 | * @param key |
|
162 | * @param superClass |
|
163 | * @param defaultValue |
|
164 | * @return Object that was created |
|
165 | */ |
|
166 | public static Object instantiateByKey( Properties props, String key, Class superClass, Object defaultValue ) |
|
167 | { |
|
168 | ||
169 | // Get the value of the property in string form |
|
170 | 1831 | String className = findAndSubst( key, props ); |
171 | 1831 | if ( className == null ) |
172 | { |
|
173 | 820 | if ( log.isTraceEnabled() ) |
174 | { |
|
175 | 0 | log.info( "Could not find value for key " + key ); |
176 | } |
|
177 | 820 | return defaultValue; |
178 | } |
|
179 | // Trim className to avoid trailing spaces that cause problems. |
|
180 | 1011 | return OptionConverter.instantiateByClassName( className.trim(), superClass, defaultValue ); |
181 | } |
|
182 | ||
183 | /** |
|
184 | * If <code>value</code> is "true", then <code>true</code> is returned. |
|
185 | * If <code>value</code> is "false", then <code>true</code> is returned. |
|
186 | * Otherwise, <code>default</code> is returned. |
|
187 | * <p> |
|
188 | * |
|
189 | * Case of value is unimportant. |
|
190 | * @param value |
|
191 | * @param dEfault |
|
192 | * @return Object |
|
193 | */ |
|
194 | ||
195 | public static boolean toBoolean( String value, class="keyword">boolean dEfault ) |
|
196 | { |
|
197 | 0 | if ( value == null ) |
198 | { |
|
199 | 0 | return dEfault; |
200 | } |
|
201 | 0 | String trimmedVal = value.trim(); |
202 | 0 | if ( "true".equalsIgnoreCase( trimmedVal ) ) |
203 | { |
|
204 | 0 | return true; |
205 | } |
|
206 | 0 | if ( "false".equalsIgnoreCase( trimmedVal ) ) |
207 | { |
|
208 | 0 | return false; |
209 | } |
|
210 | 0 | return dEfault; |
211 | } |
|
212 | ||
213 | /** Description of the Method |
|
214 | * @param value |
|
215 | * @param dEfault |
|
216 | * @return |
|
217 | */ |
|
218 | public static int toInt( String value, class="keyword">int dEfault ) |
|
219 | { |
|
220 | 0 | if ( value != null ) |
221 | { |
|
222 | 0 | String s = value.trim(); |
223 | try |
|
224 | { |
|
225 | 0 | return Integer.valueOf( s ).intValue(); |
226 | } |
|
227 | 0 | catch ( NumberFormatException e ) |
228 | { |
|
229 | 0 | log.error( "[" + s + "] is not in proper int form." ); |
230 | 0 | e.printStackTrace(); |
231 | } |
|
232 | } |
|
233 | 0 | return dEfault; |
234 | } |
|
235 | ||
236 | /** |
|
237 | * @param value |
|
238 | * @param dEfault |
|
239 | * @return |
|
240 | */ |
|
241 | public static long toFileSize( String value, class="keyword">long dEfault ) |
|
242 | { |
|
243 | 0 | if ( value == null ) |
244 | { |
|
245 | 0 | return dEfault; |
246 | } |
|
247 | ||
248 | 0 | String s = value.trim().toUpperCase(); |
249 | 0 | long multiplier = 1; |
250 | int index; |
|
251 | ||
252 | 0 | if ( ( index = s.indexOf( "KB" ) ) != -1 ) |
253 | { |
|
254 | 0 | multiplier = 1024; |
255 | 0 | s = s.substring( 0, index ); |
256 | 0 | } |
257 | 0 | else if ( ( index = s.indexOf( "MB" ) ) != -1 ) |
258 | { |
|
259 | 0 | multiplier = 1024 * 1024; |
260 | 0 | s = s.substring( 0, index ); |
261 | 0 | } |
262 | 0 | else if ( ( index = s.indexOf( "GB" ) ) != -1 ) |
263 | { |
|
264 | 0 | multiplier = 1024 * 1024 * 1024; |
265 | 0 | s = s.substring( 0, index ); |
266 | } |
|
267 | 0 | if ( s != null ) |
268 | { |
|
269 | try |
|
270 | { |
|
271 | 0 | return Long.valueOf( s ).longValue() * multiplier; |
272 | } |
|
273 | 0 | catch ( NumberFormatException e ) |
274 | { |
|
275 | 0 | log.error( "[" + s + "] is not in proper int form" ); |
276 | 0 | log.error( "[" + value + "] not in expected format", e ); |
277 | } |
|
278 | } |
|
279 | 0 | return dEfault; |
280 | } |
|
281 | ||
282 | /** |
|
283 | * Find the value corresponding to <code>key</code> in <code>props</code>. |
|
284 | * Then perform variable substitution on the found value. |
|
285 | * @param key |
|
286 | * @param props |
|
287 | * @return |
|
288 | */ |
|
289 | ||
290 | public static String findAndSubst( String key, Properties props ) |
|
291 | { |
|
292 | 5933 | String value = props.getProperty( key ); |
293 | 5933 | if ( value == null ) |
294 | { |
|
295 | 820 | return null; |
296 | } |
|
297 | ||
298 | try |
|
299 | { |
|
300 | 5113 | return substVars( value, props ); |
301 | } |
|
302 | 0 | catch ( IllegalArgumentException e ) |
303 | { |
|
304 | 0 | log.error( "Bad option value [" + value + "]", e ); |
305 | 0 | return value; |
306 | } |
|
307 | } |
|
308 | ||
309 | /** |
|
310 | * Instantiate an object given a class name. Check that the |
|
311 | * <code>className</code> is a subclass of <code>superClass</code>. If |
|
312 | * that test fails or the object could not be instantiated, then |
|
313 | * <code>defaultValue</code> is returned. |
|
314 | * |
|
315 | * @param className |
|
316 | * The fully qualified class name of the object to instantiate. |
|
317 | * @param superClass |
|
318 | * The class to which the new object should belong. |
|
319 | * @param defaultValue |
|
320 | * The object to return in case of non-fulfillment |
|
321 | * @return |
|
322 | */ |
|
323 | ||
324 | public static Object instantiateByClassName( String className, Class superClass, Object defaultValue ) |
|
325 | { |
|
326 | 1011 | if ( className != null ) |
327 | { |
|
328 | try |
|
329 | { |
|
330 | 1011 | Class classObj = Class.forName( className ); |
331 | 1011 | if ( !superClass.isAssignableFrom( classObj ) ) |
332 | { |
|
333 | 0 | log.error( "A \"" + className + "\" object is not assignable to a \"" + superClass.getName() |
334 | + "\" variable." ); |
|
335 | 0 | return defaultValue; |
336 | } |
|
337 | 1011 | return classObj.newInstance(); |
338 | } |
|
339 | 0 | catch ( Exception e ) |
340 | { |
|
341 | 0 | log.error( "Could not instantiate class [" + className + "]", e ); |
342 | } |
|
343 | } |
|
344 | 0 | return defaultValue; |
345 | } |
|
346 | ||
347 | /** |
|
348 | * Perform variable substitution in string <code>val</code> from the |
|
349 | * values of keys found in the system propeties. |
|
350 | * <p> |
|
351 | * |
|
352 | * The variable substitution delimeters are <b>${ </b> and <b>} </b>. |
|
353 | * <p> |
|
354 | * |
|
355 | * For example, if the System properties contains "key=value", then the call |
|
356 | * |
|
357 | * <pre> |
|
358 | * String s = OptionConverter.substituteVars( "Value of key is ${key}." ); |
|
359 | * </pre> |
|
360 | * |
|
361 | * will set the variable <code>s</code> to "Value of key is value.". |
|
362 | * <p> |
|
363 | * |
|
364 | * If no value could be found for the specified key, then the |
|
365 | * <code>props</code> parameter is searched, if the value could not be |
|
366 | * found there, then substitution defaults to the empty string. |
|
367 | * <p> |
|
368 | * |
|
369 | * For example, if system propeties contains no value for the key |
|
370 | * "inexistentKey", then the call |
|
371 | * |
|
372 | * <pre> |
|
373 | * String s = OptionConverter.subsVars( "Value of inexistentKey is [${inexistentKey}]" ); |
|
374 | * </pre> |
|
375 | * |
|
376 | * will set <code>s</code> to "Value of inexistentKey is []" |
|
377 | * <p> |
|
378 | * |
|
379 | * An {@link java.lang.IllegalArgumentException}is thrown if |
|
380 | * <code>val</code> contains a start delimeter "${" which is not balanced |
|
381 | * by a stop delimeter "}". |
|
382 | * </p> |
|
383 | * <p> |
|
384 | * |
|
385 | * <b>Author </b> Avy Sharell </a> |
|
386 | * </p> |
|
387 | * |
|
388 | * @param val |
|
389 | * The string on which variable substitution is performed. |
|
390 | * @param props |
|
391 | * @return String |
|
392 | * @throws IllegalArgumentException |
|
393 | * if <code>val</code> is malformed. |
|
394 | */ |
|
395 | ||
396 | public static String substVars( String val, Properties props ) |
|
397 | throws IllegalArgumentException |
|
398 | { |
|
399 | 5113 | sbuf.setLength( 0 ); |
400 | ||
401 | 5113 | int i = 0; |
402 | int j; |
|
403 | int k; |
|
404 | ||
405 | while ( true ) |
|
406 | { |
|
407 | 5160 | j = val.indexOf( DELIM_START, i ); |
408 | 5160 | if ( j == -1 ) |
409 | { |
|
410 | 5113 | if ( i == 0 ) |
411 | { |
|
412 | 5066 | return val; |
413 | } |
|
414 | 47 | sbuf.append( val.substring( i, val.length() ) ); |
415 | 47 | return sbuf.toString(); |
416 | } |
|
417 | 47 | sbuf.append( val.substring( i, j ) ); |
418 | 47 | k = val.indexOf( DELIM_STOP, j ); |
419 | 47 | if ( k == -1 ) |
420 | { |
|
421 | 0 | throw new IllegalArgumentException( '"' + val + "\" has no closing brace. Opening brace at position " |
422 | + j + '.' ); |
|
423 | } |
|
424 | 47 | j += DELIM_START_LEN; |
425 | 47 | String key = val.substring( j, k ); |
426 | // first try in System properties |
|
427 | 47 | String replacement = getSystemProperty( key, null ); |
428 | // then try props parameter |
|
429 | 47 | if ( replacement == null && props != class="keyword">null ) |
430 | { |
|
431 | 16 | replacement = props.getProperty( key ); |
432 | } |
|
433 | ||
434 | 47 | if ( replacement != null ) |
435 | { |
|
436 | 31 | sbuf.append( replacement ); |
437 | } |
|
438 | 47 | i = k + DELIM_STOP_LEN; |
439 | 47 | } |
440 | } |
|
441 | ||
442 | } |
|
443 | // end class |
This report is generated by jcoverage, Maven and Maven JCoverage Plugin. |