Merge pull request #1655 from OpenRefine/new-scope-constraint
Migrate to new scope constraint format
This commit is contained in:
commit
b3ee80d504
@ -121,29 +121,17 @@
|
||||
"title": "Statements without references.",
|
||||
"body": "Most statements should have references. You can add them easily in the schema."
|
||||
},
|
||||
"property-restricted-to-reference-found-in-mainsnak": {
|
||||
"property-found-in-mainsnak": {
|
||||
"title": "{property_entity} used as statement.",
|
||||
"body": "You are using {property_entity} in a statement but it is designed to be used in references only."
|
||||
"body": "You are using {property_entity} as a main statement but it is not designed for that."
|
||||
},
|
||||
"property-restricted-to-reference-found-in-qualifier": {
|
||||
"property-found-in-qualifier": {
|
||||
"title": "{property_entity} used as qualifier.",
|
||||
"body": "You are using in {property_entity} in a qualifier but it is designed to be used in references only."
|
||||
"body": "You are using in {property_entity} as a qualifier but it is not designed for that ."
|
||||
},
|
||||
"property-restricted-to-qualifier-found-in-mainsnak": {
|
||||
"title": "{property_entity} used as statement.",
|
||||
"body": "You are using {property_entity} in a statement but it is designed to be used in qualifiers only."
|
||||
},
|
||||
"property-restricted-to-qualifier-found-in-reference": {
|
||||
"property-found-in-reference": {
|
||||
"title": "{property_entity} used as reference.",
|
||||
"body": "You are using {property_entity} in a reference but it is designed to be used in qualifiers only."
|
||||
},
|
||||
"property-restricted-to-mainsnak-found-in-qualifier": {
|
||||
"title": "{property_entity} used as qualifier.",
|
||||
"body": "You are using {property_entity} in a qualifier but it is designed to be used as a statement only."
|
||||
},
|
||||
"property-restricted-to-mainsnak-found-in-reference": {
|
||||
"title": "{property_entity} used as reference.",
|
||||
"body": "You are using {property_entity} in a reference but it is designed to be used as a statement only."
|
||||
"body": "You are using {property_entity} in a reference but it is not designed for that."
|
||||
},
|
||||
"missing-mandatory-qualifiers": {
|
||||
"title": "{statement_property_entity} is missing a {missing_property_entity} qualifier.",
|
||||
|
@ -62,19 +62,19 @@ public interface ConstraintFetcher {
|
||||
boolean isSymmetric(PropertyIdValue pid);
|
||||
|
||||
/**
|
||||
* Is this property for values only?
|
||||
* Can this property be used as values?
|
||||
*/
|
||||
boolean isForValuesOnly(PropertyIdValue pid);
|
||||
boolean allowedAsValue(PropertyIdValue pid);
|
||||
|
||||
/**
|
||||
* Is this property for qualifiers only?
|
||||
* Can this property be used as qualifiers?
|
||||
*/
|
||||
boolean isForQualifiersOnly(PropertyIdValue pid);
|
||||
boolean allowedAsQualifier(PropertyIdValue pid);
|
||||
|
||||
/**
|
||||
* Is this property for references only?
|
||||
* Can this property be used in a reference?
|
||||
*/
|
||||
boolean isForReferencesOnly(PropertyIdValue pid);
|
||||
boolean allowedAsReference(PropertyIdValue pid);
|
||||
|
||||
/**
|
||||
* Get the list of allowed qualifiers (as property ids) for this property (null
|
||||
|
@ -60,7 +60,11 @@ public class WikidataConstraintFetcher implements ConstraintFetcher {
|
||||
public static String INVERSE_PROPERTY_PID = "P2306";
|
||||
public static String SYMMETRIC_CONSTRAINT_QID = "Q21510862";
|
||||
|
||||
public static String USED_ONLY_AS_VALUES_CONSTRAINT_QID = "Q21528958";
|
||||
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";
|
||||
|
||||
public static String USED_ONLY_AS_QUALIFIER_CONSTRAINT_QID = "Q21510863";
|
||||
|
||||
@ -123,18 +127,36 @@ public class WikidataConstraintFetcher implements ConstraintFetcher {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isForValuesOnly(PropertyIdValue pid) {
|
||||
return getSingleConstraint(pid, USED_ONLY_AS_VALUES_CONSTRAINT_QID) != null;
|
||||
public boolean allowedAsValue(PropertyIdValue pid) {
|
||||
List<SnakGroup> specs = getSingleConstraint(pid, SCOPE_CONSTRAINT_QID);
|
||||
|
||||
if (specs != null) {
|
||||
ItemIdValue target = Datamodel.makeWikidataItemIdValue(SCOPE_CONSTRAINT_VALUE_QID);
|
||||
return findValues(specs, SCOPE_CONSTRAINT_PID).contains(target);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isForQualifiersOnly(PropertyIdValue pid) {
|
||||
return getSingleConstraint(pid, USED_ONLY_AS_QUALIFIER_CONSTRAINT_QID) != null;
|
||||
public boolean allowedAsQualifier(PropertyIdValue pid) {
|
||||
List<SnakGroup> specs = getSingleConstraint(pid, SCOPE_CONSTRAINT_QID);
|
||||
|
||||
if (specs != null) {
|
||||
ItemIdValue target = Datamodel.makeWikidataItemIdValue(SCOPE_CONSTRAINT_QUALIFIER_QID);
|
||||
return findValues(specs, SCOPE_CONSTRAINT_PID).contains(target);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isForReferencesOnly(PropertyIdValue pid) {
|
||||
return getSingleConstraint(pid, USED_ONLY_AS_REFERENCE_CONSTRAINT_QID) != null;
|
||||
public boolean allowedAsReference(PropertyIdValue pid) {
|
||||
List<SnakGroup> specs = getSingleConstraint(pid, SCOPE_CONSTRAINT_QID);
|
||||
|
||||
if (specs != null) {
|
||||
ItemIdValue target = Datamodel.makeWikidataItemIdValue(SCOPE_CONSTRAINT_REFERENCE_QID);
|
||||
return findValues(specs, SCOPE_CONSTRAINT_PID).contains(target);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -23,11 +23,7 @@
|
||||
******************************************************************************/
|
||||
package org.openrefine.wikidata.qa.scrutinizers;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.openrefine.wikidata.qa.QAWarning;
|
||||
import org.wikidata.wdtk.datamodel.interfaces.EntityIdValue;
|
||||
@ -42,40 +38,6 @@ public class RestrictedPositionScrutinizer extends StatementScrutinizer {
|
||||
MAINSNAK, QUALIFIER, REFERENCE
|
||||
}
|
||||
|
||||
private Map<PropertyIdValue, SnakPosition> _restrictedPids;
|
||||
private Set<PropertyIdValue> _unrestrictedPids;
|
||||
|
||||
public RestrictedPositionScrutinizer() {
|
||||
_restrictedPids = new HashMap<>();
|
||||
_unrestrictedPids = new HashSet<>();
|
||||
}
|
||||
|
||||
SnakPosition positionRestriction(PropertyIdValue pid) {
|
||||
if (_unrestrictedPids.contains(pid)) {
|
||||
return null;
|
||||
}
|
||||
SnakPosition restriction = _restrictedPids.get(pid);
|
||||
if (restriction != null) {
|
||||
return restriction;
|
||||
} else {
|
||||
if (_fetcher.isForValuesOnly(pid)) {
|
||||
restriction = SnakPosition.MAINSNAK;
|
||||
} else if (_fetcher.isForQualifiersOnly(pid)) {
|
||||
restriction = SnakPosition.QUALIFIER;
|
||||
} else if (_fetcher.isForReferencesOnly(pid)) {
|
||||
restriction = SnakPosition.REFERENCE;
|
||||
}
|
||||
|
||||
// Cache these results:
|
||||
if (restriction != null) {
|
||||
_restrictedPids.put(pid, restriction);
|
||||
} else {
|
||||
_unrestrictedPids.add(pid);
|
||||
}
|
||||
return restriction;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void scrutinize(Statement statement, EntityIdValue entityId, boolean added) {
|
||||
// Skip the main snak
|
||||
@ -99,16 +61,25 @@ public class RestrictedPositionScrutinizer extends StatementScrutinizer {
|
||||
}
|
||||
|
||||
public void scrutinize(Snak snak, EntityIdValue entityId, SnakPosition position, boolean added) {
|
||||
SnakPosition restriction = positionRestriction(snak.getPropertyId());
|
||||
if (restriction != null && position != restriction) {
|
||||
if (!positionAllowed(snak.getPropertyId(), position)) {
|
||||
String positionStr = position.toString().toLowerCase();
|
||||
String restrictionStr = restriction.toString().toLowerCase();
|
||||
|
||||
QAWarning issue = new QAWarning("property-restricted-to-" + restrictionStr + "-found-in-" + positionStr,
|
||||
QAWarning issue = new QAWarning("property-found-in-" + positionStr,
|
||||
snak.getPropertyId().getId(), QAWarning.Severity.IMPORTANT, 1);
|
||||
issue.setProperty("property_entity", snak.getPropertyId());
|
||||
addIssue(issue);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -77,18 +77,18 @@ public class MockConstraintFetcher implements ConstraintFetcher {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isForValuesOnly(PropertyIdValue pid) {
|
||||
return mainSnakPid.equals(pid);
|
||||
public boolean allowedAsValue(PropertyIdValue pid) {
|
||||
return (!qualifierPid.equals(pid) && !referencePid.equals(pid));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isForQualifiersOnly(PropertyIdValue pid) {
|
||||
return qualifierPid.equals(pid);
|
||||
public boolean allowedAsQualifier(PropertyIdValue pid) {
|
||||
return (!mainSnakPid.equals(pid) && !referencePid.equals(pid));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isForReferencesOnly(PropertyIdValue pid) {
|
||||
return referencePid.equals(pid);
|
||||
public boolean allowedAsReference(PropertyIdValue pid) {
|
||||
return (!mainSnakPid.equals(pid) && !qualifierPid.equals(pid));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -39,10 +39,7 @@ public class WikidataConstraintFetcherTests {
|
||||
private PropertyIdValue endTime;
|
||||
private PropertyIdValue instanceOf;
|
||||
private PropertyIdValue gridId;
|
||||
private PropertyIdValue hasPart;
|
||||
private PropertyIdValue partOf;
|
||||
private PropertyIdValue referenceURL;
|
||||
private PropertyIdValue reasonForDeprecation;
|
||||
private PropertyIdValue mother;
|
||||
private PropertyIdValue child;
|
||||
|
||||
@ -53,10 +50,7 @@ public class WikidataConstraintFetcherTests {
|
||||
endTime = Datamodel.makeWikidataPropertyIdValue("P582");
|
||||
instanceOf = Datamodel.makeWikidataPropertyIdValue("P31");
|
||||
gridId = Datamodel.makeWikidataPropertyIdValue("P2427");
|
||||
hasPart = Datamodel.makeWikidataPropertyIdValue("P527");
|
||||
partOf = Datamodel.makeWikidataPropertyIdValue("P361");
|
||||
referenceURL = Datamodel.makeWikidataPropertyIdValue("P854");
|
||||
reasonForDeprecation = Datamodel.makeWikidataPropertyIdValue("P2241");
|
||||
mother = Datamodel.makeWikidataPropertyIdValue("P25");
|
||||
child = Datamodel.makeWikidataPropertyIdValue("P40");
|
||||
}
|
||||
@ -77,24 +71,6 @@ public class WikidataConstraintFetcherTests {
|
||||
Assert.assertEquals(fetcher.getInversePid(mother), child);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnlyReferences() {
|
||||
Assert.assertTrue(fetcher.isForReferencesOnly(referenceURL));
|
||||
Assert.assertFalse(fetcher.isForReferencesOnly(reasonForDeprecation));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnlyQualifiers() {
|
||||
Assert.assertTrue(fetcher.isForQualifiersOnly(reasonForDeprecation));
|
||||
Assert.assertFalse(fetcher.isForQualifiersOnly(headOfGovernment));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnlyValues() {
|
||||
Assert.assertTrue(fetcher.isForValuesOnly(headOfGovernment));
|
||||
Assert.assertFalse(fetcher.isForValuesOnly(referenceURL));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllowedQualifiers() {
|
||||
Assert.assertTrue(fetcher.allowedQualifiers(headOfGovernment).contains(startTime));
|
||||
|
@ -48,7 +48,7 @@ public class RestrictedPositionScrutinizerTest extends SnakScrutinizerTest {
|
||||
@Test
|
||||
public void testTriggerMainSnak() {
|
||||
scrutinize(TestingData.generateStatement(qid, MockConstraintFetcher.qualifierPid, qid));
|
||||
assertWarningsRaised("property-restricted-to-qualifier-found-in-mainsnak");
|
||||
assertWarningsRaised("property-found-in-mainsnak");
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -72,7 +72,7 @@ public class RestrictedPositionScrutinizerTest extends SnakScrutinizerTest {
|
||||
TestingData.generateStatement(qid, MockConstraintFetcher.mainSnakPid, qid).getClaim(),
|
||||
Collections.singletonList(Datamodel.makeReference(snakGroups)), StatementRank.NORMAL, "");
|
||||
scrutinize(statement);
|
||||
assertWarningsRaised("property-restricted-to-mainsnak-found-in-reference");
|
||||
assertWarningsRaised("property-found-in-reference");
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user