Add One-of qualifier value property constraint (#2907)

* Add One-of qualifier value property constraint

Implemented one-of qualifier value property constraint as part of #2354

* Test class added

* Test cases updated and working fine

* resolved merge conflicts
This commit is contained in:
Ekta Mishra 2020-07-15 17:43:49 +05:30 committed by GitHub
parent fe275ae634
commit 2bf493a498
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 189 additions and 0 deletions

View File

@ -156,6 +156,8 @@
"warnings-messages/existing-item-requires-property-to-have-certain-values/body": "Property {added_property_entity} doesn't have appropriate values such as on item {example_entity}. If the item already has statements with property {added_property_entity} and with appropriate values in Wikidata, then this warning can be ignored.", "warnings-messages/existing-item-requires-property-to-have-certain-values/body": "Property {added_property_entity} doesn't have appropriate values such as on item {example_entity}. If the item already has statements with property {added_property_entity} and with appropriate values in Wikidata, then this warning can be ignored.",
"warnings-messages/existing-item-requires-certain-other-statement/title": "{property_entity} requires statement with property {added_property_entity}.", "warnings-messages/existing-item-requires-certain-other-statement/title": "{property_entity} requires statement with property {added_property_entity}.",
"warnings-messages/existing-item-requires-certain-other-statement/body": "This property is expected to have another statement with property {added_property_entity} such as on item {example_entity}. If the item already has statements with property {added_property_entity} in Wikidata, then this warning can be ignored.", "warnings-messages/existing-item-requires-certain-other-statement/body": "This property is expected to have another statement with property {added_property_entity} such as on item {example_entity}. If the item already has statements with property {added_property_entity} in Wikidata, then this warning can be ignored.",
"warnings-messages/values-should-not-be-used-as-qualifier/title": "Invalid value for qualifier {qualifier_entity} on statement {statement_entity}",
"warnings-messages/values-should-not-be-used-as-qualifier/body": "On items such as {example_entity}, an invalid value for qualifier {qualifier_entity} was supplied on statement {statement_entity}.",
"warnings-messages/ignored-qualifiers/title": "Some qualifiers were ignored.", "warnings-messages/ignored-qualifiers/title": "Some qualifiers were ignored.",
"warnings-messages/ignored-qualifiers/body": "Qualifier values could not be parsed, so they will not be added to the corresponding statements.", "warnings-messages/ignored-qualifiers/body": "Qualifier values could not be parsed, so they will not be added to the corresponding statements.",
"warnings-messages/ignored-references/title": "Some references were ignored.", "warnings-messages/ignored-references/title": "Some references were ignored.",

View File

@ -73,6 +73,7 @@ public class EditInspector {
register(new DifferenceWithinRangeScrutinizer()); register(new DifferenceWithinRangeScrutinizer());
register(new ConflictsWithScrutinizer()); register(new ConflictsWithScrutinizer());
register(new ItemRequiresScrutinizer()); register(new ItemRequiresScrutinizer());
register(new UseAsQualifierScrutinizer());
} }
/** /**

View File

@ -0,0 +1,85 @@
package org.openrefine.wikidata.qa.scrutinizers;
import org.openrefine.wikidata.qa.QAWarning;
import org.openrefine.wikidata.updates.ItemUpdate;
import org.wikidata.wdtk.datamodel.helpers.Datamodel;
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 java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class UseAsQualifierScrutinizer extends EditScrutinizer {
public static final String type = "values-should-not-be-used-as-qualifier";
public static String ONE_OF_QUALIFIER_VALUE_PROPERTY_QID = "Q52712340";
public static String QUALIFIER_PROPERTY_PID = "P2306";
public static String ITEM_OF_PROPERTY_CONSTRAINT_PID = "P2305";
class UseAsQualifierConstraint {
final PropertyIdValue allowedQualifierPid;
final List<Value> itemList;
UseAsQualifierConstraint(Statement statement) {
List<SnakGroup> specs = statement.getClaim().getQualifiers();
PropertyIdValue pid = null;
this.itemList = new ArrayList<>();
for(SnakGroup group : specs) {
for (Snak snak : group.getSnaks()) {
if (group.getProperty().getId().equals(QUALIFIER_PROPERTY_PID)){
pid = (PropertyIdValue) snak.getValue();
}
if (group.getProperty().getId().equals(ITEM_OF_PROPERTY_CONSTRAINT_PID)){
this.itemList.add(snak.getValue());
}
}
}
this.allowedQualifierPid = pid;
}
}
@Override
public void scrutinize(ItemUpdate update) {
for (Statement statement : update.getAddedStatements()) {
PropertyIdValue pid = statement.getClaim().getMainSnak().getPropertyId();
Map<PropertyIdValue, List<Value>> qualifiersMap = new HashMap<>();
List<SnakGroup> qualifiersList = statement.getClaim().getQualifiers();
for(SnakGroup qualifier : qualifiersList) {
PropertyIdValue qualifierPid = Datamodel.makeWikidataPropertyIdValue(qualifier.getProperty().getId());
List<Value> itemList;
for (Snak snak : qualifier.getSnaks()) {
if (qualifiersMap.containsKey(qualifierPid)){
itemList = qualifiersMap.get(qualifierPid);
}else {
itemList = new ArrayList<>();
}
itemList.add(snak.getValue());
qualifiersMap.put(qualifierPid, itemList);
}
}
List<Statement> constraintDefinitions = _fetcher.getConstraintsByType(pid, ONE_OF_QUALIFIER_VALUE_PROPERTY_QID);
for (Statement constraintStatement : constraintDefinitions) {
UseAsQualifierConstraint constraint = new UseAsQualifierConstraint(constraintStatement);
if (qualifiersMap.containsKey(constraint.allowedQualifierPid)) {
for (Value value : qualifiersMap.get(constraint.allowedQualifierPid)) {
if (!constraint.itemList.contains(value)) {
QAWarning issue = new QAWarning(type, pid.getId()+constraint.allowedQualifierPid.getId(), QAWarning.Severity.WARNING, 1);
issue.setProperty("statement_entity", pid);
issue.setProperty("qualifier_entity", constraint.allowedQualifierPid);
issue.setProperty("example_entity", update.getItemId());
addIssue(issue);
}
}
}
}
}
}
}

View File

@ -0,0 +1,101 @@
package org.openrefine.wikidata.qa.scrutinizers;
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.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 java.util.ArrayList;
import java.util.List;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.openrefine.wikidata.qa.scrutinizers.UseAsQualifierScrutinizer.ITEM_OF_PROPERTY_CONSTRAINT_PID;
import static org.openrefine.wikidata.qa.scrutinizers.UseAsQualifierScrutinizer.ONE_OF_QUALIFIER_VALUE_PROPERTY_QID;
import static org.openrefine.wikidata.qa.scrutinizers.UseAsQualifierScrutinizer.QUALIFIER_PROPERTY_PID;
public class UseAsQualifierScrutinizerTest extends ScrutinizerTest {
public static PropertyIdValue propertyIdValue = Datamodel.makeWikidataPropertyIdValue("P2302");
public static PropertyIdValue itemParameterPID = Datamodel.makeWikidataPropertyIdValue(ITEM_OF_PROPERTY_CONSTRAINT_PID);
public static PropertyIdValue qualifierPID = Datamodel.makeWikidataPropertyIdValue(QUALIFIER_PROPERTY_PID);
public static PropertyIdValue qualifierPropertyValue = Datamodel.makeWikidataPropertyIdValue("P348");
public static ItemIdValue qualifierAllowedValue = Datamodel.makeWikidataItemIdValue("Q546");
public static ItemIdValue qualifierDisallowedValue = Datamodel.makeWikidataItemIdValue("Q12333");
public static ItemIdValue useAsQualifierEntityId = Datamodel.makeWikidataItemIdValue("Q52712340");
@Override
public EditScrutinizer getScrutinizer() {
return new UseAsQualifierScrutinizer();
}
@Test
public void testTrigger() {
ItemIdValue id = TestingData.existingId;
Snak statementQualifier = Datamodel.makeValueSnak(qualifierPropertyValue, qualifierDisallowedValue);
List<SnakGroup> qualifierList = makeSnakGroupList(statementQualifier);
List<Statement> statementList = constraintParameterStatementList(useAsQualifierEntityId, qualifierList);
Statement statement = statementList.get(0);
ItemUpdate update = new ItemUpdateBuilder(id).addStatement(statement).build();
Snak qualifierSnak1 = Datamodel.makeValueSnak(qualifierPID, qualifierPropertyValue);
Snak qualifierSnak2 = Datamodel.makeValueSnak(itemParameterPID, qualifierAllowedValue);
List<SnakGroup> constraintQualifiers = makeSnakGroupList(qualifierSnak1, qualifierSnak2);
List<Statement> constraintDefinitions = constraintParameterStatementList(useAsQualifierEntityId, constraintQualifiers);
ConstraintFetcher fetcher = mock(ConstraintFetcher.class);
when(fetcher.getConstraintsByType(any(), eq(ONE_OF_QUALIFIER_VALUE_PROPERTY_QID))).thenReturn(constraintDefinitions);
setFetcher(fetcher);
scrutinize(update);
assertWarningsRaised(UseAsQualifierScrutinizer.type);
}
@Test
public void testNoIssue() {
ItemIdValue id = TestingData.existingId;
Snak statementQualifier = Datamodel.makeValueSnak(qualifierPropertyValue, qualifierAllowedValue);
List<SnakGroup> qualifierList = makeSnakGroupList(statementQualifier);
List<Statement> statementList = constraintParameterStatementList(useAsQualifierEntityId, qualifierList);
Statement statement = statementList.get(0);
ItemUpdate update = new ItemUpdateBuilder(id).addStatement(statement).build();
Snak qualifierSnak1 = Datamodel.makeValueSnak(qualifierPID, qualifierPropertyValue);
Snak qualifierSnak2 = Datamodel.makeValueSnak(itemParameterPID, qualifierAllowedValue);
List<SnakGroup> constraintQualifiers = makeSnakGroupList(qualifierSnak1, qualifierSnak2);
List<Statement> constraintDefinitions = constraintParameterStatementList(useAsQualifierEntityId, constraintQualifiers);
ConstraintFetcher fetcher = mock(ConstraintFetcher.class);
when(fetcher.getConstraintsByType(any(), eq(ONE_OF_QUALIFIER_VALUE_PROPERTY_QID))).thenReturn(constraintDefinitions);
setFetcher(fetcher);
scrutinize(update);
assertNoWarningRaised();
}
@Test
public void testNoQualifier() {
ItemIdValue id = TestingData.existingId;
List<Statement> statementList = constraintParameterStatementList(useAsQualifierEntityId, new ArrayList<>());
Statement statement = statementList.get(0);
ItemUpdate update = new ItemUpdateBuilder(id).addStatement(statement).build();
Snak qualifierSnak1 = Datamodel.makeValueSnak(qualifierPID, qualifierPropertyValue);
Snak qualifierSnak2 = Datamodel.makeValueSnak(itemParameterPID, qualifierAllowedValue);
List<SnakGroup> constraintQualifiers = makeSnakGroupList(qualifierSnak1, qualifierSnak2);
List<Statement> constraintDefinitions = constraintParameterStatementList(useAsQualifierEntityId, constraintQualifiers);
ConstraintFetcher fetcher = mock(ConstraintFetcher.class);
when(fetcher.getConstraintsByType(any(), eq(ONE_OF_QUALIFIER_VALUE_PROPERTY_QID))).thenReturn(constraintDefinitions);
setFetcher(fetcher);
scrutinize(update);
assertNoWarningRaised();
}
}