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