ce45236a03fdf5bd6f3b40c3931761e8f94c475e
[aai/schema-service.git] / aai-schema-gen / src / main / java / org / onap / aai / schemagen / genxsd / HTMLfromOXM.java
1 /**
2  * ============LICENSE_START=======================================================
3  * org.onap.aai
4  * ================================================================================
5  * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * <p>
11  * http://www.apache.org/licenses/LICENSE-2.0
12  * <p>
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.aai.schemagen.genxsd;
22
23 import java.io.File;
24 import java.io.FileNotFoundException;
25 import java.io.IOException;
26 import java.util.ArrayList;
27 import java.util.HashMap;
28 import java.util.List;
29 import javax.xml.parsers.ParserConfigurationException;
30 import org.onap.aai.edges.EdgeIngestor;
31 import org.onap.aai.edges.exceptions.EdgeRuleNotFoundException;
32 import org.onap.aai.nodes.NodeIngestor;
33 import org.onap.aai.setup.SchemaVersion;
34 import org.onap.aai.setup.SchemaVersions;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37 import org.w3c.dom.Attr;
38 import org.w3c.dom.Element;
39 import org.w3c.dom.NamedNodeMap;
40 import org.w3c.dom.NodeList;
41 import org.xml.sax.SAXException;
42
43 public class HTMLfromOXM extends OxmFileProcessor {
44
45     private static final Logger logger = LoggerFactory.getLogger("HTMLfromOXM.class");
46
47     private String maxOccurs;
48
49     public HTMLfromOXM(String maxOccurs, SchemaVersions schemaVersions, NodeIngestor ni,
50                        EdgeIngestor ei) {
51         super(schemaVersions, ni, ei);
52         this.maxOccurs = maxOccurs;
53     }
54
55     public void setOxmVersion(File oxmFile, SchemaVersion v) {
56         super.setOxmVersion(oxmFile, v);
57         this.v = v;
58     }
59
60     public void setXmlVersion(String xml, SchemaVersion v) {
61         super.setXmlVersion(xml, v);
62         this.v = v;
63     }
64
65     public void setVersion(SchemaVersion v) {
66         super.setVersion(v);
67         this.v = v;
68     }
69
70
71     @Override
72     public String getDocumentHeader() {
73         StringBuilder sb = new StringBuilder();
74         logger.trace("processing starts");
75         sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>")
76             .append(LINE_SEPARATOR);
77         String namespace = "org.onap";
78         if (v.compareTo(getSchemaVersions().getNamespaceChangeVersion()) < 0) {
79             namespace = "org.openecomp";
80         }
81         sb.append(
82             "<xs:schema elementFormDefault=\"qualified\" version=\"1.0\" targetNamespace=\"http://")
83             .append(namespace).append(".aai.inventory/").append(v.toString())
84             .append("\" xmlns:tns=\"http://").append(namespace).append(".aai.inventory/")
85             .append(v.toString()).append("\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"")
86             .append(LINE_SEPARATOR).append("xmlns:jaxb=\"http://java.sun.com/xml/ns/jaxb\"")
87             .append(LINE_SEPARATOR).append("    jaxb:version=\"2.1\"").append(LINE_SEPARATOR)
88             .append("    xmlns:annox=\"http://annox.dev.java.net\"").append(LINE_SEPARATOR)
89             .append("    jaxb:extensionBindingPrefixes=\"annox\">")
90             .append(DOUBLE_LINE_SEPARATOR);
91         return sb.toString();
92     }
93
94     @Override
95     public String process()
96         throws ParserConfigurationException, SAXException, IOException, FileNotFoundException,
97         EdgeRuleNotFoundException {
98         StringBuilder sb = new StringBuilder();
99
100         try {
101             init();
102         } catch (Exception e) {
103             logger.error("Error initializing " + this.getClass());
104             throw e;
105         }
106         sb.append(getDocumentHeader());
107         StringBuilder sbInventory = new StringBuilder();
108         Element elem;
109         String javaTypeName;
110         combinedJavaTypes = new HashMap();
111         for (int i = 0; i < javaTypeNodes.getLength(); ++i) {
112             elem = (Element) javaTypeNodes.item(i);
113             javaTypeName = elem.getAttribute("name");
114             if (!"Inventory".equals(javaTypeName)) {
115                 if (generatedJavaType.containsKey(javaTypeName)) {
116                     continue;
117                 }
118                 // will combine all matching java-types
119                 elem = getJavaTypeElement(javaTypeName, false);
120             }
121             XSDElement javaTypeElement = new XSDElement(elem, maxOccurs);
122             //javaTypeName = javaTypeElement.name();
123             if (javaTypeName == null) {
124                 String msg = "Invalid OXM file: <java-type> has no name attribute in " + oxmFile;
125                 logger.error(msg);
126                 throw new SAXException(msg);
127             }
128             if ("Nodes".equals(javaTypeName)) {
129                 logger.debug("skipping Nodes entry (temporary feature)");
130                 continue;
131             }
132             logger.debug(getXmlRootElementName(javaTypeName) + " vs " + javaTypeName + ":" +
133                 generatedJavaType.containsKey(getXmlRootElementName(javaTypeName)));
134
135             if (!"Inventory".equals(javaTypeName)) {
136                 generatedJavaType.put(javaTypeName, null);
137             }
138             sb.append(processJavaTypeElement(javaTypeName, javaTypeElement, sbInventory));
139         }
140         sb.append(sbInventory);
141         sb.append("      </xs:sequence>" + LINE_SEPARATOR);
142         sb.append("    </xs:complexType>" + LINE_SEPARATOR);
143         sb.append("  </xs:element>" + LINE_SEPARATOR);
144         sb.append("</xs:schema>" + LINE_SEPARATOR);
145         return sb.toString();
146     }
147
148     protected boolean isValidName(String name) {
149         if (name == null || name.length() == 0) {
150             return false;
151         }
152         String pattern = "^[a-z0-9-]*$";
153         return name.matches(pattern);
154     }
155
156     protected boolean skipCheck(String javaAttribute) {
157         if (javaAttribute.equals("model")
158             || javaAttribute.equals("eventHeader")) {
159             return true;
160         }
161         return false;
162     }
163
164     public String processJavaTypeElement(String javaTypeName, Element javaType_Element,
165                                          StringBuilder sbInventory) {
166         String xmlRootElementName = getXMLRootElementName(javaType_Element);
167
168         NodeList parentNodes = javaType_Element.getElementsByTagName("java-attributes");
169         StringBuilder sb = new StringBuilder();
170         if (parentNodes.getLength() == 0) {
171             logger.trace("no java-attributes for java-type " + javaTypeName);
172             return "";
173         }
174
175         Element parentElement = (Element) parentNodes.item(0);
176         NodeList xmlElementNodes = parentElement.getElementsByTagName("xml-element");
177         // support for multiple inventory elements across oxm files
178         boolean processingInventory = false;
179         boolean hasPreviousInventory = false;
180         if ("inventory".equals(xmlRootElementName) && sbInventory != null) {
181             processingInventory = true;
182             if (sbInventory.toString().contains("xs:complexType")) {
183                 hasPreviousInventory = true;
184             }
185         }
186
187         StringBuilder sb1 = new StringBuilder();
188         if (xmlElementNodes.getLength() > 0) {
189
190             if (!processingInventory || !hasPreviousInventory) {
191                 sb1.append("  <xs:element name=\"").append(xmlRootElementName).append("\">")
192                     .append(LINE_SEPARATOR);
193                 sb1.append("    <xs:complexType>").append(LINE_SEPARATOR);
194
195                 XSDElement javaTypeElement = new XSDElement(javaType_Element, maxOccurs);
196                 logger.debug("XSDElement name: " + javaTypeElement.name());
197                 sb1.append(javaTypeElement.getHTMLAnnotation("class", "      "));
198                 sb1.append("      <xs:sequence>").append(LINE_SEPARATOR);
199             }
200             Element javatypeElement;
201             for (int i = 0; i < xmlElementNodes.getLength(); ++i) {
202
203                 XSDElement xmlElementElement =
204                     new XSDElement((Element) xmlElementNodes.item(i), maxOccurs);
205
206 //                              String elementName = xmlElementElement.getAttribute("name");
207                 String elementType = xmlElementElement.getAttribute("type");
208                 //No simple types; only AAI custom types
209                 String addType = elementType.contains("." + v.toString() + ".") ?
210                     elementType.substring(elementType.lastIndexOf('.') + 1) : null;
211                 if (elementType.contains("." + v.toString() + ".") &&
212                     !generatedJavaType.containsKey(addType)) {
213                     generatedJavaType.put(addType, elementType);
214                     javatypeElement = getJavaTypeElement(addType, processingInventory);
215                     sb.append(processJavaTypeElement(addType, javatypeElement, null));
216                 }
217                 if ("Nodes".equals(addType)) {
218                     logger.trace("Skipping nodes, temporary testing");
219                     continue;
220                 }
221                 //assembles the basic <element>
222                 sb1.append(xmlElementElement.getHTMLElement(v, true, this));
223             }
224             if (!processingInventory) {
225                 sb1.append("      </xs:sequence>" + LINE_SEPARATOR);
226                 sb1.append("    </xs:complexType>" + LINE_SEPARATOR);
227                 sb1.append("  </xs:element>" + LINE_SEPARATOR);
228             }
229         }
230
231         if (xmlElementNodes.getLength() < 1) {
232             sb.append("  <xs:element name=\"" + xmlRootElementName + "\">" + LINE_SEPARATOR);
233             sb.append("    <xs:complexType>" + LINE_SEPARATOR);
234             sb.append("      <xs:sequence/>" + LINE_SEPARATOR);
235             sb.append("    </xs:complexType>" + LINE_SEPARATOR);
236             sb.append("  </xs:element>" + LINE_SEPARATOR);
237             generatedJavaType.put(javaTypeName, null);
238             return sb.toString();
239         }
240         if (processingInventory && sbInventory != null) {
241             sbInventory.append(sb1);
242         } else {
243             sb.append(sb1);
244         }
245         return sb.toString();
246     }
247
248     private Element getJavaTypeElement(String javaTypeName, boolean processingInventory) {
249         String attrName, attrValue;
250         Attr attr;
251         Element javaTypeElement;
252
253         List<Element> combineElementList = new ArrayList<Element>();
254         for (int i = 0; i < javaTypeNodes.getLength(); ++i) {
255             javaTypeElement = (Element) javaTypeNodes.item(i);
256             NamedNodeMap attributes = javaTypeElement.getAttributes();
257             for (int j = 0; j < attributes.getLength(); ++j) {
258                 attr = (Attr) attributes.item(j);
259                 attrName = attr.getNodeName();
260                 attrValue = attr.getNodeValue();
261                 if (attrName.equals("name") && attrValue.equals(javaTypeName)) {
262                     if (processingInventory) {
263                         return javaTypeElement;
264                     } else {
265                         combineElementList.add(javaTypeElement);
266                     }
267                 }
268             }
269         }
270         if (combineElementList.size() == 0) {
271             logger.error("oxm file format error, missing java-type " + javaTypeName);
272             return (Element) null;
273         } else if (combineElementList.size() > 1) {
274             // need to combine java-attributes
275             return combineElements(javaTypeName, combineElementList);
276         }
277         return combineElementList.get(0);
278
279     }
280
281 }