Introduction
A document in PlusWorkflow contains information about the file (name, size, version, etc.) and indexes (fields defined in the document class). Documents are always saved in the system archive. They can also be assigned to tasks.
File version vs. document
In PlusWorkflow, only files are versioned, not documents. A file always has a version, while a document refers to the latest version of the file it is associated with.
Useful classes:
- DocumentService - document management
- DocumentFinder - searching for documents
- ActivityDocumentService - searching and managing documents in tasks/processes
DocumentService documentService = ServiceFactory.getDocumentService(); DocumentFinder documentFinder = FinderFactory.getDocumentFinder(); ActivityDocumentService activityDocumentService = ServiceFactory.getActivityDocumentService();
Operations on documents
Use DocumentService to perform operations on documents. It allows you to add new documents, change indexes, delete, attach or detach from/to a process/task.
Examples:
InputStream inputStream = ... DocumentClassService documentClassService=ServiceFactory.getDocumentClassService(); DocumentService documentService=ServiceFactory.getDocumentService(); DocumentClass documentClass = documentClassService.getDocumentClass( "klasa" ); Map<Long, Object> idx = new HashMap<Long, Object>(); idx.put( 1L, "wartość tekstowa" ); idx.put( 2L, 555 ); idx.put( 3L, new Date() ); DocumentDefinition definition = new DocumentDefinition(); definition.setDocumentClassId( documentClass.getId() ); definition.setFileName( "nazwa.pdf" ); definition.setDescription( "opis" ); definition.setUserName( "admin" ); definition.setIndexes( idx ); definition.setInputStream( inputStream ); definition.setActivityId( "103_proces1_zadanie1" );//optional parameters if not specified the document will only be added to the archive definition.setProcessId( "103_proces1" );// will not be attached to any process WfDocument document = documentService.addDocument( definition );
documentService.attachDocumentToProcess( documentId, documentClassId, "admin", "103_proces1", "103_proces1_zadanie1" );// specify document id and class id documentService.attachDocumentToProcess( wfDocument, "admin", "103_proces1", "103_proces1_zadanie1" );// or document object
documentService.detachDocumentFromProcess( doc.getId(), doc.getDocumentClassId(), processId);// specify document id and class id documentService.detachDocumentFromProcess( wfDocument, processId);// or document object
WfDocument document = documentService.getDocument( documentId, documentClassId ); IndexInfo indexInfo1 = document.getIndexByName( "idx1" );//download the index by name IndexInfo indexInfo2 = document.getIndexById( 1L );//download the index by id Long id = indexInfo1.getId();// id indeksu String name = indexInfo1.getName();// index name IndexType type = indexInfo1.getType();// STRING, INTEGER, LIST, DATE, DOUBLE Object value = indexInfo1.getValue();// index value, type appropriate to IndexType if ( type == IndexType.DATE ) { Date dateValue = (Date) value; } else if ( type == IndexType.LONG ) { Long longValue = (Long) value; } else if ( type == IndexType.DOUBLE ) { Double doubleValue = (Double) value; } else {// STRING lub LIST String stringValue = (String) value; } //Fucnctions to facilitate access to index values: String stringValue=(String)document.getIndexValue( "idx1" ); Date dateValue=(Date)document.getIndexValue( 1L );
WfDocument document = documentService.getDocument( documentId, documentClassId ); IndexInfo indexInfo1 = document.getIndexByName( "idx1" );// download the index by name //ustawienie wartości indeksów indexInfo1.setValue( "abc" );//typ STRING document.setIndexValue( 2L,new Date() );//by id, type DATE document.setIndexValue( "idx3",333L );//by name, type LONG document.setIndexValue("idx4",0.4);//type DOUBLE //The types of values to be entered must match the index types documentService.updateDocument( document );//function saves changes to the database
Document Search
Use the DocumentFinder class to search for documents
DocumentFinder documentFinder=FinderFactory.getDocumentFinder(); Map<Long, Object> idx = new HashMap<Long, Object>(); idx.put( 1L, "wartość tekstowa" ); idx.put( 2L, 555 ); idx.put( 3L, new Date() );//index values by which we want to search List<Sorter> sorters=new ArrayList<Sorter>(); sorters.add( new Sorter("3",SortDirection.DESC) );//sort descending by index with id 3 CountedResult<WfDocument> result=documentFinder.findByIndexes( documentClassId, idx, sorters, start, limit ); long total=result.getTotal();//number of all matching documents List<WfDocument> documents=result.getData();//list of documents found limited by start and limit
Note on the getDocumentsFromProcess method
The getDocumentsFromProcess method retrieves documents attached only to the last process task, i.e. the one that last changed its state.
This may be important if there are parallel tasks. Because the documents will be retrieved only from one task, i.e. the one that was changed last. On the other hand, the ability to retrieve documents from more than one task is provided by the getDocumentsFromOpenedActivities method, which retrieves documents from the specified process connected to all open tasks.
The method presented above searches for documents with indexes equal (operator '=' ) to the given values and combines all conditions with the logical operator AND. If you want to create more advanced search conditions, you can use the following method:
DocumentFinder documentFinder = FinderFactory.getDocumentFinder(); List<IndexFilter> filters = new ArrayList<IndexFilter>(); filters.add( new SimpleIndexFilter( 3L, date, FilterOperator.GT ) );//Greater then '>' filters.add( new SimpleIndexFilter( 1L, "%test%", FilterOperator.LIKE ) );//define search operators CountedResult<WfDocument> result = documentFinder.findByIndexes( documentClassId, filters, sorters, start, limit );
In the above example, we have defined search operators, but the conditions are still connected by a logical AND operator. To change this, we can use filter grouping:
List<IndexFilter> filters = new ArrayList<IndexFilter>(); GroupIndexFilter gif = new GroupIndexFilter( LogicOperator.OR );//create a group of conditions connected by OR operator gif.addFilter( new SimpleIndexFilter( 3L, date, FilterOperator.GT ) ); gif.addFilter( new SimpleIndexFilter( 1L, "%test%", FilterOperator.LIKE ) ); GroupIndexFilter subGroup=new GroupIndexFilter(LogicOperator.AND);// create another group of conditions subGroup.addFilter( new SimpleIndexFilter( 5L, "abc") ); subGroup.addFilter( new SimpleIndexFilter( 2L, 555 ) ); gif.addFilter( subGroup );//to a group of conditions we can add another group creating a tree of conditions filters.add( gif ); CountedResult<WfDocument> result = documentFinder.findByIndexes( documentClassId, filters, sorters, start, limit );
The above example will create the following condition: idx_3 > date OR idx_1 = '%test' OR ( idx_5 = 'abc' AND idx_2 = 555 )
CountedResult<WfDocument> result = documentFinder.findByIndexes( documentClassId, filters, sorters, start, limit, WfDocument.JOIN_DOC_CLASS ); List<WfDocument> docs= documentFinder.getDocumentsFromActivity( processId, activityId, WfDocument.JOIN_DOC_CLASS ); WfDocument doc=docs.get(0); String documentClassName=doc.getFile().getDocumentClass().getName();//Without specifying WfDocument.JOIN_DOC_CLASS, calling this line would result in an error
Specifying the WfDocument.JOIN_DOC_CLASS argument will include the document class information.
Searching and managing documents in tasks/processes
You can use ActivityDocumentService to manage and search for documents in tasks and retrieve detailed information about them.
It allows you to :
- downloading information about connected documents (including information about: tasks, processes, files, file version and user who connected)
- check if at least one document is connected
- disconnecting all documents
- disconnecting a document from a process/task
- disconnecting a file
- document modification
- rewriting a document from a task to subsequent tasks
- searching for documents according to criteria
Details available in the latest javadoc.
ActivityDocumentService ads = ServiceFactory.getActivityDocumentService(); Long fileId = 100L; List<ActivityDocument> documents = ads.getActivityDocuments( fileId, ActivityDocument.JOIN_USER );
The second parameter is optional.
If in the returned objects, some information is not filled in then, depending on your needs, you need to provide constants from ActivityDocument as additional parameters: JOIN_USER, JOIN_VERSION, JOIN_FILE, JOIN_PROCESS, JOIN_ACTIVITY.
You can specify more than one constant by adding them as further parameters.
For searching documents by criteria, services are available : findOne, findByCriteria, getAll, getCountedResult, etc.
Implementation
WfDocument
The WfDocument class represents a document in the system. It creates a link between the classes WfFile, WfFileVersion and the indexes of the document(values from the pm_idx_000x table).
WfFile
The WfFile class represents a file in the system. It contains basic information about the file.
WfFileVersion
The WfFileVersion class represents the version of a file in the system. The relationship between WfFile objects and WfFileVersion is 1-to-1.