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 package net.sourceforge.plantumldependency.commoncli.command.impl;
26
27 import static java.util.Arrays.asList;
28 import static java.util.logging.Level.FINE;
29 import static java.util.logging.Level.INFO;
30 import static java.util.logging.Level.SEVERE;
31 import static java.util.logging.Logger.getLogger;
32 import static net.sourceforge.plantumldependency.common.constants.CharacterConstants.SPACE_CHAR;
33 import static net.sourceforge.plantumldependency.common.constants.CommonConstants.BLANK_STRING;
34 import static net.sourceforge.plantumldependency.common.constants.CommonConstants.MINUS_ONE_RETURN_CODE;
35 import static net.sourceforge.plantumldependency.common.constants.log.ErrorConstants.UNEXPECTED_ERROR;
36 import static net.sourceforge.plantumldependency.common.utils.check.ParameterCheckerUtils.checkNull;
37 import static net.sourceforge.plantumldependency.common.utils.log.LogUtils.buildLogString;
38 import static net.sourceforge.plantumldependency.commoncli.constants.CommandLineConstants.OPTION_STATUS_ACTIVE_SET;
39 import static net.sourceforge.plantumldependency.commoncli.constants.log.ErrorConstants.ARGUMENT_NOT_FOUND_BUT_MANDATORY_ERROR;
40 import static net.sourceforge.plantumldependency.commoncli.constants.log.ErrorConstants.COMMAND_LINE_ARGUMENTS_NULL_ERROR;
41 import static net.sourceforge.plantumldependency.commoncli.constants.log.ErrorConstants.DUPLICATE_OPTION_ERROR;
42 import static net.sourceforge.plantumldependency.commoncli.constants.log.ErrorConstants.MANDATORY_OPTION_ERROR;
43 import static net.sourceforge.plantumldependency.commoncli.constants.log.ErrorConstants.OPTION_NULL_ERROR;
44 import static net.sourceforge.plantumldependency.commoncli.constants.log.FineConstants.NO_COMMAND_LINE_ARGUMENTS_FINE;
45 import static net.sourceforge.plantumldependency.commoncli.constants.log.FineConstants.OPTION_NOT_SPECIFIED_FINE;
46 import static net.sourceforge.plantumldependency.commoncli.constants.log.FineConstants.OPTION_SPECIFIED_FINE;
47 import static net.sourceforge.plantumldependency.commoncli.constants.log.FineConstants.SKIPPING_ARGUMENT_FINE;
48 import static net.sourceforge.plantumldependency.commoncli.constants.log.InfoConstants.ARGUMENT_NOT_SPECIFIED_INFO;
49 import static net.sourceforge.plantumldependency.commoncli.constants.log.InfoConstants.OPTION_SPECIFIED_INFO;
50
51 import java.util.ArrayList;
52 import java.util.List;
53 import java.util.logging.Logger;
54
55 import net.sourceforge.plantumldependency.commoncli.command.CommandLine;
56 import net.sourceforge.plantumldependency.commoncli.exception.CommandLineException;
57 import net.sourceforge.plantumldependency.commoncli.option.Option;
58 import net.sourceforge.plantumldependency.commoncli.option.OptionWithArgument;
59
60
61
62
63
64
65
66
67 public class CommandLineImpl implements CommandLine {
68
69
70 private static final long serialVersionUID = 8593066398749136948L;
71
72
73 private static final transient Logger LOGGER = getLogger(CommandLineImpl.class.getName());
74
75
76 private List < String > commandLineArguments;
77
78
79
80
81
82
83
84
85
86 public CommandLineImpl(final String[] args) {
87 checkNull(args, COMMAND_LINE_ARGUMENTS_NULL_ERROR);
88
89 commandLineArguments = new ArrayList < String >(asList(args));
90 }
91
92
93
94
95
96
97 @Override
98 public int compareTo(final CommandLine o) {
99 return getCommandLineArgumentsAsString().toString().compareTo(o.getCommandLineArgumentsAsString().toString());
100 }
101
102
103
104
105
106
107 @Override
108 public CommandLine deepClone() {
109 CommandLineImpl a = null;
110
111 try {
112 a = (CommandLineImpl) super.clone();
113 a.commandLineArguments = new ArrayList < String >(getCommandLineArguments());
114 } catch (final CloneNotSupportedException cnse) {
115 LOGGER.log(SEVERE, UNEXPECTED_ERROR, cnse);
116 }
117
118 return a;
119 }
120
121
122
123
124
125
126 @Override
127 public boolean equals(final Object obj) {
128 if (this == obj) {
129 return true;
130 }
131 if (obj == null) {
132 return false;
133 }
134 if (getClass() != obj.getClass()) {
135 return false;
136 }
137 final CommandLineImpl other = (CommandLineImpl) obj;
138 if (commandLineArguments == null) {
139 if (other.commandLineArguments != null) {
140 return false;
141 }
142 } else if (!commandLineArguments.equals(other.commandLineArguments)) {
143 return false;
144 }
145 return true;
146 }
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161 private int findAndCheckOptionIndex(final Option option) throws CommandLineException {
162 checkNull(option, OPTION_NULL_ERROR);
163
164 int optionIndex = MINUS_ONE_RETURN_CODE;
165
166 for (int i = 0; i < getCommandLineArguments().size(); i++) {
167 final String currentArgument = getCommandLineArguments().get(i);
168 if (option.getAllNames().contains(currentArgument)) {
169 if (optionIndex == MINUS_ONE_RETURN_CODE) {
170 LOGGER.log(INFO, buildLogString(OPTION_SPECIFIED_INFO, option.getAllNames()));
171 optionIndex = i;
172 } else {
173 throw new CommandLineException(buildLogString(DUPLICATE_OPTION_ERROR, option.getAllNames()));
174 }
175 } else {
176 LOGGER.log(FINE,
177 buildLogString(SKIPPING_ARGUMENT_FINE, new String[] {currentArgument, option.getName()}));
178 }
179 }
180
181 if (optionIndex == MINUS_ONE_RETURN_CODE) {
182 if (option.isMandatory()) {
183 throw new CommandLineException(buildLogString(MANDATORY_OPTION_ERROR, option.getAllNames()));
184 } else {
185 LOGGER.log(FINE, buildLogString(OPTION_NOT_SPECIFIED_FINE, option.getAllNames()));
186 }
187 } else {
188 LOGGER.log(FINE, buildLogString(OPTION_SPECIFIED_FINE, option.getAllNames()));
189 }
190
191 return optionIndex;
192 }
193
194
195
196
197
198
199 @Override
200 public String findOptionArgument(final OptionWithArgument < ? > option) throws CommandLineException {
201 checkNull(option, OPTION_NULL_ERROR);
202
203 String argumentString = null;
204
205 final int optionIndex = findAndCheckOptionIndex(option);
206 if (optionIndex == MINUS_ONE_RETURN_CODE) {
207 LOGGER.log(FINE, buildLogString(OPTION_NOT_SPECIFIED_FINE, option.getAllNames()));
208 } else {
209 final int argumentIndex = optionIndex + 1;
210 if (argumentIndex >= getCommandLineArguments().size()) {
211 if (option.getOptionArgument().isMandatory()) {
212 throw new CommandLineException(buildLogString(ARGUMENT_NOT_FOUND_BUT_MANDATORY_ERROR,
213 option.getAllNames()));
214 }
215 LOGGER.log(INFO, buildLogString(ARGUMENT_NOT_SPECIFIED_INFO, option.getAllNames()));
216 argumentString = BLANK_STRING;
217 } else {
218 argumentString = getCommandLineArguments().get(argumentIndex);
219 try {
220 option.getOptionArgument().parseArgument(argumentString);
221 } catch (final CommandLineException e) {
222 if (option.getOptionArgument().isMandatory()) {
223 throw new CommandLineException(buildLogString(ARGUMENT_NOT_FOUND_BUT_MANDATORY_ERROR,
224 option.getAllNames()), e);
225 }
226 LOGGER.log(INFO, buildLogString(ARGUMENT_NOT_SPECIFIED_INFO, option.getAllNames()));
227 argumentString = BLANK_STRING;
228 }
229 }
230 }
231
232 return argumentString;
233 }
234
235
236
237
238
239
240 @Override
241 public List < String > getCommandLineArguments() {
242 return commandLineArguments;
243 }
244
245
246
247
248
249
250 @Override
251 public StringBuilder getCommandLineArgumentsAsString() {
252 final StringBuilder buffer = new StringBuilder();
253
254 if (getCommandLineArguments().size() == 0) {
255 LOGGER.log(FINE, NO_COMMAND_LINE_ARGUMENTS_FINE);
256 } else {
257 for (int i = 0; i < getCommandLineArguments().size() - 1; i++) {
258 final String argument = getCommandLineArguments().get(i);
259 buffer.append(argument);
260 buffer.append(SPACE_CHAR);
261 }
262
263 buffer.append(getCommandLineArguments().get(getCommandLineArguments().size() - 1));
264 }
265
266 return buffer;
267 }
268
269
270
271
272
273
274 @Override
275 public int hashCode() {
276 final int prime = 31;
277 int result = 1;
278 result = prime * result + ((commandLineArguments == null) ? 0 : commandLineArguments.hashCode());
279 return result;
280 }
281
282
283
284
285
286
287 @Override
288 public boolean isOptionActiveAndSpecified(final Option option) throws CommandLineException {
289 return OPTION_STATUS_ACTIVE_SET.contains(option.getStatus()) && isOptionSpecified(option);
290 }
291
292
293
294
295
296
297 @Override
298 public boolean isOptionSpecified(final Option option) throws CommandLineException {
299 return findAndCheckOptionIndex(option) != MINUS_ONE_RETURN_CODE;
300 }
301
302
303
304
305
306
307 @Override
308 public String toString() {
309 return getClass().getSimpleName() + " [commandLineArguments=" + commandLineArguments + "]";
310 }
311 }