Changed an instance-reference to a static reference.
[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         for (int i = 0; i < args.size(); i++) {
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                         continue;
117                     }
118                     throw new OnapCliArgumentValueMissing(args.get(i));
119                 }
120
121                 if (paramMap.get(paramName).getParameterType().equals(OnapCommandParameterType.JSON)) {
122                     paramMap.get(paramName).setValue(readJsonStringFromUrl(args.get(i + 1),
123                             paramMap.get(paramName).getName()));
124                     i++;
125                     continue;
126
127                 } else if (paramMap.get(paramName).getParameterType().equals(OnapCommandParameterType.TEXT)) {
128                     paramMap.get(paramName).setValue(readTextStringFromUrl(args.get(i + 1),
129                             paramMap.get(paramName).getName()));
130                     i++;
131                     continue;
132
133                 } else if (paramMap.get(paramName).getParameterType().equals(OnapCommandParameterType.YAML)) {
134                     String value = readYamlStringFromUrl(args.get(i + 1),
135                             paramMap.get(paramName).getName());
136                     paramMap.get(paramName).setValue(value);
137                     i++;
138                     continue;
139
140                 } else if (paramMap.get(paramName).getParameterType().equals(OnapCommandParameterType.BYTE)) {
141                     paramMap.get(paramName).setValue(readBytesFromUrl(args.get(i + 1),
142                             paramMap.get(paramName).getName()));
143                     i++;
144                     continue;
145
146                 } else if (paramMap.get(paramName).getParameterType()
147                         .equals(OnapCommandParameterType.ARRAY)) {
148                     Object value = paramMap.get(paramName).getValue();
149                     List<String> list = (List<String>) value;
150
151                     list.add(readTextStringFromUrl(args.get(i + 1), paramMap.get(paramName).getName()));
152                     paramMap.get(paramName).setValue(list);
153                     i++;
154                     continue;
155
156                 } else if (paramMap.get(paramName).getParameterType()
157                         .equals(OnapCommandParameterType.MAP)) {
158                     Object value = paramMap.get(paramName).getValue();
159
160                     Map<String, String> map = (Map<String, String>) value;
161
162                     String arg = args.get(i + 1);
163                     String[] argArr = arg.split("=", 2);
164
165                     if (argArr.length != 2) {
166                         throw new OnapCliInvalidArgument(
167                                 paramMap.get(paramName).getName(),
168                                 "it should be in the form of <key>=<value>");
169                     }
170
171                     //Make sure to read values from file, in case file path is given.
172                     //map.put(argArr[0], readTextStringFromUrl(argArr[1], paramMap.get(paramName).getName()));
173                     map.put(argArr[0], argArr[1]);
174                     paramMap.get(paramName).setValue(map);
175                     i++;
176                     continue;
177                 }
178
179                 paramMap.get(paramName).setValue(args.get(i + 1));
180
181                 i++;
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         }
196
197         params.clear();
198         params.addAll(paramMap.values());
199     }
200
201     public static String readJsonStringFromUrl(String input, String argName) throws OnapCliInvalidArgument {
202         String jsonValue;
203         try {
204             File file = new File(input);
205             if (file.isFile()) {
206                 try(Reader reader = new FileReader(file)){
207                     jsonValue = gson.fromJson(reader, JsonElement.class).toString();
208                 }
209                 return jsonValue;
210             } else if (input.startsWith("file:") || input.startsWith("http:") || input.startsWith("ftp:")) {
211                 URL jsonUrl = new URL(input);
212                 try(Reader reader = new InputStreamReader(jsonUrl.openStream())){
213                     jsonValue = gson.fromJson(reader, JsonElement.class).toString();
214                 }
215                 return jsonValue;
216             } else {
217                 return gson.fromJson(input, JsonElement.class).toString();
218             }
219         } catch (Exception e) { // NOSONAR
220             throw new OnapCliInvalidArgument(argName, e);
221         }
222     }
223
224     public static String readTextStringFromUrl(String input, String argName) throws OnapCliInvalidArgument {
225         try {
226             File file = new File(input);
227             if (file.isFile()) {
228                 return FileUtils.readFileToString(file, (Charset) null);
229             } else {
230                 return input;
231             }
232
233         } catch (IOException e) {
234             throw new OnapCliInvalidArgument(argName, e);
235         }
236     }
237
238     public static String readYamlStringFromUrl(String input, String argName) throws OnapCliInvalidArgument {
239         try {
240             File file = new File(input);
241             if (file.isFile()) {
242                 String value = FileUtils.readFileToString(file, (Charset) null);
243                 YamlReader reader = new YamlReader(value);
244                 value = (String) reader.read();
245                 return value;
246             } else {
247                 return input;
248             }
249
250         } catch (IOException e) {
251             throw new OnapCliInvalidArgument(argName, e);
252         }
253     }
254
255     public static String readBytesFromUrl(String input, String argName) throws OnapCliInvalidArgument {
256         try {
257             File file = new File(input);
258             if (file.isFile()) {
259                 byte[] encodeBase64 = Base64.encodeBase64(FileUtils.readFileToByteArray(file));
260                 return new String(encodeBase64);
261             } else {
262                 byte[] encodeBase64 = Base64.encodeBase64(input.getBytes());
263                 return new String(encodeBase64);
264             }
265         } catch (IOException e) {
266             throw new OnapCliInvalidArgument(argName, e);
267         }
268     }
269
270     public static List<String> convertJsonToListString(String arg, String json) throws OnapCliInvalidArgument {
271         TypeToken<List<String>> mapType = new TypeToken<List<String>>() {
272         };
273         try {
274             return gson.fromJson(json, mapType.getType());
275         } catch (Exception e) { // NOSONAR
276             throw new OnapCliInvalidArgument(arg, e);
277         }
278     }
279
280     public static Map<String, String> convertJsonToMapString(String arg, String json) throws OnapCliInvalidArgument {
281         TypeToken<Map<String, String>> mapType = new TypeToken<Map<String, String>>() {
282         };
283         try {
284             return gson.fromJson(json, mapType.getType());
285         } catch (Exception e) { // NOSONAR
286             throw new OnapCliInvalidArgument(arg, e);
287         }
288     }
289 }