Downloading and uploading a file in form

I need to create a task in a workflow where a user can download a file that was uploaded in a previous task and possibly upload an updated version of the file with the same field name. If I add the same field in the form as a download and an upload it form gives an error that the field already exists. Doing two tasks (one for the download and one to upload the update) isn’t an option.

Any suggestions on how to implement this?

Are you using rest api or java api to handle file upload and download?

Neither. They are form elements in a cam-form.

this thread might be related: Use the same name in cam-variable-name

Thanks for the suggestion but that doesn’t work. You can’t add the same variable name twice in a form. It gives an error stating that the variable name has already been added. Thus the reason for asking this question.

I have a similar scenario where a file previously uploaded (through a user task embedded form) may be updated in a following user task.
Problem is that if I use cam-variable-name directive to upload file with the same variable name, and if user does not upload any new file, the original variable is also erased :frowning:
@Craig_Cudmore were you able to solve this problem?

Thanks and Regards
Chaitanya

Unfortunately I wasn’t able to find a solution for this. I tried writing some Java code to call as a service task that would replace the file contents of the variable with the contents of a new variable but was never able to get it fully working. So we redesigned the business process around this limitation.

I was also not able to solve the problem using CamForm SDK. So I found a workaround using JavaDelegates.
The first user task uses cam-variable-name directive for file variable as usual. The subsequent user tasks which want to provide update/overwrite facility for the same process (file) variable, can then include the same cam-variable-name directive block.
However, for these subsequent user tasks, I attached two Java Delegates. One at start which will cache the existing file variable into a local variable. The other at end of the same user task which will restore this local variable into process variable if user has not uploaded newer version. If user uploads newer version of the file, then the local variable will be silently discarded.
The code for the two delegates will be as follows.

package test.camunda;

import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.camunda.bpm.engine.delegate.JavaDelegate;
import org.camunda.bpm.engine.variable.value.FileValue;

// This delegate MUST be attached BEFORE the user task (as start delegate) where
// embedded user form is being reused and file variables may be overwritten.
public class FileCachingDelegate implements JavaDelegate {

    @Override
    public void execute(DelegateExecution execution) throws Exception {
        // Cache the file variables before they might be overwritten.
        if (execution.hasVariable("fileVar")){
            execution.setVariableLocal("cachedFileVar", (FileValue) execution.getVariableTyped("fileVar"));
        }
    }    
}

and

package test.camunda;

import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.camunda.bpm.engine.delegate.JavaDelegate;
import org.camunda.bpm.engine.variable.value.FileValue;

// This delegate MUST be attached AFTER the user task (as end delegate) where
// embedded user form is being reused and file variables may be overwritten.
public class FileRestorationDelegate implements JavaDelegate {

    @Override
    public void execute(DelegateExecution execution) throws Exception {
        FileValue fileVar = (FileValue) execution.getVariableTyped("fileVar");
        // Only restore the cached file variable if user has NOT updated the value of actual file variable.
        // If user has updated the value, then cached variable is redundant and can be ignored.
        if (fileVar.getFilename().isEmpty()){
            execution.setVariable("fileVar", (FileValue) execution.getVariableLocalTyped("cachedFileVar"));
        }
        execution.removeVariableLocal("cachedFileVar");
    } 
}

Unfortunately, this will still not solve the problem of showing the file download link and upload link in the same form using the same variable. But the workaround for that is also similar.

  1. In the start JavaDelegate of the user task, copy the file variable first into some other variable
  2. In the user form, display the download link for the copied variable and also provide cam-variable-name with original file variable name for file upload.
  3. If user uploads a new file then ignore the originally copied variable, otherwise restore the copied variable into original variable in the end JavaDelegate for the task.

Hope this helps.
Chaitanya

2 Likes