Adding UI extensibility
[aai/sparky-be.git] / src / main / java / org / onap / aai / sparky / sync / entity / SuggestionSearchEntity.java
  *
  * ECOMP is a trademark and service mark of AT&T Intellectual Property.
  */
-package org.onap.aai.sparky.synchronizer.entity;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ObjectNode;
+package org.onap.aai.sparky.sync.entity;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -34,117 +30,82 @@ import java.util.Map;
 
 import org.json.JSONArray;
 import org.json.JSONObject;
-import org.onap.aai.sparky.config.oxm.OxmModelLoader;
+import org.onap.aai.sparky.config.oxm.SuggestionEntityLookup;
+import org.onap.aai.sparky.search.filters.config.FiltersConfig;
+import org.onap.aai.sparky.search.filters.config.FiltersDetailsConfig;
+import org.onap.aai.sparky.search.filters.config.UiFilterConfig;
 import org.onap.aai.sparky.util.NodeUtils;
+import org.onap.aai.sparky.util.SuggestionsPermutation;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
 
 public class SuggestionSearchEntity extends IndexableEntity implements IndexDocument {
+  private static final String FILTER_ID = "filterId";
+  private static final String FILTER_VALUE = "filterValue";
+  private static final String FILTER_LIST = "filterList";
 
   private String entityType;
   private List<String> suggestionConnectorWords = new ArrayList<String>();
   private List<String> suggestionAttributeTypes = new ArrayList<String>();
-
-  /**
-   * @return the suggestionAttributeTypes
-   */
-  public List<String> getSuggestionAttributeTypes() {
-    return suggestionAttributeTypes;
-  }
-
-  /**
-   * @param suggestionAttributeTypes the suggestionAttributeTypes to set
-   */
-  public void setSuggestionAttributeTypes(List<String> suggestionAttributeTypes) {
-    this.suggestionAttributeTypes = suggestionAttributeTypes;
-  }
-
-  /**
-   * @return the suggestionTypeAliases
-   */
-  public List<String> getSuggestionTypeAliases() {
-    return suggestionTypeAliases;
-  }
-
-  /**
-   * @param suggestionTypeAliases the suggestionTypeAliases to set
-   */
-  public void setSuggestionTypeAliases(List<String> suggestionTypeAliases) {
-    this.suggestionTypeAliases = suggestionTypeAliases;
-  }
-
-  /**
-   * @return the suggestableAttr
-   */
-  public List<String> getSuggestableAttr() {
-    return suggestableAttr;
-  }
-
-  /**
-   * @param suggestableAttr the suggestableAttr to set
-   */
-  public void setSuggestableAttr(List<String> suggestableAttr) {
-    this.suggestableAttr = suggestableAttr;
-  }
-
-  /**
-   * @return the outputString
-   */
-  public StringBuffer getOutputString() {
-    return outputString;
-  }
-
-  /**
-   * @param outputString the outputString to set
-   */
-  public void setOutputString(StringBuffer outputString) {
-    this.outputString = outputString;
-  }
-
-  /**
-   * @return the mapper
-   */
-  public ObjectMapper getMapper() {
-    return mapper;
-  }
-
-  /**
-   * @param mapper the mapper to set
-   */
-  public void setMapper(ObjectMapper mapper) {
-    this.mapper = mapper;
-  }
-
-
   private List<String> suggestionAttributeValues = new ArrayList<String>();
   private List<String> suggestionTypeAliases = new ArrayList<String>();
   private List<String> suggestionInputPermutations = new ArrayList<String>();
   private List<String> suggestableAttr = new ArrayList<String>();
-  private Map<String, String> payload = new HashMap<String, String>();
-  private JSONObject payloadJsonNode = new JSONObject();
+
+  private Map<String, String> inputOutputData = new HashMap<String, String>();
+  Map<String, UiFilterConfig> filters = new HashMap<String, UiFilterConfig>();
+  private JSONObject payload = new JSONObject();
+  private JSONArray payloadFilters = new JSONArray();
   private StringBuffer outputString = new StringBuffer();
   private String aliasToUse;
 
-  public Map<String, String> getPayload() {
+  private SuggestionEntityLookup entityLookup;
+
+  public JSONObject getPayload() {
     return payload;
   }
 
-  public void setPayload(Map<String, String> payload) {
+  public void setPayload(JSONObject payload) {
     this.payload = payload;
   }
 
+  protected ObjectMapper mapper = new ObjectMapper();
 
-  public JSONObject getPayloadJsonNode() {
-    return payloadJsonNode;
-  }
+  public SuggestionSearchEntity() {
+    super();
 
-  public void setPayloadJsonNode(JSONObject payloadJsonNode) {
-    this.payloadJsonNode = payloadJsonNode;
+    FiltersDetailsConfig filterConfigList = FiltersConfig.getInstance().getFiltersConfig();
+    // Populate the map with keys that will match the suggestableAttr values
+    for (UiFilterConfig filter : filterConfigList.getFilters()) {
+      if (filter.getDataSource() != null) {
+        filters.put(filter.getDataSource().getFieldName(), filter);
+      }
+    }
   }
 
+  public SuggestionSearchEntity(SuggestionEntityLookup entityLookup) {
 
-  protected ObjectMapper mapper = new ObjectMapper();
+    this.entityLookup = entityLookup;
 
-  public SuggestionSearchEntity() {
-    super();
+    FiltersDetailsConfig filterConfigList = FiltersConfig.getInstance().getFiltersConfig();
+    // Populate the map with keys that will match the suggestableAttr values
+    for (UiFilterConfig filter : filterConfigList.getFilters()) {
+      if (filter.getDataSource() != null) {
+        filters.put(filter.getDataSource().getFieldName(), filter);
+      }
+    }
+  }
+
+  public SuggestionSearchEntity(SuggestionEntityLookup entityLookup, FiltersConfig config) {
+
+    FiltersDetailsConfig filterConfigList = config.getFiltersConfig();
+    // Populate the map with keys that will match the suggestableAttr values
+    for (UiFilterConfig filter : filterConfigList.getFilters()) {
+      if (filter.getDataSource() != null) {
+        filters.put(filter.getDataSource().getFieldName(), filter);
+      }
+    }
   }
 
   public void setSuggestableAttr(ArrayList<String> attributes) {
@@ -154,20 +115,67 @@ public class SuggestionSearchEntity extends IndexableEntity implements IndexDocu
   }
 
   public void setPayloadFromResponse(JsonNode node) {
-    Map<String, String> nodePayload = new HashMap<String, String>();
     if (suggestableAttr != null) {
+      JSONObject nodePayload = new JSONObject();
       for (String attribute : suggestableAttr) {
         if (node.get(attribute) != null) {
-          nodePayload.put(attribute, node.get(attribute).asText());
+          inputOutputData.put(attribute, node.get(attribute).asText());
+          this.payload.put(attribute, node.get(attribute).asText());
         }
       }
-      this.setPayload(nodePayload);
     }
   }
 
+  public void setFilterBasedPayloadFromResponse(JsonNode node, String entityName,
+      ArrayList<String> uniqueList) {
+
+    HashMap<String, String> desc = entityLookup.getSuggestionSearchEntityOxmModel().get(entityName);
+
+    if (desc == null) {
+      return;
+    }
+
+    String attr = desc.get("suggestibleAttributes");
+
+    if (attr == null) {
+      return;
+    }
+
+    List<String> suggestableAttrOxm = Arrays.asList(attr.split(","));
 
-  public SuggestionSearchEntity(OxmModelLoader loader) {
-    super(loader);
+    /*
+     * Note: (1) 'uniqueList' is one item within the power set of the suggestable attributes. (2)
+     * 'inputeOutputData' is used to generate permutations of strings
+     */
+    for (String selectiveAttr : uniqueList) {
+      if (node.get(selectiveAttr) != null) {
+        inputOutputData.put(selectiveAttr, node.get(selectiveAttr).asText());
+      }
+    }
+
+    if (suggestableAttrOxm != null) {
+      for (String attribute : suggestableAttrOxm) {
+        if (node.get(attribute) != null && uniqueList.contains(attribute)) {
+          UiFilterConfig filterConfig = filters.get(attribute);
+          if (filterConfig != null) {
+            JSONObject filterPayload = new JSONObject();
+            filterPayload.put(FILTER_ID, filterConfig.getFilterId());
+            filterPayload.put(FILTER_VALUE, node.get(attribute).asText());
+            this.payloadFilters.put(filterPayload);
+          } else {
+            this.payload.put(attribute, node.get(attribute).asText());
+          }
+        } else {
+          UiFilterConfig emptyValueFilterConfig = filters.get(attribute);
+          if (emptyValueFilterConfig != null) {
+            JSONObject emptyValueFilterPayload = new JSONObject();
+            emptyValueFilterPayload.put(FILTER_ID, emptyValueFilterConfig.getFilterId());
+            this.payloadFilters.put(emptyValueFilterPayload);
+          }
+        }
+      }
+      this.payload.put(FILTER_LIST, this.payloadFilters);
+    }
   }
 
   @Override
@@ -222,10 +230,10 @@ public class SuggestionSearchEntity extends IndexableEntity implements IndexDocu
 
   public void generateSuggestionInputPermutations() {
 
-
     List<String> entityNames = new ArrayList<>();
     entityNames.add(entityType);
-    HashMap<String, String> desc = loader.getOxmModel().get(this.entityType);
+    HashMap<String, String> desc =
+        entityLookup.getSuggestionSearchEntityOxmModel().get(this.entityType);
     String attr = desc.get("suggestionAliases");
     String[] suggestionAliasesArray = attr.split(",");
     suggestionTypeAliases = Arrays.asList(suggestionAliasesArray);
@@ -233,72 +241,39 @@ public class SuggestionSearchEntity extends IndexableEntity implements IndexDocu
     for (String alias : suggestionTypeAliases) {
       entityNames.add(alias);
     }
-    ArrayList<String> listOfSearchSuggestionPermutations = new ArrayList<>();
 
-    ArrayList<String> listToPermutate = new ArrayList<>(payload.values());
-
-    for (String entityName : entityNames) {
-      listToPermutate.add(entityName);
-      permutateList(listToPermutate, new ArrayList<String>(), listToPermutate.size(),
-          listOfSearchSuggestionPermutations);
-      listToPermutate.remove(entityName);
-    }
-    suggestionInputPermutations = listOfSearchSuggestionPermutations;
-  }
+    ArrayList<String> listToPermutate = new ArrayList<>(inputOutputData.values());
 
-  /**
-   * Generate all permutations of a list of Strings
-   * 
-   * @param list
-   * @param permutation
-   * @param size
-   */
-  private void permutateList(List<String> list, List<String> permutation, int size,
-      List<String> listOfSearchSuggestionPermutationList) {
-    if (permutation.size() == size) {
-      StringBuilder newPermutation = new StringBuilder();
-
-      for (int i = 0; i < permutation.size(); i++) {
-        newPermutation.append(permutation.get(i)).append(" ");
+    for (String entity : entityNames) {
+      listToPermutate.add(entity); // add entity-name or alias in list to permutate
+      List<List<String>> lists = SuggestionsPermutation.getListPermutations(listToPermutate);
+      for (List<String> li : lists) {
+        suggestionInputPermutations.add(String.join(" ", li));
       }
-
-      listOfSearchSuggestionPermutationList.add(newPermutation.toString().trim());
-
-      return;
-    }
-
-    String[] availableItems = list.toArray(new String[0]);
-
-    for (String i : availableItems) {
-      permutation.add(i);
-      list.remove(i);
-      permutateList(list, permutation, size, listOfSearchSuggestionPermutationList);
-      list.add(i);
-      permutation.remove(i);
+      // prepare for the next pass: remove the entity-name or alias from the list
+      listToPermutate.remove(entity);
     }
   }
 
   public boolean isSuggestableDoc() {
-    return this.getPayload().size() != 0;
+    return this.getPayload().length() != 0;
   }
 
 
   @Override
   public void deriveFields() {
 
-    int payloadEntryCounter = 1;
-    for (Map.Entry<String, String> payload : getPayload().entrySet()) {
-      // Add the payload(status) only if a valid value is present
-      if (payload.getValue() != null && payload.getValue().length() > 0) {
-        this.getPayloadJsonNode().put(payload.getKey(), payload.getValue());
-        this.outputString.append(payload.getValue());
-        if (payloadEntryCounter < getPayload().entrySet().size()) {
+    int entryCounter = 1;
+    for (Map.Entry<String, String> outputValue : inputOutputData.entrySet()) {
+      if (outputValue.getValue() != null && outputValue.getValue().length() > 0) {
+        this.outputString.append(outputValue.getValue());
+        if (entryCounter < inputOutputData.entrySet().size()) {
           this.outputString.append(" and ");
         } else {
           this.outputString.append(" ");
         }
       }
-      payloadEntryCounter++;
+      entryCounter++;
     }
 
     this.outputString.append(this.getAliasToUse());
@@ -306,7 +281,7 @@ public class SuggestionSearchEntity extends IndexableEntity implements IndexDocu
   }
 
   @Override
-  public String getIndexDocumentJson() {
+  public String getAsJson() {
     // TODO Auto-generated method stub
     JSONObject rootNode = new JSONObject();
 
@@ -319,18 +294,12 @@ public class SuggestionSearchEntity extends IndexableEntity implements IndexDocu
 
     entitySuggest.put("input", suggestionsArray);
     entitySuggest.put("output", this.outputString);
-    entitySuggest.put("payload", this.payloadJsonNode);
+    entitySuggest.put("payload", this.payload);
     rootNode.put("entity_suggest", entitySuggest);
 
     return rootNode.toString();
   }
 
-  @Override
-  public ObjectNode getBulkImportEntity() {
-    // TODO Auto-generated method stub
-    return null;
-  }
-
   public String getAliasToUse() {
     return aliasToUse;
   }
@@ -339,6 +308,14 @@ public class SuggestionSearchEntity extends IndexableEntity implements IndexDocu
     this.aliasToUse = aliasToUse;
   }
 
+  public Map<String, String> getInputOutputData() {
+    return inputOutputData;
+  }
+
+  public void setInputOutputData(Map<String, String> inputOutputData) {
+    this.inputOutputData = inputOutputData;
+  }
+
   @Override
   public String toString() {
     return "SuggestionSearchEntity [entityType=" + entityType + ", suggestionConnectorWords="