package fi.otavanopisto.muikku.schooldata.events;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.enterprise.event.Observes;
import javax.inject.Inject;
import org.apache.commons.lang3.StringUtils;
import fi.otavanopisto.muikku.model.users.UserEntity;
import fi.otavanopisto.muikku.model.users.UserSchoolDataIdentifier;
import fi.otavanopisto.muikku.model.workspace.WorkspaceEntity;
import fi.otavanopisto.muikku.model.workspace.WorkspaceRoleEntity;
import fi.otavanopisto.muikku.model.workspace.WorkspaceUserEntity;
import fi.otavanopisto.muikku.schooldata.SchoolDataIdentifier;
import fi.otavanopisto.muikku.schooldata.WorkspaceController;
import fi.otavanopisto.muikku.schooldata.WorkspaceEntityController;
import fi.otavanopisto.muikku.users.UserEntityController;
import fi.otavanopisto.muikku.users.UserSchoolDataIdentifierController;
import fi.otavanopisto.muikku.users.WorkspaceUserEntityController;
public class DefaultSchoolDataWorkspaceListener {
@Inject
private Logger logger;
@Inject
private UserEntityController userEntityController;
@Inject
private WorkspaceEntityController workspaceEntityController;
@Inject
private WorkspaceController workspaceController;
@Inject
private WorkspaceUserEntityController workspaceUserEntityController;
@Inject
private UserSchoolDataIdentifierController userSchoolDataIdentifierController;
@PostConstruct
public void init() {
discoveredWorkspaces = new HashMap<>();
discoveredWorkspaceUsers = new HashMap<>();
}
public synchronized void onSchoolDataWorkspaceDiscoveredEvent(@Observes SchoolDataWorkspaceDiscoveredEvent event) {
String discoverId = "WS-" + event.getDataSource() + "/" + event.getIdentifier();
if (discoveredWorkspaces.containsKey(discoverId)) {
event.setDiscoveredWorkspaceEntityId(discoveredWorkspaces.get(discoverId));
return;
}
WorkspaceEntity workspaceEntity = workspaceEntityController.findWorkspaceByDataSourceAndIdentifier(event.getDataSource(), event.getIdentifier());
if (workspaceEntity == null) {
// workspace url name
String urlNameBase = generateWorkspaceUrlName(event.getName());
String urlName = urlNameBase;
int urlNameIterator = 1;
while (workspaceEntityController.findWorkspaceByUrlName(urlName) != null) {
urlName = urlNameBase + "-" + ++urlNameIterator;
}
// workspace
workspaceEntity = workspaceEntityController.createWorkspaceEntity(event.getDataSource(), event.getIdentifier(), urlName);
} else {
logger.warning("workspaceEntity #" + event.getDataSource() + '/' + event.getIdentifier() + " already exists");
}
// workspace bookkeeping
discoveredWorkspaces.put(discoverId, workspaceEntity.getId());
event.setDiscoveredWorkspaceEntityId(workspaceEntity.getId());
}
public void onSchoolDataWorkspaceUpdated(@Observes SchoolDataWorkspaceUpdatedEvent event) {
WorkspaceEntity workspaceEntity = workspaceEntityController.findWorkspaceByDataSourceAndIdentifier(event.getDataSource(), event.getIdentifier());
if (workspaceEntity != null) {
// TODO: How should we handle the updating of URL names?
} else {
logger.warning("Updated workspaceEntity #" + event.getDataSource() + '/' + event.getIdentifier() + " could not be found");
}
}
public void onSchoolDataWorkspaceRemoved(@Observes SchoolDataWorkspaceRemovedEvent event) {
WorkspaceEntity workspaceEntity = workspaceEntityController.findWorkspaceByDataSourceAndIdentifier(event.getDataSource(), event.getIdentifier());
if (workspaceEntity != null) {
workspaceEntity = workspaceEntityController.archiveWorkspaceEntity(workspaceEntity);
}
}
public synchronized void onSchoolDataWorkspaceUserDiscoveredEvent(@Observes SchoolDataWorkspaceUserDiscoveredEvent event) {
String discoverId = "WSU-" + event.getDataSource() + "/" + event.getIdentifier();
if (discoveredWorkspaceUsers.containsKey(discoverId)) {
event.setDiscoveredWorkspaceUserEntityId(discoveredWorkspaceUsers.get(discoverId));
return;
}
WorkspaceEntity workspaceEntity = workspaceEntityController.findWorkspaceByDataSourceAndIdentifier(event.getWorkspaceDataSource(), event.getWorkspaceIdentifier());
if (workspaceEntity != null) {
WorkspaceRoleEntity workspaceUserRole = workspaceController.findWorkspaceRoleEntityByDataSourceAndIdentifier(event.getRoleDataSource(), event.getRoleIdentifier());
if (workspaceUserRole != null) {
UserSchoolDataIdentifier userSchoolDataIdentifier = userSchoolDataIdentifierController.findUserSchoolDataIdentifierByDataSourceAndIdentifier(event.getUserDataSource(), event.getUserIdentifier());
if (userSchoolDataIdentifier != null) {
WorkspaceUserEntity workspaceUserEntity =
workspaceUserEntityController.findWorkspaceUserEntityByWorkspaceAndUserSchoolDataIdentifierIncludeArchived(
workspaceEntity,
userSchoolDataIdentifier);
if (workspaceUserEntity == null) {
workspaceUserEntity = workspaceUserEntityController.createWorkspaceUserEntity(userSchoolDataIdentifier, workspaceEntity, event.getIdentifier(), workspaceUserRole);
discoveredWorkspaceUsers.put(discoverId, workspaceUserEntity.getId());
event.setDiscoveredWorkspaceUserEntityId(workspaceUserEntity.getId());
}
else {
if (!workspaceUserEntity.getIdentifier().equals(event.getIdentifier())) {
workspaceUserEntityController.updateIdentifier(workspaceUserEntity, event.getIdentifier());
}
workspaceUserEntityController.unarchiveWorkspaceUserEntity(workspaceUserEntity);
}
} else {
logger.warning("could not add workspace user because userSchoolDataIdentifier #" + event.getUserIdentifier() + '/' + event.getUserDataSource() + " could not be found");
}
} else {
logger.warning("could not init workspace user because workspace role #" + event.getRoleIdentifier() + '/' + event.getRoleDataSource() + " could not be found");
}
} else {
logger.warning("could not init workspace user because workspace entity #" + event.getWorkspaceIdentifier() + '/' + event.getWorkspaceDataSource() + " could not be found");
}
}
public void onSchoolDataWorkspaceUserUpdatedEvent(@Observes SchoolDataWorkspaceUserUpdatedEvent event) {
UserEntity userEntity = userEntityController.findUserEntityByDataSourceAndIdentifier(event.getUserDataSource(), event.getUserIdentifier());
if (userEntity != null) {
WorkspaceEntity workspaceEntity = workspaceEntityController.findWorkspaceByDataSourceAndIdentifier(event.getWorkspaceDataSource(), event.getWorkspaceIdentifier());
if (workspaceEntity != null) {
SchoolDataIdentifier workspaceUserIdentifier = new SchoolDataIdentifier(event.getIdentifier(), event.getDataSource());
WorkspaceUserEntity workspaceUserEntity = workspaceUserEntityController.findWorkspaceUserEntityByWorkspaceUserIdentifierIncludeArchived(workspaceUserIdentifier);
if (workspaceUserEntity != null) {
String currentUserIdentifier = workspaceUserEntity.getUserSchoolDataIdentifier().getIdentifier();
if (!StringUtils.equals(currentUserIdentifier, event.getUserIdentifier())) {
UserSchoolDataIdentifier newUserIdentifier = userSchoolDataIdentifierController.findUserSchoolDataIdentifierByDataSourceAndIdentifier(
event.getUserDataSource(), event.getUserIdentifier());
if (newUserIdentifier == null) {
logger.warning(String.format("Unable to update workspace user. UserSchoolDataIdentifier for %s/%s not found", event.getUserDataSource(), event.getUserIdentifier()));
}
else {
WorkspaceUserEntity existingUser = workspaceUserEntityController.findWorkspaceUserEntityByWorkspaceAndUserSchoolDataIdentifierIncludeArchived(
workspaceEntity, newUserIdentifier);
if (existingUser != null) {
if (!existingUser.getArchived().equals(workspaceUserEntity.getArchived())) {
if (existingUser.getArchived()) {
workspaceUserEntityController.unarchiveWorkspaceUserEntity(existingUser);
}
else {
workspaceUserEntityController.archiveWorkspaceUserEntity(existingUser);
}
}
workspaceUserEntityController.updateIdentifier(existingUser, workspaceUserEntity.getIdentifier());
try {
// TODO Fails if AssessmentRequestMessageId or WorkspaceUserPermissionOverride refer to WorkspaceUserEntity
workspaceUserEntityController.deleteWorkspaceUserEntity(workspaceUserEntity);
}
catch (Exception e) {
logger.log(Level.SEVERE, String.format("Failed to delete WorkspaceUserEntity %d", workspaceUserEntity.getId()), e);
}
}
else {
workspaceUserEntityController.updateUserSchoolDataIdentifier(workspaceUserEntity, newUserIdentifier);
}
}
}
}
} else {
logger.warning("could not update workspace user because workspace entity #" + event.getWorkspaceIdentifier() + '/' + event.getWorkspaceDataSource() + " could not be found");
}
} else {
logger.warning("could not update workspace user because user entity #" + event.getUserIdentifier() + '/' + event.getUserDataSource() + " could not be found");
}
}
public void onSchoolDataWorkspaceUserRemovedEvent(@Observes SchoolDataWorkspaceUserRemovedEvent event) {
UserEntity userEntity = userEntityController.findUserEntityByDataSourceAndIdentifier(event.getUserDataSource(), event.getUserIdentifier());
if (userEntity != null) {
WorkspaceEntity workspaceEntity = workspaceEntityController.findWorkspaceByDataSourceAndIdentifier(event.getWorkspaceDataSource(), event.getWorkspaceIdentifier());
if (workspaceEntity != null) {
SchoolDataIdentifier workspaceUserIdentifier = new SchoolDataIdentifier(event.getIdentifier(), event.getDataSource());
WorkspaceUserEntity workspaceUserEntity = workspaceUserEntityController.findWorkspaceUserEntityByWorkspaceUserIdentifierIncludeArchived(workspaceUserIdentifier);
if (workspaceUserEntity != null) {
// #3091: Users removed in school data source should be permanently deleted as merely archiving
// them would still lead the workspace to be shown in the student's Transcript of Records view
try {
// TODO Fails if AssessmentRequestMessageId or WorkspaceUserPermissionOverride refer to WorkspaceUserEntity
workspaceUserEntityController.deleteWorkspaceUserEntity(workspaceUserEntity);
}
catch (Exception e) {
logger.log(Level.SEVERE, String.format("Failed to delete WorkspaceUserEntity %d", workspaceUserEntity.getId()), e);
}
}
} else {
logger.warning("could not remove workspace user because workspace entity #" + event.getWorkspaceIdentifier() + '/' + event.getWorkspaceDataSource() + " could not be found");
}
} else {
logger.warning("could not remove workspace user because user entity #" + event.getUserIdentifier() + '/' + event.getUserDataSource() + " could not be found");
}
}
/**
* Generates URL name from workspace name.
*
* @param name original workspace name
* @return URL name
*/
private String generateWorkspaceUrlName(String name) {
// convert to lower-case and replace spaces and slashes with a minus sign
String urlName = name == null ? "" : StringUtils.lowerCase(name.replaceAll(" ", "-").replaceAll("/", "-"));
// truncate consecutive minus signs into just one
while (urlName.indexOf("--") >= 0) {
urlName = urlName.replace("--", "-");
}
// get rid of accented characters and all special characters other than minus, period, and underscore
urlName = StringUtils.stripAccents(urlName).replaceAll("[^a-z0-9\\-\\.\\_]", "");
return StringUtils.isBlank(urlName) ? StringUtils.substringBefore(UUID.randomUUID().toString(), "-") : urlName;
}
private Map<String, Long> discoveredWorkspaceUsers;
private Map<String, Long> discoveredWorkspaces;
}