Create 1.13.0 maven release
[aai/babel.git] / src / main / java / org / onap / aai / babel / xml / generator / api / AaiModelGenerator.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  * Copyright (C) 2019-2020 Wipro Limited.
8  * ================================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *       http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  * ============LICENSE_END=========================================================
21  */
22
23 package org.onap.aai.babel.xml.generator.api;
24
25 import java.io.StringWriter;
26 import java.util.Collection;
27 import java.util.List;
28 import javax.xml.bind.JAXBContext;
29 import javax.xml.bind.JAXBException;
30 import javax.xml.bind.Marshaller;
31 import org.onap.aai.babel.logging.ApplicationMsgs;
32 import org.onap.aai.babel.logging.LogHelper;
33 import org.onap.aai.babel.xml.generator.XmlArtifactGenerationException;
34 import org.onap.aai.babel.xml.generator.model.Model;
35 import org.onap.aai.babel.xml.generator.model.Resource;
36 import org.onap.aai.babel.xml.generator.model.Service;
37 import org.onap.aai.babel.xml.generator.model.Widget;
38 import org.onap.aai.babel.xml.generator.xsd.ModelElement;
39 import org.onap.aai.babel.xml.generator.xsd.ModelElements;
40 import org.onap.aai.babel.xml.generator.xsd.ModelVer;
41 import org.onap.aai.babel.xml.generator.xsd.ModelVers;
42 import org.onap.aai.babel.xml.generator.xsd.Relationship;
43 import org.onap.aai.babel.xml.generator.xsd.RelationshipData;
44 import org.onap.aai.babel.xml.generator.xsd.RelationshipList;
45 import org.onap.aai.cl.api.Logger;
46 import org.w3c.dom.DOMException;
47
48 /**
49  * Generates the A&AI XML models from the Service/Resource/Widget Java models.
50  */
51 public class AaiModelGenerator {
52
53     private static Logger log = LogHelper.INSTANCE;
54
55     /**
56      * Method to generate the AAI model for a Service or Resource.
57      *
58      * @param model
59      *            Java object model representing an AAI {@link Service} or {@link Resource} model
60      * @return XML representation of the model in String format
61      * @throws XmlArtifactGenerationException
62      */
63     public String generateModelFor(Model model) throws XmlArtifactGenerationException {
64         org.onap.aai.babel.xml.generator.xsd.Model aaiModel = createJaxbModel(model);
65         ModelElement baseWidget = addBaseWidgetRelation(model, aaiModel);
66         generateWidgetChildren(baseWidget, model.getWidgets());
67         return getModelAsString(aaiModel);
68     }
69
70     /**
71      * Create a JAXB Model from the supplied Service or Resource.
72      *
73      * @param model
74      *            the Service or Resource containing the model details
75      * @return a new Model object based on the A&AI schema
76      */
77     private org.onap.aai.babel.xml.generator.xsd.Model createJaxbModel(Model model) {
78         log.debug(model.toString());
79
80         org.onap.aai.babel.xml.generator.xsd.Model aaiModel = new org.onap.aai.babel.xml.generator.xsd.Model();
81         aaiModel.setModelInvariantId(model.getModelId());
82         aaiModel.setModelType(model.getModelTypeName());
83         if ("service".equals(model.getModelTypeName())){
84             aaiModel.setModelRole(model.getCategory());
85         }
86         aaiModel.setModelVers(new ModelVers());
87         aaiModel.getModelVers().getModelVer().add(createModelVersion(model));
88
89         return aaiModel;
90     }
91
92     /**
93      * Create a new JAXB object representing the model-ver complex type, and populate this with the Model Version
94      * information.
95      * 
96      * @param model
97      *            the Service or Resource containing the version details
98      * @return a new ModelVer object
99      */
100     private ModelVer createModelVersion(Model model) {
101         ModelVer modelVer = new ModelVer();
102         modelVer.setModelDescription(model.getModelDescription());
103         modelVer.setModelName(model.getModelName());
104         modelVer.setModelVersion(model.getModelVersion());
105         modelVer.setModelVersionId(model.getModelNameVersionId());
106         modelVer.setSdncModelName(model.getSdncModelName());
107         modelVer.setSdncModelVersion(model.getSdncModelVersion());
108         modelVer.setModelElements(new ModelElements());
109         return modelVer;
110     }
111
112     /**
113      * Add base widget model element for the Service or Resource.
114      * 
115      * @param model
116      *            the Service or Resource containing the Model and child resources
117      * @param aaiModel
118      *            the JAXB Model to populate
119      * @return a new ModelElement for the relationship to the base Widget
120      * @throws XmlArtifactGenerationException
121      */
122     private ModelElement addBaseWidgetRelation(Model model, org.onap.aai.babel.xml.generator.xsd.Model aaiModel)
123             throws XmlArtifactGenerationException {
124         ModelElement widgetElement = createWidgetRelationshipModelElement(model);
125         ModelVer modelVer = aaiModel.getModelVers().getModelVer().get(0);
126         modelVer.getModelElements().getModelElement().add(widgetElement);
127
128         // Add the child resources to the base widget model element list
129         List<ModelElement> modelElements = widgetElement.getModelElements().getModelElement();
130         for (Resource resource : model.getResources()) {
131             modelElements.add(createRelationshipModelElement(resource));
132         }
133
134         return widgetElement;
135     }
136
137     /**
138      * Create a model-element complex type storing the relationship to a Service or Resource model's base Widget.
139      * 
140      * @param model
141      *            the Service or Resource model storing the widget's relationship data
142      * @return a new Java object for the model-element type storing the Widget relationship
143      * @throws XmlArtifactGenerationException
144      */
145     private ModelElement createWidgetRelationshipModelElement(Model model) throws XmlArtifactGenerationException {
146         return createRelationshipModelElement(model.getDeleteFlag(), model.getWidgetId(), model.getWidgetInvariantId());
147     }
148
149     /**
150      * Create a model-element complex type storing the relationship to a Resource model.
151      * 
152      * @param resource
153      *            the Resource model storing the relationship data
154      * @return a new Java object for the model-element type storing the relationship
155      * @throws XmlArtifactGenerationException
156      */
157     private ModelElement createRelationshipModelElement(Resource resource) {
158         return createRelationshipModelElement(resource.getDeleteFlag(), resource.getModelNameVersionId(),
159                 resource.getModelId());
160     }
161
162     /**
163      * Create a model-element complex type storing the relationship to a Widget model.
164      * 
165      * @param widget
166      *            the Widget model storing the relationship data
167      * @return a new Java object for the model-element type storing the Widget relationship
168      */
169     private ModelElement createRelationshipModelElement(Widget widget) {
170         return createRelationshipModelElement(widget.getDeleteFlag(), widget.getId(), widget.getWidgetId());
171     }
172
173     /**
174      * Method to create the <model-element></model-element> holding the relationship value for a resource/widget model.
175      *
176      * @param newDataDelFlag
177      *            new-data-del-flag (mapped from boolean to the string T or F)
178      * @param modelVersionId
179      *            model-version-id
180      * @param modelInvariantId
181      *            model-invariant-id
182      * @return a new Java object for the model-element type storing the relationship
183      */
184     private ModelElement createRelationshipModelElement(boolean newDataDelFlag, String modelVersionId,
185             String modelInvariantId) {
186         ModelElement relationshipModelElement = new ModelElement();
187         relationshipModelElement.setNewDataDelFlag(newDataDelFlag ? "T" : "F");
188         relationshipModelElement.setCardinality("unbounded");
189         relationshipModelElement.setModelElements(new ModelElements());
190         relationshipModelElement.setRelationshipList(createModelRelationship(modelVersionId, modelInvariantId));
191         return relationshipModelElement;
192     }
193
194     /**
195      * Create the Model Version relationship data.
196      * 
197      * @param modelVersionId
198      *            model-version-id
199      * @param modelInvariantId
200      *            model-invariant-id
201      * @return a new RelationshipList object containing the model-ver relationships
202      */
203     private RelationshipList createModelRelationship(String modelVersionId, String modelInvariantId) {
204         Relationship relationship = new Relationship();
205         relationship.setRelatedTo("model-ver");
206         List<RelationshipData> relationshipDataList = relationship.getRelationshipData();
207         relationshipDataList.add(createRelationshipData("model-ver.model-version-id", modelVersionId));
208         relationshipDataList.add(createRelationshipData("model.model-invariant-id", modelInvariantId));
209
210         RelationshipList relationShipList = new RelationshipList();
211         relationShipList.getRelationship().add(relationship);
212         return relationShipList;
213     }
214
215     /**
216      * Create a new RelationshipData element for the given key/value pair.
217      * 
218      * @param key
219      *            relationship key
220      * @param value
221      *            relationship value
222      * @return a new Java object representing the relationship-data complex type
223      */
224     private RelationshipData createRelationshipData(String key, String value) {
225         RelationshipData data = new RelationshipData();
226         data.setRelationshipKey(key);
227         data.setRelationshipValue(value);
228         return data;
229     }
230
231     /**
232      * Method to create the child model elements of the widget. Handles the generation of recursive child widget
233      * elements (if any).
234      * 
235      * @param parent
236      *            Reference to the parent widget model element
237      * @param widgets
238      *            Set of child widgets obtained from the tosca/widget definition
239      */
240     private void generateWidgetChildren(ModelElement parent, Collection<Widget> widgets) {
241         for (Widget widget : widgets) {
242             ModelElement childRelation = createRelationshipModelElement(widget);
243             parent.getModelElements().getModelElement().add(childRelation);
244             // Recursive call to create any child widgets.
245             generateWidgetChildren(childRelation, widget.getWidgets());
246         }
247     }
248
249     /**
250      * JAXB marshalling helper method to convert the Java object model to XML String.
251      *
252      * @param model
253      *            Java Object model of a service/widget/resource
254      * @return XML representation of the Java model in String format
255      */
256     private String getModelAsString(org.onap.aai.babel.xml.generator.xsd.Model model) {
257         JAXBContext jaxbContext;
258         StringWriter modelStringWriter = new StringWriter();
259         try {
260             jaxbContext = JAXBContext.newInstance(org.onap.aai.babel.xml.generator.xsd.Model.class);
261             Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
262             jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
263             jaxbMarshaller.setProperty(Marshaller.JAXB_ENCODING, "US-ASCII");
264             jaxbMarshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
265             jaxbMarshaller.marshal(model, modelStringWriter);
266         } catch (JAXBException jaxbException) {
267             log.error(ApplicationMsgs.INVALID_CSAR_FILE, jaxbException);
268             throw new DOMException(DOMException.SYNTAX_ERR, jaxbException.getMessage());
269         }
270
271         return modelStringWriter.toString();
272     }
273 }