001/* 002 * Copyright 2024-2025 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright 2024-2025 Ping Identity Corporation 007 * 008 * Licensed under the Apache License, Version 2.0 (the "License"); 009 * you may not use this file except in compliance with the License. 010 * You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, software 015 * distributed under the License is distributed on an "AS IS" BASIS, 016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 017 * See the License for the specific language governing permissions and 018 * limitations under the License. 019 */ 020/* 021 * Copyright (C) 2024-2025 Ping Identity Corporation 022 * 023 * This program is free software; you can redistribute it and/or modify 024 * it under the terms of the GNU General Public License (GPLv2 only) 025 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 026 * as published by the Free Software Foundation. 027 * 028 * This program is distributed in the hope that it will be useful, 029 * but WITHOUT ANY WARRANTY; without even the implied warranty of 030 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 031 * GNU General Public License for more details. 032 * 033 * You should have received a copy of the GNU General Public License 034 * along with this program; if not, see <http://www.gnu.org/licenses>. 035 */ 036package com.unboundid.util; 037 038 039 040import java.util.ArrayList; 041import java.util.Collections; 042import java.util.List; 043import java.util.Map; 044import java.util.Properties; 045import java.util.concurrent.ConcurrentHashMap; 046import java.util.concurrent.atomic.AtomicInteger; 047 048import static com.unboundid.util.UtilityMessages.*; 049 050 051 052/** 053 * This class provides a mechanism for retrieving the values of specified 054 * properties in the form of either Java system properties or process 055 * environment variables (using an alternative name generated from the provided 056 * property name using the 057 * {@link #generateEnvironmentVariableNameFromPropertyName} method). System 058 * properties will be given a higher priority than environment variables, and 059 * the value can be parsed in accordance with a number of syntaxes. 060 */ 061@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 062public final class PropertyManager 063{ 064 /** 065 * A reference to the length of time in milliseconds that property information 066 * should be cached after retrieving it. 067 */ 068 @NotNull private static final AtomicInteger CACHE_DURATION_MILLIS = 069 new AtomicInteger(0); 070 071 072 073 /** 074 * A map containing cached property information. 075 */ 076 @NotNull private static final Map<String,PropertyManagerCacheRecord> CACHE = 077 new ConcurrentHashMap<>(); 078 079 080 081 /** 082 * Prevents this utility class from being instantiated. 083 */ 084 private PropertyManager() 085 { 086 // No implementation is required. 087 } 088 089 090 091 /** 092 * Retrieves the value of the specified system property or environment 093 * variable. 094 * 095 * @param propertyName The name of the system property to retrieve, and to 096 * use to generate an alternative environment variable. 097 * It must not be {@code null} or empty. 098 * 099 * @return The requested value, or {@code null} if it has not been set as 100 * either a system property or an environment variable. 101 */ 102 @Nullable() 103 public static String get(@NotNull final String propertyName) 104 { 105 return get(propertyName, null); 106 } 107 108 109 110 /** 111 * Retrieves the value of the specified system property or environment 112 * variable. 113 * 114 * @param propertyName The name of the system property to retrieve, and to 115 * use to generate an alternative environment variable. 116 * It must not be {@code null} or empty. 117 * @param defaultValue The default value to return if neither the system 118 * property nor associated environment variable have 119 * been set. It may be {@code null} if no default value 120 * should be returned. 121 * 122 * @return The requested value, or {@code null} if it has not been set as 123 * either a system property or an environment variable. 124 */ 125 @Nullable() 126 public static String get(@NotNull final String propertyName, 127 @Nullable final String defaultValue) 128 { 129 // See if there is a valid cache record for the property. If so, then use 130 // it. 131 final int cacheDurationMillis = CACHE_DURATION_MILLIS.get(); 132 if (cacheDurationMillis > 0) 133 { 134 final PropertyManagerCacheRecord cacheRecord = CACHE.get(propertyName); 135 if ((cacheRecord != null) && (! cacheRecord.isExpired())) 136 { 137 return cacheRecord.stringValue(defaultValue); 138 } 139 } 140 141 142 // See if the property is defined via a system property. 143 final String systemPropertyValue = 144 StaticUtils.getSystemProperty(propertyName); 145 if (systemPropertyValue != null) 146 { 147 if (cacheDurationMillis > 0) 148 { 149 CACHE.put(propertyName, new PropertyManagerCacheRecord(propertyName, 150 systemPropertyValue, cacheDurationMillis)); 151 } 152 153 return systemPropertyValue; 154 } 155 156 157 // See if the property is defined via an environment variable. 158 final String environmentVariableValue = 159 StaticUtils.getEnvironmentVariable(propertyName); 160 if (environmentVariableValue != null) 161 { 162 if (cacheDurationMillis > 0) 163 { 164 CACHE.put(propertyName, new PropertyManagerCacheRecord(propertyName, 165 environmentVariableValue, cacheDurationMillis)); 166 } 167 168 return environmentVariableValue; 169 } 170 171 final String alternativeEnvironmentVariableName = 172 generateEnvironmentVariableNameFromPropertyName(propertyName); 173 if (! alternativeEnvironmentVariableName.equals(propertyName)) 174 { 175 final String alternativeEnvironmentVariableValue = 176 StaticUtils.getEnvironmentVariable( 177 alternativeEnvironmentVariableName); 178 if (alternativeEnvironmentVariableValue != null) 179 { 180 if (cacheDurationMillis > 0) 181 { 182 CACHE.put(propertyName, new PropertyManagerCacheRecord(propertyName, 183 alternativeEnvironmentVariableValue, cacheDurationMillis)); 184 } 185 186 return alternativeEnvironmentVariableValue; 187 } 188 } 189 190 191 // If we've gotten here, then the property is not defined. Cache that it's 192 // not defined, if appropriate. 193 if (cacheDurationMillis > 0) 194 { 195 CACHE.put(propertyName, new PropertyManagerCacheRecord(propertyName, 196 null, cacheDurationMillis)); 197 } 198 199 return defaultValue; 200 } 201 202 203 204 /** 205 * Retrieves the value of the specified property or environment variable as a 206 * Boolean value. 207 * 208 * @param propertyName The name of the system property to retrieve, and to 209 * use to generate an alternative environment variable. 210 * It must not be {@code null} or empty. 211 * 212 * @return The Boolean value of the specified property or environment 213 * variable, or {@code null} if neither are set or are set to a 214 * value that cannot be parsed as a Boolean. 215 */ 216 @Nullable() 217 public static Boolean getBoolean(@NotNull final String propertyName) 218 { 219 return getBoolean(propertyName, null); 220 } 221 222 223 224 /** 225 * Retrieves the value of the specified property or environment variable as a 226 * Boolean value. 227 * 228 * @param propertyName The name of the system property to retrieve, and to 229 * use to generate an alternative environment variable. 230 * It must not be {@code null} or empty. 231 * @param defaultValue The default value to return if neither the system 232 * property nor associated environment variable have 233 * been set, or if the value cannot be parsed as a 234 * Boolean. It may be {@code null} if no default value 235 * should be returned. 236 * 237 * @return The Boolean value of the specified property or environment 238 * variable, or the provided default value if neither are set or are 239 * set to a value that cannot be parsed as a Boolean. 240 */ 241 @Nullable() 242 public static Boolean getBoolean(@NotNull final String propertyName, 243 @Nullable final Boolean defaultValue) 244 { 245 return getBoolean(propertyName, defaultValue, false); 246 } 247 248 249 250 /** 251 * Retrieves the value of the specified property or environment variable as a 252 * Boolean value. 253 * 254 * @param propertyName The name of the system property to retrieve, 255 * and to use to generate an alternative 256 * environment variable. It must not be 257 * {@code null} or empty. 258 * @param defaultValue The default value to return if neither the 259 * system property nor associated environment 260 * variable have been set, or if the value cannot 261 * be parsed as a Boolean and 262 * {@code throwOnInvalidValue} is {@code false}. 263 * It may be {@code null} if no default value 264 * should be returned. 265 * @param throwOnInvalidValue Indicates whether this method should throw an 266 * {@code IllegalArgumentException} if the 267 * system property or environment variable is 268 * set but its value cannot be parsed as a 269 * Boolean. 270 * 271 * @return The Boolean value of the specified property or environment 272 * variable, or the provided default value if neither are set or are 273 * set to a value that cannot be parsed as a Boolean and 274 * {@code throwOnInvalidValue} is {@code false}. 275 * 276 * @throws IllegalArgumentException If the property or environment variable 277 * is set, but its value cannot be parsed 278 * as a Boolean, and 279 * {@code throwOnInvalidValue} is 280 * {@code true}. 281 */ 282 @Nullable() 283 public static Boolean getBoolean(@NotNull final String propertyName, 284 @Nullable final Boolean defaultValue, 285 final boolean throwOnInvalidValue) 286 throws IllegalArgumentException 287 { 288 // See if there is a valid cache record for the property. If so, then use 289 // it. 290 final int cacheDurationMillis = CACHE_DURATION_MILLIS.get(); 291 if (cacheDurationMillis > 0) 292 { 293 final PropertyManagerCacheRecord cacheRecord = CACHE.get(propertyName); 294 if ((cacheRecord != null) && (! cacheRecord.isExpired())) 295 { 296 return cacheRecord.booleanValue(defaultValue, throwOnInvalidValue); 297 } 298 } 299 300 301 final String stringValue = get(propertyName); 302 if (stringValue == null) 303 { 304 return defaultValue; 305 } 306 307 final Boolean booleanValue = parseBoolean(stringValue); 308 if (booleanValue == null) 309 { 310 if (throwOnInvalidValue) 311 { 312 throw new IllegalArgumentException( 313 ERR_PROPERTY_MANAGER_NOT_BOOLEAN.get( 314 getIdentifierString(propertyName), stringValue)); 315 } 316 else 317 { 318 return defaultValue; 319 } 320 } 321 else 322 { 323 return booleanValue; 324 } 325 } 326 327 328 329 /** 330 * Attempts to parse the provided string value as a {@code Boolean}. 331 * 332 * @param stringValue The string value to parse. It must not be 333 * {@code null}. 334 * 335 * @return The {@code Boolean} value that was parsed from the given string, 336 * or {@code null} if the provided string could not be parsed as a 337 * {@code Boolean}. 338 */ 339 @Nullable() 340 static Boolean parseBoolean(@NotNull final String stringValue) 341 { 342 final String lowerValue = StaticUtils.toLowerCase(stringValue.trim()); 343 switch (lowerValue) 344 { 345 case "true": 346 case "t": 347 case "yes": 348 case "y": 349 case "on": 350 case "1": 351 return Boolean.TRUE; 352 case "false": 353 case "f": 354 case "no": 355 case "n": 356 case "off": 357 case "0": 358 return Boolean.FALSE; 359 default: 360 return null; 361 } 362 } 363 364 365 366 /** 367 * Retrieves the value of the specified property or environment variable as an 368 * integer. 369 * 370 * @param propertyName The name of the system property to retrieve, and to 371 * use to generate an alternative environment variable. 372 * It must not be {@code null} or empty. 373 * 374 * @return The integer value of the specified property or environment 375 * variable, or {@code null} if neither are set or are set to a 376 * value that cannot be parsed as an integer. 377 */ 378 @Nullable() 379 public static Integer getInt(@NotNull final String propertyName) 380 { 381 return getInt(propertyName, null); 382 } 383 384 385 386 /** 387 * Retrieves the value of the specified property or environment variable as an 388 * integer. 389 * 390 * @param propertyName The name of the system property to retrieve, and to 391 * use to generate an alternative environment variable. 392 * It must not be {@code null} or empty. 393 * @param defaultValue The default value to return if neither the system 394 * property nor associated environment variable have 395 * been set, or if the value cannot be parsed as an 396 * integer. It may be {@code null} if no default value 397 * should be returned. 398 * 399 * @return The integer value of the specified property or environment 400 * variable, or the provided default value if neither are set or are 401 * set to a value that cannot be parsed as an integer. 402 */ 403 @Nullable() 404 public static Integer getInt(@NotNull final String propertyName, 405 @Nullable final Integer defaultValue) 406 { 407 return getInt(propertyName, defaultValue, false); 408 } 409 410 411 412 /** 413 * Retrieves the value of the specified property or environment variable as an 414 * integer. 415 * 416 * @param propertyName The name of the system property to retrieve, 417 * and to use to generate an alternative 418 * environment variable. It must not be 419 * {@code null} or empty. 420 * @param defaultValue The default value to return if neither the 421 * system property nor associated environment 422 * variable have been set, or if the value cannot 423 * be parsed as an integer and 424 * {@code throwOnInvalidValue} is {@code false}. 425 * It may be {@code null} if no default value 426 * should be returned. 427 * @param throwOnInvalidValue Indicates whether this method should throw an 428 * {@code IllegalArgumentException} if the 429 * system property or environment variable is 430 * set but its value cannot be parsed as an 431 * integer. 432 * 433 * @return The integer value of the specified property or environment 434 * variable, or the provided default value if neither are set or are 435 * set to a value that cannot be parsed as an integer and 436 * {@code throwOnInvalidValue} is {@code false}. 437 * 438 * @throws IllegalArgumentException If the property or environment variable 439 * is set, but its value cannot be parsed 440 * as an integer, and 441 * {@code throwOnInvalidValue} is 442 * {@code true}. 443 */ 444 @Nullable() 445 public static Integer getInt(@NotNull final String propertyName, 446 @Nullable final Integer defaultValue, 447 final boolean throwOnInvalidValue) 448 throws IllegalArgumentException 449 { 450 // See if there is a valid cache record for the property. If so, then use 451 // it. 452 final int cacheDurationMillis = CACHE_DURATION_MILLIS.get(); 453 if (cacheDurationMillis > 0) 454 { 455 final PropertyManagerCacheRecord cacheRecord = CACHE.get(propertyName); 456 if ((cacheRecord != null) && (! cacheRecord.isExpired())) 457 { 458 return cacheRecord.intValue(defaultValue, throwOnInvalidValue); 459 } 460 } 461 462 463 final String stringValue = get(propertyName); 464 if (stringValue == null) 465 { 466 return defaultValue; 467 } 468 469 try 470 { 471 return Integer.parseInt(stringValue.trim()); 472 } 473 catch (final Exception e) 474 { 475 Debug.debugException(e); 476 if (throwOnInvalidValue) 477 { 478 throw new IllegalArgumentException( 479 ERR_PROPERTY_MANAGER_NOT_INT.get(getIdentifierString(propertyName), 480 stringValue), 481 e); 482 } 483 else 484 { 485 return defaultValue; 486 } 487 } 488 } 489 490 491 492 /** 493 * Retrieves the value of the specified property or environment variable as a 494 * long. 495 * 496 * @param propertyName The name of the system property to retrieve, and to 497 * use to generate an alternative environment variable. 498 * It must not be {@code null} or empty. 499 * 500 * @return The long value of the specified property or environment variable, 501 * or {@code null} if neither are set or are set to a value that 502 * cannot be parsed as a long. 503 */ 504 @Nullable() 505 public static Long getLong(@NotNull final String propertyName) 506 { 507 return getLong(propertyName, null); 508 } 509 510 511 512 /** 513 * Retrieves the value of the specified property or environment variable as a 514 * long. 515 * 516 * @param propertyName The name of the system property to retrieve, and to 517 * use to generate an alternative environment variable. 518 * It must not be {@code null} or empty. 519 * @param defaultValue The default value to return if neither the system 520 * property nor associated environment variable have 521 * been set, or if the value cannot be parsed as a long. 522 * It may be {@code null} if no default value should be 523 * returned. 524 * 525 * @return The long value of the specified property or environment variable, 526 * or the provided default value if neither are set or are set to a 527 * value that cannot be parsed as a long. 528 */ 529 @Nullable() 530 public static Long getLong(@NotNull final String propertyName, 531 @Nullable final Long defaultValue) 532 { 533 return getLong(propertyName, defaultValue, false); 534 } 535 536 537 538 /** 539 * Retrieves the value of the specified property or environment variable as a 540 * long. 541 * 542 * @param propertyName The name of the system property to retrieve, 543 * and to use to generate an alternative 544 * environment variable. It must not be 545 * {@code null} or empty. 546 * @param defaultValue The default value to return if neither the 547 * system property nor associated environment 548 * variable have been set, or if the value cannot 549 * be parsed as a long and 550 * {@code throwOnInvalidValue} is {@code false}. 551 * It may be {@code null} if no default value 552 * should be returned. 553 * @param throwOnInvalidValue Indicates whether this method should throw an 554 * {@code IllegalArgumentException} if the 555 * system property or environment variable is 556 * set but its value cannot be parsed as a 557 * long. 558 * 559 * @return The long value of the specified property or environment variable, 560 * or the provided default value if neither are set or are set to a 561 * value that cannot be parsed as a long and 562 * {@code throwOnInvalidValue} is {@code false}. 563 * 564 * @throws IllegalArgumentException If the property or environment variable 565 * is set, but its value cannot be parsed 566 * as a long, and 567 * {@code throwOnInvalidValue} is 568 * {@code true}. 569 */ 570 @Nullable() 571 public static Long getLong(@NotNull final String propertyName, 572 @Nullable final Long defaultValue, 573 final boolean throwOnInvalidValue) 574 throws IllegalArgumentException 575 { 576 // See if there is a valid cache record for the property. If so, then use 577 // it. 578 final int cacheDurationMillis = CACHE_DURATION_MILLIS.get(); 579 if (cacheDurationMillis > 0) 580 { 581 final PropertyManagerCacheRecord cacheRecord = CACHE.get(propertyName); 582 if ((cacheRecord != null) && (! cacheRecord.isExpired())) 583 { 584 return cacheRecord.longValue(defaultValue, throwOnInvalidValue); 585 } 586 } 587 588 589 final String stringValue = get(propertyName); 590 if (stringValue == null) 591 { 592 return defaultValue; 593 } 594 595 try 596 { 597 return Long.parseLong(stringValue.trim()); 598 } 599 catch (final Exception e) 600 { 601 Debug.debugException(e); 602 if (throwOnInvalidValue) 603 { 604 throw new IllegalArgumentException( 605 ERR_PROPERTY_MANAGER_NOT_LONG.get( 606 getIdentifierString(propertyName), stringValue), 607 e); 608 } 609 else 610 { 611 return defaultValue; 612 } 613 } 614 } 615 616 617 618 /** 619 * Retrieves the value of the specified property or environment variable as 620 * a list of comma-delimited values. Any spaces around commas will be 621 * trimmed. 622 * 623 * @param propertyName The name of the system property to retrieve, and to 624 * use to generate an alternative environment variable. 625 * It must not be {@code null} or empty. 626 * 627 * @return An unmodifiable list containing the comma-delimited values of the 628 * specified property or environment variable, or an empty list if 629 * neither is set. 630 */ 631 @NotNull() 632 public static List<String> getCommaDelimitedList( 633 @NotNull final String propertyName) 634 { 635 return getCommaDelimitedList(propertyName, true); 636 } 637 638 639 640 /** 641 * Retrieves the value of the specified property or environment variable as 642 * a list of comma-delimited values. Any spaces around commas will be 643 * trimmed. 644 * 645 * @param propertyName The name of the system property to retrieve, and to 646 * use to generate an alternative environment variable. 647 * It must not be {@code null} or empty. 648 * @param trimItems Indicates whether the individual items in the list 649 * should be trimmed to remove leading and/or trailing 650 * spaces. 651 * 652 * @return An unmodifiable list containing the comma-delimited values of the 653 * specified property or environment variable, or an empty list if 654 * neither is set. 655 */ 656 @NotNull() 657 public static List<String> getCommaDelimitedList( 658 @NotNull final String propertyName, 659 final boolean trimItems) 660 { 661 final List<String> items = new ArrayList<>(); 662 663 final String stringValue = get(propertyName); 664 if (stringValue != null) 665 { 666 int startPos = 0; 667 while (true) 668 { 669 final int commaPos = stringValue.indexOf(',', startPos); 670 if (commaPos < 0) 671 { 672 String substring = stringValue.substring(startPos); 673 if (trimItems) 674 { 675 substring = substring.trim(); 676 } 677 678 items.add(substring); 679 break; 680 } 681 else 682 { 683 String substring = stringValue.substring(startPos, commaPos); 684 if (trimItems) 685 { 686 substring = substring.trim(); 687 } 688 689 items.add(substring); 690 startPos = commaPos + 1; 691 } 692 } 693 } 694 695 return Collections.unmodifiableList(items); 696 } 697 698 699 700 /** 701 * Retrieves a {@code Properties} object with values for any of the specified 702 * properties that are currently set. 703 * 704 * @param propertyNames The name of the properties whose values should be 705 * retrieved. It must not be {@code null}, but may be 706 * empty. 707 * 708 * @return A {@code Properties} object with any of the specified properties 709 * that are set as either JVM system properties or environment 710 * variables. It may be empty if none of the specified properties 711 * have been set. 712 */ 713 @NotNull() 714 public static Properties getProperties(@NotNull final String... propertyNames) 715 { 716 final Properties properties = new Properties(); 717 718 for (final String propertyName : propertyNames) 719 { 720 final String propertyValue = get(propertyName); 721 if (propertyValue != null) 722 { 723 properties.setProperty(propertyName, propertyValue); 724 } 725 } 726 727 return properties; 728 } 729 730 731 732 /** 733 * Generates an alternative environment variable name that can be used for a 734 * given property name. All alphabetic letters in the provided name will be 735 * converted to uppercase, and all characters other than ASCII letters and 736 * digits will be converted to underscores. 737 * 738 * @param propertyName The property name to use to generate the environment 739 * variable name. It must not be {@code null} or empty. 740 * 741 * @return The alternative environment variable name generated from the given 742 * property name. 743 */ 744 @NotNull() 745 public static String generateEnvironmentVariableNameFromPropertyName( 746 @NotNull final String propertyName) 747 { 748 final String upperPropertyName = 749 StaticUtils.toUpperCase(propertyName.trim()); 750 751 final int length = upperPropertyName.length(); 752 final StringBuilder buffer = new StringBuilder(length); 753 for (int i=0; i < length; i++) 754 { 755 final char c = upperPropertyName.charAt(i); 756 if (((c >= 'A') && (c <= 'Z')) || 757 ((c >= '0') && (c <= '9'))) 758 { 759 buffer.append(c); 760 } 761 else 762 { 763 buffer.append('_'); 764 } 765 } 766 767 return buffer.toString(); 768 } 769 770 771 772 /** 773 * Retrieves an identifier string that can be used to indicate how the value 774 * of the specified property was obtained. The returned value will be one of: 775 * <UL> 776 * <LI>system property '{propertyName}'</LI> 777 * <LI>environment variable '{propertyName}'</LI> 778 * <LI>environment variable '{alternativeName}'</LI> 779 * </UL> 780 * 781 * @param propertyName The property name for which to retrieve the 782 * identifier. 783 * 784 * @return The identifier string for the provided property name, or 785 * {@code null} if the specified property is not set as either a 786 * system property or an environment variable (including with an 787 * alternative name). 788 */ 789 @Nullable() 790 static String getIdentifierString(@NotNull final String propertyName) 791 { 792 if (StaticUtils.getSystemProperty(propertyName) != null) 793 { 794 return INFO_PROPERTY_MANAGER_SYSTEM_PROPERY_IDENTIFIER.get(propertyName); 795 } 796 797 if (StaticUtils.getEnvironmentVariable(propertyName) != null) 798 { 799 return INFO_PROPERTY_MANAGER_ENVIRONMENT_VARIABLE_IDENTIFIER.get( 800 propertyName); 801 } 802 803 final String alternativeName = 804 generateEnvironmentVariableNameFromPropertyName(propertyName); 805 if (StaticUtils.getEnvironmentVariable(alternativeName) != null) 806 { 807 return INFO_PROPERTY_MANAGER_ENVIRONMENT_VARIABLE_IDENTIFIER.get( 808 alternativeName); 809 } 810 811 return null; 812 } 813 814 815 816 /** 817 * Retrieves the maximum length of time in milliseconds that property values 818 * should be cached for faster retrieval. A value of zero indicates that no 819 * caching should be performed. A value of {@code Integer.MAX_VALUE} 820 * indicates that cache records should never expire. 821 * 822 * @return The maximum length of time in milliseconds that property values 823 * should be cached for faster retrieval. 824 */ 825 public static int getCacheDurationMillis() 826 { 827 return CACHE_DURATION_MILLIS.get(); 828 } 829 830 831 832 /** 833 * Specifies the maximum length of time in milliseconds that property values 834 * should be cached for faster retrieval. 835 * 836 * @param cacheDurationMillis The maximum length of time in milliseconds 837 * that property values should be cached for 838 * faster retrieval. A value that is less than 839 * or equal to zero indicates that values should 840 * not be cached. A value of 841 * {@code Integer.MAX_VALUE} indicates that cache 842 * records should never expire. 843 */ 844 public static void setCacheDurationMillis(final int cacheDurationMillis) 845 { 846 if (cacheDurationMillis > 0) 847 { 848 PropertyManager.CACHE_DURATION_MILLIS.set(cacheDurationMillis); 849 } 850 else 851 { 852 PropertyManager.CACHE_DURATION_MILLIS.set(0); 853 } 854 } 855 856 857 858 /** 859 * Retrieves a handle to the cache. This method is only intended for testing 860 * purposes. 861 * 862 * @return A handle to the cache. 863 */ 864 @NotNull() 865 static Map<String,PropertyManagerCacheRecord> getCache() 866 { 867 return CACHE; 868 } 869 870 871 872 /** 873 * Populates the cache with current values obtained from system properties 874 * and environment variables. This will not have any effect if caching is 875 * disabled. 876 */ 877 public static void populateCache() 878 { 879 clearCache(); 880 881 final int cacheDurationMillis = CACHE_DURATION_MILLIS.get(); 882 if (cacheDurationMillis <= 0) 883 { 884 return; 885 } 886 887 for (final Map.Entry<String,String> envVar : 888 StaticUtils.getEnvironmentVariables().entrySet()) 889 { 890 final String propertyName = envVar.getKey(); 891 final String stringValue = envVar.getValue(); 892 893 CACHE.put(propertyName, new PropertyManagerCacheRecord(propertyName, 894 stringValue, cacheDurationMillis)); 895 } 896 897 for (final Map.Entry<Object,Object> systemProperty : 898 StaticUtils.getSystemProperties().entrySet()) 899 { 900 final String propertyName = String.valueOf(systemProperty.getKey()); 901 final String stringValue = String.valueOf(systemProperty.getValue()); 902 903 CACHE.put(propertyName, new PropertyManagerCacheRecord(propertyName, 904 stringValue, cacheDurationMillis)); 905 } 906 } 907 908 909 910 /** 911 * Clears any cached property information. 912 */ 913 public static void clearCache() 914 { 915 CACHE.clear(); 916 } 917}