2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2020 AT&T Intellectual Property. All rights
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END============================================
20 * ===================================================================
24 package org.onap.clamp.clds.tosca.update;
26 import com.google.gson.JsonArray;
27 import com.google.gson.JsonObject;
28 import java.util.ArrayList;
29 import java.util.Collection;
30 import java.util.LinkedHashMap;
31 import java.util.Map.Entry;
33 public class ParserToJson {
34 private LinkedHashMap<String, Component> components;
35 private LinkedHashMap<String, Template> templates;
37 public ParserToJson(LinkedHashMap<String, Component> components, LinkedHashMap<String, Template> templates) {
38 this.components = components;
39 this.templates = templates;
43 * For a given component, launch process to parse it in Json.
45 * @param nameComponent name components
48 public JsonObject getJsonProcess(String nameComponent, String typeComponent) {
49 JsonObject glob = new JsonObject();
51 if (typeComponent.equals("object")) {
52 glob = this.getFieldAsObject(matchComponent(nameComponent));
55 /*glob = this.getFieldAsArray(matchComponent(nameComponent));*/
62 * Return the classical/general fields of the component, & launch the properties deployment.
64 * @param component the compo
65 * @return a json object
67 public JsonObject getFieldAsObject(Component component) {
69 JsonObject globalFields = new JsonObject();
70 if (templates.get("object").hasFields("title")) {
71 globalFields.addProperty("title", component.getName());
73 if (templates.get("object").hasFields("type")) {
74 globalFields.addProperty("type", "object");
76 if (templates.get("object").hasFields("description")) {
77 if (component.getDescription() != null) {
78 globalFields.addProperty("description", component.getDescription());
81 if (templates.get("object").hasFields("required")) {
82 globalFields.add("required", this.getRequirements(component.getName()));
84 if (templates.get("object").hasFields("properties")) {
85 globalFields.add("properties", this.deploy(component.getName()));
91 * Get the required properties of the Component, including the parents properties requirements.
93 * @param nameComponent name component
94 * @return a json array
96 public JsonArray getRequirements(String nameComponent) {
97 JsonArray requirements = new JsonArray();
98 Component toParse = components.get(nameComponent);
99 //Check for a father component, and launch the same process
100 if (!toParse.getDerivedFrom().equals("tosca.datatypes.Root")
101 && !toParse.getDerivedFrom().equals("tosca.policies.Root")) {
102 requirements.addAll(getRequirements(toParse.getDerivedFrom()));
104 //Each property is checked, and add to the requirement array if it's required
105 Collection<Property> properties = toParse.getProperties().values();
106 for (Property property : properties) {
107 if (property.getItems().containsKey("required")
108 && property.getItems().get("required").equals(true)) {
109 requirements.add(property.getName());
116 * The beginning of the recursive process. Get the parents (or not) to launch the same process, and otherwise
117 * deploy and parse the properties.
119 * @param nameComponent name component
120 * @return a json object
122 public JsonObject deploy(String nameComponent) {
123 JsonObject jsonSchema = new JsonObject();
124 Component toParse = components.get(nameComponent);
125 //Check for a father component, and launch the same process
126 if (!toParse.getDerivedFrom().equals("tosca.datatypes.Root")
127 && !toParse.getDerivedFrom().equals("tosca.policies.Root")) {
128 jsonSchema = this.getParent(toParse.getDerivedFrom());
130 //For each component property, check if its a complex properties (a component) or not. In that case,
131 //launch the analyse of the property.
132 for (Entry<String, Property> property : toParse.getProperties().entrySet()) {
133 if (matchComponent((String) property.getValue().getItems().get("type")) != null) {
134 jsonSchema.add(property.getValue().getName(),
135 this.getJsonProcess((String) property.getValue().getItems().get("type"), "object"));
138 jsonSchema.add(property.getValue().getName(), this.complexParse(property.getValue()));
145 * If a component has a parent, it is deploy in the same way.
147 * @param nameComponent name component
148 * @return a json object
150 public JsonObject getParent(String nameComponent) {
151 return deploy(nameComponent);
157 * @param property property
158 * @return a json object
160 @SuppressWarnings("unchecked")
161 public JsonObject complexParse(Property property) {
162 JsonObject propertiesInJson = new JsonObject();
163 Template currentPropertyTemplate;
164 String typeProperty = (String) property.getItems().get("type");
165 if (typeProperty.toLowerCase().equals("list") || typeProperty.toLowerCase().equals("map")) {
166 currentPropertyTemplate = templates.get("object");
169 String propertyType = (String) property.getItems().get("type");
170 currentPropertyTemplate = templates.get(propertyType.toLowerCase());
172 //Each "special" field is analysed, and has a specific treatment
173 for (String propertyField : property.getItems().keySet()) {
174 switch (propertyField) {
176 if (currentPropertyTemplate.hasFields(propertyField)) {
177 String fieldtype = (String) property.getItems().get(propertyField);
178 switch (fieldtype.toLowerCase()) {
180 propertiesInJson.addProperty("type", "array");
183 propertiesInJson.addProperty("type", "object");
185 case "scalar-unit.time":
186 case "scalar-unit.frequency":
187 case "scalar-unit.size":
188 propertiesInJson.addProperty("type", "string");
191 propertiesInJson.addProperty("type", "string");
192 propertiesInJson.addProperty("format", "date-time");
195 propertiesInJson.addProperty("type", "number");
198 propertiesInJson.addProperty("type", "integer");
199 if (!checkConstraintPresence(property, "greater_than")
200 && currentPropertyTemplate.hasFields("exclusiveMinimum")) {
201 propertiesInJson.addProperty("exclusiveMinimum", false);
203 if (!checkConstraintPresence(property, "less_than")
204 && currentPropertyTemplate.hasFields("exclusiveMaximum")) {
205 propertiesInJson.addProperty("exclusiveMaximum", false);
209 propertiesInJson.addProperty("type", currentPropertyTemplate.getName());
217 property.addConstraintsAsJson(propertiesInJson,
218 (ArrayList<Object>) property.getItems().get("constraints"),
219 currentPropertyTemplate);
222 //Here, a way to check if entry is a component (datatype) or a simple string
223 if (matchComponent(this.extractSpecificFieldFromMap(property, "entry_schema")) != null) {
224 String nameComponent = this.extractSpecificFieldFromMap(property, "entry_schema");
225 ParserToJson child = new ParserToJson(components, templates);
226 JsonObject propertiesContainer = new JsonObject();
228 switch ((String) property.getItems().get("type")) {
229 case "map": // Get it as an object
230 JsonObject componentAsProperty = child.getJsonProcess(nameComponent,"object");
231 propertiesContainer.add(nameComponent, componentAsProperty);
232 if (currentPropertyTemplate.hasFields("properties")) {
233 propertiesInJson.add("properties", propertiesContainer);
236 default://list : get it as an Array
237 JsonObject componentAsItem = child.getJsonProcess(nameComponent, "object");
238 if (currentPropertyTemplate.hasFields("properties")) {
239 propertiesInJson.add("items", componentAsItem);
246 else if (property.getItems().get("type").equals("list")) {
247 JsonObject itemContainer = new JsonObject();
248 String valueInEntrySchema = this.extractSpecificFieldFromMap(property, "entry_schema");
249 itemContainer.addProperty("type", valueInEntrySchema);
250 propertiesInJson.add("items", itemContainer);
253 // propertiesInJson.add("key?", valueInEntrySchema);
256 default://Each classical field : type, description, default..
257 if (currentPropertyTemplate.hasFields(propertyField) && !propertyField.equals("required")) {
258 property.addFieldToJson(propertiesInJson, propertyField,
259 property.getItems().get(propertyField));
264 return propertiesInJson;
268 * Look for a matching Component for the name paramater, in the components list.
270 * @param name the name
271 * @return a component
273 public Component matchComponent(String name) {
274 Component correspondingComponent = null;
275 if (components == null) {
278 for (Component component : components.values()) {
279 if (component.getName().equals(name)) {
280 correspondingComponent = component;
283 return correspondingComponent;
287 * Simple method to extract quickly a type field from particular property item.
289 * @param property the property
290 * @param fieldName the fieldname
293 @SuppressWarnings("unchecked")
294 public String extractSpecificFieldFromMap(Property property, String fieldName) {
295 LinkedHashMap<String, String> entrySchemaFields =
296 (LinkedHashMap<String, String>) property.getItems().get(fieldName);
297 return entrySchemaFields.get("type");
301 * Check if a constraint, for a specific property, is there.
303 * @param property property
304 * @param nameConstraint name constraint
305 * @return a flag boolean
307 public boolean checkConstraintPresence(Property property, String nameConstraint) {
308 boolean presentConstraint = false;
309 if (property.getItems().containsKey("constraints")) {
310 ArrayList<Object> constraints = (ArrayList) property.getItems().get("constraints");
311 for (Object constraint : constraints) {
312 if (constraint instanceof LinkedHashMap) {
313 if (((LinkedHashMap) constraint).containsKey(nameConstraint)) {
314 presentConstraint = true;
319 return presentConstraint;