forked from nus-cs2103-AY1819S2/addressbook-level4
-
Notifications
You must be signed in to change notification settings - Fork 5
/
ConcreteAliasManager.java
214 lines (176 loc) · 7.79 KB
/
ConcreteAliasManager.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
package seedu.address.logic.parser;
import java.util.HashMap;
import java.util.Objects;
import java.util.Optional;
import java.util.logging.Logger;
import seedu.address.commons.core.LogsCenter;
import seedu.address.storage.AliasStorage;
/**
* Manages user-defined command aliases.
*/
class ConcreteAliasManager implements AliasManager {
private static final String ERROR_INVALID_SYNTAX = "Aliases must be alphabetical only";
private static final String ERROR_DISALLOWED_COMMAND = "This command cannot be aliased";
private static final String ERROR_INVALID_COMMAND = "The provided command is not a valid command";
private static final String ERROR_COMMAND_IS_ALIAS = "The provided command is another alias";
private static final String ERROR_ALIAS_IS_COMMAND = "The provided alias is an existing command";
private static final String ERROR_ALIAS_IS_UNREGISTERED = "The provided alias is not registered";
private static final String REGEX_VALIDATOR = "([a-z]|[A-Z])+";
private static final Logger logger = LogsCenter.getLogger(ConcreteAliasManager.class);
private CommandValidator commandValidator;
private HashMap<String, String> aliases = new HashMap<>();
private AliasStorage aliasStorage;
/**
* Instantiates a ConcreteAliasManager.
* @param commandValidator Validates commands, must not be null.
* @param aliasStorage An AliasStorage object to support storing aliases persistently. Pass null
* to disable alias persistence (e.g. for unit testing).
*/
ConcreteAliasManager(CommandValidator commandValidator, AliasStorage aliasStorage) {
Objects.requireNonNull(commandValidator);
logger.info("Instantiating ConcreteAliasManager.");
this.commandValidator = commandValidator;
this.aliasStorage = aliasStorage;
logger.info("Instantiated ConcreteAliasManager.");
initialize();
}
/**
* Contains setup and initialization code that should be run before usage.
*/
private void initialize() {
logger.info("Initializing ConcreteAliasManager for use.");
if (aliasStorage == null) {
logger.info("No AliasStorage object provided. Terminating initialization.");
return;
}
loadStoredAliases();
}
/**
* Loads and restores previously-stored aliases from disk into memory,
* if an AliasStorage object is provided. Otherwise, do nothing.
* If an exception is thrown, log, terminate the method, and keep the `aliases` database empty.
*/
private void loadStoredAliases() {
HashMap<String, String> loadedAliases;
logger.info("Loading aliases from storage into memory.");
if (aliasStorage == null) {
logger.info("No AliasStorage object provided. Skipping loading aliases.");
return;
}
try {
logger.info("Decoding aliases.");
loadedAliases = aliasStorage.readAliases();
} catch (Exception e) {
logger.warning(
String.format("Encountered error decoding aliases: %s",
e.toString()));
logger.warning("Terminating loading aliases.");
return;
}
aliases = new HashMap(loadedAliases);
logger.info("Loaded aliases from storage");
}
/**
* Saves the current state of `aliases` into disk for persistent storage,
* if an AliasStorage object is provided. Otherwise, do nothing.
* Any exceptions thrown are logged.
*/
private void saveAliases() {
logger.info("Saving aliases into storage.");
if (aliasStorage == null) {
logger.info("No AliasStorage object provided. Skipping saving aliases.");
return;
}
try {
logger.info("Encoding aliases.");
aliasStorage.saveAliases((HashMap) aliases.clone());
} catch (Exception e) {
logger.warning(
String.format("Encountered error encoding aliases: %s",
e.toString()));
logger.warning("Terminating saving aliases.");
return;
}
logger.info("Saved aliases into storage.");
}
public boolean isAlias(String alias) {
Objects.requireNonNull(alias);
return aliases.containsKey(alias);
}
/**
* Associates an alias with a command.
* If alias already exists, it will be overwritten.
* @throws IllegalArgumentException if command has an invalid syntax (must be alphabetical only).
* @throws IllegalArgumentException if command is designated as un-aliasable.
* @throws IllegalArgumentException if command is invalid.
* @throws IllegalArgumentException if command is another registered alias.
* @throws IllegalArgumentException if alias is an existing command.
*/
public void registerAlias(String command, String alias) throws IllegalArgumentException {
Objects.requireNonNull(alias);
Objects.requireNonNull(command);
logger.info(
String.format("Registering alias=%s to command=%s.",
alias,
command));
// Guard against invalid alias syntax
if (!alias.matches(REGEX_VALIDATOR)) {
logger.warning("Alias syntax is invalid. Throwing IllegalArgumentException.");
throw new IllegalArgumentException(ERROR_INVALID_SYNTAX);
}
// Guard against command being designated as an un-aliasable command
if (commandValidator.isUnaliasableCommand(command)) {
logger.warning("Command cannot be aliased. Throwing IllegalArgumentException.");
throw new IllegalArgumentException(ERROR_DISALLOWED_COMMAND);
}
// Guard against command being invalid
if (!commandValidator.isValidCommand(command)) {
logger.warning("Command is invalid. Throwing IllegalArgumentException.");
throw new IllegalArgumentException(ERROR_INVALID_COMMAND);
}
// Guard against command being another registered alias
if (isAlias(command)) {
logger.warning("Command is an alias and cannot be aliased. Throwing IllegalArgumentException.");
throw new IllegalArgumentException(ERROR_COMMAND_IS_ALIAS);
}
// Guard against alias being an existing command
if (commandValidator.isValidCommand(alias)) {
logger.warning("Alias is a command and cannot be registered. Throwing IllegalArgumentException.");
throw new IllegalArgumentException(ERROR_ALIAS_IS_COMMAND);
}
aliases.put(alias, command);
saveAliases();
}
/**
* Removes an alias.
* @throws IllegalArgumentException if alias is not registered.
*/
public void unregisterAlias(String alias) throws IllegalArgumentException {
logger.info(String.format("Unregistering alias=%s.", alias));
// Guard against alias being unregistered
if (!isAlias(alias)) {
logger.warning("Alias is not registered. Throwing IllegalArgumentException.");
throw new IllegalArgumentException(ERROR_ALIAS_IS_UNREGISTERED);
}
aliases.remove(alias);
saveAliases();
}
public void clearAliases() {
logger.info("Clearing all aliases.");
aliases.clear();
saveAliases();
}
public Optional<String> getCommand(String alias) {
Objects.requireNonNull(alias);
logger.info(String.format("Getting command for alias=%s.", alias));
if (!isAlias(alias)) {
return Optional.empty();
}
String command = aliases.get(alias);
return Optional.of(command);
}
public HashMap<String, String> getAliasList() {
logger.info("Getting list of aliases.");
return (HashMap) aliases.clone();
}
}