source: ccr/trunk/nhin-vista/projects/NHINC/Current/Product/Production/Common/NhincLib/src/gov/hhs/fha/nhinc/properties/PropertyAccessor.java@ 507

Last change on this file since 507 was 507, checked in by George Lilly, 15 years ago

NHIN gateway and adaptor for use on linux with VistA EHR and RPMS

File size: 31.6 KB
Line 
1package gov.hhs.fha.nhinc.properties;
2
3import java.io.FileReader;
4import java.io.File;
5
6import java.text.SimpleDateFormat;
7import java.util.Properties;
8import java.util.Date;
9import java.util.Hashtable;
10import java.util.Calendar;
11
12import java.util.Iterator;
13import java.util.Set;
14import org.apache.commons.logging.Log;
15import org.apache.commons.logging.LogFactory;
16
17/**
18 * This class is a POJO class that is used to access properties within a property
19 * file.
20 *
21 * @author Les Westberg
22 * @version 1.0
23 * @created 04-Sep-2008 1:21:31 PM
24 */
25public class PropertyAccessor
26{
27 private static Log log = LogFactory.getLog(PropertyAccessor.class);
28 private static final String NHINC_PROPERTIES_DIR = "NHINC_PROPERTIES_DIR";
29 private static final String CACHE_REFRESH_DURATION = "CacheRefreshDuration";
30 private static final String CRLF = System.getProperty("line.separator");
31
32 // This is a hash table that contains all the properties for all of the files that
33 // have been accessed. The hashtable is keyed off the property file name.
34 //---------------------------------------------------------------------------------
35 private static Hashtable<String, Properties> m_hAllProps = new Hashtable<String, Properties>();
36
37 // This hash table is used to contain the information about when the next refresh is supposed
38 // to take place on the property file. The key is the name of the property file. The
39 // value is a RefreshInfo class that contains the refresh mode and the date/time that the
40 // refresh should take place.
41 //------------------------------------------------------------------------------------------------------
42 private static Hashtable<String, RefreshInfo> m_hNextRefresh = new Hashtable<String, RefreshInfo>();
43 private static String m_sPropertyFileDir = "";
44 private static final String m_sFailedEnvVarMessage = "Unable to access environment variable: NHINC_PROPERTIES_DIR.";
45 private static boolean m_bFailedToLoadEnvVar = false;
46
47 static
48 {
49 String sValue = System.getenv(NHINC_PROPERTIES_DIR);
50 if ((sValue != null) && (sValue.length() > 0))
51 {
52 // Set it up so that we always have a "/" at the end - in case
53 //------------------------------------------------------------
54 if ((sValue.endsWith("/")) || (sValue.endsWith("\\")))
55 {
56 m_sPropertyFileDir = sValue;
57 }
58 else
59 {
60 String sFileSeparator = System.getProperty("file.separator");
61 m_sPropertyFileDir = sValue + sFileSeparator;
62 }
63 }
64 else
65 {
66 log.error(m_sFailedEnvVarMessage);
67 m_bFailedToLoadEnvVar = true;
68 }
69 }
70
71
72 /**
73 * Default constructor.
74 */
75 public PropertyAccessor()
76 {
77 }
78
79 /**
80 * This method does a quick check to make sure that the environment variable has been
81 * set. It if has not, then an exception is thrown.
82 *
83 * @return True if the environment variable is set. (It never gives false, because
84 * if it is not set, it throws an exception).
85 * @throws PropertyAccessException This is thrown if the environment variable was not set.
86 */
87 private static boolean checkEnvVarSet()
88 throws PropertyAccessException
89 {
90 if (m_bFailedToLoadEnvVar)
91 {
92 throw new PropertyAccessException(m_sFailedEnvVarMessage);
93 }
94
95 return true; // We only get here if the env variable was loaded.
96 }
97
98 /**
99 * This is a helper method that checks to see if the string is not
100 * null and that it contains a value other than the empty string. It throws
101 * an exception if it is null or contains the empty string.
102 *
103 * @param sMethodName The name of the method that is calling this one.
104 * @param sVarName The name of the variable that is being checked. (Used in the error message text.)
105 * @param sValue The variable that is being checked.
106 * @throws PropertyAccessException If the variable is null or empty this exception is thrown.
107 */
108 private static void stringIsValid(String sMethodName, String sVarName, String sValue)
109 throws PropertyAccessException
110 {
111 if (sValue == null)
112 {
113 throw new PropertyAccessException("Method: " + sMethodName +
114 ", Variable: " + sVarName +
115 " was null and it should have a valid value.");
116 }
117 else if ((sValue.length() == 0) ||
118 (sValue.trim().length() == 0))
119 {
120 throw new PropertyAccessException("Method: " + sMethodName +
121 ", Variable: " + sVarName +
122 " was '' (empty string) and it should have a valid value.");
123 }
124 }
125
126
127 /**
128 * This creates a new properties class with a full copy of all of the
129 * properties.
130 *
131 * @param oProps The property file that is to be copied.
132 * @return The copy that is returned.
133 * @throws gov.hhs.fha.nhinc.properties.PropertyAccessException This exception is thrown if
134 * it cannot load the property file for some reason.
135 */
136 private static Properties deepCopyProperties(Properties oProps)
137 throws PropertyAccessException
138 {
139 Properties oRetProps = new Properties();
140
141 Set<String> setKeys = oProps.stringPropertyNames();
142 Iterator<String> iterKeys = setKeys.iterator();
143 while (iterKeys.hasNext())
144 {
145 String sKey = iterKeys.next();
146 String sValue = oProps.getProperty(sKey);
147 if (sValue != null)
148 {
149 sValue = sValue.trim();
150 }
151 oRetProps.put(sKey, sValue);
152 }
153
154 return oRetProps;
155 }
156
157 /**
158 * This method loads the property file and sets the refresh time. If the property:
159 * "CacheRefreshDuration" is found in the property file, then it will set it as follows:
160 * If the value is "-1", then
161 *
162 * @param sPropertyFile The name of the property file to be loaded.
163 * @param oInfo The refresh information that we already know - this may be null if this
164 * is the first time the file is being loaded.
165 * @throws gov.hhs.fha.nhinc.properties.PropertyAccessException This exception is thrown if
166 * it cannot load the property file for some reason.
167 */
168 private static void loadPropertyFile(String sPropertyFile, RefreshInfo oInfo)
169 throws PropertyAccessException
170 {
171 String sPropFilePathAndName = m_sPropertyFileDir + sPropertyFile + ".properties";
172 RefreshInfo oNewInfo = null;
173 if (oInfo != null)
174 {
175 oNewInfo = oInfo;
176
177 // Reset the refresh time...
178 //--------------------------
179 if (oNewInfo.m_oRefreshMode == RefreshInfo.Mode.PERIODIC)
180 {
181 Calendar oRefreshDate = Calendar.getInstance();
182 oRefreshDate.add(Calendar.MILLISECOND, oNewInfo.m_iRefreshMilliseconds);
183 oNewInfo.m_dtRefreshDate = oRefreshDate.getTime();
184 }
185 else if (oNewInfo.m_oRefreshMode == RefreshInfo.Mode.ALWAYS)
186 {
187 oNewInfo.m_dtRefreshDate = Calendar.getInstance().getTime();
188 }
189 }
190 else
191 {
192 // Default Values -
193 //------------------
194 oNewInfo = new RefreshInfo();
195 oNewInfo.m_oRefreshMode = RefreshInfo.Mode.NEVER;
196 oNewInfo.m_dtRefreshDate = new Date();
197 oNewInfo.m_iRefreshMilliseconds = -1;
198 }
199
200 Properties oProps = new Properties();
201 FileReader frPropFile = null;
202 try
203 {
204 File fPropFile = new File(sPropFilePathAndName);
205 if (!fPropFile.exists())
206 {
207 throw new PropertyAccessException("Failed to open property file:'" + sPropFilePathAndName + "'. " +
208 "File does not exist.");
209 }
210 frPropFile = new FileReader(fPropFile);
211 oProps.load(frPropFile);
212
213 // Look to see if we have a refresh property setting. If so, update
214 // the settings we have had to the new ones...
215 //-------------------------------------------------------------------
216 String sValue = oProps.getProperty(CACHE_REFRESH_DURATION);
217 if ((sValue != null) && (sValue.length() > 0))
218 {
219 int iMilliseconds = -1;
220 try
221 {
222 iMilliseconds = Integer.parseInt(sValue.trim());
223 }
224 catch (Exception e1)
225 {
226 log.warn("Property File:'" + sPropertyFile + "' contained an invalid '" +
227 CACHE_REFRESH_DURATION + "' value. It is supposed to be numeric and it was not. " +
228 "The value was '" + sValue + "'. Treating this property file as 'refresh never'.");
229 }
230
231 // Update any refresh information that may now be in the file...
232 //---------------------------------------------------------------
233 if (iMilliseconds <= -1)
234 {
235 oNewInfo.m_oRefreshMode = RefreshInfo.Mode.NEVER;
236 oNewInfo.m_iRefreshMilliseconds = -1;
237 oNewInfo.m_dtRefreshDate = null;
238 }
239 else if (iMilliseconds == 0)
240 {
241 oNewInfo.m_oRefreshMode = RefreshInfo.Mode.ALWAYS;
242 oNewInfo.m_iRefreshMilliseconds = 0;
243 oNewInfo.m_dtRefreshDate = new Date();
244 }
245 else
246 {
247 oNewInfo.m_oRefreshMode = RefreshInfo.Mode.PERIODIC;
248 oNewInfo.m_iRefreshMilliseconds = iMilliseconds;
249 Calendar oRefreshDate = Calendar.getInstance();
250 oRefreshDate.add(Calendar.MILLISECOND, iMilliseconds);
251 oNewInfo.m_dtRefreshDate = oRefreshDate.getTime();
252 }
253 } // if ((sValue != null) && (sValue.length() > 0))
254
255 // Now lets refresh the property information
256 //------------------------------------------
257 synchronized(m_hNextRefresh)
258 {
259 m_hAllProps.put(sPropertyFile, oProps);
260 m_hNextRefresh.put(sPropertyFile, oNewInfo);
261 }
262
263// if (log.isDebugEnabled())
264// {
265// String sMessage = "Loaded/Refreshed property file: " + sPropertyFile;
266// log.debug(sMessage);
267// }
268 }
269 catch (Exception e)
270 {
271 String sMessage = "Failed to load property file. Error: " + e.getMessage();
272 throw new PropertyAccessException(sMessage, e);
273 }
274 finally
275 {
276 if (frPropFile != null)
277 {
278 try
279 {
280 frPropFile.close();
281 }
282 catch (Exception e1)
283 {
284 log.error("Failed to close property file: '" + sPropFilePathAndName + "'", e1);
285 }
286 }
287 }
288 }
289
290 /**
291 * This method will check to see if the property file needs to be refreshed
292 * and if it does, it will reload it. Otherwise it will leave it as is.
293 *
294 * @param sPropertyFile The name of the property file that is being checked and
295 * possibly loaded.
296 * @throws PropertyAccessException If an error occurs during the load process,
297 * this exception is thrown.
298 */
299 private static void checkForRefreshAndLoad(String sPropertyFile)
300 throws PropertyAccessException
301 {
302 Date dtNow = new Date();
303 RefreshInfo oInfo = m_hNextRefresh.get(sPropertyFile);
304
305 if (oInfo != null)
306 {
307 if ((oInfo.m_oRefreshMode == RefreshInfo.Mode.ALWAYS) ||
308 ((oInfo.m_oRefreshMode == RefreshInfo.Mode.PERIODIC)) &&
309 (oInfo.m_dtRefreshDate.before(dtNow)))
310 {
311 loadPropertyFile(sPropertyFile, oInfo);
312 }
313 }
314 else if (oInfo == null)
315 {
316 loadPropertyFile(sPropertyFile, oInfo); // This means that this is the firat time property file has been accessed
317 }
318 }
319
320 /**
321 * This method returns the value of the given property that is located within the
322 * given property file. If the properties have been cached and the cache is
323 * still fresh, then it will return the value from the cache. If the properties
324 * are cached, but the cache is not fresh, then the cache will be updated with the
325 * current values in the properties file and then the property will be returned.
326 * If the properties for that file are not cached at all, the property will be
327 * retrieved from the properties file and returned.
328 *
329 * @param sPropertyFile The name of the property file. This is the name of the
330 * file without a path and without the ".properties" extension. Examples of this
331 * would be "connection" or "gateway".
332 * @param sPropertyName This is the name of the property within the property
333 * file.
334 * @throws PropertyAccessException This is thrown if an error occurs accessing the property.
335 */
336 public static String getProperty(String sPropertyFile, String sPropertyName)
337 throws PropertyAccessException
338 {
339 String sReturnValue = "";
340
341 // Make sure everything is in a good state.
342 //-----------------------------------------
343 checkEnvVarSet();
344 stringIsValid("getProperty", "sPropertyFile", sPropertyFile);
345 stringIsValid("getProperty", "sPropertyName", sPropertyName);
346
347 checkForRefreshAndLoad(sPropertyFile);
348
349 Properties oProps = m_hAllProps.get(sPropertyFile);
350
351 if (oProps != null)
352 {
353 String sValue = oProps.getProperty(sPropertyName);
354 if ((sValue != null) && (sValue.length() > 0))
355 {
356 sReturnValue = sValue.trim();
357 }
358 }
359
360 return sReturnValue;
361 }
362
363 /**
364 * This will return true if the property value is: T, t, or any case combination
365 * of "TRUE" and it will return false for all other values.
366 *
367 * @param sPropertyFile The name of the property file.
368 * @param sPropertyName The name of the property that contains a boolean value.
369 * This will return true if the value is: T, t, or any case combination of "TRUE"
370 * and it will return false for all other values.
371 * @throws PropertyAccessException This is thrown if an error occurs accessing the property.
372 */
373 public static boolean getPropertyBoolean(String sPropertyFile, String sPropertyName)
374 throws PropertyAccessException
375 {
376 boolean bReturnValue = false;
377
378 // Make sure everything is in a good state.
379 //-----------------------------------------
380 checkEnvVarSet();
381 stringIsValid("getPropertyBoolean", "sPropertyFile", sPropertyFile);
382 stringIsValid("getPropertyBoolean", "sPropertyName", sPropertyName);
383
384 checkForRefreshAndLoad(sPropertyFile);
385
386 Properties oProps = m_hAllProps.get(sPropertyFile);
387
388 if (oProps != null)
389 {
390 String sValue = oProps.getProperty(sPropertyName);
391 if ((sValue != null) && (sValue.length() > 0) &&
392 ((sValue.trim().equalsIgnoreCase("T")) ||
393 (sValue.trim().equalsIgnoreCase("TRUE"))))
394 {
395 bReturnValue = true;
396 }
397 }
398
399 return bReturnValue;
400 }
401
402 /**
403 * This will return the long value conversion of the property. If the property value
404 * cannot be converted to a long, an exception will be thrown.
405 *
406 * @param sPropertyFile The name of the property file.
407 * @param sPropertyName The name of the property that contains a boolean value.
408 * @return This will return the long representation of the value.
409 * @throws PropertyAccessException This is thrown if an error occurs accessing the property.
410 */
411 public static long getPropertyLong(String sPropertyFile, String sPropertyName)
412 throws PropertyAccessException
413 {
414 long lReturnValue = 0;
415
416 // Make sure everything is in a good state.
417 //-----------------------------------------
418 checkEnvVarSet();
419 stringIsValid("getPropertyBoolean", "sPropertyFile", sPropertyFile);
420 stringIsValid("getPropertyBoolean", "sPropertyName", sPropertyName);
421
422 checkForRefreshAndLoad(sPropertyFile);
423
424 Properties oProps = m_hAllProps.get(sPropertyFile);
425
426 if (oProps != null)
427 {
428 String sValue = oProps.getProperty(sPropertyName);
429 if ((sValue != null) && (sValue.length() > 0))
430 {
431 try
432 {
433 lReturnValue = Long.parseLong(sValue.trim());
434 }
435 catch (Exception e)
436 {
437 String sError = "Failed to convert string value: '" + sValue + "' to a long. Error: " +
438 e.getMessage();
439 log.warn(sError, e);
440 throw new PropertyAccessException(sError, e);
441 }
442 }
443 }
444
445 return lReturnValue;
446 }
447
448 /**
449 * This method returns the set of keys in a property file.
450 *
451 * @param sPropertyFile The name of the property file.
452 * @return An enumeration of property keys in the property file.
453 * @throws PropertyAccessException This is thrown if an error occurs accessing the property.
454 */
455 public static final Set<String> getPropertyNames(String sPropertyFile)
456 throws PropertyAccessException
457 {
458 Set<String> setPropNames = null;
459
460 // Make sure everything is in a good state.
461 //-----------------------------------------
462 checkEnvVarSet();
463 stringIsValid("getPropertyNames", "sPropertyFile", sPropertyFile);
464
465 checkForRefreshAndLoad(sPropertyFile);
466
467 Properties oProps = m_hAllProps.get(sPropertyFile);
468
469 if (oProps != null)
470 {
471 setPropNames = oProps.stringPropertyNames();
472 }
473
474 return setPropNames;
475 }
476
477 /**
478 * This method returns the properties that are located within the given property
479 * file. If the properties have been cached and the cache is still fresh, then
480 * it will return the values from the cache. If the properties are cached, but
481 * the cache is not fresh, then the cache will be updated with the current values
482 * in the properties file and then the property values will be returned. If the
483 * properties for that file are not cached at all, the property will be retrieved
484 * from the properties file and returned.
485 *
486 * NOTE: THIS IS AN EXPENSIVE OPERATION. IT WILL CREATE A DEEP COPY OF THE
487 * PROPERTIES AND RETURN IT. THAT MEANS IT WILL CREATE AN EXACT REPLICA
488 * WITH ALL DATA. THIS IS A PROTECTION TO MAKE SURE THAT A PROPERTY
489 * IS NOT INADVERTANTLY CHANGED OUTSIDE OF THIS CLASS.
490 *
491 * @param sPropertyFile The name of the properties file without the path or
492 * extension.
493 * @throws PropertyAccessException This is thrown if an error occurs accessing the property.
494 */
495 public static final Properties getProperties(String sPropertyFile)
496 throws PropertyAccessException
497 {
498 // Make sure everything is in a good state.
499 //-----------------------------------------
500 checkEnvVarSet();
501 stringIsValid("getProperties", "sPropertyFile", sPropertyFile);
502
503 checkForRefreshAndLoad(sPropertyFile);
504
505 Properties oProps = m_hAllProps.get(sPropertyFile);
506
507 Properties oRetProps = deepCopyProperties(oProps);
508
509 return oRetProps;
510 }
511
512 /**
513 * This will return the in milliseconds the refresh duration on the property file.
514 * A setting of -1 means it never refreshes.
515 *
516 * @param sPropertyFile The name of the property file.
517 * @throws PropertyAccessException This is thrown if an error occurs accessing the property.
518 */
519 public static int getRefreshDuration(String sPropertyFile)
520 throws PropertyAccessException
521 {
522 int iRefreshDuration = -1;
523
524 // Make sure everything is in a good state.
525 //-----------------------------------------
526 checkEnvVarSet();
527 stringIsValid("getRefreshDuration", "sPropertyFile", sPropertyFile);
528
529 checkForRefreshAndLoad(sPropertyFile);
530
531 RefreshInfo oInfo = m_hNextRefresh.get(sPropertyFile);
532 if (oInfo != null)
533 {
534 iRefreshDuration = oInfo.m_iRefreshMilliseconds;
535 }
536
537 return iRefreshDuration;
538 }
539
540 /**
541 * This will return the duration in milliseconds before the next refresh of the
542 * properties file. A value of -1 indicates that no refresh will occur.
543 *
544 * @param sPropertyFile The name of the property file.
545 * @throws PropertyAccessException This is thrown if an error occurs accessing the property.
546 */
547 public static int getDurationBeforeNextRefresh(String sPropertyFile)
548 throws PropertyAccessException
549 {
550 int iNextRefreshDuration = -1;
551
552 // Make sure everything is in a good state.
553 //-----------------------------------------
554 checkEnvVarSet();
555 stringIsValid("getDurationBeforeNextRefresh", "sPropertyFile", sPropertyFile);
556
557 checkForRefreshAndLoad(sPropertyFile);
558
559 RefreshInfo oInfo = m_hNextRefresh.get(sPropertyFile);
560 if (oInfo != null)
561 {
562 if (oInfo.m_oRefreshMode == RefreshInfo.Mode.ALWAYS)
563 {
564 iNextRefreshDuration = 0;
565 }
566 else if (oInfo.m_oRefreshMode == RefreshInfo.Mode.NEVER)
567 {
568 iNextRefreshDuration = -1;
569 }
570 else
571 {
572 long lNowMilli = new Date().getTime();
573 long lRefreshMilli = oInfo.m_dtRefreshDate.getTime();
574 iNextRefreshDuration = (int) (lRefreshMilli - lNowMilli);
575 }
576 }
577
578 return iNextRefreshDuration;
579 }
580
581 /**
582 * If a property file has been cached, this will force a refresh of the property
583 * file. If a property file is not cached, then this operation will do nothing.
584 *
585 * @param sPropertyFile The name of the property file.
586 * @throws PropertyAccessException This is thrown if an error occurs accessing the property.
587 */
588 public static void forceRefresh(String sPropertyFile)
589 throws PropertyAccessException
590 {
591 // Make sure everything is in a good state.
592 //-----------------------------------------
593 checkEnvVarSet();
594 stringIsValid("forceRefresh", "sPropertyFile", sPropertyFile);
595
596 RefreshInfo oInfo = m_hNextRefresh.get(sPropertyFile);
597 // This means we have never loaded the file - so load it now...
598 //--------------------------------------------------------------
599 if (oInfo == null)
600 {
601 checkForRefreshAndLoad(sPropertyFile);
602 }
603 else if (oInfo.m_oRefreshMode != RefreshInfo.Mode.NEVER)
604 {
605 loadPropertyFile(sPropertyFile, oInfo);
606 }
607 }
608
609 /**
610 * This method will return the location of the property files. Essentially it
611 * will return the value in the NHINC_PROPERTIES_DIR environment variable.
612 */
613 public static String getPropertyFileLocation()
614 {
615 return m_sPropertyFileDir;
616 }
617
618 /**
619 * This method dumps the properties and associated values for a properties file to
620 * the log file.
621 *
622 * @param sPropertyFile The name of the property file.
623 * @throws PropertyAccessException This is thrown if an error occurs accessing the property.
624 */
625 public static void dumpPropsToLog(String sPropertyFile)
626 throws PropertyAccessException
627 {
628 // Make sure everything is in a good state.
629 //-----------------------------------------
630 checkEnvVarSet();
631 stringIsValid("dumpPropsToLog", "sPropertyFile", sPropertyFile);
632
633 StringBuffer sbLogMessage = new StringBuffer();
634
635 sbLogMessage.append("Dumping contents of property file: '" + sPropertyFile + "'." + CRLF);
636
637 RefreshInfo oInfo = m_hNextRefresh.get(sPropertyFile);
638 // This means we have never loaded the file - so load it now...
639 //--------------------------------------------------------------
640 if (oInfo != null)
641 {
642 sbLogMessage.append("RefreshInfo.RefreshMode=" + oInfo.m_oRefreshMode + CRLF);
643 sbLogMessage.append("RefreshInfo.RefreshMilliseconds=" + oInfo.m_iRefreshMilliseconds + CRLF);
644 if (oInfo.m_dtRefreshDate != null)
645 {
646 SimpleDateFormat oFormat = new SimpleDateFormat("MM/dd/yyyy.HH:mm:ss");
647 sbLogMessage.append("RefreshInfo.RefreshDate=" + oFormat.format(oInfo.m_dtRefreshDate) + CRLF);
648 }
649 else
650 {
651 sbLogMessage.append("RefreshInfo.RefreshDate=null" + CRLF);
652 }
653
654 sbLogMessage.append("Properties:");
655
656 Properties oProps = m_hAllProps.get(sPropertyFile);
657 if (oProps != null)
658 {
659 Set<String> setKeys = oProps.stringPropertyNames();
660 if (setKeys != null)
661 {
662 Iterator<String> iterKeys = setKeys.iterator();
663 while (iterKeys.hasNext())
664 {
665 String sKey = iterKeys.next();
666 String sValue = oProps.getProperty(sKey);
667 if (sValue != null)
668 {
669 sValue = sValue.trim();
670 }
671 sbLogMessage.append("Property:" + sKey + "=" + sValue + CRLF);
672 }
673 } // if (setKeys != null)
674 else
675 {
676 sbLogMessage.append("No properties were found in the property file." + CRLF);
677 }
678 } // if (oProps != null)
679 else
680 {
681 sbLogMessage.append("No properties were found in the property file." + CRLF);
682 }
683 } //if (oInfo != null)
684 else
685 {
686 sbLogMessage.append("No content. Property file has never been loaded." + CRLF);
687 }
688
689 log.info(sbLogMessage.toString());
690 }
691
692 /**
693 * This method is protected. It is only to be used for unit testing and should
694 * NEVER be used in the run-time environment. It's purpose is to allow properties
695 * to be staged for a unit test. It is marked as protected so that only classes
696 * that are derived from this one can use it. Note that this sets the property in
697 * the cache memory only. Because of the nature of this setting... If a
698 * property file is marked as not cached, or is marked with a cache refresh, the
699 * setting of a property will override that and it will now be marked as cached
700 * only and never refresh. The purpose for this is two fold: 1) You do not want
701 * the property file to be unknowningly changed. 2) Since a controlled
702 * environment is required in testing, it is not wise to have the properties reset
703 * back to the values in the stored file during the middle of a test.
704 *
705 * @param sPropertyFile The name of the property file.
706 * @param sPropertyName The name of the property.
707 * @param sValue The value to set for the property. NOTE: This will only set
708 * the property in memory (in the cache). It will not alter the file itself.
709 * @throws PropertyAccessException This is thrown if an error occurs accessing the property.
710 */
711 protected static void setProperty(String sPropertyFile, String sPropertyName, String sValue)
712 throws PropertyAccessException
713 {
714 // Make sure everything is in a good state.
715 //-----------------------------------------
716 checkEnvVarSet();
717 stringIsValid("setProperty", "sPropertyFile", sPropertyFile);
718 stringIsValid("setProperty", "sPropertyName", sPropertyName);
719
720 // Check for null and set it to empty string...
721 //---------------------------------------------
722 String sPropValue = sValue;
723 if (sPropValue == null)
724 {
725 sPropValue = "";
726 }
727
728 // This call is primarily for the case where the file has not
729 // yet been loaded. We need to make sure it gets laoded. After that
730 // if a setProperty is called the mode will be set to Never, and this
731 // call will essentially turn into a NOOP.
732 //---------------------------------------------------------------------
733 checkForRefreshAndLoad(sPropertyFile);
734
735 RefreshInfo oInfo = m_hNextRefresh.get(sPropertyFile);
736 if (oInfo == null)
737 {
738 String sMessage = "Property file: '" + sPropertyFile +
739 "' does not exist. You cannot set a property for a file that does not exist.";
740 log.error(sMessage);
741 throw new PropertyAccessException(sMessage);
742 }
743
744 // Make sure we set this to "Never" refresh...
745 //---------------------------------------------
746 if (oInfo.m_oRefreshMode != RefreshInfo.Mode.NEVER)
747 {
748 synchronized (m_hNextRefresh)
749 {
750 oInfo.m_oRefreshMode = RefreshInfo.Mode.NEVER;
751 oInfo.m_iRefreshMilliseconds = -1;
752 oInfo.m_dtRefreshDate = null;
753 m_hNextRefresh.put(sPropertyFile, oInfo);
754 }
755
756 // Put out a warning that a property file has been modified with a run-time modification.
757 //---------------------------------------------------------------------------------------
758 log.warn("Property File: " + sPropertyFile + " is being changed to 'NEVER' refresh because it is being " +
759 "modified at run-time.");
760 }
761
762 // Now update the property.
763 //-------------------------
764 Properties oProps = m_hAllProps.get(sPropertyFile);
765 if (oProps == null)
766 {
767 String sMessage = "Property file: '" + sPropertyFile +
768 "' does not exist. You cannot set a property for a file that does not exist.";
769 log.error(sMessage);
770 throw new PropertyAccessException(sMessage);
771 }
772 synchronized (m_hNextRefresh)
773 {
774 oProps.setProperty(sPropertyName, sValue);
775 }
776 // Put out a warning that a property file has been modified with a run-time modification.
777 //---------------------------------------------------------------------------------------
778 log.warn("Property File: " + sPropertyFile + ", PropertyName=" + sPropertyName +
779 " is being changed at run-time to:'" + sValue + "'.");
780 }
781
782 /**
783 * This class is used to hold refresh information for a properties file.
784 */
785 private static class RefreshInfo
786 {
787 public static enum Mode {NEVER, ALWAYS, PERIODIC};
788
789 Mode m_oRefreshMode;
790 Date m_dtRefreshDate;
791 int m_iRefreshMilliseconds;
792 }
793}
Note: See TracBrowser for help on using the repository browser.