2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
20 package org.onap.aai.util.genxsd;
23 import java.io.FileNotFoundException;
24 import java.io.IOException;
25 import java.util.ArrayList;
26 import java.util.HashMap;
27 import java.util.List;
29 import javax.xml.parsers.ParserConfigurationException;
32 import org.onap.aai.config.SpringContextAware;
33 import org.onap.aai.edges.EdgeIngestor;
34 import org.onap.aai.edges.exceptions.EdgeRuleNotFoundException;
35 import org.onap.aai.exceptions.AAIException;
36 import org.onap.aai.nodes.NodeIngestor;
37 import org.onap.aai.setup.SchemaVersion;
38 import org.onap.aai.setup.SchemaVersions;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
42 import org.w3c.dom.Attr;
43 import org.w3c.dom.Element;
44 import org.w3c.dom.NamedNodeMap;
45 import org.w3c.dom.NodeList;
46 import org.xml.sax.SAXException;
48 public class HTMLfromOXM extends OxmFileProcessor {
50 private static final Logger logger = LoggerFactory.getLogger("HTMLfromOXM.class");
52 private String maxOccurs;
54 public HTMLfromOXM(String maxOccurs, SchemaVersions schemaVersions, NodeIngestor ni, EdgeIngestor ei ){
55 super(schemaVersions, ni,ei);
56 this.maxOccurs = maxOccurs;
58 public void setOxmVersion(File oxmFile, SchemaVersion v) {
59 super.setOxmVersion(oxmFile, v);
62 public void setXmlVersion(String xml, SchemaVersion v) {
63 super.setXmlVersion(xml, v);
66 public void setVersion(SchemaVersion v) {
73 public String getDocumentHeader() {
74 StringBuffer sb = new StringBuffer();
75 logger.trace("processing starts");
76 sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" + LINE_SEPARATOR);
77 String namespace = "org.onap";
78 if (v.compareTo(getSchemaVersions().getNamespaceChangeVersion()) < 0 ) {
79 namespace = "org.openecomp";
81 if ( versionUsesAnnotations(v.toString()) ) {
82 sb.append("<xs:schema elementFormDefault=\"qualified\" version=\"1.0\" targetNamespace=\"http://" + namespace + ".aai.inventory/"
83 + v.toString() + "\" xmlns:tns=\"http://" + namespace + ".aai.inventory/" + v.toString() + "\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\""
85 + "xmlns:jaxb=\"http://java.sun.com/xml/ns/jaxb\"" + LINE_SEPARATOR +
86 " jaxb:version=\"2.1\"" + LINE_SEPARATOR +
87 " xmlns:annox=\"http://annox.dev.java.net\"" + LINE_SEPARATOR +
88 " jaxb:extensionBindingPrefixes=\"annox\">" + DOUBLE_LINE_SEPARATOR);
90 sb.append("<xs:schema elementFormDefault=\"qualified\" version=\"1.0\" targetNamespace=\"http://" + namespace + ".aai.inventory/"
91 + v.toString() + "\" xmlns:tns=\"http://" + namespace + ".aai.inventory/" + v.toString() + "\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">" + DOUBLE_LINE_SEPARATOR);
97 public String process() throws ParserConfigurationException, SAXException, IOException, AAIException, FileNotFoundException, EdgeRuleNotFoundException {
98 StringBuilder sb = new StringBuilder();
102 } catch(Exception e) {
103 logger.error( "Error initializing " + this.getClass());
106 sb.append(getDocumentHeader());
107 StringBuilder sbInventory = new StringBuilder();
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) ) {
118 // will combine all matching java-types
119 elem = getJavaTypeElement(javaTypeName,false );
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;
126 throw new AAIException(msg);
128 if ("Nodes".equals(javaTypeName)) {
129 logger.debug("skipping Nodes entry (temporary feature)");
132 logger.debug(getXmlRootElementName(javaTypeName)+" vs "+ javaTypeName+":"+generatedJavaType.containsKey(getXmlRootElementName(javaTypeName)));
134 if ( !"Inventory".equals(javaTypeName)) {
135 generatedJavaType.put(javaTypeName, null);
137 sb.append(processJavaTypeElement( javaTypeName, javaTypeElement, sbInventory ));
139 sb.append(sbInventory);
140 sb.append(" </xs:sequence>" + LINE_SEPARATOR);
141 sb.append(" </xs:complexType>" + LINE_SEPARATOR);
142 sb.append(" </xs:element>" + LINE_SEPARATOR);
143 sb.append("</xs:schema>" + LINE_SEPARATOR);
144 return sb.toString();
147 protected boolean isValidName( String name ) {
148 if ( name == null || name.length() == 0 ) {
151 String pattern = "^[a-z0-9-]*$";
152 return name.matches(pattern);
155 protected boolean skipCheck( String javaAttribute ) {
156 if ( javaAttribute.equals("model")
157 || javaAttribute.equals("eventHeader") ) {
163 public String processJavaTypeElement( String javaTypeName, Element javaType_Element, StringBuilder sbInventory) {
164 String xmlRootElementName = getXMLRootElementName(javaType_Element);
166 NodeList parentNodes = javaType_Element.getElementsByTagName("java-attributes");
167 StringBuffer sb = new StringBuffer();
168 if ( parentNodes.getLength() == 0 ) {
169 logger.trace( "no java-attributes for java-type " + javaTypeName);
173 Element parentElement = (Element)parentNodes.item(0);
174 NodeList xmlElementNodes = parentElement.getElementsByTagName("xml-element");
175 // support for multiple inventory elements across oxm files
176 boolean processingInventory = false;
177 boolean hasPreviousInventory = false;
178 if ( "inventory".equals(xmlRootElementName) && sbInventory != null ) {
179 processingInventory = true;
180 if ( sbInventory.toString().contains("xs:complexType") ) {
181 hasPreviousInventory = true;
185 StringBuffer sb1 = new StringBuffer();
186 if ( xmlElementNodes.getLength() > 0 ) {
188 if ( !processingInventory || !hasPreviousInventory ) {
189 sb1.append(" <xs:element name=\"" + xmlRootElementName + "\">" + LINE_SEPARATOR);
190 sb1.append(" <xs:complexType>" + LINE_SEPARATOR);
192 XSDElement javaTypeElement = new XSDElement(javaType_Element, maxOccurs);
193 logger.debug("XSDElement name: "+javaTypeElement.name());
194 if(versionUsesAnnotations(v.toString())) {
195 sb1.append(javaTypeElement.getHTMLAnnotation("class", " "));
197 sb1.append(" <xs:sequence>" + LINE_SEPARATOR);
199 Element javatypeElement;
200 for ( int i = 0; i < xmlElementNodes.getLength(); ++i ) {
202 XSDElement xmlElementElement = new XSDElement((Element)xmlElementNodes.item(i), maxOccurs);
204 // String elementName = xmlElementElement.getAttribute("name");
205 String elementType = xmlElementElement.getAttribute("type");
206 //No simple types; only AAI custom types
207 String addType = elementType.contains("." + v.toString() + ".") ? elementType.substring(elementType.lastIndexOf('.')+1) : null;
208 if ( elementType.contains("." + v.toString() + ".") && !generatedJavaType.containsKey(addType) ) {
209 generatedJavaType.put(addType, elementType);
210 javatypeElement = getJavaTypeElement(addType, processingInventory);
211 sb.append(processJavaTypeElement( addType, javatypeElement, null ));
213 if ("Nodes".equals(addType)) {
214 logger.trace("Skipping nodes, temporary testing");
217 //assembles the basic <element>
218 sb1.append(xmlElementElement.getHTMLElement(v, versionUsesAnnotations(v.toString()), this));
220 if ( !processingInventory ) {
221 sb1.append(" </xs:sequence>" + LINE_SEPARATOR);
222 sb1.append(" </xs:complexType>" + LINE_SEPARATOR);
223 sb1.append(" </xs:element>" + LINE_SEPARATOR);
227 if ( xmlElementNodes.getLength() < 1 ) {
228 sb.append(" <xs:element name=\"" + xmlRootElementName + "\">" + LINE_SEPARATOR);
229 sb.append(" <xs:complexType>" + LINE_SEPARATOR);
230 sb.append(" <xs:sequence/>" + LINE_SEPARATOR);
231 sb.append(" </xs:complexType>" + LINE_SEPARATOR);
232 sb.append(" </xs:element>" + LINE_SEPARATOR);
233 generatedJavaType.put(javaTypeName, null);
234 return sb.toString();
236 if ( processingInventory && sbInventory != null ) {
237 sbInventory.append(sb1);
241 return sb.toString();
244 private Element getJavaTypeElement( String javaTypeName, boolean processingInventory )
246 String attrName, attrValue;
248 Element javaTypeElement;
250 List<Element> combineElementList = new ArrayList<Element>();
251 for ( int i = 0; i < javaTypeNodes.getLength(); ++ i ) {
252 javaTypeElement = (Element) javaTypeNodes.item(i);
253 NamedNodeMap attributes = javaTypeElement.getAttributes();
254 for ( int j = 0; j < attributes.getLength(); ++j ) {
255 attr = (Attr) attributes.item(j);
256 attrName = attr.getNodeName();
257 attrValue = attr.getNodeValue();
258 if ( attrName.equals("name") && attrValue.equals(javaTypeName)) {
259 if ( processingInventory ) {
260 return javaTypeElement;
262 combineElementList.add(javaTypeElement);
267 if ( combineElementList.size() == 0 ) {
268 logger.error( "oxm file format error, missing java-type " + javaTypeName);
269 return (Element) null;
270 } else if ( combineElementList.size() > 1 ) {
271 // need to combine java-attributes
272 return combineElements( javaTypeName, combineElementList);
274 return combineElementList.get(0);
278 private boolean versionUsesAnnotations( String version) {
279 int ver = new Integer(version.substring(1)).intValue();
280 if ( ver >= HTMLfromOXM.annotationsStartVersion ) {
283 if ( ver <= HTMLfromOXM.annotationsMinVersion ) {