From da9872576ec5dc15f35b82b59470b804d118b3b7 Mon Sep 17 00:00:00 2001 From: George Kalampokis Date: Thu, 5 Nov 2020 18:20:37 +0200 Subject: [PATCH] Initial commit for the new Dataset Template Field (identifier validator) --- .../java/eu/eudat/controllers/Validation.java | 44 +++++++++++++++++++ .../logic/managers/ValidationManager.java | 31 +++++++++++++ .../logic/proxy/config/ExternalUrls.java | 10 +++++ .../proxy/config/entities/ValidationUrls.java | 36 +++++++++++++++ .../logic/proxy/fetching/RemoteFetcher.java | 9 ++++ .../resources/externalUrls/ExternalUrls.xml | 22 ++++++++++ .../enum/dataset-profile-field-view-style.ts | 3 +- .../external-sources.service.ts | 4 ++ .../dataset-profile/dataset-profile.module.ts | 4 +- ...file-editor-validator-field.component.html | 9 ++++ ...file-editor-validator-field.component.scss | 3 ++ ...rofile-editor-validator-field.component.ts | 18 ++++++++ ...ataset-profile-editor-field.component.html | 1 + .../form-field/form-field.component.html | 24 ++++++++++ .../form-field/form-field.component.ts | 15 +++++++ 15 files changed, 231 insertions(+), 2 deletions(-) create mode 100644 dmp-backend/web/src/main/java/eu/eudat/controllers/Validation.java create mode 100644 dmp-backend/web/src/main/java/eu/eudat/logic/managers/ValidationManager.java create mode 100644 dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/entities/ValidationUrls.java create mode 100644 dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field-type/validator/dataset-profile-editor-validator-field.component.html create mode 100644 dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field-type/validator/dataset-profile-editor-validator-field.component.scss create mode 100644 dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field-type/validator/dataset-profile-editor-validator-field.component.ts diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/Validation.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/Validation.java new file mode 100644 index 000000000..f9e26d6dd --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/Validation.java @@ -0,0 +1,44 @@ +package eu.eudat.controllers; + +import eu.eudat.data.entities.Service; +import eu.eudat.logic.managers.ServiceManager; +import eu.eudat.logic.managers.ValidationManager; +import eu.eudat.logic.proxy.config.exceptions.HugeResultSet; +import eu.eudat.logic.proxy.config.exceptions.NoURLFound; +import eu.eudat.logic.services.ApiContext; +import eu.eudat.models.data.helpers.responses.ResponseItem; +import eu.eudat.models.data.security.Principal; +import eu.eudat.models.data.services.ServiceModel; +import eu.eudat.types.ApiMessageCode; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + + +@RestController +@CrossOrigin +@RequestMapping(value = {"/api"}) +public class Validation extends BaseController { + + private ValidationManager validationManager; + + @Autowired + public Validation(ApiContext apiContext, ValidationManager validationManager) { + super(apiContext); + this.validationManager = validationManager; + } + + @RequestMapping(method = RequestMethod.GET, value = {"/external/validation"}, produces = "application/json") + public @ResponseBody + ResponseEntity> validate( + @RequestParam(value = "query", required = false) String query, @RequestParam(value = "type", required = false) String type, Principal principal + ) throws HugeResultSet, NoURLFound { + Boolean isValid = this.validationManager.validateIdentifier(query, type, principal); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().payload(isValid).status(ApiMessageCode.NO_MESSAGE)); + } +} + diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/ValidationManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/ValidationManager.java new file mode 100644 index 000000000..566d64bc1 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/ValidationManager.java @@ -0,0 +1,31 @@ +package eu.eudat.logic.managers; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import eu.eudat.logic.proxy.config.ExternalUrlCriteria; +import eu.eudat.logic.proxy.config.exceptions.HugeResultSet; +import eu.eudat.logic.proxy.config.exceptions.NoURLFound; +import eu.eudat.logic.proxy.fetching.RemoteFetcher; +import eu.eudat.models.data.security.Principal; + +@Component +public class ValidationManager { + + private RemoteFetcher remoteFetcher; + + @Autowired + public ValidationManager(RemoteFetcher remoteFetcher) { + super(); + this.remoteFetcher = remoteFetcher; + } + + public Boolean validateIdentifier(String identifier, String type, Principal principal) throws NoURLFound, HugeResultSet { + ExternalUrlCriteria externalUrlCriteria = new ExternalUrlCriteria(identifier); + Integer count = this.remoteFetcher.findEntries(externalUrlCriteria, type); + return principal != null && count > 0; + } + + + +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/ExternalUrls.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/ExternalUrls.java index cb47186c1..2706681f7 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/ExternalUrls.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/ExternalUrls.java @@ -25,6 +25,7 @@ public class ExternalUrls implements Serializable { /*TagUrls tags;*/ FunderUrls funders; LicenseUrls licenses; + ValidationUrls validations; public RegistryUrls getRegistries() { @@ -143,6 +144,15 @@ public class ExternalUrls implements Serializable { public void setLicenses(LicenseUrls licenses) { this.licenses = licenses; } + + public ValidationUrls getValidations() { + return validations; + } + + @XmlElement(name = "validators") + public void setValidations(ValidationUrls validations) { + this.validations = validations; + } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/entities/ValidationUrls.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/entities/ValidationUrls.java new file mode 100644 index 000000000..56c8f4b33 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/entities/ValidationUrls.java @@ -0,0 +1,36 @@ +package eu.eudat.logic.proxy.config.entities; + +import java.util.List; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementWrapper; + +import eu.eudat.logic.proxy.config.FetchStrategy; +import eu.eudat.logic.proxy.config.UrlConfiguration; + +public class ValidationUrls { + + List urls; + FetchStrategy fetchMode; + + public List getUrls() { + return urls; + } + + @XmlElementWrapper + @XmlElement(name = "urlConfig") + public void setUrls(List urls) { + this.urls = urls; + } + + public FetchStrategy getFetchMode() { + return fetchMode; + } + + @XmlElement(name = "fetchMode") + public void setFetchMode(FetchStrategy fetchMode) { + this.fetchMode = fetchMode; + } + + +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcher.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcher.java index 2b0b6c2c1..674dcc30e 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcher.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcher.java @@ -141,6 +141,15 @@ public class RemoteFetcher { FetchStrategy fetchStrategy = configLoader.getExternalUrls().getLicenses().getFetchMode(); return getAll(urlConfigs, fetchStrategy, externalUrlCriteria); } + + public Integer findEntries(ExternalUrlCriteria externalUrlCriteria, String key) throws NoURLFound, HugeResultSet { + List urlConfigs = + key != null && !key.isEmpty() ? configLoader.getExternalUrls().getValidations().getUrls().stream().filter(item -> item.getKey().equals(key)).collect(Collectors.toList()) + : configLoader.getExternalUrls().getLicenses().getUrls(); + FetchStrategy fetchStrategy = configLoader.getExternalUrls().getLicenses().getFetchMode(); + List> data = this.getAll(urlConfigs, fetchStrategy, externalUrlCriteria); + return data.size(); + } private List> getAll(List urlConfigs, FetchStrategy fetchStrategy, ExternalUrlCriteria externalUrlCriteria) throws NoURLFound, HugeResultSet { diff --git a/dmp-backend/web/src/main/resources/externalUrls/ExternalUrls.xml b/dmp-backend/web/src/main/resources/externalUrls/ExternalUrls.xml index 5c128c86d..6c3eddf5c 100644 --- a/dmp-backend/web/src/main/resources/externalUrls/ExternalUrls.xml +++ b/dmp-backend/web/src/main/resources/externalUrls/ExternalUrls.xml @@ -959,6 +959,28 @@ FIRST + + + + + zenodo + + 1 + External + https://sandbox.zenodo.org/api/records/?page={page}&size={pageSize}&q={like} + 1 + application/vnd.zenodo.v1+json; charset=utf-8 + + $['hits']['hits'][*] + + 'conceptrecid' + + + $['hits']['total'] + + + FIRST + diff --git a/dmp-frontend/src/app/core/common/enum/dataset-profile-field-view-style.ts b/dmp-frontend/src/app/core/common/enum/dataset-profile-field-view-style.ts index c656787e3..a82869dec 100644 --- a/dmp-frontend/src/app/core/common/enum/dataset-profile-field-view-style.ts +++ b/dmp-frontend/src/app/core/common/enum/dataset-profile-field-view-style.ts @@ -15,5 +15,6 @@ export enum DatasetProfileFieldViewStyle { Researchers = "researchers", Organizations = "organizations", DatasetIdentifier = "datasetIdentifier", - Currency = "currency" + Currency = "currency", + Validation = 'validation' } diff --git a/dmp-frontend/src/app/core/services/external-sources/external-sources.service.ts b/dmp-frontend/src/app/core/services/external-sources/external-sources.service.ts index 3e91ec516..d2ab71653 100644 --- a/dmp-frontend/src/app/core/services/external-sources/external-sources.service.ts +++ b/dmp-frontend/src/app/core/services/external-sources/external-sources.service.ts @@ -76,4 +76,8 @@ export class ExternalSourcesService { return this.http.get(this.actionUrl + 'datasetprofiles/get' + '?query=' + like, { headers: this.headers }); } + public validateIdentifier(like: string, type: string): Observable { + return this.http.get(this.actionUrl + 'validation?query=' + like, '&type=' + type); + } + } diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/dataset-profile.module.ts b/dmp-frontend/src/app/ui/admin/dataset-profile/dataset-profile.module.ts index 538f26e0b..e79d5176d 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/dataset-profile.module.ts +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/dataset-profile.module.ts @@ -37,6 +37,7 @@ import { DatasetProfileEditorResearchersFieldComponent } from './editor/componen import { DatasetProfileEditorOrganizationsFieldComponent } from './editor/components/field-type/organizations/dataset-profile-editor-organizations-field.component'; import { DatasetProfileEditorDatasetIdentifierFieldComponent } from './editor/components/field-type/dataset-identifier/dataset-profile-editor-dataset-identifier-field.component'; import { DatasetProfileEditorCurrencyFieldComponent } from './editor/components/field-type/currency/dataset-profile-editor-currency-field.component'; +import { DatasetProfileEditorValidatorFieldComponent } from './editor/components/field-type/validator/dataset-profile-editor-validator-field.component'; @NgModule({ imports: [ @@ -79,7 +80,8 @@ import { DatasetProfileEditorCurrencyFieldComponent } from './editor/components/ DatasetProfileEditorResearchersFieldComponent, DatasetProfileEditorOrganizationsFieldComponent, DatasetProfileEditorDatasetIdentifierFieldComponent, - DatasetProfileEditorCurrencyFieldComponent + DatasetProfileEditorCurrencyFieldComponent, + DatasetProfileEditorValidatorFieldComponent ], entryComponents: [ DialodConfirmationUploadDatasetProfiles diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field-type/validator/dataset-profile-editor-validator-field.component.html b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field-type/validator/dataset-profile-editor-validator-field.component.html new file mode 100644 index 000000000..78920fe77 --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field-type/validator/dataset-profile-editor-validator-field.component.html @@ -0,0 +1,9 @@ +
+
{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-DATE-PICKER-TITLE' + | translate}}
+ + + +
diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field-type/validator/dataset-profile-editor-validator-field.component.scss b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field-type/validator/dataset-profile-editor-validator-field.component.scss new file mode 100644 index 000000000..3db0dee74 --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field-type/validator/dataset-profile-editor-validator-field.component.scss @@ -0,0 +1,3 @@ +.full-width { + width: 100%; +} diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field-type/validator/dataset-profile-editor-validator-field.component.ts b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field-type/validator/dataset-profile-editor-validator-field.component.ts new file mode 100644 index 000000000..021fa2633 --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field-type/validator/dataset-profile-editor-validator-field.component.ts @@ -0,0 +1,18 @@ +import { Component, Input, OnInit } from '@angular/core'; +import { FormGroup } from '@angular/forms'; +import { DataRepositoriesDataEditorModel } from '@app/ui/admin/dataset-profile/admin/field-data/data-repositories-data-editor-models'; + +@Component({ + selector: 'app-dataset-profile-editor-validator-field-component', + styleUrls: ['./dataset-profile-editor-validator-field.component.scss'], + templateUrl: './dataset-profile-editor-validator-field.component.html' +}) +export class DatasetProfileEditorValidatorFieldComponent implements OnInit { + + @Input() form: FormGroup; + private data: DataRepositoriesDataEditorModel = new DataRepositoriesDataEditorModel(); + + ngOnInit() { + if (!this.form.get('data')) { this.form.addControl('data', this.data.buildForm()); } + } +} 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 820ba4dd6..61611ef16 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 @@ -82,6 +82,7 @@ +

{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.RULES-TITLE' | translate}} diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-field/form-field.component.html b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-field/form-field.component.html index bd576ccdb..4632b73b0 100644 --- a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-field/form-field.component.html +++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-field/form-field.component.html @@ -247,4 +247,28 @@

+ +
+
+ + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + + + + + + {{ type.name }} + + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + + + + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + + +
+
diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-field/form-field.component.ts b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-field/form-field.component.ts index e4beae865..5f6419b86 100644 --- a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-field/form-field.component.ts +++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-field/form-field.component.ts @@ -78,6 +78,11 @@ export class FormFieldComponent extends BaseComponent implements OnInit { { name: 'Other', value: 'other' } ]; + + readonly validationTypes: any[] = [ + { name: 'Zenodo', value: 'zenodo' } + ]; + constructor( public visibilityRulesService: VisibilityRulesService, private datasetExternalAutocompleteService: DatasetExternalAutocompleteService, @@ -420,4 +425,14 @@ export class FormFieldComponent extends BaseComponent implements OnInit { searchCurrency(query: string): Observable { return this.currencyService.get(query); } + + validateId() { + const identifier = this.getDatasetIdControl('identifier').value; + const type = this.getDatasetIdControl('type').value; + + this.externalSourcesService.validateIdentifier(identifier, type).pipe(takeUntil(this._destroyed)).subscribe(result => { + console.log(result); + }); + + } }