/src/main/groovy/com/onresolve/jira/groovy/customfield/ScriptedFieldPreviewServlet.groovy
Groovy | 129 lines | 97 code | 22 blank | 10 comment | 10 complexity | e52a5ab51eb4ca83b88328f835f2fc12 MD5 | raw file
- package com.onresolve.jira.groovy.customfield
-
- import com.atlassian.crowd.embedded.api.User
- import com.atlassian.jira.ComponentManager
- import com.atlassian.jira.issue.CustomFieldManager
- import com.atlassian.jira.issue.IssueManager
- import com.atlassian.jira.issue.MutableIssue
- import com.atlassian.jira.issue.fields.CustomField
- import com.atlassian.jira.issue.fields.layout.field.FieldLayout
- import com.atlassian.jira.issue.fields.layout.field.FieldLayoutItem
- import com.atlassian.jira.issue.fields.layout.field.FieldLayoutManager
- import com.atlassian.jira.security.PermissionManager
- import com.atlassian.jira.security.Permissions
- import com.atlassian.jira.util.json.JSONObject
- import com.onresolve.jira.groovy.GroovyCustomField
- import javax.servlet.http.HttpServlet
- import javax.servlet.http.HttpServletRequest
- import javax.servlet.http.HttpServletResponse
- import org.apache.log4j.Category
-
- class ScriptedFieldPreviewServlet extends HttpServlet{
- Category log = Category.getInstance(ScriptedFieldPreviewServlet.class)
-
- ComponentManager componentManager = ComponentManager.getInstance()
- CustomFieldManager customFieldManager = componentManager.getCustomFieldManager()
- IssueManager issueManager = componentManager.getIssueManager()
- FieldLayoutManager fieldLayoutManager = componentManager.getFieldLayoutManager()
-
- private static Map<String,Class> expectedResults = [
- "com.atlassian.jira.issue.customfields.searchers.TextSearcher" : String.class,
- "com.atlassian.jira.issue.customfields.searchers.ExactTextSearcher" : String.class,
- "com.atlassian.jira.issue.customfields.searchers.ExactNumberSearcher" : Double.class,
- "com.atlassian.jira.issue.customfields.searchers.NumberRangeSearcher" : Double.class,
- // "com.atlassian.jira.issue.customfields.searchers.UserPickerSearcher" : com.opensymphony.user.User.class,
-
- // "com.atlassian.jira.issue.customfields.searchers.DateRangeSearcher" : java.util.Date.class,
- // "com.atlassian.jira.issue.customfields.searchers.DateTimeRangeSearcher" : java.util.Date.class,
- // "com.atlassian.jira.issue.customfields.searchers.GroupPickerSearcher" : List.class, // or rather the first one should be a Group
-
-
-
- // "float" : java.lang.Double.class,
- // "datepicker" : java.util.Date.class,
- // "datetime" : java.util.Date.class,
- // "multigrouppicker" : List.class,
-
- ] as Map<String,Class>
-
- protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
-
- User user = componentManager.getJiraAuthenticationContext().getUser()
- PermissionManager permissionManager = componentManager.getPermissionManager()
- if (!permissionManager.hasPermission(Permissions.ADMINISTER, user)) {
- log.warn("Non-admin accessing ${getClass().getName()}")
- return;
- }
-
- resp.setContentType("application/json")
- PrintWriter out = resp.getWriter()
-
- CustomField customField = customFieldManager.getCustomFieldObject(req.getParameter("cfid") as Long)
- FieldLayout fieldLayout = fieldLayoutManager.getFieldLayout(req.getParameter("fieldLayoutId") as Long)
-
- GroovyCustomField cftype = customField.getCustomFieldType() as GroovyCustomField
- FieldLayoutItem fieldLayoutItem = fieldLayout.getFieldLayoutItem(customField)
- MutableIssue issue
- String errors = ""
- String output = ""
-
- issue = issueManager.getIssueObject(req.getParameter("previewIssueKey"))
- if (!issue) {
- errors = "Issue not found.\n"
- }
- else {
- try {
- cftype.setPreviewMode(true)
- cftype.setScript(req.getParameter("script"))
- cftype.setScriptFile(req.getParameter("scriptFile"))
- String modelTemplate = req.getParameter("modelTemplate") as String
- cftype.setModelTemplate(modelTemplate)
- cftype.setCustomTemplate(req.getParameter("customTemplate"))
-
- try {
- Map velocityParams = cftype.getRealVelocityParameters(issue, customField, fieldLayoutItem)
- Object value = velocityParams["value"]
-
- output = cftype.getHtml(velocityParams)
- String exMsg = cftype.getExceptionMessage()
-
- // check that the right value is returned for the indexer in use
- if (!exMsg && value != null) {
- log.debug ("Return type: ${value.getClass()}")
-
- // todo: check the configured indexer, not the template
- String searcherClazz = getConfiguredSearcherClass(customField.getIdAsLong())
- if (expectedResults.containsKey(searcherClazz)) {
- Class clazz = expectedResults[searcherClazz]
- if (! value.getClass().equals(clazz) && ! value.getClass().getInterfaces().toList().contains(clazz)) {
- log.warn ("Not the right return type")
- errors = "The indexer for this field expects a <b>${expectedResults[searcherClazz].getName()}</b> but\n" +
- "the script returned a <b>${value.getClass().getName()}</b> - this will cause problems.\n\n"
- }
- }
- }
-
- if (exMsg) {
- errors = errors + exMsg + "\nA stacktrace has been logged."
- }
- }
- catch (Exception e) {
- errors = e.getMessage()
- log.debug(e.getMessage(), e)
- }
- }
- finally {
- cftype.setScript(null)
- cftype.setScriptFile(null)
- cftype.setModelTemplate(null)
- cftype.setPreviewMode(false)
- }
- }
-
- out.write(new JSONObject(["output":output, "errors":errors]).toString())
- }
-
- public String getConfiguredSearcherClass(Long cfId) {
- customFieldManager.getCustomFieldObject(cfId).getCustomFieldSearcher()?.getClass()?.getName() ?: "None"
- }
- }