Code optimization and polishing.

This commit is contained in:
Lampros Smyrnaios 2023-07-27 14:48:10 +03:00
parent 7be1dbe493
commit a4c7c33907
7 changed files with 70 additions and 61 deletions

View File

@ -2,18 +2,16 @@ package eu.dnetlib.validator2.engine;
public class RuleEngine {
public static <T, R extends Rule<T>> void applyAndReport(R rule, T t, Reporter<T, R> reporter) {
public static <T, R extends Rule<T>> void applyAndReport(R rule, T t, Reporter<T, R> 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);
}

View File

@ -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);

View File

@ -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);

View File

@ -47,27 +47,27 @@ class GuidelineEvaluation {
logger.debug("Evaluating " + rules);
for (SyntheticRule<Document> rule: rules) {
for ( SyntheticRule<Document> 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<Document> rule) {
return subjectId + ": rule " + Helper.stringify(rule) + " has failed";
}
private String synthesizeNotApplicableMessage(Rule<Document> rule) {
return subjectId + ": rule " + Helper.stringify(rule) + " is not applicable";
}

View File

@ -386,6 +386,7 @@ class F2_01M_SPEC extends AbstractGuideline<Document> {
// TODO: iterate over results and build one Guideline.Result
try {
XMLApplicationProfile.ValidationResult res_F = profile.validate(id, t);
Map<String, Guideline.Result> 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<Document> {
List<String> warnings2 = new ArrayList<>();
List<String> 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<String, Guideline.Result> 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<Document> {
try {
// System.out.println("\nMetadata includes the identifier for the data");
XMLApplicationProfile.ValidationResult res_F = profile.validate(id, t);
Map<String, Result> results = res_F.results();
Map<String, Guideline.Result> 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<Document> {
ArrayList<String> warnings2 = new ArrayList<>();
ArrayList<String> 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<String, Guideline.Result> 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<Document> {
// 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<String, Result> results = res_F.results();
Map<String, Guideline.Result> 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<Document> {
ArrayList<String> warnings2 = new ArrayList<>();
ArrayList<String> 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<String, Guideline.Result> 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<Document> {
try {
// System.out.println("\nPlurality of accurate and relevant attributes are provided to allow reuse");
XMLApplicationProfile.ValidationResult res_F = profile.validate(id, t);
Map<String, Result> results = res_F.results();
Map<String, Guideline.Result> results = res_F.results();
int MaxScoreR1_01M_SPEC = (int) ((res_F.score()*getWeight())/100);
ArrayList<String> warnings2 = new ArrayList<>();
ArrayList<String> 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<String, Guideline.Result> 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<Document> {
try {
// System.out.println("\nMetadata includes provenance information according to a cross-community language");
XMLApplicationProfile.ValidationResult res_F = profile.validate(id, t);
Map<String, Result> results = res_F.results();
Map<String, Guideline.Result> results = res_F.results();
int MaxScoreR1_2_01M_SPEC = (int) ((res_F.score()*getWeight())/100);
ArrayList<String> warnings2 = new ArrayList<>();
ArrayList<String> 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<String, Guideline.Result> 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;

View File

@ -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<ZipEntry> filter,
BiConsumer < String, Document > documentConsumer) {
if (documentConsumer) {
if (documentConsumer)
{
DocumentBuilderFactory factory = FactorySupport.createDocumentBuilderFactory()
factory.setNamespaceAware(true)
factory.setValidating(false)

View File

@ -25,7 +25,7 @@ public class Test_FAIR {
"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/openaireguidelinesV4/01_gv4.xml" // This file does not exist!
};
public static void main(String[] args) {