948914c06314ee67600a89f1d531546346373fff
[aai/gizmo.git] / src / main / java / org / onap / schema / OxmModelLoader.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 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 package org.onap.schema;
22
23 import java.io.IOException;
24 import java.util.ArrayList;
25 import java.util.HashMap;
26 import java.util.LinkedHashMap;
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 javax.ws.rs.core.Response.Status;
34
35 import org.eclipse.persistence.dynamic.DynamicType;
36 import org.eclipse.persistence.internal.oxm.mappings.Descriptor;
37 import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext;
38 import org.onap.aai.cl.eelf.LoggerFactory;
39 import org.onap.aai.nodes.NodeIngestor;
40 import org.onap.aai.setup.ConfigTranslator;
41 import org.onap.aai.setup.SchemaLocationsBean;
42 import org.onap.aai.setup.Version;
43 import org.onap.crud.exception.CrudException;
44 import org.onap.crud.logging.CrudServiceMsgs;
45 import org.onap.schema.util.SchemaIngestPropertyReader;
46
47 import com.google.common.base.CaseFormat;
48
49 public class OxmModelLoader {
50
51     private static Map<String, DynamicJAXBContext> versionContextMap =
52             new ConcurrentHashMap<>();
53     
54     private static Map<String, HashMap<String, DynamicType>> xmlElementLookup = new ConcurrentHashMap<String, HashMap<String, DynamicType>>();
55
56     static final Pattern p = Pattern.compile("aai_oxm_(.*).xml");
57     static final Pattern versionPattern = Pattern.compile("V(\\d*)");
58
59     private static org.onap.aai.cl.api.Logger logger =
60             LoggerFactory.getInstance().getLogger(OxmModelLoader.class.getName());
61
62     private OxmModelLoader() {
63     }
64
65     /**
66      * Finds all OXM model files
67      *
68      * @throws SpikeException
69      * @throws IOException
70      *
71      */
72     public static synchronized void loadModels() throws CrudException {
73         SchemaIngestPropertyReader schemaIngestPropertyReader = new SchemaIngestPropertyReader();
74
75         SchemaLocationsBean schemaLocationsBean = new SchemaLocationsBean();
76         schemaLocationsBean.setNodeDirectory(schemaIngestPropertyReader.getNodeDir());
77         ConfigTranslator configTranslator = new OxmModelConfigTranslator(schemaLocationsBean);
78         NodeIngestor nodeIngestor = new NodeIngestor(configTranslator);
79
80         if (logger.isDebugEnabled()) {
81             logger.debug("Loading OXM Models");
82         }
83
84         for (Version oxmVersion : Version.values()) {
85             DynamicJAXBContext jaxbContext = nodeIngestor.getContextForVersion(oxmVersion);
86             if (jaxbContext != null) {
87                 loadModel(oxmVersion.toString().toLowerCase(), jaxbContext);
88             }
89         }
90     }
91
92
93     private static synchronized void loadModel(String oxmVersion, DynamicJAXBContext jaxbContext) {
94         versionContextMap.put(oxmVersion, jaxbContext);
95         loadXmlLookupMap(oxmVersion, jaxbContext);
96         logger.info(CrudServiceMsgs.LOADED_OXM_FILE, oxmVersion);
97     }
98
99     /**
100      * Retrieves the JAXB context for the specified OXM model version.
101      *
102      * @param version - The OXM version that we want the JAXB context for.
103      *
104      * @return - A JAXB context derived from the OXM model schema.
105      *
106      * @throws SpikeException
107      */
108     public static DynamicJAXBContext getContextForVersion(String version) throws CrudException {
109
110         // If we haven't already loaded in the available OXM models, then do so now.
111         if (versionContextMap == null || versionContextMap.isEmpty()) {
112             loadModels();
113         } else if (!versionContextMap.containsKey(version)) {
114                         logger.error(CrudServiceMsgs.OXM_LOAD_ERROR, "Error loading oxm model: " + version);
115             throw new CrudException("Error loading oxm model: " + version, Status.INTERNAL_SERVER_ERROR);
116         }
117
118         return versionContextMap.get(version);
119     }
120
121     public static String getLatestVersion() throws CrudException {
122
123         // If we haven't already loaded in the available OXM models, then do so now.
124         if (versionContextMap == null || versionContextMap.isEmpty()) {
125             loadModels();
126         }
127
128         // If there are still no models available, then there's not much we can do...
129         if (versionContextMap.isEmpty()) {
130                         logger.error(CrudServiceMsgs.OXM_LOAD_ERROR, "No available OXM schemas to get latest version for.");
131             throw new CrudException("No available OXM schemas to get latest version for.",
132                     Status.INTERNAL_SERVER_ERROR);
133         }
134
135         // Iterate over the available model versions to determine which is the most
136         // recent.
137         Integer latestVersion = null;
138         String latestVersionStr = null;
139         for (String versionKey : versionContextMap.keySet()) {
140
141             Matcher matcher = versionPattern.matcher(versionKey.toUpperCase());
142             if (matcher.find()) {
143
144                 int currentVersion = Integer.parseInt(matcher.group(1));
145
146                 if ((latestVersion == null) || (currentVersion > latestVersion)) {
147                     latestVersion = currentVersion;
148                     latestVersionStr = versionKey;
149                 }
150             }
151         }
152
153         return latestVersionStr;
154     }
155
156     /**
157      * Retrieves the list of all Loaded OXM versions.
158      *
159      * @return - A List of Strings of all loaded OXM versions.
160      *
161      * @throws CrudException
162      */
163     public static List<String> getLoadedOXMVersions() throws CrudException {
164
165         // If we haven't already loaded in the available OXM models, then do so now.
166         if (versionContextMap == null || versionContextMap.isEmpty()) {
167             loadModels();
168         }
169
170         // If there are still no models available, then there's not much we can do...
171         if (versionContextMap.isEmpty()) {
172             logger.error(CrudServiceMsgs.OXM_LOAD_ERROR, "No available OXM schemas to get versions for.");
173             throw new CrudException("No available OXM schemas to get versions for.",
174                     Status.INTERNAL_SERVER_ERROR);
175         }
176
177         List<String> versions = new ArrayList<String> ();
178         for (String versionKey : versionContextMap.keySet()) {
179
180             Matcher matcher = versionPattern.matcher(versionKey.toUpperCase());
181             if (matcher.find()) {
182                 versions.add ( "V" + matcher.group ( 1 ) );
183             }
184         }
185         return versions;
186     }
187
188     /**
189      * Retrieves the map of all JAXB context objects that have been created by importing the
190      * available OXM model schemas.
191      *
192      * @return - Map of JAXB context objects.
193      */
194     public static Map<String, DynamicJAXBContext> getVersionContextMap() {
195         return versionContextMap;
196     }
197
198     /**
199      * Assigns the map of all JAXB context objects.
200      *
201      * @param versionContextMap
202      */
203     public static void setVersionContextMap(Map<String, DynamicJAXBContext> versionContextMap) {
204         OxmModelLoader.versionContextMap = versionContextMap;
205     }
206     
207    
208     public static void loadXmlLookupMap(String version, DynamicJAXBContext jaxbContext )  {
209       
210       @SuppressWarnings("rawtypes")
211       List<Descriptor> descriptorsList = jaxbContext.getXMLContext().getDescriptors();     
212       HashMap<String,DynamicType> types = new HashMap<String,DynamicType>();
213
214       for (@SuppressWarnings("rawtypes")
215       Descriptor desc : descriptorsList) {
216
217         DynamicType entity = jaxbContext.getDynamicType(desc.getAlias());
218         String entityName = desc.getDefaultRootElement();
219         types.put(entityName, entity);
220       }
221       xmlElementLookup.put(version, types);
222     }
223     
224     
225   public static DynamicType getDynamicTypeForVersion(String version, String type) throws CrudException {
226
227     DynamicType dynamicType;
228     // If we haven't already loaded in the available OXM models, then do so now.
229     if (versionContextMap == null || versionContextMap.isEmpty()) {
230       loadModels();
231     } else if (!versionContextMap.containsKey(version)) {
232       logger.error(CrudServiceMsgs.OXM_LOAD_ERROR, "Error loading oxm model: " + version);
233       throw new CrudException("Error loading oxm model: " + version, Status.INTERNAL_SERVER_ERROR);
234     }
235
236     // First try to match the Java-type based on hyphen to camel case translation
237     String javaTypeName = CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_CAMEL, type);
238     dynamicType = versionContextMap.get(version).getDynamicType(javaTypeName);
239
240     //Attempt to lookup in xml elements
241     if (xmlElementLookup.containsKey(version)) {
242       if (dynamicType == null) {
243         // Try to lookup by xml root element by exact match
244         dynamicType = xmlElementLookup.get(version).get(type);
245       }
246
247       if (dynamicType == null) {
248         // Try to lookup by xml root element by lowercase
249         dynamicType = xmlElementLookup.get(version).get(type.toLowerCase());
250       }
251
252       if (dynamicType == null) {
253         // Direct lookup as java-type name
254         dynamicType = versionContextMap.get(version).getDynamicType(type);
255       }
256     }
257
258     return dynamicType;
259
260   }
261 }