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