Integrate aai-schema-ingest library into aai-core
[aai/aai-common.git] / aai-core / src / main / java / org / onap / aai / util / 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  *
11  *    http://www.apache.org/licenses/LICENSE-2.0
12  *
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 package org.onap.aai.util.genxsd;
21
22 import java.io.File;
23 import java.io.FileNotFoundException;
24 import java.io.IOException;
25
26 import javax.xml.parsers.ParserConfigurationException;
27
28
29 import org.onap.aai.config.SpringContextAware;
30 import org.onap.aai.edges.EdgeIngestor;
31 import org.onap.aai.edges.exceptions.EdgeRuleNotFoundException;
32 import org.onap.aai.exceptions.AAIException;
33 import org.onap.aai.nodes.NodeIngestor;
34 import org.onap.aai.setup.SchemaVersion;
35 import org.onap.aai.setup.SchemaVersions;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38
39 import org.w3c.dom.Attr;
40 import org.w3c.dom.Element;
41 import org.w3c.dom.NamedNodeMap;
42 import org.w3c.dom.NodeList;
43 import org.xml.sax.SAXException;
44
45 public class HTMLfromOXM extends OxmFileProcessor {
46
47         private static final Logger logger = LoggerFactory.getLogger("HTMLfromOXM.class");
48
49         
50         
51         public HTMLfromOXM(SchemaVersions schemaVersions, NodeIngestor ni, EdgeIngestor ei ){
52                 super(schemaVersions, ni,ei);
53         }
54         public void setOxmVersion(File oxmFile, SchemaVersion v) {
55                 super.setOxmVersion(oxmFile, v);
56                 this.v = v;
57         }
58         public void setXmlVersion(String xml, SchemaVersion v) {
59                 super.setXmlVersion(xml, v);
60                 this.v = v;
61         }
62         public void setVersion(SchemaVersion v) {
63                 super.setVersion(v);
64                 this.v = v;
65         }
66         
67         
68         @Override
69         public String getDocumentHeader() {
70                 StringBuffer sb = new StringBuffer();
71                 logger.trace("processing starts");
72                 sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n");
73                 String namespace = "org.onap";
74                 if (v.compareTo(getSchemaVersions().getNamespaceChangeVersion()) < 0 ) {
75                         namespace = "org.openecomp";
76                 }
77                 if ( versionUsesAnnotations(v.toString()) ) {
78                         sb.append("<xs:schema elementFormDefault=\"qualified\" version=\"1.0\" targetNamespace=\"http://" + namespace + ".aai.inventory/" 
79                                 + v.toString() + "\" xmlns:tns=\"http://" + namespace + ".aai.inventory/" + v.toString() + "\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\""
80                                                 + "\n"
81                                                 + "xmlns:jaxb=\"http://java.sun.com/xml/ns/jaxb\"\r\n" + 
82                                                 "    jaxb:version=\"2.1\"\r\n" + 
83                                                 "    xmlns:annox=\"http://annox.dev.java.net\"\r\n" + 
84                                                 "    jaxb:extensionBindingPrefixes=\"annox\">\n\n");
85                 } else {
86                         sb.append("<xs:schema elementFormDefault=\"qualified\" version=\"1.0\" targetNamespace=\"http://" + namespace + ".aai.inventory/" 
87                                         + v.toString() + "\" xmlns:tns=\"http://" + namespace + ".aai.inventory/" + v.toString() + "\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">\n\n");
88                 }
89                 return sb.toString();
90         }
91
92         @Override
93         public String process() throws ParserConfigurationException, SAXException, IOException, AAIException, FileNotFoundException, EdgeRuleNotFoundException {
94                 StringBuilder sb = new StringBuilder();
95                 try {
96                         init();
97                 } catch(Exception e) {
98                         logger.error( "Error initializing " + this.getClass());
99                         throw e;
100                 }
101                 sb.append(getDocumentHeader());
102                 StringBuilder sbInventory = new StringBuilder();
103                 for ( int i = 0; i < javaTypeNodes.getLength(); ++ i ) {
104                         XSDElement javaTypeElement = new XSDElement((Element)javaTypeNodes.item(i));
105                         String javaTypeName = javaTypeElement.name();
106                         if ( javaTypeName == null ) {
107                                 String msg = "Invalid OXM file: <java-type> has no name attribute in " + oxmFile; 
108                                 logger.error(msg);
109                                 throw new AAIException(msg);
110                         }
111                         if ("Nodes".equals(javaTypeName)) {
112                                 logger.debug("skipping Nodes entry (temporary feature)");
113                                 continue;
114                         }
115                         //Skip any type that has already been processed(recursion could be the reason)
116                         logger.debug(getXmlRootElementName(javaTypeName)+" vs "+ javaTypeName+":"+generatedJavaType.containsKey(getXmlRootElementName(javaTypeName)));
117                         if ( generatedJavaType.containsKey(javaTypeName) ) {
118                                         continue;
119                         }
120                         if ( !"Inventory".equals(javaTypeName)) {
121                                 generatedJavaType.put(javaTypeName, null);
122                         }
123                         sb.append(processJavaTypeElement( javaTypeName, javaTypeElement, sbInventory ));
124                 }
125                 sb.append(sbInventory);
126                 sb.append("      </xs:sequence>\n");
127                 sb.append("    </xs:complexType>\n");
128                 sb.append("  </xs:element>\n");                 
129                 sb.append("</xs:schema>\n");
130                 return sb.toString();
131         }
132
133         public String processJavaTypeElement( String javaTypeName, Element javaType_Element, StringBuilder sbInventory) {
134         
135                 String xmlRootElementName = getXMLRootElementName(javaType_Element);
136
137                 NodeList parentNodes = javaType_Element.getElementsByTagName("java-attributes");
138                 StringBuffer sb = new StringBuffer();
139                 if ( parentNodes.getLength() == 0 ) {
140                         logger.trace( "no java-attributes for java-type " + javaTypeName);
141                         return "";
142                 }
143         
144                 Element parentElement = (Element)parentNodes.item(0);
145                 NodeList xmlElementNodes = parentElement.getElementsByTagName("xml-element");
146                 // support for multiple inventory elements across oxm files
147                 boolean processingInventory = false;
148                 boolean hasPreviousInventory = false;
149                 if ( "inventory".equals(xmlRootElementName) && sbInventory != null ) {
150                         processingInventory = true;
151                         if ( sbInventory.toString().contains("xs:complexType") ) {
152                                 hasPreviousInventory = true;
153                         }
154                 }
155                 
156                 StringBuffer sb1 = new StringBuffer();
157                 if ( xmlElementNodes.getLength() > 0 ) {
158
159                         if ( !processingInventory || !hasPreviousInventory ) {
160                                 sb1.append("  <xs:element name=\"" + xmlRootElementName + "\">\n");
161                                 sb1.append("    <xs:complexType>\n");
162
163                                 XSDElement javaTypeElement = new XSDElement(javaType_Element);
164                                 logger.debug("XSDElement name: "+javaTypeElement.name());
165                                 if(versionUsesAnnotations(v.toString())) {
166                                         sb1.append(javaTypeElement.getHTMLAnnotation("class", "      "));
167                                 }
168                                 sb1.append("      <xs:sequence>\n");
169                         }
170                         for ( int i = 0; i < xmlElementNodes.getLength(); ++i ) {
171                         
172                                 XSDElement xmlElementElement = new XSDElement((Element)xmlElementNodes.item(i));
173
174 //                              String elementName = xmlElementElement.getAttribute("name");
175                                 String elementType = xmlElementElement.getAttribute("type");
176                                 //No simple types; only AAI custom types
177                                 String addType = elementType.contains("." + v.toString() + ".") ? elementType.substring(elementType.lastIndexOf('.')+1) : null;
178                         if ( elementType.contains("." + v.toString() + ".") && !generatedJavaType.containsKey(addType) ) {
179                                 generatedJavaType.put(addType, elementType);
180                                 sb.append(processJavaTypeElement( addType, getJavaTypeElement(addType), null ));        
181                         }
182                         if ("Nodes".equals(addType)) {
183                                 logger.trace("Skipping nodes, temporary testing");
184                                 continue;
185                         }
186                         //assembles the basic <element> 
187                         sb1.append(xmlElementElement.getHTMLElement(v, versionUsesAnnotations(v.toString()), this));
188                         }
189                         if ( !processingInventory ) {
190                                 sb1.append("      </xs:sequence>\n");
191                                 sb1.append("    </xs:complexType>\n");
192                                 sb1.append("  </xs:element>\n");
193                         }
194                 }
195         
196                 if ( xmlElementNodes.getLength() < 1 ) {
197                         sb.append("  <xs:element name=\"" + xmlRootElementName + "\">\n");
198                         sb.append("    <xs:complexType>\n");
199                         sb.append("      <xs:sequence/>\n");
200                         sb.append("    </xs:complexType>\n");
201                         sb.append("  </xs:element>\n");
202                         generatedJavaType.put(javaTypeName, null);
203                         return sb.toString();                   
204                 }
205                 if ( processingInventory && sbInventory != null ) {
206                         sbInventory.append(sb1);
207                 } else {
208                         sb.append( sb1 );
209                 }
210                 return sb.toString();
211         }
212         
213         private Element getJavaTypeElement( String javaTypeName )
214         {               
215                 String attrName, attrValue;
216                 Attr attr;
217                 Element javaTypeElement;
218                 for ( int i = 0; i < javaTypeNodes.getLength(); ++ i ) {
219                         javaTypeElement = (Element) javaTypeNodes.item(i);
220                         NamedNodeMap attributes = javaTypeElement.getAttributes();
221                         for ( int j = 0; j < attributes.getLength(); ++j ) {
222                     attr = (Attr) attributes.item(j);
223                     attrName = attr.getNodeName();
224                     attrValue = attr.getNodeValue();
225                     if ( attrName.equals("name") && attrValue.equals(javaTypeName))
226                         return javaTypeElement;
227                         }
228                 }
229                 logger.error( "oxm file format error, missing java-type " + javaTypeName);
230                 return (Element) null;
231         }
232
233         private boolean versionUsesAnnotations( String version) {
234                 int ver = new Integer(version.substring(1)).intValue();
235                 if ( ver >= HTMLfromOXM.annotationsStartVersion ) {
236                         return true;
237                 }
238                 if ( ver <= HTMLfromOXM.annotationsMinVersion ) {
239                         return true;
240                 }
241                 return false;
242         }
243 }