Add entity type constraint check

This commit is contained in:
Antonin Delpeuch 2018-06-10 09:24:22 +01:00
parent e2ae09f5be
commit 1910833ad8
7 changed files with 84 additions and 0 deletions

View File

@ -236,6 +236,10 @@
"no-unit-provided": {
"title": "Unit missing for {property_entity}",
"body": "Values such as <span class=\"wb-issue-preformat\">{example_value}</span> on {example_item_entity} are expected to have units."
},
"invalid-entity-type": {
"title": "{property_entity} used on items",
"body": "Uses of {property_entity} on items such as {example_entity} are invalid."
}
}
}

View File

@ -129,4 +129,9 @@ public interface ConstraintFetcher {
* Returns the allowed units for this property. If empty, no unit is allowed. If null, any unit is allowed.
*/
Set<ItemIdValue> allowedUnits(PropertyIdValue pid);
/**
* Can this property be used on items?
*/
boolean usableOnItems(PropertyIdValue pid);
}

View File

@ -30,6 +30,7 @@ import java.util.stream.Collectors;
import org.openrefine.wikidata.qa.scrutinizers.DistinctValuesScrutinizer;
import org.openrefine.wikidata.qa.scrutinizers.EditScrutinizer;
import org.openrefine.wikidata.qa.scrutinizers.EntityTypeScrutinizer;
import org.openrefine.wikidata.qa.scrutinizers.FormatScrutinizer;
import org.openrefine.wikidata.qa.scrutinizers.InverseConstraintScrutinizer;
import org.openrefine.wikidata.qa.scrutinizers.NewItemScrutinizer;
@ -77,6 +78,7 @@ public class EditInspector {
register(new WhitespaceScrutinizer());
register(new QuantityScrutinizer());
register(new RestrictedValuesScrutinizer());
register(new EntityTypeScrutinizer());
}
/**

View File

@ -31,6 +31,7 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.openrefine.wikidata.utils.EntityCache;
import org.wikidata.wdtk.datamodel.helpers.Datamodel;
import org.wikidata.wdtk.datamodel.interfaces.EntityIdValue;
import org.wikidata.wdtk.datamodel.interfaces.ItemIdValue;
import org.wikidata.wdtk.datamodel.interfaces.PropertyDocument;
@ -88,6 +89,10 @@ public class WikidataConstraintFetcher implements ConstraintFetcher {
public static String ALLOWED_UNITS_CONSTRAINT_QID = "Q21514353";
public static String ALLOWED_UNITS_CONSTRAINT_PID = "P2305";
public static String ALLOWED_ENTITY_TYPES_QID = "Q52004125";
public static String ALLOWED_ITEM_TYPE_QID = "Q29934200";
public static String ALLOWED_ENTITY_TYPES_PID = "P2305";
// The following constraints still need to be implemented:
@ -223,6 +228,16 @@ public class WikidataConstraintFetcher implements ConstraintFetcher {
}
return null;
}
@Override
public boolean usableOnItems(PropertyIdValue pid) {
List<SnakGroup> constraint = getSingleConstraint(pid, ALLOWED_ENTITY_TYPES_QID);
if (constraint != null) {
return findValues(constraint, ALLOWED_ENTITY_TYPES_PID).contains(
Datamodel.makeWikidataItemIdValue(ALLOWED_ITEM_TYPE_QID));
}
return true;
}
/**
* Returns a single constraint for a particular type and a property, or null if

View File

@ -0,0 +1,22 @@
package org.openrefine.wikidata.qa.scrutinizers;
import org.openrefine.wikidata.qa.QAWarning;
import org.wikidata.wdtk.datamodel.interfaces.EntityIdValue;
import org.wikidata.wdtk.datamodel.interfaces.PropertyIdValue;
import org.wikidata.wdtk.datamodel.interfaces.Snak;
public class EntityTypeScrutinizer extends SnakScrutinizer {
public final static String type = "invalid-entity-type";
@Override
public void scrutinize(Snak snak, EntityIdValue entityId, boolean added) {
PropertyIdValue pid = snak.getPropertyId();
if(!_fetcher.usableOnItems(pid)) {
QAWarning issue = new QAWarning(type, null, QAWarning.Severity.WARNING, 1);
issue.setProperty("example_entity", entityId);
addIssue(issue);
}
}
}

View File

@ -56,6 +56,8 @@ public class MockConstraintFetcher implements ConstraintFetcher {
public static PropertyIdValue noBoundsPid = Datamodel.makeWikidataPropertyIdValue("P8932");
public static PropertyIdValue integerPid = Datamodel.makeWikidataPropertyIdValue("P389");
public static PropertyIdValue propertyOnlyPid = Datamodel.makeWikidataPropertyIdValue("P372");
@Override
public String getFormatRegex(PropertyIdValue pid) {
@ -154,4 +156,9 @@ public class MockConstraintFetcher implements ConstraintFetcher {
}
return null;
}
@Override
public boolean usableOnItems(PropertyIdValue pid) {
return !propertyOnlyPid.equals(pid);
}
}

View File

@ -0,0 +1,29 @@
package org.openrefine.wikidata.qa.scrutinizers;
import org.openrefine.wikidata.qa.MockConstraintFetcher;
import org.openrefine.wikidata.testing.TestingData;
import org.testng.annotations.Test;
import org.wikidata.wdtk.datamodel.helpers.Datamodel;
import org.wikidata.wdtk.datamodel.interfaces.ItemIdValue;
public class EntityTypeScrutinizerTest extends StatementScrutinizerTest {
private static ItemIdValue qid = Datamodel.makeWikidataItemIdValue("Q343");
@Override
public EditScrutinizer getScrutinizer() {
return new EntityTypeScrutinizer();
}
@Test
public void testAllowed() {
scrutinize(TestingData.generateStatement(qid, qid));
assertNoWarningRaised();
}
@Test
public void testDisallowed() {
scrutinize(TestingData.generateStatement(qid, MockConstraintFetcher.propertyOnlyPid, qid));
assertWarningsRaised(EntityTypeScrutinizer.type);
}
}