PageRenderTime 28ms CodeModel.GetById 1ms RepoModel.GetById 0ms app.codeStats 0ms

/src/main/java/com/atlassian/jira/collector/plugin/rest/TemporaryAttachmentsResource.java

https://bitbucket.org/knecht_andreas/jira-issue-collector-plugin/
Java | 181 lines | 153 code | 22 blank | 6 comment | 15 complexity | 5d5a3f8c5ccec96db36a3165f72795b2 MD5 | raw file
  1. package com.atlassian.jira.collector.plugin.rest;
  2. import com.atlassian.core.util.FileSize;
  3. import com.atlassian.jira.bc.ServiceOutcome;
  4. import com.atlassian.jira.collector.plugin.components.Collector;
  5. import com.atlassian.jira.config.properties.APKeys;
  6. import com.atlassian.jira.issue.attachment.TemporaryAttachment;
  7. import com.atlassian.jira.rest.v1.util.CacheControl;
  8. import com.atlassian.jira.security.JiraAuthenticationContext;
  9. import com.atlassian.jira.util.AttachmentUtils;
  10. import com.atlassian.jira.util.I18nHelper;
  11. import com.atlassian.jira.util.JiraVelocityUtils;
  12. import com.atlassian.jira.web.action.issue.TemporaryAttachmentsMonitor;
  13. import com.atlassian.jira.collector.plugin.components.CollectorService;
  14. import com.atlassian.plugins.rest.common.multipart.FilePart;
  15. import com.atlassian.plugins.rest.common.multipart.MultipartFormParam;
  16. import com.atlassian.plugins.rest.common.security.AnonymousAllowed;
  17. import com.atlassian.templaterenderer.TemplateRenderer;
  18. import org.apache.log4j.Logger;
  19. import webwork.config.Configuration;
  20. import java.io.File;
  21. import java.io.IOException;
  22. import java.io.StringWriter;
  23. import java.util.Collection;
  24. import java.util.Map;
  25. import java.util.UUID;
  26. import javax.servlet.http.HttpServletRequest;
  27. import javax.ws.rs.Consumes;
  28. import javax.ws.rs.POST;
  29. import javax.ws.rs.Path;
  30. import javax.ws.rs.PathParam;
  31. import javax.ws.rs.Produces;
  32. import javax.ws.rs.core.Context;
  33. import javax.ws.rs.core.MediaType;
  34. import javax.ws.rs.core.Response;
  35. @Path ("tempattachment")
  36. @Produces ( { MediaType.APPLICATION_JSON })
  37. @Consumes ( { MediaType.TEXT_HTML })
  38. @AnonymousAllowed
  39. public class TemporaryAttachmentsResource
  40. {
  41. private static final Logger log = Logger.getLogger(TemporaryAttachmentsResource.class);
  42. public static final long UNKNOWN_ISSUE_ID = -1L;
  43. private final CollectorService collectorService;
  44. private final JiraAuthenticationContext authenticationContext;
  45. private final TemplateRenderer templateRenderer;
  46. @Context
  47. private HttpServletRequest request;
  48. public TemporaryAttachmentsResource(final CollectorService collectorService, final JiraAuthenticationContext authenticationContext,
  49. final TemplateRenderer templateRenderer)
  50. {
  51. this.collectorService = collectorService;
  52. this.authenticationContext = authenticationContext;
  53. this.templateRenderer = templateRenderer;
  54. }
  55. @POST
  56. @Path ("{collectorId}")
  57. @Consumes ( { MediaType.MULTIPART_FORM_DATA })
  58. @Produces ( { MediaType.TEXT_HTML })
  59. public Response attachTemporaryFile(@PathParam ("collectorId") String collectorId, @MultipartFormParam ("screenshot") Collection<FilePart> fileParts)
  60. {
  61. //check if the collector exists!
  62. final ServiceOutcome<Collector> outcome = collectorService.getCollector(collectorId);
  63. if (outcome.getReturnedValue() == null || !outcome.getReturnedValue().isEnabled())
  64. {
  65. return Response.status(Response.Status.NOT_FOUND).cacheControl(CacheControl.NO_CACHE).build();
  66. }
  67. final Collector collector = outcome.getReturnedValue();
  68. final I18nHelper i18n = authenticationContext.getI18nHelper();
  69. //check if we can get an attachments monitor
  70. final TemporaryAttachmentsMonitor temporaryAttachmentsMonitor = TemporaryAttachmentsMonitorLocator.getAttachmentsMonitor(request, collector.getId());
  71. if (temporaryAttachmentsMonitor == null)
  72. {
  73. return Response.serverError().cacheControl(CacheControl.NO_CACHE).build();
  74. }
  75. //do some basic validation
  76. final Map<String, Object> context = JiraVelocityUtils.createVelocityParams(authenticationContext);
  77. if (fileParts.size() != 1)
  78. {
  79. context.put("errorMsg", i18n.getText("collector.plugin.template.error.no.attachments"));
  80. String out = renderTemplate("templates/rest/tempfilejson.vm", context);
  81. if (out == null)
  82. {
  83. return Response.serverError().cacheControl(CacheControl.NO_CACHE).build();
  84. }
  85. return Response.status(Response.Status.BAD_REQUEST).entity(out).cacheControl(CacheControl.NO_CACHE).build();
  86. }
  87. //ensure the file is not larger than a certain size!
  88. final FilePart filePart = fileParts.iterator().next();
  89. try
  90. {
  91. int maxAttachmentSize = new Integer(Configuration.getString(APKeys.JIRA_ATTACHMENT_SIZE));
  92. if (filePart.getInputStream().available() > maxAttachmentSize)
  93. {
  94. context.put("errorMsg", i18n.getText("collector.plugin.template.error.attachment.large", FileSize.format(maxAttachmentSize)));
  95. String out = renderTemplate("templates/rest/tempfilejson.vm", context);
  96. if (out == null)
  97. {
  98. return Response.serverError().cacheControl(CacheControl.NO_CACHE).build();
  99. }
  100. return Response.status(Response.Status.BAD_REQUEST).entity(out).cacheControl(CacheControl.NO_CACHE).build();
  101. }
  102. }
  103. catch (IOException e)
  104. {
  105. return Response.serverError().cacheControl(CacheControl.NO_CACHE).build();
  106. }
  107. //finally create the temporary attachment!
  108. final TemporaryAttachment temporaryAttachment = createTemporaryAttachment(filePart);
  109. temporaryAttachmentsMonitor.add(temporaryAttachment);
  110. context.put("temporaryAttachment", temporaryAttachment);
  111. String out = renderTemplate("templates/rest/tempfilejson.vm", context);
  112. if (out == null)
  113. {
  114. return Response.serverError().cacheControl(CacheControl.NO_CACHE).build();
  115. }
  116. return Response.ok(out).cacheControl(CacheControl.NO_CACHE).build();
  117. }
  118. private TemporaryAttachment createTemporaryAttachment(final FilePart filePart)
  119. {
  120. final File tmpDir = AttachmentUtils.getTemporaryAttachmentDirectory();
  121. long uniqueId;
  122. File tempAttachmentFile;
  123. do
  124. {
  125. //if the file already exists, choose a new UUID to avoid clashes!
  126. uniqueId = getUUID();
  127. tempAttachmentFile = new File(tmpDir, uniqueId + "_" + filePart.getName());
  128. }
  129. while (tempAttachmentFile.exists());
  130. try
  131. {
  132. filePart.write(tempAttachmentFile);
  133. }
  134. catch (IOException e)
  135. {
  136. log.error("Error creating temporary attachment", e);
  137. return null;
  138. }
  139. return new TemporaryAttachment(uniqueId, UNKNOWN_ISSUE_ID, tempAttachmentFile, filePart.getName(), filePart.getContentType());
  140. }
  141. private String renderTemplate(String templatePath, Map<String, Object> context)
  142. {
  143. final StringWriter out = new StringWriter();
  144. try
  145. {
  146. templateRenderer.render(templatePath, context, out);
  147. }
  148. catch (IOException e)
  149. {
  150. log.error("Error rendering template '" + templatePath + "'.", e);
  151. return null;
  152. }
  153. return out.toString();
  154. }
  155. private long getUUID()
  156. {
  157. return Math.abs(UUID.randomUUID().getLeastSignificantBits());
  158. }
  159. }