diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/Datasets.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/Datasets.java index c1ffd67f1..68a3e32c8 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/Datasets.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/Datasets.java @@ -15,6 +15,7 @@ import eu.eudat.logic.proxy.config.configloaders.ConfigLoader; import eu.eudat.logic.security.claims.ClaimedAuthorities; import eu.eudat.logic.services.ApiContext; import eu.eudat.logic.services.forms.VisibilityRuleService; +import eu.eudat.logic.services.forms.VisibilityRuleServiceImpl; import eu.eudat.logic.utilities.documents.helpers.FileEnvelope; import eu.eudat.logic.utilities.documents.pdf.PDFUtils; import eu.eudat.models.data.dataset.DatasetOverviewModel; @@ -126,11 +127,11 @@ public class Datasets extends BaseController { public @ResponseBody ResponseEntity getSingle(@PathVariable String id, @RequestHeader("Content-Type") String contentType, @ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal) throws IllegalAccessException, IOException, InstantiationException { try { + VisibilityRuleService visibilityRuleService = new VisibilityRuleServiceImpl(); if (contentType.equals("application/xml")) { - VisibilityRuleService visibilityRuleService = this.getApiContext().getUtilitiesService().getVisibilityRuleService(); return this.datasetManager.getDocument(id, visibilityRuleService, contentType, principal); } else if (contentType.equals("application/msword")) { - FileEnvelope file = datasetManager.getWordDocumentFile(this.configLoader, id, this.getApiContext().getUtilitiesService().getVisibilityRuleService(), principal); + FileEnvelope file = datasetManager.getWordDocumentFile(this.configLoader, id, visibilityRuleService, principal); InputStream resource = new FileInputStream(file.getFile()); HttpHeaders responseHeaders = new HttpHeaders(); responseHeaders.setContentLength(file.getFile().length()); @@ -218,7 +219,7 @@ public class Datasets extends BaseController { @RequestMapping(method = RequestMethod.GET, value = {"/getPDF/{id}"}) public @ResponseBody ResponseEntity getPDFDocument(@PathVariable String id, @ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal) throws IllegalAccessException, IOException, InstantiationException, InterruptedException { - FileEnvelope file = datasetManager.getWordDocumentFile(this.configLoader, id, this.getApiContext().getUtilitiesService().getVisibilityRuleService(), principal); + FileEnvelope file = datasetManager.getWordDocumentFile(this.configLoader, id, new VisibilityRuleServiceImpl(), principal); String fileName = file.getFilename().replace(" ", "_").replace(",", "_"); if (fileName.endsWith(".docx")){ fileName = fileName.substring(0, fileName.length() - 5); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java index b8c4ccf0d..6b13dc058 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java @@ -1,7 +1,5 @@ package eu.eudat.logic.managers; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import eu.eudat.configurations.dynamicgrant.DynamicGrantConfiguration; import eu.eudat.configurations.dynamicgrant.entities.Property; @@ -33,6 +31,7 @@ import eu.eudat.logic.mapper.elastic.criteria.DmpCriteriaMapper; import eu.eudat.logic.proxy.config.configloaders.ConfigLoader; import eu.eudat.logic.services.ApiContext; import eu.eudat.logic.services.forms.VisibilityRuleService; +import eu.eudat.logic.services.forms.VisibilityRuleServiceImpl; import eu.eudat.logic.services.operations.DatabaseRepository; import eu.eudat.logic.services.utilities.UtilitiesService; import eu.eudat.logic.utilities.builders.XmlBuilder; @@ -106,7 +105,6 @@ public class DataManagementPlanManager { private ApiContext apiContext; private DatasetManager datasetManager; - private UtilitiesService utilitiesService; private DatabaseRepository databaseRepository; private Environment environment; private RDAManager rdaManager; @@ -117,7 +115,6 @@ public class DataManagementPlanManager { public DataManagementPlanManager(ApiContext apiContext, DatasetManager datasetManager, Environment environment, RDAManager rdaManager, UserManager userManager, MetricsManager metricsManager) { this.apiContext = apiContext; this.datasetManager = datasetManager; - this.utilitiesService = apiContext.getUtilitiesService(); this.databaseRepository = apiContext.getOperationsContext().getDatabaseRepository(); this.environment = environment; this.rdaManager = rdaManager; @@ -1172,7 +1169,7 @@ public class DataManagementPlanManager { public FileEnvelope getWordDocument(String id, Principal principal, ConfigLoader configLoader, Boolean versioned) throws IOException { WordBuilder wordBuilder = new WordBuilder(); - VisibilityRuleService visibilityRuleService = this.utilitiesService.getVisibilityRuleService(); + VisibilityRuleService visibilityRuleService = new VisibilityRuleServiceImpl(); DatasetWizardModel dataset = new DatasetWizardModel(); XWPFDocument document = configLoader.getDocument(); @@ -1341,7 +1338,7 @@ public class DataManagementPlanManager { private FileEnvelope getXmlDocument(String id, Principal principal) throws InstantiationException, IllegalAccessException, IOException { ExportXmlBuilder xmlBuilder = new ExportXmlBuilder(); - VisibilityRuleService visibilityRuleService = utilitiesService.getVisibilityRuleService(); + VisibilityRuleService visibilityRuleService = new VisibilityRuleServiceImpl(); eu.eudat.data.entities.DMP dmp = databaseRepository.getDmpDao().find(UUID.fromString(id)); if (!dmp.isPublic() && dmp.getUsers().stream().filter(userInfo -> userInfo.getUser().getId() == principal.getId()).collect(Collectors.toList()).size() == 0) throw new UnauthorisedException(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementProfileManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementProfileManager.java index 6f1797776..031bab7e7 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementProfileManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementProfileManager.java @@ -164,18 +164,23 @@ public class DataManagementProfileManager { } private List> externalAutocompleteRequest(DmpProfileExternalAutoComplete data, String like) { - List> result = new LinkedList<>(); - RestTemplate restTemplate = new RestTemplate(); - HttpHeaders headers = new HttpHeaders(); - headers.setAccept(Collections.singletonList(MediaType.valueOf("application/vnd.api+json; charset=utf-8"))); - headers.setContentType(MediaType.APPLICATION_JSON); - HttpEntity entity = new HttpEntity<>("parameters", headers); - - ResponseEntity response = restTemplate.exchange(data.getUrl() + "?search=" + like, HttpMethod.GET, entity, Object.class); - DocumentContext jsonContext = JsonPath.parse(response.getBody()); - - List> jsonItems = jsonContext.read(data.getOptionsRoot() + "['" + data.getLabel() + "','" + data.getValue() + "']"); - jsonItems.forEach(item -> result.add(new Tuple<>(item.get(data.getValue()), item.get(data.getLabel())))); - return result; + return externalAutocompleteRequest(data.getUrl(), data.getOptionsRoot(), data.getLabel(), data.getValue(), like); } + + public static List> externalAutocompleteRequest(String url, String optionsRoot, String label, String value, String like) { + List> result = new LinkedList<>(); + RestTemplate restTemplate = new RestTemplate(); + HttpHeaders headers = new HttpHeaders(); + headers.setAccept(Collections.singletonList(MediaType.valueOf("application/vnd.api+json; charset=utf-8"))); + headers.setContentType(MediaType.APPLICATION_JSON); + HttpEntity entity = new HttpEntity<>("parameters", headers); + + ResponseEntity response = restTemplate.exchange(url + "?search=" + like, HttpMethod.GET, entity, Object.class); + DocumentContext jsonContext = JsonPath.parse(response.getBody()); + + List> jsonItems = jsonContext.read(optionsRoot + "['" + label + "','" + value + "']"); + jsonItems.forEach(item -> result.add(new Tuple<>(item.get(value), item.get(label)))); + return result; + + } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java index 92b7d11c0..5d3c35c98 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java @@ -26,6 +26,7 @@ import eu.eudat.logic.mapper.elastic.criteria.DmpCriteriaMapper; import eu.eudat.logic.proxy.config.configloaders.ConfigLoader; import eu.eudat.logic.services.ApiContext; import eu.eudat.logic.services.forms.VisibilityRuleService; +import eu.eudat.logic.services.forms.VisibilityRuleServiceImpl; import eu.eudat.logic.services.operations.DatabaseRepository; import eu.eudat.logic.utilities.documents.helpers.FileEnvelope; import eu.eudat.logic.utilities.documents.types.ParagraphStyle; @@ -49,7 +50,6 @@ import eu.eudat.models.data.user.composite.PagedDatasetProfile; import eu.eudat.queryable.QueryableList; import eu.eudat.types.Authorities; import eu.eudat.types.MetricNames; -import org.apache.commons.io.IOUtils; import org.apache.poi.xwpf.extractor.XWPFWordExtractor; import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.apache.poi.xwpf.usermodel.XWPFParagraph; @@ -60,11 +60,11 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; -import org.springframework.core.io.FileSystemResource; -import org.springframework.http.*; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.web.client.RestTemplate; import org.springframework.web.multipart.MultipartFile; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -91,8 +91,6 @@ import java.time.temporal.ChronoUnit; import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; @Component public class DatasetManager { @@ -527,7 +525,7 @@ public class DatasetManager { public String getWordDocumentText (Dataset datasetEntity) throws Exception { DatasetWizardModel datasetWizardModel = new DatasetWizardModel().fromDataModel(datasetEntity); datasetWizardModel.setDatasetProfileDefinition(this.getPagedProfile(datasetWizardModel, datasetEntity)); - XWPFDocument document = getLightWordDocument(this.configLoader, datasetWizardModel, this.apiContext.getUtilitiesService().getVisibilityRuleService()); + XWPFDocument document = getLightWordDocument(this.configLoader, datasetWizardModel, new VisibilityRuleServiceImpl()); XWPFWordExtractor extractor = new XWPFWordExtractor(document); return extractor.getText();/*.replaceAll("\n\\s*", " ");*/ } @@ -657,7 +655,7 @@ public class DatasetManager { JSONObject obj = new JSONObject(dataset.getProperties()); - VisibilityRuleService visibilityRuleService = this.apiContext.getUtilitiesService().getVisibilityRuleService(); + VisibilityRuleService visibilityRuleService = new VisibilityRuleServiceImpl(); visibilityRuleService.setProperties(obj.toMap()); dataset.setProfile(profile); @@ -666,12 +664,16 @@ public class DatasetManager { for (String validator : datasetProfileValidators) { - if ((obj.has(validator) && (obj.getString(validator) == null || obj.getString(validator).trim().isEmpty())) && isElementVisible(nodeList, validator, visibilityRuleService)) { + if (obj.has(validator) && isNullOrEmpty(obj.getString(validator)) && isElementVisible(nodeList, validator, visibilityRuleService)) { throw new Exception("Field value of " + validator + " must be filled."); } } } + private boolean isNullOrEmpty(String value) { + return value == null || value.trim().isEmpty(); + } + private boolean isElementVisible(NodeList nodeList, String id, VisibilityRuleService visibilityRuleService) { Element fieldSet = null; for (int i = 0; i < nodeList.getLength(); i++) { @@ -1048,10 +1050,13 @@ public class DatasetManager { Set tagNodes = new HashSet<>(); tagNodes.addAll(JsonSearcher.findNodes(propertiesJson, "renderStyle", "tags", true)); tagNodes.addAll(JsonSearcher.findNodes(propertiesJson, "rdaProperty", "dataset.keyword")); + if(wizardModel.getTags() == null){ + wizardModel.setTags(new ArrayList<>()); + } if (!tagNodes.isEmpty()) { tagNodes.forEach(node -> { JsonNode value = node.get("value"); - if (!value.toString().equals("\"\"")) { + if (!value.toString().equals("\"\"") && !value.toString().equals("null")) { String stringValue = value.toString().replaceAll("=", ":"); JSONArray values = new JSONArray(stringValue); values.iterator().forEachRemaining(element -> { diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/forms/VisibilityRuleServiceImpl.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/forms/VisibilityRuleServiceImpl.java index d46e138de..c5ce592f1 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/services/forms/VisibilityRuleServiceImpl.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/forms/VisibilityRuleServiceImpl.java @@ -1,30 +1,26 @@ package eu.eudat.logic.services.forms; import eu.eudat.models.data.user.components.commons.Rule; -import org.springframework.stereotype.Service; import java.util.*; /** * Created by ikalyvas on 3/5/2018. */ -@Service("visibilityRuleService") public class VisibilityRuleServiceImpl implements VisibilityRuleService { - private Map elementVisibility = new HashMap<>(); - private VisibilityContext visibilityContext; + private final Map elementVisibility = new HashMap<>(); private Map properties; public boolean isElementVisible(String id) { - if (!this.elementVisibility.containsKey(id) || this.elementVisibility.get(id)) return true; - return false; + return !this.elementVisibility.containsKey(id) || this.elementVisibility.get(id); } public void setProperties(Map properties) { this.properties = properties; this.properties.entrySet().stream() - .filter(stringObjectEntry -> stringObjectEntry.getValue() instanceof String && ((String) stringObjectEntry.getValue()).startsWith("[") && ((String) stringObjectEntry.getValue()).endsWith("]")).forEach(stringObjectEntry -> { - stringObjectEntry.setValue(parseArray((String) stringObjectEntry.getValue())); - }); + .filter(stringObjectEntry -> stringObjectEntry.getValue() instanceof String && ((String) stringObjectEntry.getValue()).startsWith("[") + && ((String) stringObjectEntry.getValue()).endsWith("]")) + .forEach(stringObjectEntry -> stringObjectEntry.setValue(parseArray((String) stringObjectEntry.getValue()))); } private List parseArray(String original) { @@ -33,19 +29,20 @@ public class VisibilityRuleServiceImpl implements VisibilityRuleService { } public void buildVisibilityContext(List sources) { - this.visibilityContext = new VisibilityContext(); - this.visibilityContext.buildVisibilityContext(sources); - this.visibilityContext.getVisibilityRules().forEach(item-> this.evaluateVisibility(item)); + VisibilityContext visibilityContext = new VisibilityContext(); + visibilityContext.buildVisibilityContext(sources); + visibilityContext.getVisibilityRules().forEach(this::evaluateVisibility); } private void evaluateVisibility(VisibilityRule rule) { List sources = rule.getVisibilityRuleSources(); - for(int i = 0; i < sources.size(); i++){ - if (properties.containsKey(sources.get(i).getVisibilityRuleSourceId()) && (isContained(properties.get(sources.get(i).getVisibilityRuleSourceId()), sources.get(i).getVisibilityRuleSourceValue()) || properties.get(sources.get(i).getVisibilityRuleSourceId()).equals(sources.get(i).getVisibilityRuleSourceValue()))) { + for(VisibilityRuleSource source: sources){ + if (properties.containsKey(source.getVisibilityRuleSourceId()) + && isContained(properties.get(source.getVisibilityRuleSourceId()), source.getVisibilityRuleSourceValue())) { this.elementVisibility.put(rule.getVisibilityRuleTargetId(), true); - }else{ - this.elementVisibility.put(rule.getVisibilityRuleTargetId(), false); - return; + } else { + this.elementVisibility.put(rule.getVisibilityRuleTargetId(), + this.elementVisibility.getOrDefault(rule.getVisibilityRuleTargetId(), false)); } } } @@ -53,7 +50,8 @@ public class VisibilityRuleServiceImpl implements VisibilityRuleService { private Boolean isContained(Object values, String source) { if (values instanceof List) { return ((Collection) values).contains(source); + } else { + return values.equals(source); } - return false; } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/utilities/UtilitiesService.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/utilities/UtilitiesService.java index 3a6a25c4f..58e9c499b 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/services/utilities/UtilitiesService.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/utilities/UtilitiesService.java @@ -11,7 +11,5 @@ public interface UtilitiesService { MailService getMailService(); - VisibilityRuleService getVisibilityRuleService(); - ConfirmationEmailService getConfirmationEmailService(); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/utilities/UtilitiesServiceImpl.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/utilities/UtilitiesServiceImpl.java index 9838a8b99..9bc943280 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/services/utilities/UtilitiesServiceImpl.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/utilities/UtilitiesServiceImpl.java @@ -1,6 +1,7 @@ package eu.eudat.logic.services.utilities; import eu.eudat.logic.services.forms.VisibilityRuleService; +import eu.eudat.logic.services.forms.VisibilityRuleServiceImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -12,22 +13,15 @@ public class UtilitiesServiceImpl implements UtilitiesService { private InvitationService invitationService; private MailService mailService; - private VisibilityRuleService visibilityRuleService; private ConfirmationEmailService confirmationEmailService; @Autowired - public UtilitiesServiceImpl(InvitationService invitationService, MailService mailService, VisibilityRuleService visibilityRuleService, ConfirmationEmailService confirmationEmailService) { + public UtilitiesServiceImpl(InvitationService invitationService, MailService mailService, ConfirmationEmailService confirmationEmailService) { this.invitationService = invitationService; this.mailService = mailService; - this.visibilityRuleService = visibilityRuleService; this.confirmationEmailService = confirmationEmailService; } - @Override - public VisibilityRuleService getVisibilityRuleService() { - return visibilityRuleService; - } - @Override public ConfirmationEmailService getConfirmationEmailService() { return confirmationEmailService; diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/word/WordBuilder.java b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/word/WordBuilder.java index 6a341fed4..51eeee345 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/word/WordBuilder.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/word/WordBuilder.java @@ -27,7 +27,9 @@ import java.io.IOException; import java.math.BigInteger; import java.text.SimpleDateFormat; import java.time.Instant; +import java.time.LocalDate; import java.time.ZoneId; +import java.time.ZoneOffset; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; import java.time.temporal.TemporalAccessor; @@ -191,6 +193,7 @@ public class WordBuilder { private Boolean createCompositeFields(List
compositeFields, XWPFDocument mainDocumentPart, Integer indent, Boolean createListing, VisibilityRuleService visibilityRuleService, Integer page, String section) { if (createListing) this.addListing(mainDocumentPart, indent, true, true); boolean hasValue = false; + boolean returnedValue = false; for (FieldSet compositeField: compositeFields) { if (visibilityRuleService.isElementVisible(compositeField.getId()) && hasVisibleFields(compositeField, visibilityRuleService)) { char c = 'a'; @@ -205,6 +208,9 @@ public class WordBuilder { } } hasValue = createFields(compositeField.getFields(), mainDocumentPart, 3, createListing, visibilityRuleService); + if(hasValue){ + returnedValue = true; + } if (compositeField.getMultiplicityItems() != null && !compositeField.getMultiplicityItems().isEmpty()) { List
list = compositeField.getMultiplicityItems().stream().sorted(Comparator.comparingInt(FieldSet::getOrdinal)).collect(Collectors.toList()); for (FieldSet multiplicityFieldset : list) { @@ -213,6 +219,9 @@ public class WordBuilder { addParagraphContent(c + ".\n", mainDocumentPart, ParagraphStyle.HEADER6, numId); } hasValue = createFields(multiplicityFieldset.getFields(), mainDocumentPart, 3, createListing, visibilityRuleService); + if(hasValue){ + returnedValue = true; + } } } if (hasValue && compositeField.getHasCommentField() && compositeField.getCommentFieldValue() != null && !compositeField.getCommentFieldValue().isEmpty() && !createListing) { @@ -225,7 +234,7 @@ public class WordBuilder { } } } - return hasValue; + return returnedValue; } private Boolean createFields(List fields, XWPFDocument mainDocumentPart, Integer indent, Boolean createListing, VisibilityRuleService visibilityRuleService) { @@ -395,7 +404,7 @@ public class WordBuilder { try { instant = Instant.parse((String) field.getValue()); } catch (DateTimeParseException ex) { - instant = Instant.from(DateTimeFormatter.ofPattern("yyyy-MM-dd").withZone(ZoneId.systemDefault()).parse((String) field.getValue())); + instant = LocalDate.parse((String) field.getValue()).atStartOfDay().toInstant(ZoneOffset.UTC); } return field.getValue() != null ? DateTimeFormatter.ofPattern("yyyy-MM-dd").withZone(ZoneId.systemDefault()).format(instant) : ""; } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/datasetProfileXml/ExportXmlBuilderDatasetProfile.java b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/datasetProfileXml/ExportXmlBuilderDatasetProfile.java index 78d485371..c88e39b9b 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/datasetProfileXml/ExportXmlBuilderDatasetProfile.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/datasetProfileXml/ExportXmlBuilderDatasetProfile.java @@ -163,6 +163,11 @@ public class ExportXmlBuilderDatasetProfile { numbering.setTextContent(field.getNumbering()); elementField.appendChild(numbering); } + if (field.getRdaProperty() != null) { + Element rdaProperty = element.createElement("rdaProperty"); + rdaProperty.setTextContent(field.getRdaProperty()); + elementField.appendChild(rdaProperty); + } if (field.getValidations() != null) { Element validations = element.createElement("validations"); field.getValidations().forEach(validation -> { diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/datasetProfileXml/datasetProfileModel/Fields/Field.java b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/datasetProfileXml/datasetProfileModel/Fields/Field.java index a4cce3d02..89e66e869 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/datasetProfileXml/datasetProfileModel/Fields/Field.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/datasetProfileXml/datasetProfileModel/Fields/Field.java @@ -29,6 +29,8 @@ public class Field { private Object data; + private String rdaProperty; + @XmlAttribute(name = "id") public String getId() { return id; @@ -101,6 +103,15 @@ public class Field { this.data = data; } + @XmlElement(name = "rdaProperty") + public String getRdaProperty() { + return rdaProperty; + } + + public void setRdaProperty(String rdaProperty) { + this.rdaProperty = rdaProperty; + } + public eu.eudat.models.data.admin.components.datasetprofile.Field toAdminCompositeModelSection() { eu.eudat.models.data.admin.components.datasetprofile.Field fieldEntity =new eu.eudat.models.data.admin.components.datasetprofile.Field(); @@ -120,6 +131,7 @@ public class Field { if (data != null) { fieldEntity.setData(data.toMap((Element) this.data)); } + fieldEntity.setRdaCommonStandard(this.rdaProperty); return fieldEntity; } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/admin/components/datasetprofile/Field.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/admin/components/datasetprofile/Field.java index 7903a4ddc..8847c8692 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/admin/components/datasetprofile/Field.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/admin/components/datasetprofile/Field.java @@ -13,7 +13,7 @@ import java.util.stream.Collectors; public class Field implements ViewStyleDefinition, Comparable { public enum ValidationType { - NONE((short) 0), REQUIRED((short) 1); + NONE((short) 0), REQUIRED((short) 1), URL((short) 2); private short value; private ValidationType(short value) { @@ -30,6 +30,8 @@ public class Field implements ViewStyleDefinition { @@ -361,6 +357,11 @@ public class DatasetWizardModel implements DataModel parsedTags = rawTags.stream().map(rawTag -> new Tag((String) rawTag, (String) rawTag)).collect(Collectors.toList()); value = mapper.writeValueAsString(parsedTags); + List nodes = JsonSearcher.findNodes(parentNode, "rdaProperty", "dataset.keyword"); + for (JsonNode node: nodes) { + String id = node.get(0) != null ? node.get(0).get("id").asText() : node.get("id").asText(); + properties.put(id, value); + } } } setterMethod.invoke(datasetWizardModel, mapper.readValue(value, params[0])); @@ -375,9 +376,10 @@ public class DatasetWizardModel implements DataModel formats = new ArrayList<>(); String extension; @@ -389,37 +391,45 @@ public class DatasetWizardModel implements DataModel standardFormats = new ArrayList<>(); - for(String format: formats) { - RestTemplate restTemplate = new RestTemplate(); - String parsedUrl = "https://eestore.paas2.uninett.no/api/fileformat/?search=" + format; - HttpHeaders headers = new HttpHeaders(); - headers.setAccept(Collections.singletonList(new MediaType("application", "vnd.api+json"))); - HttpEntity entity = new HttpEntity("", headers); - Map data = restTemplate.exchange(parsedUrl, HttpMethod.GET, entity, LinkedHashMap.class).getBody(); - jsonArr = new JSONArray(new ObjectMapper().writeValueAsString(data.get("data"))); - for(int i = 0; i < jsonArr.length(); i++){ - JSONObject jsonObj = jsonArr.getJSONObject(i); - jsonObj = jsonObj.getJSONObject("attributes"); - JSONArray extensions = jsonObj.getJSONArray("extensions"); - Object formatName = jsonObj.get("name"); - boolean found = false; - for(int j = 0; j < extensions.length(); j++){ - if(extensions.getString(j).equals(format)){ - JSONObject cur = new JSONObject(); - cur.put("label", formatName.toString()); - standardFormats.add(cur.toString()); - found = true; - break; + + String renderStyle = node.get(0) != null ? node.get(0).get("viewStyle").get("renderStyle").asText() : node.get("viewStyle").get("renderStyle").asText(); + if(renderStyle.equals("combobox")){ + String autocomplete = node.get(0) != null ? node.get(0).get("data").get("type").asText() : node.get("data").get("type").asText(); + if(autocomplete.equals("autocomplete")) { + JsonNode urlNode = node.get(0) != null ? node.get(0).get("data").get("autoCompleteSingleDataList") : node.get("data").get("autoCompleteSingleDataList"); + String url = urlNode.get(0).get("url").asText(); + String optionsRoot = urlNode.get(0).get("optionsRoot").asText(); + String label = urlNode.get(0).get("autoCompleteOptions").get("label").asText(); + String val = urlNode.get(0).get("autoCompleteOptions").get("value").asText(); + for (String format : formats) { + List> result = DataManagementProfileManager.externalAutocompleteRequest(url, optionsRoot, label, val, format); + result = result.stream().distinct().collect(Collectors.toList()); + if(!result.isEmpty()){ + for (Tuple f : result) { + JSONObject cur = new JSONObject(); + cur.put("label", f.getLabel()); + standardFormats.add(cur.toString()); + freeTextFormat.append(f.getLabel()).append(", "); + } + } + else{ + freeTextFormat.append(format).append(", "); } } - if(found){ - break; + properties.put(id, standardFormats); + } + } + else if(renderStyle.equals("freetext")){ + if (freeTextFormat.length() == 0) { + for (String format : formats) { + freeTextFormat.append(format).append(", "); } } - + freeTextFormat.setLength(freeTextFormat.length() - 2); + properties.put(id, freeTextFormat.toString()); } - properties.put(id, standardFormats); } else if(prefillingMapping.getMaDmpTarget().equals("dataset.distribution.data_access")){ value = value.replace("\"", ""); diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DistributionRDAMapper.java b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DistributionRDAMapper.java index 00eae64b7..c9bd007dc 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DistributionRDAMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DistributionRDAMapper.java @@ -89,12 +89,12 @@ public class DistributionRDAMapper { int i = 1; while(iter.hasNext()) { JsonNode current = iter.next(); - String format = JavaToJson.objectStringToJson(current.asText()); + String format = JavaToJson.objectStringToJson(current.toString()); try { Map result = new ObjectMapper().readValue(format, HashMap.class); format = result.get("label"); formats.add(format); - rda.setAdditionalProperty("format" + i++, new ObjectMapper().readTree(current.asText())); + rda.setAdditionalProperty("format" + i++, new ObjectMapper().readTree(current.toString())); } catch(JsonProcessingException e){ logger.warn(e.getMessage()); @@ -103,7 +103,12 @@ public class DistributionRDAMapper { rda.setFormat(formats); } else{ - rda.setFormat(new ArrayList<>(Arrays.asList(rdaValue.replace(" ", "").split(",")))); + if(rda.getFormat() == null || rda.getFormat().isEmpty()){ + rda.setFormat(new ArrayList<>(Arrays.asList(rdaValue.replace(" ", "").split(",")))); + } + else{ + rda.getFormat().addAll(Arrays.asList(rdaValue.replace(" ", "").split(","))); + } } rda.setAdditionalProperty(ImportPropertyName.FORMAT.getName(), node.get("id").asText()); break; @@ -209,19 +214,27 @@ public class DistributionRDAMapper { break; case FORMAT: if (rda.getFormat() != null && !rda.getFormat().isEmpty()) { - Map additionalProperties = rda.getAdditionalProperties(); - List standardFormats = new ArrayList<>(); - ObjectMapper mapper = new ObjectMapper(); - rda.getAdditionalProperties().forEach((key, value) -> { - try { - if (key.matches("format\\d+")) { - standardFormats.add(additionalProperties.get(key)); - properties.put(distributionNode.get("id").asText(), mapper.writeValueAsString(standardFormats)); - } - } catch (JsonProcessingException e) { - logger.error(e.getMessage(), e); + String style = distributionNode.get("viewStyle").get("renderStyle").asText(); + if(style.equals("combobox")) { + if (distributionNode.get("data").get("type").asText().equals("autocomplete")) { + Map additionalProperties = rda.getAdditionalProperties(); + List standardFormats = new ArrayList<>(); + ObjectMapper mapper = new ObjectMapper(); + rda.getAdditionalProperties().forEach((key, value) -> { + try { + if (key.matches("format\\d+")) { + standardFormats.add(additionalProperties.get(key)); + properties.put(distributionNode.get("id").asText(), mapper.writeValueAsString(standardFormats)); + } + } catch (JsonProcessingException e) { + logger.error(e.getMessage(), e); + } + }); } - }); + } + else if(style.equals("freetext")){ + properties.put(distributionNode.get("id").asText(), String.join(", ", rda.getFormat())); + } } break; case LICENSE: diff --git a/dmp-frontend/src/app/core/common/enum/validation-type.ts b/dmp-frontend/src/app/core/common/enum/validation-type.ts index f7ded1fba..d6a206e28 100644 --- a/dmp-frontend/src/app/core/common/enum/validation-type.ts +++ b/dmp-frontend/src/app/core/common/enum/validation-type.ts @@ -1,4 +1,18 @@ +import {ValidatorFn, Validators} from "@angular/forms"; + export enum ValidationType { None = 0, - Required = 1 + Required = 1, + URL = 2 +} + +export class ValidatorURL { + + public static regex = 'https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.' + + '[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.' + + '[a-zA-Z0-9]+\.[^\s]{2,}'; + + public static get validator(): ValidatorFn { + return Validators.pattern(ValidatorURL.regex); + } } diff --git a/dmp-frontend/src/app/core/model/dataset-profile-definition/field.ts b/dmp-frontend/src/app/core/model/dataset-profile-definition/field.ts index dc8cd80cd..93e74cab1 100644 --- a/dmp-frontend/src/app/core/model/dataset-profile-definition/field.ts +++ b/dmp-frontend/src/app/core/model/dataset-profile-definition/field.ts @@ -21,4 +21,5 @@ export interface Field { data: any; validations: Array; validationRequired; -} \ No newline at end of file + validationURL; +} diff --git a/dmp-frontend/src/app/library/rich-text-editor/rich-text-editor.component.scss b/dmp-frontend/src/app/library/rich-text-editor/rich-text-editor.component.scss index 721812d6a..f33c65603 100644 --- a/dmp-frontend/src/app/library/rich-text-editor/rich-text-editor.component.scss +++ b/dmp-frontend/src/app/library/rich-text-editor/rich-text-editor.component.scss @@ -9,6 +9,7 @@ //} .editor-wrapper { + position: relative; border: 1px solid transparent !important; border-radius: 5px; } @@ -40,6 +41,14 @@ border: 1px solid #f44336 !important; } +.clear { + position: absolute; + right: 5px; + bottom: 5px; + transform: translate(-50%, -50%); + cursor: pointer; +} + .full-width { width: 100%; } diff --git a/dmp-frontend/src/app/library/rich-text-editor/rich-text-editor.component.ts b/dmp-frontend/src/app/library/rich-text-editor/rich-text-editor.component.ts index 0a820532b..18a325348 100644 --- a/dmp-frontend/src/app/library/rich-text-editor/rich-text-editor.component.ts +++ b/dmp-frontend/src/app/library/rich-text-editor/rich-text-editor.component.ts @@ -1,5 +1,6 @@ import {Component, Input} from "@angular/core"; import {AngularEditorConfig} from "@kolkov/angular-editor"; +import {FormControl} from "@angular/forms"; @Component({ selector: 'rich-text-editor-component', @@ -7,6 +8,7 @@ import {AngularEditorConfig} from "@kolkov/angular-editor";
+ close
`, styleUrls: ['./rich-text-editor.component.scss'] @@ -53,6 +55,7 @@ export class RichTextEditorComponent { ] }; - constructor() { + get formInput(): FormControl { + return this.parentFormGroup.get(this.controlName); } } diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field/dataset-profile-editor-field.component.html b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field/dataset-profile-editor-field.component.html index 01347a092..7479f6a2b 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field/dataset-profile-editor-field.component.html +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field/dataset-profile-editor-field.component.html @@ -5,11 +5,16 @@
    -
  • +
  • {{'GENERAL.VALIDATION.REQUIRED' | translate}}
  • +
  • + + {{'GENERAL.VALIDATION.URL.LABEL' | translate}} + +
  • diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field/dataset-profile-editor-field.component.ts b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field/dataset-profile-editor-field.component.ts index 6010e3ebe..7a6149e2c 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field/dataset-profile-editor-field.component.ts +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field/dataset-profile-editor-field.component.ts @@ -1,21 +1,20 @@ - -import { Component, EventEmitter, Input, OnInit, Output} from '@angular/core'; +import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core'; import {FormArray, FormControl, FormGroup, FormGroupDirective, NgForm,} from '@angular/forms'; -import { DatasetProfileFieldViewStyle } from '@app/core/common/enum/dataset-profile-field-view-style'; -import { ValidationType } from '@app/core/common/enum/validation-type'; -import { DatasetProfileService } from '@app/core/services/dataset-profile/dataset-profile.service'; -import { EnumUtils } from '@app/core/services/utilities/enum-utils.service'; -import { RuleEditorModel } from '@app/ui/admin/dataset-profile/admin/rule-editor-model'; -import { BaseComponent } from '@common/base/base.component'; -import { Subscription } from 'rxjs'; -import { ViewStyleType } from './view-style-enum'; -import { DatasetProfileComboBoxType } from '@app/core/common/enum/dataset-profile-combo-box-type'; -import { ErrorStateMatcher } from '@angular/material/core'; -import { MatDialog } from '@angular/material/dialog'; -import { MatSlideToggleChange } from '@angular/material/slide-toggle'; -import { Field } from '@app/core/model/admin/dataset-profile/dataset-profile'; -import { DatasetProfileInternalDmpEntitiesType } from '@app/core/common/enum/dataset-profile-internal-dmp-entities-type'; -import { FieldEditorModel } from '../../../admin/field-editor-model'; +import {DatasetProfileFieldViewStyle} from '@app/core/common/enum/dataset-profile-field-view-style'; +import {ValidationType} from '@app/core/common/enum/validation-type'; +import {DatasetProfileService} from '@app/core/services/dataset-profile/dataset-profile.service'; +import {EnumUtils} from '@app/core/services/utilities/enum-utils.service'; +import {RuleEditorModel} from '@app/ui/admin/dataset-profile/admin/rule-editor-model'; +import {BaseComponent} from '@common/base/base.component'; +import {Subscription} from 'rxjs'; +import {ViewStyleType} from './view-style-enum'; +import {DatasetProfileComboBoxType} from '@app/core/common/enum/dataset-profile-combo-box-type'; +import {ErrorStateMatcher} from '@angular/material/core'; +import {MatDialog} from '@angular/material/dialog'; +import {MatSlideToggleChange} from '@angular/material/slide-toggle'; +import {Field} from '@app/core/model/admin/dataset-profile/dataset-profile'; +import {DatasetProfileInternalDmpEntitiesType} from '@app/core/common/enum/dataset-profile-internal-dmp-entities-type'; +import {FieldEditorModel} from '../../../admin/field-editor-model'; import { AutoCompleteFieldData, BooleanDecisionFieldData, @@ -28,17 +27,19 @@ import { ExternalDatasetsFieldData, FieldDataOption, FreeTextFieldData, + LicensesFieldData, OrganizationsFieldData, + PublicationsFieldData, RadioBoxFieldData, RegistriesFieldData, ResearchersAutoCompleteFieldData, + RichTextAreaFieldData, ServicesFieldData, TagsFieldData, + TaxonomiesFieldData, TextAreaFieldData, - RichTextAreaFieldData, ValidationFieldData, - WordListFieldData, - TaxonomiesFieldData, LicensesFieldData, PublicationsFieldData + WordListFieldData } from '@app/core/model/dataset-profile-definition/field-data/field-data'; @Component({ @@ -185,7 +186,9 @@ export class DatasetProfileEditorFieldComponent extends BaseComponent implements this.viewType = this.viewTypeEnum.Validation; break; } - + if(this.viewType !== this.viewTypeEnum.FreeText) { + this.setValidator(ValidationType.URL, false); + } } // this.showPreview = true; @@ -891,20 +894,24 @@ export class DatasetProfileEditorFieldComponent extends BaseComponent implements toggleRequired(event:MatSlideToggleChange){ + this.setValidator(ValidationType.Required, event.checked); + } + toggleURL(event:MatSlideToggleChange){ + this.setValidator(ValidationType.URL, event.checked); + } + + private setValidator(validationType: ValidationType, add: boolean) { let validationsControl = this.form.get('validations') as FormControl; let validations: Array = validationsControl.value; - if(event.checked){ - if(!validations.includes(ValidationType.Required)){//IS ALREADY REQUIRED - // validationsControl.setValue(validations.filter(validator=> validator != ValidationType.Required)); - // validationsControl.updateValueAndValidity(); - validations.push(ValidationType.Required); - // validationsControl.setValue(validations); + if(add){ + if(!validations.includes(validationType)){ + validations.push(validationType); validationsControl.updateValueAndValidity(); } - }else{ - validationsControl.setValue(validations.filter(validator=> validator != ValidationType.Required)); + } else{ + validationsControl.setValue(validations.filter(validator=> validator != validationType)); validationsControl.updateValueAndValidity(); } this.form.markAsDirty();//deactivate guard @@ -916,6 +923,12 @@ export class DatasetProfileEditorFieldComponent extends BaseComponent implements return validations.includes(ValidationType.Required); } + get isURL(){ + let validationsControl = this.form.get('validations') as FormControl; + let validations: Array = validationsControl.value; + return validations.includes(ValidationType.URL); + } + onDelete(){ this.delete.emit(); diff --git a/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.html b/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.html index 9a0a489c8..ec1cb77f6 100644 --- a/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.html +++ b/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.html @@ -89,7 +89,7 @@ chevron_right
    {{'DMP-EDITOR.STEPPER.NEXT' | translate}}
-
+
{{ 'DATASET-WIZARD.ACTIONS.SAVE-AND-ADD' | translate }}
@@ -107,7 +107,7 @@