javax0.jamal.tools.OptionsStore Maven / Gradle / Ivy
package javax0.jamal.tools;
import javax0.jamal.api.BadSyntax;
import javax0.jamal.api.Identified;
import javax0.jamal.api.Processor;
import javax0.jamal.api.SpecialCharacters;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class OptionsStore implements Identified {
final Processor processor;
private OptionsStore(Processor processor) {
this.processor = processor;
}
/**
* Get the options store that works with this processor.
*
* @param processor the processor of which we need the options store
* @return the options store.
*/
public static OptionsStore getInstance(Processor processor) {
return new OptionsStore(processor);
}
/**
* The name of the macro is {@code `options} that starts with a backtick. This is a character that is not allowed in
* a macro name. This way the macro instances will be stored in the macro register when it gets registered
* programmatically, but the macro source cannot reference it and also the built-in macro {@code define} will not
* overwrite it.
*
* @return the constant string {@code `options}
*/
@Override
public String getId() {
return null;
}
/**
* Add the options to the options store. If an option starts with the {@code ~} character then it will be removed
* from the options. This way it is possible to switch off an option.
*
* @param options the options to add to the store
*/
public void addOptions(final String... options) {
getNegatedParameters(options)
.forEach(s -> getOption(s).set(false));
getPositiveParameters(options)
.forEach(s -> getOption(s).set(true));
}
private static Stream getParameters(String[] options) {
return Arrays.stream(options)
.map(String::trim)
.filter(s -> !s.isEmpty());
}
private static List getNegatedParameters(String[] options) {
return getParameters(options)
.filter(s -> s.charAt(0) == SpecialCharacters.OPTION_NEGATE)
.map(s -> s.substring(1)).collect(Collectors.toList());
}
private static List getPositiveParameters(String[] options) {
return getParameters(options)
.filter(s -> s.charAt(0) != SpecialCharacters.OPTION_NEGATE).collect(Collectors.toList());
}
public void pushOptions(final String... options) {
getNegatedParameters(options)
.forEach(s -> getOption(s).push(false));
getPositiveParameters(options)
.forEach(s -> getOption(s).push(true));
}
public void popOptions(final String... options) throws BadSyntax {
BadSyntax.when(!getNegatedParameters(options).isEmpty(), "Cannot pop negated options");
for (final var s : getPositiveParameters(options)) {
getOption(s).pop();
}
}
private static Optional