diff --git a/src/main/java/org/filteredpush/qc/metadata/DwCMetadataDQ.java b/src/main/java/org/filteredpush/qc/metadata/DwCMetadataDQ.java index 9fad254..ec0876c 100644 --- a/src/main/java/org/filteredpush/qc/metadata/DwCMetadataDQ.java +++ b/src/main/java/org/filteredpush/qc/metadata/DwCMetadataDQ.java @@ -63,22 +63,25 @@ * * #72 13d5a10e-188e-40fd-a22c-dbaa87b91df2 ISSUE_DATAGENERALIZATIONS_NOTEMPTY * #94 acc8dff2-d8d1-483a-946d-65a02a452700 ISSUE_ESTABLISHMENTMEANS_NOTEMPTY - * #58 ac2b7648-d5f9-48ca-9b07-8ad5879a2536 VALIDATION_BASISOFRECORD_NOTEMPTY - * #103 374b091a-fc90-4791-91e5-c1557c649169 VALIDATION_DCTYPE_NOTEMPTY - * #99 15f78619-811a-4c6f-997a-a4c7888ad849 VALIDATION_LICENSE_NOTEMPTY * #47 c486546c-e6e5-48a7-b286-eba7f5ca56c4 VALIDATION_OCCURRENCEID_NOTEMPTY - * #117 eb4a17f6-6bea-4cdd-93dd-d5a7e9d1eccf VALIDATION_OCCURRENCESTATUS_NOTEMPTY - * #116 7af25f1e-a4e2-4ff4-b161-d1f25a5c3e47 VALIDATION_OCCURRENCESTATUS_STANDARD - * #104 42408a00-bf71-4892-a399-4325e2bc1fb8 VALIDATION_BASISOFRECORD_STANDARD - * #91 cdaabb0d-a863-49d0-bc0f-738d771acba5 VALIDATION_DCTYPE_STANDARD + * #99 15f78619-811a-4c6f-997a-a4c7888ad849 VALIDATION_LICENSE_NOTEMPTY * #38 3136236e-04b6-49ea-8b34-a65f25e3aba1 VALIDATION_LICENSE_STANDARD + * #91 cdaabb0d-a863-49d0-bc0f-738d771acba5 VALIDATION_DCTYPE_STANDARD + * #103 374b091a-fc90-4791-91e5-c1557c649169 VALIDATION_DCTYPE_NOTEMPTY * #41 bd385eeb-44a2-464b-a503-7abe407ef904 AMENDMENT_DCTYPE_STANDARDIZED + * #58 ac2b7648-d5f9-48ca-9b07-8ad5879a2536 VALIDATION_BASISOFRECORD_NOTEMPTY + * #104 42408a00-bf71-4892-a399-4325e2bc1fb8 VALIDATION_BASISOFRECORD_STANDARD * 63 07c28ace-561a-476e-a9b9-3d5ad6e35933 AMENDMENT_BASISOFRECORD_STANDARDIZED + * #117 eb4a17f6-6bea-4cdd-93dd-d5a7e9d1eccf VALIDATION_OCCURRENCESTATUS_NOTEMPTY + * #116 7af25f1e-a4e2-4ff4-b161-d1f25a5c3e47 VALIDATION_OCCURRENCESTATUS_STANDARD * #75 96667a0a-ae59-446a-bbb0-b7f2b0ca6cf5 AMENDMENT_OCCURRENCESTATUS_ASSUMEDDEFAULT * #115 f8f3a093-042c-47a3-971a-a482aaaf3b75 AMENDMENT_OCCURRENCESTATUS_STANDARDIZED * #277 5424e933-bee7-4125-839e-d8743ea69f93 VALIDATION_PATHWAY_STANDARD * #285 4833a522-12eb-4fe0-b4cf-7f7a337a6048 VALIDATION_TYPESTATUS_STANDARD * #283 88d8598b-3318-483d-9475-a5acf9887404 VALIDATION_SEX_STANDARD + * #284 33c45ae1-e2db-462a-a59e-7169bb01c5d6 AMENDMENT_SEX_STANDARDIZED + * #275 060e7734-607d-4737-8b2c-bfa17788bf1a VALIDATION_DEGREEOFESTABLISHMENT_STANDARD + * #276 74ef1034-e289-4596-b5b0-cde73796697d AMENDMENT_DEGREEOFESTABLISHMENT_STANDARDIZED * * TODO: Implement: * @@ -1285,33 +1288,64 @@ public DQResponse amendmentLifestageStandardized( /** * Does the value of dwc:degreeOfEstablishment occur in bdq:sourceAuthority? * - * Provides: VALIDATION_DEGREEOFESTABLISHMENT_STANDARD + * Provides: 275 VALIDATION_DEGREEOFESTABLISHMENT_STANDARD * Version: 2024-02-09 * * @param degreeOfEstablishment the provided dwc:degreeOfEstablishment to evaluate as ActedUpon. + * @param sourceAuthority the bdq:sourceAuthority to consult. * @return DQResponse the response of type ComplianceValue to return */ @Validation(label="VALIDATION_DEGREEOFESTABLISHMENT_STANDARD", description="Does the value of dwc:degreeOfEstablishment occur in bdq:sourceAuthority?") @Provides("060e7734-607d-4737-8b2c-bfa17788bf1a") @ProvidesVersion("https://rs.tdwg.org/bdq/terms/060e7734-607d-4737-8b2c-bfa17788bf1a/2024-02-09") - @Specification("EXTERNAL_PREREQUISITES_NOT_MET if the bdq:sourceAuthority is not available; INTERNAL_PREREQUISITES_NOT_MET if dwc:degreeOfEstablishment is EMPTY; COMPLIANT if the value of dwc:degreeOfEstablishment is in the bdq:sourceAuthority; otherwise NOT_COMPLIANT. bdq:sourceAuthority default = 'Darwin Core degreeOfEstablishment' {[https://dwc.tdwg.org/list/#dwc_degreeOfEstablishment]} {dwc:degreeOfEstablishment vocabulary API [https://api.gbif.org/v1/vocabularies/DegreeOfEstablishment/concepts]}") - public DQResponse validationDegreeofestablishmentStandard( - @ActedUpon("dwc:degreeOfEstablishment") String degreeOfEstablishment + @Specification("EXTERNAL_PREREQUISITES_NOT_MET if the bdq:sourceAuthority is not available; INTERNAL_PREREQUISITES_NOT_MET if dwc:degreeOfEstablishment is EMPTY; COMPLIANT if the value of dwc:degreeOfEstablishment is in the bdq:sourceAuthority; otherwise NOT_COMPLIANT.") + public static DQResponse validationDegreeofestablishmentStandard( + @ActedUpon("dwc:degreeOfEstablishment") String degreeOfEstablishment, + @Parameter(name="bdq:sourceAuthority") String sourceAuthority ) { DQResponse result = new DQResponse(); - //TODO: Implement specification - // EXTERNAL_PREREQUISITES_NOT_MET if the bdq:sourceAuthority - // is not available; INTERNAL_PREREQUISITES_NOT_MET if dwc:degreeOfEstablishment - // is EMPTY; COMPLIANT if the value of dwc:degreeOfEstablishment - // is in the bdq:sourceAuthority; otherwise NOT_COMPLIANT. - // bdq:sourceAuthority default = "Darwin Core degreeOfEstablishment" - // {[https://dwc.tdwg.org/list/#dwc_degreeOfEstablishment]} - // {dwc:degreeOfEstablishment vocabulary API [https://api.gbif.org/v1/vocabularies/DegreeOfEstablishment/concepts]} - // + // specification + // EXTERNAL_PREREQUISITES_NOT_MET if the bdq:sourceAuthority is not available; + // INTERNAL_PREREQUISITES_NOT_MET if dwc:degreeOfEstablishment is EMPTY; + // COMPLIANT if the value of dwc:degreeOfEstablishment is in the + // bdq:sourceAuthority; otherwise NOT_COMPLIANT. - //TODO: Parameters. This test is defined as parameterized. - // bdq:sourceAuthority + // Parameters. This test is defined as parameterized. + // bdq:sourceAuthority default = "Degree of Establishment Controlled Vocabulary + // List of Terms" {[https://dwc.tdwg.org/doe/]} {GBIF vocabulary API + // [https://api.gbif.org/v1/vocabularies/DegreeOfEstablishment/concepts]} + + if (MetadataUtils.isEmpty(degreeOfEstablishment)) { + result.addComment("No Value provided for dwc:degreeOfEstablishment"); + result.setResultState(ResultState.INTERNAL_PREREQUISITES_NOT_MET); + } else { + if (MetadataUtils.isEmpty(sourceAuthority)) { + sourceAuthority = "GBIF DegreeOfEstablishment Vocabulary"; + } + try { + MetadataSourceAuthority sourceAuthorityObject = new MetadataSourceAuthority(sourceAuthority); + if (!MetadataSingleton.getInstance().isLoaded()) { + result.addComment("Error accessing sourceAuthority: " + MetadataSingleton.getInstance().getLoadError() ); + result.setResultState(ResultState.EXTERNAL_PREREQUISITES_NOT_MET); + } else { + result.setResultState(ResultState.RUN_HAS_RESULT); + if (MetadataSingleton.getInstance().getDegreeOfEstablishmentTerms().containsKey(degreeOfEstablishment)) { + result.addComment("Provided value of dwc:degreeOfEstablishment found in the sourceAuthority"); + result.setValue(ComplianceValue.COMPLIANT); + } else { + result.addComment("Provided value of dwc:degreeOfEstablishment [" + degreeOfEstablishment + "] not found in the sourceAuthority"); + result.setValue(ComplianceValue.NOT_COMPLIANT); + } + } + } catch (SourceAuthorityException e) { + result.addComment("Error with specified bdq:sourceAuthority ["+ sourceAuthority +"]: " + e.getMessage()); + result.setResultState(ResultState.EXTERNAL_PREREQUISITES_NOT_MET); + } catch (Exception e) { + result.addComment("Error evaluating dwc:degreeOfEstablishment: " + e.getMessage()); + result.setResultState(ResultState.EXTERNAL_PREREQUISITES_NOT_MET); + } + } return result; } @@ -1319,22 +1353,24 @@ public DQResponse validationDegreeofestablishmentStandard( /** * Propose amendment to the value of dwc:degreeOfEstablishment using bdq:sourceAuthority. * - * Provides: AMENDMENT_DEGREEOFESTABLISHMENT_STANDARDIZED + * Provides: 276 AMENDMENT_DEGREEOFESTABLISHMENT_STANDARDIZED * Version: 2024-02-09 * * @param degreeOfEstablishment the provided dwc:degreeOfEstablishment to evaluate as ActedUpon. + * @param sourceAuthority the bdq:sourceAuthority to consult. * @return DQResponse the response of type AmendmentValue to return */ @Amendment(label="AMENDMENT_DEGREEOFESTABLISHMENT_STANDARDIZED", description="Propose amendment to the value of dwc:degreeOfEstablishment using bdq:sourceAuthority.") @Provides("74ef1034-e289-4596-b5b0-cde73796697d") @ProvidesVersion("https://rs.tdwg.org/bdq/terms/74ef1034-e289-4596-b5b0-cde73796697d/2024-02-09") @Specification("EXTERNAL_PREREQUISITES_NOT_MET if the bdq:sourceAuthority is not available; INTERNAL PREREQUISITES_NOT_MET if dwc:degreeOfEstablishment is EMPTY; AMENDED the value of dwc:degreeOfEstablishment if it can be unambiguously matched to a term in bdq:sourceAuthority; otherwise NOT_AMENDED bdq:sourceAuthority default = 'Darwin Core degreeOfEstablishment' {[https://dwc.tdwg.org/list/#dwc_degreeOfEstablishment]} {dwc:degreeOfEstablishment vocabulary API [https://api.gbif.org/v1/vocabularies/DegreeOfEstablishment/concepts]}") - public DQResponse amendmentDegreeofestablishmentStandardized( - @ActedUpon("dwc:degreeOfEstablishment") String degreeOfEstablishment + public static DQResponse amendmentDegreeofestablishmentStandardized( + @ActedUpon("dwc:degreeOfEstablishment") String degreeOfEstablishment, + @Parameter(name="bdq:sourceAuthority") String sourceAuthority ) { DQResponse result = new DQResponse(); - //TODO: Implement specification + // Specification // EXTERNAL_PREREQUISITES_NOT_MET if the bdq:sourceAuthority // is not available; INTERNAL PREREQUISITES_NOT_MET if dwc:degreeOfEstablishment // is EMPTY; AMENDED the value of dwc:degreeOfEstablishment @@ -1347,6 +1383,52 @@ public DQResponse amendmentDegreeofestablishmentStandardized( //TODO: Parameters. This test is defined as parameterized. // bdq:sourceAuthority + if (MetadataUtils.isEmpty(degreeOfEstablishment)) { + result.addComment("No Value provided for dwc:degreeOfEstablishment"); + result.setResultState(ResultState.INTERNAL_PREREQUISITES_NOT_MET); + } else { + if (MetadataUtils.isEmpty(sourceAuthority)) { + sourceAuthority = "GBIF DegreeOfEstablishment Vocabulary"; + } + try { + MetadataSourceAuthority sourceAuthorityObject = new MetadataSourceAuthority(sourceAuthority); + if (!MetadataSingleton.getInstance().isLoaded()) { + result.addComment("Error accessing sourceAuthority: " + MetadataSingleton.getInstance().getLoadError() ); + result.setResultState(ResultState.EXTERNAL_PREREQUISITES_NOT_MET); + } else { + if (MetadataSingleton.getInstance().getDegreeOfEstablishmentTerms().containsKey(degreeOfEstablishment)) { + result.addComment("Provided value of dwc:degreeOfEstablishment ["+degreeOfEstablishment+"] found in the sourceAuthority"); + result.setResultState(ResultState.NOT_AMENDED); + } else { + // Handle camel case value + if (degreeOfEstablishment.trim().toLowerCase().equals("widespread invasive")) { + degreeOfEstablishment = "widespreadInvasive"; + } + if (degreeOfEstablishment.trim().toLowerCase().equals("widespreadinvasive")) { + degreeOfEstablishment = "widespreadInvasive"; + } + if (MetadataSingleton.getInstance().getDegreeOfEstablishmentValues().containsKey(degreeOfEstablishment.trim())) { + String match = MetadataSingleton.getInstance().getDegreeOfEstablishmentValues().get(degreeOfEstablishment.trim()); + result.setResultState(ResultState.AMENDED); + Map values = new HashMap<>(); + values.put("dwc:degreeOfEstablishment", match) ; + result.setValue(new AmendmentValue(values)); + result.addComment("Provided value of dwc:degreeOfEstablishment [" + degreeOfEstablishment + "] conformed to the sourceAuthority"); + } else { + result.addComment("Provided value of dwc:degreeOfEstablishment [" + degreeOfEstablishment + "] unable to be conformed to the sourceAuthority"); + result.setResultState(ResultState.NOT_AMENDED); + } + } + } + } catch (SourceAuthorityException e) { + result.addComment("Error with specified bdq:sourceAuthority ["+ sourceAuthority +"]: " + e.getMessage()); + result.setResultState(ResultState.EXTERNAL_PREREQUISITES_NOT_MET); + } catch (Exception e) { + result.addComment("Error evaluating dwc:degreeOfEstablishment: " + e.getMessage()); + result.setResultState(ResultState.EXTERNAL_PREREQUISITES_NOT_MET); + } + } + return result; } @@ -1397,7 +1479,7 @@ public static DQResponse validationPathwayStandard( result.setResultState(ResultState.EXTERNAL_PREREQUISITES_NOT_MET); } else { result.setResultState(ResultState.RUN_HAS_RESULT); - if (MetadataSingleton.getInstance().getPathwayValues().containsKey(pathway)) { + if (MetadataSingleton.getInstance().getPathwayTerms().containsKey(pathway)) { result.addComment("Provided value of dwc:pathway found in the sourceAuthority"); result.setValue(ComplianceValue.COMPLIANT); } else { @@ -1528,7 +1610,7 @@ public static DQResponse validationSexStandard( result.setResultState(ResultState.EXTERNAL_PREREQUISITES_NOT_MET); } else { result.setResultState(ResultState.RUN_HAS_RESULT); - if (MetadataSingleton.getInstance().getSexValues().containsKey(sex)) { + if (MetadataSingleton.getInstance().getSexTerms().containsKey(sex)) { result.addComment("Provided value of dwc:sex found in the sourceAuthority"); result.setValue(ComplianceValue.COMPLIANT); } else { @@ -1551,32 +1633,72 @@ public static DQResponse validationSexStandard( /** * Propose amendment to the value of dwc:sex using bdq:sourceAuthority. * - * Provides: AMENDMENT_SEX_STANDARDIZED - * Version: 2024-02-09 + * Provides: 284 AMENDMENT_SEX_STANDARDIZED + * Version: 2024-03-25 * * @param sex the provided dwc:sex to evaluate as ActedUpon. + * @param sourceAuthority the bdq:sourceAuthority to consult. * @return DQResponse the response of type AmendmentValue to return */ @Amendment(label="AMENDMENT_SEX_STANDARDIZED", description="Propose amendment to the value of dwc:sex using bdq:sourceAuthority.") @Provides("33c45ae1-e2db-462a-a59e-7169bb01c5d6") - @ProvidesVersion("https://rs.tdwg.org/bdq/terms/33c45ae1-e2db-462a-a59e-7169bb01c5d6/2024-02-09") - @Specification("EXTERNAL_PREREQUISITES_NOT_MET if the bdq:sourceAuthority is not available; INTERNAL PREREQUISITES_NOT_MET if dwc:sex is EMPTY; AMENDED the value of dwc:sex if it can be unambiguously matched to a term in bdq:sourceAuthority; otherwise NOT_AMENDED bdq:sourceAuthority default = 'Darwin Core sex' {[https://dwc.tdwg.org/list/#dwc_sex]} {dwc:sex vocabulary API [NO CURRENT API EXISTS]}") - public DQResponse amendmentSexStandardized( - @ActedUpon("dwc:sex") String sex + @ProvidesVersion("https://rs.tdwg.org/bdq/terms/33c45ae1-e2db-462a-a59e-7169bb01c5d6/2024-03-25") + @Specification("EXTERNAL_PREREQUISITES_NOT_MET if the bdq:sourceAuthority is not available; INTERNAL PREREQUISITES_NOT_MET if dwc:sex is EMPTY; AMENDED the value of dwc:sex if it can be unambiguously matched to a term in bdq:sourceAuthority; otherwise NOT_AMENDED") + public static DQResponse amendmentSexStandardized( + @ActedUpon("dwc:sex") String sex, + @Parameter(name="bdq:sourceAuthority") String sourceAuthority ) { DQResponse result = new DQResponse(); - //TODO: Implement specification - // EXTERNAL_PREREQUISITES_NOT_MET if the bdq:sourceAuthority - // is not available; INTERNAL PREREQUISITES_NOT_MET if dwc:sex - // is EMPTY; AMENDED the value of dwc:sex if it can be unambiguously - // matched to a term in bdq:sourceAuthority; otherwise NOT_AMENDED - // bdq:sourceAuthority default = "Darwin Core sex" {[https://dwc.tdwg.org/list/#dwc_sex]} - // {dwc:sex vocabulary API [NO CURRENT API EXISTS]} + // specification + // EXTERNAL_PREREQUISITES_NOT_MET if the bdq:sourceAuthority is not available; + // INTERNAL PREREQUISITES_NOT_MET if dwc:sex is EMPTY; AMENDED the value of + // dwc:sex if it can be unambiguously matched to a term in bdq:sourceAuthority; + // otherwise NOT_AMENDED - //TODO: Parameters. This test is defined as parameterized. - // bdq:sourceAuthority + // Parameters. This test is defined as parameterized. + // bdq:sourceAuthority default = "GBIF Sex Vocabulary" + // [https://api.gbif.org/v1/vocabularies/Sex]} {"dwc:sex vocabulary API" + // [https://api.gbif.org/v1/vocabularies/Sex/concepts]} + if (MetadataUtils.isEmpty(sex)) { + result.addComment("No Value provided for dwc:sex"); + result.setResultState(ResultState.INTERNAL_PREREQUISITES_NOT_MET); + } else { + if (MetadataUtils.isEmpty(sourceAuthority)) { + sourceAuthority = "GBIF Sex Vocabulary"; + } + try { + MetadataSourceAuthority sourceAuthorityObject = new MetadataSourceAuthority(sourceAuthority); + if (!MetadataSingleton.getInstance().isLoaded()) { + result.addComment("Error accessing sourceAuthority: " + MetadataSingleton.getInstance().getLoadError() ); + result.setResultState(ResultState.EXTERNAL_PREREQUISITES_NOT_MET); + } else { + if (MetadataSingleton.getInstance().getSexTerms().containsKey(sex)) { + result.addComment("Provided value of dwc:sex found in the sourceAuthority"); + result.setResultState(ResultState.NOT_AMENDED); + } else { + if (MetadataSingleton.getInstance().getSexValues().containsKey(sex.trim())) { + String match = MetadataSingleton.getInstance().getSexValues().get(sex.trim()); + result.setResultState(ResultState.AMENDED); + Map values = new HashMap<>(); + values.put("dwc:sex", match) ; + result.setValue(new AmendmentValue(values)); + } else { + result.addComment("Provided value of dwc:sex [" + sex + "] unable to be conformed to the the sourceAuthority"); + result.setResultState(ResultState.NOT_AMENDED); + } + } + } + } catch (SourceAuthorityException e) { + result.addComment("Error with specified bdq:sourceAuthority ["+ sourceAuthority +"]: " + e.getMessage()); + result.setResultState(ResultState.EXTERNAL_PREREQUISITES_NOT_MET); + } catch (Exception e) { + result.addComment("Error evaluating dwc:sex: " + e.getMessage()); + result.setResultState(ResultState.EXTERNAL_PREREQUISITES_NOT_MET); + } + } + return result; } @@ -1625,7 +1747,7 @@ public static DQResponse validationTypestatusStandard( result.setResultState(ResultState.EXTERNAL_PREREQUISITES_NOT_MET); } else { result.setResultState(ResultState.RUN_HAS_RESULT); - if (MetadataSingleton.getInstance().getTypeStatusValues().containsKey(typeStatus)) { + if (MetadataSingleton.getInstance().getTypeStatusTerms().containsKey(typeStatus)) { result.addComment("Provided value of dwc:typeStatus found in the sourceAuthority"); result.setValue(ComplianceValue.COMPLIANT); } else { @@ -1907,7 +2029,7 @@ public static DQResponse validationLifestageStandard( result.setResultState(ResultState.EXTERNAL_PREREQUISITES_NOT_MET); } else { result.setResultState(ResultState.RUN_HAS_RESULT); - if (MetadataSingleton.getInstance().getLifeStageValues().containsKey(lifeStage)) { + if (MetadataSingleton.getInstance().getLifeStageTerms().containsKey(lifeStage)) { result.addComment("Provided value of dwc:lifeStage found in the sourceAuthority"); result.setValue(ComplianceValue.COMPLIANT); } else { diff --git a/src/main/java/org/filteredpush/qc/metadata/DwCMetadataDQDefaults.java b/src/main/java/org/filteredpush/qc/metadata/DwCMetadataDQDefaults.java index 85fca7f..ca63d05 100644 --- a/src/main/java/org/filteredpush/qc/metadata/DwCMetadataDQDefaults.java +++ b/src/main/java/org/filteredpush/qc/metadata/DwCMetadataDQDefaults.java @@ -164,4 +164,63 @@ public static DQResponse validationSexStandard( ) { return validationSexStandard(sex, null); } + + /** + * Propose amendment to the value of dwc:sex using bdq:sourceAuthority. + * Uses the default source authority + * + * Provides: 284 AMENDMENT_SEX_STANDARDIZED + * Version: 2024-03-25 + * + * @param sex the provided dwc:sex to evaluate as ActedUpon. + * @return DQResponse the response of type AmendmentValue to return + */ + @Amendment(label="AMENDMENT_SEX_STANDARDIZED", description="Propose amendment to the value of dwc:sex using bdq:sourceAuthority.") + @Provides("33c45ae1-e2db-462a-a59e-7169bb01c5d6") + @ProvidesVersion("https://rs.tdwg.org/bdq/terms/33c45ae1-e2db-462a-a59e-7169bb01c5d6/2024-03-25") + @Specification("EXTERNAL_PREREQUISITES_NOT_MET if the bdq:sourceAuthority is not available; INTERNAL PREREQUISITES_NOT_MET if dwc:sex is EMPTY; AMENDED the value of dwc:sex if it can be unambiguously matched to a term in bdq:sourceAuthority; otherwise NOT_AMENDED") + public static DQResponse amendmentSexStandardized( + @ActedUpon("dwc:sex") String sex + ) { + return amendmentSexStandardized(sex, null); + } + + /** + * Does the value of dwc:degreeOfEstablishment occur in bdq:sourceAuthority? + * Uses the default source authority + * + * Provides: 275 VALIDATION_DEGREEOFESTABLISHMENT_STANDARD + * Version: 2024-02-09 + * + * @param degreeOfEstablishment the provided dwc:degreeOfEstablishment to evaluate as ActedUpon. + * @return DQResponse the response of type ComplianceValue to return + */ + @Validation(label="VALIDATION_DEGREEOFESTABLISHMENT_STANDARD", description="Does the value of dwc:degreeOfEstablishment occur in bdq:sourceAuthority?") + @Provides("060e7734-607d-4737-8b2c-bfa17788bf1a") + @ProvidesVersion("https://rs.tdwg.org/bdq/terms/060e7734-607d-4737-8b2c-bfa17788bf1a/2024-02-09") + @Specification("EXTERNAL_PREREQUISITES_NOT_MET if the bdq:sourceAuthority is not available; INTERNAL_PREREQUISITES_NOT_MET if dwc:degreeOfEstablishment is EMPTY; COMPLIANT if the value of dwc:degreeOfEstablishment is in the bdq:sourceAuthority; otherwise NOT_COMPLIANT.") + public static DQResponse validationDegreeofestablishmentStandard( + @ActedUpon("dwc:degreeOfEstablishment") String degreeOfEstablishment + ) { + return validationDegreeofestablishmentStandard(degreeOfEstablishment, null); + } + + /** + * Propose amendment to the value of dwc:degreeOfEstablishment using the default bdq:sourceAuthority. + * + * Provides: 276 AMENDMENT_DEGREEOFESTABLISHMENT_STANDARDIZED + * Version: 2024-02-09 + * + * @param degreeOfEstablishment the provided dwc:degreeOfEstablishment to evaluate as ActedUpon. + * @return DQResponse the response of type AmendmentValue to return + */ + @Amendment(label="AMENDMENT_DEGREEOFESTABLISHMENT_STANDARDIZED", description="Propose amendment to the value of dwc:degreeOfEstablishment using bdq:sourceAuthority.") + @Provides("74ef1034-e289-4596-b5b0-cde73796697d") + @ProvidesVersion("https://rs.tdwg.org/bdq/terms/74ef1034-e289-4596-b5b0-cde73796697d/2024-02-09") + @Specification("EXTERNAL_PREREQUISITES_NOT_MET if the bdq:sourceAuthority is not available; INTERNAL PREREQUISITES_NOT_MET if dwc:degreeOfEstablishment is EMPTY; AMENDED the value of dwc:degreeOfEstablishment if it can be unambiguously matched to a term in bdq:sourceAuthority; otherwise NOT_AMENDED bdq:sourceAuthority default = 'Darwin Core degreeOfEstablishment' {[https://dwc.tdwg.org/list/#dwc_degreeOfEstablishment]} {dwc:degreeOfEstablishment vocabulary API [https://api.gbif.org/v1/vocabularies/DegreeOfEstablishment/concepts]}") + public static DQResponse amendmentDegreeofestablishmentStandardized( + @ActedUpon("dwc:degreeOfEstablishment") String degreeOfEstablishment + ) { + return amendmentDegreeofestablishmentStandardized(degreeOfEstablishment, null); + } } diff --git a/src/main/java/org/filteredpush/qc/metadata/EnumMetadataSourceAuthority.java b/src/main/java/org/filteredpush/qc/metadata/EnumMetadataSourceAuthority.java index d40365e..b40a41b 100644 --- a/src/main/java/org/filteredpush/qc/metadata/EnumMetadataSourceAuthority.java +++ b/src/main/java/org/filteredpush/qc/metadata/EnumMetadataSourceAuthority.java @@ -40,6 +40,10 @@ public enum EnumMetadataSourceAuthority { * GBIF Sex vocabulary */ GBIF_SEX, + /** + * GBIF Degree of Establishment Vocabulary + */ + GBIF_DEGREEOFESTABLISHMENT, /** * Darwin Core Class Names */ diff --git a/src/main/java/org/filteredpush/qc/metadata/MetadataSourceAuthority.java b/src/main/java/org/filteredpush/qc/metadata/MetadataSourceAuthority.java index 3820798..8dfbe07 100644 --- a/src/main/java/org/filteredpush/qc/metadata/MetadataSourceAuthority.java +++ b/src/main/java/org/filteredpush/qc/metadata/MetadataSourceAuthority.java @@ -88,6 +88,14 @@ public MetadataSourceAuthority(String authorityString) throws SourceAuthorityExc } else if (authorityString.equals("https://api.gbif.org/v1/vocabularies/Sex")) { this.authority = EnumMetadataSourceAuthority.GBIF_SEX; + } else if (authorityString.toUpperCase().equals("GBIF DEGREEOFESTABLISHMENT VOCABULARY")) { + this.authority = EnumMetadataSourceAuthority.GBIF_DEGREEOFESTABLISHMENT; + } else if (authorityString.equals("https://api.gbif.org/v1/vocabularies/DegreeOfEstablishment")) { + this.authority = EnumMetadataSourceAuthority.GBIF_DEGREEOFESTABLISHMENT; + } else if (authorityString.toUpperCase().equals("DEGREE OF ESTABLISHMENT CONTROLLED VOCABULARY LIST OF TERMS")) { + // TODO: This should point at the TDWG vocabulary + this.authority = EnumMetadataSourceAuthority.GBIF_DEGREEOFESTABLISHMENT; + } else if (authorityString.toUpperCase().startsWith("HTTPS://INVALID/")) { this.authority = EnumMetadataSourceAuthority.INVALID; } else { diff --git a/src/main/java/org/filteredpush/qc/metadata/services/GbifService.java b/src/main/java/org/filteredpush/qc/metadata/services/GbifService.java index 635fd30..fe7d36a 100644 --- a/src/main/java/org/filteredpush/qc/metadata/services/GbifService.java +++ b/src/main/java/org/filteredpush/qc/metadata/services/GbifService.java @@ -112,18 +112,33 @@ public Map> loadVocabulary(String vocabulary) { String name = item.get("name").toString(); ArrayList list = new ArrayList(); list.add(name); + if (!name.equals(name.toLowerCase())) { + list.add(name.toLowerCase()); + } logger.debug(name); // label[0].value JSONArray labels = (JSONArray) item.get("label"); for (int j=0; j> sexTerms = new HashMap>(); private Map sexValues = new HashMap(); + private Map> degreeOfEstablishmentTerms = new HashMap>(); + private Map degreeOfEstablishmentValues = new HashMap(); + private MetadataSingleton() { init(); } @@ -118,6 +121,16 @@ private void init() { } } + degreeOfEstablishmentTerms = gbif.loadVocabulary("DegreeOfEstablishment"); + keys = degreeOfEstablishmentTerms.keySet().iterator(); + while (keys.hasNext()) { + String key = keys.next(); + List values = degreeOfEstablishmentTerms.get(key); + Iterator i = values.iterator(); + while (i.hasNext()) { + degreeOfEstablishmentValues.put(i.next(), key); + } + } loaded = true; loadError = ""; @@ -127,7 +140,8 @@ private void init() { } /** - * get the lifeStage key:value pairs + * get the lifeStage value:key pairs + * for finding vocabulary values for alternative labels * * @return the map of lifeStage values from the vocabulary */ @@ -135,7 +149,18 @@ public Map getLifeStageValues() { return lifeStageValues; } /** - * get the pathway key:value pairs + * get the liifeStage key:list of value pairs + * for finding values in the vocabulary + * + * @return the map of lifeStage values from the vocabulary + */ + public Map> getLifeStageTerms() { + return lifeStageTerms; + } + + /** + * get the pathway value:key pairs + * for finding vocabulary values for alternative labels * * @return the map of pathway values from the vocabulary */ @@ -143,16 +168,36 @@ public Map getPathwayValues() { return pathwayValues; } /** - * get the typeStatus key:value pairs + * get the pathway key:list of value pairs + * for finding values in the vocabulary + * + * @return the map of pathway values from the vocabulary + */ + public Map> getPathwayTerms() { + return pathwayTerms; + } + + /** + * get the typeStatus value:key pairs * * @return the map of typeStatus values from the vocabulary */ public Map getTypeStatusValues() { return typeStatusValues; } + /** + * get the typeStatus key:list of value pairs + * for finding values in the vocabulary + * + * @return the map of typeStatus values from the vocabulary + */ + public Map> getTypeStatusTerms() { + return typeStatusTerms; + } /** - * get the sex key:value pairs + * get the sex value:key pairs + * for finding vocabulary values for alternative labels * * @return the map of sex values from the vocabulary */ @@ -160,6 +205,36 @@ public Map getSexValues() { return sexValues; } + /** + * get the sex key:list of value pairs + * for finding values in the vocabulary + * + * @return the map of sex values from the vocabulary + */ + public Map> getSexTerms() { + return sexTerms; + } + + /** + * get the degreeOfEstablishment value:key pairs + * for finding vocabulary values for alternative labels + * + * @return the map of degreeOfEstablishment values from the vocabulary + */ + public Map getDegreeOfEstablishmentValues() { + return degreeOfEstablishmentValues; + } + + /** + * get the degreeOfEstablishment key:list of value pairs + * for finding values in the vocabulary + * + * @return the map of degreeOfEstablishment values from the vocabulary + */ + public Map> getDegreeOfEstablishmentTerms() { + return degreeOfEstablishmentTerms; + } + /** * @return true if vocabularies have been loaded */ diff --git a/src/test/java/org/filteredpush/qc/metadata/DwCMetadataDQTest.java b/src/test/java/org/filteredpush/qc/metadata/DwCMetadataDQTest.java index d78c94f..de9e8ff 100644 --- a/src/test/java/org/filteredpush/qc/metadata/DwCMetadataDQTest.java +++ b/src/test/java/org/filteredpush/qc/metadata/DwCMetadataDQTest.java @@ -24,6 +24,8 @@ import java.util.Arrays; import java.util.Iterator; import java.util.List; +import java.util.Map; +import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -34,6 +36,7 @@ import org.datakurator.ffdq.model.ResultState; import org.filteredpush.qc.metadata.DwCMetadataDQ; import org.filteredpush.qc.metadata.DwCMetadataDQDefaults; +import org.filteredpush.qc.metadata.util.MetadataSingleton; import org.junit.Test; /** @@ -812,6 +815,196 @@ public void testValidationSexStandard() { assertEquals(ResultState.RUN_HAS_RESULT.getLabel(), result.getResultState().getLabel()); assertEquals(ComplianceValue.COMPLIANT.getLabel(), result.getValue().getLabel()); assertNotNull(result.getComment()); + + sex = "Indeterminado"; // es translation label + result = DwCMetadataDQ.validationSexStandard(sex,"GBIF Sex Vocabulary"); + logger.debug(result.getComment()); + assertEquals(ResultState.RUN_HAS_RESULT.getLabel(), result.getResultState().getLabel()); + assertEquals(ComplianceValue.NOT_COMPLIANT.getLabel(), result.getValue().getLabel()); + assertNotNull(result.getComment()); + + Map> vocabulary = MetadataSingleton.getInstance().getSexTerms(); + Set keys = vocabulary.keySet(); + Iterator i = keys.iterator(); + while (i.hasNext()) { + sex = i.next(); + result = DwCMetadataDQ.validationSexStandard(sex,"GBIF Sex Vocabulary"); + logger.debug(result.getComment()); + assertEquals(ResultState.RUN_HAS_RESULT.getLabel(), result.getResultState().getLabel()); + assertEquals(ComplianceValue.COMPLIANT.getLabel(), result.getValue().getLabel()); + assertNotNull(result.getComment()); + + if (sex.equals(sex.toLowerCase())) { + sex = sex.toUpperCase(); + result = DwCMetadataDQ.validationSexStandard(sex,"GBIF Sex Vocabulary"); + logger.debug(result.getComment()); + assertEquals(ResultState.RUN_HAS_RESULT.getLabel(), result.getResultState().getLabel()); + assertEquals(ComplianceValue.NOT_COMPLIANT.getLabel(), result.getValue().getLabel()); + assertNotNull(result.getComment()); + } else { + sex = sex.toLowerCase(); + result = DwCMetadataDQ.validationSexStandard(sex,"GBIF Sex Vocabulary"); + logger.debug(result.getComment()); + assertEquals(ResultState.RUN_HAS_RESULT.getLabel(), result.getResultState().getLabel()); + assertEquals(ComplianceValue.NOT_COMPLIANT.getLabel(), result.getValue().getLabel()); + assertNotNull(result.getComment()); + } + } + + } + + /** + * Test method for {@link org.filteredpush.qc.metadata.DwCMetadataDQ#amendmentSexStandardized(java.lang.String, java.lang.String)}. + */ + @Test + public void testAmendmentSexStandardized() { + + String sex = ""; + DQResponse result = DwCMetadataDQ.amendmentSexStandardized(sex, null); + logger.debug(result.getComment()); + assertEquals(ResultState.INTERNAL_PREREQUISITES_NOT_MET.getLabel(), result.getResultState().getLabel()); + assertNull(result.getValue()); + assertNotNull(result.getComment()); + + Map vocabulary = MetadataSingleton.getInstance().getSexValues(); + Set keys = vocabulary.keySet(); + Iterator i = keys.iterator(); + while (i.hasNext()){ + sex=i.next(); + if (MetadataSingleton.getInstance().getSexTerms().containsKey(sex)) { + result = DwCMetadataDQ.amendmentSexStandardized(sex, null); + logger.debug(result.getComment()); + assertEquals(ResultState.NOT_AMENDED.getLabel(), result.getResultState().getLabel()); + assertNull(result.getValue()); + assertNotNull(result.getComment()); + } else { + String match = MetadataSingleton.getInstance().getSexValues().get(sex); + result = DwCMetadataDQ.amendmentSexStandardized(sex, null); + logger.debug(result.getComment()); + assertEquals(ResultState.AMENDED.getLabel(), result.getResultState().getLabel()); + assertEquals(match,result.getValue().getObject().get("dwc:sex")); + assertNotNull(result.getComment()); + + if (sex.equals(sex.toLowerCase())) { + sex = sex.toUpperCase(); + } else { + sex = sex.toLowerCase(); + } + result = DwCMetadataDQ.amendmentSexStandardized(sex, null); + logger.debug(result.getComment()); + assertEquals(ResultState.AMENDED.getLabel(), result.getResultState().getLabel()); + assertEquals(match,result.getValue().getObject().get("dwc:sex")); + assertNotNull(result.getComment()); + } + } + } + + /** + * Test method for {@link org.filteredpush.qc.metadata.DwCMetadataDQ#validationDegreeofestablishmentStandard(java.lang.String)}. + */ + @Test + public void testValidationDegreeofestablishmentStandard() { + String degreeOfEstablishment = "foo"; + DQResponse result = DwCMetadataDQ.validationDegreeofestablishmentStandard(degreeOfEstablishment,"GBIF DegreeOfEstablishment Vocabulary"); + logger.debug(result.getComment()); + assertEquals(ResultState.RUN_HAS_RESULT.getLabel(), result.getResultState().getLabel()); + assertEquals(ComplianceValue.NOT_COMPLIANT.getLabel(), result.getValue().getLabel()); + assertNotNull(result.getComment()); + + degreeOfEstablishment = ""; + result = DwCMetadataDQ.validationDegreeofestablishmentStandard(degreeOfEstablishment,"GBIF DegreeOfEstablishment Vocabulary"); + logger.debug(result.getComment()); + assertEquals(ResultState.INTERNAL_PREREQUISITES_NOT_MET.getLabel(), result.getResultState().getLabel()); + assertNull(result.getValue()); + + degreeOfEstablishment = "managed"; + result = DwCMetadataDQ.validationDegreeofestablishmentStandard(degreeOfEstablishment,"GBIF DegreeOfEstablishment Vocabulary"); + logger.debug(result.getComment()); + assertEquals(ResultState.RUN_HAS_RESULT.getLabel(), result.getResultState().getLabel()); + assertEquals(ComplianceValue.COMPLIANT.getLabel(), result.getValue().getLabel()); + assertNotNull(result.getComment()); + + degreeOfEstablishment = "naturalized"; + result = DwCMetadataDQ.validationDegreeofestablishmentStandard(degreeOfEstablishment,"GBIF DegreeOfEstablishment Vocabulary"); + logger.debug(result.getComment()); + assertEquals(ResultState.RUN_HAS_RESULT.getLabel(), result.getResultState().getLabel()); + assertEquals(ComplianceValue.COMPLIANT.getLabel(), result.getValue().getLabel()); + assertNotNull(result.getComment()); + + Map> vocabulary = MetadataSingleton.getInstance().getDegreeOfEstablishmentTerms(); + Set keys = vocabulary.keySet(); + Iterator i = keys.iterator(); + while (i.hasNext()) { + degreeOfEstablishment = i.next(); + result = DwCMetadataDQ.validationDegreeofestablishmentStandard(degreeOfEstablishment,"GBIF DegreeOfEstablishment Vocabulary"); + logger.debug(result.getComment()); + assertEquals(ResultState.RUN_HAS_RESULT.getLabel(), result.getResultState().getLabel()); + assertEquals(ComplianceValue.COMPLIANT.getLabel(), result.getValue().getLabel()); + assertNotNull(result.getComment()); + + if (degreeOfEstablishment.equals(degreeOfEstablishment.toLowerCase())) { + degreeOfEstablishment = degreeOfEstablishment.toUpperCase(); + result = DwCMetadataDQ.validationDegreeofestablishmentStandard(degreeOfEstablishment,"GBIF DegreeOfEstablishment Vocabulary"); + logger.debug(result.getComment()); + assertEquals(ResultState.RUN_HAS_RESULT.getLabel(), result.getResultState().getLabel()); + assertEquals(ComplianceValue.NOT_COMPLIANT.getLabel(), result.getValue().getLabel()); + assertNotNull(result.getComment()); + } else { + degreeOfEstablishment = degreeOfEstablishment.toLowerCase(); + result = DwCMetadataDQ.validationDegreeofestablishmentStandard(degreeOfEstablishment,"GBIF DegreeOfEstablishment Vocabulary"); + logger.debug(result.getComment()); + assertEquals(ResultState.RUN_HAS_RESULT.getLabel(), result.getResultState().getLabel()); + assertEquals(ComplianceValue.NOT_COMPLIANT.getLabel(), result.getValue().getLabel()); + assertNotNull(result.getComment()); + } + } + + } + + /** + * Test method for {@link org.filteredpush.qc.metadata.DwCMetadataDQ#amendmentDegreeOfEstablishmentStandardized(java.lang.String, java.lang.String)}. + */ + @Test + public void testAmendmentDegreeOfEstablishmentStandardized() { + + String degreeOfEstablishment = ""; + DQResponse result = DwCMetadataDQ.amendmentDegreeofestablishmentStandardized(degreeOfEstablishment, null); + logger.debug(result.getComment()); + assertEquals(ResultState.INTERNAL_PREREQUISITES_NOT_MET.getLabel(), result.getResultState().getLabel()); + assertNull(result.getValue()); + assertNotNull(result.getComment()); + + Map vocabulary = MetadataSingleton.getInstance().getDegreeOfEstablishmentValues(); + Set keys = vocabulary.keySet(); + Iterator i = keys.iterator(); + while (i.hasNext()){ + degreeOfEstablishment=i.next(); + if (MetadataSingleton.getInstance().getDegreeOfEstablishmentTerms().containsKey(degreeOfEstablishment)) { + result = DwCMetadataDQ.amendmentDegreeofestablishmentStandardized(degreeOfEstablishment, null); + logger.debug(result.getComment()); + assertEquals(ResultState.NOT_AMENDED.getLabel(), result.getResultState().getLabel()); + assertNull(result.getValue()); + assertNotNull(result.getComment()); + } else { + String match = MetadataSingleton.getInstance().getDegreeOfEstablishmentValues().get(degreeOfEstablishment); + result = DwCMetadataDQ.amendmentDegreeofestablishmentStandardized(degreeOfEstablishment, null); + logger.debug(result.getComment()); + assertEquals(ResultState.AMENDED.getLabel(), result.getResultState().getLabel()); + assertEquals(match,result.getValue().getObject().get("dwc:degreeOfEstablishment")); + assertNotNull(result.getComment()); + + if (degreeOfEstablishment.equals(degreeOfEstablishment.toLowerCase())) { + degreeOfEstablishment = degreeOfEstablishment.toUpperCase(); + } else { + degreeOfEstablishment = " " + degreeOfEstablishment.toLowerCase(); + } + result = DwCMetadataDQ.amendmentDegreeofestablishmentStandardized(degreeOfEstablishment, null); + logger.debug(result.getComment()); + assertEquals(ResultState.AMENDED.getLabel(), result.getResultState().getLabel()); + assertEquals(match,result.getValue().getObject().get("dwc:degreeOfEstablishment")); + assertNotNull(result.getComment()); + } + } } /** @@ -939,6 +1132,41 @@ public void testValidationLifestageStandard() { assertEquals(ComplianceValue.COMPLIANT.getLabel(), result.getValue().getLabel()); assertNotNull(result.getComment()); + lifeStage = "larva"; + result = DwCMetadataDQ.validationLifestageStandard(lifeStage,null); + logger.debug(result.getComment()); + assertEquals(ResultState.RUN_HAS_RESULT.getLabel(), result.getResultState().getLabel()); + assertEquals(ComplianceValue.NOT_COMPLIANT.getLabel(), result.getValue().getLabel()); + assertNotNull(result.getComment()); + + Map> vocabulary = MetadataSingleton.getInstance().getLifeStageTerms(); + Set keys = vocabulary.keySet(); + Iterator i = keys.iterator(); + while (i.hasNext()) { + lifeStage = i.next(); + result = DwCMetadataDQ.validationLifestageStandard(lifeStage,null); + logger.debug(result.getComment()); + assertEquals(ResultState.RUN_HAS_RESULT.getLabel(), result.getResultState().getLabel()); + assertEquals(ComplianceValue.COMPLIANT.getLabel(), result.getValue().getLabel()); + assertNotNull(result.getComment()); + + if (lifeStage.equals(lifeStage.toLowerCase())) { + lifeStage = lifeStage.toUpperCase(); + result = DwCMetadataDQ.validationLifestageStandard(lifeStage,null); + logger.debug(result.getComment()); + assertEquals(ResultState.RUN_HAS_RESULT.getLabel(), result.getResultState().getLabel()); + assertEquals(ComplianceValue.NOT_COMPLIANT.getLabel(), result.getValue().getLabel()); + assertNotNull(result.getComment()); + } else { + lifeStage = lifeStage.toLowerCase(); + result = DwCMetadataDQ.validationLifestageStandard(lifeStage,null); + logger.debug(result.getComment()); + assertEquals(ResultState.RUN_HAS_RESULT.getLabel(), result.getResultState().getLabel()); + assertEquals(ComplianceValue.NOT_COMPLIANT.getLabel(), result.getValue().getLabel()); + assertNotNull(result.getComment()); + } + } + } /**