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:
parent
fe275ae634
commit
2bf493a498
@ -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.",
|
||||||
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user