From 132af25b4af5d47a69cf1815b5b7e8e73ddca548 Mon Sep 17 00:00:00 2001 From: Antonin Delpeuch Date: Wed, 10 Jan 2018 10:42:21 +0000 Subject: [PATCH] Add single value scrutinizer --- .../wikidata/module/langs/translation-en.json | 4 ++ .../wikidata/qa/ConstraintFetcher.java | 23 +++++++++-- .../openrefine/wikidata/qa/EditInspector.java | 2 + .../scrutinizers/SingleValueScrutinizer.java | 39 +++++++++++++++++++ .../wikidata/qa/ConstraintFetcherTests.java | 12 ++++++ 5 files changed, 76 insertions(+), 4 deletions(-) create mode 100644 extensions/wikidata/src/org/openrefine/wikidata/qa/scrutinizers/SingleValueScrutinizer.java diff --git a/extensions/wikidata/module/langs/translation-en.json b/extensions/wikidata/module/langs/translation-en.json index f86c253b2..880011cd1 100644 --- a/extensions/wikidata/module/langs/translation-en.json +++ b/extensions/wikidata/module/langs/translation-en.json @@ -85,6 +85,10 @@ "disallowed-qualifiers": { "title": "Disallowed qualifiers.", "body": "Some of your qualifiers are incompatible with the statements that they qualify. Please check your schema." + }, + "single-valued-property-added-more-than-once": { + "title": "Single valued property added more than once.", + "body": "A property that is expected to be used at most once on each item has been added multiple times on the same item." } } } diff --git a/extensions/wikidata/src/org/openrefine/wikidata/qa/ConstraintFetcher.java b/extensions/wikidata/src/org/openrefine/wikidata/qa/ConstraintFetcher.java index b6788e5e5..d79bb18a6 100644 --- a/extensions/wikidata/src/org/openrefine/wikidata/qa/ConstraintFetcher.java +++ b/extensions/wikidata/src/org/openrefine/wikidata/qa/ConstraintFetcher.java @@ -42,16 +42,17 @@ public class ConstraintFetcher { public static String USED_ONLY_AS_REFERENCE_CONSTRAINT_QID = "Q21528959"; - // The following constraints still need to be implemented: - public static String ALLOWED_QUALIFIERS_CONSTRAINT_QID = "Q21510851"; public static String ALLOWED_QUALIFIERS_CONSTRAINT_PID = "P2306"; public static String MANDATORY_QUALIFIERS_CONSTRAINT_QID = "Q21510856"; public static String MANDATORY_QUALIFIERS_CONSTRAINT_PID = "P2306"; - public static String SINGLE_VALUE_CONSRAINT_QID = "Q19474404"; - public static String DISTINCT_VALUES_CONSRAINT_QID = "Q21502410"; + public static String SINGLE_VALUE_CONSTRAINT_QID = "Q19474404"; + public static String DISTINCT_VALUES_CONSTRAINT_QID = "Q21502410"; + + // The following constraints still need to be implemented: + public static String TYPE_CONSTRAINT_QID = "Q21503250"; @@ -136,6 +137,20 @@ public class ConstraintFetcher { return null; } + /** + * Is this property expected to have at most one value per item? + */ + public boolean hasSingleValue(PropertyIdValue pid) { + return getSingleConstraint(pid, SINGLE_VALUE_CONSTRAINT_QID) != null; + } + + /** + * Is this property expected to have distinct values? + */ + public boolean hasDistinctValues(PropertyIdValue pid) { + return getSingleConstraint(pid, DISTINCT_VALUES_CONSTRAINT_QID) != null; + } + /** * Returns a single constraint for a particular type and a property, or null * if there is no such constraint diff --git a/extensions/wikidata/src/org/openrefine/wikidata/qa/EditInspector.java b/extensions/wikidata/src/org/openrefine/wikidata/qa/EditInspector.java index 24a44a2d4..bc2ab001f 100644 --- a/extensions/wikidata/src/org/openrefine/wikidata/qa/EditInspector.java +++ b/extensions/wikidata/src/org/openrefine/wikidata/qa/EditInspector.java @@ -11,6 +11,7 @@ import org.openrefine.wikidata.qa.scrutinizers.NewItemScrutinizer; import org.openrefine.wikidata.qa.scrutinizers.QualifierCompatibilityScrutinizer; import org.openrefine.wikidata.qa.scrutinizers.RestrictedPositionScrutinizer; import org.openrefine.wikidata.qa.scrutinizers.SelfReferentialScrutinizer; +import org.openrefine.wikidata.qa.scrutinizers.SingleValueScrutinizer; import org.openrefine.wikidata.qa.scrutinizers.UnsourcedScrutinizer; import org.openrefine.wikidata.schema.ItemUpdate; @@ -35,6 +36,7 @@ public class EditInspector { register(new UnsourcedScrutinizer()); register(new RestrictedPositionScrutinizer()); register(new QualifierCompatibilityScrutinizer()); + register(new SingleValueScrutinizer()); } /** diff --git a/extensions/wikidata/src/org/openrefine/wikidata/qa/scrutinizers/SingleValueScrutinizer.java b/extensions/wikidata/src/org/openrefine/wikidata/qa/scrutinizers/SingleValueScrutinizer.java new file mode 100644 index 000000000..726008183 --- /dev/null +++ b/extensions/wikidata/src/org/openrefine/wikidata/qa/scrutinizers/SingleValueScrutinizer.java @@ -0,0 +1,39 @@ +package org.openrefine.wikidata.qa.scrutinizers; + +import java.util.HashSet; +import java.util.Set; + +import org.openrefine.wikidata.qa.ConstraintFetcher; +import org.openrefine.wikidata.schema.ItemUpdate; +import org.wikidata.wdtk.datamodel.interfaces.PropertyIdValue; +import org.wikidata.wdtk.datamodel.interfaces.Statement; + +/** + * For now this scrutinizer only checks for uniqueness at + * the item level (it ignores qualifiers and references). + * @author antonin + * + */ +public class SingleValueScrutinizer extends ItemEditScrutinizer { + + private ConstraintFetcher _fetcher; + + public SingleValueScrutinizer() { + _fetcher = new ConstraintFetcher(); + } + + @Override + public void scrutinize(ItemUpdate update) { + Set seenSingleProperties = new HashSet<>(); + + for(Statement statement : update.getAddedStatements()) { + PropertyIdValue pid = statement.getClaim().getMainSnak().getPropertyId(); + if (seenSingleProperties.contains(pid)) { + warning("single-valued-property-added-more-than-once"); + } else if (_fetcher.hasSingleValue(pid)) { + seenSingleProperties.add(pid); + } + } + } + +} diff --git a/extensions/wikidata/tests/src/org/openrefine/wikidata/qa/ConstraintFetcherTests.java b/extensions/wikidata/tests/src/org/openrefine/wikidata/qa/ConstraintFetcherTests.java index 612ee4921..7df9ebbb4 100644 --- a/extensions/wikidata/tests/src/org/openrefine/wikidata/qa/ConstraintFetcherTests.java +++ b/extensions/wikidata/tests/src/org/openrefine/wikidata/qa/ConstraintFetcherTests.java @@ -82,4 +82,16 @@ public class ConstraintFetcherTests { Assert.assertFalse(fetcher.mandatoryQualifiers(headOfGovernment).contains(endTime)); Assert.assertNull(fetcher.allowedQualifiers(startTime)); } + + @Test + public void testSingleValue() { + Assert.assertFalse(fetcher.hasSingleValue(headOfGovernment)); + Assert.assertTrue(fetcher.hasSingleValue(gridId)); + } + + @Test + public void testDistinctValues() { + Assert.assertFalse(fetcher.hasDistinctValues(partOf)); + Assert.assertTrue(fetcher.hasDistinctValues(gridId)); + } }