| /* |
| * 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.flink.configuration; |
| |
| import org.apache.flink.annotation.Public; |
| import org.apache.flink.annotation.PublicEvolving; |
| import org.apache.flink.api.common.ExecutionConfig; |
| import org.apache.flink.core.io.IOReadableWritable; |
| import org.apache.flink.core.memory.DataInputView; |
| import org.apache.flink.core.memory.DataOutputView; |
| import org.apache.flink.types.StringValue; |
| |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import java.io.IOException; |
| import java.util.Arrays; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Map; |
| import java.util.Properties; |
| import java.util.Set; |
| |
| /** |
| * Lightweight configuration object which stores key/value pairs. |
| */ |
| @Public |
| public class Configuration extends ExecutionConfig.GlobalJobParameters |
| implements IOReadableWritable, java.io.Serializable, Cloneable { |
| |
| private static final long serialVersionUID = 1L; |
| |
| private static final byte TYPE_STRING = 0; |
| private static final byte TYPE_INT = 1; |
| private static final byte TYPE_LONG = 2; |
| private static final byte TYPE_BOOLEAN = 3; |
| private static final byte TYPE_FLOAT = 4; |
| private static final byte TYPE_DOUBLE = 5; |
| private static final byte TYPE_BYTES = 6; |
| |
| /** The log object used for debugging. */ |
| private static final Logger LOG = LoggerFactory.getLogger(Configuration.class); |
| |
| |
| /** Stores the concrete key/value pairs of this configuration object. */ |
| protected final HashMap<String, Object> confData; |
| |
| // -------------------------------------------------------------------------------------------- |
| |
| /** |
| * Creates a new empty configuration. |
| */ |
| public Configuration() { |
| this.confData = new HashMap<>(); |
| } |
| |
| /** |
| * Creates a new configuration with the copy of the given configuration. |
| * |
| * @param other The configuration to copy the entries from. |
| */ |
| public Configuration(Configuration other) { |
| this.confData = new HashMap<>(other.confData); |
| } |
| |
| // -------------------------------------------------------------------------------------------- |
| |
| /** |
| * Returns the class associated with the given key as a string. |
| * |
| * @param <T> The type of the class to return. |
| |
| * @param key The key pointing to the associated value |
| * @param defaultValue The optional default value returned if no entry exists |
| * @param classLoader The class loader used to resolve the class. |
| * |
| * @return The value associated with the given key, or the default value, if to entry for the key exists. |
| */ |
| @SuppressWarnings("unchecked") |
| public <T> Class<T> getClass(String key, Class<? extends T> defaultValue, ClassLoader classLoader) throws ClassNotFoundException { |
| Object o = getRawValue(key); |
| if (o == null) { |
| return (Class<T>) defaultValue; |
| } |
| |
| if (o.getClass() == String.class) { |
| return (Class<T>) Class.forName((String) o, true, classLoader); |
| } |
| |
| LOG.warn("Configuration cannot evaluate value " + o + " as a class name"); |
| return (Class<T>) defaultValue; |
| } |
| |
| /** |
| * Adds the given key/value pair to the configuration object. The class can be retrieved by invoking |
| * {@link #getClass(String, Class, ClassLoader)} if it is in the scope of the class loader on the caller. |
| * |
| * @param key The key of the pair to be added |
| * @param klazz The value of the pair to be added |
| * @see #getClass(String, Class, ClassLoader) |
| */ |
| public void setClass(String key, Class<?> klazz) { |
| setValueInternal(key, klazz.getName()); |
| } |
| |
| /** |
| * Returns the value associated with the given key as a string. |
| * |
| * @param key |
| * the key pointing to the associated value |
| * @param defaultValue |
| * the default value which is returned in case there is no value associated with the given key |
| * @return the (default) value associated with the given key |
| */ |
| public String getString(String key, String defaultValue) { |
| Object o = getRawValue(key); |
| if (o == null) { |
| return defaultValue; |
| } else { |
| return o.toString(); |
| } |
| } |
| |
| /** |
| * Returns the value associated with the given config option as a string. |
| * |
| * @param configOption The configuration option |
| * @return the (default) value associated with the given config option |
| */ |
| @PublicEvolving |
| public String getString(ConfigOption<String> configOption) { |
| Object o = getValueOrDefaultFromOption(configOption); |
| return o == null ? null : o.toString(); |
| } |
| |
| /** |
| * Returns the value associated with the given config option as a string. |
| * If no value is mapped under any key of the option, it returns the specified |
| * default instead of the option's default value. |
| * |
| * @param configOption The configuration option |
| * @return the (default) value associated with the given config option |
| */ |
| @PublicEvolving |
| public String getString(ConfigOption<String> configOption, String overrideDefault) { |
| Object o = getRawValueFromOption(configOption); |
| return o == null ? overrideDefault : o.toString(); |
| } |
| |
| /** |
| * Adds the given key/value pair to the configuration object. |
| * |
| * @param key |
| * the key of the key/value pair to be added |
| * @param value |
| * the value of the key/value pair to be added |
| */ |
| public void setString(String key, String value) { |
| setValueInternal(key, value); |
| } |
| |
| /** |
| * Adds the given value to the configuration object. |
| * The main key of the config option will be used to map the value. |
| * |
| * @param key |
| * the option specifying the key to be added |
| * @param value |
| * the value of the key/value pair to be added |
| */ |
| @PublicEvolving |
| public void setString(ConfigOption<String> key, String value) { |
| setValueInternal(key.key(), value); |
| } |
| |
| /** |
| * Returns the value associated with the given key as an integer. |
| * |
| * @param key |
| * the key pointing to the associated value |
| * @param defaultValue |
| * the default value which is returned in case there is no value associated with the given key |
| * @return the (default) value associated with the given key |
| */ |
| public int getInteger(String key, int defaultValue) { |
| Object o = getRawValue(key); |
| if (o == null) { |
| return defaultValue; |
| } |
| |
| return convertToInt(o, defaultValue); |
| } |
| |
| /** |
| * Returns the value associated with the given config option as an integer. |
| * |
| * @param configOption The configuration option |
| * @return the (default) value associated with the given config option |
| */ |
| @PublicEvolving |
| public int getInteger(ConfigOption<Integer> configOption) { |
| Object o = getValueOrDefaultFromOption(configOption); |
| return convertToInt(o, configOption.defaultValue()); |
| } |
| |
| /** |
| * Returns the value associated with the given config option as an integer. |
| * If no value is mapped under any key of the option, it returns the specified |
| * default instead of the option's default value. |
| * |
| * @param configOption The configuration option |
| * @param overrideDefault The value to return if no value was mapper for any key of the option |
| * @return the configured value associated with the given config option, or the overrideDefault |
| */ |
| @PublicEvolving |
| public int getInteger(ConfigOption<Integer> configOption, int overrideDefault) { |
| Object o = getRawValueFromOption(configOption); |
| if (o == null) { |
| return overrideDefault; |
| } |
| return convertToInt(o, configOption.defaultValue()); |
| } |
| |
| /** |
| * Adds the given key/value pair to the configuration object. |
| * |
| * @param key |
| * the key of the key/value pair to be added |
| * @param value |
| * the value of the key/value pair to be added |
| */ |
| public void setInteger(String key, int value) { |
| setValueInternal(key, value); |
| } |
| |
| /** |
| * Adds the given value to the configuration object. |
| * The main key of the config option will be used to map the value. |
| * |
| * @param key |
| * the option specifying the key to be added |
| * @param value |
| * the value of the key/value pair to be added |
| */ |
| @PublicEvolving |
| public void setInteger(ConfigOption<Integer> key, int value) { |
| setValueInternal(key.key(), value); |
| } |
| |
| /** |
| * Returns the value associated with the given key as a long. |
| * |
| * @param key |
| * the key pointing to the associated value |
| * @param defaultValue |
| * the default value which is returned in case there is no value associated with the given key |
| * @return the (default) value associated with the given key |
| */ |
| public long getLong(String key, long defaultValue) { |
| Object o = getRawValue(key); |
| if (o == null) { |
| return defaultValue; |
| } |
| |
| return convertToLong(o, defaultValue); |
| } |
| |
| /** |
| * Returns the value associated with the given config option as a long integer. |
| * |
| * @param configOption The configuration option |
| * @return the (default) value associated with the given config option |
| */ |
| @PublicEvolving |
| public long getLong(ConfigOption<Long> configOption) { |
| Object o = getValueOrDefaultFromOption(configOption); |
| return convertToLong(o, configOption.defaultValue()); |
| } |
| |
| /** |
| * Returns the value associated with the given config option as a long integer. |
| * If no value is mapped under any key of the option, it returns the specified |
| * default instead of the option's default value. |
| * |
| * @param configOption The configuration option |
| * @param overrideDefault The value to return if no value was mapper for any key of the option |
| * @return the configured value associated with the given config option, or the overrideDefault |
| */ |
| @PublicEvolving |
| public long getLong(ConfigOption<Long> configOption, long overrideDefault) { |
| Object o = getRawValueFromOption(configOption); |
| if (o == null) { |
| return overrideDefault; |
| } |
| return convertToLong(o, configOption.defaultValue()); |
| } |
| |
| /** |
| * Adds the given key/value pair to the configuration object. |
| * |
| * @param key |
| * the key of the key/value pair to be added |
| * @param value |
| * the value of the key/value pair to be added |
| */ |
| public void setLong(String key, long value) { |
| setValueInternal(key, value); |
| } |
| |
| /** |
| * Adds the given value to the configuration object. |
| * The main key of the config option will be used to map the value. |
| * |
| * @param key |
| * the option specifying the key to be added |
| * @param value |
| * the value of the key/value pair to be added |
| */ |
| @PublicEvolving |
| public void setLong(ConfigOption<Long> key, long value) { |
| setValueInternal(key.key(), value); |
| } |
| |
| /** |
| * Returns the value associated with the given key as a boolean. |
| * |
| * @param key |
| * the key pointing to the associated value |
| * @param defaultValue |
| * the default value which is returned in case there is no value associated with the given key |
| * @return the (default) value associated with the given key |
| */ |
| public boolean getBoolean(String key, boolean defaultValue) { |
| Object o = getRawValue(key); |
| if (o == null) { |
| return defaultValue; |
| } |
| |
| return convertToBoolean(o); |
| } |
| |
| /** |
| * Returns the value associated with the given config option as a boolean. |
| * |
| * @param configOption The configuration option |
| * @return the (default) value associated with the given config option |
| */ |
| @PublicEvolving |
| public boolean getBoolean(ConfigOption<Boolean> configOption) { |
| Object o = getValueOrDefaultFromOption(configOption); |
| return convertToBoolean(o); |
| } |
| |
| /** |
| * Returns the value associated with the given config option as a boolean. |
| * If no value is mapped under any key of the option, it returns the specified |
| * default instead of the option's default value. |
| * |
| * @param configOption The configuration option |
| * @param overrideDefault The value to return if no value was mapper for any key of the option |
| * @return the configured value associated with the given config option, or the overrideDefault |
| */ |
| @PublicEvolving |
| public boolean getBoolean(ConfigOption<Boolean> configOption, boolean overrideDefault) { |
| Object o = getRawValueFromOption(configOption); |
| if (o == null) { |
| return overrideDefault; |
| } |
| return convertToBoolean(o); |
| } |
| |
| /** |
| * Adds the given key/value pair to the configuration object. |
| * |
| * @param key |
| * the key of the key/value pair to be added |
| * @param value |
| * the value of the key/value pair to be added |
| */ |
| public void setBoolean(String key, boolean value) { |
| setValueInternal(key, value); |
| } |
| |
| /** |
| * Adds the given value to the configuration object. |
| * The main key of the config option will be used to map the value. |
| * |
| * @param key |
| * the option specifying the key to be added |
| * @param value |
| * the value of the key/value pair to be added |
| */ |
| @PublicEvolving |
| public void setBoolean(ConfigOption<Boolean> key, boolean value) { |
| setValueInternal(key.key(), value); |
| } |
| |
| /** |
| * Returns the value associated with the given key as a float. |
| * |
| * @param key |
| * the key pointing to the associated value |
| * @param defaultValue |
| * the default value which is returned in case there is no value associated with the given key |
| * @return the (default) value associated with the given key |
| */ |
| public float getFloat(String key, float defaultValue) { |
| Object o = getRawValue(key); |
| if (o == null) { |
| return defaultValue; |
| } |
| |
| return convertToFloat(o, defaultValue); |
| } |
| |
| /** |
| * Returns the value associated with the given config option as a float. |
| * |
| * @param configOption The configuration option |
| * @return the (default) value associated with the given config option |
| */ |
| @PublicEvolving |
| public float getFloat(ConfigOption<Float> configOption) { |
| Object o = getValueOrDefaultFromOption(configOption); |
| return convertToFloat(o, configOption.defaultValue()); |
| } |
| |
| /** |
| * Returns the value associated with the given config option as a float. |
| * If no value is mapped under any key of the option, it returns the specified |
| * default instead of the option's default value. |
| * |
| * @param configOption The configuration option |
| * @param overrideDefault The value to return if no value was mapper for any key of the option |
| * @return the configured value associated with the given config option, or the overrideDefault |
| */ |
| @PublicEvolving |
| public float getFloat(ConfigOption<Float> configOption, float overrideDefault) { |
| Object o = getRawValueFromOption(configOption); |
| if (o == null) { |
| return overrideDefault; |
| } |
| return convertToFloat(o, configOption.defaultValue()); |
| } |
| |
| /** |
| * Adds the given key/value pair to the configuration object. |
| * |
| * @param key |
| * the key of the key/value pair to be added |
| * @param value |
| * the value of the key/value pair to be added |
| */ |
| public void setFloat(String key, float value) { |
| setValueInternal(key, value); |
| } |
| |
| /** |
| * Adds the given value to the configuration object. |
| * The main key of the config option will be used to map the value. |
| * |
| * @param key |
| * the option specifying the key to be added |
| * @param value |
| * the value of the key/value pair to be added |
| */ |
| @PublicEvolving |
| public void setFloat(ConfigOption<Float> key, float value) { |
| setValueInternal(key.key(), value); |
| } |
| |
| /** |
| * Returns the value associated with the given key as a double. |
| * |
| * @param key |
| * the key pointing to the associated value |
| * @param defaultValue |
| * the default value which is returned in case there is no value associated with the given key |
| * @return the (default) value associated with the given key |
| */ |
| public double getDouble(String key, double defaultValue) { |
| Object o = getRawValue(key); |
| if (o == null) { |
| return defaultValue; |
| } |
| |
| return convertToDouble(o, defaultValue); |
| } |
| |
| /** |
| * Returns the value associated with the given config option as a {@code double}. |
| * |
| * @param configOption The configuration option |
| * @return the (default) value associated with the given config option |
| */ |
| @PublicEvolving |
| public double getDouble(ConfigOption<Double> configOption) { |
| Object o = getValueOrDefaultFromOption(configOption); |
| return convertToDouble(o, configOption.defaultValue()); |
| } |
| |
| /** |
| * Returns the value associated with the given config option as a {@code double}. |
| * If no value is mapped under any key of the option, it returns the specified |
| * default instead of the option's default value. |
| * |
| * @param configOption The configuration option |
| * @param overrideDefault The value to return if no value was mapper for any key of the option |
| * @return the configured value associated with the given config option, or the overrideDefault |
| */ |
| @PublicEvolving |
| public double getDouble(ConfigOption<Double> configOption, double overrideDefault) { |
| Object o = getRawValueFromOption(configOption); |
| if (o == null) { |
| return overrideDefault; |
| } |
| return convertToDouble(o, configOption.defaultValue()); |
| } |
| |
| /** |
| * Adds the given key/value pair to the configuration object. |
| * |
| * @param key |
| * the key of the key/value pair to be added |
| * @param value |
| * the value of the key/value pair to be added |
| */ |
| public void setDouble(String key, double value) { |
| setValueInternal(key, value); |
| } |
| |
| /** |
| * Adds the given value to the configuration object. |
| * The main key of the config option will be used to map the value. |
| * |
| * @param key |
| * the option specifying the key to be added |
| * @param value |
| * the value of the key/value pair to be added |
| */ |
| @PublicEvolving |
| public void setDouble(ConfigOption<Double> key, double value) { |
| setValueInternal(key.key(), value); |
| } |
| |
| /** |
| * Returns the value associated with the given key as a byte array. |
| * |
| * @param key |
| * The key pointing to the associated value. |
| * @param defaultValue |
| * The default value which is returned in case there is no value associated with the given key. |
| * @return the (default) value associated with the given key. |
| */ |
| @SuppressWarnings("EqualsBetweenInconvertibleTypes") |
| public byte[] getBytes(String key, byte[] defaultValue) { |
| |
| Object o = getRawValue(key); |
| if (o == null) { |
| return defaultValue; |
| } |
| else if (o.getClass().equals(byte[].class)) { |
| return (byte[]) o; |
| } |
| else { |
| LOG.warn("Configuration cannot evaluate value {} as a byte[] value", o); |
| return defaultValue; |
| } |
| } |
| |
| /** |
| * Adds the given byte array to the configuration object. If key is <code>null</code> then nothing is added. |
| * |
| * @param key |
| * The key under which the bytes are added. |
| * @param bytes |
| * The bytes to be added. |
| */ |
| public void setBytes(String key, byte[] bytes) { |
| setValueInternal(key, bytes); |
| } |
| |
| /** |
| * Returns the value associated with the given config option as a string. |
| * |
| * @param configOption The configuration option |
| * @return the (default) value associated with the given config option |
| */ |
| @PublicEvolving |
| public String getValue(ConfigOption<?> configOption) { |
| Object o = getValueOrDefaultFromOption(configOption); |
| return o == null ? null : o.toString(); |
| } |
| |
| // -------------------------------------------------------------------------------------------- |
| |
| /** |
| * Returns the keys of all key/value pairs stored inside this |
| * configuration object. |
| * |
| * @return the keys of all key/value pairs stored inside this configuration object |
| */ |
| public Set<String> keySet() { |
| synchronized (this.confData) { |
| return new HashSet<>(this.confData.keySet()); |
| } |
| } |
| |
| /** |
| * Adds all entries in this {@code Configuration} to the given {@link Properties}. |
| */ |
| public void addAllToProperties(Properties props) { |
| synchronized (this.confData) { |
| for (Map.Entry<String, Object> entry : this.confData.entrySet()) { |
| props.put(entry.getKey(), entry.getValue()); |
| } |
| } |
| } |
| |
| public void addAll(Configuration other) { |
| synchronized (this.confData) { |
| synchronized (other.confData) { |
| this.confData.putAll(other.confData); |
| } |
| } |
| } |
| |
| public void addAll(Map<String, String> other) { |
| synchronized (this.confData) { |
| this.confData.putAll(other); |
| } |
| } |
| |
| /** |
| * Adds all entries from the given configuration into this configuration. The keys |
| * are prepended with the given prefix. |
| * |
| * @param other |
| * The configuration whose entries are added to this configuration. |
| * @param prefix |
| * The prefix to prepend. |
| */ |
| public void addAll(Configuration other, String prefix) { |
| final StringBuilder bld = new StringBuilder(); |
| bld.append(prefix); |
| final int pl = bld.length(); |
| |
| synchronized (this.confData) { |
| synchronized (other.confData) { |
| for (Map.Entry<String, Object> entry : other.confData.entrySet()) { |
| bld.setLength(pl); |
| bld.append(entry.getKey()); |
| this.confData.put(bld.toString(), entry.getValue()); |
| } |
| } |
| } |
| } |
| |
| @Override |
| public Configuration clone() { |
| Configuration config = new Configuration(); |
| config.addAll(this); |
| |
| return config; |
| } |
| |
| /** |
| * Checks whether there is an entry with the specified key. |
| * |
| * @param key key of entry |
| * @return true if the key is stored, false otherwise |
| */ |
| public boolean containsKey(String key){ |
| synchronized (this.confData){ |
| return this.confData.containsKey(key); |
| } |
| } |
| |
| /** |
| * Checks whether there is an entry for the given config option. |
| * |
| * @param configOption The configuration option |
| * |
| * @return <tt>true</tt> if a valid (current or deprecated) key of the config option is stored, |
| * <tt>false</tt> otherwise |
| */ |
| @PublicEvolving |
| public boolean contains(ConfigOption<?> configOption) { |
| synchronized (this.confData){ |
| // first try the current key |
| if (this.confData.containsKey(configOption.key())) { |
| return true; |
| } |
| else if (configOption.hasDeprecatedKeys()) { |
| // try the deprecated keys |
| for (String deprecatedKey : configOption.deprecatedKeys()) { |
| if (this.confData.containsKey(deprecatedKey)) { |
| LOG.warn("Config uses deprecated configuration key '{}' instead of proper key '{}'", |
| deprecatedKey, configOption.key()); |
| return true; |
| } |
| } |
| } |
| |
| return false; |
| } |
| } |
| |
| public void remove(String key) { |
| synchronized (this.confData) { |
| this.confData.remove(key); |
| } |
| } |
| |
| public void remove(ConfigOption<?> configOption) { |
| synchronized (this.confData) { |
| this.confData.remove(configOption.key()); |
| } |
| } |
| |
| // -------------------------------------------------------------------------------------------- |
| |
| @Override |
| public Map<String, String> toMap() { |
| synchronized (this.confData){ |
| Map<String, String> ret = new HashMap<>(this.confData.size()); |
| for (Map.Entry<String, Object> entry : confData.entrySet()) { |
| ret.put(entry.getKey(), entry.getValue().toString()); |
| } |
| return ret; |
| } |
| } |
| |
| |
| // -------------------------------------------------------------------------------------------- |
| |
| <T> void setValueInternal(String key, T value) { |
| if (key == null) { |
| throw new NullPointerException("Key must not be null."); |
| } |
| if (value == null) { |
| throw new NullPointerException("Value must not be null."); |
| } |
| |
| synchronized (this.confData) { |
| this.confData.put(key, value); |
| } |
| } |
| |
| private Object getRawValue(String key) { |
| if (key == null) { |
| throw new NullPointerException("Key must not be null."); |
| } |
| |
| synchronized (this.confData) { |
| return this.confData.get(key); |
| } |
| } |
| |
| private Object getRawValueFromOption(ConfigOption<?> configOption) { |
| // first try the current key |
| Object o = getRawValue(configOption.key()); |
| |
| if (o != null) { |
| // found a value for the current proper key |
| return o; |
| } |
| else if (configOption.hasDeprecatedKeys()) { |
| // try the deprecated keys |
| for (String deprecatedKey : configOption.deprecatedKeys()) { |
| Object oo = getRawValue(deprecatedKey); |
| if (oo != null) { |
| LOG.warn("Config uses deprecated configuration key '{}' instead of proper key '{}'", |
| deprecatedKey, configOption.key()); |
| return oo; |
| } |
| } |
| } |
| |
| return null; |
| } |
| |
| private Object getValueOrDefaultFromOption(ConfigOption<?> configOption) { |
| Object o = getRawValueFromOption(configOption); |
| return o != null ? o : configOption.defaultValue(); |
| } |
| |
| // -------------------------------------------------------------------------------------------- |
| // Type conversion |
| // -------------------------------------------------------------------------------------------- |
| |
| private int convertToInt(Object o, int defaultValue) { |
| if (o.getClass() == Integer.class) { |
| return (Integer) o; |
| } |
| else if (o.getClass() == Long.class) { |
| long value = (Long) o; |
| if (value <= Integer.MAX_VALUE && value >= Integer.MIN_VALUE) { |
| return (int) value; |
| } else { |
| LOG.warn("Configuration value {} overflows/underflows the integer type.", value); |
| return defaultValue; |
| } |
| } |
| else { |
| try { |
| return Integer.parseInt(o.toString()); |
| } |
| catch (NumberFormatException e) { |
| LOG.warn("Configuration cannot evaluate value {} as an integer number", o); |
| return defaultValue; |
| } |
| } |
| } |
| |
| private long convertToLong(Object o, long defaultValue) { |
| if (o.getClass() == Long.class) { |
| return (Long) o; |
| } |
| else if (o.getClass() == Integer.class) { |
| return ((Integer) o).longValue(); |
| } |
| else { |
| try { |
| return Long.parseLong(o.toString()); |
| } |
| catch (NumberFormatException e) { |
| LOG.warn("Configuration cannot evaluate value " + o + " as a long integer number"); |
| return defaultValue; |
| } |
| } |
| } |
| |
| private boolean convertToBoolean(Object o) { |
| if (o.getClass() == Boolean.class) { |
| return (Boolean) o; |
| } |
| else { |
| return Boolean.parseBoolean(o.toString()); |
| } |
| } |
| |
| private float convertToFloat(Object o, float defaultValue) { |
| if (o.getClass() == Float.class) { |
| return (Float) o; |
| } |
| else if (o.getClass() == Double.class) { |
| double value = ((Double) o); |
| if (value == 0.0 |
| || (value >= Float.MIN_VALUE && value <= Float.MAX_VALUE) |
| || (value >= -Float.MAX_VALUE && value <= -Float.MIN_VALUE)) { |
| return (float) value; |
| } else { |
| LOG.warn("Configuration value {} overflows/underflows the float type.", value); |
| return defaultValue; |
| } |
| } |
| else { |
| try { |
| return Float.parseFloat(o.toString()); |
| } |
| catch (NumberFormatException e) { |
| LOG.warn("Configuration cannot evaluate value {} as a float value", o); |
| return defaultValue; |
| } |
| } |
| } |
| |
| private double convertToDouble(Object o, double defaultValue) { |
| if (o.getClass() == Double.class) { |
| return (Double) o; |
| } |
| else if (o.getClass() == Float.class) { |
| return ((Float) o).doubleValue(); |
| } |
| else { |
| try { |
| return Double.parseDouble(o.toString()); |
| } |
| catch (NumberFormatException e) { |
| LOG.warn("Configuration cannot evaluate value {} as a double value", o); |
| return defaultValue; |
| } |
| } |
| } |
| |
| // -------------------------------------------------------------------------------------------- |
| // Serialization |
| // -------------------------------------------------------------------------------------------- |
| |
| @Override |
| public void read(DataInputView in) throws IOException { |
| synchronized (this.confData) { |
| final int numberOfProperties = in.readInt(); |
| |
| for (int i = 0; i < numberOfProperties; i++) { |
| String key = StringValue.readString(in); |
| Object value; |
| |
| byte type = in.readByte(); |
| switch (type) { |
| case TYPE_STRING: |
| value = StringValue.readString(in); |
| break; |
| case TYPE_INT: |
| value = in.readInt(); |
| break; |
| case TYPE_LONG: |
| value = in.readLong(); |
| break; |
| case TYPE_FLOAT: |
| value = in.readFloat(); |
| break; |
| case TYPE_DOUBLE: |
| value = in.readDouble(); |
| break; |
| case TYPE_BOOLEAN: |
| value = in.readBoolean(); |
| break; |
| case TYPE_BYTES: |
| byte[] bytes = new byte[in.readInt()]; |
| in.readFully(bytes); |
| value = bytes; |
| break; |
| default: |
| throw new IOException("Unrecognized type: " + type); |
| } |
| |
| this.confData.put(key, value); |
| } |
| } |
| } |
| |
| @Override |
| public void write(final DataOutputView out) throws IOException { |
| synchronized (this.confData) { |
| out.writeInt(this.confData.size()); |
| |
| for (Map.Entry<String, Object> entry : this.confData.entrySet()) { |
| String key = entry.getKey(); |
| Object val = entry.getValue(); |
| |
| StringValue.writeString(key, out); |
| Class<?> clazz = val.getClass(); |
| |
| if (clazz == String.class) { |
| out.write(TYPE_STRING); |
| StringValue.writeString((String) val, out); |
| } |
| else if (clazz == Integer.class) { |
| out.write(TYPE_INT); |
| out.writeInt((Integer) val); |
| } |
| else if (clazz == Long.class) { |
| out.write(TYPE_LONG); |
| out.writeLong((Long) val); |
| } |
| else if (clazz == Float.class) { |
| out.write(TYPE_FLOAT); |
| out.writeFloat((Float) val); |
| } |
| else if (clazz == Double.class) { |
| out.write(TYPE_DOUBLE); |
| out.writeDouble((Double) val); |
| } |
| else if (clazz == byte[].class) { |
| out.write(TYPE_BYTES); |
| byte[] bytes = (byte[]) val; |
| out.writeInt(bytes.length); |
| out.write(bytes); |
| } |
| else if (clazz == Boolean.class) { |
| out.write(TYPE_BOOLEAN); |
| out.writeBoolean((Boolean) val); |
| } |
| else { |
| throw new IllegalArgumentException("Unrecognized type"); |
| } |
| } |
| } |
| } |
| |
| // -------------------------------------------------------------------------------------------- |
| |
| @Override |
| public int hashCode() { |
| int hash = 0; |
| for (String s : this.confData.keySet()) { |
| hash ^= s.hashCode(); |
| } |
| return hash; |
| } |
| |
| @SuppressWarnings("EqualsBetweenInconvertibleTypes") |
| @Override |
| public boolean equals(Object obj) { |
| if (this == obj) { |
| return true; |
| } |
| else if (obj instanceof Configuration) { |
| Map<String, Object> otherConf = ((Configuration) obj).confData; |
| |
| for (Map.Entry<String, Object> e : this.confData.entrySet()) { |
| Object thisVal = e.getValue(); |
| Object otherVal = otherConf.get(e.getKey()); |
| |
| if (!thisVal.getClass().equals(byte[].class)) { |
| if (!thisVal.equals(otherVal)) { |
| return false; |
| } |
| } else if (otherVal.getClass().equals(byte[].class)) { |
| if (!Arrays.equals((byte[]) thisVal, (byte[]) otherVal)) { |
| return false; |
| } |
| } else { |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| else { |
| return false; |
| } |
| } |
| |
| @Override |
| public String toString() { |
| return this.confData.toString(); |
| } |
| } |