I'm developing a web service interface for the BPM packages of the Oracle BPM API to handle process instance operations, as the Human Workflow Services only handles task operations.
The Oracle BPM API Javadoc: http://docs.oracle.com/cd/E23943_01/apirefs.1111/e25378/
The part I'm having problems is with process instance attachments, I get a null from getContent and getInputStream from IProcessAttachment whenever I call getProcessAttachments or getProcessInstance.getAttachment from the InstanceQueryService.
Maybe the problem might be when I'm adding attachments in the first place; the code for adding attachment is based on Oracle's ATeam Custom Worklist example, specifically from http://java.net/projects/bpmworklist/sources/worklist/content/trunk/src/main/java/com/oracle/ateam/domain/MTaskList.java?rev=115#L377, addAttachment method at line 377.
The example above is for task attachments, I adapted it for process instance attachments:
Oracle BPM API imports:
import oracle.bpel.services.bpm.common.IBPMContext;
import oracle.bpel.services.workflow.task.model.ObjectFactory;
import oracle.bpm.services.common.exception.BPMException;
import oracle.bpm.services.instancemanagement.model.IProcessAttachment;
import oracle.bpm.services.instancemanagement.model.IProcessInstance;
import oracle.bpm.services.instancemanagement.model.impl.ProcessAttachment;
(...)
public @WebResult(name = "attachment")
Attachment addAttachment(@WebParam(name = "context") BPMContext context,
@WebParam(name = "instanceId") String instanceId,
@WebParam(name = "attachment") Attachment attachment)
throws BPMFault {
try {
// Creates a concrete oracle.bpel.services.workflow.verification.impl.WorkflowContext
// as there's a bug in the API where it casts to it explicitly.
IBPMContext ctx = (IBPMContext) context.toWorkflowContext();
IProcessInstance processInstance = getInstanceQueryService().getProcessInstance(ctx, instanceId);
IProcessAttachment processAttachment = new ProcessAttachment(new ObjectFactory().createAttachment());
processAttachment.setName(attachment.getName());
// content is a String.
// impl: this.content = content;
processAttachment.setContent(attachment.getContent());
// getInputStream's impl:
// return org.apache.commons.io.IOUtils.toInputStream(this.content);
processAttachment.setInputStream(attachment.getInputStream());
// processAttachment.getInputStream() does return the correct content at this point.
processAttachment.setMimeType(attachment.getMimeType());
processAttachment.setDescription(attachment.getDescription());
return new Attachment(getInstanceManagementService().addAttachment(ctx, processInstance, processAttachment));
} catch (BPMException e) {
throw new BPMFault(e);
} catch (Throwable t) {
t.printStackTrace();
throw new BPMFault(t);
}
}
public @WebResult(name = "attachment")
Attachment getProcessAttachment(
@WebParam(name = "context") BPMContext context,
@WebParam(name = "instanceId") String instanceId,
@WebParam(name = "name") String attachmentName) throws BPMFault {
try {
IBPMContext ctx = (IBPMContext) context.toWorkflowContext();
IProcessInstance processInstance = getInstanceQueryService().getProcessInstance(ctx, instanceId);
// Either this processInstance or getInstanceQueryService().getProcessAttachment
// return the same IProcessAttachment objects with a null inputStream.
if (processInstance.getAttachment() != null) {
for (Object processAttachmentObj : processInstance.getAttachment()) {
IProcessAttachment processAttachment = (IProcessAttachment) processAttachmentObj;
if (attachmentName.equals(processAttachment.getName())) {
Attachment attachment = new Attachment(processAttachment);
// loadContentFrom's impl:
// this.content = IOUtils.toString(processAttachment.getInputStream());
//
// NPEs because getInputStream returns null.
attachment.loadContentFrom(processAttachment);
return attachment;
}
}
}
return null;
} catch (BPMException e) {
throw new BPMFault(e);
} catch (Throwable t) {
t.printStackTrace();
throw new BPMFault(t);
}
}
What is the correct way to add and download attachments to a process instance using this API?