argos/dmp-backend/core/src/main/java/eu/eudat/model/mapper/deposit/DmpEntityDepositMapper.java

162 lines
7.7 KiB
Java

package eu.eudat.model.mapper.deposit;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import eu.eudat.commons.enums.IsActive;
import eu.eudat.commons.types.xml.XmlBuilder;
import eu.eudat.data.DescriptionEntity;
import eu.eudat.data.DescriptionTemplateEntity;
import eu.eudat.data.DmpEntity;
import eu.eudat.data.old.UserDMP;
import eu.eudat.data.old.UserInfo;
import eu.eudat.depositinterface.models.*;
import jakarta.persistence.EntityManager;
import jakarta.persistence.criteria.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.xml.xpath.*;
import java.io.File;
import java.util.*;
import java.util.stream.Collectors;
@Component
public class DmpEntityDepositMapper {
private static final Logger logger = LoggerFactory.getLogger(DmpEntityDepositMapper.class);
private final ObjectMapper mapper;
private final EntityManager entityManager;
public DmpEntityDepositMapper(EntityManager entityManager) {
this.entityManager = entityManager;
this.mapper = new ObjectMapper();
}
//TODO: WIP, missing some things like researchers, organizations etc. Must check Blueprint properties and check if those have some standard way to be identified
public DMPDepositModel toDeposit(DmpEntity dmpEntity, File zip, FileEnvelope pdf, FileEnvelope json, String previousDOI) {
DMPDepositModel model = new DMPDepositModel();
List<DescriptionEntity> desciptions = this.getDescriptions(dmpEntity.getId());
List<UserDMP> users = getUsers(dmpEntity.getId());
model.setId(dmpEntity.getId());
model.setLabel(dmpEntity.getLabel());
model.setDescription(dmpEntity.getDescription());
model.setVersion(dmpEntity.getVersion());
model.setPdfFile(pdf);
model.setRdaJsonFile(json);
model.setSupportingFilesZip(zip);
model.setDatasets(desciptions.stream().map(this::toDatasetDeposit).toList());
model.setExtraProperties(dmpEntity.getProperties());
model.setUsers(users.stream().map(this::toUserDeposit).collect(Collectors.toSet()));
model.setPreviousDOI(previousDOI);
return model;
}
private List<DescriptionEntity> getDescriptions(UUID dmpId) {
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<DescriptionEntity> query = builder.createQuery(DescriptionEntity.class);
Root<DescriptionEntity> root = query.from(DescriptionEntity.class);
query = query.where(builder.and(builder.equal(root.get("dmp"), dmpId), builder.equal(root.get("isActive"), IsActive.Active)));
return entityManager.createQuery(query).getResultList();
}
private DatasetDepositModel toDatasetDeposit(DescriptionEntity entity) {
DatasetDepositModel model = new DatasetDepositModel();
model.setLabel(entity.getLabel());
model.setDescription(entity.getDescription());
model.setProperties(entity.getProperties());
DescriptionTemplateEntity descriptionTemplateEntity = getDescriptionTemplate(entity.getProfile());
model.setProfileDefinition(descriptionTemplateEntity.getDefinition());
model.setFields(fromDefinitionAndProperties(descriptionTemplateEntity.getDefinition(), entity.getProperties()));
return model;
}
private DescriptionTemplateEntity getDescriptionTemplate(UUID descId) {
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<DescriptionTemplateEntity> query = builder.createQuery(DescriptionTemplateEntity.class);
Root<DescriptionTemplateEntity> root = query.from(DescriptionTemplateEntity.class);
query = query.where(builder.and(builder.equal(root.get("id"), descId), builder.equal(root.get("isActive"), IsActive.Active)));
return entityManager.createQuery(query).getSingleResult();
}
private List<DatasetFieldsDepositModel> fromDefinitionAndProperties(String definition, String properties){
List<DatasetFieldsDepositModel> deposit = new ArrayList<>();
try {
Map<String, Object> datasetAnswers = mapper.readValue(properties, HashMap.class);
Document document = XmlBuilder.fromXml(definition);
XPathFactory xpathFactory = XPathFactory.newInstance();
XPath xpath = xpathFactory.newXPath();
XPathExpression expr = xpath.compile("//schematics");
NodeList schematics = (NodeList) expr.evaluate(document, XPathConstants.NODESET);
for (int i = 0; i < schematics.getLength(); i++) {
Node schematicsNode = schematics.item(i);
NodeList schematicsList = schematicsNode.getChildNodes();
DatasetFieldsDepositModel fieldDeposit = new DatasetFieldsDepositModel();
List<String> schematicsDeposit = new ArrayList<>();
if(schematicsList != null){
for(int j = 0; j < schematicsList.getLength(); j++){
Node schematic = schematicsList.item(j);
if(schematic.getTextContent().matches(".*\\w+.*")) {
schematicsDeposit.add(schematic.getTextContent());
}
}
}
fieldDeposit.setSchematics(schematicsDeposit);
String fieldId = schematicsNode.getParentNode().getAttributes().getNamedItem("id").getNodeValue();
Object value = datasetAnswers.get(fieldId);
fieldDeposit.setValue(value);
Element field = (Element) schematicsNode.getParentNode();
Element viewStyle = (Element) field.getElementsByTagName("viewStyle").item(0);
String renderStyle = viewStyle.getAttribute("renderstyle");
fieldDeposit.setRenderStyleType(renderStyle);
Element data = (Element) field.getElementsByTagName("data").item(0);
String multipleSelection = data.getAttribute("multiList");
String multipleAutoComplete = data.getAttribute("multiAutoComplete");
if(!multipleSelection.isEmpty()){
fieldDeposit.setMultiple(Boolean.parseBoolean(multipleSelection));
}
else if(!multipleAutoComplete.isEmpty()){
fieldDeposit.setMultiple(Boolean.parseBoolean(multipleAutoComplete));
}
else{
fieldDeposit.setMultiple(false);
}
deposit.add(fieldDeposit);
}
}
catch (XPathExpressionException | JsonProcessingException ex){
logger.error(ex.getMessage(), ex);
return null;
}
return deposit;
}
private List<UserDMP> getUsers(UUID dmpId) {
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<UserDMP> query = builder.createQuery(UserDMP.class);
Root<UserDMP> root = query.from(UserDMP.class);
Join<UserInfo, UserDMP> join = root.join("user").join("id");
query = query.multiselect(root.get("user"), root.get("role"));
return entityManager.createQuery(query).getResultList();
}
private UserDMPDepositModel toUserDeposit(UserDMP user) {
UserDMPDepositModel userDMPDepositModel = new UserDMPDepositModel();
userDMPDepositModel.setUser(new UserInfoDepositModel());
userDMPDepositModel.getUser().setName(user.getUser().getName());
userDMPDepositModel.getUser().setEmail(user.getUser().getEmail());
userDMPDepositModel.setRole(user.getRole());
return userDMPDepositModel;
}
}