PageRenderTime 40ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/components/server-data-access/src/main/java/org/marvelution/jji/data/services/DefaultIssueReferenceProvider.java

https://bitbucket.org/marvelution/jira-jenkins-integration
Java | 203 lines | 174 code | 14 blank | 15 comment | 16 complexity | 107faa244d00512c71232de3c2ae8b9b MD5 | raw file
  1. /*
  2. * Copyright (c) 2012-present Marvelution Holding B.V.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.marvelution.jji.data.services;
  17. import java.util.*;
  18. import java.util.function.*;
  19. import javax.annotation.*;
  20. import javax.inject.*;
  21. import com.marvelution.jji.jira.rest.model.*;
  22. import org.marvelution.jji.data.services.api.*;
  23. import org.marvelution.jji.model.*;
  24. import com.atlassian.jira.issue.Issue;
  25. import com.atlassian.jira.issue.*;
  26. import com.atlassian.jira.issue.fields.*;
  27. import com.atlassian.jira.issue.fields.rest.*;
  28. import com.atlassian.jira.issue.fields.rest.json.*;
  29. import com.atlassian.jira.project.Project;
  30. import com.atlassian.jira.user.*;
  31. import com.atlassian.plugin.spring.scanner.annotation.imports.*;
  32. import com.atlassian.plugins.rest.common.json.*;
  33. import com.google.common.collect.*;
  34. import com.jayway.jsonpath.*;
  35. import org.codehaus.jackson.map.Module;
  36. import org.slf4j.*;
  37. import static com.marvelution.jji.jira.rest.model.IssueFields.*;
  38. import static org.marvelution.jji.utils.KeyExtractor.*;
  39. import static java.util.stream.Collectors.*;
  40. import static javax.ws.rs.core.UriBuilder.*;
  41. @Named
  42. public class DefaultIssueReferenceProvider
  43. implements IssueReferenceProvider
  44. {
  45. private static final Logger LOGGER = LoggerFactory.getLogger(DefaultIssueReferenceProvider.class);
  46. private static final Map<String, Function<Issue, ApplicationUser>> USER_FIELDS = ImmutableMap.of(CREATOR, Issue::getCreator, ASSIGNEE,
  47. Issue::getAssignee, REPORTER,
  48. Issue::getReporter);
  49. private final ConfigurationService configurationService;
  50. private final IssueManager issueManager;
  51. private final FieldManager fieldManager;
  52. private final JaxbJsonMarshaller jaxbJsonMarshaller;
  53. @Inject
  54. public DefaultIssueReferenceProvider(
  55. ConfigurationService configurationService,
  56. @ComponentImport IssueManager issueManager,
  57. @ComponentImport FieldManager fieldManager,
  58. List<Module> modules)
  59. {
  60. this.configurationService = configurationService;
  61. this.issueManager = issueManager;
  62. this.fieldManager = fieldManager;
  63. this.jaxbJsonMarshaller = DefaultJaxbJsonMarshaller.builder().modules(modules).build();
  64. }
  65. @Override
  66. public void setIssueUrl(IssueReference reference)
  67. {
  68. reference.setIssueUrl(fromUri(configurationService.getBaseUrl()).path("browse/{issueKey}").build(reference.getIssueKey()));
  69. }
  70. @Override
  71. public Optional<IssueReference> getIssueReference(
  72. String key,
  73. FieldContext fieldContext)
  74. {
  75. return Optional.of(key).map(issueManager::getIssueObject).map(issue -> toReference(issue, fieldContext));
  76. }
  77. @Override
  78. public Set<IssueReference> getIssueReferences(
  79. Set<String> keys,
  80. FieldContext fieldContext)
  81. {
  82. return keys.stream()
  83. .map(issueManager::getIssueObject)
  84. .filter(Objects::nonNull)
  85. .map(issue -> toReference(issue, fieldContext))
  86. .collect(toSet());
  87. }
  88. private IssueReference toReference(
  89. Issue issue,
  90. FieldContext fieldContext)
  91. {
  92. IssueReference reference = new IssueReference().setIssueKey(issue.getKey())
  93. .setProjectKey(Optional.ofNullable(issue.getProjectObject())
  94. .map(Project::getKey)
  95. .orElse(extractProjectKeyFromIssueKey(issue.getKey())));
  96. setIssueUrl(reference);
  97. if (fieldContext.hasAdditionalFields())
  98. {
  99. for (String fieldKey : fieldContext.additionalFields())
  100. {
  101. FieldJsonRepresentation jsonRepresentation = null;
  102. Field field = fieldManager.getField(fieldKey);
  103. if (field == null)
  104. {
  105. LOGGER.warn("Skipping non-existing field {} for issue {}", fieldKey, issue.getKey());
  106. continue;
  107. }
  108. else if (field instanceof KeySystemField)
  109. {
  110. LOGGER.debug("Skipping issuekey field for issue {}", issue.getKey());
  111. continue;
  112. }
  113. else if (USER_FIELDS.containsKey(field.getId()))
  114. {
  115. ApplicationUser user = USER_FIELDS.get(field.getId()).apply(issue);
  116. if (user != null)
  117. {
  118. User userJson = new User();
  119. userJson.setAccountId(String.valueOf(user.getId()));
  120. userJson.setKey(user.getKey());
  121. userJson.setName(user.getName());
  122. userJson.setDisplayName(user.getDisplayName());
  123. userJson.setEmailAddress(user.getEmailAddress());
  124. jsonRepresentation = new FieldJsonRepresentation(new JsonData(userJson), null);
  125. }
  126. }
  127. else if (field instanceof RestAwareField)
  128. {
  129. jsonRepresentation = ((RestAwareField) field).getJsonFromIssue(issue, true, null);
  130. }
  131. if (jsonRepresentation != null)
  132. {
  133. String value = getFieldValueFromJson(field.getId(), field.getName(), jsonRepresentation, fieldContext);
  134. if (value != null)
  135. {
  136. reference.addField(field.getName(), value);
  137. }
  138. else
  139. {
  140. LOGGER.debug("Skipping field {} of issue {} as its value is 'null'", fieldKey, issue.getKey());
  141. }
  142. }
  143. else
  144. {
  145. LOGGER.warn("Unable to get value of field {} for issue {}", fieldKey, issue.getKey());
  146. }
  147. }
  148. }
  149. return reference;
  150. }
  151. @Nullable
  152. protected String getFieldValueFromJson(
  153. String fieldKey,
  154. String fieldName,
  155. FieldJsonRepresentation jsonRepresentation,
  156. FieldContext fieldContext)
  157. {
  158. try
  159. {
  160. Object valueJson = getJson(jsonRepresentation.getStandardData());
  161. Object renderedValueJson = getJson(jsonRepresentation.getRenderedData());
  162. LOGGER.debug("Attempting to extract the value for field {} from value: {}; renderedValue: {}", fieldKey, valueJson,
  163. renderedValueJson);
  164. return fieldContext.fieldValue(fieldKey, fieldName, valueJson, renderedValueJson);
  165. }
  166. catch (Exception e)
  167. {
  168. LOGGER.error("failed to extract field value for field {}", fieldKey, e);
  169. return null;
  170. }
  171. }
  172. private Object getJson(JsonData jsonData)
  173. {
  174. try
  175. {
  176. return Optional.ofNullable(jsonData)
  177. .map(JsonData::getData)
  178. .map(jaxbJsonMarshaller::marshal)
  179. .map(JsonPath::parse)
  180. .map(DocumentContext::json)
  181. .orElse(null);
  182. }
  183. catch (Exception e)
  184. {
  185. LOGGER.debug("Unable to get json string from json data {}", jsonData);
  186. return null;
  187. }
  188. }
  189. }