Merge "[AAI] Fix doc config files"
[aai/aai-common.git] / aai-schema-abstraction / src / main / java / org / onap / aai / schemaif / oxm / OxmSchemaLoader.java
1 /**
2  * ============LICENSE_START=======================================================
3  * org.onap.aai
4  * ================================================================================
5  * Copyright © 2019 AT&T Intellectual Property. All rights reserved.
6  * Copyright © 2019 Amdocs
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
22 package org.onap.aai.schemaif.oxm;
23
24 import java.io.IOException;
25 import java.util.ArrayList;
26 import java.util.HashMap;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.concurrent.ConcurrentHashMap;
30 import java.util.regex.Matcher;
31 import java.util.regex.Pattern;
32
33 import org.eclipse.persistence.dynamic.DynamicType;
34 import org.eclipse.persistence.internal.oxm.mappings.Descriptor;
35 import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext;
36 import org.onap.aai.cl.eelf.LoggerFactory;
37 import org.onap.aai.nodes.NodeIngestor;
38 import org.onap.aai.schemaif.SchemaProviderException;
39 import org.onap.aai.schemaif.SchemaProviderMsgs;
40 import org.onap.aai.schemaif.definitions.VertexSchema;
41 import org.onap.aai.setup.SchemaVersion;
42 import org.onap.aai.setup.Translator;
43 import org.springframework.beans.factory.annotation.Autowired;
44 import org.springframework.stereotype.Component;
45
46 /**
47  * This class contains all of the logic for importing OXM model schemas from the available OXM
48  * schema files.
49  */
50 @Component
51 public class OxmSchemaLoader {
52
53     private static Translator translator;
54     private static NodeIngestor nodeIngestor;
55
56     private static Map<String, DynamicJAXBContext> versionContextMap = new ConcurrentHashMap<>();
57     private static Map<String, HashMap<String, DynamicType>> xmlElementLookup = new ConcurrentHashMap<>();
58     private static Map<String, HashMap<String, VertexSchema>> vertexLookup = new ConcurrentHashMap<>();
59
60     final static Pattern versionPattern = Pattern.compile("(?i)v(\\d*)");
61
62     private static org.onap.aai.cl.api.Logger logger =
63             LoggerFactory.getInstance().getLogger(OxmSchemaLoader.class.getName());
64
65     private OxmSchemaLoader() {
66     }
67
68     /**
69      * This constructor presents an awkward marrying of Spring bean creation and static method use. This
70      * is technical debt that will need fixing.
71      *
72      * @param translator contains schema versions configuration
73      * @param nodeIngestor provides DynamicJAXBContext for the OXM version
74      */
75     @Autowired
76     public OxmSchemaLoader(Translator translator, NodeIngestor nodeIngestor) {
77         OxmSchemaLoader.translator = translator;
78         OxmSchemaLoader.nodeIngestor = nodeIngestor;
79     }
80
81     /**
82      * Finds all OXM model files
83      *
84      * @throws SchemaProviderException
85      * @throws IOException
86      *
87      */
88     public synchronized static void loadModels() throws SchemaProviderException {
89         if (logger.isDebugEnabled()) {
90             logger.debug("Loading OXM Models");
91         }
92
93         for (SchemaVersion oxmVersion : translator.getSchemaVersions().getVersions()) {
94             DynamicJAXBContext jaxbContext = nodeIngestor.getContextForVersion(oxmVersion);
95             if (jaxbContext != null) {
96                 loadModel(oxmVersion.toString(), jaxbContext);
97             }
98         }
99     }
100
101     private synchronized static void loadModel(String oxmVersion, DynamicJAXBContext jaxbContext) {
102         versionContextMap.put(oxmVersion, jaxbContext);
103         loadXmlLookupMap(oxmVersion, jaxbContext);
104         loadVertexLookupMap(oxmVersion, jaxbContext);
105         logger.info(SchemaProviderMsgs.LOADED_SCHEMA_FILE, oxmVersion);
106     }
107
108     /**
109      * Retrieves the JAXB context for the specified OXM model version.
110      *
111      * @param version - The OXM version that we want the JAXB context for.
112      *
113      * @return - A JAXB context derived from the OXM model schema.
114      *
115      * @throws SchemaProviderException
116      */
117     public static DynamicJAXBContext getContextForVersion(String version) throws SchemaProviderException {
118
119         // If we haven't already loaded in the available OXM models, then do so now.
120         if (versionContextMap == null || versionContextMap.isEmpty()) {
121             loadModels();
122         } else if (!versionContextMap.containsKey(version)) {
123             throw new SchemaProviderException("Error loading oxm model: " + version);
124         }
125
126         return versionContextMap.get(version);
127     }
128
129     public static String getLatestVersion() throws SchemaProviderException {
130
131         // If we haven't already loaded in the available OXM models, then do so now.
132         if (versionContextMap == null || versionContextMap.isEmpty()) {
133             loadModels();
134         }
135
136         // If there are still no models available, then there's not much we can do...
137         if (versionContextMap.isEmpty()) {
138             throw new SchemaProviderException("No available OXM schemas to get latest version for.");
139         }
140
141         // Iterate over the available model versions to determine which is the most
142         // recent.
143         Integer latestVersion = null;
144         String latestVersionStr = null;
145         for (String versionKey : versionContextMap.keySet()) {
146
147             Matcher matcher = versionPattern.matcher(versionKey);
148             if (matcher.find()) {
149
150                 int currentVersion = Integer.valueOf(matcher.group(1));
151
152                 if ((latestVersion == null) || (currentVersion > latestVersion)) {
153                     latestVersion = currentVersion;
154                     latestVersionStr = versionKey;
155                 }
156             }
157         }
158
159         return latestVersionStr;
160     }
161
162     private static void loadXmlLookupMap(String version, DynamicJAXBContext jaxbContext) {
163
164         @SuppressWarnings("rawtypes")
165         List<Descriptor> descriptorsList = jaxbContext.getXMLContext().getDescriptors();
166         HashMap<String, DynamicType> types = new HashMap<String, DynamicType>();
167
168         for (@SuppressWarnings("rawtypes")
169         Descriptor desc : descriptorsList) {
170
171             DynamicType entity = jaxbContext.getDynamicType(desc.getAlias());
172             String entityName = desc.getDefaultRootElement();
173             types.put(entityName, entity);
174         }
175         xmlElementLookup.put(version, types);
176     }
177
178     private static void loadVertexLookupMap(String version, DynamicJAXBContext jaxbContext) {
179
180         @SuppressWarnings("rawtypes")
181         List<Descriptor> descriptorsList = jaxbContext.getXMLContext().getDescriptors();
182         HashMap<String, VertexSchema> vertexMap = new HashMap<String, VertexSchema>();
183
184         for (@SuppressWarnings("rawtypes")
185         Descriptor desc : descriptorsList) {
186             try {
187                 FromOxmVertexSchema vs = new FromOxmVertexSchema();
188                 vs.fromOxm(desc.getDefaultRootElement(), jaxbContext, getXmlLookupMap(version));
189                 vertexMap.put(vs.getName(), vs);
190             } catch (SchemaProviderException e) {
191                 continue;
192             }
193         }
194         vertexLookup.put(version, vertexMap);
195     }
196
197     /**
198      * Retrieves the list of all Loaded OXM versions.
199      *
200      * @return - A List of Strings of all loaded OXM versions.
201      *
202      * @throws SpikeException
203      */
204     public static List<String> getLoadedOXMVersions() throws SchemaProviderException {
205         // If we haven't already loaded in the available OXM models, then do so now.
206         if (versionContextMap == null || versionContextMap.isEmpty()) {
207             loadModels();
208         }
209         // If there are still no models available, then there's not much we can do...
210         if (versionContextMap.isEmpty()) {
211             logger.error(SchemaProviderMsgs.SCHEMA_LOAD_ERROR, "No available OXM schemas to get versions for.");
212             throw new SchemaProviderException("No available OXM schemas to get latest version for.");
213         }
214         List<String> versions = new ArrayList<String>();
215         for (String versionKey : versionContextMap.keySet()) {
216             Matcher matcher = versionPattern.matcher(versionKey);
217             if (matcher.find()) {
218                 versions.add("V" + matcher.group(1));
219             }
220         }
221         return versions;
222     }
223
224     public static HashMap<String, DynamicType> getXmlLookupMap(String version) {
225         return xmlElementLookup.get(version);
226     }
227
228     public static HashMap<String, VertexSchema> getVertexLookupForVersion(String version)
229             throws SchemaProviderException {
230         // If we haven't already loaded in the available OXM models, then do so now.
231         if (vertexLookup == null || vertexLookup.isEmpty()) {
232             loadModels();
233         } else if (!vertexLookup.containsKey(version)) {
234             throw new SchemaProviderException("Error loading oxm model: " + version);
235         }
236         return vertexLookup.get(version);
237     }
238
239 }