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

/src/main/groovy/com/onresolve/jira/groovy/customfield/ScriptedFieldPreviewServlet.groovy

https://bitbucket.org/sorin/jira-plugin-intellij
Groovy | 129 lines | 97 code | 22 blank | 10 comment | 10 complexity | e52a5ab51eb4ca83b88328f835f2fc12 MD5 | raw file
  1. package com.onresolve.jira.groovy.customfield
  2. import com.atlassian.crowd.embedded.api.User
  3. import com.atlassian.jira.ComponentManager
  4. import com.atlassian.jira.issue.CustomFieldManager
  5. import com.atlassian.jira.issue.IssueManager
  6. import com.atlassian.jira.issue.MutableIssue
  7. import com.atlassian.jira.issue.fields.CustomField
  8. import com.atlassian.jira.issue.fields.layout.field.FieldLayout
  9. import com.atlassian.jira.issue.fields.layout.field.FieldLayoutItem
  10. import com.atlassian.jira.issue.fields.layout.field.FieldLayoutManager
  11. import com.atlassian.jira.security.PermissionManager
  12. import com.atlassian.jira.security.Permissions
  13. import com.atlassian.jira.util.json.JSONObject
  14. import com.onresolve.jira.groovy.GroovyCustomField
  15. import javax.servlet.http.HttpServlet
  16. import javax.servlet.http.HttpServletRequest
  17. import javax.servlet.http.HttpServletResponse
  18. import org.apache.log4j.Category
  19. class ScriptedFieldPreviewServlet extends HttpServlet{
  20. Category log = Category.getInstance(ScriptedFieldPreviewServlet.class)
  21. ComponentManager componentManager = ComponentManager.getInstance()
  22. CustomFieldManager customFieldManager = componentManager.getCustomFieldManager()
  23. IssueManager issueManager = componentManager.getIssueManager()
  24. FieldLayoutManager fieldLayoutManager = componentManager.getFieldLayoutManager()
  25. private static Map<String,Class> expectedResults = [
  26. "com.atlassian.jira.issue.customfields.searchers.TextSearcher" : String.class,
  27. "com.atlassian.jira.issue.customfields.searchers.ExactTextSearcher" : String.class,
  28. "com.atlassian.jira.issue.customfields.searchers.ExactNumberSearcher" : Double.class,
  29. "com.atlassian.jira.issue.customfields.searchers.NumberRangeSearcher" : Double.class,
  30. // "com.atlassian.jira.issue.customfields.searchers.UserPickerSearcher" : com.opensymphony.user.User.class,
  31. // "com.atlassian.jira.issue.customfields.searchers.DateRangeSearcher" : java.util.Date.class,
  32. // "com.atlassian.jira.issue.customfields.searchers.DateTimeRangeSearcher" : java.util.Date.class,
  33. // "com.atlassian.jira.issue.customfields.searchers.GroupPickerSearcher" : List.class, // or rather the first one should be a Group
  34. // "float" : java.lang.Double.class,
  35. // "datepicker" : java.util.Date.class,
  36. // "datetime" : java.util.Date.class,
  37. // "multigrouppicker" : List.class,
  38. ] as Map<String,Class>
  39. protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
  40. User user = componentManager.getJiraAuthenticationContext().getUser()
  41. PermissionManager permissionManager = componentManager.getPermissionManager()
  42. if (!permissionManager.hasPermission(Permissions.ADMINISTER, user)) {
  43. log.warn("Non-admin accessing ${getClass().getName()}")
  44. return;
  45. }
  46. resp.setContentType("application/json")
  47. PrintWriter out = resp.getWriter()
  48. CustomField customField = customFieldManager.getCustomFieldObject(req.getParameter("cfid") as Long)
  49. FieldLayout fieldLayout = fieldLayoutManager.getFieldLayout(req.getParameter("fieldLayoutId") as Long)
  50. GroovyCustomField cftype = customField.getCustomFieldType() as GroovyCustomField
  51. FieldLayoutItem fieldLayoutItem = fieldLayout.getFieldLayoutItem(customField)
  52. MutableIssue issue
  53. String errors = ""
  54. String output = ""
  55. issue = issueManager.getIssueObject(req.getParameter("previewIssueKey"))
  56. if (!issue) {
  57. errors = "Issue not found.\n"
  58. }
  59. else {
  60. try {
  61. cftype.setPreviewMode(true)
  62. cftype.setScript(req.getParameter("script"))
  63. cftype.setScriptFile(req.getParameter("scriptFile"))
  64. String modelTemplate = req.getParameter("modelTemplate") as String
  65. cftype.setModelTemplate(modelTemplate)
  66. cftype.setCustomTemplate(req.getParameter("customTemplate"))
  67. try {
  68. Map velocityParams = cftype.getRealVelocityParameters(issue, customField, fieldLayoutItem)
  69. Object value = velocityParams["value"]
  70. output = cftype.getHtml(velocityParams)
  71. String exMsg = cftype.getExceptionMessage()
  72. // check that the right value is returned for the indexer in use
  73. if (!exMsg && value != null) {
  74. log.debug ("Return type: ${value.getClass()}")
  75. // todo: check the configured indexer, not the template
  76. String searcherClazz = getConfiguredSearcherClass(customField.getIdAsLong())
  77. if (expectedResults.containsKey(searcherClazz)) {
  78. Class clazz = expectedResults[searcherClazz]
  79. if (! value.getClass().equals(clazz) && ! value.getClass().getInterfaces().toList().contains(clazz)) {
  80. log.warn ("Not the right return type")
  81. errors = "The indexer for this field expects a <b>${expectedResults[searcherClazz].getName()}</b> but\n" +
  82. "the script returned a <b>${value.getClass().getName()}</b> - this will cause problems.\n\n"
  83. }
  84. }
  85. }
  86. if (exMsg) {
  87. errors = errors + exMsg + "\nA stacktrace has been logged."
  88. }
  89. }
  90. catch (Exception e) {
  91. errors = e.getMessage()
  92. log.debug(e.getMessage(), e)
  93. }
  94. }
  95. finally {
  96. cftype.setScript(null)
  97. cftype.setScriptFile(null)
  98. cftype.setModelTemplate(null)
  99. cftype.setPreviewMode(false)
  100. }
  101. }
  102. out.write(new JSONObject(["output":output, "errors":errors]).toString())
  103. }
  104. public String getConfiguredSearcherClass(Long cfId) {
  105. customFieldManager.getCustomFieldObject(cfId).getCustomFieldSearcher()?.getClass()?.getName() ?: "None"
  106. }
  107. }