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