package ru.vyarus.dropwizard.guice.module.context.option;
import ru.vyarus.dropwizard.guice.module.context.option.internal.OptionHolder;
import ru.vyarus.dropwizard.guice.module.context.option.internal.OptionsSupport;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* Provides access to used options and values. Contains only options either set
* (in {@link ru.vyarus.dropwizard.guice.GuiceBundle}) or read (by guicey, bundles or guice services).
* Instance bound to guice context and available for injection. Also may be accessed through
* {@link ru.vyarus.dropwizard.guice.module.GuiceyConfigurationInfo#getOptions()}.
* <p>
* NOTE: service just provides info of already used options (consultation only service - for reporting).
* If option wasn't used then default value will not be returned (error will be thrown). Option value read will not
* mark option as used. Do not use it for reading option value (for actual option usage): use {@link Options} instead.
* <p>
* Most methods accept simple Enum instead of Enum & Option to simplify generic usage: if not allowed enum
* value will be used methods will throw exceptions. {@link #knowsOption(Enum)} method may be used to
* safely check enum value before calling actual data methods.
*
* @author Vyacheslav Rusakov
* @see Option for options details
* @since 11.08.2016
*/
@SuppressWarnings("unchecked")
public final class OptionsInfo {
private final OptionsSupport options;
public OptionsInfo(final OptionsSupport support) {
this.options = support;
}
/**
* NOTE: as option could be accessed at any time by guice service, so more options could appear over time.
* As a consequence, it can't be known for sure that option is not used, for example, just after application start.
*
* @param <T> helper type to define option
* @return set of all used options (either read or set)
* @see #getOptionGroups() for option groups
*/
public <T extends Enum & Option> Set<T> getOptions() {
return options.getOptions();
}
/**
* In contrast to {@link #getOptions()} returns only enum types of used options.
* For example, {@link ru.vyarus.dropwizard.guice.GuiceyOptions} is enum type for core guicey options.
*
* @return list of used option enums sorted by name
*/
public List<Class<Enum>> getOptionGroups() {
return getOptions().stream().<Class<Enum>>map(Enum::getDeclaringClass).distinct()
.sorted((one, two) -> one.getSimpleName().compareTo(two.getSimpleName()))
.collect(Collectors.toList());
}
/**
* @param option option enum
* @param <V> value type
* @return current option value (default or defined)
* @throws IllegalArgumentException if option was not used
*/
public <V> V getValue(final Enum option) {
final OptionHolder<V> holder = options.getHolder(option);
return holder == null ? null : holder.getValue();
}
/**
* Option usage tracked when option read by either
* {@linkplain ru.vyarus.dropwizard.guice.module.installer.bundle.GuiceyBootstrap#option(Enum) bundle} or
* from {@linkplain Options#get(Enum) guice service}. Option may be read in any time of application life so
* used value may change over time (even new options could appear for reporting).
*
* @param option option enum
* @return true if option was read, false if option set but never used
* @throws IllegalArgumentException if option was not used
*/
public boolean isUsed(final Enum option) {
final OptionHolder holder = options.getHolder(option);
return holder != null && holder.isUsed();
}
/**
* All options are set in application (before application start) and will not change after.
*
* @param option option enum
* @return true if option was manually defined, false when default value used
* @throws IllegalArgumentException if option was not used
*/
public boolean isSet(final Enum option) {
final OptionHolder holder = options.getHolder(option);
return holder != null && holder.isSet();
}
/**
* Use this method to check if option is available for reporting (option details methods will fail with
* exception if not known option will be provided).
*
* @param option option enum
* @return true if option registered (was used or set), false otherwise
*/
public boolean knowsOption(final Enum option) {
return options.containsOption(option);
}
}