org.telegram.telegrambots.abilitybots.api.objects.Ability Maven / Gradle / Ivy
Show all versions of telegrambots-abilities Show documentation
package org.telegram.telegrambots.abilitybots.api.objects;
import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import lombok.extern.slf4j.Slf4j;
import org.telegram.telegrambots.abilitybots.api.bot.BaseAbilityBot;
import org.telegram.telegrambots.meta.api.objects.Update;
import java.util.Arrays;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Predicate;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Lists.newArrayList;
import static java.lang.String.format;
import static java.util.Objects.hash;
import static java.util.Optional.ofNullable;
import static org.telegram.telegrambots.abilitybots.api.util.AbilityUtils.isValidCommandName;
/**
* An ability is a fully-fledged bot action that contains all the necessary information to process:
*
* - A response to a command
* - A post-response to a command
* - A reply to a sequence of actions
*
*
* In-order to instantiate an ability, you can call {@link Ability#builder()} to get the {@link AbilityBuilder}.
* Once you're done setting your ability, you'll call {@link AbilityBuilder#build()} to get your constructed ability.
*
* The only optional fields in an ability are {@link Ability#info}, {@link Ability#postAction}, {@link Ability#flags} and {@link Ability#replies}.
*
* @author Abbas Abou Daya
*/
@Slf4j
public final class Ability {
private final String name;
private final String info;
private final Locality locality;
private final Privacy privacy;
private final int argNum;
private final boolean statsEnabled;
private final Consumer action;
private final Consumer postAction;
private final List replies;
private final List> flags;
@SafeVarargs
private Ability(String name, String info, Locality locality, Privacy privacy, int argNum, boolean statsEnabled, Consumer action, Consumer postAction, List replies, Predicate... flags) {
checkArgument(isValidCommandName(name), "Method name can only contain alpha-numeric characters and underscores," +
" cannot be longer than 31 characters, empty or null", name);
this.name = name;
this.info = info;
this.locality = checkNotNull(locality, "Please specify a valid locality setting. Use the Locality enum class");
this.privacy = checkNotNull(privacy, "Please specify a valid privacy setting. Use the Privacy enum class");
checkArgument(argNum >= 0, "The number of arguments the method can handle CANNOT be negative. " +
"Use the number 0 if the method ignores the arguments OR uses as many as appended");
this.argNum = argNum;
this.action = checkNotNull(action, "Method action can't be empty. Please assign a function by using .action() method");
if (postAction == null)
log.info(format("No post action was detected for method with name [%s]", name));
this.flags = ofNullable(flags).map(Arrays::asList).orElse(newArrayList());
this.postAction = postAction;
this.replies = replies;
this.statsEnabled = statsEnabled;
}
public static AbilityBuilder builder() {
return new AbilityBuilder();
}
public String name() {
return name;
}
public String info() {
return info;
}
public Locality locality() {
return locality;
}
public Privacy privacy() {
return privacy;
}
public int tokens() {
return argNum;
}
public boolean statsEnabled() {
return statsEnabled;
}
public Consumer action() {
return action;
}
public Consumer postAction() {
return postAction;
}
public List replies() {
return replies;
}
public List> flags() {
return flags;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("name", name)
.add("locality", locality)
.add("privacy", privacy)
.add("argNum", argNum)
.toString();
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
Ability ability = (Ability) o;
return argNum == ability.argNum &&
Objects.equal(name, ability.name) &&
locality == ability.locality &&
privacy == ability.privacy;
}
@Override
public int hashCode() {
return hash(name, info, locality, privacy, argNum, action, postAction, replies, flags);
}
public static class AbilityBuilder {
private String name;
private String info;
private Privacy privacy;
private Locality locality;
private int argNum;
private boolean statsEnabled;
private Consumer action;
private Consumer postAction;
private List replies;
private Predicate[] flags;
private AbilityBuilder() {
statsEnabled = false;
replies = newArrayList();
}
public AbilityBuilder action(Consumer consumer) {
this.action = consumer;
return this;
}
public AbilityBuilder name(String name) {
this.name = name;
return this;
}
public AbilityBuilder info(String info) {
this.info = info;
return this;
}
public AbilityBuilder flag(Predicate... flags) {
this.flags = flags;
return this;
}
public AbilityBuilder locality(Locality type) {
this.locality = type;
return this;
}
public AbilityBuilder input(int argNum) {
this.argNum = argNum;
return this;
}
public AbilityBuilder enableStats() {
statsEnabled = true;
return this;
}
public AbilityBuilder setStatsEnabled(boolean statsEnabled) {
this.statsEnabled = statsEnabled;
return this;
}
public AbilityBuilder privacy(Privacy privacy) {
this.privacy = privacy;
return this;
}
public AbilityBuilder post(Consumer postAction) {
this.postAction = postAction;
return this;
}
@SafeVarargs
public final AbilityBuilder reply(BiConsumer action, Predicate... conditions) {
replies.add(Reply.of(action, conditions));
return this;
}
public final AbilityBuilder reply(Reply reply) {
replies.add(reply);
return this;
}
public AbilityBuilder basedOn(Ability ability) {
replies.clear();
replies.addAll(ability.replies());
return name(ability.name())
.info(ability.info())
.input(ability.tokens())
.locality(ability.locality())
.privacy(ability.privacy())
.action(ability.action())
.post(ability.postAction());
}
public Ability build() {
return new Ability(name, info, locality, privacy, argNum, statsEnabled, action, postAction, replies, flags);
}
}
}