/src/main/java/com/dionetechnology/jira/plugins/multicascadeselect/searcher/indexer/MultiCascadeSelectIndexer.java

https://bitbucket.org/ram_tandukar/multi-cascade-select · Java · 171 lines · 109 code · 36 blank · 26 comment · 23 complexity · 895f5e3c8d7c4f8214dabd80ca0619bd MD5 · raw file

  1. package com.dionetechnology.jira.plugins.multicascadeselect.searcher.indexer;
  2. import static com.atlassian.jira.util.dbc.Assertions.notNull;
  3. import java.util.HashMap;
  4. import java.util.Map;
  5. import org.apache.log4j.Logger;
  6. import org.apache.lucene.document.Document;
  7. import org.apache.lucene.document.Field;
  8. import com.atlassian.jira.component.ComponentAccessor;
  9. import com.atlassian.jira.issue.Issue;
  10. import com.atlassian.jira.issue.customfields.converters.SelectConverter;
  11. import com.atlassian.jira.issue.customfields.option.Option;
  12. import com.atlassian.jira.issue.fields.CustomField;
  13. import com.atlassian.jira.issue.index.indexers.impl.AbstractCustomFieldIndexer;
  14. import com.atlassian.jira.jql.util.JqlSelectOptionsUtil;
  15. import com.atlassian.jira.util.NonInjectableComponent;
  16. import com.atlassian.jira.web.FieldVisibilityManager;
  17. import com.dionetechnology.jira.plugins.multicascadeselect.ao.MultiCSCFEntity;
  18. import com.dionetechnology.jira.plugins.multicascadeselect.ao.MultiCascadeSelectService;
  19. import com.dionetechnology.jira.plugins.multicascadeselect.type.MultiCascadeSelectCFType;
  20. /**
  21. * A custom field indexer for the multi level cascading select custom fields.
  22. * This class indexes the options saved for each multi level cascading entry in
  23. * each multilevel cascading select custom field.
  24. *
  25. * Forked from https://github.com/sourcesense/jira-multi-level-cascade-select
  26. */
  27. @NonInjectableComponent
  28. public class MultiCascadeSelectIndexer extends AbstractCustomFieldIndexer {
  29. private static final Logger log = Logger.getLogger(MultiCascadeSelectIndexer.class);
  30. private final CustomField customField;
  31. private final MultiCascadeSelectService multiCascadeSelectService;
  32. public MultiCascadeSelectIndexer(final FieldVisibilityManager fieldVisibilityManager, final CustomField customField, JqlSelectOptionsUtil jqlSelectOptionsUtil, SelectConverter selectConverter) {
  33. super(fieldVisibilityManager, notNull("customField", customField));
  34. this.customField = customField;
  35. this.multiCascadeSelectService = ComponentAccessor.getComponent(MultiCascadeSelectService.class);
  36. }
  37. @Override
  38. public void addDocumentFieldsSearchable(final Document doc, final Issue issue) {
  39. addDocumentFields(doc, issue, Field.Index.NOT_ANALYZED);
  40. }
  41. @Override
  42. public void addDocumentFieldsNotSearchable(final Document doc, final Issue issue) {
  43. addDocumentFields(doc, issue, Field.Index.NO);
  44. }
  45. /*
  46. * indexes the custom field params extracting the options from the custom field and building a Document (to use in Lucene Indexing)
  47. * Updated to Jira 5.0.4 To Check in deep but probably OK
  48. */
  49. private void addDocumentFields(final Document doc, final Issue issue, final Field.Index indexType) {
  50. final Map<String, Option> cascadingOptions = (Map<String, Option>) customField.getValue(issue);
  51. if (cascadingOptions != null) {
  52. // Add a field with a string containing all options (cfid:0)
  53. addField(doc, getDocumentFieldId() + ":0", serializeOptions(cascadingOptions), indexType);
  54. // Add a field with the first option .. (cfid)
  55. indexParentField(cascadingOptions, doc, indexType);
  56. // .. and other fields with the remaining option (cfid:1, cfid:2,...)
  57. this.indexAllLevels(cascadingOptions, doc, indexType);
  58. }
  59. }
  60. /*
  61. * Serialize option to the string "opt1 - opt2 - opt3 ..."
  62. * updated jira 5.0.4 TO CHECK
  63. */
  64. private String serializeOptions(Map<String, Option> cascadingOptions) {
  65. StringBuilder serializedOption = new StringBuilder();
  66. Option currentOption = cascadingOptions.get("0");
  67. if (currentOption != null) {
  68. serializedOption.append(currentOption.getValue());
  69. }
  70. for (int i = 1; i < cascadingOptions.size(); i++) {
  71. currentOption = cascadingOptions.get("" + i);
  72. if (currentOption != null) {
  73. serializedOption.append(" - ").append(currentOption.getValue());
  74. }
  75. }
  76. return serializedOption.toString();
  77. }
  78. /*
  79. * indexes all the info contained in all child-level of the custom field.
  80. * Remember that the Multi level cascading select allows you to create n levels of children from the parent node.
  81. * Updated to Jira 5.04 To Check
  82. */
  83. private void indexAllLevels(Map<String, Option> cascadingOptions, final Document doc, final Field.Index indexType) {
  84. MultiCascadeSelectCFType customfieldtype = (MultiCascadeSelectCFType) customField.getCustomFieldType();
  85. final Option selectedValue = cascadingOptions.get("0");
  86. for (Map.Entry<String, Option> entry : cascadingOptions.entrySet())
  87. {
  88. log.debug(entry.getKey() + "/" + entry.getValue().getValue());
  89. }
  90. Option currentOption;
  91. MultiCSCFEntity currentEntity;
  92. Map<Integer, String> options = new HashMap<Integer, String>();
  93. for (Option option : selectedValue.getChildOptions()) {
  94. for (Option childoption : option.getChildOptions()) {
  95. log.debug("cascadingOptions.size():" + String.valueOf(cascadingOptions.size()));
  96. for (int i=1;i<cascadingOptions.size();i++) {
  97. currentOption = cascadingOptions.get(""+i);
  98. log.debug("i:" + i);
  99. if (currentOption != null) {
  100. log.debug("currentOption.getValue():" + currentOption.getValue());
  101. if (childoption.getOptionId().equals(currentOption.getOptionId())){
  102. log.debug("childoption.getOptionId():" + childoption.getOptionId().toString());
  103. log.debug("currentOption.getOptionId():" + currentOption.getOptionId().toString());
  104. currentEntity = customfieldtype.getOptionByCustomFieldValue(customField, currentOption.getParentOption());
  105. options.put(i, String.valueOf(currentEntity.getID()));
  106. }
  107. }
  108. }
  109. }
  110. }
  111. if ((cascadingOptions != null) && !cascadingOptions.isEmpty()) {
  112. for (int i=1;i<cascadingOptions.size();i++) {
  113. currentOption = cascadingOptions.get(""+i);
  114. if (currentOption != null) {
  115. String indexFieldName = getDocumentFieldId();
  116. indexFieldName += ":" + options.get(i);
  117. log.debug("Indexing :" + currentOption + "With ID=" + indexFieldName);
  118. addField(doc, indexFieldName, currentOption.getOptionId().toString(), indexType);
  119. }
  120. }
  121. }
  122. }
  123. /*
  124. * indexes the Parent Option value in the Lucene Doc.
  125. */
  126. private void indexParentField(Map<String, Option> cascadingOptions, final Document doc, final Field.Index indexType) {
  127. if ((cascadingOptions != null) && !cascadingOptions.isEmpty()) {
  128. final Option selectedValue = cascadingOptions.get("0");
  129. addField(doc, getDocumentFieldId(), selectedValue.getOptionId().toString(), indexType);
  130. }
  131. }
  132. private void addField(final Document doc, final String indexFieldName, final String value, final Field.Index indexType) {
  133. doc.add(new Field(indexFieldName, value, Field.Store.YES, indexType));
  134. }
  135. }