com.netgrif.application.engine.petrinet.service.ProcessRoleService Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of application-engine Show documentation
Show all versions of application-engine Show documentation
System provides workflow management functions including user, role and data management.
package com.netgrif.application.engine.petrinet.service;
import com.netgrif.application.engine.auth.domain.IUser;
import com.netgrif.application.engine.auth.domain.LoggedUser;
import com.netgrif.application.engine.auth.service.interfaces.IUserService;
import com.netgrif.application.engine.event.events.user.UserRoleChangeEvent;
import com.netgrif.application.engine.importer.model.EventPhaseType;
import com.netgrif.application.engine.petrinet.domain.PetriNet;
import com.netgrif.application.engine.petrinet.domain.dataset.logic.action.Action;
import com.netgrif.application.engine.petrinet.domain.dataset.logic.action.context.RoleContext;
import com.netgrif.application.engine.petrinet.domain.dataset.logic.action.runner.RoleActionsRunner;
import com.netgrif.application.engine.petrinet.domain.events.Event;
import com.netgrif.application.engine.petrinet.domain.events.EventType;
import com.netgrif.application.engine.petrinet.domain.repositories.PetriNetRepository;
import com.netgrif.application.engine.petrinet.domain.roles.ProcessRole;
import com.netgrif.application.engine.petrinet.domain.roles.ProcessRoleRepository;
import com.netgrif.application.engine.petrinet.service.interfaces.IPetriNetService;
import com.netgrif.application.engine.petrinet.service.interfaces.IProcessRoleService;
import com.netgrif.application.engine.security.service.ISecurityContextService;
import org.bson.types.ObjectId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
@Service
public class ProcessRoleService implements IProcessRoleService {
private static final Logger log = LoggerFactory.getLogger(ProcessRoleService.class);
private final IUserService userService;
private final ProcessRoleRepository processRoleRepository;
private final PetriNetRepository netRepository;
private final ApplicationEventPublisher publisher;
private final RoleActionsRunner roleActionsRunner;
private final IPetriNetService petriNetService;
private final ISecurityContextService securityContextService;
private ProcessRole defaultRole;
private ProcessRole anonymousRole;
public ProcessRoleService(ProcessRoleRepository processRoleRepository,
PetriNetRepository netRepository,
ApplicationEventPublisher publisher, RoleActionsRunner roleActionsRunner,
@Lazy IPetriNetService petriNetService, @Lazy IUserService userService, ISecurityContextService securityContextService) {
this.processRoleRepository = processRoleRepository;
this.netRepository = netRepository;
this.publisher = publisher;
this.roleActionsRunner = roleActionsRunner;
this.petriNetService = petriNetService;
this.userService = userService;
this.securityContextService = securityContextService;
}
@Override
public List saveAll(Iterable entities) {
return StreamSupport.stream(entities.spliterator(), false).map(processRole -> {
if (!processRole.isGlobal() || processRoleRepository.findAllByImportId(processRole.getImportId()).isEmpty()) {
return processRoleRepository.save(processRole);
}
return null;
}).filter(Objects::nonNull).collect(Collectors.toList());
}
@Override
public Set findByIds(Set ids) {
return StreamSupport.stream(processRoleRepository.findAllById(ids).spliterator(), false).collect(Collectors.toSet());
}
@Override
public void assignRolesToUser(String userId, Set requestedRolesIds, LoggedUser loggedUser) {
assignRolesToUser(userId, requestedRolesIds, loggedUser, new HashMap<>());
}
@Override
public void assignRolesToUser(String userId, Set requestedRolesIds, LoggedUser loggedUser, Map params) {
IUser user = userService.resolveById(userId, true);
Set requestedRoles = this.findByIds(requestedRolesIds);
if (requestedRoles.isEmpty() && !requestedRolesIds.isEmpty())
throw new IllegalArgumentException("No process roles found.");
if (requestedRoles.size() != requestedRolesIds.size())
throw new IllegalArgumentException("Not all process roles were found!");
Set userOldRoles = user.getProcessRoles();
Set rolesNewToUser = getRolesNewToUser(userOldRoles, requestedRoles);
Set rolesRemovedFromUser = getRolesRemovedFromUser(userOldRoles, requestedRoles);
String idOfPetriNetContainingRole = getPetriNetIdRoleBelongsTo(rolesNewToUser, rolesRemovedFromUser);
if (!isGlobalFromFirstRole(rolesNewToUser) && !isGlobalFromFirstRole(rolesRemovedFromUser) && idOfPetriNetContainingRole == null) {
return;
}
PetriNet petriNet = null;
if (idOfPetriNetContainingRole != null) {
petriNet = petriNetService.getPetriNet(idOfPetriNetContainingRole);
}
Set rolesNewToUserIds = mapUserRolesToIds(rolesNewToUser);
Set rolesRemovedFromUserIds = mapUserRolesToIds(rolesRemovedFromUser);
Set newRoles = this.findByIds(rolesNewToUserIds);
Set removedRoles = this.findByIds(rolesRemovedFromUserIds);
if (petriNet != null) {
runAllPreActions(newRoles, removedRoles, user, petriNet, params);
}
requestedRoles = updateRequestedRoles(user, rolesNewToUser, rolesRemovedFromUser);
replaceUserRolesAndPublishEvent(requestedRolesIds, user, requestedRoles);
if (petriNet != null) {
runAllPostActions(newRoles, removedRoles, user, petriNet, params);
}
securityContextService.saveToken(userId);
if (Objects.equals(userId, loggedUser.getId())) {
loggedUser.getProcessRoles().clear();
loggedUser.parseProcessRoles(user.getProcessRoles());
securityContextService.reloadSecurityContext(loggedUser);
}
}
private Set updateRequestedRoles(IUser user, Set rolesNewToUser, Set rolesRemovedFromUser) {
Set userRolesAfterPreActions = user.getProcessRoles();
userRolesAfterPreActions.addAll(rolesNewToUser);
userRolesAfterPreActions.removeAll(rolesRemovedFromUser);
return new HashSet<>(userRolesAfterPreActions);
}
private String getPetriNetIdRoleBelongsTo(Set newRoles, Set removedRoles) {
if (!newRoles.isEmpty()) {
return getPetriNetIdFromFirstRole(newRoles);
}
if (!removedRoles.isEmpty()) {
return getPetriNetIdFromFirstRole(removedRoles);
}
return null;
}
private boolean isGlobalFromFirstRole(Set roles) {
if (roles.isEmpty()) {
return false;
}
ProcessRole role = roles.iterator().next();
return role.isGlobal();
}
private String getPetriNetIdFromFirstRole(Set newRoles) {
return newRoles.iterator().next().getNetId();
}
private void replaceUserRolesAndPublishEvent(Set requestedRolesIds, IUser user, Set requestedRoles) {
removeOldAndAssignNewRolesToUser(user, requestedRoles);
publisher.publishEvent(new UserRoleChangeEvent(user, this.findByIds(requestedRolesIds)));
}
private Set getRolesNewToUser(Set userOldRoles, Set newRequestedRoles) {
Set rolesNewToUser = new HashSet<>(newRequestedRoles);
rolesNewToUser.removeAll(userOldRoles);
return rolesNewToUser;
}
private Set getRolesRemovedFromUser(Set userOldRoles, Set newRequestedRoles) {
Set rolesRemovedFromUser = new HashSet<>(userOldRoles);
rolesRemovedFromUser.removeAll(newRequestedRoles);
return rolesRemovedFromUser;
}
private Set mapUserRolesToIds(Collection processRoles) {
return processRoles.stream()
.map(ProcessRole::getStringId)
.collect(Collectors.toSet());
}
private void runAllPreActions(Set newRoles, Set removedRoles, IUser user, PetriNet petriNet, Map params) {
runAllSuitableActionsOnRoles(newRoles, EventType.ASSIGN, EventPhaseType.PRE, user, petriNet, params);
runAllSuitableActionsOnRoles(removedRoles, EventType.CANCEL, EventPhaseType.PRE, user, petriNet, params);
}
private void runAllPostActions(Set newRoles, Set removedRoles, IUser user, PetriNet petriNet, Map params) {
runAllSuitableActionsOnRoles(newRoles, EventType.ASSIGN, EventPhaseType.POST, user, petriNet, params);
runAllSuitableActionsOnRoles(removedRoles, EventType.CANCEL, EventPhaseType.POST, user, petriNet, params);
}
private void runAllSuitableActionsOnRoles(Set roles, EventType requiredEventType, EventPhaseType requiredPhase, IUser user, PetriNet petriNet, Map params) {
roles.forEach(role -> {
RoleContext roleContext = new RoleContext<>(user, role, petriNet);
runAllSuitableActionsOnOneRole(role.getEvents(), requiredEventType, requiredPhase, roleContext, params);
});
}
private void runAllSuitableActionsOnOneRole(Map eventMap, EventType requiredEventType, EventPhaseType requiredPhase, RoleContext roleContext, Map params) {
if (eventMap == null) {
return;
}
eventMap.forEach((eventType, event) -> {
if (eventType != requiredEventType) {
return;
}
runActionsBasedOnPhase(event, requiredPhase, roleContext, params);
});
}
private void runActionsBasedOnPhase(Event event, EventPhaseType requiredPhase, RoleContext roleContext, Map params) {
switch (requiredPhase) {
case PRE:
runActions(event.getPreActions(), roleContext, params);
break;
case POST:
runActions(event.getPostActions(), roleContext, params);
break;
}
}
private void runActions(List actions, RoleContext roleContext, Map params) {
actions.forEach(action -> roleActionsRunner.run(action, roleContext, params));
}
private void removeOldAndAssignNewRolesToUser(IUser user, Set requestedRoles) {
user.getProcessRoles().clear();
user.getProcessRoles().addAll(requestedRoles);
userService.save(user);
}
@Override
public List findAll() {
return processRoleRepository.findAll();
}
@Override
public Set findAllGlobalRoles() {
return processRoleRepository.findAllByGlobalIsTrue();
}
@Override
public List findAll(String netId) {
Optional netOptional = netRepository.findById(netId);
if (netOptional.isEmpty())
throw new IllegalArgumentException("Could not find model with id [" + netId + "]");
return findAll(netOptional.get());
}
private List findAll(PetriNet net) {
return new LinkedList<>(net.getRoles().values());
}
@Override
public ProcessRole defaultRole() {
if (defaultRole == null) {
Set roles = processRoleRepository.findAllByName_DefaultValue(ProcessRole.DEFAULT_ROLE);
if (roles.isEmpty())
throw new IllegalStateException("No default process role has been found!");
if (roles.size() > 1)
throw new IllegalStateException("More than 1 default process role exists!");
defaultRole = roles.stream().findFirst().orElse(null);
}
return defaultRole;
}
@Override
public ProcessRole anonymousRole() {
if (anonymousRole == null) {
Set roles = processRoleRepository.findAllByImportId(ProcessRole.ANONYMOUS_ROLE);
if (roles.isEmpty())
throw new IllegalStateException("No anonymous process role has been found!");
if (roles.size() > 1)
throw new IllegalStateException("More than 1 anonymous process role exists!");
anonymousRole = roles.stream().findFirst().orElse(null);
}
return anonymousRole;
}
/**
* @param importId id from a process of a role
* @return a process role object
* @deprecated use {@link ProcessRoleService#findAllByImportId(String)} instead
*/
@Deprecated(forRemoval = true, since = "6.2.0")
@Override
public ProcessRole findByImportId(String importId) {
return processRoleRepository.findAllByImportId(importId).stream().findFirst().orElse(null);
}
@Override
public Set findAllByImportId(String importId) {
return processRoleRepository.findAllByImportId(importId);
}
@Override
public Set findAllByDefaultName(String name) {
return processRoleRepository.findAllByName_DefaultValue(name);
}
@Override
public ProcessRole findById(String id) {
return processRoleRepository.findById(id).orElse(null);
}
@Override
public void deleteRolesOfNet(PetriNet net, LoggedUser loggedUser) {
log.info("[" + net.getStringId() + "]: Initiating deletion of all roles of Petri net " + net.getIdentifier() + " version " + net.getVersion().toString());
List deletedRoleIds = this.findAll(net.getStringId()).stream().filter(processRole -> processRole.getNetId() != null).map(ProcessRole::get_id).collect(Collectors.toList());
Set deletedRoleStringIds = deletedRoleIds.stream().map(ObjectId::toString).collect(Collectors.toSet());
List usersWithRemovedRoles = this.userService.findAllByProcessRoles(deletedRoleStringIds, false);
for (IUser user : usersWithRemovedRoles) {
log.info("[" + net.getStringId() + "]: Removing deleted roles of Petri net " + net.getIdentifier() + " version " + net.getVersion().toString() + " from user " + user.getFullName() + " with id " + user.getStringId());
if (user.getProcessRoles().size() == 0)
continue;
Set newRoles = user.getProcessRoles().stream()
.filter(role -> !deletedRoleStringIds.contains(role.getStringId()))
.map(ProcessRole::getStringId)
.collect(Collectors.toSet());
this.assignRolesToUser(user.getStringId(), newRoles, loggedUser);
}
log.info("[" + net.getStringId() + "]: Deleting all roles of Petri net " + net.getIdentifier() + " version " + net.getVersion().toString());
this.processRoleRepository.deleteAllBy_idIn(deletedRoleIds);
}
public void clearCache() {
this.defaultRole = null;
this.anonymousRole = null;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy