re base code
[sdc.git] / catalog-model / src / main / java / org / openecomp / sdc / be / model / tosca / converters / ListConverter.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.openecomp.sdc.be.model.tosca.converters;
22
23 import com.google.gson.*;
24 import fj.data.Either;
25 import org.apache.commons.lang3.tuple.ImmutablePair;
26 import org.openecomp.sdc.be.config.BeEcompErrorManager;
27 import org.openecomp.sdc.be.model.DataTypeDefinition;
28 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
29 import org.openecomp.sdc.be.model.tosca.validators.DataTypeValidatorConverter;
30 import org.openecomp.sdc.be.model.tosca.validators.ListValidator;
31 import org.openecomp.sdc.common.log.wrappers.Logger;
32 import org.openecomp.sdc.common.util.GsonFactory;
33 import org.openecomp.sdc.common.util.JsonUtils;
34
35 import java.math.BigInteger;
36 import java.util.ArrayList;
37 import java.util.List;
38 import java.util.Map;
39
40 public class ListConverter implements PropertyValueConverter {
41
42     private static ListConverter listConverter = new ListConverter();
43     private static Gson gson = GsonFactory.getGson();
44     private static final Logger log = Logger.getLogger(ListValidator.class.getName());
45
46     DataTypeValidatorConverter dataTypeValidatorConverter = DataTypeValidatorConverter.getInstance();
47
48     private static JsonParser jsonParser = new JsonParser();
49
50     public static ListConverter getInstance() {
51         return listConverter;
52     }
53
54     @Override
55     public String convert(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) {
56         Either<String, Boolean> convertWithErrorResult = this.convertWithErrorResult(value, innerType, dataTypes);
57         if (convertWithErrorResult.isRight()) {
58             return null;
59         }
60
61         return convertWithErrorResult.left().value();
62     }
63
64     public Either<String, Boolean> convertWithErrorResult(String value, String innerType,
65             Map<String, DataTypeDefinition> dataTypes) {
66         if (value == null || innerType == null) {
67             return Either.left(value);
68         }
69
70         PropertyValueConverter innerConverter;
71         ToscaPropertyType innerToscaType = ToscaPropertyType.isValidType(innerType);
72
73         if (innerToscaType != null) {
74             PropertyValueConverter innerConverter1;
75             switch (innerToscaType) {
76             case STRING:
77                 innerConverter1 = ToscaPropertyType.STRING.getConverter();
78                 break;
79             case INTEGER:
80                 innerConverter1 = ToscaPropertyType.INTEGER.getConverter();
81                 break;
82             case FLOAT:
83                 innerConverter1 = ToscaPropertyType.FLOAT.getConverter();
84                 break;
85             case BOOLEAN:
86                 innerConverter1 = ToscaPropertyType.BOOLEAN.getConverter();
87                 break;
88             case JSON:
89                 innerConverter1 = ToscaPropertyType.JSON.getConverter();
90                 break;
91             default:
92                 log.debug("inner Tosca Type is unknown");
93                 return Either.left(value);
94             }
95             innerConverter = innerConverter1;
96         } else {
97             log.debug("inner Tosca Type {} ia a complex data type.", innerType);
98
99             return convertComplexInnerType(value, innerType, dataTypes);
100         }
101
102         try {
103             ArrayList<String> newList = new ArrayList<>();
104
105             JsonArray jo = (JsonArray) jsonParser.parse(value);
106             if(ToscaPropertyType.JSON == innerToscaType)
107                 return Either.left(value);
108             int size = jo.size();
109             for (int i = 0; i < size; i++) {
110                 JsonElement currentValue = jo.get(i);
111                 String element = JsonUtils.toString(currentValue);
112
113                 if (element == null || element.isEmpty()) {
114                     continue;
115                 }
116                 element = innerConverter.convert(element, null, dataTypes);
117                 newList.add(element);
118             }
119
120             switch (innerToscaType) {
121             case STRING:
122                 value = gson.toJson(newList);
123                 break;
124             case INTEGER:
125                 List<BigInteger> intList = new ArrayList<>();
126
127                 for (String str : newList) {
128                     int base = 10;
129                     if (str.contains("0x")) {
130                         str = str.replaceFirst("0x", "");
131                         base = 16;
132                     }
133                     if (str.contains("0o")) {
134                         str = str.replaceFirst("0o", "");
135                         base = 8;
136                     }
137                     intList.add(new BigInteger(str, base));
138                 }
139                 value = gson.toJson(intList);
140                 break;
141             case FLOAT:
142                 value = "[";
143                 for (String str : newList) {
144                     value += str + ",";
145                 }
146                 value = value.substring(0, value.length() - 1);
147                 value += "]";
148                 break;
149             case BOOLEAN:
150                 List<Boolean> boolList = new ArrayList<>();
151                 for (String str : newList) {
152                     boolList.add(Boolean.valueOf(str));
153                 }
154                 value = gson.toJson(boolList);
155                 break;
156             default:
157                 value = gson.toJson(newList);
158                 log.debug("inner Tosca Type unknown : {}", innerToscaType);
159             }
160
161         } catch (JsonParseException e) {
162             log.debug("Failed to parse json : {}", value, e);
163             BeEcompErrorManager.getInstance().logBeInvalidJsonInput("List Converter");
164             return Either.right(false);
165         }
166
167         return Either.left(value);
168     }
169
170     private Either<String, Boolean> convertComplexInnerType(String value, String innerType,
171             Map<String, DataTypeDefinition> allDataTypes) {
172
173         DataTypeDefinition dataTypeDefinition = allDataTypes.get(innerType);
174         if (dataTypeDefinition == null) {
175             log.debug("Cannot find data type {}", innerType);
176             return Either.right(false);
177         }
178
179         List<JsonElement> newList = new ArrayList<>();
180
181         try {
182
183             JsonArray jo = (JsonArray) jsonParser.parse(value);
184             int size = jo.size();
185             for (int i = 0; i < size; i++) {
186                 JsonElement currentValue = jo.get(i);
187
188                 if (currentValue != null) {
189
190                     String element = JsonUtils.toString(currentValue);
191
192                     ImmutablePair<JsonElement, Boolean> validateAndUpdate = dataTypeValidatorConverter
193                             .validateAndUpdate(element, dataTypeDefinition, allDataTypes);
194                     if (!validateAndUpdate.right.booleanValue()) {
195                         log.debug("Cannot parse value {} from type {} in list position {}",currentValue,innerType,i);
196                         return Either.right(false);
197                     }
198                     JsonElement newValue = validateAndUpdate.left;
199                     newList.add(newValue);
200                 }
201             }
202         } catch (Exception e) {
203             log.debug("Failed to parse the value {} of list parameter.", value);
204             return Either.right(false);
205         }
206         value = gson.toJson(newList);
207         return Either.left(value);
208     }
209
210 }