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