diff --git a/extensions/wikidata/src/org/openrefine/wikidata/qa/ConstraintFetcher.java b/extensions/wikidata/src/org/openrefine/wikidata/qa/ConstraintFetcher.java index c4639a73c..f3dc02b32 100644 --- a/extensions/wikidata/src/org/openrefine/wikidata/qa/ConstraintFetcher.java +++ b/extensions/wikidata/src/org/openrefine/wikidata/qa/ConstraintFetcher.java @@ -26,6 +26,7 @@ package org.openrefine.wikidata.qa; import org.wikidata.wdtk.datamodel.interfaces.ItemIdValue; import org.wikidata.wdtk.datamodel.interfaces.PropertyIdValue; import org.wikidata.wdtk.datamodel.interfaces.QuantityValue; +import org.wikidata.wdtk.datamodel.interfaces.SnakGroup; import org.wikidata.wdtk.datamodel.interfaces.Statement; import org.wikidata.wdtk.datamodel.interfaces.Value; @@ -154,6 +155,17 @@ public interface ConstraintFetcher { */ List getConstraintsByType(PropertyIdValue pid, String qid); + /** + * Returns the values of a given property in qualifiers + * + * @param groups + * the qualifiers + * @param pid + * the property to filter on + * @return + */ + List findValues(List groups, String pid); + /** * Retrieves the lower bound of the range * required in difference-within-range constraint diff --git a/extensions/wikidata/src/org/openrefine/wikidata/qa/WikidataConstraintFetcher.java b/extensions/wikidata/src/org/openrefine/wikidata/qa/WikidataConstraintFetcher.java index 4c19f3442..f773b001f 100644 --- a/extensions/wikidata/src/org/openrefine/wikidata/qa/WikidataConstraintFetcher.java +++ b/extensions/wikidata/src/org/openrefine/wikidata/qa/WikidataConstraintFetcher.java @@ -293,7 +293,7 @@ public class WikidataConstraintFetcher implements ConstraintFetcher { /** * Gets the list of constraints of a particular type for a property - * + * * @param pid * the property to retrieve the constraints for * @param qid @@ -336,7 +336,8 @@ public class WikidataConstraintFetcher implements ConstraintFetcher { * the property to filter on * @return */ - protected List findValues(List groups, String pid) { + @Override + public List findValues(List groups, String pid) { List results = new ArrayList<>(); for (SnakGroup group : groups) { if (group.getProperty().getId().equals(pid)) { diff --git a/extensions/wikidata/src/org/openrefine/wikidata/qa/scrutinizers/EntityTypeScrutinizer.java b/extensions/wikidata/src/org/openrefine/wikidata/qa/scrutinizers/EntityTypeScrutinizer.java index 60f9b4478..49b1a9f7b 100644 --- a/extensions/wikidata/src/org/openrefine/wikidata/qa/scrutinizers/EntityTypeScrutinizer.java +++ b/extensions/wikidata/src/org/openrefine/wikidata/qa/scrutinizers/EntityTypeScrutinizer.java @@ -1,23 +1,40 @@ package org.openrefine.wikidata.qa.scrutinizers; import org.openrefine.wikidata.qa.QAWarning; +import org.wikidata.wdtk.datamodel.helpers.Datamodel; import org.wikidata.wdtk.datamodel.interfaces.EntityIdValue; import org.wikidata.wdtk.datamodel.interfaces.PropertyIdValue; import org.wikidata.wdtk.datamodel.interfaces.Snak; +import org.wikidata.wdtk.datamodel.interfaces.SnakGroup; +import org.wikidata.wdtk.datamodel.interfaces.Statement; + +import java.util.List; public class EntityTypeScrutinizer extends SnakScrutinizer { public final static String type = "invalid-entity-type"; + public static String ALLOWED_ENTITY_TYPES_QID = "Q52004125"; + public static String ALLOWED_ITEM_TYPE_QID = "Q29934200"; + public static String ALLOWED_ENTITY_TYPES_PID = "P2305"; @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("property_entity", pid); - issue.setProperty("example_entity", entityId); - addIssue(issue); + List statementList = _fetcher.getConstraintsByType(pid, ALLOWED_ENTITY_TYPES_QID); + if(!statementList.isEmpty()) { + List constraint = statementList.get(0).getClaim().getQualifiers(); + boolean isUsable = true; + if (constraint != null) { + isUsable = _fetcher.findValues(constraint, ALLOWED_ENTITY_TYPES_PID).contains( + Datamodel.makeWikidataItemIdValue(ALLOWED_ITEM_TYPE_QID)); + } + if (!isUsable) { + QAWarning issue = new QAWarning(type, null, QAWarning.Severity.WARNING, 1); + issue.setProperty("property_entity", pid); + issue.setProperty("example_entity", entityId); + addIssue(issue); + } } } } diff --git a/extensions/wikidata/tests/src/org/openrefine/wikidata/qa/MockConstraintFetcher.java b/extensions/wikidata/tests/src/org/openrefine/wikidata/qa/MockConstraintFetcher.java index aa1b77f2f..194a57b41 100644 --- a/extensions/wikidata/tests/src/org/openrefine/wikidata/qa/MockConstraintFetcher.java +++ b/extensions/wikidata/tests/src/org/openrefine/wikidata/qa/MockConstraintFetcher.java @@ -248,4 +248,9 @@ public class MockConstraintFetcher implements ConstraintFetcher { return statements; } + + @Override + public List findValues(List groups, String pid) { + return null; + } } diff --git a/extensions/wikidata/tests/src/org/openrefine/wikidata/qa/scrutinizers/EntityTypeScrutinizerTest.java b/extensions/wikidata/tests/src/org/openrefine/wikidata/qa/scrutinizers/EntityTypeScrutinizerTest.java index baaf6f44e..e8f7688ba 100644 --- a/extensions/wikidata/tests/src/org/openrefine/wikidata/qa/scrutinizers/EntityTypeScrutinizerTest.java +++ b/extensions/wikidata/tests/src/org/openrefine/wikidata/qa/scrutinizers/EntityTypeScrutinizerTest.java @@ -1,14 +1,38 @@ package org.openrefine.wikidata.qa.scrutinizers; +import org.openrefine.wikidata.qa.ConstraintFetcher; import org.openrefine.wikidata.qa.MockConstraintFetcher; import org.openrefine.wikidata.testing.TestingData; +import org.openrefine.wikidata.updates.ItemUpdate; +import org.openrefine.wikidata.updates.ItemUpdateBuilder; import org.testng.annotations.Test; import org.wikidata.wdtk.datamodel.helpers.Datamodel; +import org.wikidata.wdtk.datamodel.implementation.StatementImpl; import org.wikidata.wdtk.datamodel.interfaces.ItemIdValue; +import org.wikidata.wdtk.datamodel.interfaces.PropertyIdValue; +import org.wikidata.wdtk.datamodel.interfaces.Snak; +import org.wikidata.wdtk.datamodel.interfaces.SnakGroup; +import org.wikidata.wdtk.datamodel.interfaces.Statement; +import org.wikidata.wdtk.datamodel.interfaces.Value; +import org.wikidata.wdtk.datamodel.interfaces.ValueSnak; + +import java.util.Collections; +import java.util.List; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; public class EntityTypeScrutinizerTest extends StatementScrutinizerTest { - - private static ItemIdValue qid = Datamodel.makeWikidataItemIdValue("Q343"); + + public static PropertyIdValue propertyIdValue = Datamodel.makeWikidataPropertyIdValue("P2302"); + public static Value propertyValue = MockConstraintFetcher.conflictsWithStatementValue; + + public static ItemIdValue entityIdValue = Datamodel.makeWikidataItemIdValue("Q52004125"); + public static PropertyIdValue itemParameterPID = Datamodel.makeWikidataPropertyIdValue("P2305"); + public static Value itemValue = Datamodel.makeWikidataItemIdValue("Q29934218"); + public static Value allowedValue = Datamodel.makeWikidataItemIdValue("Q29934200"); + + @Override public EditScrutinizer getScrutinizer() { @@ -17,13 +41,49 @@ public class EntityTypeScrutinizerTest extends StatementScrutinizerTest { @Test public void testAllowed() { - scrutinize(TestingData.generateStatement(qid, qid)); + ItemIdValue idA = TestingData.existingId; + + ValueSnak mainValueSnak = Datamodel.makeValueSnak(propertyIdValue, propertyValue); + Statement statement = new StatementImpl("P2302", mainValueSnak, idA); + + ItemUpdate update = new ItemUpdateBuilder(idA).addStatement(statement).build(); + + Snak qualifierSnak = Datamodel.makeValueSnak(itemParameterPID, itemValue); + List qualifierSnakList = Collections.singletonList(qualifierSnak); + SnakGroup qualifierSnakGroup = Datamodel.makeSnakGroup(qualifierSnakList); + List snakGroupList = Collections.singletonList(qualifierSnakGroup); + List statementList = constraintParameterStatementList(entityIdValue, snakGroupList); + + ConstraintFetcher fetcher = mock(ConstraintFetcher.class); + when(fetcher.getConstraintsByType(propertyIdValue,"Q52004125")).thenReturn(statementList); + when(fetcher.findValues(snakGroupList, "P2305")).thenReturn(Collections.singletonList(allowedValue)); + setFetcher(fetcher); + + scrutinize(update); assertNoWarningRaised(); } @Test public void testDisallowed() { - scrutinize(TestingData.generateStatement(qid, MockConstraintFetcher.propertyOnlyPid, qid)); + ItemIdValue idA = TestingData.existingId; + + ValueSnak mainValueSnak = Datamodel.makeValueSnak(propertyIdValue, propertyValue); + Statement statement = new StatementImpl("P2302", mainValueSnak, idA); + + ItemUpdate update = new ItemUpdateBuilder(idA).addStatement(statement).build(); + + Snak qualifierSnak = Datamodel.makeValueSnak(itemParameterPID, itemValue); + List qualifierSnakList = Collections.singletonList(qualifierSnak); + SnakGroup qualifierSnakGroup = Datamodel.makeSnakGroup(qualifierSnakList); + List snakGroupList = Collections.singletonList(qualifierSnakGroup); + List statementList = constraintParameterStatementList(entityIdValue, snakGroupList); + + ConstraintFetcher fetcher = mock(ConstraintFetcher.class); + when(fetcher.getConstraintsByType(propertyIdValue,"Q52004125")).thenReturn(statementList); + when(fetcher.findValues(snakGroupList, "P2305")).thenReturn(Collections.singletonList(itemValue)); + setFetcher(fetcher); + + scrutinize(update); assertWarningsRaised(EntityTypeScrutinizer.type); } }