/* * Licensed to the Apache Software Foundation (ASF) under one or more contributor license * agreements. See the NOTICE file distributed with this work for additional information regarding * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance with the License. You may obtain a * copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ package org.apache.geode.admin.internal; import org.apache.geode.admin.ConfigurationParameter; import org.apache.geode.admin.UnmodifiableConfigurationException; import org.apache.geode.internal.i18n.LocalizedStrings; import java.io.File; // import java.net.InetAddress; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * A single configuration parameter of a system member. * * @since GemFire 3.5 * */ public class ConfigurationParameterImpl implements org.apache.geode.admin.ConfigurationParameter { /** Identifying name of this configuration parameter */ protected String name; /** Full description of this configuration parameter */ protected String description; /** The current value */ protected Object value; /** Class type of the value */ protected Class type; /** True if this is modifiable; false if read-only */ protected boolean userModifiable; /** List of listeners to notify when value changes */ private final List listeners = new ArrayList(); // ------------------------------------------------------------------------- // Constructor(s) // ------------------------------------------------------------------------- /** * Constructs new <code>ConfigurationParameterImpl</code>. * * @param name the name of this parameter which cannot change * @param description full description to use * @param value the value of this parameter * @param type the class type of the value * @param userModifiable true if this is modifiable; false if read-only */ protected ConfigurationParameterImpl(String name, String description, Object value, Class type, boolean userModifiable) { if (name == null || name.length() == 0) { throw new IllegalArgumentException( LocalizedStrings.ConfigurationParameterImpl_CONFIGURATIONPARAMETER_NAME_MUST_BE_SPECIFIED .toLocalizedString()); } this.name = name; setInternalState(description, value, type, userModifiable); } /** * Constructs new <code>ConfigurationParameterImpl</code>. * * @param name the name of this parameter which cannot change * @param value the value of this parameter */ protected ConfigurationParameterImpl(String name, Object value) { if (name == null || name.length() == 0) { throw new IllegalArgumentException( LocalizedStrings.ConfigurationParameterImpl_CONFIGURATIONPARAMETER_NAME_MUST_BE_SPECIFIED .toLocalizedString()); } this.name = name; setInternalState(name, value, value.getClass(), true); } /** Constructor to allow serialization by subclass */ protected ConfigurationParameterImpl() {} // ------------------------------------------------------------------------- // Attribute accessors and mutators // ------------------------------------------------------------------------- public String getName() { return this.name; } public String getDescription() { return this.description; } public Object getValue() { return this.value; } public String getValueAsString() { if (isString()) { return (String) this.value; } else if (isInetAddress()) { return InetAddressUtil.toString(this.value); } else if (isFile()) { return this.value.toString(); } else if (isOctal()) { String strVal = Integer.toOctalString(((Integer) this.value).intValue()); if (!strVal.startsWith("0")) { strVal = "0" + strVal; } return strVal; } else if (isArray()) { List list = Arrays.asList((Object[]) this.value); return list.toString(); } else { return this.value.toString(); } } public Class getValueType() { return this.type; } public boolean isModifiable() { return this.userModifiable; } public boolean isArray() { return "manager-parameters".equals(this.name) || "manager-classpaths".equals(this.name); } public boolean isInetAddress() { return java.net.InetAddress.class.isAssignableFrom(this.type); } public boolean isFile() { return java.io.File.class.equals(this.type); } public boolean isOctal() { return "shared-memory-permissions".equals(this.name); } public boolean isString() { return java.lang.String.class.equals(this.type); } public void setValue(Object value) throws UnmodifiableConfigurationException { if (!isModifiable()) { throw new UnmodifiableConfigurationException( LocalizedStrings.ConfigurationParameterImpl_0_IS_NOT_A_MODIFIABLE_CONFIGURATION_PARAMETER .toLocalizedString(getName())); } if (value == null) { throw new IllegalArgumentException( LocalizedStrings.ConfigurationParameterImpl_UNABLE_TO_SET_0_TO_NULL_VALUE .toLocalizedString(getName())); } if (!getValueType().equals(value.getClass())) { throw new IllegalArgumentException( LocalizedStrings.ConfigurationParameterImpl_UNABLE_TO_SET_TYPE_0_WITH_TYPE_1 .toLocalizedString( new Object[] {getValueType().getName(), value.getClass().getName()})); } if (value instanceof String && !isString()) { // we need to check what the type should be and convert to it... setValueFromString((String) value); } else { this.value = value; } fireConfigurationParameterValueChanged(this); } // ------------------------------------------------------------------------- // Operations for handling the registration of listeners // Note: this is only for use within impl pkg and subclass pkgs // ------------------------------------------------------------------------- /** Adds the listener for any changes to this configuration parameter. */ public void addConfigurationParameterListener(ConfigurationParameterListener listener) { if (!this.listeners.contains(listener)) { this.listeners.add(listener); } } /** Removes the listener if it's currently registered. */ public void removeConfigurationParameterListener(ConfigurationParameterListener listener) { if (this.listeners.contains(listener)) { this.listeners.remove(listener); } } // ------------------------------------------------------------------------- // Implementation methods // ------------------------------------------------------------------------- protected void setValueFromString(String newValue) { if (newValue == null) { throw new IllegalArgumentException( LocalizedStrings.ConfigurationParameterImpl_UNABLE_TO_SET_0_TO_NULL_VALUE .toLocalizedString(getName())); } if (isInetAddress()) { this.value = InetAddressUtil.toInetAddress(newValue); } else if (isFile()) { this.value = new File(newValue); } else if (isOctal()) { if (!newValue.startsWith("0")) { newValue = "0" + newValue; } this.value = Integer.valueOf(Integer.parseInt(newValue, 8)); } else if (isArray()) { // parse it TODO throw new IllegalArgumentException( LocalizedStrings.ConfigurationParameterImpl_SETTING_ARRAY_VALUE_FROM_DELIMITED_STRING_IS_NOT_SUPPORTED .toLocalizedString()); } else { this.value = newValue; } } /** * Fires changed configuration parameter to registered listeners. * * @param parm the configuration parameter the changed */ protected void fireConfigurationParameterValueChanged(ConfigurationParameter parm) { ConfigurationParameterListener[] listeners = (ConfigurationParameterListener[]) this.listeners .toArray(new ConfigurationParameterListener[0]); for (int i = 0; i < listeners.length; i++) { listeners[i].configurationParameterValueChanged(parm); } } /** * Sets the internal state of this configuration parameter. * * @param description full description to use * @param value the value of this parameter * @param type the class type of the value * @param userModifiable true if this is modifiable; false if read-only */ protected void setInternalState(String description, Object value, Class type, boolean userModifiable) { if (description == null || description.length() == 0) { throw new IllegalArgumentException( LocalizedStrings.ConfigurationParameterImpl_CONFIGURATIONPARAMETER_DESCRIPTION_MUST_BE_SPECIFIED .toLocalizedString()); } this.description = description; this.type = type; this.userModifiable = userModifiable; if (value == null) { throw new IllegalArgumentException( LocalizedStrings.ConfigurationParameterImpl_UNABLE_TO_SET_0_TO_NULL_VALUE .toLocalizedString(getName())); } this.value = value; } @Override public String toString() { return this.name; } }