Passed
Push — master ( 482350...d5f627 )
by Roannel Fernández
03:16
created

com.github.netkorp.telegram.framework.commands.basic.BasicHelpCommand   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 136
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 54
dl 0
loc 136
rs 10
c 1
b 0
f 0
wmc 14

8 Methods

Rating   Name   Duplication   Size   Complexity  
A helpForCommand(Command) 0 2 1
A description() 0 3 1
A BasicHelpCommand(SecurityManager) 0 3 1
A execute(Update,String[]) 0 22 5
A getAvailableCommands(Long) 0 6 2
A commandsByGroup(Collection) 0 14 1
A helpForGroup(String,List) 0 7 2
A execute(Update) 0 7 1
1
package com.github.netkorp.telegram.framework.commands.basic;
2
3
import com.github.netkorp.telegram.framework.annotations.TelegramCommand;
4
import com.github.netkorp.telegram.framework.commands.abstracts.AbstractSimpleCommand;
5
import com.github.netkorp.telegram.framework.commands.interfaces.Command;
6
import com.github.netkorp.telegram.framework.commands.interfaces.HelpCommand;
7
import com.github.netkorp.telegram.framework.condition.ExcludeCondition;
8
import com.github.netkorp.telegram.framework.exceptions.CommandNotFound;
9
import com.github.netkorp.telegram.framework.managers.CommandManager;
10
import com.github.netkorp.telegram.framework.managers.SecurityManager;
11
import org.apache.logging.log4j.util.Strings;
12
import org.springframework.beans.factory.annotation.Autowired;
13
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
14
import org.springframework.context.annotation.Conditional;
15
import org.telegram.telegrambots.meta.api.objects.Update;
16
17
import java.util.Collection;
18
import java.util.LinkedList;
19
import java.util.List;
20
import java.util.SortedMap;
21
import java.util.StringJoiner;
22
import java.util.TreeMap;
23
24
/**
25
 * Displays the bot's help.
26
 */
27
@TelegramCommand(name = "help", group = "Basic")
28
@Conditional(ExcludeCondition.class)
29
@ConditionalOnSingleCandidate(HelpCommand.class)
30
public class BasicHelpCommand extends AbstractSimpleCommand implements HelpCommand {
31
32
    /**
33
     * The component to know which user is authorized.
34
     */
35
    private final SecurityManager securityManager;
36
37
    /**
38
     * Constructs a new {@link BasicHelpCommand} instance with the {@link SecurityManager} component instance.
39
     *
40
     * @param securityManager the {@link SecurityManager} component instance.
41
     */
42
    @Autowired
43
    public BasicHelpCommand(SecurityManager securityManager) {
44
        this.securityManager = securityManager;
45
    }
46
47
    /**
48
     * Processes the data sent by the users.
49
     *
50
     * @param update the received message.
51
     * @param args   the parameters passed to the command execution.
52
     */
53
    @Override
54
    public void execute(final Update update, String[] args) {
55
        try {
56
            if (args.length == 0) {
57
                execute(update);
58
                return;
59
            }
60
61
            StringJoiner stringJoiner = new StringJoiner(System.lineSeparator());
62
63
            for (String arg : args) {
64
                try {
65
                    stringJoiner.add(helpForCommand(commandManager.getCommand(CommandManager.getCommandFullName(arg))));
66
                } catch (CommandNotFound commandNotFound) {
67
                    bot.sendMessage(String.format("%s: %s", commandNotFound.getMessage(), arg), update.getMessage().getChatId(), true);
68
                    execute(update);
69
                    throw commandNotFound;
70
                }
71
            }
72
73
            bot.sendMessage(stringJoiner.toString(), update.getMessage().getChatId(), true);
74
        } catch (CommandNotFound commandNotFound) {
75
            // Do nothing
76
        }
77
    }
78
79
    /**
80
     * Executes the command's logic without taking parameters.
81
     *
82
     * @param update the received message.
83
     */
84
    @Override
85
    public void execute(Update update) {
86
        StringJoiner stringJoiner = new StringJoiner(System.lineSeparator());
87
        stringJoiner.add("You can control me by sending these commands:");
88
        commandsByGroup(getAvailableCommands(update.getMessage().getChatId()))
89
                .forEach((group, commands) -> stringJoiner.add(helpForGroup(group, commands)));
90
        bot.sendMessage(stringJoiner.toString(), update.getMessage().getChatId(), true);
91
    }
92
93
    /**
94
     * Returns the help for the group of commands.
95
     *
96
     * @param group    the name of the group.
97
     * @param commands the commands into the group.
98
     * @return the help for the group.
99
     */
100
    private String helpForGroup(String group, List<Command> commands) {
101
        StringJoiner stringJoiner = new StringJoiner(System.lineSeparator());
102
        if (!Strings.isEmpty(group)) {
103
            stringJoiner.add(String.format("<b>%s</b>", group));
104
        }
105
        commands.forEach(command -> stringJoiner.add(helpForCommand(command)));
106
        return System.lineSeparator() + stringJoiner.toString();
107
    }
108
109
    /**
110
     * Returns the help for a single command.
111
     *
112
     * @param command the command.
113
     * @return the help of the command.
114
     */
115
    private String helpForCommand(Command command) {
116
        return String.format("%s - %s", CommandManager.getCommandFullName(command), command.description());
117
    }
118
119
    /**
120
     * Organizes the available commands into groups.
121
     *
122
     * @param commands the list with all the available commands.
123
     * @return the available commands in groups sorted by the group's name.
124
     */
125
    private SortedMap<String, List<Command>> commandsByGroup(Collection<Command> commands) {
126
        SortedMap<String, List<Command>> commandsByGroup = new TreeMap<>();
127
128
        commands.forEach(command -> {
129
            // Groups
130
            String group = command.getClass().getAnnotation(TelegramCommand.class).group();
131
132
            List<Command> commandList = commandsByGroup.getOrDefault(group, new LinkedList<>());
133
            commandList.add(command);
134
135
            commandsByGroup.put(group, commandList);
136
        });
137
138
        return commandsByGroup;
139
    }
140
141
    /**
142
     * Returns the list of available commands for the user. It takes into account whether the user is authorized or not.
143
     *
144
     * @param chatId the identification of the user's chat.
145
     * @return the list of available commands.
146
     */
147
    private Collection<Command> getAvailableCommands(Long chatId) {
148
        if (securityManager.isAuthorized(chatId)) {
149
            return commandManager.getAvailableCommands();
150
        }
151
152
        return commandManager.getAvailableNonSecureCommands();
153
    }
154
155
    /**
156
     * Returns the command's description, used to be displayed in help message.
157
     *
158
     * @return the command's description.
159
     */
160
    @Override
161
    public String description() {
162
        return "Shows this message";
163
    }
164
}
165