Java/Groovy API
File Field is compatible with all Jira automation apps: ScriptRunner, Automation for Jira, JSU, etc. You can use the FileManager java component to manage your files programmatically from java/groovy scripts.

Plain Java Example

1
import com.apwide.file.api.FileManager;
2
...
3
import com.atlassian.jira.component.*;
4
5
6
// Get FileManager instance
7
FileManager fileManager = ComponentAccessor.getComponent(FileManager.class);
8
9
// Binary content to upload
10
InputStream inputStream = new ByteArrayInputStream("any content".getBytes(StandardCharsets.UTF_8));
11
// Name of the file to upload
12
String fileName = "Readme.txt";
13
// Size limit of file to upload (ex: 10Mo)
14
long maxFileSize = 10*1000*1000;
15
16
// UPLOAD
17
String fileId = fileManager.upload(fileName, inputStream, maxFileSize);
18
19
// DONWLOAD
20
InputStream downloadedFile = fileManager.download(fileId);
21
22
// GET PATH
23
String filePath = fileManager.getPath(fileId);
24
25
// CHECK IF IT EXISTS
26
boolean exists = fileManager.exists(fileId);
27
28
// DELETE
29
boolean deleted = fileManager.delete(fileId);234567891011121314151617181920212223242526272829
Copied!

Script Runner Groovy Example

This example script shows how to create/upload 2 files and add them to an existing File Field customfield.
N.B. Adding multiple uploaded files into 1 single customfield is supported since version 3.1.0.
You should always set the value of a File customfield using a unique String:
  • containing 1 file id. Example: "1568037617780_10000_w3c_home.gif"
  • or containing multiple file ids separated by a comma. Example: "1568037617780_10000_w3c_home.gif,1568037613455_10000_another_file.gif"
1
import com.onresolve.scriptrunner.runner.customisers.WithPlugin
2
import com.onresolve.scriptrunner.runner.customisers.PluginModule
3
4
@WithPlugin("com.apwide.document.file-field")
5
6
import com.apwide.file.api.FileManager;
7
import com.atlassian.jira.component.*;
8
import java.io.ByteArrayInputStream;
9
import java.io.InputStream;
10
import java.nio.charset.StandardCharsets;
11
12
13
@PluginModule
14
FileManager fileManager
15
16
// Size limit of file to upload (ex: 10Mo)
17
long maxFileSize = 10*1000*1000;
18
19
// create and upload first file
20
String textFileContent = "My first example file"
21
InputStream inputStream = new ByteArrayInputStream(textFileContent.getBytes(StandardCharsets.UTF_8))
22
String fileId_1 = fileManager.upload("My First example file.txt", inputStream, maxFileSize)
23
24
// create and upload second file
25
String textFileContent = "My second example file"
26
InputStream inputStream = new ByteArrayInputStream(textFileContent.getBytes(StandardCharsets.UTF_8))
27
String fileId_2 = fileManager.upload("My Second example file.txt", inputStream, maxFileSize)
28
29
30
31
// Update the customfield
32
import com.atlassian.jira.issue.Issue
33
import com.atlassian.jira.issue.ModifiedValue
34
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
35
36
37
def issueManager = ComponentAccessor.getIssueManager()
38
def issue = issueManager.getIssueObject("HSP-31")
39
def customFieldManager = ComponentAccessor.getCustomFieldManager()
40
def fileField = customFieldManager.getCustomFieldObjects(issue).find {it.name == "file"}
41
42
// get current value of the file field for an Issue if you need it (file ids. String with following format: "fileId1,fileId2")
43
def currentFileIds = fileField.getValue(issue)
44
45
if (fileField) {
46
def changeHolder = new DefaultIssueChangeHolder()
47
// update customfield's value using a String containing file ids separated by a comma
48
fileField.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(fileField), fileId_1 + "," + fileId_2), changeHolder)
49
}
Copied!

Copy an Attachment to a File Field custom field

This ScriptRunner groovy script shows how to copy an existing attachment to a File Field customfield:
1
import com.onresolve.scriptrunner.runner.customisers.WithPlugin
2
import com.onresolve.scriptrunner.runner.customisers.PluginModule
3
4
@WithPlugin("com.apwide.document.file-field")
5
6
import com.apwide.file.api.FileManager;
7
import com.atlassian.jira.component.*;
8
import com.atlassian.jira.issue.attachment.Attachment
9
import com.atlassian.jira.issue.attachment.FileSystemAttachmentDirectoryAccessor
10
import com.atlassian.jira.issue.Issue
11
import com.atlassian.jira.issue.ModifiedValue
12
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
13
14
15
def attachmentManager = ComponentAccessor.getAttachmentManager()
16
def attachmentDirectoryAccessor = ComponentAccessor.getComponent(FileSystemAttachmentDirectoryAccessor.class)
17
18
@PluginModule
19
FileManager fileManager
20
21
// Load the issue you want to update
22
def issueManager = ComponentAccessor.getIssueManager()
23
Issue issue = issueManager.getIssueObject("GOT-1")
24
25
// find attachment by file name
26
String fileName = "Existing Attachment Name.txt"
27
List<Attachment> lastAttachments = attachmentManager.getAttachments(issue)
28
Attachment attachment = lastAttachments.find({ attachment -> attachment.getFilename().equals(fileName) })
29
log.warn "Found Attachment: ${attachment}"
30
if (attachment){
31
// get attachment binary file
32
log.warn "Files found in issue folder: ${attachmentDirectoryAccessor.getAttachmentDirectory(issue).listFiles()}"
33
def file = attachmentDirectoryAccessor.getAttachmentDirectory(issue)
34
.listFiles()
35
.find({ it-> it.getName().equals(""+attachment.id)})
36
log.warn "File found: ${file}"
37
if (file){
38
// Size limit of file to upload (ex: 10Mo)
39
long maxFileSize = 10*1000*1000;
40
// upload the attachment binary file to File Field and get its unique id
41
String fileId = fileManager.upload(fileName, new FileInputStream(file), maxFileSize)
42
log.warn "FileId of newly updated file: ${fileId}"
43
44
// find the target File Field to update
45
def customFieldManager = ComponentAccessor.getCustomFieldManager()
46
def fileField = customFieldManager.getCustomFieldObjects(issue).find {it.name == "Existing File Field customfield name"}
47
log.warn "File Field found: ${fileField}"
48
49
if (fileField) {
50
def changeHolder = new DefaultIssueChangeHolder()
51
// update customfield's value using a String containing the file id
52
fileField.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(fileField), fileId), changeHolder)
53
log.warn "File field successfully updated with the new fileId"
54
}
55
}
56
}
Copied!

Copy File Fields to the Jira attachments field

Ram Kumar Aravindakshan (Adaptavist) answered this question on the Jira Community:
For your requirement, you could try using a ScriptRunner Listener.
The IssueCreate event / IssueUpdated event can be used to copy the attachment from the Apwide File Field to the Attachment field either during the creation of the Issue or when the Issue is being updated.
Below is a print screen of the Listener configuration:
Below is a working sample code for your reference:
1
import com.atlassian.jira.component.ComponentAccessor
2
import com.atlassian.jira.issue.MutableIssue
3
import com.atlassian.jira.issue.attachment.CreateAttachmentParamsBean
4
5
import java.text.SimpleDateFormat
6
7
def issue = event.issue as MutableIssue
8
9
def customFieldManager = ComponentAccessor.customFieldManager
10
def attachmentManager = ComponentAccessor.attachmentManager
11
def loggedInUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser
12
13
def appwide = customFieldManager.getCustomFieldObjectsByName("Appwide Attachment")[0]
14
def appwideValue = appwide.getValue(issue).toString().split(",") as List<String>
15
16
//The path where the apwide attachments are stored
17
def folderPath = "/media/ram/Linux_Disk_Space/atlassian/application-data/jira8/data/attachments/00_apwide_file_field_files"
18
19
def formatYear = new SimpleDateFormat("yyyy")
20
def formatCurrentDate = new SimpleDateFormat("yyyy-MM-dd")
21
def currentYear = formatYear.format(new Date())
22
def currentDate = formatCurrentDate.format(new Date())
23
24
def latestFile = "${folderPath}/${currentYear}/${currentDate}/${appwideValue.last()}"
25
def sourceFile = new File(latestFile)
26
27
def attachmentParams = new CreateAttachmentParamsBean(sourceFile,sourceFile.name,null,loggedInUser,issue,null,false,null,new Date(),true)
28
attachmentManager.createAttachment(attachmentParams)
Copied!
Below are some test print screens:
  • When the Apwide attachment is added, it is automatically added to Jira's attachment, as well as shown in the image below:
  • Although the attachment displays as the Actual file name added when it is stored in the Folder, it will display a timestamp as shown in the image below (which is why the Jira attachment appears to be so):
  • However, in the Jira attachments folder, it displays as a regular attachment file as shown below:

JavaDoc

String upload(String fileName, InputStream file, long maxFileSize)

Upload file
  • Parameters:
    • fileName — name of the file
    • file — file content
    • maxFileSize — max file size allowed (in bytes)
  • Returns: generated unique id of the uploaded file

boolean exists(String fileId)

Check if file exists
  • Parameters: fileId — unique id of the file
  • Returns: true if file exists, false otherwise

InputStream download(String fileId) throws FileNotFoundException

Donwload file
  • Parameters: fileId — unique id of the file
  • Returns: content of the file
  • Exceptions: FileNotFoundException — if file could not be found

boolean delete(String fileId) throws FileNotFoundException

Delete file
  • Parameters: fileId — unique id of the file
  • Returns: true if file was deleted
  • Exceptions: FileNotFoundException — if file could not be found

String getPath(String fileId) throws FileNotFoundException

Get file path from file id
  • Parameters: fileId — unique id of the file
  • Returns: file path of the file
  • Exceptions: FileNotFoundException — if file could not be found

Java API Interface

1
package com.apwide.file.api;
2
3
import java.io.FileNotFoundException;
4
import java.io.InputStream;
5
6
public interface FileManager {
7
/**
8
* Upload file
9
* @param fileName name of the file
10
* @param file file content
11
* @param maxFileSize max file size allowed (in bytes)
12
* @return generated unique id of the uploaded file
13
*/
14
String upload(String fileName, InputStream file, long maxFileSize);
15
16
/**
17
* Check if file exists
18
* @param fileId unique id of the file
19
* @return true if file exists, false otherwise
20
*/
21
boolean exists(String fileId);
22
23
/**
24
* Donwload file
25
* @param fileId unique id of the file
26
* @return content of the file
27
* @throws FileNotFoundException if file could not be found
28
*/
29
InputStream download(String fileId) throws FileNotFoundException;
30
31
/**
32
* Delete file
33
* @param fileId unique id of the file
34
* @return true if file was deleted
35
* @throws FileNotFoundException if file could not be found
36
*/
37
boolean delete(String fileId) throws FileNotFoundException;
38
39
/**
40
* Get file path from file id
41
* @param fileId unique id of the file
42
* @return file path of the file
43
* @throws FileNotFoundException if file could not be found
44
*/
45
String getPath(String fileId) throws FileNotFoundException;
46
}
Copied!
Last modified 2mo ago