fa9e4d5fc734acd61e80eea3d1c87487ac4425a0
[sdc.git] / common-be / src / main / java / org / openecomp / sdc / be / utils / PropertyFilterConstraintDataDefinitionHelper.java
1 /*
2  * -
3  *  ============LICENSE_START=======================================================
4  *  Copyright (C) 2022 Nordix Foundation.
5  *  ================================================================================
6  *  Licensed under the Apache License, Version 2.0 (the "License");
7  *  you may not use this file except in compliance with the License.
8  *  You may obtain a copy of the License at
9  *
10  *       http://www.apache.org/licenses/LICENSE-2.0
11  *
12  *  Unless required by applicable law or agreed to in writing, software
13  *  distributed under the License is distributed on an "AS IS" BASIS,
14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  *  See the License for the specific language governing permissions and
16  *  limitations under the License.
17  *
18  *  SPDX-License-Identifier: Apache-2.0
19  *  ============LICENSE_END=========================================================
20  */
21
22 package org.openecomp.sdc.be.utils;
23
24 import java.util.ArrayList;
25 import java.util.HashMap;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.Objects;
29 import java.util.Optional;
30 import java.util.Set;
31 import java.util.stream.Collectors;
32 import java.util.stream.Stream;
33 import lombok.AccessLevel;
34 import lombok.NoArgsConstructor;
35 import org.apache.commons.collections.CollectionUtils;
36 import org.apache.commons.lang3.StringUtils;
37 import org.openecomp.sdc.be.config.Configuration;
38 import org.openecomp.sdc.be.config.ConfigurationManager;
39 import org.openecomp.sdc.be.datatypes.elements.CustomYamlFunction;
40 import org.openecomp.sdc.be.datatypes.elements.PropertyFilterConstraintDataDefinition;
41 import org.openecomp.sdc.be.datatypes.elements.ToscaConcatFunction;
42 import org.openecomp.sdc.be.datatypes.elements.ToscaCustomFunction;
43 import org.openecomp.sdc.be.datatypes.elements.ToscaFunction;
44 import org.openecomp.sdc.be.datatypes.elements.ToscaFunctionParameter;
45 import org.openecomp.sdc.be.datatypes.elements.ToscaFunctionType;
46 import org.openecomp.sdc.be.datatypes.elements.ToscaGetFunctionDataDefinition;
47 import org.openecomp.sdc.be.datatypes.elements.ToscaStringParameter;
48 import org.openecomp.sdc.be.datatypes.enums.ConstraintType;
49 import org.openecomp.sdc.be.datatypes.enums.FilterValueType;
50 import org.openecomp.sdc.be.datatypes.enums.PropertyFilterTargetType;
51 import org.openecomp.sdc.be.datatypes.enums.PropertySource;
52 import org.openecomp.sdc.be.datatypes.tosca.ToscaGetFunctionType;
53 import org.yaml.snakeyaml.Yaml;
54
55 @NoArgsConstructor(access = AccessLevel.PRIVATE)
56 public class PropertyFilterConstraintDataDefinitionHelper {
57
58     public static PropertyFilterConstraintDataDefinition convertLegacyConstraint(final String constraint) {
59         final var propertyFilterConstraint = new PropertyFilterConstraintDataDefinition();
60         final Map<String, Object> constraintYaml = new Yaml().load(constraint);
61         final String propertyName = constraintYaml.keySet().iterator().next();
62         propertyFilterConstraint.setPropertyName(propertyName);
63         final Map<String, Object> operatorYaml = (Map<String, Object>) constraintYaml.get(propertyName);
64         final String operator = operatorYaml.keySet().iterator().next();
65         propertyFilterConstraint.setOperator(ConstraintType.findByType(operator).orElse(null));
66         final Object valueYaml = operatorYaml.get(operator);
67         final Optional<ToscaFunction> toscaFunction = createToscaFunctionFromLegacyConstraintValue(valueYaml);
68         if (toscaFunction.isPresent()) {
69             propertyFilterConstraint.setValue(toscaFunction.get());
70             propertyFilterConstraint.setValueType(detectValueType(valueYaml));
71         }
72         else {
73             propertyFilterConstraint.setValue(valueYaml);
74             if (valueYaml instanceof List) {
75                 List<ToscaFunction> listToscaFunction = new ArrayList<>();
76                 ((List<?>) valueYaml).stream().forEach(val -> {
77                     final Optional<ToscaFunction> optToscaFunctionLst = createToscaFunctionFromLegacyConstraintValue(val);
78                     if (optToscaFunctionLst.isPresent()) {
79                         listToscaFunction.add(optToscaFunctionLst.get());
80                     }
81                 });
82                 propertyFilterConstraint.setValue(listToscaFunction);
83                 propertyFilterConstraint.setValueType(FilterValueType.SEVERAL);
84             }
85             else {
86                 propertyFilterConstraint.setValueType(detectValueType(valueYaml));
87             }
88         }
89         propertyFilterConstraint.setTargetType(PropertyFilterTargetType.PROPERTY);
90         return propertyFilterConstraint;
91     }
92
93     public static Optional<ToscaFunction> createToscaFunctionFromLegacyConstraintValue(final Object filterValue) {
94         if (!(filterValue instanceof Map)) {
95             return Optional.empty();
96         }
97         final Map<?, ?> filterValueAsMap = (Map<?, ?>) filterValue;
98         final Set<?> keys = filterValueAsMap.keySet();
99         if (keys.size() != 1) {
100             return Optional.empty();
101         }
102         final Object toscaFunctionTypeObject = keys.iterator().next();
103         if (!(toscaFunctionTypeObject instanceof String)) {
104             return Optional.empty();
105         }
106         ToscaFunctionType toscaFunctionType = ToscaFunctionType.findType((String) toscaFunctionTypeObject).orElse(null);
107         if (toscaFunctionType == null) {
108             if (((String) toscaFunctionTypeObject).startsWith("$")) {
109                 toscaFunctionType = ToscaFunctionType.CUSTOM;
110             }
111             else {
112                 return Optional.empty();
113             }
114         }
115         switch (toscaFunctionType) {
116             case GET_INPUT:
117                 return readLegacyGetInputConstraintValue(filterValueAsMap, toscaFunctionTypeObject);
118             case GET_ATTRIBUTE:
119             case GET_PROPERTY:
120                 return readLegacyGetPropertyConstraintValue(filterValueAsMap, toscaFunctionTypeObject, toscaFunctionType);
121             case CONCAT:
122                 return readLegacyConcatConstraintValue(filterValueAsMap, toscaFunctionTypeObject);
123             case CUSTOM:
124                 return handleCustomFunction((Map<String, Object>)filterValueAsMap, (String)toscaFunctionTypeObject);
125             default:
126                 return Optional.empty();
127         }
128     }
129
130     private static Optional<ToscaFunction> handleCustomFunction(Map<String, Object> toscaFunctionPropertyValueMap, String functionType) {
131         final ToscaCustomFunction toscaCustomFunction = new ToscaCustomFunction();
132         toscaCustomFunction.setName(functionType.substring(1));
133         final Object functionValueObj = toscaFunctionPropertyValueMap.get(functionType);
134         toscaCustomFunction.setToscaFunctionType(getCustomFunctionType(toscaCustomFunction.getName()));
135         if (ToscaFunctionType.GET_INPUT.equals(toscaCustomFunction.getToscaFunctionType())) {
136             return handleCustomFunctionGetInputType(toscaCustomFunction, functionValueObj);
137         }
138         return handelCustomFunctionCustomType(toscaCustomFunction, functionValueObj);
139     }
140
141     private static Optional<ToscaFunction> handleCustomFunctionGetInputType(ToscaCustomFunction toscaCustomFunction, Object functionValueObj) {
142         if (!(functionValueObj instanceof String) && !(functionValueObj instanceof List)) {
143             return Optional.empty();
144         }
145         Map<String, Object> parameterMap = new HashMap<>();
146         parameterMap.put(ToscaFunctionType.GET_INPUT.getName(), functionValueObj);
147         buildToscaFunctionBasedOnPropertyValue(parameterMap).ifPresent(toscaFunction -> {
148             if (toscaFunction instanceof ToscaFunctionParameter) {
149                 toscaCustomFunction.addParameter((ToscaFunctionParameter) toscaFunction);
150             }
151         });
152         return Optional.of(toscaCustomFunction);
153     }
154
155     private static Optional<ToscaFunction> buildToscaFunctionBasedOnPropertyValue(final Map<String, Object> toscaFunctionPropertyValueMap) {
156         if (!isPropertyValueToscaFunction(toscaFunctionPropertyValueMap)) {
157             return Optional.empty();
158         }
159         final String functionType = toscaFunctionPropertyValueMap.keySet().iterator().next();
160         final ToscaFunctionType toscaFunctionType =
161             ToscaFunctionType.findType(functionType).orElse(functionType.startsWith("$") ? ToscaFunctionType.CUSTOM : null);
162         if (toscaFunctionType == null) {
163             return Optional.empty();
164         }
165         switch (toscaFunctionType) {
166             case GET_INPUT: {
167                 return handleGetInputFunction(toscaFunctionPropertyValueMap, functionType);
168             }
169             case GET_PROPERTY:
170             case GET_ATTRIBUTE: {
171                 return handleGetPropertyFunction(toscaFunctionPropertyValueMap, functionType, toscaFunctionType);
172             }
173             case CONCAT:
174                 return handleConcatFunction(toscaFunctionPropertyValueMap, functionType);
175             case CUSTOM:
176                 return handleCustomFunction(toscaFunctionPropertyValueMap, functionType);
177             default:
178                 return Optional.empty();
179         }
180     }
181
182     private static Optional<ToscaFunction> handleConcatFunction(Map<String, Object> toscaFunctionPropertyValueMap, String functionType) {
183         final ToscaConcatFunction toscaConcatFunction = new ToscaConcatFunction();
184         final Object functionValueObj = toscaFunctionPropertyValueMap.get(functionType);
185         if (!(functionValueObj instanceof List)) {
186             return Optional.empty();
187         }
188         final List<Object> functionParameters = (List<Object>) functionValueObj;
189         if (functionParameters.size() < 2) {
190             return Optional.empty();
191         }
192         functionParameters.forEach(parameter -> {
193             if (parameter instanceof String) {
194                 final var stringParameter = new ToscaStringParameter();
195                 stringParameter.setValue((String) parameter);
196                 toscaConcatFunction.addParameter(stringParameter);
197                 return;
198             }
199             if (isPropertyValueToscaFunction(parameter)) {
200                 buildToscaFunctionBasedOnPropertyValue((Map<String, Object>) parameter).ifPresent(toscaFunction -> {
201                     if (toscaFunction instanceof ToscaFunctionParameter) {
202                         toscaConcatFunction.addParameter((ToscaFunctionParameter) toscaFunction);
203                     }
204                 });
205                 return;
206             }
207             final var customYamlFunction = new CustomYamlFunction();
208             customYamlFunction.setYamlValue(parameter);
209             toscaConcatFunction.addParameter(customYamlFunction);
210         });
211         return Optional.of(toscaConcatFunction);
212     }
213
214     private static Optional<ToscaFunction> handleGetPropertyFunction(Map<String, Object> toscaFunctionPropertyValueMap, String functionType,
215                                                                      ToscaFunctionType toscaFunctionType) {
216         final ToscaGetFunctionDataDefinition toscaGetFunction = new ToscaGetFunctionDataDefinition();
217         toscaGetFunction.setFunctionType(
218             toscaFunctionType == ToscaFunctionType.GET_PROPERTY ? ToscaGetFunctionType.GET_PROPERTY : ToscaGetFunctionType.GET_ATTRIBUTE
219         );
220         final Object functionValueObj = toscaFunctionPropertyValueMap.get(functionType);
221         if (!(functionValueObj instanceof List)) {
222             return Optional.empty();
223         }
224         final List<String> functionParameters;
225         try {
226             functionParameters = ((List<Object>) functionValueObj).stream()
227                 .map(object -> Objects.toString(object, null))
228                 .collect(Collectors.toList());
229         } catch (final ClassCastException ignored) {
230             return Optional.empty();
231         }
232         if (functionParameters.size() < 2) {
233             return Optional.empty();
234         }
235         final String propertySourceType = functionParameters.get(0);
236         final PropertySource propertySource = PropertySource.findType(propertySourceType).orElse(null);
237         if (propertySource == PropertySource.SELF) {
238             toscaGetFunction.setPropertySource(propertySource);
239         } else {
240             toscaGetFunction.setPropertySource(PropertySource.INSTANCE);
241             toscaGetFunction.setSourceName(propertySourceType);
242         }
243         List<String> propertySourceIndex = functionParameters.subList(1, functionParameters.size());
244         List<String> propertySourcePath = new ArrayList<>();
245         propertySourcePath.add((String)propertySourceIndex.get(0));
246         if (propertySourceIndex.size() > 1 ) {
247             List<Object> indexParsedList = new ArrayList<Object>();
248             List<String> indexObjectList = propertySourceIndex.subList(1,propertySourceIndex.size());
249             boolean loopFlag = true;
250             for (String indexValue : indexObjectList) {
251                 if (!indexValue.equalsIgnoreCase("INDEX") && !StringUtils.isNumeric(indexValue) && loopFlag) {
252                     propertySourcePath.add(indexValue);
253                 } else {
254                     loopFlag = false;
255                     if (StringUtils.isNumeric(indexValue)) {
256                         indexParsedList.add(Integer.parseInt(indexValue));
257                     } else {
258                         indexParsedList.add(indexValue);
259                     }
260                 }
261             }
262             toscaGetFunction.setToscaIndexList(indexParsedList);
263         }
264         toscaGetFunction.setPropertyPathFromSource(propertySourcePath);
265         final String propertyName = toscaGetFunction.getPropertyPathFromSource().get(toscaGetFunction.getPropertyPathFromSource().size() - 1);
266         toscaGetFunction.setPropertyName(propertyName);
267         return Optional.of(toscaGetFunction);
268     }
269
270     private static Optional<ToscaFunction> handleGetInputFunction(Map<String, Object> toscaFunctionPropertyValueMap, String functionType) {
271         final ToscaGetFunctionDataDefinition toscaGetFunction = new ToscaGetFunctionDataDefinition();
272         toscaGetFunction.setFunctionType(ToscaGetFunctionType.GET_INPUT);
273         toscaGetFunction.setPropertySource(PropertySource.SELF);
274         final Object functionValueObj = toscaFunctionPropertyValueMap.get(functionType);
275         if (!(functionValueObj instanceof List) && !(functionValueObj instanceof String)) {
276             return Optional.empty();
277         }
278         if (functionValueObj instanceof String) {
279             toscaGetFunction.setPropertyPathFromSource(List.of((String) functionValueObj));
280         } else {
281             final List<String> functionParameters;
282             try {
283                 functionParameters = ((List<Object>) functionValueObj).stream()
284                     .map(object -> Objects.toString(object, null))
285                     .collect(Collectors.toList());
286             } catch (final ClassCastException ignored) {
287                 return Optional.empty();
288             }
289             List<String> propertySourcePath = new ArrayList<>();
290             propertySourcePath.add((String)functionParameters.get(0));
291             if (functionParameters.size() > 1 ) {
292                 List<Object> indexParsedList = new ArrayList<Object>();
293                 List<String> indexObjectList = functionParameters.subList(1,functionParameters.size());
294                 boolean loopFlag = true;
295                 for (String indexValue : indexObjectList) {
296                     if (!indexValue.equalsIgnoreCase("INDEX") && !StringUtils.isNumeric(indexValue) && loopFlag) {
297                         propertySourcePath.add(indexValue);
298                     } else {
299                         loopFlag = false;
300                         if (StringUtils.isNumeric(indexValue)) {
301                             indexParsedList.add(Integer.parseInt(indexValue));
302                         } else {
303                             indexParsedList.add(indexValue);
304                         }
305                     }
306                 }
307                 toscaGetFunction.setToscaIndexList(indexParsedList);
308             }
309             toscaGetFunction.setPropertyPathFromSource(propertySourcePath);
310         }
311         final String propertyName = toscaGetFunction.getPropertyPathFromSource().get(toscaGetFunction.getPropertyPathFromSource().size() - 1);
312         toscaGetFunction.setPropertyName(propertyName);
313         return Optional.of(toscaGetFunction);
314     }
315
316     public static boolean isPropertyValueToscaFunction(final Object propValueObj) {
317         if (propValueObj instanceof Map) {
318             final Map<String, Object> propValueMap = (Map<String, Object>) propValueObj;
319             if (propValueMap.keySet().size() > 1) {
320                 return false;
321             }
322             if (propValueMap.keySet().stream().anyMatch(keyValue -> keyValue.startsWith("$"))) {
323                 return true;
324             }
325
326             return Stream.of(ToscaFunctionType.GET_INPUT, ToscaFunctionType.GET_PROPERTY, ToscaFunctionType.GET_ATTRIBUTE, ToscaFunctionType.CONCAT)
327                 .anyMatch(type -> propValueMap.containsKey(type.getName()));
328         }
329         return false;
330     }
331
332     private static ToscaFunctionType getCustomFunctionType(String name) {
333         List<Configuration.CustomToscaFunction> customFunctions =
334             ConfigurationManager.getConfigurationManager().getConfiguration().getDefaultCustomToscaFunctions();
335         if (CollectionUtils.isEmpty(customFunctions)) {
336             return ToscaFunctionType.CUSTOM;
337         }
338         Optional<Configuration.CustomToscaFunction> optionalFunc = customFunctions.stream().filter(func -> func.getName().equals(name)).findFirst();
339         if (optionalFunc.isEmpty()) {
340             return ToscaFunctionType.CUSTOM;
341         }
342         String type = optionalFunc.get().getType();
343         return ToscaFunctionType.findType(type).get();
344     }
345
346     private static Optional<ToscaFunction> handelCustomFunctionCustomType(ToscaCustomFunction toscaCustomFunction, Object functionValueObj) {
347         if (!(functionValueObj instanceof List)) {
348             return Optional.empty();
349         }
350         final List<Object> functionParameters = (List<Object>) functionValueObj;
351         functionParameters.forEach(parameter -> {
352             if (parameter instanceof String) {
353                 final var stringParameter = new ToscaStringParameter();
354                 stringParameter.setValue((String) parameter);
355                 toscaCustomFunction.addParameter(stringParameter);
356                 return;
357             }
358             if (isPropertyValueToscaFunction(parameter)) {
359                 buildToscaFunctionBasedOnPropertyValue((Map<String, Object>) parameter).ifPresent(toscaFunction -> {
360                     if (toscaFunction instanceof ToscaFunctionParameter) {
361                         toscaCustomFunction.addParameter((ToscaFunctionParameter) toscaFunction);
362                     }
363                 });
364                 return;
365             }
366             final var customYamlFunction = new CustomYamlFunction();
367             customYamlFunction.setYamlValue(parameter);
368             toscaCustomFunction.addParameter(customYamlFunction);
369         });
370         return Optional.of(toscaCustomFunction);
371     }
372
373     public static Optional<FilterValueType> convertFromToscaFunctionType(final ToscaFunctionType toscaFunctionType) {
374         return FilterValueType.findByName(toscaFunctionType.getName());
375     }
376
377     private static Optional<ToscaFunction> readLegacyConcatConstraintValue(Map<?, ?> filterValueAsMap, Object toscaFunctionType) {
378         final List<Object> concatValue;
379         try {
380             concatValue = (List<Object>) filterValueAsMap.get(toscaFunctionType);
381         } catch (final Exception ignored) {
382             return Optional.empty();
383         }
384         if (concatValue.isEmpty()) {
385             return Optional.empty();
386         }
387         final var toscaConcatFunction = new ToscaConcatFunction();
388         for (Object parameter : concatValue) {
389             if (parameter instanceof String) {
390                 final ToscaStringParameter toscaStringParameter = new ToscaStringParameter();
391                 toscaStringParameter.setValue((String) parameter);
392                 toscaConcatFunction.addParameter(toscaStringParameter);
393             } else {
394                 createToscaFunctionFromLegacyConstraintValue(parameter)
395                     .ifPresent(toscaFunction -> toscaConcatFunction.addParameter((ToscaFunctionParameter) toscaFunction));
396             }
397         }
398         return Optional.of(toscaConcatFunction);
399     }
400
401     private static Optional<ToscaFunction> readLegacyGetPropertyConstraintValue(Map<?, ?> filterValueAsMap, Object toscaFunctionType,
402                                                                                 ToscaFunctionType toscaFunctionType1) {
403         final ToscaGetFunctionDataDefinition toscaGetFunction = new ToscaGetFunctionDataDefinition();
404         toscaGetFunction.setFunctionType(
405             toscaFunctionType.toString().equalsIgnoreCase(ToscaFunctionType.GET_PROPERTY.getName()) ? ToscaGetFunctionType.GET_PROPERTY : ToscaGetFunctionType.GET_ATTRIBUTE
406         );
407         final Object functionValueObj = null != filterValueAsMap.get(toscaFunctionType1) ?
408             filterValueAsMap.get(toscaFunctionType1) : filterValueAsMap.get(toscaFunctionType);
409         if (!(functionValueObj instanceof List)) {
410             return Optional.empty();
411         }
412         final List<String> functionParameters;
413         try {
414             functionParameters = ((List<Object>) functionValueObj).stream()
415                 .map(object -> Objects.toString(object, null))
416                 .collect(Collectors.toList());
417         } catch (final ClassCastException ignored) {
418             return Optional.empty();
419         }
420         if (functionParameters.size() < 2) {
421             return Optional.empty();
422         }
423         final String propertySourceType = functionParameters.get(0);
424         final PropertySource propertySource = PropertySource.findType(propertySourceType).orElse(null);
425         if (propertySource == PropertySource.SELF) {
426             toscaGetFunction.setPropertySource(propertySource);
427         } else {
428             toscaGetFunction.setPropertySource(PropertySource.INSTANCE);
429             toscaGetFunction.setSourceName(propertySourceType);
430         }
431         List<String> propertySourceIndex = functionParameters.subList(1, functionParameters.size());
432         List<String> propertySourcePath = new ArrayList<>();
433         propertySourcePath.add((String)propertySourceIndex.get(0));
434         if (propertySourceIndex.size() > 1 ) {
435             List<Object> indexParsedList = new ArrayList<Object>();
436             List<String> indexObjectList = propertySourceIndex.subList(1,propertySourceIndex.size());
437             boolean loopFlag = true;
438             for (String indexValue : indexObjectList) {
439                 if (!indexValue.equalsIgnoreCase("INDEX") && !StringUtils.isNumeric(indexValue) && loopFlag) {
440                     propertySourcePath.add(indexValue);
441                 } else {
442                     loopFlag = false;
443                     if (StringUtils.isNumeric(indexValue)) {
444                         indexParsedList.add(Integer.parseInt(indexValue));
445                     } else {
446                         indexParsedList.add(indexValue);
447                     }
448                 }
449             }
450             toscaGetFunction.setToscaIndexList(indexParsedList);
451         }
452         toscaGetFunction.setPropertyPathFromSource(propertySourcePath);
453         final String propertyName = toscaGetFunction.getPropertyPathFromSource().get(toscaGetFunction.getPropertyPathFromSource().size() - 1);
454         toscaGetFunction.setPropertyName(propertyName);
455         return Optional.of(toscaGetFunction);
456     }
457
458     private static Optional<ToscaFunction> readLegacyGetInputConstraintValue(Map<?, ?> filterValueAsMap, Object toscaFunctionType) {
459         final ToscaGetFunctionDataDefinition toscaGetFunction = new ToscaGetFunctionDataDefinition();
460         toscaGetFunction.setFunctionType(ToscaGetFunctionType.GET_INPUT);
461         toscaGetFunction.setPropertySource(PropertySource.SELF);
462         final Object functionValueObj = filterValueAsMap.get(toscaFunctionType);
463         if (!(functionValueObj instanceof List) && !(functionValueObj instanceof String)) {
464             return Optional.empty();
465         }
466         if (functionValueObj instanceof String) {
467             toscaGetFunction.setPropertyPathFromSource(List.of((String) functionValueObj));
468         } else {
469             final List<String> functionParameters;
470             try {
471                 functionParameters = ((List<Object>) functionValueObj).stream()
472                     .map(object -> Objects.toString(object, null))
473                     .collect(Collectors.toList());
474             } catch (final ClassCastException ignored) {
475                 return Optional.empty();
476             }
477             List<String> propertySourcePath = new ArrayList<>();
478             propertySourcePath.add((String)functionParameters.get(0));
479             if (functionParameters.size() > 1 ) {
480                 List<Object> indexParsedList = new ArrayList<Object>();
481                 List<String> indexObjectList = functionParameters.subList(1,functionParameters.size());
482                 boolean loopFlag = true;
483                 for (String indexValue : indexObjectList) {
484                     if (!indexValue.equalsIgnoreCase("INDEX") && !StringUtils.isNumeric(indexValue) && loopFlag) {
485                         propertySourcePath.add(indexValue);
486                     } else {
487                         loopFlag = false;
488                         if (StringUtils.isNumeric(indexValue)) {
489                             indexParsedList.add(Integer.parseInt(indexValue));
490                         } else {
491                             indexParsedList.add(indexValue);
492                         }
493                     }
494                 }
495                 toscaGetFunction.setToscaIndexList(indexParsedList);
496             }
497             toscaGetFunction.setPropertyPathFromSource(propertySourcePath);
498         }
499         final String propertyName = toscaGetFunction.getPropertyPathFromSource().get(toscaGetFunction.getPropertyPathFromSource().size() - 1);
500         toscaGetFunction.setPropertyName(propertyName);
501         return Optional.of(toscaGetFunction);
502     }
503
504     private static FilterValueType detectValueType(final Object value) {
505         if (value instanceof Map) {
506             final Map<?, ?> valueAsMap = (Map<?, ?>) value;
507             if (valueAsMap.containsKey(ToscaFunctionType.CONCAT.getName())) {
508                 return FilterValueType.CONCAT;
509             }
510             if (valueAsMap.containsKey(ToscaFunctionType.GET_ATTRIBUTE.getName())) {
511                 return FilterValueType.GET_ATTRIBUTE;
512             }
513             if (valueAsMap.containsKey(ToscaFunctionType.GET_PROPERTY.getName())) {
514                 return FilterValueType.GET_PROPERTY;
515             }
516             if (valueAsMap.containsKey(ToscaFunctionType.GET_INPUT.getName())) {
517                 return FilterValueType.GET_INPUT;
518             }
519             if (valueAsMap.containsKey("$get_input_ext") ||
520                 valueAsMap.containsKey("$juel") ||
521                 valueAsMap.containsKey("$other")) {
522                 return FilterValueType.CUSTOM;
523             }
524         }
525         else if (value instanceof List) {
526             final Map<?, ?> valueAsMap = (Map<?, ?>) ((List<?>) value).get(0);
527             if (valueAsMap.containsKey(ToscaFunctionType.CONCAT.getName())) {
528                 return FilterValueType.CONCAT;
529             }
530             if (valueAsMap.containsKey(ToscaFunctionType.GET_ATTRIBUTE.getName())) {
531                 return FilterValueType.GET_ATTRIBUTE;
532             }
533             if (valueAsMap.containsKey(ToscaFunctionType.GET_PROPERTY.getName())) {
534                 return FilterValueType.GET_PROPERTY;
535             }
536             if (valueAsMap.containsKey(ToscaFunctionType.GET_INPUT.getName())) {
537                 return FilterValueType.GET_INPUT;
538             }
539             if (valueAsMap.containsKey("$get_input_ext") ||
540                 valueAsMap.containsKey("$juel") ||
541                 valueAsMap.containsKey("$other")) {
542                 return FilterValueType.CUSTOM;
543             }
544         }
545         return FilterValueType.STATIC;
546     }
547
548 }