Skip to content

Commit

Permalink
Add relation between import configurations and clients (kitodo#6124)
Browse files Browse the repository at this point in the history
* Add relation between import configurations and clients

* Add special permission to assign import configurations to clients

* Fix import order

* Rename constant

* Automatically assign new import configurations to the current client

* Add test

* Adjust tests

* Omit unnecessary cast to 'Long'
  • Loading branch information
solth authored Jul 17, 2024
1 parent 0732f28 commit b421d45
Show file tree
Hide file tree
Showing 26 changed files with 329 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ public class Client extends BaseBean {
foreignKey = @ForeignKey(name = "FK_column_id"))})
private List<ListColumn> listColumns;

@ManyToMany(mappedBy = "clients", cascade = CascadeType.PERSIST)
private List<ImportConfiguration> importConfigurations;

/**
* Gets name.
*
Expand Down Expand Up @@ -99,4 +102,26 @@ public List<ListColumn> getListColumns() {
public void setListColumns(List<ListColumn> columns) {
this.listColumns = columns;
}

/**
* Get import configuration.
*
* @return import configurations
*/
public List<ImportConfiguration> getImportConfigurations() {
initialize(new ClientDAO(), this.importConfigurations);
if (Objects.isNull(this.importConfigurations)) {
this.importConfigurations = new ArrayList<>();
}
return importConfigurations;
}

/**
* Set import configurations.
*
* @param configurations import configurations
*/
public void setImportConfigurations(List<ImportConfiguration> configurations) {
this.importConfigurations = configurations;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@
import javax.persistence.Table;

import org.apache.commons.lang3.StringUtils;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;
import org.kitodo.api.externaldatamanagement.ImportConfigurationType;
import org.kitodo.data.database.persistence.ImportConfigurationDAO;
import org.kitodo.data.database.persistence.MappingFileDAO;
import org.kitodo.data.database.persistence.SearchFieldDAO;
import org.kitodo.data.database.persistence.UrlParameterDAO;
Expand Down Expand Up @@ -158,6 +161,16 @@ public class ImportConfiguration extends BaseBean {
@Column(name = "metadata_record_title_xpath")
private String metadataRecordTitleXPath;

@ManyToMany(cascade = CascadeType.PERSIST)
@LazyCollection(LazyCollectionOption.FALSE)
@JoinTable(name = "client_x_importconfiguration", joinColumns = {
@JoinColumn(name = "importconfiguration_id",
foreignKey = @ForeignKey(name = "FK_client_x_importconfiguration_importconfiguration_id")) },
inverseJoinColumns = {
@JoinColumn(name = "client_id",
foreignKey = @ForeignKey(name = "FK_client_x_importconfiguration_client_id")) })
private List<Client> clients;

/**
* Default constructor.
*/
Expand Down Expand Up @@ -842,6 +855,28 @@ public String getConfigurationTypeKey() {
return "";
}

/**
* Get clients.
*
* @return value of clients
*/
public List<Client> getClients() {
initialize(new ImportConfigurationDAO(), this.clients);
if (Objects.isNull(this.clients)) {
this.clients = new ArrayList<>();
}
return clients;
}

/**
* Set clients.
*
* @param clients List of Client
*/
public void setClients(List<Client> clients) {
this.clients = clients;
}

@Override
public boolean equals(Object object) {
if (this == object) {
Expand Down Expand Up @@ -898,7 +933,8 @@ public int hashCode() {
sruRecordSchema,
oaiMetadataPrefix,
metadataRecordIdXPath,
metadataRecordTitleXPath
metadataRecordTitleXPath,
clients
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
--
-- (c) Kitodo. Key to digital objects e. V. <[email protected]>
--
-- This file is part of the Kitodo project.
--
-- It is licensed under GNU General Public License version 3 or later.
--
-- For the full copyright and license information, please read the
-- GPL3-License.txt file that was distributed with this source code.
--

--
-- Migration: Create relation between ImportConfigurations and Clients
--

SET SQL_SAFE_UPDATES = 0;

-- 1. create cross table
CREATE TABLE IF NOT EXISTS client_x_importconfiguration (
client_id INT(11) NOT NULL,
importconfiguration_id INT(11) NOT NULL,
PRIMARY KEY ( client_id, importconfiguration_id ),
KEY FK_client_x_importconfiguration_client_id (client_id),
KEY FK_client_x_importconfiguration_importconfiguration_id (importconfiguration_id),
CONSTRAINT FK_client_x_importconfiguration_client_id FOREIGN KEY (client_id) REFERENCES client(id),
CONSTRAINT FK_client_x_importconfiguration_importconfiguration_id FOREIGN KEY (importconfiguration_id) REFERENCES importconfiguration(id)
) DEFAULT CHARACTER SET = utf8mb4
COLLATE utf8mb4_unicode_ci;

-- 2. initially map all clients to all import configurations to retain status quo
INSERT INTO client_x_importconfiguration SELECT client.id, importconfiguration.id FROM client, importconfiguration;

-- 3. add new special permission to allow users to map import configuration to clients
INSERT IGNORE INTO authority (title) VALUES ('assignImportConfigurationToClient_globalAssignable');

SET SQL_SAFE_UPDATES = 1;
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ public class StringConstants {

public static final String COMMA_DELIMITER = ", ";
public static final String SEMICOLON_DELIMITER = "; ";
public static final String EDIT_FORM_SAVE = "editForm:save";

}
Original file line number Diff line number Diff line change
Expand Up @@ -1099,4 +1099,13 @@ public boolean hasAuthorityToRunKitodoScripts() {
public boolean hasAuthorityToRenameMediaFiles() {
return securityAccessService.hasAuthorityToRenameMediaFiles();
}

/**
* Check if the current user has the permission to assign import configurations to clients.
*
* @return true if the current user has the permission to assign import configurations to clients.
*/
public boolean hasAuthorityToAssignImportConfigurationToClient() {
return securityAccessService.hasAuthorityToAssignImportConfigurationToClient();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@

package org.kitodo.production.controller;

import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import javax.enterprise.context.RequestScoped;
import javax.faces.context.FacesContext;
Expand Down Expand Up @@ -149,7 +151,7 @@ public String setSessionClient(Client sessionClient) {
*
* @return The list of clients.
*/
public List<Client> getAvailableClientsOfCurrentUser() {
public List<Client> getAvailableClientsOfCurrentUser() {
User currentUser = ServiceManager.getUserService().getCurrentUser();
List<Client> clients = currentUser.getClients();
for (Project project : currentUser.getProjects()) {
Expand All @@ -159,4 +161,13 @@ public List<Client> getAvailableClientsOfCurrentUser() {
}
return clients;
}

/**
* Get list of available clients of current user sorted by name.
* @return list of available clients of current user sorted by name
*/
public List<Client> getAvailableClientsOfCurrentUserSortedByName() {
return getAvailableClientsOfCurrentUser().stream().sorted(Comparator.comparing(Client::getName))
.collect(Collectors.toList());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.kitodo.api.externaldatamanagement.SearchInterfaceType;
import org.kitodo.api.schemaconverter.FileFormat;
import org.kitodo.api.schemaconverter.MetadataFormat;
import org.kitodo.data.database.beans.Client;
import org.kitodo.data.database.beans.ImportConfiguration;
import org.kitodo.data.database.beans.MappingFile;
import org.kitodo.data.database.beans.Process;
Expand All @@ -49,6 +50,7 @@ public class ImportConfigurationEditView extends BaseForm {
private static final Logger logger = LogManager.getLogger(ImportConfigurationEditView.class);
private ImportConfiguration importConfiguration = new ImportConfiguration();
private List<SelectItem> searchFields = new ArrayList<>();
private List<Client> availableClients = new ArrayList<>();
private static final List<String> SRU_VERSIONS = List.of("1.1", "1.2", "2.0");
private static final List<String> SCHEMES = List.of("https", "http", "ftp");
private static final List<String> PARENT_ELEMENT_TYPES = Collections.singletonList("reference");
Expand Down Expand Up @@ -103,6 +105,8 @@ public void load(int id) {
importConfiguration = ServiceManager.getImportConfigurationService().getById(id);
} else {
importConfiguration = new ImportConfiguration();
importConfiguration.setClients(Collections.singletonList(ServiceManager.getUserService()
.getSessionClientOfAuthenticatedUser()));
}
setSaveDisabled(true);
} catch (DAOException e) {
Expand Down Expand Up @@ -435,4 +439,38 @@ public String getParentIdSearchField() {
public void setParentIdSearchField(String parentIdSearchField) {
importConfiguration.setParentSearchField(getSearchFieldMap().get(parentIdSearchField));
}

/**
* Get assigned clients.
*
* @return assigned clients
*/
public List<Client> getAssignedClients() {
return new ArrayList<>(importConfiguration.getClients());
}

/**
* Set assigned clients.
*
* @param clients assigned clients
*/
public void setAssignedClients(List<Client> clients) {
this.importConfiguration.setClients(clients);
}

/**
* Get list of available clients.
* @return list of available clients
*/
public List<Client> getAvailableClients() {
if (Objects.isNull(availableClients) || availableClients.isEmpty()) {
try {
availableClients = ServiceManager.getClientService().getAllSortedByName();
} catch (DAOException e) {
Helper.setErrorMessage(e);
availableClients = new ArrayList<>();
}
}
return availableClients;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
import org.kitodo.exceptions.ImportConfigurationInUseException;
import org.kitodo.production.enums.ObjectType;
import org.kitodo.production.helper.Helper;
import org.kitodo.production.model.LazyDTOModel;
import org.kitodo.production.services.ServiceManager;
import org.primefaces.PrimeFaces;

Expand All @@ -44,7 +43,6 @@ public class ImportConfigurationListView extends BaseForm {
*/
public ImportConfigurationListView() {
super();
super.setLazyDTOModel(new LazyDTOModel(ServiceManager.getImportConfigurationService()));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,18 @@
import javax.faces.validator.ValidatorException;

import org.apache.commons.lang3.StringUtils;
import org.kitodo.constants.StringConstants;

@FacesValidator("AbsolutePathValidator")
public class AbsolutePathValidator implements Validator<String> {

private static final String SAVE = "editForm:save";


@Override
public void validate(FacesContext facesContext, UIComponent uiComponent, String pathString)
throws ValidatorException {
// only validate when saving
if (!facesContext.getExternalContext().getRequestParameterMap().containsKey(SAVE)) {
if (!facesContext.getExternalContext().getRequestParameterMap().containsKey(StringConstants.EDIT_FORM_SAVE)) {
return;
}
if (StringUtils.isNotBlank(pathString) && !pathString.startsWith("/")) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* (c) Kitodo. Key to digital objects e. V. <[email protected]>
*
* This file is part of the Kitodo project.
*
* It is licensed under GNU General Public License version 3 or later.
*
* For the full copyright and license information, please read the
* GPL3-License.txt file that was distributed with this source code.
*/

package org.kitodo.production.forms.validators;

import java.util.ArrayList;

import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.FacesValidator;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;

import org.kitodo.constants.StringConstants;

@FacesValidator("ImportConfigurationClientValidator")
public class ImportConfigurationClientValidator implements Validator<ArrayList<?>> {

@Override
public void validate(FacesContext context, UIComponent component, ArrayList<?> clientList)
throws ValidatorException {
// only validate when saving
if (!context.getExternalContext().getRequestParameterMap().containsKey(StringConstants.EDIT_FORM_SAVE)) {
return;
}
if (clientList.isEmpty()) {
throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR,
"The import configuration must be assigned to at least one client", null));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import java.net.URL;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
Expand Down Expand Up @@ -105,6 +106,8 @@ private void convertOpacConfig(String catalogName, List<String> currentConfigura
}
importConfiguration.setMappingFiles(getMappingFiles(importConfiguration));
importConfiguration.setPrestructuredImport(OPACConfig.isPrestructuredImport(catalogName));
importConfiguration.setClients(Collections.singletonList(ServiceManager.getUserService()
.getSessionClientOfAuthenticatedUser()));
}
ServiceManager.getImportConfigurationService().saveToDatabase(importConfiguration);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

import static org.kitodo.constants.StringConstants.COMMA_DELIMITER;

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
Expand Down Expand Up @@ -120,4 +121,14 @@ public static String getClientNames(List<Client> clients) {
.contains(client)).map(Client::getName).collect(Collectors.joining(COMMA_DELIMITER));
}
}

/**
* Get all clients sorted by name.
* @return all clients, sorted by name
* @throws DAOException when retrieving clients from the database fails
*/
public List<Client> getAllSortedByName() throws DAOException {
return getAll().stream().sorted(Comparator.comparing(Client::getName))
.collect(Collectors.toList());
}
}
Loading

0 comments on commit b421d45

Please sign in to comment.