Merge "re visit a block of commented-out lines of code"
[cli.git] / main / src / main / java / org / onap / cli / main / utils / OnapCliArgsParser.java
1 /*
2  * Copyright 2017 Huawei Technologies Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package org.onap.cli.main.utils;
18
19 import java.io.File;
20 import java.io.IOException;
21 import java.net.URL;
22 import java.nio.charset.Charset;
23 import java.util.ArrayList;
24 import java.util.HashMap;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.Set;
28
29 import org.apache.commons.codec.binary.Base64;
30 import org.apache.commons.io.FileUtils;
31 import org.onap.cli.fw.error.OnapCommandException;
32 import org.onap.cli.fw.error.OnapCommandInvalidParameterValue;
33 import org.onap.cli.fw.input.OnapCommandParameter;
34 import org.onap.cli.fw.input.OnapCommandParameterType;
35 import org.onap.cli.main.error.OnapCliArgumentValueMissing;
36 import org.onap.cli.main.error.OnapCliInvalidArgument;
37 import com.esotericsoftware.yamlbeans.YamlReader;
38
39 import com.google.gson.Gson;
40 import com.google.gson.GsonBuilder;
41 import com.google.gson.JsonElement;
42 import com.google.gson.reflect.TypeToken;
43
44 import java.io.Reader;
45 import java.io.InputStreamReader;
46 import java.io.FileReader;
47
48 /**
49  * Oclip CLI utilities.
50  *
51  */
52 public class OnapCliArgsParser {
53     private static Gson gson = new GsonBuilder().serializeNulls().create();
54
55     /**
56      * private Constructor.
57      */
58     private OnapCliArgsParser() {
59
60     }
61
62     /**
63      * It read thru the args and populate the given params for short optional, long option and postional args the idx of
64      * positional args, is calculated based on the position at which it present in the params and args.
65      *
66      * @param params
67      *            List of command paramters
68      * @param args
69      *            Array of arguments
70      * @throws OnapCliArgumentValueMissing
71      *             ArgumentValueMissing exception
72      * @throws OnapCliInvalidArgument
73      *             Invalid argument exception
74      * @throws OnapCommandInvalidParameterValue
75      *             exception
76      */
77     public static void populateParams(Set<OnapCommandParameter> params, List<String> args)
78             throws OnapCommandException {
79         Map<String, String> shortOptionMap = new HashMap<>();
80         Map<String, String> longOptionMap = new HashMap<>();
81         List<String> positionArgs = new ArrayList<>();
82         Map<String, OnapCommandParameter> paramMap = new HashMap<>();
83
84         for (OnapCommandParameter param : params) {
85             boolean positional = true;
86             if (param.getShortOption() != null) {
87                 shortOptionMap.put(OnapCommandParameter.printShortOption(param.getShortOption()), param.getName());
88                 positional = false;
89             }
90             if (param.getLongOption() != null) {
91                 longOptionMap.put(OnapCommandParameter.printLongOption(param.getLongOption()), param.getName());
92                 positional = false;
93             }
94
95             if (positional) {
96                 positionArgs.add(param.getName());
97             }
98
99             paramMap.put(param.getName(), param);
100         }
101
102         int positionalIdx = 0;
103         int i = 0;
104         while(i < args.size()) {
105             String paramName = null;
106             if (shortOptionMap.containsKey(args.get(i))) {
107                 paramName = shortOptionMap.get(args.get(i));
108             } else if (longOptionMap.containsKey(args.get(i))) {
109                 paramName = longOptionMap.get(args.get(i));
110             }
111
112             if (paramName != null) {
113                 // end of the list or if its option rather than a value
114                 if ((i + 1) == args.size() || args.get(i + 1).startsWith("-")) {
115                     if (paramMap.get(paramName).getParameterType().equals(OnapCommandParameterType.BOOL)) {
116                         paramMap.get(paramName).setValue(true);
117                         i++;
118                         continue;
119                     }
120                     throw new OnapCliArgumentValueMissing(args.get(i));
121                 }
122
123                 if (paramMap.get(paramName).getParameterType().equals(OnapCommandParameterType.JSON)) {
124                     paramMap.get(paramName).setValue(readJsonStringFromUrl(args.get(i + 1),
125                             paramMap.get(paramName).getName()));
126                     i += 2;
127                     continue;
128
129                 } else if (paramMap.get(paramName).getParameterType().equals(OnapCommandParameterType.TEXT)) {
130                     paramMap.get(paramName).setValue(readTextStringFromUrl(args.get(i + 1),
131                             paramMap.get(paramName).getName()));
132                     i += 2;
133                     continue;
134
135                 } else if (paramMap.get(paramName).getParameterType().equals(OnapCommandParameterType.YAML)) {
136                     String value = readYamlStringFromUrl(args.get(i + 1),
137                             paramMap.get(paramName).getName());
138                     paramMap.get(paramName).setValue(value);
139                     i += 2;
140                     continue;
141
142                 } else if (paramMap.get(paramName).getParameterType().equals(OnapCommandParameterType.BYTE)) {
143                     paramMap.get(paramName).setValue(readBytesFromUrl(args.get(i + 1),
144                             paramMap.get(paramName).getName()));
145                     i += 2;
146                     continue;
147
148                 } else if (paramMap.get(paramName).getParameterType()
149                         .equals(OnapCommandParameterType.ARRAY)) {
150                     Object value = paramMap.get(paramName).getValue();
151                     List<String> list = (List<String>) value;
152
153                     list.add(readTextStringFromUrl(args.get(i + 1), paramMap.get(paramName).getName()));
154                     paramMap.get(paramName).setValue(list);
155                     i += 2;
156                     continue;
157
158                 } else if (paramMap.get(paramName).getParameterType()
159                         .equals(OnapCommandParameterType.MAP)) {
160                     Object value = paramMap.get(paramName).getValue();
161
162                     Map<String, String> map = (Map<String, String>) value;
163
164                     String arg = args.get(i + 1);
165                     String[] argArr = arg.split("=", 2);
166
167                     if (argArr.length != 2) {
168                         throw new OnapCliInvalidArgument(
169                                 paramMap.get(paramName).getName(),
170                                 "it should be in the form of <key>=<value>");
171                     }
172
173                     map.put(argArr[0], argArr[1]);
174                     paramMap.get(paramName).setValue(map);
175                     i += 2;
176                     continue;
177                 }
178
179                 paramMap.get(paramName).setValue(args.get(i + 1));
180
181                 i += 2;
182                 continue;
183             }
184
185             // it is positional option
186             // Positional arg is missing from the params
187             if (positionalIdx >= positionArgs.size()) {
188                 throw new OnapCliInvalidArgument(
189                         args.get(i),
190                         "No positional argument is defined for this one");
191             }
192
193             paramMap.get(positionArgs.get(positionalIdx)).setValue(args.get(i));
194             positionalIdx++;
195             i++;
196         }
197
198         params.clear();
199         params.addAll(paramMap.values());
200     }
201
202     public static String readJsonStringFromUrl(String input, String argName) throws OnapCliInvalidArgument {
203         String jsonValue;
204         try {
205             File file = new File(input);
206             if (file.isFile()) {
207                 try(Reader reader = new FileReader(file)){
208                     jsonValue = gson.fromJson(reader, JsonElement.class).toString();
209                 }
210                 return jsonValue;
211             } else if (input.startsWith("file:") || input.startsWith("http:") || input.startsWith("ftp:")) {
212                 URL jsonUrl = new URL(input);
213                 try(Reader reader = new InputStreamReader(jsonUrl.openStream())){
214                     jsonValue = gson.fromJson(reader, JsonElement.class).toString();
215                 }
216                 return jsonValue;
217             } else {
218                 return gson.fromJson(input, JsonElement.class).toString();
219             }
220         } catch (Exception e) { // NOSONAR
221             throw new OnapCliInvalidArgument(argName, e);
222         }
223     }
224
225     public static String readTextStringFromUrl(String input, String argName) throws OnapCliInvalidArgument {
226         try {
227             File file = new File(input);
228             if (file.isFile()) {
229                 return FileUtils.readFileToString(file, (Charset) null);
230             } else {
231                 return input;
232             }
233
234         } catch (IOException e) {
235             throw new OnapCliInvalidArgument(argName, e);
236         }
237     }
238
239     public static String readYamlStringFromUrl(String input, String argName) throws OnapCliInvalidArgument {
240         try {
241             File file = new File(input);
242             if (file.isFile()) {
243                 String value = FileUtils.readFileToString(file, (Charset) null);
244                 YamlReader reader = new YamlReader(value);
245                 value = (String) reader.read();
246                 return value;
247             } else {
248                 return input;
249             }
250
251         } catch (IOException e) {
252             throw new OnapCliInvalidArgument(argName, e);
253         }
254     }
255
256     public static String readBytesFromUrl(String input, String argName) throws OnapCliInvalidArgument {
257         try {
258             File file = new File(input);
259             if (file.isFile()) {
260                 byte[] encodeBase64 = Base64.encodeBase64(FileUtils.readFileToByteArray(file));
261                 return new String(encodeBase64);
262             } else {
263                 byte[] encodeBase64 = Base64.encodeBase64(input.getBytes());
264                 return new String(encodeBase64);
265             }
266         } catch (IOException e) {
267             throw new OnapCliInvalidArgument(argName, e);
268         }
269     }
270
271     public static List<String> convertJsonToListString(String arg, String json) throws OnapCliInvalidArgument {
272         TypeToken<List<String>> mapType = new TypeToken<List<String>>() {
273         };
274         try {
275             return gson.fromJson(json, mapType.getType());
276         } catch (Exception e) { // NOSONAR
277             throw new OnapCliInvalidArgument(arg, e);
278         }
279     }
280
281     public static Map<String, String> convertJsonToMapString(String arg, String json) throws OnapCliInvalidArgument {
282         TypeToken<Map<String, String>> mapType = new TypeToken<Map<String, String>>() {
283         };
284         try {
285             return gson.fromJson(json, mapType.getType());
286         } catch (Exception e) { // NOSONAR
287             throw new OnapCliInvalidArgument(arg, e);
288         }
289     }
290 }