98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts/*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Copyright (c) 2005 Sun Microsystems Inc. All Rights Reserved
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * The contents of this file are subject to the terms
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * of the Common Development and Distribution License
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * (the License). You may not use this file except in
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * compliance with the License.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * You can obtain a copy of the License at
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * https://opensso.dev.java.net/public/CDDLv1.0.html or
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * opensso/legal/CDDLv1.0.txt
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * See the License for the specific language governing
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * permission and limitations under the License.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * When distributing Covered Code, include this CDDL
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Header Notice in each file and include the License file
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * at opensso/legal/CDDLv1.0.txt.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * If applicable, add the following below the CDDL Header,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * with the fields enclosed by brackets [] replaced by
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * your own identifying information:
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "Portions Copyrighted [year] [name of copyright owner]"
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts * Portions Copyrighted 2010-2016 ForgeRock AS.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterpackage com.iplanet.am.util;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Maddenimport static org.forgerock.openam.utils.CollectionUtils.asSet;
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Maddenimport com.iplanet.sso.SSOToken;
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Maddenimport com.sun.identity.common.AttributeStruct;
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Maddenimport com.sun.identity.common.PropertiesFinder;
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Maddenimport com.sun.identity.common.configuration.ConfigurationListener;
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Maddenimport com.sun.identity.common.configuration.ConfigurationObserver;
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Maddenimport com.sun.identity.common.configuration.ServerConfiguration;
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Maddenimport com.sun.identity.security.AdminTokenAction;
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Maddenimport com.sun.identity.shared.Constants;
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Maddenimport com.sun.identity.sm.SMSEntry;
71ef1e179613c2e17b9ad5f1c9db6bf533941f9dRobert Wapshott
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.io.FileInputStream;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.io.IOException;
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Maddenimport java.io.PrintWriter;
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Maddenimport java.io.StringWriter;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.net.InetAddress;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.security.AccessController;
2cdbc4fc62ed8b9c2c8ef660adc4fe0188b65407Neil Maddenimport java.util.Collections;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.util.HashMap;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.util.HashSet;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.util.Map;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.util.MissingResourceException;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.util.Properties;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.util.ResourceBundle;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.util.Set;
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Maddenimport java.util.concurrent.atomic.AtomicReference;
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpottsimport javax.annotation.Nullable;
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpottsimport org.forgerock.guava.common.base.Predicate;
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Maddenimport org.forgerock.guava.common.collect.ImmutableMap;
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Maddenimport org.forgerock.guava.common.collect.Maps;
69920e8c9c3fc2f914a89ad905988dbbe0a2c13cNeil Maddenimport org.forgerock.openam.cts.api.CoreTokenConstants;
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Maddenimport org.forgerock.openam.utils.StringUtils;
69920e8c9c3fc2f914a89ad905988dbbe0a2c13cNeil Madden
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * This class provides functionality that allows single-point-of-access to all
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * related system properties.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * <p>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * The system properties can be set in couple of ways: programmatically by
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * calling the <code>initializeProperties</code> method, or can be statically
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * loaded at startup from a file named:
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * <code>AMConfig.[class,properties]</code>.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Setting the properties through the API takes precedence and will replace the
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * properties loaded via file. For statically loading the properties via a file,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * this class tries to first find a class, <code>AMConfig.class</code>, and
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * then a file, <code>AMConfig.properties</code> in the CLASSPATH accessible
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * to this code. The <code>AMConfig.class</code> takes precedence over the
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * flat file <code>AMConfig.properties</code>.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * <p>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * If multiple servers are running, each may have their own configuration file.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * The naming convention for such scenarios is
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * <code>AMConfig-&lt;serverName></code>.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * @supported.all.api
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterpublic class SystemProperties {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Runtime flag to be set, in order to override the path of the
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * configuration file.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public static final String CONFIG_PATH = "com.iplanet.services.configpath";
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Default name of the configuration file.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public static final String CONFIG_FILE_NAME = "serverconfig.xml";
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * New configuration file extension
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public static final String PROPERTIES = "properties";
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public static final String NEWCONFDIR = "NEW_CONF_DIR";
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden private static final String SERVER_NAME_PROPERTY = "server.name";
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden private static final String CONFIG_NAME_PROPERTY = "amconfig";
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden private static final String AMCONFIG_FILE_NAME = "AMConfig";
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden /** Regular expression pattern for a sequence of 1 or more white space characters. */
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden private static final String WHITESPACE = "\\s+";
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden private static final Map<String, AttributeStruct> ATTRIBUTE_MAP = initAttributeMapping();
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden private static final int TAG_START = '%';
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /**
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden * Maps from tags to the system properties that they should be replaced with. System property values containing
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden * these tags will be replaced with the actual values of these properties by {@link #get(String)}.
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden */
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden private static final Map<String, String> TAG_SWAP_PROPERTIES = ImmutableMap.<String, String>builder()
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden .put("%SERVER_PORT%", Constants.AM_SERVER_PORT)
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden .put("%SERVER_URI%", Constants.AM_SERVICES_DEPLOYMENT_DESCRIPTOR)
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden .put("%SERVER_HOST%", Constants.AM_SERVER_HOST)
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden .put("%SERVER_PROTO%", Constants.AM_SERVER_PROTOCOL)
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden .put("%BASE_DIR%", CONFIG_PATH)
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden .put("%SESSION_ROOT_SUFFIX%", CoreTokenConstants.SYS_PROPERTY_SESSION_HA_REPOSITORY_ROOT_SUFFIX)
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden .put("%SESSION_STORE_TYPE%", CoreTokenConstants.SYS_PROPERTY_SESSION_HA_REPOSITORY_TYPE)
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden .build();
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden private static final boolean SITEMONITOR_DISABLED;
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden /**
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden * Reference to the current properties map and tagswap values.
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden */
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden private static final AtomicReference<PropertiesHolder> propertiesHolderRef =
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden new AtomicReference<>(new PropertiesHolder());
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden private static String initError = null;
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden private static String initSecondaryError = null;
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden private static String instanceName = null;
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden /*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Initialization to load the properties file for config information before
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * anything else starts.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster static {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster try {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Load properties from file
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String serverName = System.getProperty(SERVER_NAME_PROPERTY);
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden String configName = System.getProperty(CONFIG_NAME_PROPERTY, AMCONFIG_FILE_NAME);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String fname = null;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (serverName != null) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster serverName = serverName.replace('.', '_');
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster fname = configName + "-" + serverName;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } else {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster fname = configName;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster initializeProperties(fname);
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden PropertiesHolder props = propertiesHolderRef.get();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Get the location of the new configuration file in case
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // of single war deployment
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster try {
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden String newConfigFileLoc = props.getProperty(Constants.AM_NEW_CONFIGFILE_PATH);
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden if (!StringUtils.isEmpty(newConfigFileLoc) && !NEWCONFDIR.equals(newConfigFileLoc)) {
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden String hostName = InetAddress.getLocalHost().getHostName().toLowerCase();
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden String serverURI = props.getProperty(Constants.AM_SERVICES_DEPLOYMENT_DESCRIPTOR).replace('/', '_')
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden .toLowerCase();
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden String fileName = newConfigFileLoc + "/" + AMCONFIG_FILE_NAME + serverURI + hostName +
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden props.getProperty(Constants.AM_SERVER_PORT) + "." + PROPERTIES;
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster try {
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden props = loadProperties(props, fileName);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } catch (IOException ioe) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster try {
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden props = loadProperties(props, newConfigFileLoc + "/" + AMCONFIG_FILE_NAME + "." +
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden PROPERTIES);
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden } catch (IOException ioe2) {
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden saveException(ioe2);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden propertiesHolderRef.set(props);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } catch (Exception ex) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster saveException(ex);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } catch (MissingResourceException e) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Can't print the message to debug due to dependency
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Save it as a String and provide when requested.
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden StringWriter sw = new StringWriter();
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden e.printStackTrace(new PrintWriter(sw));
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden initError = sw.toString();
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden }
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden SITEMONITOR_DISABLED = Boolean.parseBoolean(getProp(Constants.SITEMONITOR_DISABLED, "false"));
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden }
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden private static PropertiesHolder loadProperties(PropertiesHolder props, String file) throws IOException {
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden try (FileInputStream fis = new FileInputStream(file)) {
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden Properties temp = new Properties();
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden temp.load(fis);
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden return props.putAll(temp);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Helper function to handle associated exceptions during initialization of
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * properties using external properties file in a single war deployment.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster static void saveException(Exception ex) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Save it as a String and provide when requested.
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden StringWriter sw = new StringWriter();
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden ex.printStackTrace(new PrintWriter(sw));
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden initSecondaryError = sw.toString();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * This method lets you query for a system property whose value is same as
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * <code>String</code> key. The method first tries to read the property
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * from java.lang.System followed by a lookup in the config file.
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * @param key
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * type <code>String</code>, the key whose value one is
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * looking for.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * @return the value if the key exists; otherwise returns <code>null</code>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public static String get(String key) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden String answer = null;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden // look up values in SMS services only if in server mode.
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden if (isServerMode() || SITEMONITOR_DISABLED) {
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden AttributeStruct ast = ATTRIBUTE_MAP.get(key);
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden if (ast != null) {
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden answer = PropertiesFinder.getProperty(key, ast);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden if (answer == null) {
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden answer = getProp(key);
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden final Map<String, String> tagswapValues = propertiesHolderRef.get().tagSwapValues;
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden if (answer != null && tagswapValues != null && answer.indexOf(TAG_START) != -1) {
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden for (Map.Entry<String, String> tagSwapEntry : tagswapValues.entrySet()) {
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden String k = tagSwapEntry.getKey();
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden String val = tagSwapEntry.getValue();
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden if (k.equals("%SERVER_URI%")) {
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden if (!StringUtils.isEmpty(val)) {
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden if (val.charAt(0) == '/') {
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden answer = answer.replaceAll("/%SERVER_URI%", val);
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden String lessSlash = val.substring(1);
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden answer = answer.replaceAll("%SERVER_URI%", lessSlash);
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden } else {
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden answer = answer.replaceAll(k, val);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden } else {
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden answer = answer.replaceAll(k, val);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden if (answer.contains("%ROOT_SUFFIX%")) {
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden answer = answer.replaceAll("%ROOT_SUFFIX%", SMSEntry.getAMSdkBaseDN());
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden return answer;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private static String getProp(String key, String def) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String value = getProp(key);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return ((value == null) ? def : value);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private static String getProp(String key) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String answer = System.getProperty(key);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (answer == null) {
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden answer = propertiesHolderRef.get().getProperty(key);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return answer;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * This method lets you query for a system property whose value is same as
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * <code>String</code> key.
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * @param key the key whose value one is looking for.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * @param def the default value if the key does not exist.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * @return the value if the key exists; otherwise returns default value.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public static String get(String key, String def) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String value = get(key);
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden return value == null ? def : value;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Returns the property value as a boolean
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * @param key the key whose value one is looking for.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * @return the boolean value if the key exists; otherwise returns false
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public static boolean getAsBoolean(String key) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String value = get(key);
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden return Boolean.parseBoolean(value);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
751ffbacd21180fbc0849885f30c91425fcee44ajeff.schenk
751ffbacd21180fbc0849885f30c91425fcee44ajeff.schenk /**
751ffbacd21180fbc0849885f30c91425fcee44ajeff.schenk * Returns the property value as a boolean
751ffbacd21180fbc0849885f30c91425fcee44ajeff.schenk *
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden * @param key the property name.
751ffbacd21180fbc0849885f30c91425fcee44ajeff.schenk * @param defaultValue value if key is not found.
ca66273b61a8889f097081b01b6ff9a5f5801064Peter Major * @return the boolean value if the key exists; otherwise the default value
751ffbacd21180fbc0849885f30c91425fcee44ajeff.schenk */
751ffbacd21180fbc0849885f30c91425fcee44ajeff.schenk public static boolean getAsBoolean(String key, boolean defaultValue) {
751ffbacd21180fbc0849885f30c91425fcee44ajeff.schenk String value = get(key);
751ffbacd21180fbc0849885f30c91425fcee44ajeff.schenk
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden if (value == null) {
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden return defaultValue;
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden }
751ffbacd21180fbc0849885f30c91425fcee44ajeff.schenk
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden return Boolean.parseBoolean(value);
751ffbacd21180fbc0849885f30c91425fcee44ajeff.schenk }
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott /**
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott * @param key The System Property key to lookup.
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott * @param defaultValue If the property was not set, or could not be parsed to an int.
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott * @return Either the defaultValue, or the numeric value assigned to the System Property.
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott */
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott public static int getAsInt(String key, int defaultValue) {
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott String value = get(key);
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott if (value == null) {
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott return defaultValue;
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott }
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott try {
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott return Integer.parseInt(value);
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott } catch (NumberFormatException e) {
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott return defaultValue;
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott }
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott }
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell /**
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell * @param key The System Property key to lookup.
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell * @param defaultValue If the property was not set, or could not be parsed to a long.
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell * @return Either the defaultValue, or the numeric value assigned to the System Property.
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell */
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell public static long getAsLong(String key, long defaultValue) {
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell String value = get(key);
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell if (value == null) {
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell return defaultValue;
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell }
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell try {
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell return Long.parseLong(value);
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell } catch (NumberFormatException e) {
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell return defaultValue;
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell }
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell }
cc7c18212481f5e9ee508afe2ffcaecb6b9330f5Craig McDonnell
2cdbc4fc62ed8b9c2c8ef660adc4fe0188b65407Neil Madden /**
2cdbc4fc62ed8b9c2c8ef660adc4fe0188b65407Neil Madden * Parses a system property as a set of strings by splitting the value on the given delimiter expression.
2cdbc4fc62ed8b9c2c8ef660adc4fe0188b65407Neil Madden *
2cdbc4fc62ed8b9c2c8ef660adc4fe0188b65407Neil Madden * @param key The System Property key to lookup.
2cdbc4fc62ed8b9c2c8ef660adc4fe0188b65407Neil Madden * @param delimiterRegex The regular expression to use to split the value into elements in the set.
2cdbc4fc62ed8b9c2c8ef660adc4fe0188b65407Neil Madden * @param defaultValue The default set to return if the property does not exist.
2cdbc4fc62ed8b9c2c8ef660adc4fe0188b65407Neil Madden * @return the value of the property parsed as a set of strings.
2cdbc4fc62ed8b9c2c8ef660adc4fe0188b65407Neil Madden */
2cdbc4fc62ed8b9c2c8ef660adc4fe0188b65407Neil Madden public static Set<String> getAsSet(String key, String delimiterRegex, Set<String> defaultValue) {
2cdbc4fc62ed8b9c2c8ef660adc4fe0188b65407Neil Madden String value = get(key);
2cdbc4fc62ed8b9c2c8ef660adc4fe0188b65407Neil Madden if (value == null || value.trim().isEmpty()) {
2cdbc4fc62ed8b9c2c8ef660adc4fe0188b65407Neil Madden return defaultValue;
2cdbc4fc62ed8b9c2c8ef660adc4fe0188b65407Neil Madden }
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts return asSet(value.split(delimiterRegex));
2cdbc4fc62ed8b9c2c8ef660adc4fe0188b65407Neil Madden }
2cdbc4fc62ed8b9c2c8ef660adc4fe0188b65407Neil Madden
2cdbc4fc62ed8b9c2c8ef660adc4fe0188b65407Neil Madden /**
2cdbc4fc62ed8b9c2c8ef660adc4fe0188b65407Neil Madden * Parses a system property as a set of strings by splitting the value on the given delimiter expression.
2cdbc4fc62ed8b9c2c8ef660adc4fe0188b65407Neil Madden *
2cdbc4fc62ed8b9c2c8ef660adc4fe0188b65407Neil Madden * @param key The System Property key to lookup.
2cdbc4fc62ed8b9c2c8ef660adc4fe0188b65407Neil Madden * @param delimiterRegex The regular expression to use to split the value into elements in the set.
2cdbc4fc62ed8b9c2c8ef660adc4fe0188b65407Neil Madden * @return the value of the property parsed as a set of strings or an empty set if no match is found.
2cdbc4fc62ed8b9c2c8ef660adc4fe0188b65407Neil Madden */
2cdbc4fc62ed8b9c2c8ef660adc4fe0188b65407Neil Madden public static Set<String> getAsSet(String key, String delimiterRegex) {
2cdbc4fc62ed8b9c2c8ef660adc4fe0188b65407Neil Madden return getAsSet(key, delimiterRegex, Collections.<String>emptySet());
2cdbc4fc62ed8b9c2c8ef660adc4fe0188b65407Neil Madden }
2cdbc4fc62ed8b9c2c8ef660adc4fe0188b65407Neil Madden
2cdbc4fc62ed8b9c2c8ef660adc4fe0188b65407Neil Madden /**
2cdbc4fc62ed8b9c2c8ef660adc4fe0188b65407Neil Madden * Parses a system property as a set of strings by splitting the value on white space characters.
2cdbc4fc62ed8b9c2c8ef660adc4fe0188b65407Neil Madden *
2cdbc4fc62ed8b9c2c8ef660adc4fe0188b65407Neil Madden * @param key The System Property key to lookup.
2cdbc4fc62ed8b9c2c8ef660adc4fe0188b65407Neil Madden * @return the value of the property parsed as a set of strings or an empty set if no match is found.
2cdbc4fc62ed8b9c2c8ef660adc4fe0188b65407Neil Madden */
2cdbc4fc62ed8b9c2c8ef660adc4fe0188b65407Neil Madden public static Set<String> getAsSet(String key) {
2cdbc4fc62ed8b9c2c8ef660adc4fe0188b65407Neil Madden return getAsSet(key, WHITESPACE);
2cdbc4fc62ed8b9c2c8ef660adc4fe0188b65407Neil Madden }
2cdbc4fc62ed8b9c2c8ef660adc4fe0188b65407Neil Madden
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /**
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden * Returns all the properties defined and their values. This is a defensive copy of the properties and so updates
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden * to the returned object will not be reflected in the actual properties used by OpenAM.
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden *
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden * @return Properties object with a copy of all the key value pairs.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public static Properties getProperties() {
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden Properties properties = new Properties();
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden properties.putAll(propertiesHolderRef.get().properties);
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden return properties;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * This method lets you get all the properties defined and their values. The
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * method first tries to load the properties from java.lang.System followed
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * by a lookup in the config file.
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * @return Properties object with all the key value pairs.
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public static Properties getAll() {
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden Properties properties = new Properties();
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden properties.putAll(propertiesHolderRef.get().properties);
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden // Iterate over the System Properties & add them in result obj
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden properties.putAll(System.getProperties());
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden return properties;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * This method lets you query for all the platform properties defined and
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * their values. Returns a Properties object with all the key value pairs.
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * @deprecated use <code>getAll()</code>
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * @return the platform properties
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public static Properties getPlatform() {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return getAll();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Initializes properties bundle from the <code>file<code>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * passed.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * @param file type <code>String</code>, file name for the resource bundle
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * @exception MissingResourceException
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden public static void initializeProperties(String file) throws MissingResourceException {
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden Properties props = new Properties();
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden ResourceBundle bundle = ResourceBundle.getBundle(file);
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden // Copy the properties to props
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden for (String key : bundle.keySet()) {
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden props.put(key, bundle.getString(key));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden initializeProperties(props, false, false);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden public static void initializeProperties(Properties properties) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster initializeProperties(properties, false);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /**
8d3140b524c0e28c0a49dc7c7d481123ef3cfe11Chris Lee * Initializes the properties to be used by OpenAM. Ideally this
8d3140b524c0e28c0a49dc7c7d481123ef3cfe11Chris Lee * must be called first before any other method is called within OpenAM.
8d3140b524c0e28c0a49dc7c7d481123ef3cfe11Chris Lee * This method provides a programmatic way to set the properties, and will
8d3140b524c0e28c0a49dc7c7d481123ef3cfe11Chris Lee * override similar properties if loaded for a properties file.
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden *
8d3140b524c0e28c0a49dc7c7d481123ef3cfe11Chris Lee * @param properties properties for OpenAM
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * @param reset <code>true</code> to reset existing properties.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden public static void initializeProperties(Properties properties, boolean reset) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster initializeProperties(properties, reset, false);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /**
8d3140b524c0e28c0a49dc7c7d481123ef3cfe11Chris Lee * Initializes the properties to be used by OpenAM. Ideally this
8d3140b524c0e28c0a49dc7c7d481123ef3cfe11Chris Lee * must be called first before any other method is called within OpenAM.
8d3140b524c0e28c0a49dc7c7d481123ef3cfe11Chris Lee * This method provides a programmatic way to set the properties, and will
8d3140b524c0e28c0a49dc7c7d481123ef3cfe11Chris Lee * override similar properties if loaded for a properties file.
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden *
8d3140b524c0e28c0a49dc7c7d481123ef3cfe11Chris Lee * @param properties properties for OpenAM.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * @param reset <code>true</code> to reset existing properties.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * @param withDefaults <code>true</code> to include default properties.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden public static void initializeProperties(Properties properties, boolean reset, boolean withDefaults) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Properties defaultProp = null;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (withDefaults) {
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden SSOToken appToken = AccessController.doPrivileged(AdminTokenAction.getInstance());
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster defaultProp = ServerConfiguration.getDefaults(appToken);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden PropertiesHolder oldProps;
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden PropertiesHolder newProps;
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden do {
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden oldProps = propertiesHolderRef.get();
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden final Properties combined = new Properties();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (defaultProp != null) {
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden combined.putAll(defaultProp);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (!reset) {
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden combined.putAll(oldProps.properties);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden combined.putAll(properties);
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden newProps = new PropertiesHolder(Maps.fromProperties(combined));
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden } while (!propertiesHolderRef.compareAndSet(oldProps, newProps));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /**
8d3140b524c0e28c0a49dc7c7d481123ef3cfe11Chris Lee * Initializes a property to be used by OpenAM. Ideally this
8d3140b524c0e28c0a49dc7c7d481123ef3cfe11Chris Lee * must be called first before any other method is called within OpenAM.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * This method provides a programmatic way to set a specific property, and
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * will override similar property if loaded for a properties file.
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * @param propertyName property name.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * @param propertyValue property value.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden public static void initializeProperties(String propertyName, String propertyValue) {
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden Properties newProps = new Properties();
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden newProps.put(propertyName, propertyValue);
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden initializeProperties(newProps, false, false);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Returns a counter for last modification. The counter is incremented if
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * the properties are changed by calling the following method
8d3140b524c0e28c0a49dc7c7d481123ef3cfe11Chris Lee * <code>initializeProperties</code>. This is a convenience method for
8d3140b524c0e28c0a49dc7c7d481123ef3cfe11Chris Lee * applications to track changes to OpenAM properties.
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * @return counter of the last modification
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public static long lastModified() {
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden return propertiesHolderRef.get().lastModified;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Returns error messages during initialization, else <code>null</code>.
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * @return error messages during initialization
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public static String getInitializationError() {
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden return initError;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Returns error messages during initialization using the single war
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * deployment, else <code>null</code>.
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden *
8d3140b524c0e28c0a49dc7c7d481123ef3cfe11Chris Lee * @return error messages during initialization of OpenAM as single war
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public static String getSecondaryInitializationError() {
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden return initSecondaryError;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Sets the server instance name of which properties are retrieved
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * to initialized this object.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * @param name Server instance name.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public static void setServerInstanceName(String name) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster instanceName = name;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Returns the server instance name of which properties are retrieved
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * to initialized this object.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * @return Server instance name.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public static String getServerInstanceName() {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return instanceName;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Returns <code>true</code> if instance is running in server mode.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * @return <code>true</code> if instance is running in server mode.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public static boolean isServerMode() {
69920e8c9c3fc2f914a89ad905988dbbe0a2c13cNeil Madden return IsServerModeHolder.isServerMode;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Returns the property name to service attribute schema name mapping.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * @return Property name to service attribute schema name mapping.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public static Map getAttributeMap() {
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden return ATTRIBUTE_MAP;
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden }
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden private static Map<String, AttributeStruct> initAttributeMapping() {
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden final Map<String, AttributeStruct> attributeMapping = new HashMap<>();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster try {
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden ResourceBundle rb = ResourceBundle.getBundle("serverAttributeMap");
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden for (String propertyName : rb.keySet()) {
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden attributeMapping.put(propertyName, new AttributeStruct(rb.getString(propertyName)));
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden }
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden } catch (MissingResourceException mse) {
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden // No Resource Bundle Found, Continue.
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden // Could be in Test Mode.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden return Collections.unmodifiableMap(attributeMapping);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
69920e8c9c3fc2f914a89ad905988dbbe0a2c13cNeil Madden
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden
69920e8c9c3fc2f914a89ad905988dbbe0a2c13cNeil Madden /**
69920e8c9c3fc2f914a89ad905988dbbe0a2c13cNeil Madden * Lazy initialisation holder idiom for server mode flag as this is read frequently but never changes.
69920e8c9c3fc2f914a89ad905988dbbe0a2c13cNeil Madden */
69920e8c9c3fc2f914a89ad905988dbbe0a2c13cNeil Madden private static final class IsServerModeHolder {
69920e8c9c3fc2f914a89ad905988dbbe0a2c13cNeil Madden // use getProp and not get method to avoid infinite loop
69920e8c9c3fc2f914a89ad905988dbbe0a2c13cNeil Madden private static final boolean isServerMode = Boolean.parseBoolean(getProp(Constants.SERVER_MODE, "false"));
69920e8c9c3fc2f914a89ad905988dbbe0a2c13cNeil Madden }
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts /**
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts * A singleton enum for the configuration listeners, which will be lazily initialized on first use. The code
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts * here cannot be added to the {@code SystemProperties} class initialization as it would create a cyclic
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts * dependency on the static initialization of {@code ConfigurationObserver}.
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts */
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts private enum Listeners {
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts INSTANCE;
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts private final Map<String, ServicePropertiesConfigurationListener> servicePropertiesListeners;
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts private final ServicePropertiesConfigurationListener platformServicePropertiesListener;
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts Listeners() {
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts servicePropertiesListeners = new HashMap<>();
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts platformServicePropertiesListener = new ServicePropertiesConfigurationListener();
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts Map<String, Set<String>> services = new HashMap<>();
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden for (Map.Entry<String, AttributeStruct> property : ATTRIBUTE_MAP.entrySet()) {
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts String serviceName = property.getValue().getServiceName();
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts if (!services.containsKey(serviceName)) {
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts services.put(serviceName, new HashSet<String>());
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts }
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts services.get(serviceName).add(property.getKey());
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts }
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts ConfigurationObserver configurationObserver = ConfigurationObserver.getInstance();
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts for (final Map.Entry<String, Set<String>> service : services.entrySet()) {
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts if (!Constants.SVC_NAME_PLATFORM.equals(service.getKey())) {
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts Set<String> properties = service.getValue();
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts ServicePropertiesConfigurationListener listener =
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts new ServicePropertiesConfigurationListener(properties);
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts for (String property : properties) {
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts servicePropertiesListeners.put(property, listener);
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts }
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts configurationObserver.addServiceListener(listener, new Predicate<String>() {
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts @Override
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts public boolean apply(@Nullable String s) {
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts return s != null && s.equals(service.getKey());
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts }
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts });
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts }
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts }
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts configurationObserver.addServiceListener(platformServicePropertiesListener, new Predicate<String>() {
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts @Override
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts public boolean apply(@Nullable String s) {
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts return Constants.SVC_NAME_PLATFORM.equals(s);
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts }
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts });
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts }
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts }
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts /**
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts * A listener for the properties that are provided by a single service. Property values are cached so that
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts * property listeners are only notified when the property(-ies) they are observing have changed.
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts */
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts private static final class ServicePropertiesConfigurationListener implements ConfigurationListener {
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts private final Map<String, Set<ConfigurationListener>> propertyListeners = new HashMap<>();
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts private final Map<String, String> propertyValues = new HashMap<>();
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts private ServicePropertiesConfigurationListener(Set<String> propertyNames) {
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts for (String propertyName : propertyNames) {
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts registerPropertyName(propertyName);
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts }
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts }
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts private void registerPropertyName(String propertyName) {
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts propertyListeners.put(propertyName, Collections.synchronizedSet(new HashSet<ConfigurationListener>()));
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts }
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts private ServicePropertiesConfigurationListener() {
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts // nothing to see here
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts }
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts @Override
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts public void notifyChanges() {
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts Set<ConfigurationListener> affectedListeners = new HashSet<>();
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts for (Map.Entry<String, Set<ConfigurationListener>> propertyListeners : this.propertyListeners.entrySet()) {
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts String propertyName = propertyListeners.getKey();
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts String value = get(propertyName);
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts String oldValue = propertyValues.get(propertyName);
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts if (value != null && !value.equals(oldValue) || value == null && oldValue != null) {
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts Set<ConfigurationListener> listeners = propertyListeners.getValue();
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts for (ConfigurationListener listener : listeners) {
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts affectedListeners.add(listener);
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts }
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts propertyValues.put(propertyName, value);
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts }
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts }
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts for (ConfigurationListener listener : affectedListeners) {
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts listener.notifyChanges();
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts }
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts }
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts }
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts /**
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts * Listen for runtime changes to a system property value. Only values that are stored in the SMS will
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts * be changed at runtime. See {@code serverdefaults.properties}, {@code amPlatform.xml} and
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts * {@code serverAttributeMap.properties}.
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts *
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts * @param listener The listener to call when one of the provided properties has changed.
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts * @param properties The list of properties that should be observed. A change in any one of these properties
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts * will cause the listener to be notified.
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts */
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts public static void observe(ConfigurationListener listener, String... properties) {
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts for (String property : properties) {
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts ServicePropertiesConfigurationListener serviceListener =
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts Listeners.INSTANCE.servicePropertiesListeners.get(property);
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts if (serviceListener == null) {
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts serviceListener = Listeners.INSTANCE.platformServicePropertiesListener;
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts }
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts synchronized (serviceListener) {
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts if (!serviceListener.propertyListeners.containsKey(property)) {
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts serviceListener.registerPropertyName(property);
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts }
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts serviceListener.propertyListeners.get(property).add(listener);
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts }
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts }
98ea99a9d0a5253440a949279650e7d229051ee7James Phillpotts }
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden /**
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden * Holds the current properties map together with the tagswap values and last updated timestamp to allow atomic
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden * updates of all three as one unit without locking. This is an immutable structure that is intended to be used
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden * with an AtomicReference.
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden */
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden private static final class PropertiesHolder {
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden private final Map<String, String> properties;
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden private final Map<String, String> tagSwapValues;
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden private final long lastModified;
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden PropertiesHolder() {
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden this.properties = Collections.emptyMap();
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden this.tagSwapValues = Collections.emptyMap();
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden this.lastModified = System.currentTimeMillis();
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden }
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden PropertiesHolder(final Map<String, String> properties) {
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden Map<String, String> tagSwapMap = new HashMap<>();
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden for (Map.Entry<String, String> tagSwapEntry : TAG_SWAP_PROPERTIES.entrySet()) {
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden String tag = tagSwapEntry.getKey();
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden String propertyName = tagSwapEntry.getValue();
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden String val = System.getProperty(propertyName);
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden if (val == null) {
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden val = properties.get(propertyName);
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden }
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden tagSwapMap.put(tag, val);
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden }
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden this.properties = Collections.unmodifiableMap(properties);
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden this.tagSwapValues = Collections.unmodifiableMap(tagSwapMap);
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden this.lastModified = System.currentTimeMillis();
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden }
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden String getProperty(String name) {
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden return properties.get(name);
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden }
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden PropertiesHolder putAll(Properties newProperties) {
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden return new PropertiesHolder(Maps.fromProperties(newProperties));
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden }
6f4585ccfd5c6dac45cc93a0110ea8ad255315ffNeil Madden }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster}