diff --git a/src/main/java/eu/dnetlib/validator2/engine/RuleEngine.java b/src/main/java/eu/dnetlib/validator2/engine/RuleEngine.java index 2f5f519..07d2c83 100644 --- a/src/main/java/eu/dnetlib/validator2/engine/RuleEngine.java +++ b/src/main/java/eu/dnetlib/validator2/engine/RuleEngine.java @@ -2,18 +2,16 @@ package eu.dnetlib.validator2.engine; public class RuleEngine { - public static > void applyAndReport(R rule, T t, Reporter reporter) { - + public static > void applyAndReport(R rule, T t, Reporter reporter) throws IllegalArgumentException + { if (reporter == null) throw new IllegalArgumentException("Reporter cannot be null"); if (rule == null) throw new IllegalArgumentException("Rule cannot be null"); try { - if(rule.test(t)) { + if ( rule.test(t) ) reporter.reportSuccessFor(rule, t); - } - else { + else reporter.reportFailureFor(rule, t); - } } catch (Throwable throwable) { reporter.reportErrorFor(rule, t, throwable); } diff --git a/src/main/java/eu/dnetlib/validator2/engine/builtins/XPathExpressionHelper.java b/src/main/java/eu/dnetlib/validator2/engine/builtins/XPathExpressionHelper.java index 1093ab9..29cbeb3 100644 --- a/src/main/java/eu/dnetlib/validator2/engine/builtins/XPathExpressionHelper.java +++ b/src/main/java/eu/dnetlib/validator2/engine/builtins/XPathExpressionHelper.java @@ -42,8 +42,6 @@ public class XPathExpressionHelper { if ( logger.isTraceEnabled() ) logger.trace("Compiling {}", s); XPathExpression expr = XPATH.compile(s); - if ( logger.isTraceEnabled() ) - logger.trace("Compiled {} = {}", s, expr); return expr; } catch (XPathExpressionException e) { logger.error("Compilation failure", e); diff --git a/src/main/java/eu/dnetlib/validator2/validation/guideline/ElementSpecCompiler.java b/src/main/java/eu/dnetlib/validator2/validation/guideline/ElementSpecCompiler.java index d697922..d868b24 100644 --- a/src/main/java/eu/dnetlib/validator2/validation/guideline/ElementSpecCompiler.java +++ b/src/main/java/eu/dnetlib/validator2/validation/guideline/ElementSpecCompiler.java @@ -69,7 +69,7 @@ class ElementSpecCompiler { // TODO: Should we escape the arg? private static String xpathForNodeName(String name) { - return "local-name()='" + name + "'"; + return "name()='" + name + "'"; } private static String xpathForNodeName(String name, String valuePrefix) { @@ -436,12 +436,13 @@ class ElementSpecCompiler { @Override public boolean test(Document doc) throws RuleEvaluationException { GuidelineEvaluation guidelineEvaluation = runtimeInfo.get(); - String thisId = getContext().getIdProperty().getValue(); + XMLContext context = getContext(); + String thisId = context.getIdProperty().getValue(); if (isApplicable(this, guidelineEvaluation).test(doc)) { try { logger.debug("Applying {}", thisId); - NodeList nodes = getContext().getXPathExpressionProperty().evaluate(doc); + NodeList nodes = context.getXPathExpressionProperty().evaluate(doc); boolean result = predicate.test(nodes); if (result) { logger.debug("Setting node list of this rule {}", thisId); diff --git a/src/main/java/eu/dnetlib/validator2/validation/guideline/GuidelineEvaluation.java b/src/main/java/eu/dnetlib/validator2/validation/guideline/GuidelineEvaluation.java index 902e188..020154e 100644 --- a/src/main/java/eu/dnetlib/validator2/validation/guideline/GuidelineEvaluation.java +++ b/src/main/java/eu/dnetlib/validator2/validation/guideline/GuidelineEvaluation.java @@ -47,27 +47,27 @@ class GuidelineEvaluation { logger.debug("Evaluating " + rules); - for (SyntheticRule rule: rules) { + for ( SyntheticRule rule: rules ) { String id = rule.getContext().getIdProperty().getValue(); RuleEngine.applyAndReport(rule, doc, reporter); Status status = diagnostics.getLastReportedStatus(); - if (status == Status.ERROR) { + if ( status == Status.ERROR ) { // fail fast in case of errors (no reason to proceed, since results may be rubbish) return StandardResult.forError(diagnostics.getLastReportedError().getMessage()); } - if (status == Status.SUCCESS && getRequirementLevelOf(id) == RequirementLevel.NOT_APPLICABLE) { + if ( status == Status.SUCCESS && getRequirementLevelOf(id) == RequirementLevel.NOT_APPLICABLE ) { // Report the non-applicability of a rule as a warning // The check for both status and non-applicable requirement level is redundant - // (non-applicable rules always succeed), yet it is more clear hopefully. + // (non-applicable rules always succeed), yet it is more clear, hopefully. logger.warn("Non-applicable: " + rule); warnings.add(synthesizeFailureMessage(rule)); } - else if (status == Status.FAILURE) { - if (getRequirementLevelOf(id) == RequirementLevel.MANDATORY) { + else if ( status == Status.FAILURE ) { + if ( getRequirementLevelOf(id) == RequirementLevel.MANDATORY ) { // A mandatory rule has failed, yet we don't know whether we should report is as such. // Let's check the parent of the rule @@ -78,8 +78,7 @@ class GuidelineEvaluation { logger.error("Fail fast for root failure: " + rule); errors.add(synthesizeFailureMessage(rule)); return StandardResult.forFailure(warnings, errors); - } - else { + } else { // The current rule has a parent/ancestor which: // (a) is non-mandatory or // (b) it was successful. @@ -87,8 +86,7 @@ class GuidelineEvaluation { logger.warn("Mandatory failure: " + rule); warnings.add(synthesizeFailureMessage(rule)); } - } - else { + } else { // This is a warning: a non-mandatory rule has failed. // Note that MA rules are treated as non-mandatory. // We let the evaluation loop proceed. @@ -99,7 +97,7 @@ class GuidelineEvaluation { } int returnedWeight = weight; - if (rules.size() == warnings.size()) { + if ( rules.size() == warnings.size() ) { // TODO: I think this is the desired behavior, but we need to get confirmation for this. // All rules have failed, but with warnings (thus being either optional or recommended). // This indicates a success with 0 weight. @@ -109,12 +107,10 @@ class GuidelineEvaluation { } private String synthesizeFailureMessage(Rule rule) { - return subjectId + ": rule " + Helper.stringify(rule) + " has failed"; } private String synthesizeNotApplicableMessage(Rule rule) { - return subjectId + ": rule " + Helper.stringify(rule) + " is not applicable"; } diff --git a/src/main/java/eu/dnetlib/validator2/validation/guideline/openaire/AbstractOpenAireProfile.java b/src/main/java/eu/dnetlib/validator2/validation/guideline/openaire/AbstractOpenAireProfile.java index 4f97071..bedf62b 100644 --- a/src/main/java/eu/dnetlib/validator2/validation/guideline/openaire/AbstractOpenAireProfile.java +++ b/src/main/java/eu/dnetlib/validator2/validation/guideline/openaire/AbstractOpenAireProfile.java @@ -63,7 +63,7 @@ public abstract class AbstractOpenAireProfile implements XMLApplicationProfile { return XMLCardinalityRule .builder() .setId(ElementSpec.APPLICABILITY_RULE_ID) - .setXPathExpression("//*[local-name()='" + elementName + "']") + .setXPathExpression("//*[name()='" + elementName + "']") .setIsInclusive(true).setRange(1, Long.MAX_VALUE) .build(); } diff --git a/src/main/java/eu/dnetlib/validator2/validation/guideline/openaire/FAIR_Data_GuidelinesProfile.java b/src/main/java/eu/dnetlib/validator2/validation/guideline/openaire/FAIR_Data_GuidelinesProfile.java index 672cc4f..aa6ed4a 100644 --- a/src/main/java/eu/dnetlib/validator2/validation/guideline/openaire/FAIR_Data_GuidelinesProfile.java +++ b/src/main/java/eu/dnetlib/validator2/validation/guideline/openaire/FAIR_Data_GuidelinesProfile.java @@ -386,6 +386,7 @@ class F2_01M_SPEC extends AbstractGuideline { // TODO: iterate over results and build one Guideline.Result try { XMLApplicationProfile.ValidationResult res_F = profile.validate(id, t); + Map results = res_F.results(); // Get actual score and not (%) to incorporate to FAIR score final int MaxScoreF2_01M_SPEC = (int) ((res_F.score()*getWeight())/100); @@ -397,19 +398,23 @@ class F2_01M_SPEC extends AbstractGuideline { List warnings2 = new ArrayList<>(); List errors2 = new ArrayList<>(); int score = 0; - - for (Map.Entry entry : res_F.results().entrySet()) { - if (res_F.results().get(entry.getKey()).warnings().toString().length() > 2) { - warnings2.add(res_F.results().get(entry.getKey()).warnings().toString()); + for (Map.Entry entry : results.entrySet()) { + String key = entry.getKey(); + String warningsStr = results.get(key).warnings().toString(); + String errorsStr = results.get(key).errors().toString(); + if ( warningsStr.length() > 2 ) { + warnings2.add(warningsStr); } - if (res_F.results().get(entry.getKey()).errors().toString().length() > 2) { - errors2.add(res_F.results().get(entry.getKey()).errors().toString()); + if ( errorsStr.length() > 2 ) { + errors2.add(errorsStr); } if (entry.getValue().toString().contains("SUCCESS")) { score += 2; } - logger.debug(String.valueOf(res_F.results().get(entry.getKey()).warnings().getClass())); - logger.debug(String.valueOf(warnings2.getClass())); + if ( logger.isTraceEnabled() ) { + logger.trace(String.valueOf(results.get(key).warnings().getClass())); + logger.trace(String.valueOf(warnings2.getClass())); + } } @@ -470,7 +475,7 @@ class F3_01M_SPEC extends AbstractGuideline { try { // System.out.println("\nMetadata includes the identifier for the data"); XMLApplicationProfile.ValidationResult res_F = profile.validate(id, t); - Map results = res_F.results(); + Map results = res_F.results(); // int MaxScoreF3_01M_SPEC = (int) ((res_F.score()*getWeight())/100); int MaxScoreF3_01M_SPEC; @@ -483,12 +488,15 @@ class F3_01M_SPEC extends AbstractGuideline { ArrayList warnings2 = new ArrayList<>(); ArrayList errors2 = new ArrayList<>(); - for (Map.Entry entry : res_F.results().entrySet()) { - if (res_F.results().get(entry.getKey()).warnings().toString().length() > 2) { - warnings2.add(res_F.results().get(entry.getKey()).warnings().toString()); + for (Map.Entry entry : results.entrySet()) { + String key = entry.getKey(); + String warningsStr = results.get(key).warnings().toString(); + String errorsStr = results.get(key).errors().toString(); + if ( warningsStr.length() > 2 ) { + warnings2.add(warningsStr); } - if (res_F.results().get(entry.getKey()).errors().toString().length() > 2) { - errors2.add(res_F.results().get(entry.getKey()).errors().toString()); + if ( errorsStr.length() > 2 ) { + errors2.add(errorsStr); } } @@ -544,9 +552,9 @@ class I2_01M_SPEC extends AbstractGuideline { // TODO: iterate over results and build one Guideline.Result try { - logger.debug("\nMetadata uses FAIR-compliant vocabularies"); + logger.debug("Metadata uses FAIR-compliant vocabularies"); XMLApplicationProfile.ValidationResult res_F = profile.validate(id, t); - Map results = res_F.results(); + Map results = res_F.results(); // int MaxScoreI2_01M_SPEC = (int) ((res_F.score()*getWeight())/100); int MaxScoreI2_01M_SPEC; @@ -559,12 +567,15 @@ class I2_01M_SPEC extends AbstractGuideline { ArrayList warnings2 = new ArrayList<>(); ArrayList errors2 = new ArrayList<>(); - for (Map.Entry entry : res_F.results().entrySet()) { - if (res_F.results().get(entry.getKey()).warnings().toString().length() > 2) { - warnings2.add(res_F.results().get(entry.getKey()).warnings().toString()); + for (Map.Entry entry : results.entrySet()) { + String key = entry.getKey(); + String warningsStr = results.get(key).warnings().toString(); + String errorsStr = results.get(key).errors().toString(); + if ( warningsStr.length() > 2 ) { + warnings2.add(warningsStr); } - if (res_F.results().get(entry.getKey()).errors().toString().length() > 2) { - errors2.add(res_F.results().get(entry.getKey()).errors().toString()); + if ( errorsStr.length() > 2 ) { + errors2.add(errorsStr); } } @@ -624,18 +635,21 @@ class R1_01M_SPEC extends AbstractGuideline { try { // System.out.println("\nPlurality of accurate and relevant attributes are provided to allow reuse"); XMLApplicationProfile.ValidationResult res_F = profile.validate(id, t); - Map results = res_F.results(); + Map results = res_F.results(); int MaxScoreR1_01M_SPEC = (int) ((res_F.score()*getWeight())/100); ArrayList warnings2 = new ArrayList<>(); ArrayList errors2 = new ArrayList<>(); int score = 0; - for (Map.Entry entry : res_F.results().entrySet()) { - if (res_F.results().get(entry.getKey()).warnings().toString().length() > 2) { - warnings2.add(res_F.results().get(entry.getKey()).warnings().toString()); + for (Map.Entry entry : results.entrySet()) { + String key = entry.getKey(); + String warningsStr = results.get(key).warnings().toString(); + String errorsStr = results.get(key).errors().toString(); + if ( warningsStr.length() > 2 ) { + warnings2.add(warningsStr); } - if (res_F.results().get(entry.getKey()).errors().toString().length() > 2) { - errors2.add(res_F.results().get(entry.getKey()).errors().toString()); + if ( errorsStr.length() > 2 ) { + errors2.add(errorsStr); } if (entry.getValue().toString().contains("SUCCESS")) { score += 3; @@ -698,19 +712,21 @@ class R1_2_01M_SPEC extends AbstractGuideline { try { // System.out.println("\nMetadata includes provenance information according to a cross-community language"); XMLApplicationProfile.ValidationResult res_F = profile.validate(id, t); - Map results = res_F.results(); + Map results = res_F.results(); int MaxScoreR1_2_01M_SPEC = (int) ((res_F.score()*getWeight())/100); - ArrayList warnings2 = new ArrayList<>(); ArrayList errors2 = new ArrayList<>(); int score = 0; - for (Map.Entry entry : res_F.results().entrySet()) { - if (res_F.results().get(entry.getKey()).warnings().toString().length() > 2) { - warnings2.add(res_F.results().get(entry.getKey()).warnings().toString()); + for (Map.Entry entry : results.entrySet()) { + String key = entry.getKey(); + String warningsStr = results.get(key).warnings().toString(); + String errorsStr = results.get(key).errors().toString(); + if ( warningsStr.length() > 2 ) { + warnings2.add(warningsStr); } - if (res_F.results().get(entry.getKey()).errors().toString().length() > 2) { - errors2.add(res_F.results().get(entry.getKey()).errors().toString()); + if ( errorsStr.length() > 2 ) { + errors2.add(errorsStr); } if (entry.getValue().toString().contains("SUCCESS")) { score += 3; diff --git a/src/main/java/eu/dnetlib/validator2/validation/guideline/openaire/LiteratureGuidelinesV3Profile.java b/src/main/java/eu/dnetlib/validator2/validation/guideline/openaire/LiteratureGuidelinesV3Profile.java index 482dc8e..81a33ac 100644 --- a/src/main/java/eu/dnetlib/validator2/validation/guideline/openaire/LiteratureGuidelinesV3Profile.java +++ b/src/main/java/eu/dnetlib/validator2/validation/guideline/openaire/LiteratureGuidelinesV3Profile.java @@ -77,69 +77,69 @@ public final class LiteratureGuidelinesV3Profile extends AbstractOpenAireProfile }; private static final ElementSpec TITLE_SPEC = Builders - .forMandatoryElement("title", ONE_TO_N) + .forMandatoryElement("dc:title", ONE_TO_N) .build(); private static final ElementSpec CREATOR_SPEC = Builders - .forMandatoryElement("creator", ONE_TO_N) + .forMandatoryElement("dc:creator", ONE_TO_N) .build(); private static final ElementSpec PROJECT_IDENTIFIER_SPEC = Builders - .forMandatoryIfApplicableElement("relation", ONE, elementIsPresent("relation")) + .forMandatoryIfApplicableElement("dc:relation", ONE, elementIsPresent("dc:relation")) .allowedValues(new RegexValuePredicate(COMPILED_PROJECT_IDENTIFIER_REGEX)) .build(); private static final ElementSpec ACCESS_LEVEL_SPEC = Builders - .forMandatoryElement("rights", ONE).allowedValues(repoAccessTerms) + .forMandatoryElement("dc:rights", ONE).allowedValues(repoAccessTerms) .build(); private static final ElementSpec LICENSE_CONDITION_SPEC = Builders - .forRecommendedRepeatableElement("rights") + .forRecommendedRepeatableElement("dc:rights") .allowedValues(new RegexValuePredicate(COMPILED_LICENSE_CONDITION_REG_EX)) .build(); private static final ElementSpec EMBARGO_END_DATE_SPEC = Builders - .forMandatoryIfApplicableElement("date", ONE, applicabilityRuleForEmbargoEndDate()) + .forMandatoryIfApplicableElement("dc:date", ONE, applicabilityRuleForEmbargoEndDate()) .allowedValues(new EmbargoedEndDateValuePredicate()) .build(); private static final ElementSpec ALT_IDENTIFIER_SPEC = Builders - .forRecommendedRepeatableElement("relation") + .forRecommendedRepeatableElement("dc:relation") .allowedValues(new RegexValuePredicate(COMPILED_ALT_IDENTIFIER_REG_EX)) .build(); private static final ElementSpec PUBLICATION_REF_SPEC = Builders - .forRecommendedRepeatableElement("relation") + .forRecommendedRepeatableElement("dc:relation") .allowedValues(new RegexValuePredicate(COMPILED_PUBLICATION_REFERENCE_REG_EX)) .build(); private static final ElementSpec DATASET_REF_SPEC = Builders - .forRecommendedRepeatableElement("relation") + .forRecommendedRepeatableElement("dc:relation") .allowedValues(new RegexValuePredicate(COMPILED_DATASET_REFERENCE_REG_EX)) .build(); //TODO value is either a keyword (free text) or a classification (info:eu-repo/classification) // v3 guideliness recommends ddc classification (Dewey Decimal Classification) private static final ElementSpec SUBJECT_SPEC = Builders - .forMandatoryIfApplicableElement("subject", ONE_TO_N, elementIsPresent("subject")) + .forMandatoryIfApplicableElement("dc:subject", ONE_TO_N, elementIsPresent("dc:subject")) .build(); private static final ElementSpec DESCRIPTION_SPEC = Builders - .forMandatoryIfApplicableElement("description", ONE_TO_N, elementIsPresent("description")) + .forMandatoryIfApplicableElement("dc:description", ONE_TO_N, elementIsPresent("dc:description")) .build(); private static final ElementSpec PUBLISHER_SPEC = Builders - .forMandatoryIfApplicableElement("publisher", ONE_TO_N, elementIsPresent("publisher")) + .forMandatoryIfApplicableElement("dc:publisher", ONE_TO_N, elementIsPresent("dc:publisher")) .build(); private static final ElementSpec CONTRIBUTOR_SPEC = Builders - .forRecommendedRepeatableElement("contributor") + .forRecommendedRepeatableElement("dc:contributor") .build(); //TODO // Search element -> dc:date AND NOT embargoedDate private static final ElementSpec PUBLICATION_DATE_SPEC = Builders - .forMandatoryElement("date", ONE) + .forMandatoryElement("dc:date", ONE) .allowedValues(new RegexValuePredicate(COMPILED_PUBLICATION_DATE_REG_EX)) .build(); @@ -147,7 +147,7 @@ public final class LiteratureGuidelinesV3Profile extends AbstractOpenAireProfile // Search element -> dc:type AND values IN publicationTypes set //TODO: Check it is first occurrence private static final ElementSpec PUBLICATION_TYPE_M_SPEC = Builders - .forMandatoryElement("type", ONE) + .forMandatoryElement("dc:type", ONE) .atPosition(ElementPosition.FIRST) .allowedValues(publicationTypes) .build(); @@ -156,47 +156,47 @@ public final class LiteratureGuidelinesV3Profile extends AbstractOpenAireProfile // Search element -> dc:type AND values NOT IN publicationTypes //TODO: check it is second occurrence private static final ElementSpec PUBLICATION_TYPE_O_SPEC = Builders - .forOptionalElement("type") + .forOptionalElement("dc:type") .atPosition(ElementPosition.SECOND) .allowedValues(new Predicates.SetOfCaseInsensitiveAllowedValues(publicationTypesAndVersions).negate()) .build(); private static final ElementSpec PUBLICATION_VERSION_SPEC = Builders - .forRecommendedElement("type") + .forRecommendedElement("dc:type") .allowedValues(publicationVersions) .build(); private static final ElementSpec FORMAT_SPEC = Builders - .forRecommendedRepeatableElement("format") + .forRecommendedRepeatableElement("dc:format") .allowedValues(new MediaTypesValuePredicate()) .build(); private static final ElementSpec RESOURCE_IDENTIFIER_SPEC = Builders - .forMandatoryElement("identifier", ONE_TO_N) + .forMandatoryElement("dc:identifier", ONE_TO_N) .build(); private static final ElementSpec SOURCE_SPEC = Builders - .forRecommendedRepeatableElement("source") + .forRecommendedRepeatableElement("dc:source") .build(); //TODO values from ISO 639-1 or 639-2 or 639-3 (recommended) private static final ElementSpec LANGUAGE_SPEC = Builders - .forRecommendedRepeatableElement("language") + .forRecommendedRepeatableElement("dc:language") .allowedValues(new ISO639ValuePredicate()) .build(); //TODO: Should exclude other dc:relation elements e.g. !containsAllowedValuesOF -> Project Identifier (MA), Alternative Identifier (R), Publication Reference (R), Dataset Reference (R) private static final ElementSpec RELATION_SPEC = Builders - .forOptionalRepeatableElement("relation") + .forOptionalRepeatableElement("dc:relation") .allowedValues(relationSpecAllowedValuesPredicate()) .build(); private static final ElementSpec COVERAGE_SPEC = Builders - .forRecommendedRepeatableElement("coverage") + .forRecommendedRepeatableElement("dc:coverage") .build(); private static final ElementSpec AUDIENCE_SPEC = Builders - .forRecommendedRepeatableElement("audience") + .forRecommendedRepeatableElement("dc:audience") .allowedValues(audiences) .build(); @@ -204,7 +204,7 @@ public final class LiteratureGuidelinesV3Profile extends AbstractOpenAireProfile return XMLCardinalityRule.builder(). setId(ElementSpec.APPLICABILITY_RULE_ID). // first predicate count(...) makes sure there is only one Access Level set and then the second predicate verifies its value. - setXPathExpression("//*[count(//*[local-name()='rights' and starts-with(normalize-space(text()), 'info:eu-repo/semantics/')])=1][local-name()='rights' and normalize-space(text())='info:eu-repo/semantics/embargoedAccess']"). + setXPathExpression("//*[count(//*[name()='dc:rights' and starts-with(normalize-space(text()), 'info:eu-repo/semantics/')])=1][name()='dc:rights' and normalize-space(text())='info:eu-repo/semantics/embargoedAccess']"). setRange(1,1). setIsInclusive(true). build(); diff --git a/src/main/java/eu/dnetlib/validator2/validation/guideline/openaire/LiteratureGuidelinesV4Profile.java b/src/main/java/eu/dnetlib/validator2/validation/guideline/openaire/LiteratureGuidelinesV4Profile.java index fd9bab1..a78a767 100644 --- a/src/main/java/eu/dnetlib/validator2/validation/guideline/openaire/LiteratureGuidelinesV4Profile.java +++ b/src/main/java/eu/dnetlib/validator2/validation/guideline/openaire/LiteratureGuidelinesV4Profile.java @@ -137,61 +137,61 @@ public final class LiteratureGuidelinesV4Profile extends AbstractOpenAireProfile }; private static final ElementSpec TITLE_SPEC = Builders. - forMandatoryElement("title", ONE_TO_N). + forMandatoryElement("datacite:title", ONE_TO_N). withOptionalAttribute("xml:lang", new RegexValuePredicate(COMPILED_BCP47_LANG_TAGS_REG_EX)). withOptionalAttribute("titleType", TITLE_TYPES). build(); private static final ElementSpec CREATOR_SPEC = Builders. - forMandatoryElement("creator", ONE_TO_N). + forMandatoryElement("datacite:creator", ONE_TO_N). withSubElement(Builders. - forMandatoryElement("creatorName", ONE). + forMandatoryElement("datacite:creatorName", ONE). withRecommendedAttribute("nameType", NAME_TYPES)). withSubElement(Builders. - forRecommendedElement("givenName")). + forRecommendedElement("datacite:givenName")). withSubElement(Builders. - forRecommendedElement("familyName")). + forRecommendedElement("datacite:familyName")). withSubElement(Builders. - forRecommendedRepeatableElement("nameIdentifier"). + forRecommendedRepeatableElement("datacite:nameIdentifier"). withMandatoryAttribute("nameIdentifierScheme"). withRecommendedAttribute("schemeURI")). withSubElement(Builders. - forRecommendedRepeatableElement("affiliation")). + forRecommendedRepeatableElement("datacite:affiliation")). build(); private static final ElementSpec CONTRIBUTOR_SPEC = Builders. - forMandatoryIfApplicableElement("contributor", ONE_TO_N, elementIsPresent("contributor")). + forMandatoryIfApplicableElement("datacite:contributor", ONE_TO_N, elementIsPresent("datacite:contributor")). withMandatoryAttribute("contributorType", CONTRIBUTOR_TYPES). withSubElement(Builders. - forMandatoryElement("contributorName", ONE). + forMandatoryElement("datacite:contributorName", ONE). withRecommendedAttribute("nameType", NAME_TYPES)). withSubElement(Builders. - forOptionalElement("familyName")). + forOptionalElement("datacite:familyName")). withSubElement(Builders. - forOptionalElement("givenName")). + forOptionalElement("datacite:givenName")). withSubElement(Builders. - forRecommendedRepeatableElement("nameIdentifier"). + forRecommendedRepeatableElement("datacite:nameIdentifier"). withMandatoryAttribute("nameIdentifierScheme"). withRecommendedAttribute("schemeURI")). withSubElement(Builders. - forRecommendedRepeatableElement("affiliation")). + forRecommendedRepeatableElement("datacite:affiliation")). build(); //This property has some issues/annotations in documentation private static final ElementSpec FUNDING_REFERENCE_SPEC = Builders. - forMandatoryIfApplicableElement("fundingReference", ONE_TO_N, elementIsPresent("fundingReference")). + forMandatoryIfApplicableElement("oaire:fundingReference", ONE_TO_N, elementIsPresent("oaire:fundingReference")). withSubElement(Builders. - forMandatoryElement("funderName", ONE)). + forMandatoryElement("oaire:funderName", ONE)). withSubElement(Builders. - forRecommendedElement("funderIdentifier"). + forRecommendedElement("oaire:funderIdentifier"). withRecommendedAttribute("funderIdentifierType", FUNDER_IDENTIFIER_TYPES)). withSubElement(Builders. - forOptionalElement("fundingStream")). + forOptionalElement("oaire:fundingStream")). withSubElement(Builders. - forMandatoryIfApplicableElement("awardNumber", ONE, elementIsPresent("awardNumber")). + forMandatoryIfApplicableElement("oaire:awardNumber", ONE, elementIsPresent("oaire:awardNumber")). withRecommendedAttribute("awardURI")). withSubElement(Builders. - forRecommendedElement("awardTitle")). + forRecommendedElement("oaire:awardTitle")). build(); //TODO: Allowed values are referred as "suggested" in the documentation, but then a controlled list is given. @@ -199,12 +199,12 @@ public final class LiteratureGuidelinesV4Profile extends AbstractOpenAireProfile // https://bitbucket.org/saikos/openaire-validator/issues/40 // https://bitbucket.org/saikos/openaire-validator/issues/32/ private static final ElementSpec ALTERNATE_IDENTIFIER_SPEC = Builders. - forRecommendedRepeatableElement("alternateIdentifier"). + forRecommendedRepeatableElement("datacite:alternateIdentifier"). withMandatoryAttribute("alternateIdentifierType", IDENTIFIER_TYPES). build(); private static final ElementSpec RELATED_IDENTIFIER_SPEC = Builders. - forRecommendedRepeatableElement("relatedIdentifier"). + forRecommendedRepeatableElement("datacite:relatedIdentifier"). withMandatoryAttribute("relatedIdentifierType", IDENTIFIER_TYPES). withMandatoryAttribute("relationType", RELATION_TYPES). //TODO: For following 3 attributes. Need a way to target relationType attribute of current element @@ -223,13 +223,13 @@ public final class LiteratureGuidelinesV4Profile extends AbstractOpenAireProfile //TODO: Implement proper applicability rule //LEONIDAS: The withMandatoryAttribute fails whe another date element eg. for Publication Date exists private static final ElementSpec EMBARGO_PERIOD_DATE_SPEC = Builders. - forMandatoryIfApplicableElement("date", ONE_TO_N, applicabilityRuleForEmbargoPeriodDate()). + forMandatoryIfApplicableElement("datacite:date", ONE_TO_N, applicabilityRuleForEmbargoPeriodDate()). withMandatoryAttribute("dateType", EMBARGO_DATE_TYPES). allowedValues(new RegexValuePredicate(COMPILED_YYYY_MM_DD_RANGE_REGEX).or(new RegexValuePredicate(COMPILED_YEAR_YYYY_REG_EX))). build(); // private static final ElementSpec EMBARGO_PERIOD_DATE_SPEC = Builders. -// forMandatoryIfApplicableElement("date", TWO, applicabilityRuleForEmbargoPeriodDate()). +// forMandatoryIfApplicableElement("datacite:date", TWO, applicabilityRuleForEmbargoPeriodDate()). // withMandatoryAttribute("dateType", EMBARGO_DATE_TYPES). // build(); @@ -237,12 +237,12 @@ public final class LiteratureGuidelinesV4Profile extends AbstractOpenAireProfile There are no "strict" allowed values. Recommendations are IETF BCP 47 and ISO 639-x */ private static final ElementSpec LANGUAGE_SPEC = Builders. - forMandatoryIfApplicableElement("language", ONE_TO_N, elementIsPresent("language")). + forMandatoryIfApplicableElement("dc:language", ONE_TO_N, elementIsPresent("dc:language")). allowedValues(new RegexValuePredicate(COMPILED_BCP47_LANG_TAGS_REG_EX).or(new ISO639ValuePredicate())). build(); private static final ElementSpec PUBLISHER_SPEC = Builders. - forMandatoryIfApplicableElement("publisher", ONE_TO_N, elementIsPresent("publisher")). + forMandatoryIfApplicableElement("dc:publisher", ONE_TO_N, elementIsPresent("dc:publisher")). build(); /* @@ -251,98 +251,98 @@ public final class LiteratureGuidelinesV4Profile extends AbstractOpenAireProfile "Recommended" best practice for encoding the date value is ISO 8601 [W3CDTF] (YYYY-MM-DD) (YYYY mandatory) */ private static final ElementSpec PUBLICATION_DATE_SPEC = Builders. - forMandatoryElement("date", ONE). + forMandatoryElement("datacite:date", ONE). withMandatoryAttribute("dateType", PUBLICATION_DATE_TYPE). allowedValues(new RegexValuePredicate(COMPILED_PUBLICATION_DATE_REG_EX).or(new RegexValuePredicate(COMPILED_YYYY_MM_DD_RANGE_REGEX).or(new RegexValuePredicate(COMPILED_YEAR_YYYY_REG_EX)))). build(); private static final ElementSpec RESOURCE_TYPE_SPEC = Builders. - forMandatoryElement("resourceType", ONE). + forMandatoryElement("oaire:resourceType", ONE). withMandatoryAttribute("resourceTypeGeneral", RESOURCE_GENERAL_TYPES). withMandatoryAttribute("uri", RESOURCE_CONCEPT_URIS). build(); private static final ElementSpec DESCRIPTION_SPEC = Builders. - forMandatoryIfApplicableElement("description", ONE_TO_N, elementIsPresent("description")). + forMandatoryIfApplicableElement("dc:description", ONE_TO_N, elementIsPresent("dc:description")). withOptionalAttribute("xml:lang", new RegexValuePredicate(COMPILED_BCP47_LANG_TAGS_REG_EX)). build(); private static final ElementSpec FORMAT_SPEC = Builders. - forRecommendedRepeatableElement("format"). + forRecommendedRepeatableElement("dc:format"). allowedValues(new MediaTypesValuePredicate()). build(); private static final ElementSpec RESOURCE_IDENTIFIER_SPEC = Builders. - forMandatoryElement("identifier", ONE). + forMandatoryElement("datacite:identifier", ONE). withMandatoryAttribute("identifierType", RESOURCE_IDENTIFIER_TYPES). build(); private static final ElementSpec ACCESS_RIGHTS_SPEC = Builders. - forMandatoryElement("rights", ONE). + forMandatoryElement("datacite:rights", ONE). withMandatoryAttribute("uri", ACCESS_RIGHTS_URIS). allowedValues(ACCESS_RIGHTS_TYPES). build(); private static final ElementSpec SOURCE_SPEC = Builders. - forRecommendedRepeatableElement("source"). + forRecommendedRepeatableElement("dc:source"). build(); //TODO: Should we check URI attribute values are valid? private static final ElementSpec SUBJECT_SPEC = Builders. - forMandatoryIfApplicableElement("subject", ONE_TO_N, elementIsPresent("subject")). + forMandatoryIfApplicableElement("datacite:subject", ONE_TO_N, elementIsPresent("datacite:subject")). withOptionalAttribute("subjectScheme"). withOptionalAttribute("schemeURI"). withOptionalAttribute("valueURI"). build(); private static final ElementSpec LICENSE_CONDITION_SPEC = Builders. - forRecommendedElement("licenseCondition"). - withMandatoryIfApplicableAttribute("uri", elementIsPresent("licenseCondition")). - withMandatoryIfApplicableAttribute("startDate", elementIsPresent("licenseCondition")). + forRecommendedElement("oaire:licenseCondition"). + withMandatoryIfApplicableAttribute("uri", elementIsPresent("oaire:licenseCondition")). + withMandatoryIfApplicableAttribute("startDate", elementIsPresent("oaire:licenseCondition")). build(); private static final ElementSpec COVERAGE_SPEC = Builders. - forRecommendedRepeatableElement("coverage"). + forRecommendedRepeatableElement("dc:coverage"). build(); private static final ElementSpec SIZE_SPEC = Builders. - forOptionalRepeatableElement("size"). + forOptionalRepeatableElement("datacite:size"). build(); private static final ElementSpec GEO_LOCATION_SPEC = Builders. - forOptionalRepeatableElement("geoLocation"). + forOptionalRepeatableElement("datacite:geoLocation"). withSubElement(Builders. - forOptionalElement("geoLocationPoint"). + forOptionalElement("datacite:geoLocationPoint"). withSubElement(Builders. - forMandatoryElement("pointLongitude", ONE)). + forMandatoryElement("datacite:pointLongitude", ONE)). withSubElement(Builders. - forMandatoryElement("pointLatitude", ONE))). + forMandatoryElement("datacite:pointLatitude", ONE))). withSubElement(Builders. - forOptionalElement("geoLocationBox"). + forOptionalElement("datacite:geoLocationBox"). withSubElement(Builders. - forMandatoryElement("westBoundLongitude", ONE)). + forMandatoryElement("datacite:westBoundLongitude", ONE)). withSubElement(Builders. - forMandatoryElement("eastBoundLongitude", ONE)). + forMandatoryElement("datacite:eastBoundLongitude", ONE)). withSubElement(Builders. - forMandatoryElement("southBoundLatitude", ONE)). + forMandatoryElement("datacite:southBoundLatitude", ONE)). withSubElement(Builders. - forMandatoryElement("northBoundLatitude", ONE))). + forMandatoryElement("datacite:northBoundLatitude", ONE))). withSubElement(Builders. - forOptionalElement("geoLocationPlace")). + forOptionalElement("datacite:geoLocationPlace")). withSubElement(Builders. - forOptionalRepeatableElement("geoLocationPolygon"). + forOptionalRepeatableElement("datacite:geoLocationPolygon"). withSubElement(Builders. - forMandatoryElement("polygonPoint", FOUR_TO_N). + forMandatoryElement("datacite:polygonPoint", FOUR_TO_N). withSubElement(Builders. - forMandatoryElement("pointLongitude", ONE)). + forMandatoryElement("datacite:pointLongitude", ONE)). withSubElement(Builders. - forMandatoryElement("pointLatitude", ONE))). + forMandatoryElement("datacite:pointLatitude", ONE))). withSubElement(Builders. - forOptionalElement("inPolygonPoint"). + forOptionalElement("datacite:inPolygonPoint"). withSubElement(Builders. - forMandatoryElement("pointLongitude", ONE)). + forMandatoryElement("datacite:pointLongitude", ONE)). withSubElement(Builders. - forMandatoryElement("pointLatitude", ONE)))). + forMandatoryElement("datacite:pointLatitude", ONE)))). build(); /* @@ -354,57 +354,57 @@ public final class LiteratureGuidelinesV4Profile extends AbstractOpenAireProfile TODO: Should we cross-check attribute and element value are relevant? */ private static final ElementSpec RESOURCE_VERSION_SPEC = Builders. - forRecommendedElement("version"). + forRecommendedElement("oaire:version"). withMandatoryIfApplicableAttribute("uri", applicabilityRuleForURIAttributeOfResourceVersion(), RESOURCE_VERSION_URIS). build(); //TODO: Has annotation/issue: accessRightsURI attribute values also appears on ACCESS_RIGHTS_SPEC. Should check it's the same? private static final ElementSpec FILE_LOCATION_SPEC = Builders. - forMandatoryIfApplicableElement("file", ONE_TO_N, elementIsPresent("file")). + forMandatoryIfApplicableElement("oaire:file", ONE_TO_N, elementIsPresent("oaire:file")). withRecommendedAttribute("accessRightsURI", ACCESS_RIGHTS_URIS). withRecommendedAttribute("mimeType", new MediaTypesValuePredicate()). withRecommendedAttribute("objectType", FILE_OBJECT_TYPES). build(); private static final ElementSpec CITATION_TITLE_SPEC = Builders. - forRecommendedElement("citationTitle"). + forRecommendedElement("oaire:citationTitle"). build(); private static final ElementSpec CITATION_VOLUME_SPEC = Builders. - forRecommendedElement("citationVolume"). + forRecommendedElement("oaire:citationVolume"). build(); private static final ElementSpec CITATION_ISSUE_SPEC = Builders. - forRecommendedElement("citationIssue"). + forRecommendedElement("oaire:citationIssue"). build(); private static final ElementSpec CITATION_START_PAGE_SPEC = Builders. - forRecommendedElement("citationStartPage"). + forRecommendedElement("oaire:citationStartPage"). build(); private static final ElementSpec CITATION_END_PAGE_SPEC = Builders. - forRecommendedElement("citationEndPage"). + forRecommendedElement("oaire:citationEndPage"). build(); private static final ElementSpec CITATION_EDITION_SPEC = Builders. - forRecommendedElement("citationEdition"). + forRecommendedElement("oaire:citationEdition"). build(); private static final ElementSpec CITATION_CONFERENCE_PLACE_SPEC = Builders. - forRecommendedElement("citationConferencePlace"). + forRecommendedElement("oaire:citationConferencePlace"). build(); //TODO: Implement regex/allowedValuesPredicate // Date has recommended best practice ISO 8601 [W3CDTF], and two [single date] [start date - end date] formats private static final ElementSpec CITATION_CONFERENCE_DATE_SPEC = Builders. - forRecommendedElement("citationConferenceDate"). + forRecommendedElement("oaire:citationConferenceDate"). allowedValues(new RegexValuePredicate(COMPILED_YYYY_MM_DD_REGEX).or(new RegexValuePredicate(COMPILED_YYYY_MM_DD_RANGE_REGEX))). build(); //TODO: A non-exhaustive list is provided for values, derived from the Common Education Data Standards vocabulary // Should we add it? private static final ElementSpec AUDIENCE_SPEC = Builders. - forOptionalRepeatableElement("audience"). + forOptionalRepeatableElement("dcterms:audience"). allowedValues(AUDIENCE_VOCABULARY). build(); diff --git a/src/test/groovy/eu/dnetlib/validator2/engine/XMLHelper.groovy b/src/test/groovy/eu/dnetlib/validator2/engine/XMLHelper.groovy index 1eb1eb0..e5392a7 100644 --- a/src/test/groovy/eu/dnetlib/validator2/engine/XMLHelper.groovy +++ b/src/test/groovy/eu/dnetlib/validator2/engine/XMLHelper.groovy @@ -1,6 +1,6 @@ package eu.dnetlib.validator2.engine -import eu.dnetlib.validator2.engine.Helper + import groovy.xml.DOMBuilder import groovy.xml.FactorySupport import org.w3c.dom.Document @@ -31,8 +31,8 @@ class XMLHelper { int bufferSize, Predicate filter, BiConsumer < String, Document > documentConsumer) { - if (documentConsumer) { - + if (documentConsumer) + { DocumentBuilderFactory factory = FactorySupport.createDocumentBuilderFactory() factory.setNamespaceAware(true) factory.setValidating(false) diff --git a/src/test/java/eu/dnetlib/validator2/engine/Test.java b/src/test/java/eu/dnetlib/validator2/engine/Test.java index 4ebf670..64b8181 100644 --- a/src/test/java/eu/dnetlib/validator2/engine/Test.java +++ b/src/test/java/eu/dnetlib/validator2/engine/Test.java @@ -21,7 +21,8 @@ public class Test { // "src/test/resources/openaireguidelinesV3/dia.library.tuc.gr/Record_21811.xml", // "src/test/resources/openaireguidelinesV3/cris.vtt.fi/01.xml", // "src/test/resources/openaireguidelinesV3/cris.vtt.fi/02.xml", - "src/test/resources/openaireguidelinesV3/cris.vtt.fi/03.xml" +// "src/test/resources/openaireguidelinesV3/cris.vtt.fi/03.xml" + "src/test/resources/openaireguidelinesV3/ngi.brage.unit.no/ListRecords_prefix_oai_dc_set_openaire.xml" }; public static void main(String[] args) { diff --git a/src/test/java/eu/dnetlib/validator2/engine/Test_FAIR.java b/src/test/java/eu/dnetlib/validator2/engine/Test_FAIR.java index 425f8bd..ae8536e 100644 --- a/src/test/java/eu/dnetlib/validator2/engine/Test_FAIR.java +++ b/src/test/java/eu/dnetlib/validator2/engine/Test_FAIR.java @@ -24,8 +24,8 @@ public class Test_FAIR { "src/test/resources/openaireguidelinesV3/cris.vtt.fi/01_data.xml", "src/test/resources/openaireguidelinesV3/cris.vtt.fi/02_data.xml", "src/test/resources/openaireguidelinesV3/cris.vtt.fi/04_data.xml", -// "src/test/resources/openaireguidelinesV3/cris.vtt.fi/03_data.xml", -// "src/test/resources/openaireguidelinesV4/01_gv4.xml" + "src/test/resources/openaireguidelinesV3/cris.vtt.fi/03_data.xml", + //"src/test/resources/openaireguidelinesV4/01_gv4.xml" // This file does not exist! }; public static void main(String[] args) { diff --git a/src/test/java/eu/dnetlib/validator2/engine/Test_v4.java b/src/test/java/eu/dnetlib/validator2/engine/Test_v4.java index 074f7cb..0328f36 100644 --- a/src/test/java/eu/dnetlib/validator2/engine/Test_v4.java +++ b/src/test/java/eu/dnetlib/validator2/engine/Test_v4.java @@ -20,8 +20,8 @@ public class Test_v4 { private static final String[] FILES = new String[] { - "src/test/resources/openaireguidelinesV4/v4_literature_all_invalid_guidelines_record.xml", -// "src/test/resources/openaireguidelinesV4/v4_literature_all_guidelines_record.xml", + //"src/test/resources/openaireguidelinesV4/v4_literature_all_invalid_guidelines_record.xml", + "src/test/resources/openaireguidelinesV4/v4_literature_all_guidelines_record.xml", // "src/test/resources/openaireguidelinesV4/oai_mediarep_org_doc_2534.xml", // "src/test/resources/openaireguidelinesV4/01_gv4.xml" };