Fix checkstyle violations in sdc/jtosca
[sdc/sdc-tosca.git] / src / main / java / org / onap / sdc / toscaparser / api / functions / Function.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2019 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.onap.sdc.toscaparser.api.functions;
22
23
24 import org.onap.sdc.toscaparser.api.TopologyTemplate;
25
26 import java.util.ArrayList;
27 import java.util.HashMap;
28 import java.util.LinkedHashMap;
29 import java.util.Map;
30
31 public abstract class Function {
32
33     protected static final String GET_PROPERTY = "get_property";
34     protected static final String GET_ATTRIBUTE = "get_attribute";
35     protected static final String GET_INPUT = "get_input";
36     protected static final String GET_OPERATION_OUTPUT = "get_operation_output";
37     protected static final String CONCAT = "concat";
38     protected static final String TOKEN = "token";
39
40     protected static final String SELF = "SELF";
41     protected static final String HOST = "HOST";
42     protected static final String TARGET = "TARGET";
43     protected static final String SOURCE = "SOURCE";
44
45     protected static final String HOSTED_ON = "tosca.relationships.HostedOn";
46
47     protected static HashMap<String, String> functionMappings = _getFunctionMappings();
48
49     private static HashMap<String, String> _getFunctionMappings() {
50         HashMap<String, String> map = new HashMap<>();
51         map.put(GET_PROPERTY, "GetProperty");
52         map.put(GET_INPUT, "GetInput");
53         map.put(GET_ATTRIBUTE, "GetAttribute");
54         map.put(GET_OPERATION_OUTPUT, "GetOperationOutput");
55         map.put(CONCAT, "Concat");
56         map.put(TOKEN, "Token");
57         return map;
58     }
59
60     protected TopologyTemplate toscaTpl;
61     protected Object context;
62     protected String name;
63     protected ArrayList<Object> args;
64
65
66     public Function(TopologyTemplate _toscaTpl, Object _context, String _name, ArrayList<Object> _args) {
67         toscaTpl = _toscaTpl;
68         context = _context;
69         name = _name;
70         args = _args;
71         validate();
72
73     }
74
75     abstract Object result();
76
77     abstract void validate();
78
79     @SuppressWarnings("unchecked")
80     public static boolean isFunction(Object funcObj) {
81         // Returns True if the provided function is a Tosca intrinsic function.
82         //
83         //Examples:
84         //
85         //* "{ get_property: { SELF, port } }"
86         //* "{ get_input: db_name }"
87         //* Function instance
88
89         //:param function: Function as string or a Function instance.
90         //:return: True if function is a Tosca intrinsic function, otherwise False.
91         //
92
93         if (funcObj instanceof LinkedHashMap) {
94             LinkedHashMap<String, Object> function = (LinkedHashMap<String, Object>) funcObj;
95             if (function.size() == 1) {
96                 String funcName = (new ArrayList<String>(function.keySet())).get(0);
97                 return functionMappings.keySet().contains(funcName);
98             }
99         }
100         return (funcObj instanceof Function);
101     }
102
103     @SuppressWarnings("unchecked")
104     public static Object getFunction(TopologyTemplate ttpl, Object context, Object rawFunctionObj, boolean resolveGetInput) {
105         // Gets a Function instance representing the provided template function.
106
107         // If the format provided raw_function format is not relevant for template
108         // functions or if the function name doesn't exist in function mapping the
109         // method returns the provided raw_function.
110         //
111         // :param tosca_tpl: The tosca template.
112         // :param node_template: The node template the function is specified for.
113         // :param raw_function: The raw function as dict.
114         // :return: Template function as Function instance or the raw_function if
115         //  parsing was unsuccessful.
116
117
118         // iterate over leaves of the properties's tree and convert function leaves to function object,
119         // support List and Map nested,
120         // assuming that leaf value of function is always map type contains 1 item (e.g. my_leaf: {get_input: xxx}).
121
122         if (rawFunctionObj instanceof LinkedHashMap) { // In map type case
123             LinkedHashMap rawFunction = ((LinkedHashMap) rawFunctionObj);
124             if (rawFunction.size() == 1 &&
125                     !(rawFunction.values().iterator().next() instanceof LinkedHashMap)) { // End point
126                 return getFunctionForObjectItem(ttpl, context, rawFunction, resolveGetInput);
127             } else {
128                 return getFunctionForMap(ttpl, context, rawFunction, resolveGetInput);
129             }
130         } else if (rawFunctionObj instanceof ArrayList) { // In list type case
131             return getFunctionForList(ttpl, context, (ArrayList) rawFunctionObj, resolveGetInput);
132         }
133
134         return rawFunctionObj;
135     }
136
137     private static Object getFunctionForList(TopologyTemplate ttpl, Object context, ArrayList rawFunctionObj, boolean resolveGetInput) {
138         // iterate over list properties in recursion, convert leaves to function,
139         // and collect them in the same hierarchy as the original list.
140         ArrayList<Object> rawFunctionObjList = new ArrayList<>();
141         for (Object rawFunctionObjItem : rawFunctionObj) {
142             rawFunctionObjList.add(getFunction(ttpl, context, rawFunctionObjItem, resolveGetInput));
143         }
144         return rawFunctionObjList;
145     }
146
147     private static Object getFunctionForMap(TopologyTemplate ttpl, Object context, LinkedHashMap rawFunction, boolean resolveGetInput) {
148         // iterate over map nested properties in recursion, convert leaves to function,
149         // and collect them in the same hierarchy as the original map.
150         LinkedHashMap rawFunctionObjMap = new LinkedHashMap();
151         for (Object rawFunctionObjItem : rawFunction.entrySet()) {
152             Object itemValue = getFunction(ttpl, context, ((Map.Entry) rawFunctionObjItem).getValue(), resolveGetInput);
153             rawFunctionObjMap.put(((Map.Entry) rawFunctionObjItem).getKey(), itemValue);
154         }
155         return rawFunctionObjMap;
156     }
157
158     private static Object getFunctionForObjectItem(TopologyTemplate ttpl, Object context, Object rawFunctionObjItem, boolean resolveGetInput) {
159         if (isFunction(rawFunctionObjItem)) {
160             LinkedHashMap<String, Object> rawFunction = (LinkedHashMap<String, Object>) rawFunctionObjItem;
161             String funcName = (new ArrayList<String>(rawFunction.keySet())).get(0);
162             if (functionMappings.keySet().contains(funcName)) {
163                 String funcType = functionMappings.get(funcName);
164                 Object oargs = (new ArrayList<Object>(rawFunction.values())).get(0);
165                 ArrayList<Object> funcArgs;
166                 if (oargs instanceof ArrayList) {
167                     funcArgs = (ArrayList<Object>) oargs;
168                 } else {
169                     funcArgs = new ArrayList<>();
170                     funcArgs.add(oargs);
171                 }
172
173                 switch (funcType) {
174                     case "GetInput":
175                         if (resolveGetInput) {
176                             GetInput input = new GetInput(ttpl, context, funcName, funcArgs);
177                             return input.result();
178                         }
179                         return new GetInput(ttpl, context, funcName, funcArgs);
180                     case "GetAttribute":
181                         return new GetAttribute(ttpl, context, funcName, funcArgs);
182                     case "GetProperty":
183                         return new GetProperty(ttpl, context, funcName, funcArgs);
184                     case "GetOperationOutput":
185                         return new GetOperationOutput(ttpl, context, funcName, funcArgs);
186                     case "Concat":
187                         return new Concat(ttpl, context, funcName, funcArgs);
188                     case "Token":
189                         return new Token(ttpl, context, funcName, funcArgs);
190                 }
191             }
192         }
193
194         return rawFunctionObjItem;
195     }
196
197     @Override
198     public String toString() {
199         String argsStr = args.size() > 1 ? args.toString() : args.get(0).toString();
200         return name + ":" + argsStr;
201     }
202 }
203
204 /*python
205
206 from toscaparser.common.exception import ValidationIsshueCollector
207 from toscaparser.common.exception import UnknownInputError
208 from toscaparser.dataentity import DataEntity
209 from toscaparser.elements.constraints import Schema
210 from toscaparser.elements.datatype import DataType
211 from toscaparser.elements.entity_type import EntityType
212 from toscaparser.elements.relationshiptype import RelationshipType
213 from toscaparser.elements.statefulentitytype import StatefulEntityType
214 from toscaparser.utils.gettextutils import _
215
216
217 GET_PROPERTY = 'get_property'
218 GET_ATTRIBUTE = 'get_attribute'
219 GET_INPUT = 'get_input'
220 GET_OPERATION_OUTPUT = 'get_operation_output'
221 CONCAT = 'concat'
222 TOKEN = 'token'
223
224 SELF = 'SELF'
225 HOST = 'HOST'
226 TARGET = 'TARGET'
227 SOURCE = 'SOURCE'
228
229 HOSTED_ON = 'tosca.relationships.HostedOn'
230
231
232 @six.add_metaclass(abc.ABCMeta)
233 class Function(object):
234     """An abstract type for representing a Tosca template function."""
235
236     def __init__(self, tosca_tpl, context, name, args):
237         self.tosca_tpl = tosca_tpl
238         self.context = context
239         self.name = name
240         self.args = args
241         self.validate()
242
243     @abc.abstractmethod
244     def result(self):
245         """Invokes the function and returns its result
246
247         Some methods invocation may only be relevant on runtime (for example,
248         getting runtime properties) and therefore its the responsibility of
249         the orchestrator/translator to take care of such functions invocation.
250
251         :return: Function invocation result.
252         """
253         return {self.name: self.args}
254
255     @abc.abstractmethod
256     def validate(self):
257         """Validates function arguments."""
258         pass
259 */