1f7459c59db942f8540bd786f3d14822846b5963
[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         } else {
71             propertyFilterConstraint.setValue(valueYaml);
72         }
73         propertyFilterConstraint.setValueType(detectValueType(valueYaml));
74         propertyFilterConstraint.setTargetType(PropertyFilterTargetType.PROPERTY);
75         return propertyFilterConstraint;
76     }
77
78     public static Optional<ToscaFunction> createToscaFunctionFromLegacyConstraintValue(final Object filterValue) {
79         if (!(filterValue instanceof Map)) {
80             return Optional.empty();
81         }
82         final Map<?, ?> filterValueAsMap = (Map<?, ?>) filterValue;
83         final Set<?> keys = filterValueAsMap.keySet();
84         if (keys.size() != 1) {
85             return Optional.empty();
86         }
87         final Object toscaFunctionTypeObject = keys.iterator().next();
88         if (!(toscaFunctionTypeObject instanceof String)) {
89             return Optional.empty();
90         }
91         ToscaFunctionType toscaFunctionType = ToscaFunctionType.findType((String) toscaFunctionTypeObject).orElse(null);
92         if (toscaFunctionType == null) {
93             if (((String) toscaFunctionTypeObject).equalsIgnoreCase("$get_input_ext") ||
94                 ((String) toscaFunctionTypeObject).equalsIgnoreCase("$juel") ||
95                 ((String) toscaFunctionTypeObject).equalsIgnoreCase("$other")) {
96                 toscaFunctionType = ToscaFunctionType.CUSTOM;
97             }
98             else {
99                 return Optional.empty();
100             }
101         }
102         switch (toscaFunctionType) {
103             case GET_INPUT:
104                 return readLegacyGetInputConstraintValue(filterValueAsMap, toscaFunctionTypeObject);
105             case GET_ATTRIBUTE:
106             case GET_PROPERTY:
107                 return readLegacyGetPropertyConstraintValue(filterValueAsMap, toscaFunctionTypeObject, toscaFunctionType);
108             case CONCAT:
109                 return readLegacyConcatConstraintValue(filterValueAsMap, toscaFunctionTypeObject);
110             case CUSTOM:
111                 return handleCustomFunction((Map<String, Object>)filterValueAsMap, (String)toscaFunctionTypeObject);
112             default:
113                 return Optional.empty();
114         }
115     }
116
117     private static Optional<ToscaFunction> handleCustomFunction(Map<String, Object> toscaFunctionPropertyValueMap, String functionType) {
118         final ToscaCustomFunction toscaCustomFunction = new ToscaCustomFunction();
119         toscaCustomFunction.setName(functionType.substring(1));
120         final Object functionValueObj = toscaFunctionPropertyValueMap.get(functionType);
121         toscaCustomFunction.setToscaFunctionType(getCustomFunctionType(toscaCustomFunction.getName()));
122         if (ToscaFunctionType.GET_INPUT.equals(toscaCustomFunction.getToscaFunctionType())) {
123             return handleCustomFunctionGetInputType(toscaCustomFunction, functionValueObj);
124         }
125         return handelCustomFunctionCustomType(toscaCustomFunction, functionValueObj);
126     }
127
128     private static Optional<ToscaFunction> handleCustomFunctionGetInputType(ToscaCustomFunction toscaCustomFunction, Object functionValueObj) {
129         if (!(functionValueObj instanceof String) && !(functionValueObj instanceof List)) {
130             return Optional.empty();
131         }
132         Map<String, Object> parameterMap = new HashMap<>();
133         parameterMap.put(ToscaFunctionType.GET_INPUT.getName(), functionValueObj);
134         buildToscaFunctionBasedOnPropertyValue(parameterMap).ifPresent(toscaFunction -> {
135             if (toscaFunction instanceof ToscaFunctionParameter) {
136                 toscaCustomFunction.addParameter((ToscaFunctionParameter) toscaFunction);
137             }
138         });
139         return Optional.of(toscaCustomFunction);
140     }
141
142     private static Optional<ToscaFunction> buildToscaFunctionBasedOnPropertyValue(final Map<String, Object> toscaFunctionPropertyValueMap) {
143         if (!isPropertyValueToscaFunction(toscaFunctionPropertyValueMap)) {
144             return Optional.empty();
145         }
146         final String functionType = toscaFunctionPropertyValueMap.keySet().iterator().next();
147         final ToscaFunctionType toscaFunctionType =
148             ToscaFunctionType.findType(functionType).orElse(functionType.startsWith("$") ? ToscaFunctionType.CUSTOM : null);
149         if (toscaFunctionType == null) {
150             return Optional.empty();
151         }
152         switch (toscaFunctionType) {
153             case GET_INPUT: {
154                 return handleGetInputFunction(toscaFunctionPropertyValueMap, functionType);
155             }
156             case GET_PROPERTY:
157             case GET_ATTRIBUTE: {
158                 return handleGetPropertyFunction(toscaFunctionPropertyValueMap, functionType, toscaFunctionType);
159             }
160             case CONCAT:
161                 return handleConcatFunction(toscaFunctionPropertyValueMap, functionType);
162             case CUSTOM:
163                 return handleCustomFunction(toscaFunctionPropertyValueMap, functionType);
164             default:
165                 return Optional.empty();
166         }
167     }
168
169     private static Optional<ToscaFunction> handleConcatFunction(Map<String, Object> toscaFunctionPropertyValueMap, String functionType) {
170         final ToscaConcatFunction toscaConcatFunction = new ToscaConcatFunction();
171         final Object functionValueObj = toscaFunctionPropertyValueMap.get(functionType);
172         if (!(functionValueObj instanceof List)) {
173             return Optional.empty();
174         }
175         final List<Object> functionParameters = (List<Object>) functionValueObj;
176         if (functionParameters.size() < 2) {
177             return Optional.empty();
178         }
179         functionParameters.forEach(parameter -> {
180             if (parameter instanceof String) {
181                 final var stringParameter = new ToscaStringParameter();
182                 stringParameter.setValue((String) parameter);
183                 toscaConcatFunction.addParameter(stringParameter);
184                 return;
185             }
186             if (isPropertyValueToscaFunction(parameter)) {
187                 buildToscaFunctionBasedOnPropertyValue((Map<String, Object>) parameter).ifPresent(toscaFunction -> {
188                     if (toscaFunction instanceof ToscaFunctionParameter) {
189                         toscaConcatFunction.addParameter((ToscaFunctionParameter) toscaFunction);
190                     }
191                 });
192                 return;
193             }
194             final var customYamlFunction = new CustomYamlFunction();
195             customYamlFunction.setYamlValue(parameter);
196             toscaConcatFunction.addParameter(customYamlFunction);
197         });
198         return Optional.of(toscaConcatFunction);
199     }
200
201     private static Optional<ToscaFunction> handleGetPropertyFunction(Map<String, Object> toscaFunctionPropertyValueMap, String functionType,
202                                                                      ToscaFunctionType toscaFunctionType) {
203         final ToscaGetFunctionDataDefinition toscaGetFunction = new ToscaGetFunctionDataDefinition();
204         toscaGetFunction.setFunctionType(
205             toscaFunctionType == ToscaFunctionType.GET_PROPERTY ? ToscaGetFunctionType.GET_PROPERTY : ToscaGetFunctionType.GET_ATTRIBUTE
206         );
207         final Object functionValueObj = toscaFunctionPropertyValueMap.get(functionType);
208         if (!(functionValueObj instanceof List)) {
209             return Optional.empty();
210         }
211         final List<String> functionParameters;
212         try {
213             functionParameters = ((List<Object>) functionValueObj).stream()
214                 .map(object -> Objects.toString(object, null))
215                 .collect(Collectors.toList());
216         } catch (final ClassCastException ignored) {
217             return Optional.empty();
218         }
219         if (functionParameters.size() < 2) {
220             return Optional.empty();
221         }
222         final String propertySourceType = functionParameters.get(0);
223         final PropertySource propertySource = PropertySource.findType(propertySourceType).orElse(null);
224         if (propertySource == PropertySource.SELF) {
225             toscaGetFunction.setPropertySource(propertySource);
226         } else {
227             toscaGetFunction.setPropertySource(PropertySource.INSTANCE);
228             toscaGetFunction.setSourceName(propertySourceType);
229         }
230         List<String> propertySourceIndex = functionParameters.subList(1, functionParameters.size());
231         List<String> propertySourcePath = new ArrayList<>();
232         propertySourcePath.add((String)propertySourceIndex.get(0));
233         if (propertySourceIndex.size() > 1 ) {
234             List<Object> indexParsedList = new ArrayList<Object>();
235             List<String> indexObjectList = propertySourceIndex.subList(1,propertySourceIndex.size());
236             boolean loopFlag = true;
237             for (String indexValue : indexObjectList) {
238                 if (!indexValue.equalsIgnoreCase("INDEX") && !StringUtils.isNumeric(indexValue) && loopFlag) {
239                     propertySourcePath.add(indexValue);
240                 } else {
241                     loopFlag = false;
242                     if (StringUtils.isNumeric(indexValue)) {
243                         indexParsedList.add(Integer.parseInt(indexValue));
244                     } else {
245                         indexParsedList.add(indexValue);
246                     }
247                 }
248             }
249             toscaGetFunction.setToscaIndexList(indexParsedList);
250         }
251         toscaGetFunction.setPropertyPathFromSource(propertySourcePath);
252         final String propertyName = toscaGetFunction.getPropertyPathFromSource().get(toscaGetFunction.getPropertyPathFromSource().size() - 1);
253         toscaGetFunction.setPropertyName(propertyName);
254         return Optional.of(toscaGetFunction);
255     }
256
257     private static Optional<ToscaFunction> handleGetInputFunction(Map<String, Object> toscaFunctionPropertyValueMap, String functionType) {
258         final ToscaGetFunctionDataDefinition toscaGetFunction = new ToscaGetFunctionDataDefinition();
259         toscaGetFunction.setFunctionType(ToscaGetFunctionType.GET_INPUT);
260         toscaGetFunction.setPropertySource(PropertySource.SELF);
261         final Object functionValueObj = toscaFunctionPropertyValueMap.get(functionType);
262         if (!(functionValueObj instanceof List) && !(functionValueObj instanceof String)) {
263             return Optional.empty();
264         }
265         if (functionValueObj instanceof String) {
266             toscaGetFunction.setPropertyPathFromSource(List.of((String) functionValueObj));
267         } else {
268             final List<String> functionParameters;
269             try {
270                 functionParameters = ((List<Object>) functionValueObj).stream()
271                     .map(object -> Objects.toString(object, null))
272                     .collect(Collectors.toList());
273             } catch (final ClassCastException ignored) {
274                 return Optional.empty();
275             }
276             List<String> propertySourcePath = new ArrayList<>();
277             propertySourcePath.add((String)functionParameters.get(0));
278             if (functionParameters.size() > 1 ) {
279                 List<Object> indexParsedList = new ArrayList<Object>();
280                 List<String> indexObjectList = functionParameters.subList(1,functionParameters.size());
281                 boolean loopFlag = true;
282                 for (String indexValue : indexObjectList) {
283                     if (!indexValue.equalsIgnoreCase("INDEX") && !StringUtils.isNumeric(indexValue) && loopFlag) {
284                         propertySourcePath.add(indexValue);
285                     } else {
286                         loopFlag = false;
287                         if (StringUtils.isNumeric(indexValue)) {
288                             indexParsedList.add(Integer.parseInt(indexValue));
289                         } else {
290                             indexParsedList.add(indexValue);
291                         }
292                     }
293                 }
294                 toscaGetFunction.setToscaIndexList(indexParsedList);
295             }
296             toscaGetFunction.setPropertyPathFromSource(propertySourcePath);
297         }
298         final String propertyName = toscaGetFunction.getPropertyPathFromSource().get(toscaGetFunction.getPropertyPathFromSource().size() - 1);
299         toscaGetFunction.setPropertyName(propertyName);
300         return Optional.of(toscaGetFunction);
301     }
302
303     public static boolean isPropertyValueToscaFunction(final Object propValueObj) {
304         if (propValueObj instanceof Map) {
305             final Map<String, Object> propValueMap = (Map<String, Object>) propValueObj;
306             if (propValueMap.keySet().size() > 1) {
307                 return false;
308             }
309             if (propValueMap.keySet().stream().anyMatch(keyValue -> keyValue.startsWith("$"))) {
310                 return true;
311             }
312
313             return Stream.of(ToscaFunctionType.GET_INPUT, ToscaFunctionType.GET_PROPERTY, ToscaFunctionType.GET_ATTRIBUTE, ToscaFunctionType.CONCAT)
314                 .anyMatch(type -> propValueMap.containsKey(type.getName()));
315         }
316         return false;
317     }
318
319     private static ToscaFunctionType getCustomFunctionType(String name) {
320         List<Configuration.CustomToscaFunction> customFunctions =
321             ConfigurationManager.getConfigurationManager().getConfiguration().getDefaultCustomToscaFunctions();
322         if (CollectionUtils.isEmpty(customFunctions)) {
323             return ToscaFunctionType.CUSTOM;
324         }
325         Optional<Configuration.CustomToscaFunction> optionalFunc = customFunctions.stream().filter(func -> func.getName().equals(name)).findFirst();
326         if (optionalFunc.isEmpty()) {
327             return ToscaFunctionType.CUSTOM;
328         }
329         String type = optionalFunc.get().getType();
330         return ToscaFunctionType.findType(type).get();
331     }
332
333     private static Optional<ToscaFunction> handelCustomFunctionCustomType(ToscaCustomFunction toscaCustomFunction, Object functionValueObj) {
334         if (!(functionValueObj instanceof List)) {
335             return Optional.empty();
336         }
337         final List<Object> functionParameters = (List<Object>) functionValueObj;
338         functionParameters.forEach(parameter -> {
339             if (parameter instanceof String) {
340                 final var stringParameter = new ToscaStringParameter();
341                 stringParameter.setValue((String) parameter);
342                 toscaCustomFunction.addParameter(stringParameter);
343                 return;
344             }
345             if (isPropertyValueToscaFunction(parameter)) {
346                 buildToscaFunctionBasedOnPropertyValue((Map<String, Object>) parameter).ifPresent(toscaFunction -> {
347                     if (toscaFunction instanceof ToscaFunctionParameter) {
348                         toscaCustomFunction.addParameter((ToscaFunctionParameter) toscaFunction);
349                     }
350                 });
351                 return;
352             }
353             final var customYamlFunction = new CustomYamlFunction();
354             customYamlFunction.setYamlValue(parameter);
355             toscaCustomFunction.addParameter(customYamlFunction);
356         });
357         return Optional.of(toscaCustomFunction);
358     }
359
360     public static Optional<FilterValueType> convertFromToscaFunctionType(final ToscaFunctionType toscaFunctionType) {
361         return FilterValueType.findByName(toscaFunctionType.getName());
362     }
363
364     private static Optional<ToscaFunction> readLegacyConcatConstraintValue(Map<?, ?> filterValueAsMap, Object toscaFunctionType) {
365         final List<Object> concatValue;
366         try {
367             concatValue = (List<Object>) filterValueAsMap.get(toscaFunctionType);
368         } catch (final Exception ignored) {
369             return Optional.empty();
370         }
371         if (concatValue.isEmpty()) {
372             return Optional.empty();
373         }
374         final var toscaConcatFunction = new ToscaConcatFunction();
375         for (Object parameter : concatValue) {
376             if (parameter instanceof String) {
377                 final ToscaStringParameter toscaStringParameter = new ToscaStringParameter();
378                 toscaStringParameter.setValue((String) parameter);
379                 toscaConcatFunction.addParameter(toscaStringParameter);
380             } else {
381                 createToscaFunctionFromLegacyConstraintValue(parameter)
382                     .ifPresent(toscaFunction -> toscaConcatFunction.addParameter((ToscaFunctionParameter) toscaFunction));
383             }
384         }
385         return Optional.of(toscaConcatFunction);
386     }
387
388     private static Optional<ToscaFunction> readLegacyGetPropertyConstraintValue(Map<?, ?> filterValueAsMap, Object toscaFunctionType,
389                                                                                 ToscaFunctionType toscaFunctionType1) {
390         final ToscaGetFunctionDataDefinition toscaGetFunction = new ToscaGetFunctionDataDefinition();
391         toscaGetFunction.setFunctionType(
392             toscaFunctionType.toString().equalsIgnoreCase(ToscaFunctionType.GET_PROPERTY.getName()) ? ToscaGetFunctionType.GET_PROPERTY : ToscaGetFunctionType.GET_ATTRIBUTE
393         );
394         final Object functionValueObj = null != filterValueAsMap.get(toscaFunctionType1) ?
395             filterValueAsMap.get(toscaFunctionType1) : filterValueAsMap.get(toscaFunctionType);
396         if (!(functionValueObj instanceof List)) {
397             return Optional.empty();
398         }
399         final List<String> functionParameters;
400         try {
401             functionParameters = ((List<Object>) functionValueObj).stream()
402                 .map(object -> Objects.toString(object, null))
403                 .collect(Collectors.toList());
404         } catch (final ClassCastException ignored) {
405             return Optional.empty();
406         }
407         if (functionParameters.size() < 2) {
408             return Optional.empty();
409         }
410         final String propertySourceType = functionParameters.get(0);
411         final PropertySource propertySource = PropertySource.findType(propertySourceType).orElse(null);
412         if (propertySource == PropertySource.SELF) {
413             toscaGetFunction.setPropertySource(propertySource);
414         } else {
415             toscaGetFunction.setPropertySource(PropertySource.INSTANCE);
416             toscaGetFunction.setSourceName(propertySourceType);
417         }
418         List<String> propertySourceIndex = functionParameters.subList(1, functionParameters.size());
419         List<String> propertySourcePath = new ArrayList<>();
420         propertySourcePath.add((String)propertySourceIndex.get(0));
421         if (propertySourceIndex.size() > 1 ) {
422             List<Object> indexParsedList = new ArrayList<Object>();
423             List<String> indexObjectList = propertySourceIndex.subList(1,propertySourceIndex.size());
424             boolean loopFlag = true;
425             for (String indexValue : indexObjectList) {
426                 if (!indexValue.equalsIgnoreCase("INDEX") && !StringUtils.isNumeric(indexValue) && loopFlag) {
427                     propertySourcePath.add(indexValue);
428                 } else {
429                     loopFlag = false;
430                     if (StringUtils.isNumeric(indexValue)) {
431                         indexParsedList.add(Integer.parseInt(indexValue));
432                     } else {
433                         indexParsedList.add(indexValue);
434                     }
435                 }
436             }
437             toscaGetFunction.setToscaIndexList(indexParsedList);
438         }
439         toscaGetFunction.setPropertyPathFromSource(propertySourcePath);
440         final String propertyName = toscaGetFunction.getPropertyPathFromSource().get(toscaGetFunction.getPropertyPathFromSource().size() - 1);
441         toscaGetFunction.setPropertyName(propertyName);
442         return Optional.of(toscaGetFunction);
443     }
444
445     private static Optional<ToscaFunction> readLegacyGetInputConstraintValue(Map<?, ?> filterValueAsMap, Object toscaFunctionType) {
446         final ToscaGetFunctionDataDefinition toscaGetFunction = new ToscaGetFunctionDataDefinition();
447         toscaGetFunction.setFunctionType(ToscaGetFunctionType.GET_INPUT);
448         toscaGetFunction.setPropertySource(PropertySource.SELF);
449         final Object functionValueObj = filterValueAsMap.get(toscaFunctionType);
450         if (!(functionValueObj instanceof List) && !(functionValueObj instanceof String)) {
451             return Optional.empty();
452         }
453         if (functionValueObj instanceof String) {
454             toscaGetFunction.setPropertyPathFromSource(List.of((String) functionValueObj));
455         } else {
456             final List<String> functionParameters;
457             try {
458                 functionParameters = ((List<Object>) functionValueObj).stream()
459                     .map(object -> Objects.toString(object, null))
460                     .collect(Collectors.toList());
461             } catch (final ClassCastException ignored) {
462                 return Optional.empty();
463             }
464             List<String> propertySourcePath = new ArrayList<>();
465             propertySourcePath.add((String)functionParameters.get(0));
466             if (functionParameters.size() > 1 ) {
467                 List<Object> indexParsedList = new ArrayList<Object>();
468                 List<String> indexObjectList = functionParameters.subList(1,functionParameters.size());
469                 boolean loopFlag = true;
470                 for (String indexValue : indexObjectList) {
471                     if (!indexValue.equalsIgnoreCase("INDEX") && !StringUtils.isNumeric(indexValue) && loopFlag) {
472                         propertySourcePath.add(indexValue);
473                     } else {
474                         loopFlag = false;
475                         if (StringUtils.isNumeric(indexValue)) {
476                             indexParsedList.add(Integer.parseInt(indexValue));
477                         } else {
478                             indexParsedList.add(indexValue);
479                         }
480                     }
481                 }
482                 toscaGetFunction.setToscaIndexList(indexParsedList);
483             }
484             toscaGetFunction.setPropertyPathFromSource(propertySourcePath);
485         }
486         final String propertyName = toscaGetFunction.getPropertyPathFromSource().get(toscaGetFunction.getPropertyPathFromSource().size() - 1);
487         toscaGetFunction.setPropertyName(propertyName);
488         return Optional.of(toscaGetFunction);
489     }
490
491     private static FilterValueType detectValueType(final Object value) {
492         if (value instanceof Map) {
493             final Map<?, ?> valueAsMap = (Map<?, ?>) value;
494             if (valueAsMap.containsKey(ToscaFunctionType.CONCAT.getName())) {
495                 return FilterValueType.CONCAT;
496             }
497             if (valueAsMap.containsKey(ToscaFunctionType.GET_ATTRIBUTE.getName())) {
498                 return FilterValueType.GET_ATTRIBUTE;
499             }
500             if (valueAsMap.containsKey(ToscaFunctionType.GET_PROPERTY.getName())) {
501                 return FilterValueType.GET_PROPERTY;
502             }
503             if (valueAsMap.containsKey(ToscaFunctionType.GET_INPUT.getName())) {
504                 return FilterValueType.GET_INPUT;
505             }
506             if (valueAsMap.containsKey("$get_input_ext") ||
507                 valueAsMap.containsKey("$juel") ||
508                 valueAsMap.containsKey("$other")) {
509                 return FilterValueType.CUSTOM;
510             }
511         }
512         return FilterValueType.STATIC;
513     }
514
515 }