Wstęp
Dokument w systemie PlusWorkflow zawiera informację o pliku(nazwa, rozmiar, wersja itp.) i indeksach (polach zdefiniowanych w klasie dokumentów). Dokumenty są zawsze zapisywane w archiwum systemowym. Mogą być również przypisywane do zadań.
Wersja pliku, a dokument
W systemie PlusWorkflow wersjonowane są wyłącznie pliki, a nie dokumenty. Plik zawsze posiada wersję, natomiast dokument odnosi się do najnowszej wersji pliku z którym jest powiązany.
Przydatne klasy:
- DocumentService - zarządzanie dokumentami
- DocumentFinder - wyszukiwanie dokumentów
- ActivityDocumentService - wyszukiwanie i zarządzanie dokumentami w zadaniach/procesach
DocumentService documentService = ServiceFactory.getDocumentService(); DocumentFinder documentFinder = FinderFactory.getDocumentFinder(); ActivityDocumentService activityDocumentService = ServiceFactory.getActivityDocumentService();
Operacje na dokumentach
Do wykonywania operacji na dokumentach należy używać usługi DocumentService. Umożliwia ona dodawania nowych dokumentów, zmianę indeksów, usunięcie, dołączanie lub odłączenie z/do procesu/zadania.
Przykłady:
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" );//parametry opcjonalne jeżeli nie zostaną podane dokument zostanie dodany tylko do archiwum definition.setProcessId( "103_proces1" );// nie będzie dołączony do żadnego procesu WfDocument document = documentService.addDocument( definition );
documentService.attachDocumentToProcess( documentId, documentClassId, "admin", "103_proces1", "103_proces1_zadanie1" );// podajemy id dokumentu i id klasy documentService.attachDocumentToProcess( wfDocument, "admin", "103_proces1", "103_proces1_zadanie1" );// lub obiekt dokumentu
documentService.detachDocumentFromProcess( doc.getId(), doc.getDocumentClassId(), processId);// podajemy id dokumentu i id klasy documentService.detachDocumentFromProcess( wfDocument, processId);// lub obiekt dokumentu
WfDocument document = documentService.getDocument( documentId, documentClassId ); IndexInfo indexInfo1 = document.getIndexByName( "idx1" );//pobieramy indeks po nazwie IndexInfo indexInfo2 = document.getIndexById( 1L );//pobieramy indeks po id Long id = indexInfo1.getId();// id indeksu String name = indexInfo1.getName();// nazwa indeksu IndexType type = indexInfo1.getType();// STRING, INTEGER, LIST, DATE, DOUBLE Object value = indexInfo1.getValue();// wartość indeksu, typ odpowiedni do 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; } //Fukncje ułatwiajace dostęp do wartości indeksów: String stringValue=(String)document.getIndexValue( "idx1" ); Date dateValue=(Date)document.getIndexValue( 1L );
WfDocument document = documentService.getDocument( documentId, documentClassId ); IndexInfo indexInfo1 = document.getIndexByName( "idx1" );// pobieramy indeks po nazwie //ustawienie wartości indeksów indexInfo1.setValue( "abc" );//typ STRING document.setIndexValue( 2L,new Date() );//poprzez id, typ DATE document.setIndexValue( "idx3",333L );//poprzez nazwę, typ LONG document.setIndexValue("idx4",0.4);//type DOUBLE //Typy wprowadzanych wartości muszą odpowiadać typom indeksów documentService.updateDocument( document );//funkcja zapisuje zmiany w bazie danych
Wyszukiwanie dokumentów
Do wyszukiwania dokumentów należy używać klasy DocumentFinder
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() );//wartości indeksów po których chcemy wyszukiwać List<Sorter> sorters=new ArrayList<Sorter>(); sorters.add( new Sorter("3",SortDirection.DESC) );//sorujemy malejąco po indeksie o id 3 CountedResult<WfDocument> result=documentFinder.findByIndexes( idx, sorters, documentClassId, start, limit ); long total=result.getTotal();//liczba wszystkich pasujących dokumentów List<WfDocument> documents=result.getData();//lista znalezionych dokumentów ograniczona przez start i limit
Uwaga dot. metody getDocumentsFromProcess
Metoda getDocumentsFromProcess pobiera dokumenty dołączone tylko do ostatniego zadania procesu tj. takiego, które ostatnie zmieniło swój stan.
Co może to mieć znaczenie w przypadku występowania zadań równoległych. Bowiem dokumenty zostaną pobrane tylko z jednego zadania tj. tego które było zmienione ostatnie. Natomiast możliwość pobrania dokumentów z więcej niż jednego zadania daje metoda getDocumentsFromOpenedActivities, która pobiera dokumenty z podanego procesu podłączone do wszystkich otwartych zadań.
Przedstawiona wyżej metoda wyszukuje dokumenty o indeksach równych (operator '=' ) podanym wartościom i wszystkie warunki łączy operatorem logicznym AND. Jeżeli chcemy stworzyć bardziej zaawansowane warunki wyszukiwania możemy wykorzystać następującą metodę:
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 ) );//definiujemy operatory wyszukiwania CountedResult<WfDocument> result = documentFinder.findByIndexes( filters, sorters, documentClassId, start, limit );
W powyższym przykładzie zdefiniowaliśmy operatory wyszukiwania, lecz warunki nadal są połączone logicznym operatorem AND. Aby to zmienić możemy wykorzystać grupowanie filtrów:
List<IndexFilter> filters = new ArrayList<IndexFilter>(); GroupIndexFilter gif = new GroupIndexFilter( LogicOperator.OR );//tworzymy grupę warunków połączonych operatorem OR gif.addFilter( new SimpleIndexFilter( 3L, date, FilterOperator.GT ) ); gif.addFilter( new SimpleIndexFilter( 1L, "%test%", FilterOperator.LIKE ) ); GroupIndexFilter subGroup=new GroupIndexFilter(LogicOperator.AND);// tworzymy kolejną grupę warunków subGroup.addFilter( new SimpleIndexFilter( 5L, "abc") ); subGroup.addFilter( new SimpleIndexFilter( 2L, 555 ) ); gif.addFilter( subGroup );//do grupy warunków możmy dodać inną grupę tworząc drzewo warunków filters.add( gif ); CountedResult<WfDocument> result = documentFinder.findByIndexes( filters, sorters, documentClassId, start, limit );
Powyższy przykład utworzy następujący warunek: idx_3 > date OR idx_1 = '%test' OR ( idx_5 = 'abc' AND idx_2 = 555 )
CountedResult<WfDocument> result = documentFinder.findByIndexes( filters, sorters, documentClassId, start, limit, WfDocument.JOIN_DOC_CLASS ); List<WfDocument> docs= documentFinder.getDocumentsFromActivity( activityId, WfDocument.JOIN_DOC_CLASS ); WfDocument doc=docs.get(0); String documentClassName=doc.getFile().getDocumentClass().getName();//bez podania WfDocument.JOIN_DOC_CLASS wywołanie tej linii spowodowałoby błąd
Podając argument WfDocument.JOIN_DOC_CLASS dołączymy informacje o klasie dokumentów.
Wyszukiwanie i zarządzanie dokumentami w zadaniach/procesach
Do zarządzania dokumentami i ich wyszukiwania w zadaniach oraz pobierania szczegółowych informacji o nich można używać usługi ActivityDocumentService.
Umożliwia ona :
- pobranie informacji o podłączonych dokumentach (w tym informacje o : zadaniach, procesach, plikach, wersji pliku oraz użytkowniku który podłączył)
- sprawdzenie czy jest podłączony co najmniej jeden dokument
- odłączenie wszystkich dokumentów
- odłączanie dokumentu z procesu/zadania
- odłączenie pliku
- modyfikację dokumentu
- przepisanie dokumentu z zadania do kolejnych zadań
- wyszukiwanie dokumentów wg kryteriów
Szczegóły dostępne w najnowszym javadoc.
ActivityDocumentService ads = ServiceFactory.getActivityDocumentService(); Long fileId = 100L; List<ActivityDocument> documents = ads.getActivityDocuments( fileId, ActivityDocument.JOIN_USER );
Drugi parametr jest opcjonalny.
Jeśli w zwróconych obiektach, któreś informacje nie są wypełnione to w zależności od potrzeb trzeba jako dodatkowe parametry podać stałe z ActivityDocument: JOIN_USER, JOIN_VERSION, JOIN_FILE, JOIN_PROCESS, JOIN_ACTIVITY.
Można podać więcej niż jedną stałą, dodając je jako kolejne parametry.
Do wyszukiwania dokumentów wg kryteriów dostępne są usługi : findOne, findByCriteria, getAll, getCountedResult itp.
Implementacja
WfDocument
Klasa WfDocument reprezentuje dokument w systemie. Tworzy powiązanie między klasami WfFile, WfFileVersion oraz indeksami dokumentu(wartościami z tabeli pm_idx_000x).
WfFile
Klasa WfFile reprezentuje plik w systemie. Zawiera podstawowe informacje o pliku.
WfFileVersion
Klasa WfFileVersion reprezentuje wersję pliku w systemie. Relacja między obiektami WfFile, a WfFileVersion to 1-do-1