package de.ozgcloud.alfa; import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.*; import java.util.List; import java.util.Optional; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.hateoas.Link; import org.springframework.hateoas.server.LinkBuilder; import org.springframework.stereotype.Component; import de.ozgcloud.alfa.common.ModelBuilder; import de.ozgcloud.alfa.common.user.CurrentUserService; import de.ozgcloud.alfa.common.user.UserId; import de.ozgcloud.alfa.common.user.UserRole; import de.ozgcloud.alfa.system.SystemStatusService; import de.ozgcloud.alfa.vorgang.Vorgang.VorgangStatus; import de.ozgcloud.alfa.vorgang.VorgangController; import lombok.NonNull; @Component class RootViewLinkHandler { static final String VORGAENGE_ALL_REL_TEMPLATE = "vorgaenge_%s_all"; static final String VORGAENGE_MY_REL_TEMPLATE = "vorgaenge_%s_my"; static final String VORGAENGE_UNASSIGNED_REL_TEMPLATE = "vorgaenge_%s_unassigned"; static final String ALL_VORGAENGE_REL = "vorgaenge_all"; static final String MY_VORGEANGE_REL = "vorgaenge_my"; static final String UNASSIGNED_VORGEANGE_REL = "vorgaenge_unassigned"; static final String ALL_WIEDERVORLAGEN_REL = "vorgaenge_wiedervorlagen_all"; static final String MY_WIEDERVORLAGEN_REL = "vorgaenge_wiedervorlagen_my"; static final String UNASSIGNED_WIEDERVORLAGEN_REL = "vorgaenge_wiedervorlagen_unassigned"; static final String SEARCH_ALL_REL = "search_all"; static final String SEARCH_MY_VORGEANGE_REL = "search_my"; static final String SEARCH_UNASSIGNED_VORGEANGE_REL = "search_unassigned"; static final String ALL_UNGELESENE_NACHRICHTEN_REL = "vorgaenge_ungelesene_nachrichten_all"; static final String MY_UNGELESENE_NACHRICHTEN_REL = "vorgaenge_ungelesene_nachrichten_my"; static final String UNASSIGNED_UNGELESENE_NACHRICHTEN_REL = "vorgaenge_ungelesene_nachrichten_unassigned"; static final int PAGE_SIZE = 100; @Autowired private CurrentUserService currentUserService; @Autowired private SystemStatusService systemStatusService; private final List<VorgangStatus> statusList = List.of(VorgangStatus.NEU, VorgangStatus.ANGENOMMEN, VorgangStatus.IN_BEARBEITUNG, VorgangStatus.BESCHIEDEN, VorgangStatus.ABGESCHLOSSEN, VorgangStatus.VERWORFEN, VorgangStatus.ZU_LOESCHEN); public void addViewLinks(ModelBuilder<Root> modelBuilder, Optional<UserId> userId) { modelBuilder.addLink(buildGetAllVorgaengeLink()); addSearchAllVorgaengeLink(modelBuilder); if (currentUserService.hasRole(UserRole.VERWALTUNG_POSTSTELLE)) { addViewLinksForVerwaltungPoststelle(modelBuilder, userId); } if (currentUserService.hasRole(UserRole.VERWALTUNG_USER)) { addViewLinksForVerwaltungUser(modelBuilder, userId); } } private Link buildGetAllVorgaengeLink() { return linkTo(methodOn(VorgangController.class).getAll(0, PAGE_SIZE)).withRel(ALL_VORGAENGE_REL); } void addSearchAllVorgaengeLink(ModelBuilder<Root> modelBuilder) { if (systemStatusService.isSearchServerAvailable()) { modelBuilder.addLink(buildGetAllVorgaengeBySearchByLink()); } } Link buildGetAllVorgaengeBySearchByLink() { return linkTo(methodOn(VorgangController.class).getAllBySearchBy(0, PAGE_SIZE, null)).withRel(SEARCH_ALL_REL); } void addViewLinksForVerwaltungPoststelle(ModelBuilder<Root> modelBuilder, Optional<UserId> userId) { userId.map(this::buildMyVorgaengeLink).ifPresent(modelBuilder::addLink); if (systemStatusService.isSearchServerAvailable()) { userId.map(this::buildSearchMyVorgaengeLink).ifPresent(modelBuilder::addLink); } } void addViewLinksForVerwaltungUser(ModelBuilder<Root> modelBuilder, Optional<UserId> userId) { addAllVorgangStatusLinks(modelBuilder); modelBuilder.addLink(buildGetAllUnassignedVorgaengeLink()); modelBuilder.addLinks(buildUnassignedVorgaengeStatusLinks()); userId.map(this::buildMyVorgaengeLink).ifPresent(modelBuilder::addLink); userId.map(this::buildMyVorgaengeStatusLinks).ifPresent(modelBuilder::addLinks); if (systemStatusService.isSearchServerAvailable()) { userId.map(this::buildSearchMyVorgaengeLink).ifPresent(modelBuilder::addLink); modelBuilder.addLink(buildSearchUnassignedVorgaengeLink()); } modelBuilder.addLink(buildGetAllByHasNextWiedervorlageFristLink().withRel(ALL_WIEDERVORLAGEN_REL)); modelBuilder .addLink(buildGetAllByAssignedToAndHasNextWiedervorlageFristLink(UserId.empty(), UNASSIGNED_WIEDERVORLAGEN_REL)); userId.map(id -> buildGetAllByAssignedToAndHasNextWiedervorlageFristLink(id, MY_WIEDERVORLAGEN_REL)).ifPresent(modelBuilder::addLink); addGetByUngeleseneNachrichtenLinks(modelBuilder, userId); } Link buildGetAllUnassignedVorgaengeLink() { return buildGetAllVorgaengeByAssignedToLink(UserId.empty()).withRel(UNASSIGNED_VORGEANGE_REL); } Link buildMyVorgaengeLink(@NonNull UserId userId) { return buildGetAllVorgaengeByAssignedToLink(userId).withRel(MY_VORGEANGE_REL); } LinkBuilder buildGetAllVorgaengeByAssignedToLink(UserId userId) { return linkTo(methodOn(VorgangController.class).getAllByAssignedTo(0, PAGE_SIZE, userId)); } Link buildSearchMyVorgaengeLink(@NonNull UserId userId) { return buildGetAllVorgaengeByAssignedToAndSearchByLink(userId).withRel(SEARCH_MY_VORGEANGE_REL); } Link buildSearchUnassignedVorgaengeLink() { return buildGetAllVorgaengeByAssignedToAndSearchByLink(UserId.empty()).withRel(SEARCH_UNASSIGNED_VORGEANGE_REL); } LinkBuilder buildGetAllVorgaengeByAssignedToAndSearchByLink(UserId userId) { return linkTo(methodOn(VorgangController.class).getAllByAssignedToAndSearchBy(0, PAGE_SIZE, userId, null)); } void addAllVorgangStatusLinks(ModelBuilder<Root> modelBuilder) { addVorgangStatusLinks(modelBuilder, VORGAENGE_ALL_REL_TEMPLATE); } void addVorgangStatusLinks(ModelBuilder<Root> modelBuilder, String linkRelTemplate) { statusList.forEach(status -> modelBuilder.addLink(buildGetAllVorgaengeByStatus(status, linkRelTemplate))); } Link buildGetAllVorgaengeByStatus(VorgangStatus status, String linkRelTemplate) { var linkRel = formatLinkRelTemplate(linkRelTemplate, status); return linkTo(methodOn(VorgangController.class).getAllByStatus(0, PAGE_SIZE, status)).withRel(linkRel); } List<Link> buildMyVorgaengeStatusLinks(@NonNull UserId userId) { return buildVorgangStatusLinks(VORGAENGE_MY_REL_TEMPLATE, userId); } List<Link> buildUnassignedVorgaengeStatusLinks() { return buildVorgangStatusLinks(VORGAENGE_UNASSIGNED_REL_TEMPLATE, UserId.empty()); } List<Link> buildVorgangStatusLinks(String linkRelTemplate, UserId userId) { return statusList.stream().map(status -> buildGetAllVorgaengeByAssignedToAndStatus(status, linkRelTemplate, userId)).toList(); } Link buildGetAllVorgaengeByAssignedToAndStatus(VorgangStatus status, String linkRelTemplate, UserId userId) { var linkRel = formatLinkRelTemplate(linkRelTemplate, status); return linkTo(methodOn(VorgangController.class).getAllByAssignedToAndStatus(0, PAGE_SIZE, userId, status)).withRel(linkRel); } String formatLinkRelTemplate(String linkRelTempalte, VorgangStatus status) { return String.format(linkRelTempalte, status.toString().toLowerCase()); } Link buildGetAllByHasNextWiedervorlageFristLink() { return linkTo(methodOn(VorgangController.class).getAllByHasNextWiedervorlageFrist(0, PAGE_SIZE, VorgangController.PARAM_NEXT_WIEDERVORLAGE_FRIST_EXISTS)).withRel(ALL_WIEDERVORLAGEN_REL); } Link buildGetAllByAssignedToAndHasNextWiedervorlageFristLink(@NonNull UserId userId, String linkRel) { return linkTo(methodOn(VorgangController.class).getAllByAssignedToAndHasNextWiedervorlageFrist(0, PAGE_SIZE, userId, VorgangController.PARAM_NEXT_WIEDERVORLAGE_FRIST_EXISTS)).withRel(linkRel); } void addGetByUngeleseneNachrichtenLinks(ModelBuilder<Root> modelBuilder, Optional<UserId> userId) { modelBuilder.addLink(buildGelAllByUngeleseneNachrichtenLink()); modelBuilder.addLink(buildGetAllByAssignedToAndUngeleseneNachrichten(UserId.empty(), UNASSIGNED_UNGELESENE_NACHRICHTEN_REL)); userId.map(id -> buildGetAllByAssignedToAndUngeleseneNachrichten(id, MY_UNGELESENE_NACHRICHTEN_REL)).ifPresent(modelBuilder::addLink); } Link buildGelAllByUngeleseneNachrichtenLink() { return linkTo(methodOn(VorgangController.class) .getAllByUngeleseneNachrichten(0, PAGE_SIZE, VorgangController.PARAM_NACHRICHTEN_UNGELESENE)) .withRel(ALL_UNGELESENE_NACHRICHTEN_REL); } Link buildGetAllByAssignedToAndUngeleseneNachrichten(@NonNull UserId userId, String linkRel) { return linkTo(methodOn(VorgangController.class) .getAllByAssignedToAndUngeleseneNachrichten(0, PAGE_SIZE, userId, VorgangController.PARAM_NACHRICHTEN_UNGELESENE)) .withRel(linkRel); } }