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