Re-implement model type value for Resource Mapping
[aai/babel.git] / src / main / java / org / onap / aai / babel / xml / generator / api / AaiModelGeneratorImpl.java
1 /**
2  * ============LICENSE_START=======================================================
3  * org.onap.aai
4  * ================================================================================
5  * Copyright (c) 2017-2019 AT&T Intellectual Property. All rights reserved.
6  * Copyright (c) 2017-2019 European Software Marketing Ltd.
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
11  *
12  *       http://www.apache.org/licenses/LICENSE-2.0
13  *
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  */
21
22 package org.onap.aai.babel.xml.generator.api;
23
24 import java.io.StringWriter;
25 import java.util.List;
26 import java.util.Set;
27 import javax.xml.bind.JAXBContext;
28 import javax.xml.bind.JAXBException;
29 import javax.xml.bind.Marshaller;
30 import org.onap.aai.babel.logging.ApplicationMsgs;
31 import org.onap.aai.babel.logging.LogHelper;
32 import org.onap.aai.babel.xml.generator.XmlArtifactGenerationException;
33 import org.onap.aai.babel.xml.generator.model.Resource;
34 import org.onap.aai.babel.xml.generator.model.Service;
35 import org.onap.aai.babel.xml.generator.model.Widget;
36 import org.onap.aai.babel.xml.generator.xsd.Model;
37 import org.onap.aai.babel.xml.generator.xsd.ModelElement;
38 import org.onap.aai.babel.xml.generator.xsd.ModelElements;
39 import org.onap.aai.babel.xml.generator.xsd.ModelVer;
40 import org.onap.aai.babel.xml.generator.xsd.ModelVers;
41 import org.onap.aai.babel.xml.generator.xsd.Relationship;
42 import org.onap.aai.babel.xml.generator.xsd.RelationshipData;
43 import org.onap.aai.babel.xml.generator.xsd.RelationshipList;
44 import org.onap.aai.cl.api.Logger;
45 import org.w3c.dom.DOMException;
46
47 /**
48  * Implementation of the {@link AaiModelGenerator} which generates the XML models from the Service/Resource/Widget java
49  * models.
50  */
51 public class AaiModelGeneratorImpl implements AaiModelGenerator {
52     private static Logger log = LogHelper.INSTANCE;
53
54     /**
55      * Method to generate the AAI model for a Service.
56      *
57      * @param service
58      *            Java object model representing an AAI {@link Service} model
59      * @return XML representation of the service model in String format
60      * @throws XmlArtifactGenerationException 
61      */
62     @Override
63     public String generateModelFor(Service service) throws XmlArtifactGenerationException {
64         // Create a JAXB Model for AAI service model
65         Model aaiServiceModel = new Model();
66         log.debug("Generating Model for Service with ModelName: " + service.getModelName());
67         // after new model
68         aaiServiceModel.setModelInvariantId(service.getModelId());
69         aaiServiceModel.setModelVers(new ModelVers());
70         ModelVer modelVer = new ModelVer();
71         modelVer.setModelDescription(service.getModelDescription());
72         modelVer.setModelName(service.getModelName());
73         modelVer.setModelVersion(service.getModelVersion());
74         modelVer.setModelVersionId(service.getModelNameVersionId());
75         modelVer.setModelElements(new ModelElements());
76         ModelElements modelElements = modelVer.getModelElements();
77         // Populate basic model details
78         aaiServiceModel.setModelType(service.getModelTypeName());
79         List<ModelElement> modelElementList = modelElements.getModelElement();
80
81         // Add service base widget model element
82         ModelElement serviceWidgetModelRelationshipElement = createRelationshipModelElement(
83                 getNewDataDelFlagValue(service.getDeleteFlag()), service.getWidgetId(), service.getWidgetInvariantId());
84         modelElementList.add(serviceWidgetModelRelationshipElement);
85
86         // Add the resource model elements
87         ModelElements serviceModelElements = serviceWidgetModelRelationshipElement.getModelElements();
88         List<ModelElement> serviceModelElementList = serviceModelElements.getModelElement();
89         Set<Resource> serviceResources = service.getResources();
90         if (serviceResources != null && !serviceResources.isEmpty()) {
91             for (Resource resourceModel : serviceResources) {
92                 ModelElement aaiResourceModelElement =
93                         createRelationshipModelElement(getNewDataDelFlagValue(resourceModel.getDeleteFlag()),
94                                 resourceModel.getModelNameVersionId(), resourceModel.getModelId());
95                 serviceModelElementList.add(aaiResourceModelElement);
96             }
97         }
98
99         // Add the widget model elements
100         Set<Widget> serviceWidgets = service.getWidgets();
101         if (serviceWidgets != null && !serviceWidgets.isEmpty()) {
102             for (Widget widgetModel : serviceWidgets) {
103                 ModelElement widgetModelElement =
104                         createRelationshipModelElement(getNewDataDelFlagValue(widgetModel.getDeleteFlag()),
105                                 widgetModel.getId(), widgetModel.getWidgetId());
106                 serviceModelElementList.add(widgetModelElement);
107             }
108         }
109         ModelVers modelVers = aaiServiceModel.getModelVers();
110         List<ModelVer> modelVerList = modelVers.getModelVer();
111         modelVerList.add(modelVer);
112         return getModelAsString(aaiServiceModel);
113     }
114
115     /**
116      * Method to generate the AAI model for a Resource.
117      *
118      * @param resource
119      *            Java object model representing an AAI {@link Resource} model
120      * @return XML representation of the resource model in String format
121      * @throws XmlArtifactGenerationException 
122      */
123     @Override
124     public String generateModelFor(Resource resource) throws XmlArtifactGenerationException {
125         // Create a JAXB Model for AAI Resource model
126         Model aaiResourceModel = new Model();
127         log.debug("Generating Model for Resource with ModelName: " + resource.getModelName());
128         aaiResourceModel.setModelInvariantId(resource.getModelId());
129         aaiResourceModel.setModelVers(new ModelVers());
130         ModelVer modelVer = new ModelVer();
131         modelVer.setModelDescription(resource.getModelDescription());
132         modelVer.setModelName(resource.getModelName());
133         modelVer.setModelVersion(resource.getModelVersion());
134         modelVer.setModelVersionId(resource.getModelNameVersionId());
135         modelVer.setModelElements(new ModelElements());
136         ModelElements modelElements = modelVer.getModelElements();
137         aaiResourceModel.setModelType(resource.getModelTypeName());
138         List<ModelElement> modelElementList = modelElements.getModelElement();
139
140         // Add resource base widget model element
141         ModelElement resourceWidgetModelRelationshipElement =
142                 createRelationshipModelElement(getNewDataDelFlagValue(resource.getDeleteFlag()), resource.getWidgetId(),
143                         resource.getWidgetInvariantId());
144         modelElementList.add(resourceWidgetModelRelationshipElement);
145
146         // Add the child resources to the base widget model element list
147         ModelElements baseResourceWidgetModelElements = resourceWidgetModelRelationshipElement.getModelElements();
148         List<ModelElement> baseResourceWidgetModelElementList = baseResourceWidgetModelElements.getModelElement();
149         Set<Resource> childResources = resource.getResources();
150         if (childResources != null && !childResources.isEmpty()) {
151             for (Resource childResourceModel : childResources) {
152                 ModelElement aaiChildResourceModelElement =
153                         createRelationshipModelElement(getNewDataDelFlagValue(childResourceModel.getDeleteFlag()),
154                                 childResourceModel.getModelNameVersionId(), childResourceModel.getModelId());
155                 baseResourceWidgetModelElementList.add(aaiChildResourceModelElement);
156             }
157         }
158         // Add resource widgets/resources to the resource widget model relationship element
159         Set<Widget> resourceWidgets = resource.getWidgets();
160         if (resourceWidgets != null && !resourceWidgets.isEmpty()) {
161             generateWidgetChildren(resourceWidgetModelRelationshipElement, resourceWidgets);
162         }
163
164         ModelVers modelVers = aaiResourceModel.getModelVers();
165         List<ModelVer> modelVerList = modelVers.getModelVer();
166         modelVerList.add(modelVer);
167         return getModelAsString(aaiResourceModel);
168     }
169
170     /**
171      * Method to create the <model-element></model-element> holding the relationship value for a resource/widget model.
172      *
173      * @param newDataDelFlag
174      *            Value of the <new-data-del-flag></new-data-del-flag> attribute for a widget/resource in the model xml
175      * @param relationshipValue
176      *            Value of the <relationship-value></relationship-value> attribute for the widget/resource in the model
177      *            xml
178      * @return Java object representation for the <model-element></model-element> holding the relationship
179      */
180     private ModelElement createRelationshipModelElement(String newDataDelFlag, String modelVersionId,
181             String modelInvariantId) {
182         ModelElement relationshipModelElement = new ModelElement();
183         relationshipModelElement.setNewDataDelFlag(newDataDelFlag); // Set new-data-del-flag value
184         relationshipModelElement.setCardinality("unbounded");
185         RelationshipList relationShipList = new RelationshipList();
186         final List<Relationship> relationships = relationShipList.getRelationship();
187         Relationship relationship = new Relationship();
188         relationship.setRelatedTo("model-ver");
189         List<RelationshipData> relationshipDataList = relationship.getRelationshipData();
190
191         RelationshipData modelVersionRelationshipData = new RelationshipData();
192         modelVersionRelationshipData.setRelationshipKey("model-ver.model-version-id");
193         modelVersionRelationshipData.setRelationshipValue(modelVersionId); // Set the widget/resource name-version-uuid
194         // as value
195         relationshipDataList.add(modelVersionRelationshipData);
196         RelationshipData modelInvariantRelationshipData = new RelationshipData();
197         modelInvariantRelationshipData.setRelationshipKey("model.model-invariant-id");
198         modelInvariantRelationshipData.setRelationshipValue(modelInvariantId);
199         relationshipDataList.add(modelInvariantRelationshipData);
200         relationships.add(relationship);
201         relationshipModelElement.setRelationshipList(relationShipList);
202         relationshipModelElement.setModelElements(new ModelElements());
203         return relationshipModelElement;
204     }
205
206     /**
207      * Method to create the child model elements of the widget. Handles the generation of recursive child widget
208      * elements (if any)
209      *
210      * @param parent
211      *            Reference to the parent widget model element
212      * @param widgetChildrenSet
213      *            Set of children obtained from the tosca/widget definition
214      */
215     private void generateWidgetChildren(ModelElement parent, Set<Widget> widgetChildrenSet) {
216         for (Widget widget : widgetChildrenSet) {
217             Set<Widget> widgetSubChildren = widget.getWidgets();
218             if (widgetSubChildren != null && !widgetSubChildren.isEmpty()) {
219                 ModelElement widgetChildRelationshipElement = createRelationshipModelElement(
220                         getNewDataDelFlagValue(widget.getDeleteFlag()), widget.getId(), widget.getWidgetId());
221                 // Recursive call for getting the children of widgets (if any)
222                 generateWidgetChildren(widgetChildRelationshipElement, widgetSubChildren);
223                 parent.getModelElements().getModelElement().add(widgetChildRelationshipElement);
224             } else {
225                 ModelElement widgetChildRelationshipElement = createRelationshipModelElement(
226                         getNewDataDelFlagValue(widget.getDeleteFlag()), widget.getId(), widget.getWidgetId());
227                 parent.getModelElements().getModelElement().add(widgetChildRelationshipElement);
228             }
229         }
230     }
231
232     /**
233      * Converts the data delete flag value from boolean to String as per AAI model.
234      *
235      * @param delFlag
236      *            Boolean value as true/false from the annotation
237      * @return Converted value to a flag as per AAI model
238      */
239     private String getNewDataDelFlagValue(boolean delFlag) {
240         return delFlag ? "T" : "F";
241     }
242
243     /**
244      * JAXB marshalling helper method to convert the Java object model to XML String.
245      *
246      * @param model
247      *            Java Object model of a service/widget/resource
248      * @return XML representation of the Java model in String format
249      */
250     private String getModelAsString(Model model) {
251         JAXBContext jaxbContext;
252         StringWriter modelStringWriter = new StringWriter();
253         try {
254             jaxbContext = JAXBContext.newInstance(Model.class);
255             Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
256             jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
257             jaxbMarshaller.setProperty(Marshaller.JAXB_ENCODING, "US-ASCII");
258             jaxbMarshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
259             jaxbMarshaller.marshal(model, modelStringWriter);
260         } catch (JAXBException jaxbException) {
261             log.error(ApplicationMsgs.INVALID_CSAR_FILE, jaxbException);
262             throw new DOMException(DOMException.SYNTAX_ERR, jaxbException.getMessage());
263         }
264
265         return modelStringWriter.toString();
266     }
267 }