Wstęp
Przydatne klasy:
ProcessService processService = ServiceFactory.getProcessService(); ActivityService activityService = ServiceFactory.getActivityService(); ProcessFinder processFinder =FinderFactory.getProcessFinder(); ActivityFinder activityFinder=FinderFactory.getActivityFinder();
Procesy
ProcessBuilderDefinition definition = new ProcessBuilderDefinition(); definition.setPackageId( "suncode" ); definition.setCreator( "admin" ); definition.setCreatorPassword( "xxxxxx" ); definition.setProcessDefId( "proces1" ); Map<String, Object> variables = new HashMap<String, Object>(); variables.put( "zmienna1", "abc" ); definition.setVariables( variables ); String processId = processService.createProcess( definition ); // Pobieranie informacji o procesie Process process = processService.getProcess( processId ); process = processService.getProcess( processId, Process.JOIN_PROCESS_DEFINITION );// jeżeli chcemy mieć dostęp // do definicji procesu String name = process.getName(); String desc = process.getDescription(); // Definicja procesu ProcessDefinition processDef = process.getProcessDefinition(); String packageId = processDef.getPackageId();// bez Process.JOIN_PROCESS_DEFINITION rzuci wyjątek String processDefId = processDef.getProcessDefinitionId(); // Zmiana wartości zmiennych procesu Map<String, Object> ctx = processService.getProcessContext( processId ); ctx.put( "zmienna", "abc" ); processService.setProcessContext( processId, ctx ); //Usunięcie procesu processService.deleteProcess( processId );
Do wyszukiwania procesów należy używać klasy ProcessFinder
//definijemy wartości zmiennych procesu, który chcemy znaleźć Map<String, Object> indexes = new HashMap<String, Object>(); indexes.put( "textcol", "text5" ); indexes.put( "datecol", DateUtils.parseDate( "2014-02-12", "yyyy-MM-dd" ) ); indexes.put( "doublecol", 4.3); indexes.put( "intcol", 5 ); List<Process> processes = finder.findByIndexes( processDefId, indexes ); Process p = processes.get( 0 );//znaleziony proces //odczyt indeksów String textcol = (String) p.getIndexValue( "textcol" ); Date datecol = (Date) p.getIndexValue( "datecol" ); Double doublecol = (Double) p.getIndexValue( "doublecol" ); Integer intcol = (Integer) p.getIndexValue( "intcol" );
Przedstawiona wyżej metoda wyszukuje procesy 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ę:
List<IndexFilter> filters = new ArrayList<IndexFilter>(); filters.add( new SimpleIndexFilter( "datecol", date, FilterOperator.GT ) );// Greater then '>' filters.add( new SimpleIndexFilter( "textcol", "%text%", FilterOperator.LIKE ) ); List<Process> result = finder.findByIndexes( processDefId, filters );
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>(); // tworzymy grupę warunków połączonych operatorem OR GroupIndexFilter gif = new GroupIndexFilter( LogicOperator.OR ); // tworzymy pierwszą podgrupę warunków GroupIndexFilter subGroup1 = new GroupIndexFilter( LogicOperator.AND ); subGroup1.addFilter( new SimpleIndexFilter( "datecol", date, FilterOperator.GT ) ); subGroup1.addFilter( new SimpleIndexFilter( "textcol", "%text%", FilterOperator.LIKE ) ); // tworzymy drugą grupę warunków GroupIndexFilter subGroup2 = new GroupIndexFilter( LogicOperator.AND );// tworzymy kolejną grupę warunków subGroup2.addFilter( new SimpleIndexFilter( "textcol", "text3" ) ); subGroup2.addFilter( new SimpleIndexFilter( "intcol", 3 ) ); gif.addFilter( subGroup1 );// do grupy warunków możmy dodać inną grupę tworząc drzewo warunków gif.addFilter( subGroup2 ); filters.add( gif ); List<Process> result = finder.findByIndexes( processDefId, filters );
Powyższy przykład utworzy następujący warunek: ( ( datecol > '2014-02-11' and textcol like '%text%' ) or ( textcol = 'text3' and intcol = 3 ) )
Zadania
// Pobieranie informacji o zadaniu Activity activity=activityService.getActivity( processId, activityId ); String activityDefId=activity.getActivityDefinitionId(); String desc=activity.getDescription(); String name=activity.getName(); ActivityState state=activity.getState();//RUNNING, NOT_STARTED, SUSPENDED, COMPLETED, TERMINATED, ABORTED Date created=activity.getCreatedTime();//data utworzenia zadani Date started=activity.getStartedTime();//data uruchomienia // Zmiana wartości zmiennych zadania Map<String,Object> activityContext=activityService.getActivityContext( processId, activityId ); activityContext.put( "zmienna", "wartość" ); activityService.setActivityContext( processId, activityId, activityContext ); //Otworzenie zadania przez podanego użytkownika. Jeżeli zadanie ma status 'Oczekujące na uruchomienie' //i jest przypisane do podanego użytkownika to poniższa funkcja spowoduje przypisanie zadania //do podanego użytkownia i zmieni status na 'Uruchomione' activityService.openActivity( userName, userPassword, processId, activityId ); //Akceptacja zadania String executor="jkowalski";//użytkownik akceptujący String actionName="akceptacja";//nazwa akcji z mapy Map<String,Object> map=new HashMap<String,Object>(); map.put( "zmienna", "wartosc" );//mapa nie zostanie całkowicie zastąpiona podaną //zostaną nadpisane tylko podane wartości AcceptationDefinition acceptation=new AcceptationDefinition( processId, activityId, executor, actionName ); acceptation.setContextMap( map );//opcjonalnie acceptation.setIgnoreValidators( false ); //opcjonalne wymuszenie walidacji akceptacji //Akceptacja zadania, na dowolnym użytkowniku (ownerLogin), jeśli jest on właścicielem zadania (tj.zostało przez niego otwarte w PWFL) String ownerLogin = "jkowalski"; AcceptationDefinition acceptation = new AcceptationDefinition( procId, activId, ownerLogin, actionName ); activityService.acceptActivity( acceptation ); //Akceptacja zadania, na dowolnym użytkowniku (approverLogin), nawet jeśli nie jest on właścicielem zadania String approverLogin = "test"; assignmentService.assignActivityToUser( procId, activId, approverLogin ); AcceptationDefinition acceptation = new AcceptationDefinition( procId, activId, approverLogin, actionName ); acceptation.setIgnoreOwnerShip( true ); activityService.acceptActivity( acceptation );
Uwaga dot. akceptacji zadania
Powyżej wspomniana akceptacja zadania nie może być uruchamiana w tej samej transakcji co tworzenie procesu w którego dotyczy akceptowane zadanie. Wtedy co prawda akceptacja powiedzie się, ale w logach polecą wyjątki dot. powiadomień systemowych, które przez to nie zostaną poprawnie wykonane.
Jeśli jest potrzeba, aby akceptacja zadania była wykonana zaraz po utworzeniu procesu tego zadania (np w jednym zadaniu automatycznym/zaplanowanym itp.), to trzeba wymusić stworzenie procesu w osobnej transakcji. Co można zrobić zgodnie z instrukcją Opis używania transakcji.
Uwaga dot. walidacji akceptacji
Przy walidacji zadania przez API brane są pod uwagę tylko walidatory komponentowe.
// Pobieranie otwartych zadań List<Activity> activities = activityFinder.findOpenedActivities( processId ); for ( Activity activity : activities ) { activityId = activity.getActivityId(); } // Pobieranie zadań przypisanych do użytkownika activities = activityFinder.findActivitiesAssignedToUser( userName, Activity.JOIN_PROCESS ); for ( Activity activity : activities ) { activityId = activity.getActivityId(); Process process = activity.getProcess();// tylko gdy użyliśmy Activity.JOIN_PROCESS } // Pobieranie zadań z procesu activities = activityFinder.findByProcessId( processId, Activity.JOIN_PROCESS ); for ( Activity activity : activities ) { activityId = activity.getActivityId(); Process process = activity.getProcess();// tylko gdy użyliśmy Activity.JOIN_PROCESS }