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