Adding back-end support for UI filters
[aai/sparky-be.git] / src / main / java / org / onap / aai / sparky / config / oxm / OxmModelLoader.java
1 /**
2  * ============LICENSE_START=======================================================
3  * org.onap.aai
4  * ================================================================================
5  * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
6  * Copyright © 2017 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  * ECOMP is a trademark and service mark of AT&T Intellectual Property.
22  */
23 package org.onap.aai.sparky.config.oxm;
24
25 import java.io.File;
26 import java.io.FileInputStream;
27 import java.io.FileNotFoundException;
28 import java.io.IOException;
29 import java.io.InputStream;
30 import java.util.ArrayList;
31 import java.util.Arrays;
32 import java.util.HashMap;
33 import java.util.LinkedHashMap;
34 import java.util.List;
35 import java.util.Map;
36 import java.util.Map.Entry;
37 import java.util.Vector;
38 import java.util.regex.Matcher;
39 import java.util.regex.Pattern;
40
41 import org.eclipse.persistence.dynamic.DynamicType;
42 import org.eclipse.persistence.internal.oxm.mappings.Descriptor;
43 import org.eclipse.persistence.jaxb.JAXBContextProperties;
44 import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext;
45 import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContextFactory;
46 import org.eclipse.persistence.mappings.DatabaseMapping;
47 import org.onap.aai.sparky.logging.AaiUiMsgs;
48 import org.onap.aai.sparky.synchronizer.entity.SuggestionSearchEntity;
49 import org.onap.aai.sparky.viewandinspect.config.TierSupportUiConstants;
50 import org.onap.aai.cl.api.Logger;
51 import org.onap.aai.cl.eelf.LoggerFactory;
52
53 /**
54  * The Class OxmModelLoader.
55  */
56 public class OxmModelLoader {
57
58   private static OxmModelLoader instance;
59
60   private static final Logger LOG = LoggerFactory.getInstance().getLogger(OxmModelLoader.class);
61
62   private Map<String, HashMap<String, String>> oxmModel =
63       new LinkedHashMap<String, HashMap<String, String>>();
64
65   private Map<String, DynamicType> entityTypeLookup = new LinkedHashMap<String, DynamicType>();
66
67   private Map<String, HashMap<String, String>> searchableOxmModel =
68       new LinkedHashMap<String, HashMap<String, String>>();
69
70   private Map<String, HashMap<String, String>> crossReferenceEntityOxmModel =
71       new LinkedHashMap<String, HashMap<String, String>>();
72
73   private Map<String, HashMap<String, String>> geoEntityOxmModel =
74       new LinkedHashMap<String, HashMap<String, String>>();
75
76   private Map<String, HashMap<String, String>> suggestionSearchEntityOxmModel =
77       new LinkedHashMap<String, HashMap<String, String>>();
78
79   private Map<String, OxmEntityDescriptor> entityDescriptors =
80       new HashMap<String, OxmEntityDescriptor>();
81
82   private Map<String, OxmEntityDescriptor> searchableEntityDescriptors =
83       new HashMap<String, OxmEntityDescriptor>();
84
85   private Map<String, OxmEntityDescriptor> crossReferenceEntityDescriptors =
86       new HashMap<String, OxmEntityDescriptor>();
87
88   private Map<String, OxmEntityDescriptor> geoEntityDescriptors =
89       new HashMap<String, OxmEntityDescriptor>();
90
91   private Map<String, OxmEntityDescriptor> suggestionSearchEntityDescriptors =
92       new HashMap<String, OxmEntityDescriptor>();
93
94   public static OxmModelLoader getInstance() {
95     if (instance == null) {
96       instance = new OxmModelLoader();
97       LOG.info(AaiUiMsgs.INITIALIZE_OXM_MODEL_LOADER);
98       instance.loadModels();
99     }
100
101     return instance;
102
103   }
104
105   /**
106    * Instantiates a new oxm model loader.
107    */
108   public OxmModelLoader() {
109
110   }
111
112   /**
113    * Load models.
114    */
115   private void loadModels() {
116     // find latest version of OXM file in folder
117     String version = findLatestOxmVersion();
118     if (version == null) {
119       LOG.error(AaiUiMsgs.OXM_FILE_NOT_FOUND, TierSupportUiConstants.CONFIG_OXM_LOCATION);
120       return;
121     }
122
123     // load the latest version based on file name
124     loadModel(version);
125
126   }
127
128   /**
129    * Load model.
130    *
131    * @param version the version
132    */
133   public void loadModel(String version) {
134     String fileName = loadOxmFileName(version);
135
136     try (FileInputStream inputStream = new FileInputStream(new File(fileName))) {
137       Map<String, Object> properties = new HashMap<String, Object>();
138       properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, inputStream);
139
140       final DynamicJAXBContext oxmContext = DynamicJAXBContextFactory
141           .createContextFromOXM(Thread.currentThread().getContextClassLoader(), properties);
142       parseOxmContext(oxmContext);
143       // populateSearchableOxmModel();
144       LOG.info(AaiUiMsgs.OXM_LOAD_SUCCESS);
145
146     } catch (FileNotFoundException fnf) {
147       LOG.info(AaiUiMsgs.OXM_READ_ERROR_NONVERBOSE);
148       LOG.error(AaiUiMsgs.OXM_READ_ERROR_VERBOSE, fileName);
149     } catch (Exception exc) {
150       LOG.info(AaiUiMsgs.OXM_PARSE_ERROR_NONVERBOSE);
151       LOG.error(AaiUiMsgs.OXM_PARSE_ERROR_VERBOSE, fileName, exc.getMessage());
152     }
153   }
154
155   /**
156    * Parses the oxm context.
157    *
158    * @param oxmContext the oxm context
159    */
160   private void parseOxmContext(DynamicJAXBContext oxmContext) {
161     @SuppressWarnings("rawtypes")
162     List<Descriptor> descriptorsList = oxmContext.getXMLContext().getDescriptors();
163
164     for (@SuppressWarnings("rawtypes")
165     Descriptor desc : descriptorsList) {
166
167       DynamicType entity = oxmContext.getDynamicType(desc.getAlias());
168
169       LinkedHashMap<String, String> oxmProperties = new LinkedHashMap<String, String>();
170
171       // Not all fields have key attributes
172       if (desc.getPrimaryKeyFields() != null) {
173         oxmProperties.put("primaryKeyAttributeNames", desc.getPrimaryKeyFields().toString()
174             .replaceAll("/text\\(\\)", "").replaceAll("\\[", "").replaceAll("\\]", ""));
175       }
176
177       String entityName = desc.getDefaultRootElement();
178
179       entityTypeLookup.put(entityName, entity);
180
181       // add entityName
182       oxmProperties.put("entityName", entityName);
183
184       Map<String, String> properties = entity.getDescriptor().getProperties();
185       if (properties != null) {
186         for (Map.Entry<String, String> entry : properties.entrySet()) {
187
188           if (entry.getKey().equalsIgnoreCase("searchable")) {
189             oxmProperties.put("searchableAttributes", entry.getValue());
190           } else if (entry.getKey().equalsIgnoreCase("crossEntityReference")) {
191             oxmProperties.put("crossEntityReference", entry.getValue());
192           } else if (entry.getKey().equalsIgnoreCase("geoLat")) {
193             if (entry.getValue().length() > 0) {
194               oxmProperties.put("geoLat", entry.getValue());
195             }
196           } else if (entry.getKey().equalsIgnoreCase("geoLong")) {
197             if (entry.getValue().length() > 0) {
198               oxmProperties.put("geoLong", entry.getValue());
199             }
200           } else if (entry.getKey().equalsIgnoreCase("containsSuggestibleProps")) {
201
202             oxmProperties.put("containsSuggestibleProps", "true");
203
204             Vector<DatabaseMapping> descriptorMaps = entity.getDescriptor().getMappings();
205             List<String> listOfSuggestableAttributes = new ArrayList<String>();
206
207             for (DatabaseMapping descMap : descriptorMaps) {
208               if (descMap.isAbstractDirectMapping()) {
209
210                 if (descMap.getProperties().get("suggestibleOnSearch") != null) {
211                   String suggestableOnSearchString =
212                       String.valueOf(descMap.getProperties().get("suggestibleOnSearch"));
213
214                   boolean isSuggestibleOnSearch = Boolean.valueOf(suggestableOnSearchString);
215
216                   if (isSuggestibleOnSearch) {
217                     /* Grab attribute types for suggestion */
218                     String attributeName =
219                         descMap.getField().getName().replaceAll("/text\\(\\)", "");
220                     listOfSuggestableAttributes.add(attributeName);
221
222                     if (descMap.getProperties().get("suggestionVerbs") != null) {
223                       String suggestionVerbsString =
224                           String.valueOf(descMap.getProperties().get("suggestionVerbs"));
225
226                       oxmProperties.put("suggestionVerbs", suggestionVerbsString);
227                     }
228                   }
229                 }
230               }
231             }
232             if (!listOfSuggestableAttributes.isEmpty()) {
233               oxmProperties.put("suggestibleAttributes",
234                   String.join(",", listOfSuggestableAttributes));
235             }
236           } else if (entry.getKey().equalsIgnoreCase("suggestionAliases")) {
237             oxmProperties.put("suggestionAliases", entry.getValue());
238           }
239         }
240       }
241
242       oxmModel.put(entityName, oxmProperties);
243
244       // Add all searchable entity types for reserve lookup
245       if (oxmProperties.containsKey("searchableAttributes")) {
246         searchableOxmModel.put(entityName, oxmProperties);
247       }
248
249       if (oxmProperties.containsKey("crossEntityReference")) {
250         crossReferenceEntityOxmModel.put(entityName, oxmProperties);
251       }
252
253       if (oxmProperties.containsKey("geoLat") && oxmProperties.containsKey("geoLong")) {
254         geoEntityOxmModel.put(entityName, oxmProperties);
255       }
256
257       if (oxmProperties.containsKey("containsSuggestibleProps")) {
258         suggestionSearchEntityOxmModel.put(entityName, oxmProperties);
259       }
260     }
261
262     for (Entry<String, HashMap<String, String>> entityModel : oxmModel.entrySet()) {
263       HashMap<String, String> attribute = entityModel.getValue();
264       OxmEntityDescriptor entity = new OxmEntityDescriptor();
265       entity.setEntityName(attribute.get("entityName"));
266       if (attribute.containsKey("primaryKeyAttributeNames")) {
267
268         entity.setPrimaryKeyAttributeName(
269             Arrays.asList(attribute.get("primaryKeyAttributeNames").replace(" ", "").split(",")));
270         if (attribute.containsKey("searchableAttributes")) {
271           entity.setSearchableAttributes(
272               Arrays.asList(attribute.get("searchableAttributes").split(",")));
273         } else if (attribute.containsKey("crossEntityReference")) {
274           List<String> crossEntityRefTokens =
275               Arrays.asList(attribute.get("crossEntityReference").split(","));
276
277           if (crossEntityRefTokens.size() >= 2) {
278             CrossEntityReference entityRef = new CrossEntityReference();
279             entityRef.setTargetEntityType(crossEntityRefTokens.get(0));
280
281             for (int i = 1; i < crossEntityRefTokens.size(); i++) {
282               entityRef.addReferenceAttribute(crossEntityRefTokens.get(i));
283             }
284
285             entity.setCrossEntityReference(entityRef);
286           } else {
287             LOG.error(AaiUiMsgs.OXM_PROP_DEF_ERR_CROSS_ENTITY_REF, attribute.get("entityName"),
288                 attribute.get("crossEntityReference"));
289           }
290         }
291
292         if (attribute.containsKey("geoLat") || attribute.containsKey("geoLong")) {
293           entity.setGeoLatName(attribute.get("geoLat"));
294           entity.setGeoLongName(attribute.get("geoLong"));
295         }
296
297         if (attribute.containsKey("suggestionVerbs")) {
298           String entityName = attribute.get("entityName");
299           SuggestionSearchEntity suggestionSearchEntity = new SuggestionSearchEntity(this);
300           suggestionSearchEntity.setEntityType(entityName);
301
302           entity.setSuggestionSearchEntity(suggestionSearchEntity);
303         }
304
305         entityDescriptors.put(attribute.get("entityName"), entity);
306       }
307     }
308
309
310     for (Entry<String, HashMap<String, String>> searchableModel : searchableOxmModel.entrySet()) {
311       HashMap<String, String> attribute = searchableModel.getValue();
312       OxmEntityDescriptor entity = new OxmEntityDescriptor();
313       entity.setEntityName(attribute.get("entityName"));
314       entity.setPrimaryKeyAttributeName(
315           Arrays.asList(attribute.get("primaryKeyAttributeNames").replace(" ", "").split(",")));
316       entity
317           .setSearchableAttributes(Arrays.asList(attribute.get("searchableAttributes").split(",")));
318       searchableEntityDescriptors.put(attribute.get("entityName"), entity);
319     }
320
321     for (Entry<String, HashMap<String, String>> geoEntityModel : geoEntityOxmModel.entrySet()) {
322       HashMap<String, String> attribute = geoEntityModel.getValue();
323       OxmEntityDescriptor entity = new OxmEntityDescriptor();
324       entity.setEntityName(attribute.get("entityName"));
325       entity.setPrimaryKeyAttributeName(
326           Arrays.asList(attribute.get("primaryKeyAttributeNames").replace(" ", "").split(",")));
327       entity.setGeoLatName(attribute.get("geoLat"));
328       entity.setGeoLongName(attribute.get("geoLong"));
329       geoEntityDescriptors.put(attribute.get("entityName"), entity);
330     }
331
332     for (Entry<String, HashMap<String, String>> crossRefModel : crossReferenceEntityOxmModel
333         .entrySet()) {
334       HashMap<String, String> attribute = crossRefModel.getValue();
335       OxmEntityDescriptor entity = new OxmEntityDescriptor();
336       entity.setEntityName(attribute.get("entityName"));
337       entity.setPrimaryKeyAttributeName(
338           Arrays.asList(attribute.get("primaryKeyAttributeNames").replace(" ", "").split(",")));
339
340
341       List<String> crossEntityRefTokens =
342           Arrays.asList(attribute.get("crossEntityReference").split(","));
343
344       if (crossEntityRefTokens.size() >= 2) {
345         CrossEntityReference entityRef = new CrossEntityReference();
346         entityRef.setTargetEntityType(crossEntityRefTokens.get(0));
347
348         for (int i = 1; i < crossEntityRefTokens.size(); i++) {
349           entityRef.addReferenceAttribute(crossEntityRefTokens.get(i));
350         }
351
352         entity.setCrossEntityReference(entityRef);
353       }
354       crossReferenceEntityDescriptors.put(attribute.get("entityName"), entity);
355     }
356
357     for (Entry<String, HashMap<String, String>> suggestionEntityModel : suggestionSearchEntityOxmModel
358         .entrySet()) {
359       HashMap<String, String> attribute = suggestionEntityModel.getValue();
360
361       String entityName = attribute.get("entityName");
362       SuggestionSearchEntity suggestionSearchEntity = new SuggestionSearchEntity(this);
363       suggestionSearchEntity.setEntityType(entityName);
364
365       if (attribute.get("suggestionVerbs") != null) {
366         suggestionSearchEntity.setSuggestionConnectorWords(
367             Arrays.asList(attribute.get("suggestionVerbs").split(",")));
368       }
369
370       if (attribute.get("suggestionAliases") != null) {
371         suggestionSearchEntity
372             .setSuggestionAliases(Arrays.asList(attribute.get("suggestionAliases").split(",")));
373       }
374
375       if (attribute.get("suggestibleAttributes") != null) {
376         suggestionSearchEntity.setSuggestionPropertyTypes(
377             Arrays.asList(attribute.get("suggestibleAttributes").split(",")));
378       }
379
380       OxmEntityDescriptor entity = new OxmEntityDescriptor();
381       entity.setSuggestionSearchEntity(suggestionSearchEntity);
382       entity.setEntityName(entityName);
383
384       if (attribute.get("primaryKeyAttributeNames") != null) {
385         entity.setPrimaryKeyAttributeName(
386             Arrays.asList(attribute.get("primaryKeyAttributeNames").replace(" ", "").split(",")));
387       }
388
389       suggestionSearchEntityDescriptors.put(entityName, entity);
390     }
391   }
392
393   /**
394    * Find latest oxm version.
395    *
396    * @return the string
397    */
398   public String findLatestOxmVersion() {
399     File[] listOxmFiles = loadOxmFolder().listFiles();
400
401     if (listOxmFiles == null) {
402       return null;
403     }
404
405     Integer latestVersion = -1;
406
407     Pattern oxmFileNamePattern = Pattern.compile("^aai_oxm_v([0-9]*).xml");
408
409     for (File file : listOxmFiles) {
410       if (file.isFile()) {
411         String fileName = file.getName();
412         Matcher matcher = oxmFileNamePattern.matcher(fileName);
413         if (matcher.matches()) {
414           if (latestVersion <= Integer.parseInt(matcher.group(1))) {
415             latestVersion = Integer.parseInt(matcher.group(1));
416           }
417         }
418       }
419
420     }
421     if (latestVersion != -1) {
422       return "v" + latestVersion.toString();
423     } else {
424       return null;
425     }
426
427   }
428
429   /**
430    * Load oxm folder.
431    *
432    * @return the file
433    */
434   public File loadOxmFolder() {
435     return new File(TierSupportUiConstants.CONFIG_OXM_LOCATION);
436   }
437
438   /**
439    * Load oxm file name.
440    *
441    * @param version the version
442    * @return the string
443    */
444   public String loadOxmFileName(String version) {
445     return new String(TierSupportUiConstants.CONFIG_OXM_LOCATION + "aai_oxm_" + version + ".xml");
446   }
447
448   /*
449    * Get the original representation of the OXM Model
450    */
451   public Map<String, HashMap<String, String>> getOxmModel() {
452     return oxmModel;
453   }
454
455   /*
456    * Get the searchable raw map entity types
457    */
458   public Map<String, HashMap<String, String>> getSearchableOxmModel() {
459     return searchableOxmModel;
460   }
461
462   public Map<String, HashMap<String, String>> getCrossReferenceEntityOxmModel() {
463     return crossReferenceEntityOxmModel;
464   }
465
466   public Map<String, OxmEntityDescriptor> getEntityDescriptors() {
467     return entityDescriptors;
468   }
469
470   /**
471    * Gets the entity descriptor.
472    *
473    * @param type the type
474    * @return the entity descriptor
475    */
476   public OxmEntityDescriptor getEntityDescriptor(String type) {
477     return entityDescriptors.get(type);
478   }
479
480   public Map<String, OxmEntityDescriptor> getSearchableEntityDescriptors() {
481     return searchableEntityDescriptors;
482   }
483
484   /**
485    * Gets the searchable entity descriptor.
486    *
487    * @param entityType the entity type
488    * @return the searchable entity descriptor
489    */
490   public OxmEntityDescriptor getSearchableEntityDescriptor(String entityType) {
491     return searchableEntityDescriptors.get(entityType);
492   }
493
494   public Map<String, OxmEntityDescriptor> getCrossReferenceEntityDescriptors() {
495     return crossReferenceEntityDescriptors;
496   }
497
498   public Map<String, OxmEntityDescriptor> getGeoEntityDescriptors() {
499     return geoEntityDescriptors;
500   }
501
502   public Map<String, OxmEntityDescriptor> getSuggestionSearchEntityDescriptors() {
503     return suggestionSearchEntityDescriptors;
504   }
505
506 }