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