Manage documents with code examples using Java APIs
Code examples that illustrate how the Bonita Engine Java APIs let you create, add a new version and attach documents to a Bonita process.
More information
You might want to consult the document documentation first.
A document is treated in a similar way to a variable in Bonita Engine database. It is defined in Bonita Studio or programmatically, and is stored in the Bonita Engine database. Inside a process instance, a document is a byte stream.
A document is treated in a similar way to a variable in Bonita Engine database. It is defined in Bonita Studio or programmatically, and is stored in the Bonita Engine database.
Set or update the value of a document in a process operation using a script
In a process operation, you might want to set / update the value of a document data using a groovy script instead of simply use a contract input.
The script should return a DocumentValue .
N.B: All the following examples deal with single document data. For multiple document data, just adapt the scripts to return a list of DocumentInput instead of a document input.
Create a new document
The following groovy scripts create a new document from an existing contract input / url / file.
import java.nio.file.Files
import org.bonitasoft.engine.bpm.contract.FileInputValue
import org.bonitasoft.engine.bpm.document.DocumentValue
// From a contractInput
def DocumentValue createNewDocument(FileInputValue fileFromContract) {
new DocumentValue(fileFromContract.content, fileFromContract.contentType, fileFromContract.fileName)
}
// From an url
def DocumentValue createNewDocument(String url) {
new DocumentValue(url)
}
// From an existing file on the fileSystem
def DocumentValue createNewDocument(File file) throws IOException {
def mimeType = Files.probeContentType(file.toPath())
new DocumentValue(file.bytes, mimeType, file.name)
}
Update the value of an existing document if a new content is provided
This following script is a way to address the use case of an optional update of the value of a document:
A user might want to change the value of a document, or not. If a new document is uploaded then the value of the data must be updated, if not then the data should be left unchanged.
import java.nio.file.Files
import org.bonitasoft.engine.bpm.contract.FileInputValue
import org.bonitasoft.engine.bpm.document.DocumentValue
// From a contractInput
def DocumentValue optionalUpdateDocument(long documentId, FileInputValue fileFromContract) {
return fileFromContract
? new DocumentValue(documentId, fileFromContract.content, fileFromContract.contentType, fileFromContract.fileName)
: new DocumentValue(documentId)
}
// From an url
def DocumentValue optionalUpdateDocument(long documentId, String url) {
return url
? new DocumentValue(documentId, url)
: new DocumentValue(documentId)
}
// From an existing file on the fileSystem
def DocumentValue optionalUpdateDocument(long documentId, File file) throws IOException {
return file
? new DocumentValue(documentId, file.bytes, Files.probeContentType(file.toPath()), file.name)
: new DocumentValue(documentId)
}
Create a case with documents
The following method, createCaseWithDocument
, creates a case and attaches documents to it.
import java.nio.file.Files
import org.bonitasoft.engine.bpm.document.DocumentValue
import org.bonitasoft.engine.exception.BonitaException
import org.bonitasoft.engine.expression.ExpressionBuilder
import org.bonitasoft.engine.operation.OperationBuilder
import com.bonitasoft.engine.api.ProcessAPI
/**
* In this example, `documents` is a map which link a document data (key) to a file (value)
* This map will be converted to operations to set document data with DocumentValue
* We assume in this example that all documents are initialized with Files (i.e contents), it could be URLs!
*/
def createCaseWithDocument(String processDefinitionName,
String processVersion,
Map<String, File> documents,
ProcessAPI processAPI) throws BonitaException {
def processDefinitionId = processAPI.getProcessDefinitionId(processDefinitionName, processVersion)
def operations = []
def listExpressionsContext = [:]
// ----- create setDocument operations -----
documents.keySet().each { documentName ->
def file = documents.get(documentName)
def mimeType = Files.probeContentType(file.toPath())
def documentValue = new DocumentValue(file.bytes, mimeType, file.name)
def expressionName = documentName + "Reference"
def expression = new ExpressionBuilder().createInputExpression(expressionName, DocumentValue.class.getName())
def operation = new OperationBuilder().createSetDocument(documentName, expression)
operations.add(operation)
listExpressionsContext.put(expressionName, documentValue)
}
// ----- start process instance -----
processAPI.startProcess(processDefinitionId, operations, listExpressionsContext)
}
Attach a document to a case
To attach a first version of a document data to a case, use the attachDocument
method of the process API.
To attach a new version of a document data to a case, use the attachDocumentNewDocumentVersion
method of the process API.
import java.nio.file.Files
import com.bonitasoft.engine.api.ProcessAPI
// Set the first value of the document `documentName` with the file `document`
// throw an exception if `documentName` has already a value
def attachDocumentToCase(ProcessAPI processAPI, long processInstanceId, String documentName, File document) {
def mimeType = Files.probeContentType(document.toPath())
processAPI.attachDocument(processInstanceId, documentName, document.name, mimeType, document.bytes)
}
// Update the value of the document `documentName` with the file `document`
// throw an exception if `documentName` doesn't already have a value
def attachNewDocumentVersionToCase(ProcessAPI processAPI, long processInstanceId, String documentName, File document) {
def mimeType = Files.probeContentType(document.toPath())
processAPI.attachNewDocumentVersion(processInstanceId, documentName, document.name, mimeType, document.bytes)
}
Delete documents of archived cases based on archive date
The use case is to delete the documents of archived cases older than a certain date.
searchArchivedDocumentsOlderThanArchivedDate
look for archived documents
deleteArchivedDocumentsOlderThan
delete the content of the document
Although the document binary will be deleted there will still be records in the database. The Purge Tool should be used to completely get rid of the document from the database to free disk space. |
//Search for documents of archived cases with archived date older than "archivedDate"
def SearchResult searchArchivedDocumentsOlderThanArchivedDate(ProcessAPI processAPI, long archivedDate, int startIndex, int maxResults){
processAPI.searchArchivedDocuments(new SearchOptionsBuilder(startIndex, maxResults).with {
lessOrEquals(ArchivedDocumentsSearchDescriptor.ARCHIVE_DATE, archivedDate)
done()
})
}
//Delete archived documents older than archivedDate
def deleteArchivedDocumentsOlderThan(ProcessAPI processAPI, long archivedDate) {
int startIndex = 0
int maxResults = 100
def searchResult = searchArchivedDocumentsOlderThanArchivedDate(processAPI, archivedDate, startIndex, maxResults)
while(searchResult.count > 0){
searchResult.result.each { archivedDocument ->
processAPI.deleteContentOfArchivedDocument(archivedDocument.getId())
}
startIndex += maxResults
searchResult = searchArchivedDocumentsOlderThanArchivedDate(processAPI, archivedDate, startIndex, maxResults)
}
}
//Then just call the method with desired archivedDate
deleteArchivedDocumentsOlderThan(processAPI, archivedDate)