org.rhq.enterprise.communications.ServiceContainerConfiguration Maven / Gradle / Ivy
/*
* RHQ Management Platform
* Copyright (C) 2005-2008 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package org.rhq.enterprise.communications;
import java.io.File;
import java.lang.management.ManagementFactory;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;
import mazz.i18n.Logger;
import org.jboss.remoting.security.SSLSocketBuilder;
import org.rhq.enterprise.communications.command.client.RemoteInputStream;
import org.rhq.enterprise.communications.command.client.RemoteOutputStream;
import org.rhq.enterprise.communications.command.impl.echo.server.EchoCommandService;
import org.rhq.enterprise.communications.command.impl.identify.server.IdentifyCommandService;
import org.rhq.enterprise.communications.command.impl.stream.server.RemoteInputStreamCommandService;
import org.rhq.enterprise.communications.command.impl.stream.server.RemoteOutputStreamCommandService;
import org.rhq.enterprise.communications.command.server.CommandAuthenticator;
import org.rhq.enterprise.communications.i18n.CommI18NFactory;
import org.rhq.enterprise.communications.i18n.CommI18NResourceKeys;
import org.rhq.enterprise.communications.util.ConcurrencyManager;
/**
* Just provides some convienence methods to extract the service container configuration properties. These are remoting
* server configuration properties that are common on both the RHQ Server and RHQ Agent used to configure the
* communications services.
*
* @author John Mazzitelli
*/
public class ServiceContainerConfiguration {
/**
* Logger
*/
private static final Logger LOG = CommI18NFactory.getLogger(ServiceContainerConfiguration.class);
/**
* The configuration properties this object wraps. This must be either the RHQ Server or RHQ Agent preferences node.
*/
private final Preferences m_preferences;
/**
* Wraps a preferences object in this instance.
*
* @param prefs the service container configuration preferences
*
* @throws IllegalArgumentException if prefs
is null
*/
public ServiceContainerConfiguration(Preferences prefs) {
if (prefs == null) {
throw new IllegalArgumentException("prefs=null");
}
m_preferences = prefs;
}
/**
* Returns the raw preferences containing the service container configuration.
*
* @return the configuration preferences
*/
public Preferences getPreferences() {
return m_preferences;
}
/**
* Returns the version of the configuration schema.
*
* @return configuration version; if the configuration isn't versioned, 0 is returned
*/
public int getServiceContainerConfigurationVersion() {
int value = m_preferences.getInt(ServiceContainerConfigurationConstants.CONFIG_SCHEMA_VERSION, 0);
return value;
}
/**
* This tags the existing preferences by setting the configuration schema version preference appropriately.
*/
public void tagWithServiceContainerConfigurationVersion() {
m_preferences.putInt(ServiceContainerConfigurationConstants.CONFIG_SCHEMA_VERSION,
ServiceContainerConfigurationConstants.CURRENT_CONFIG_SCHEMA_VERSION);
flush(ServiceContainerConfigurationConstants.CONFIG_SCHEMA_VERSION);
}
/**
* Returns the global concurrency limit on the number of commands that are allowed to be received concurrently (i.e.
* the counting semaphore name as known to the {@link ConcurrencyManager}).
*
* If this returns a value of 0 or less, there will be no global limit on the number of messages that can be
* received and processed concurrently.
*
* @return the global concurrency limit value
*/
public int getGlobalConcurrencyLimit() {
int value = m_preferences.getInt(ServiceContainerConfigurationConstants.GLOBAL_CONCURRENCY_LIMIT, 0);
return value;
}
/**
* Returns the name of the MBeanServer that will be created to house all the services. This is actually the default
* domain name of the MBeanServer. If an MBeanServer already exists and is registered with this default domain name,
* it will be used to house the communications services. If the MBeanServer name does not exist in the
* configuration, null
will be returned, which indicates that the
* {@link ManagementFactory#getPlatformMBeanServer() JVM's platform MBeanServer} should be used.
*
* @return the MBeanServer name
*/
public String getMBeanServerName() {
String value = m_preferences.get(ServiceContainerConfigurationConstants.MBEANSERVER_NAME, null);
return value;
}
/**
* Returns true
if the communication services should be disabled, false
if they should be
* created normally. It is rare that you would want to configure this setting to be true
.
*
* @return the flag to indicate if communications should be disabled
*/
public boolean isCommunicationsDisabled() {
boolean value = m_preferences.getBoolean(ServiceContainerConfigurationConstants.DISABLE_COMMUNICATIONS,
ServiceContainerConfigurationConstants.DEFAULT_DISABLE_COMMUNICATIONS);
return value;
}
/**
* Returns the data directory where all internally persisted data can be written to. If the data directory does not
* exist, it will be created.
*
* Because this does alittle extra work, it may not be suitable to call if you just want to get the value of the
* data directory or if you just want to know if its defined or not. In those instances, use
* {@link #getDataDirectoryIfDefined()} instead.
*
* @return the data directory
*/
public File getDataDirectory() {
String dirStr = m_preferences.get(ServiceContainerConfigurationConstants.DATA_DIRECTORY,
ServiceContainerConfigurationConstants.DEFAULT_DATA_DIRECTORY);
File dir = new File(dirStr);
if (!dir.exists()) {
dir.mkdirs();
}
return dir;
}
/**
* This will return the data directory string as found in the preferences. If the data directory is not defined in
* the preferences, null
is returned.
*
* @return the data directory string as defined in the preferences or null
if it is not defined
*
* @see #getDataDirectory()
*/
public String getDataDirectoryIfDefined() {
String dir_str = m_preferences.get(ServiceContainerConfigurationConstants.DATA_DIRECTORY, null);
return dir_str;
}
/**
* Returns the flag to indicate if the multicast detector should be enabled or not.
*
* @return the multicast detector enable flag (true
means the detector should be enabled)
*/
public boolean isMulticastDetectorEnabled() {
boolean value = m_preferences.getBoolean(ServiceContainerConfigurationConstants.MULTICASTDETECTOR_ENABLED,
ServiceContainerConfigurationConstants.DEFAULT_MULTICASTDETECTOR_ENABLED);
return value;
}
/**
* Returns the multicast detector's multicast address used for network registry messages (servers coming and going).
* This is the IP of the multicast group that the detector will join.
*
* @return the multicast detector multicast address (null
if not set in the preferences)
*/
public String getMulticastDetectorMulticastAddress() {
String value = m_preferences.get(ServiceContainerConfigurationConstants.MULTICASTDETECTOR_ADDRESS, null);
return value;
}
/**
* Returns the multicast detector's bind address which is what the network interface binds to.
*
* @return the multicast detector bind address (null
if not set in the preferences)
*/
public String getMulticastDetectorBindAddress() {
String value = m_preferences.get(ServiceContainerConfigurationConstants.MULTICASTDETECTOR_BINDADDRESS, null);
return value;
}
/**
* Returns the multicast detector's default time delay. This is the amount of time, in milliseconds, which can
* elapse without receiving a detection event before suspecting that a server is dead and performing an explicit
* invocation on it to verify it is alive. If this invocation, or ping, fails, the server will be removed from the
* network registry. This should be greater than {@link #getMulticastDetectorHeartbeatTimeDelay()}.
*
* @return the multicast detector default time delay (Long.MIN_VALUE
if not set in the preferences)
*/
public long getMulticastDetectorDefaultTimeDelay() {
long value = m_preferences.getLong(ServiceContainerConfigurationConstants.MULTICASTDETECTOR_DEFAULT_TIMEDELAY,
Long.MIN_VALUE);
return value;
}
/**
* Returns the multicast detector's heartbeat time delay. This is the amount of time to wait between sending (and
* sometimes receiving) detection messages. This should be less than {@link #getMulticastDetectorDefaultTimeDelay()}
* .
*
* @return the multicast detector heartbeat time delay (Long.MIN_VALUE
if not set in the preferences)
*/
public long getMulticastDetectorHeartbeatTimeDelay() {
long value = m_preferences.getLong(
ServiceContainerConfigurationConstants.MULTICASTDETECTOR_HEARTBEAT_TIMEDELAY, Long.MIN_VALUE);
return value;
}
/**
* Returns the multicast detector's port.
*
* @return the multicast detector port (Integer.MIN_VALUE
if not set in the preferences)
*/
public int getMulticastDetectorPort() {
int value = m_preferences.getInt(ServiceContainerConfigurationConstants.MULTICASTDETECTOR_PORT,
Integer.MIN_VALUE);
return value;
}
/**
* Returns the connector's RHQ type (indicating if the remoting server resides in the RHQ Server or RHQ Agent).
*
* @return the RHQ type
*/
public String getConnectorRHQType() {
String value = m_preferences.get(ServiceContainerConfigurationConstants.CONNECTOR_RHQTYPE,
ServiceContainerConfigurationConstants.DEFAULT_CONNECTOR_RHQTYPE);
return value;
}
/**
* Returns the connector's transport type (socket, http, etc).
*
* @return the connector transport type
*/
public String getConnectorTransport() {
String value = m_preferences.get(ServiceContainerConfigurationConstants.CONNECTOR_TRANSPORT,
ServiceContainerConfigurationConstants.DEFAULT_CONNECTOR_TRANSPORT);
return value;
}
/**
* Returns the connector's bind address.
*
* @return the connector bind address
*/
public String getConnectorBindAddress() {
String defaultBindAddress;
try {
defaultBindAddress = InetAddress.getLocalHost().getHostAddress();
} catch (UnknownHostException e) {
defaultBindAddress = "127.0.0.1";
}
String value = m_preferences.get(ServiceContainerConfigurationConstants.CONNECTOR_BIND_ADDRESS,
defaultBindAddress);
return value;
}
/**
* Returns the connector's bind port.
*
* @return the connector's bind port
*/
public int getConnectorBindPort() {
int value = m_preferences.getInt(ServiceContainerConfigurationConstants.CONNECTOR_BIND_PORT,
ServiceContainerConfigurationConstants.DEFAULT_CONNECTOR_BIND_PORT);
return value;
}
/**
* Returns the connector's transport parameters which are used to further customize the connector and its transport
* subsystem.
*
* @return the connector transport parameters
*/
public String getConnectorTransportParams() {
String value = m_preferences.get(ServiceContainerConfigurationConstants.CONNECTOR_TRANSPORT_PARAMS,
ServiceContainerConfigurationConstants.DEFAULT_CONNECTOR_TRANSPORT_PARAMS);
// see BZ 1166383
final String requiredParamName = "generalizeSocketException";
if (value != null) {
if (!value.contains(requiredParamName)) {
if (value.startsWith("/")) {
if (!value.contains("/?")) {
if (!value.endsWith("/")) {
value += "/";
}
value += "?";
} else {
value += "&";
}
} else {
value += "&";
}
value += requiredParamName + "=true";
}
} else {
value = requiredParamName + "=true";
}
return value;
}
/**
* This is a convienence method that builds a full remote endpoint string that combines
* {@link #getConnectorTransport()}, {@link #getConnectorBindAddress()}, {@link #getConnectorBindPort()},
* {@link #getConnectorTransportParams()} and {@link #getConnectorRHQType()}.
*
* @return a remote endpoint string that can be used by remote clients to connect to the connector.
*/
public String getConnectorRemoteEndpoint() {
String rhqtype = getConnectorRHQType();
if (!rhqtype.equals(ServiceContainerConfigurationConstants.RHQTYPE_AGENT)
&& !rhqtype.equals(ServiceContainerConfigurationConstants.RHQTYPE_SERVER)) {
LOG.warn(CommI18NResourceKeys.SERVICE_CONTAINER_INVALID_RHQTYPE, rhqtype,
ServiceContainerConfigurationConstants.RHQTYPE_SERVER,
ServiceContainerConfigurationConstants.RHQTYPE_AGENT);
rhqtype = ServiceContainerConfigurationConstants.RHQTYPE_AGENT;
}
String rhqtype_param = ServiceContainerConfigurationConstants.CONNECTOR_RHQTYPE + "=" + rhqtype;
String transport = getConnectorTransport();
String bind_address = getConnectorBindAddress();
int bind_port = getConnectorBindPort();
String transport_params = getConnectorTransportParams().trim();
// build the locator URI from the configuration properties
String locator_uri = transport + "://" + bind_address + ":" + bind_port;
if (transport_params.length() == 0) {
transport_params = "/?" + rhqtype_param;
} else {
// for some transports (e.g. servlet) the params will actually be the rest of the URL with options query string
// to denote that we don't want to start the query string immediately after host:port, the params can start with /
if (transport_params.startsWith("/")) {
if (transport_params.indexOf('?') == -1) {
transport_params += "?" + rhqtype_param;
} else {
transport_params += "&" + rhqtype_param;
}
} else {
transport_params = "/?" + rhqtype_param + "&" + transport_params;
}
}
locator_uri += transport_params;
return locator_uri;
}
/**
* Returns the connector's lease period, in milliseconds. When this period is greater than 0, it enables the
* capability for the connector to detect when a client is no longer available. This is done by estabilishing a
* lease with the remoting clients.
*
* @return the connector's lease period (Long.MIN_VALUE
if not set in the preferences)
*/
public long getConnectorLeasePeriod() {
long value = m_preferences.getLong(ServiceContainerConfigurationConstants.CONNECTOR_LEASE_PERIOD,
Long.MIN_VALUE);
return value;
}
/**
* Returns the protocol used over the secure socket.
*
* @return protocol name
*/
public String getConnectorSecuritySocketProtocol() {
String value = m_preferences.get(ServiceContainerConfigurationConstants.CONNECTOR_SECURITY_SOCKET_PROTOCOL,
ServiceContainerConfigurationConstants.DEFAULT_CONNECTOR_SECURITY_SOCKET_PROTOCOL);
return value;
}
/**
* Returns the client authentication mode. It is either:}
*
*
* - {@link SSLSocketBuilder#CLIENT_AUTH_MODE_NONE} - clients are not authenticated
* - {@link SSLSocketBuilder#CLIENT_AUTH_MODE_WANT} - clients are authenticated if they provide a cert; if they
* do not, anonymous connections are allowed
* - {@link SSLSocketBuilder#CLIENT_AUTH_MODE_NEED} - clients must supply a cert and they must be
* authenticated
*
*
* The default is {@link SSLSocketBuilder#CLIENT_AUTH_MODE_NONE} - that will be returned if the client auth mode was
* not found in the configuration.
*
* Note: To support Tomcat syntax, the client authentication mode value is allowed to be "true" or "false".
* "true" maps to {@link SSLSocketBuilder#CLIENT_AUTH_MODE_NEED},
* "false" maps to {@link SSLSocketBuilder#CLIENT_AUTH_MODE_NONE}.
*
* @return the client authentication mode
*/
public String getConnectorSecurityClientAuthMode() {
String value = m_preferences.get(ServiceContainerConfigurationConstants.CONNECTOR_SECURITY_CLIENT_AUTH_MODE,
ServiceContainerConfigurationConstants.DEFAULT_CONNECTOR_SECURITY_CLIENT_AUTH_MODE);
if (value.equalsIgnoreCase("true")) {
value = SSLSocketBuilder.CLIENT_AUTH_MODE_NEED;
} else if (value.equalsIgnoreCase("false")) {
value = SSLSocketBuilder.CLIENT_AUTH_MODE_NONE;
}
if (!value.equals(SSLSocketBuilder.CLIENT_AUTH_MODE_NONE)
&& !value.equals(SSLSocketBuilder.CLIENT_AUTH_MODE_WANT)
&& !value.equals(SSLSocketBuilder.CLIENT_AUTH_MODE_NEED)) {
LOG.warn(CommI18NResourceKeys.SERVICE_CONTAINER_CONFIGURATION_INVALID_CLIENT_AUTH,
ServiceContainerConfigurationConstants.CONNECTOR_SECURITY_CLIENT_AUTH_MODE, value,
SSLSocketBuilder.CLIENT_AUTH_MODE_NONE, SSLSocketBuilder.CLIENT_AUTH_MODE_WANT,
SSLSocketBuilder.CLIENT_AUTH_MODE_NEED, SSLSocketBuilder.CLIENT_AUTH_MODE_NEED);
value = SSLSocketBuilder.CLIENT_AUTH_MODE_NEED;
}
return value;
}
/**
* Returns the path to the keystore file. This returns a String
as opposed to File
since
* some underlying remoting code may allow for this filepath to be relative to a jar inside the classloader.
*
* @return keystore file path
*/
public String getConnectorSecurityKeystoreFile() {
String value = m_preferences.get(ServiceContainerConfigurationConstants.CONNECTOR_SECURITY_KEYSTORE_FILE, null);
if (value == null) {
value = new File(getDataDirectory(),
ServiceContainerConfigurationConstants.DEFAULT_CONNECTOR_SECURITY_KEYSTORE_FILE_NAME).getAbsolutePath();
}
return value;
}
/**
* Returns the algorithm used to manage the keys in the keystore.
*
* @return key manager algorithm
*/
public String getConnectorSecurityKeystoreAlgorithm() {
String value = m_preferences.get(ServiceContainerConfigurationConstants.CONNECTOR_SECURITY_KEYSTORE_ALGORITHM,
ServiceContainerConfigurationConstants.DEFAULT_CONNECTOR_SECURITY_KEYSTORE_ALGORITHM);
return value;
}
/**
* Returns the type of keystore.
*
* @return keystore type
*/
public String getConnectorSecurityKeystoreType() {
String value = m_preferences.get(ServiceContainerConfigurationConstants.CONNECTOR_SECURITY_KEYSTORE_TYPE,
ServiceContainerConfigurationConstants.DEFAULT_CONNECTOR_SECURITY_KEYSTORE_TYPE);
return value;
}
/**
* Returns the password to the keystore file itself.
*
* @return keystore password
*/
public String getConnectorSecurityKeystorePassword() {
String value = m_preferences.get(ServiceContainerConfigurationConstants.CONNECTOR_SECURITY_KEYSTORE_PASSWORD,
"rhqpwd");
return value;
}
/**
* Returns the password to gain access to the key in the keystore. If no key password is configured, this returns
* the {@link #getConnectorSecurityKeystorePassword() keystore password}.
*
* @return password to the key
*/
public String getConnectorSecurityKeystoreKeyPassword() {
String value = m_preferences.get(
ServiceContainerConfigurationConstants.CONNECTOR_SECURITY_KEYSTORE_KEY_PASSWORD, null);
if (value == null) {
value = getConnectorSecurityKeystorePassword();
}
return value;
}
/**
* Returns the key alias of the key in the keystore.
*
* @return key alias name
*/
public String getConnectorSecurityKeystoreAlias() {
String value = m_preferences.get(ServiceContainerConfigurationConstants.CONNECTOR_SECURITY_KEYSTORE_ALIAS,
ServiceContainerConfigurationConstants.DEFAULT_CONNECTOR_SECURITY_KEYSTORE_ALIAS);
return value;
}
/**
* Returns the path to the truststore file. This returns a String
as opposed to File
since
* some underlying remoting code may allow for this filepath to be relative to a jar inside the classloader.
*
* @return truststore file path
*/
public String getConnectorSecurityTruststoreFile() {
String value = m_preferences.get(ServiceContainerConfigurationConstants.CONNECTOR_SECURITY_TRUSTSTORE_FILE,
null);
if (value == null) {
value = new File(getDataDirectory(),
ServiceContainerConfigurationConstants.DEFAULT_CONNECTOR_SECURITY_TRUSTSTORE_FILE_NAME)
.getAbsolutePath();
}
return value;
}
/**
* Returns the algorithm used to manage the keys in the truststore.
*
* @return algorithm name
*/
public String getConnectorSecurityTruststoreAlgorithm() {
String value = m_preferences.get(
ServiceContainerConfigurationConstants.CONNECTOR_SECURITY_TRUSTSTORE_ALGORITHM,
ServiceContainerConfigurationConstants.DEFAULT_CONNECTOR_SECURITY_TRUSTSTORE_ALGORITHM);
return value;
}
/**
* Returns the type of the truststore file.
*
* @return truststore file type
*/
public String getConnectorSecurityTruststoreType() {
String value = m_preferences.get(ServiceContainerConfigurationConstants.CONNECTOR_SECURITY_TRUSTSTORE_TYPE,
ServiceContainerConfigurationConstants.DEFAULT_CONNECTOR_SECURITY_TRUSTSTORE_TYPE);
return value;
}
/**
* Returns the password of the truststore file itself.
*
* @return truststore file password
*/
public String getConnectorSecurityTruststorePassword() {
String value = m_preferences.get(ServiceContainerConfigurationConstants.CONNECTOR_SECURITY_TRUSTSTORE_PASSWORD,
null);
return value;
}
/**
* Returns the command services that are to be automatically deployed when the services are started up.
*
* @return the set of command services to be automatically deployed at startup
*/
public String getStartupCommandServices() {
String value = m_preferences.get(ServiceContainerConfigurationConstants.CMDSERVICES, EchoCommandService.class
.getName()
+ "," + IdentifyCommandService.class.getName());
return value;
}
/**
* Returns the definitions of the POJOs that are to be automatically deployed as remote services at start up.
*
* @return the set of POJOs to remote at startup
*/
public String getStartupRemotePojos() {
String value = m_preferences.get(ServiceContainerConfigurationConstants.REMOTE_POJOS, PingImpl.class.getName()
+ ":" + Ping.class.getName());
return value;
}
/**
* Returns the maximum amount of milliseconds a remote {@link RemoteOutputStream output} or
* {@link RemoteInputStream input} stream server-side component hosted in a {@link RemoteOutputStreamCommandService}
* or {@link RemoteInputStreamCommandService} is allowed to be idle before it is automatically closed and removed.
* This means that a client must attempt to access the remote stream every X milliseconds (where X is the value this
* method returns) or that stream will no longer be available. Note that this does not mean a client must read/write
* the entire stream in this amount of time, it only means a client must make a request on the stream every X
* milliseconds (be it to read or write a byte, mark it, see how many bytes are available, etc).
*
* @return the max idle time in milliseconds
*/
public long getRemoteStreamMaxIdleTime() {
long value = m_preferences.getLong(ServiceContainerConfigurationConstants.REMOTE_STREAM_MAX_IDLE_TIME,
ServiceContainerConfigurationConstants.DEFAULT_REMOTE_STREAM_MAX_IDLE_TIME);
return value;
}
/**
* Returns the flag to indicate if the command service directory has been enabled to perform dynamic discovery of
* new command services that are added to (or old services removed from) the system after the initial startup
* discovery.
*
* @return true
if dynamic discovery of command services is enabled; false
if the initial
* set of {@link #getStartupCommandServices() } are the only ones that will be enabled during the lifetime
* of the service container
*/
public boolean isCommandServiceDirectoryDynamicDiscoveryEnabled() {
boolean value = m_preferences.getBoolean(
ServiceContainerConfigurationConstants.CMDSERVICE_DIRECTORY_DYNAMIC_DISCOVERY,
ServiceContainerConfigurationConstants.DEFAULT_CMDSERVICE_DIRECTORY_DYNAMIC_DISCOVERY);
return value;
}
/**
* Returns an implementation of the configured {@link CommandAuthenticator} that should be used to authenticate
* incoming commands.
*
* @return command authenticator object instance or null
if no authenticator is configured
*
* @throws Exception if failed to instantiate the configured class name
*/
public CommandAuthenticator getCommandAuthenticator() throws Exception {
CommandAuthenticator obj = null;
String value = m_preferences.get(ServiceContainerConfigurationConstants.COMMAND_AUTHENTICATOR, "");
if ((value != null) && (value.length() > 0)) {
obj = (CommandAuthenticator) Class.forName(value).newInstance();
}
return obj;
}
/**
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
StringBuffer buf = new StringBuffer(m_preferences.absolutePath());
buf.append('[');
try {
String[] keys = m_preferences.keys();
for (int i = 0; i < keys.length; i++) {
String key = keys[i];
buf.append(key);
buf.append('=');
buf.append(m_preferences.get(key, LOG
.getMsgString(CommI18NResourceKeys.SERVICE_CONTAINER_CONFIGURATION_UNKNOWN)));
if ((i + 1) < keys.length) {
buf.append(',');
}
}
} catch (BackingStoreException e) {
buf.append('<');
buf.append(LOG.getMsgString(CommI18NResourceKeys.SERVICE_CONTAINER_CONFIGURATION_CANNOT_GET_PREFS, e));
buf.append('>');
}
buf.append(']');
return buf.toString();
}
/**
* Forces the preferences to flush so they get written to the backing store.
*
* @param changedPreference the name of the preference that was changed to
* cause flush to be called (used for error log message)
*/
private void flush(String changedPreference) {
try {
m_preferences.flush();
} catch (Exception e) {
LOG.warn(LOG.getMsgString(CommI18NResourceKeys.CANNOT_STORE_PREFERENCES), changedPreference, e);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy