PageRenderTime 46ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/src/main/resources/com/onresolve/jira/groovy/canned/admin/BulkImportCustomFieldValues.groovy

https://bitbucket.org/sorin/jira-plugin-intellij
Groovy | 147 lines | 122 code | 25 blank | 0 comment | 14 complexity | 983b67ead14bb98ee28bcb46047bd284 MD5 | raw file
  1. package com.onresolve.jira.groovy.canned.admin
  2. import com.atlassian.jira.ComponentManager
  3. import com.atlassian.jira.component.ComponentAccessor
  4. import com.atlassian.jira.issue.customfields.impl.CascadingSelectCFType
  5. import com.atlassian.jira.issue.customfields.option.Option
  6. import com.atlassian.jira.issue.fields.config.FieldConfigScheme
  7. import com.atlassian.jira.issue.fields.config.manager.FieldConfigSchemeManager
  8. import com.atlassian.jira.util.ErrorCollection
  9. import com.atlassian.jira.util.SimpleErrorCollection
  10. import com.onresolve.jira.groovy.canned.CannedScript
  11. import com.onresolve.jira.groovy.canned.utils.CannedScriptUtils
  12. import org.apache.log4j.Category
  13. class BulkImportCustomFieldValues implements CannedScript {
  14. public static String FIELD_IMPORT_VALUES = "FIELD_IMPORT_VALUES"
  15. public static String FIELD_FCS = "FIELD_FCS"
  16. Category log = Category.getInstance(BulkImportCustomFieldValues.class)
  17. def componentManager = ComponentManager.getInstance()
  18. def customFieldManager = componentManager.getCustomFieldManager()
  19. def optionsManager = ComponentAccessor.getOptionsManager()
  20. String getName() {
  21. return "Bulk import custom field values"
  22. }
  23. String getDescription() {
  24. return "Bulk import custom field values"
  25. }
  26. public String getHelpUrl() {
  27. "https://studio.plugins.atlassian.com/wiki/display/GRV/Built-In+Scripts#Built-InScripts-BulkImportCustomFieldValues"
  28. }
  29. List getCategories() {
  30. ["ADMIN"]
  31. }
  32. List getParameters(Map params) {
  33. [
  34. [
  35. Name:FIELD_FCS,
  36. Label:"Name of custom field config scheme",
  37. Description:"The name of the field config scheme in which to import these values",
  38. Type:"groupedlist", // multilist requires map of maps
  39. Values: CannedScriptUtils.getFieldConfigSchemesByCustomField(true)
  40. ],
  41. [
  42. Name:FIELD_IMPORT_VALUES,
  43. Label:"Values to import",
  44. Description:"Each line will be imported as a new field value. For cascading selects, indent child options " +
  45. "with a tab or two spaces. If a value exists it will be skipped.",
  46. Type:"text",
  47. ],
  48. ]
  49. }
  50. ErrorCollection doValidate(Map params, boolean forPreview) {
  51. def errorCollection = new SimpleErrorCollection()
  52. def importValues = params[FIELD_IMPORT_VALUES]
  53. FieldConfigScheme scheme = getSchemeFromParams(params)
  54. if (!scheme) {
  55. errorCollection.addError(FIELD_FCS, "No field config scheme with this ID found, or you have not selected one.")
  56. }
  57. else {
  58. if (!importValues) {
  59. errorCollection.addError(FIELD_IMPORT_VALUES, "Please enter values to import.")
  60. }
  61. }
  62. errorCollection
  63. }
  64. private FieldConfigScheme getSchemeFromParams(Map params) {
  65. def fcsId = params[FIELD_FCS] as Long
  66. def fieldConfigSchemeManager = ComponentManager.getComponentInstanceOfType(FieldConfigSchemeManager.class)
  67. def scheme = fieldConfigSchemeManager.getFieldConfigScheme(fcsId)
  68. scheme
  69. }
  70. Map doScript(Map params, boolean forPreview = false) {
  71. String importValues = params[FIELD_IMPORT_VALUES]
  72. FieldConfigScheme fcs = getSchemeFromParams(params)
  73. Integer existingOptions = 0
  74. Integer newOptions = 0
  75. def oneAndOnlyConfig = fcs.getOneAndOnlyConfig()
  76. def cf = oneAndOnlyConfig.getCustomField()
  77. def isCascadingSelect = cf.getCustomFieldType() instanceof CascadingSelectCFType
  78. Option previousOption = null
  79. importValues.eachLine {String line ->
  80. def option = optionsManager.getOptions(oneAndOnlyConfig).getOptionForValue(line.trim(),
  81. (isCascadingSelect && isIndented(line)) ? previousOption?.optionId : null)
  82. if (option) {
  83. existingOptions++
  84. }
  85. else {
  86. newOptions++
  87. if (isIndented(line) && isCascadingSelect) {
  88. if (!forPreview) {
  89. optionsManager.createOption(oneAndOnlyConfig, previousOption.optionId, null, line.trim())
  90. }
  91. log.debug("Adding option with value ${line.trim()} to parent option ${previousOption?.getValue()}")
  92. }
  93. else {
  94. log.debug("Adding option with value ${line.trim()}")
  95. if (!forPreview) {
  96. option = optionsManager.createOption(oneAndOnlyConfig, null, null, line.trim())
  97. }
  98. }
  99. }
  100. if (!isIndented(line)) {
  101. previousOption = option
  102. }
  103. }
  104. def rt = new StringBuffer()
  105. rt << (forPreview ? "Will add" : "Added")
  106. rt << " $newOptions new option(s) to scheme: <b>${fcs.name}</b> for custom field:" <<
  107. " <b>${cf.name}</b>."
  108. if (existingOptions) {
  109. rt << " $existingOptions option(s) already existed"
  110. }
  111. return [output: rt.toString()]
  112. }
  113. private boolean isIndented(String line) {
  114. line ==~ /^\t.*/ || line ==~ /^\s\s.*/
  115. }
  116. String getDescription(Map params, boolean forPreview) {
  117. doScript(params, forPreview).get("output")
  118. }
  119. Boolean isFinalParamsPage(Map params) {
  120. return true
  121. }
  122. }