Return List<Artifact> in ArtifactDownloadManager
[aai/model-loader.git] / src / main / java / org / onap / aai / modelloader / entity / model / ModelArtifactParser.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.modelloader.entity.model;
22
23 import java.io.StringWriter;
24 import java.util.List;
25 import java.util.Objects;
26 import java.util.stream.Collector;
27 import java.util.stream.IntStream;
28 import javax.xml.XMLConstants;
29 import javax.xml.transform.OutputKeys;
30 import javax.xml.transform.Transformer;
31 import javax.xml.transform.TransformerException;
32 import javax.xml.transform.TransformerFactory;
33 import javax.xml.transform.dom.DOMSource;
34 import javax.xml.transform.stream.StreamResult;
35
36 import org.onap.aai.cl.api.Logger;
37 import org.onap.aai.cl.eelf.LoggerFactory;
38 import org.onap.aai.modelloader.entity.Artifact;
39 import org.onap.aai.modelloader.service.ModelLoaderMsgs;
40 import org.springframework.stereotype.Component;
41 import org.w3c.dom.Element;
42 import org.w3c.dom.Node;
43 import org.w3c.dom.NodeList;
44
45 @Component
46 public class ModelArtifactParser extends AbstractModelArtifactParser {
47
48     public static final String MODEL_VER = "model-ver";
49     public static final String MODEL_VERSION_ID = "model-version-id";
50     public static final String MODEL_INVARIANT_ID = "model-invariant-id";
51     private static final String RELATIONSHIP = "relationship";
52     private static final String MODEL_ELEMENT_RELATIONSHIP_KEY = "model." + MODEL_INVARIANT_ID;
53     private static final String MODEL_VER_ELEMENT_RELATIONSHIP_KEY = MODEL_VER + "." + MODEL_VERSION_ID;
54
55     private static Logger logger = LoggerFactory.getInstance().getLogger(ModelArtifactParser.class.getName());
56
57     @Override
58     void parseNode(Node node, IModelArtifact model) {
59         if (node.getNodeName().equalsIgnoreCase(MODEL_INVARIANT_ID)
60                 || node.getNodeName().equalsIgnoreCase(MODEL_VERSION_ID)) {
61             setVersionId(model, node);
62         } else if (node.getNodeName().equalsIgnoreCase(RELATIONSHIP)) {
63             parseRelationshipNode(node, model);
64         } else {
65             if (node.getNodeName().equalsIgnoreCase(MODEL_VER)) {
66                 String modelVersion;
67                 try {
68                     modelVersion = nodeToString(node);
69                     ((ModelArtifact) model).setModelVer(modelVersion);
70                 } catch (TransformerException e) {
71                     logger.error(ModelLoaderMsgs.ARTIFACT_PARSE_ERROR, "Failed to parse resource version for input: " + node.toString());
72                 }
73                 if (((ModelArtifact) model).getModelNamespace() != null
74                         && !((ModelArtifact) model).getModelNamespace().isEmpty()) {
75                     Element e = (Element) node;
76                     e.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns",
77                             ((ModelArtifact) model).getModelNamespace());
78                 }
79             }
80
81             parseChildNodes(node, model);
82         }
83     }
84
85     private String nodeToString(Node node) throws TransformerException {
86         StringWriter sw = new StringWriter();
87         TransformerFactory transFact = TransformerFactory.newInstance();
88         transFact.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
89         transFact.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
90         transFact.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
91         Transformer t = transFact.newTransformer();
92         t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
93         t.transform(new DOMSource(node), new StreamResult(sw));
94         return sw.toString();
95     }
96
97     /**
98      * {@inheritDoc}
99      */
100     @Override
101     void setVersionId(IModelArtifact model, Node node) {
102         if (MODEL_INVARIANT_ID.equals(node.getNodeName())) {
103             ((ModelArtifact) model).setModelInvariantId(node.getTextContent().trim());
104         } else if (MODEL_VERSION_ID.equals(node.getNodeName())) {
105             ((ModelArtifact) model).setModelVerId(node.getTextContent().trim());
106         }
107     }
108
109     /**
110      * {@inheritDoc}
111      */
112     @Override
113     ModelId buildModelId(NodeList nodeList) {
114         return IntStream.range(0, nodeList.getLength()).mapToObj(nodeList::item)
115                 .filter(childNode -> childNode.getNodeName().equalsIgnoreCase(RELATIONSHIP_DATA))
116                 .map(this::getRelationship) //
117                 .collect(Collector.of(ModelId::new, ModelId::setRelationship, (m, p) -> m));
118     }
119
120     /**
121      * Find a relationship key and value pair from the children of the supplied node.
122      *
123      * @param node containing children storing relationship keys and values
124      * @return a pair containing a relationship key and its value. Note: if multiple relationships are found, existing
125      *         values stored in the pair will be overwritten.
126      */
127     private Pair<String, String> getRelationship(Node node) {
128         Objects.requireNonNull(node);
129         NodeList relDataChildList = node.getChildNodes();
130         Objects.requireNonNull(relDataChildList);
131
132         return IntStream.range(0, relDataChildList.getLength()).mapToObj(relDataChildList::item)
133                 .filter(this::filterRelationshipNode)
134                 .collect(Collector.of(Pair::new, applyRelationshipValue, (p, n) -> p));
135     }
136
137     /**
138      * This method is responsible for creating an instance of {@link ModelArtifactParser.ModelId}
139      *
140      * @return IModelId instance of {@link ModelArtifactParser.ModelId}
141      */
142     @Override
143     IModelId createModelIdInstance() {
144         return new ModelId();
145     }
146
147     private class ModelId implements IModelId {
148
149         private String modelInvariantIdValue;
150         private String modelVersionIdValue;
151
152         @Override
153         public void setRelationship(Pair<String, String> p) {
154             if (p.getKey().equalsIgnoreCase(MODEL_VER_ELEMENT_RELATIONSHIP_KEY)) {
155                 modelVersionIdValue = p.getValue();
156             } else if (p.getKey().equalsIgnoreCase(MODEL_ELEMENT_RELATIONSHIP_KEY)) {
157                 modelInvariantIdValue = p.getValue();
158             }
159         }
160
161         @Override
162         public boolean defined() {
163             return modelInvariantIdValue != null && modelVersionIdValue != null;
164         }
165
166         @Override
167         public String toString() {
168             return modelInvariantIdValue + "|" + modelVersionIdValue;
169         }
170     }
171
172     /**
173      * {@inheritDoc}
174      */
175     @Override
176     String buildArtifactParseExceptionMessage(String artifactName, String localisedMessage) {
177         return "Unable to parse legacy model artifact " + artifactName + ": " + localisedMessage;
178     }
179
180     /**
181      * {@inheritDoc}
182      */
183     @Override
184     IModelArtifact createModelArtifactInstance() {
185         return new ModelArtifact();
186     }
187
188     @Override
189     boolean modelIsValid(IModelArtifact model) {
190         return ((ModelArtifact) model).getModelInvariantId() != null && ((ModelArtifact) model).getModelVerId() != null;
191     }
192
193     /**
194      * {@inheritDoc}
195      */
196     @Override
197     boolean processParsedModel(List<Artifact> modelList, String artifactName, IModelArtifact model) {
198         boolean valid = false;
199
200         if (model != null) {
201             ModelArtifact modelImpl = (ModelArtifact) model;
202             logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, "Model parsed =====>>>> " + "Model-invariant-Id: "
203                     + modelImpl.getModelInvariantId() + " Model-Version-Id: " + modelImpl.getModelVerId());
204             modelList.add(modelImpl);
205             valid = true;
206         } else {
207             logger.error(ModelLoaderMsgs.ARTIFACT_PARSE_ERROR, "Unable to parse artifact " + artifactName);
208         }
209
210         return valid;
211     }
212
213     /**
214      * {@inheritDoc}
215      */
216     @Override
217     String getModelElementRelationshipKey() {
218         return null;
219     }
220
221     /**
222      * {@inheritDoc}
223      */
224     @Override
225     String getVersionIdNodeName() {
226         return null;
227     }
228 }