Downloading Attachments from Work Items


I published how to upload attachments to work items some time ago. The missing piece was how to download them. I was able to figure that out now and want to share it.

License and how to get started with the RTC API’S

As always, our lawyers reminded me to state that the code in this post is derived from examples from Jazz.net as well as the RTC SDK. The usage of code from that example source code is governed by this license. Therefore this code is governed by this license, which basically means you can use it for internal usage, but not sell. Please also remember, as stated in the disclaimer, that this code comes with the usual lack of promise or guarantee. Enjoy!

If you just get started with extending Rational Team Concert, or create API based automation, start with the post Learning To Fly: Getting Started with the RTC Java API’s and follow the linked resources.

You should be able to use the following code in this environment and get your own automation or extension working.

To keep it simple this example is, as many others in this blog, based on the Jazz Team Wiki entry on Programmatic Work Item Creation and the Plain Java Client Library Snippets. The example in this blog shows RTC Client and Common API.

Download the code here

Solution Overview

The example below is based on the wiki entry on Programmatic Work Item Creation. I basically use the main() and run() operation for the parameter handling. The code below is inserted at the end of the run() operation. The WorkItemOperation part is not used in this case.

The code below shows how to get to the attachments resolving the work item references and using the endpoint to narrow down to the attachments. See the post about manipulation references using the Plain Java Client Library for more details on references.

Once the IAttachment is resolved it is passed to the saveAttachment() method which does the download and saving part.

IWorkItem workItem = workItemClient.findWorkItemById(id, IWorkItem.FULL_PROFILE, null);

IWorkItemCommon common = (IWorkItemCommon) teamRepository.getClientLibrary(IWorkItemCommon.class);
IWorkItemReferences workitemReferences = common.resolveWorkItemReferences(workItem, null);
List references = workitemReferences.getReferences(WorkItemEndPoints.ATTACHMENT);
for (IReference iReference : references) {
	IAttachmentHandle attachHandle = (IAttachmentHandle) iReference.resolve();
	IAuditableClient auditableClient = (IAuditableClient) teamRepository.getClientLibrary(IAuditableClient.class);
	IAttachment attachment = (IAttachment) auditableClient.resolveAuditable((IAttachmentHandle) attachHandle,
		IAttachment.DEFAULT_PROFILE, null);
	saveAttachment(teamRepository, attachment);
}

The saveAttachment() method basically creates a new file with the name stored in the attachment and uses the ITeamRepository.contentManager() to get the content into the file. The code below uses the file name stored in the attachment for simplicity, but you can provide a different name and location.

/**
 * Save the attachment
 */
public static void saveAttachment(ITeamRepository teamRepository,IAttachment attachment) throws TeamRepositoryException {
	try {
		File save = new File(attachment.getName());

		OutputStream out = new FileOutputStream(save);
		try {
			teamRepository.contentManager().retrieveContent(attachment.getContent(), out, null);
		} finally {
			out.close();
		}
	} catch (FileNotFoundException e) {
		// TODO Auto-generated catch block
	} catch (IOException e) {
		// TODO Auto-generated catch block
	}
}

As usual the exception handling is very basic and you might want to improve that if using this code. I hope this is helpful and saves some cycles searching through the RTC SDK.