diff --git a/extensions/wikidata/src/org/openrefine/wikidata/qa/scrutinizers/RestrictedPositionScrutinizer.java b/extensions/wikidata/src/org/openrefine/wikidata/qa/scrutinizers/RestrictedPositionScrutinizer.java index fc09e134a..ac674dcea 100644 --- a/extensions/wikidata/src/org/openrefine/wikidata/qa/scrutinizers/RestrictedPositionScrutinizer.java +++ b/extensions/wikidata/src/org/openrefine/wikidata/qa/scrutinizers/RestrictedPositionScrutinizer.java @@ -23,21 +23,48 @@ ******************************************************************************/ package org.openrefine.wikidata.qa.scrutinizers; -import java.util.Iterator; - 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.ItemIdValue; import org.wikidata.wdtk.datamodel.interfaces.PropertyIdValue; import org.wikidata.wdtk.datamodel.interfaces.Reference; 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 java.util.Iterator; +import java.util.List; public class RestrictedPositionScrutinizer extends StatementScrutinizer { + public static String SCOPE_CONSTRAINT_QID = "Q53869507"; + public static String SCOPE_CONSTRAINT_PID = "P5314"; + public static String SCOPE_CONSTRAINT_VALUE_QID = "Q54828448"; + public static String SCOPE_CONSTRAINT_QUALIFIER_QID = "Q54828449"; + public static String SCOPE_CONSTRAINT_REFERENCE_QID = "Q54828450"; + protected enum SnakPosition { MAINSNAK, QUALIFIER, REFERENCE } + class RestrictedPositionConstraint { + boolean isAllowedAsValue, isAllowedAsQualifier, isAllowedAsReference; + RestrictedPositionConstraint(Statement statement) { + List specs = statement.getClaim().getQualifiers(); + if (specs != null) { + ItemIdValue targetValue = Datamodel.makeWikidataItemIdValue(SCOPE_CONSTRAINT_VALUE_QID); + ItemIdValue targetQualifier = Datamodel.makeWikidataItemIdValue(SCOPE_CONSTRAINT_QUALIFIER_QID); + ItemIdValue targetReference = Datamodel.makeWikidataItemIdValue(SCOPE_CONSTRAINT_REFERENCE_QID); + List snakValues = _fetcher.findValues(specs, SCOPE_CONSTRAINT_PID); + isAllowedAsValue = snakValues.contains(targetValue); + isAllowedAsQualifier = snakValues.contains(targetQualifier); + isAllowedAsReference = snakValues.contains(targetReference); + } + } + } + @Override public void scrutinize(Statement statement, EntityIdValue entityId, boolean added) { // Skip the main snak @@ -72,12 +99,16 @@ public class RestrictedPositionScrutinizer extends StatementScrutinizer { } public boolean positionAllowed(PropertyIdValue pid, SnakPosition position) { - if(position.equals(SnakPosition.MAINSNAK)) { - return _fetcher.allowedAsValue(pid); - } else if(position.equals(SnakPosition.QUALIFIER)) { - return _fetcher.allowedAsQualifier(pid); - } else if(position.equals(SnakPosition.REFERENCE)) { - return _fetcher.allowedAsReference(pid); + List constraintDefinitions = _fetcher.getConstraintsByType(pid, SCOPE_CONSTRAINT_QID); + if (!constraintDefinitions.isEmpty()) { + RestrictedPositionConstraint constraint = new RestrictedPositionConstraint(constraintDefinitions.get(0)); + if (position.equals(SnakPosition.MAINSNAK)) { + return constraint.isAllowedAsValue; + } else if (position.equals(SnakPosition.QUALIFIER)) { + return constraint.isAllowedAsQualifier; + } else if (position.equals(SnakPosition.REFERENCE)) { + return constraint.isAllowedAsReference; + } } return true; } diff --git a/extensions/wikidata/tests/src/org/openrefine/wikidata/qa/scrutinizers/RestrictedPositionScrutinizerTest.java b/extensions/wikidata/tests/src/org/openrefine/wikidata/qa/scrutinizers/RestrictedPositionScrutinizerTest.java index 7b7a0bb55..247e01a47 100644 --- a/extensions/wikidata/tests/src/org/openrefine/wikidata/qa/scrutinizers/RestrictedPositionScrutinizerTest.java +++ b/extensions/wikidata/tests/src/org/openrefine/wikidata/qa/scrutinizers/RestrictedPositionScrutinizerTest.java @@ -23,22 +23,41 @@ ******************************************************************************/ package org.openrefine.wikidata.qa.scrutinizers; -import java.util.Collections; -import java.util.List; - -import org.openrefine.wikidata.qa.MockConstraintFetcher; +import org.openrefine.wikidata.qa.ConstraintFetcher; 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.StatementRank; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.openrefine.wikidata.qa.scrutinizers.RestrictedPositionScrutinizer.SCOPE_CONSTRAINT_PID; +import static org.openrefine.wikidata.qa.scrutinizers.RestrictedPositionScrutinizer.SCOPE_CONSTRAINT_QID; +import static org.openrefine.wikidata.qa.scrutinizers.RestrictedPositionScrutinizer.SCOPE_CONSTRAINT_QUALIFIER_QID; +import static org.openrefine.wikidata.qa.scrutinizers.RestrictedPositionScrutinizer.SCOPE_CONSTRAINT_REFERENCE_QID; +import static org.openrefine.wikidata.qa.scrutinizers.RestrictedPositionScrutinizer.SCOPE_CONSTRAINT_VALUE_QID; + public class RestrictedPositionScrutinizerTest extends SnakScrutinizerTest { - private ItemIdValue qid = TestingData.existingId; + public static PropertyIdValue propertyIdValue = Datamodel.makeWikidataPropertyIdValue("P22"); + public static PropertyIdValue mainSnakPid = Datamodel.makeWikidataPropertyIdValue("P1234"); + public static PropertyIdValue propertyScopeParameter = Datamodel.makeWikidataPropertyIdValue("P5314"); + public static ItemIdValue entityIdValue = Datamodel.makeWikidataItemIdValue(SCOPE_CONSTRAINT_QID); + public static ItemIdValue asMainSnak = Datamodel.makeWikidataItemIdValue(SCOPE_CONSTRAINT_VALUE_QID); + public static ItemIdValue asQualifier = Datamodel.makeWikidataItemIdValue(SCOPE_CONSTRAINT_QUALIFIER_QID); + public static ItemIdValue asReference = Datamodel.makeWikidataItemIdValue(SCOPE_CONSTRAINT_REFERENCE_QID); @Override public EditScrutinizer getScrutinizer() { @@ -47,31 +66,77 @@ public class RestrictedPositionScrutinizerTest extends SnakScrutinizerTest { @Test public void testTriggerMainSnak() { - scrutinize(TestingData.generateStatement(qid, MockConstraintFetcher.qualifierPid, qid)); + ItemIdValue idA = TestingData.existingId; + Snak mainSnak = Datamodel.makeSomeValueSnak(propertyIdValue); + Statement statement = new StatementImpl("P22", mainSnak, idA); + ItemUpdate update = new ItemUpdateBuilder(idA).addStatement(statement).build(); + + Snak qualifierSnak = Datamodel.makeValueSnak(propertyScopeParameter, asQualifier); + List constraintQualifiers = makeSnakGroupList(qualifierSnak); + List constraintDefinitions = constraintParameterStatementList(entityIdValue, constraintQualifiers); + ConstraintFetcher fetcher = mock(ConstraintFetcher.class); + when(fetcher.getConstraintsByType(propertyIdValue, SCOPE_CONSTRAINT_QID)).thenReturn(constraintDefinitions); + when(fetcher.findValues(constraintQualifiers, SCOPE_CONSTRAINT_PID)).thenReturn(Collections.singletonList(asQualifier)); + setFetcher(fetcher); + + scrutinize(update); assertWarningsRaised("property-found-in-mainsnak"); } @Test public void testNoProblem() { - scrutinize(TestingData.generateStatement(qid, MockConstraintFetcher.mainSnakPid, qid)); + ItemIdValue idA = TestingData.existingId; + Snak mainSnak = Datamodel.makeSomeValueSnak(propertyIdValue); + Statement statement = new StatementImpl("P22", mainSnak, idA); + ItemUpdate update = new ItemUpdateBuilder(idA).addStatement(statement).build(); + + Snak qualifierSnak = Datamodel.makeValueSnak(propertyScopeParameter, asMainSnak); + List constraintQualifiers = makeSnakGroupList(qualifierSnak); + List constraintDefinitions = constraintParameterStatementList(entityIdValue, constraintQualifiers); + ConstraintFetcher fetcher = mock(ConstraintFetcher.class); + when(fetcher.getConstraintsByType(propertyIdValue, SCOPE_CONSTRAINT_QID)).thenReturn(constraintDefinitions); + when(fetcher.findValues(constraintQualifiers, SCOPE_CONSTRAINT_PID)).thenReturn(Collections.singletonList(asMainSnak)); + setFetcher(fetcher); + + scrutinize(update); assertNoWarningRaised(); } @Test public void testNotRestricted() { - scrutinize(TestingData.generateStatement(qid, Datamodel.makeWikidataPropertyIdValue("P3748"), qid)); + ItemIdValue idA = TestingData.existingId; + Snak mainSnak = Datamodel.makeSomeValueSnak(propertyIdValue); + Statement statement = new StatementImpl("P22", mainSnak, idA); + ItemUpdate update = new ItemUpdateBuilder(idA).addStatement(statement).build(); + + ConstraintFetcher fetcher = mock(ConstraintFetcher.class); + when(fetcher.getConstraintsByType(propertyIdValue, SCOPE_CONSTRAINT_QID)).thenReturn(new ArrayList<>()); + setFetcher(fetcher); + + scrutinize(update); assertNoWarningRaised(); } @Test public void testTriggerReference() { - Snak snak = Datamodel.makeValueSnak(MockConstraintFetcher.mainSnakPid, qid); + ItemIdValue idA = TestingData.existingId; + Snak snak = Datamodel.makeValueSnak(propertyIdValue, idA); List snakGroups = Collections .singletonList(Datamodel.makeSnakGroup(Collections.singletonList(snak))); Statement statement = Datamodel.makeStatement( - TestingData.generateStatement(qid, MockConstraintFetcher.mainSnakPid, qid).getClaim(), + TestingData.generateStatement(idA, propertyIdValue, idA).getClaim(), Collections.singletonList(Datamodel.makeReference(snakGroups)), StatementRank.NORMAL, ""); - scrutinize(statement); + ItemUpdate update = new ItemUpdateBuilder(idA).addStatement(statement).build(); + + Snak qualifierSnak = Datamodel.makeValueSnak(propertyScopeParameter, asMainSnak); + List constraintQualifiers = makeSnakGroupList(qualifierSnak); + List constraintDefinitions = constraintParameterStatementList(entityIdValue, constraintQualifiers); + ConstraintFetcher fetcher = mock(ConstraintFetcher.class); + when(fetcher.getConstraintsByType(propertyIdValue, SCOPE_CONSTRAINT_QID)).thenReturn(constraintDefinitions); + when(fetcher.findValues(constraintQualifiers, SCOPE_CONSTRAINT_PID)).thenReturn(Collections.singletonList(asMainSnak)); + setFetcher(fetcher); + + scrutinize(update); assertWarningsRaised("property-found-in-reference"); }