Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.xnio.OptionMap Maven / Gradle / Ivy
/*
* JBoss, Home of Professional Open Source
*
* Copyright 2009 Red Hat, Inc. and/or its affiliates.
*
* Licensed 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.xnio;
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.Properties;
import java.io.Serializable;
import static org.xnio._private.Messages.msg;
import static org.xnio._private.Messages.optionParseMsg;
/**
* An immutable map of options to option values. No {@code null} keys or values are permitted.
*/
public final class OptionMap implements Iterable>, Serializable {
private static final long serialVersionUID = 3632842565346928132L;
private final Map , Object> value;
private OptionMap(final Map , Object> value) {
this.value = value;
}
/**
* Determine whether this option map contains the given option.
*
* @param option the option to check
* @return {@code true} if the option is present in the option map
*/
public boolean contains(Option> option) {
return value.containsKey(option);
}
/**
* Get the value of an option from this option map.
*
* @param option the option to get
* @param the type of the option
* @return the option value, or {@code null} if it is not present
*/
public T get(Option option) {
return option.cast(value.get(option));
}
/**
* Get the value of an option from this option map, with a specified default if the value is missing.
*
* @param option the option to get
* @param defaultValue the value to return if the option is not set
* @param the type of the option
* @return the option value, or {@code null} if it is not present
*/
public T get(Option option, T defaultValue) {
final Object o = value.get(option);
return o == null ? defaultValue : option.cast(o);
}
/**
* Get a boolean value from this option map, with a specified default if the value is missing.
*
* @param option the option to get
* @param defaultValue the default value if the option is not present
* @return the result
*/
public boolean get(Option option, boolean defaultValue) {
final Object o = value.get(option);
return o == null ? defaultValue : option.cast(o).booleanValue();
}
/**
* Get a int value from this option map, with a specified default if the value is missing.
*
* @param option the option to get
* @param defaultValue the default value if the option is not present
* @return the result
*/
public int get(Option option, int defaultValue) {
final Object o = value.get(option);
return o == null ? defaultValue : option.cast(o).intValue();
}
/**
* Get a long value from this option map, with a specified default if the value is missing.
*
* @param option the option to get
* @param defaultValue the default value if the option is not present
* @return the result
*/
public long get(Option option, long defaultValue) {
final Object o = value.get(option);
return o == null ? defaultValue : option.cast(o).longValue();
}
/**
* Iterate over the options in this map.
*
* @return an iterator over the options
*/
public Iterator> iterator() {
return Collections.unmodifiableCollection(value.keySet()).iterator();
}
/**
* Get the number of options stored in this map.
*
* @return the number of options
*/
public int size() {
return value.size();
}
/**
* The empty option map.
*/
public static final OptionMap EMPTY = new OptionMap(Collections. , Object>emptyMap());
/**
* Create a new builder.
*
* @return a new builder
*/
public static Builder builder() {
return new Builder();
}
/**
* Create a single-valued option map.
*
* @param option the option to put in the map
* @param value the option value
* @param the option value type
* @return the option map
*
* @since 3.0
*/
public static OptionMap create(Option option, T value) {
if (option == null) {
throw msg.nullParameter("option");
}
if (value == null) {
throw msg.nullParameter("value");
}
return new OptionMap(Collections., Object>singletonMap(option, option.cast(value)));
}
/**
* Create a two-valued option map. If both options are the same key, then only the second one is added
* to the map.
*
* @param option1 the first option to put in the map
* @param value1 the first option value
* @param option2 the second option to put in the map
* @param value2 the second option value
* @param the first option value type
* @param the second option value type
* @return the option map
*
* @since 3.0
*/
public static OptionMap create(Option option1, T1 value1, Option option2, T2 value2) {
if (option1 == null) {
throw msg.nullParameter("option1");
}
if (value1 == null) {
throw msg.nullParameter("value1");
}
if (option2 == null) {
throw msg.nullParameter("option2");
}
if (value2 == null) {
throw msg.nullParameter("value2");
}
if (option1 == option2) {
return create(option2, value2);
}
final IdentityHashMap, Object> map = new IdentityHashMap , Object>(2);
map.put(option1, value1);
map.put(option2, value2);
return new OptionMap(map);
}
public String toString() {
final StringBuilder builder = new StringBuilder();
builder.append('{');
final Iterator, Object>> iterator = value.entrySet().iterator();
while (iterator.hasNext()) {
final Map.Entry, Object> entry = iterator.next();
builder.append(entry.getKey()).append("=>").append(entry.getValue());
if (iterator.hasNext()) {
builder.append(',');
}
}
builder.append('}');
return builder.toString();
}
/**
* Determine whether this option map is equal to another.
*
* @param other the other option map
* @return {@code true} if they are equal, {@code false} otherwise
*/
public boolean equals(Object other) {
return other instanceof OptionMap && equals((OptionMap)other);
}
/**
* Determine whether this option map is equal to another.
*
* @param other the other option map
* @return {@code true} if they are equal, {@code false} otherwise
*/
public boolean equals(OptionMap other) {
return this == other || other != null && value.equals(other.value);
}
/**
* Get the hash code for this option map.
*
* @return the hash code
*/
public int hashCode() {
return value.hashCode();
}
/**
* A builder for immutable option maps. Create an instance with the {@link OptionMap#builder()} method.
*/
public static final class Builder {
private Builder() {
}
private static class OVPair {
Option option;
T value;
private OVPair(final Option option, final T value) {
this.option = option;
this.value = value;
}
}
private List> list = new ArrayList>();
/**
* Set a key-value pair, parsing the value from the given string.
*
* @param key the key
* @param stringValue the string value
* @param the option type
* @return this builder
*/
public Builder parse(Option key, String stringValue) {
set(key, key.parseValue(stringValue, key.getClass().getClassLoader()));
return this;
}
/**
* Set a key-value pair, parsing the value from the given string.
*
* @param key the key
* @param stringValue the string value
* @param classLoader the class loader to use for parsing the value
* @param the option type
* @return this builder
*/
public Builder parse(Option key, String stringValue, ClassLoader classLoader) {
set(key, key.parseValue(stringValue, classLoader));
return this;
}
/**
* Add all options from a properties file. Finds all entries which start with a given prefix followed by '.';
* the remainder of the property key (after the prefix) is the option name, and the value is the option value.
* If the prefix does not end with '.' character, a '.' will be appended to it before parsing.
*
* @param props the properties to read
* @param prefix the prefix
* @param optionClassLoader the class loader to use to resolve option names
* @return this builder
*/
public Builder parseAll(Properties props, String prefix, ClassLoader optionClassLoader) {
if (! prefix.endsWith(".")) {
prefix = prefix + ".";
}
for (String name : props.stringPropertyNames()) {
if (name.startsWith(prefix)) {
final String optionName = name.substring(prefix.length());
try {
final Option> option = Option.fromString(optionName, optionClassLoader);
parse(option, props.getProperty(name), optionClassLoader);
} catch (IllegalArgumentException e) {
optionParseMsg.invalidOptionInProperty(optionName, name, e);
}
}
}
return this;
}
/**
* Add all options from a properties file. Finds all entries which start with a given prefix followed by '.';
* the remainder of the property key (after the prefix) is the option name, and the value is the option value.
*
If the prefix does not end with '.' character, a '.' will be appended to it before parsing.
*
* @param props the properties to read
* @param prefix the prefix
* @return this builder
*/
public Builder parseAll(Properties props, String prefix) {
if (! prefix.endsWith(".")) {
prefix = prefix + ".";
}
for (String name : props.stringPropertyNames()) {
if (name.startsWith(prefix)) {
final String optionName = name.substring(prefix.length());
try {
final Option> option = Option.fromString(optionName, getClass().getClassLoader());
parse(option, props.getProperty(name));
} catch (IllegalArgumentException e) {
optionParseMsg.invalidOptionInProperty(optionName, name, e);
}
}
}
return this;
}
/**
* Set a key-value pair.
*
* @param key the key
* @param value the value
* @param the option type
* @return this builder
*/
public Builder set(Option key, T value) {
if (key == null) {
throw msg.nullParameter("key");
}
if (value == null) {
throw msg.nullParameter("value");
}
list.add(new OVPair(key, value));
return this;
}
/**
* Set an int value for an Integer key.
*
* @param key the option
* @param value the value
* @return this builder
*/
public Builder set(Option key, int value) {
if (key == null) {
throw msg.nullParameter("key");
}
list.add(new OVPair(key, Integer.valueOf(value)));
return this;
}
/**
* Set int values for an Integer sequence key.
*
* @param key the key
* @param values the values
* @return this builder
*/
public Builder setSequence(Option> key, int... values) {
if (key == null) {
throw msg.nullParameter("key");
}
Integer[] a = new Integer[values.length];
for (int i = 0; i < values.length; i++) {
a[i] = Integer.valueOf(values[i]);
}
list.add(new OVPair>(key, Sequence.of(a)));
return this;
}
/**
* Set a long value for a Long key.
*
* @param key the option
* @param value the value
* @return this builder
*/
public Builder set(Option key, long value) {
if (key == null) {
throw msg.nullParameter("key");
}
list.add(new OVPair(key, Long.valueOf(value)));
return this;
}
/**
* Set long values for a Long sequence key.
*
* @param key the key
* @param values the values
* @return this builder
*/
public Builder setSequence(Option> key, long... values) {
if (key == null) {
throw msg.nullParameter("key");
}
Long[] a = new Long[values.length];
for (int i = 0; i < values.length; i++) {
a[i] = Long.valueOf(values[i]);
}
list.add(new OVPair>(key, Sequence.of(a)));
return this;
}
/**
* Set a boolean value for a Boolean key.
*
* @param key the option
* @param value the value
* @return this builder
*/
public Builder set(Option key, boolean value) {
if (key == null) {
throw msg.nullParameter("key");
}
list.add(new OVPair(key, Boolean.valueOf(value)));
return this;
}
/**
* Set boolean values for an Boolean sequence key.
*
* @param key the key
* @param values the values
* @return this builder
*/
public Builder setSequence(Option> key, boolean... values) {
if (key == null) {
throw msg.nullParameter("key");
}
Boolean[] a = new Boolean[values.length];
for (int i = 0; i < values.length; i++) {
a[i] = Boolean.valueOf(values[i]);
}
list.add(new OVPair>(key, Sequence.of(a)));
return this;
}
/**
* Set a key-value pair, where the value is a sequence type.
*
* @param key the key
* @param values the values
* @param the option type
* @return this builder
*/
public Builder setSequence(Option> key, T... values) {
if (key == null) {
throw msg.nullParameter("key");
}
list.add(new OVPair>(key, Sequence.of(values)));
return this;
}
private void copy(Map, ?> map, Option option) {
set(option, option.cast(map.get(option)));
}
/**
* Add all the entries of a map. Any keys of the map which are not valid {@link Option}s, or whose
* values are not valid arguments for the given {@code Option}, will cause an exception to be thrown.
* Any keys which occur more than once in this builder will be overwritten with the last occurring value.
*
* @param map the map
* @return this builder
* @throws ClassCastException if any entries of the map are not valid option-value pairs
*/
public Builder add(Map, ?> map) throws ClassCastException {
for (Object key : map.keySet()) {
final Option> option = Option.class.cast(key);
copy(map, option);
}
return this;
}
private void copy(OptionMap optionMap, Option option) {
set(option, optionMap.get(option));
}
/**
* Add all entries from an existing option map to the one being built.
* Any keys which occur more than once in this builder will be overwritten with the last occurring value.
*
* @param optionMap the original option map
* @return this builder
*/
public Builder addAll(OptionMap optionMap) {
for (Option> option : optionMap) {
copy(optionMap, option);
}
return this;
}
/**
* Build a map that reflects the current state of this builder.
*
* @return the new immutable option map
*/
public OptionMap getMap() {
final List> list = this.list;
if (list.size() == 0) {
return EMPTY;
} else if (list.size() == 1) {
final OVPair> pair = list.get(0);
return new OptionMap(Collections., Object>singletonMap(pair.option, pair.value));
} else {
final Map , Object> map = new IdentityHashMap , Object>();
for (OVPair> ovPair : list) {
map.put(ovPair.option, ovPair.value);
}
return new OptionMap(map);
}
}
}
}