Remove EditGroups URL template from Wikibase schema (#3779)

* Remove EditGroups URL template from Wikibase schema

Instead it is fetched from the manifest and stored in operation metadata.

Closes #3656.

* Fix compatibility with older JDKs

* Remove unnecessary fallback in ManifestV1 constructor
This commit is contained in:
Antonin Delpeuch 2021-04-01 13:58:28 +02:00 committed by GitHub
parent 2de5929350
commit fa9d670d30
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 59 additions and 26 deletions

View File

@ -43,7 +43,6 @@ ImportSchemaDialog.launch = function() {
if (!schema.siteIri || !schema.mediaWikiApiEndpoint) { if (!schema.siteIri || !schema.mediaWikiApiEndpoint) {
schema.siteIri = WikidataManifestV1_0.wikibase.site_iri; schema.siteIri = WikidataManifestV1_0.wikibase.site_iri;
schema.mediaWikiApiEndpoint = WikidataManifestV1_0.mediawiki.api; schema.mediaWikiApiEndpoint = WikidataManifestV1_0.mediawiki.api;
schema.editGroupsURLSchema = WikidataManifestV1_0.editgroups.url_schema;
} }
} catch(e) { } catch(e) {
elmts.invalidSchema.text($.i18n('import-wikibase-schema/invalid-schema')); elmts.invalidSchema.text($.i18n('import-wikibase-schema/invalid-schema'));

View File

@ -53,7 +53,11 @@ PerformEditsDialog.launch = function(logged_in_username, max_severity) {
"wikidata", "wikidata",
"perform-wikibase-edits", "perform-wikibase-edits",
{}, {},
{ summary: elmts.editSummary.val(), maxlag: elmts.maxlag.val() }, {
summary: elmts.editSummary.val(),
maxlag: elmts.maxlag.val(),
editGroupsUrlSchema: WikibaseManager.getSelectedWikibaseEditGroupsURLSchema()
},
{ includeEngine: true, cellsChanged: true, columnStatsChanged: true }, { includeEngine: true, cellsChanged: true, columnStatsChanged: true },
{ onDone: function() { dismiss(); } } { onDone: function() { dismiss(); } }
); );

View File

@ -1279,8 +1279,7 @@ SchemaAlignment.getJSON = function() {
return { return {
itemDocuments: list, itemDocuments: list,
siteIri: WikibaseManager.getSelectedWikibaseSiteIri(), siteIri: WikibaseManager.getSelectedWikibaseSiteIri(),
mediaWikiApiEndpoint: WikibaseManager.getSelectedWikibaseApi(), mediaWikiApiEndpoint: WikibaseManager.getSelectedWikibaseApi()
editGroupsURLSchema: WikibaseManager.getSelectedWikibaseEditGroupsURLSchema()
}; };
} else { } else {
return null; return null;

View File

@ -40,7 +40,8 @@ public class PerformWikibaseEditsCommand extends EngineDependentCommand {
String summary = request.getParameter("summary"); String summary = request.getParameter("summary");
String maxlagStr = request.getParameter("maxlag"); String maxlagStr = request.getParameter("maxlag");
int maxlag = maxlagStr == null ? 5 : Integer.parseInt(maxlagStr); int maxlag = maxlagStr == null ? 5 : Integer.parseInt(maxlagStr);
return new PerformWikibaseEditsOperation(engineConfig, summary, maxlag); String editGroupsUrlSchema = request.getParameter("editGroupsUrlSchema");
return new PerformWikibaseEditsOperation(engineConfig, summary, maxlag, editGroupsUrlSchema);
} }
} }

View File

@ -20,4 +20,5 @@ public interface Manifest {
String getConstraintsRelatedId(String name); String getConstraintsRelatedId(String name);
String getEditGroupsUrlSchema();
} }

View File

@ -6,6 +6,8 @@ import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
import org.wikidata.wdtk.wikibaseapi.ApiConnection;
public class ManifestV1 implements Manifest { public class ManifestV1 implements Manifest {
private String version; private String version;
@ -16,6 +18,7 @@ public class ManifestV1 implements Manifest {
private String subclassOfPid; private String subclassOfPid;
private String mediaWikiApiEndpoint; private String mediaWikiApiEndpoint;
private String reconServiceEndpoint; private String reconServiceEndpoint;
private String editGroupsUrlSchema;
private Map<String, String> constraintsRelatedIdMap = new HashMap<>(); private Map<String, String> constraintsRelatedIdMap = new HashMap<>();
@ -44,6 +47,9 @@ public class ManifestV1 implements Manifest {
JsonNode reconciliation = manifest.path("reconciliation"); JsonNode reconciliation = manifest.path("reconciliation");
reconServiceEndpoint = reconciliation.path("endpoint").textValue(); reconServiceEndpoint = reconciliation.path("endpoint").textValue();
JsonNode editGroups = manifest.path("editgroups");
editGroupsUrlSchema = editGroups.path("url_schema").textValue();
} }
@Override @Override
@ -91,4 +97,9 @@ public class ManifestV1 implements Manifest {
return constraintsRelatedIdMap.get(name); return constraintsRelatedIdMap.get(name);
} }
@Override
public String getEditGroupsUrlSchema() {
return editGroupsUrlSchema;
}
} }

View File

@ -65,12 +65,19 @@ public class PerformWikibaseEditsOperation extends EngineDependentOperation {
static final Logger logger = LoggerFactory.getLogger(PerformWikibaseEditsOperation.class); static final Logger logger = LoggerFactory.getLogger(PerformWikibaseEditsOperation.class);
// only used for backwards compatibility, these things are configurable through
// the manifest now.
static final private String WIKIDATA_EDITGROUPS_URL_SCHEMA = "([[:toollabs:editgroups/b/OR/${batch_id}|details]])";
@JsonProperty("summary") @JsonProperty("summary")
private String summary; private String summary;
@JsonProperty("maxlag") @JsonProperty("maxlag")
private int maxlag; private int maxlag;
@JsonProperty("editGroupsUrlSchema")
private String editGroupsUrlSchema;
@JsonCreator @JsonCreator
public PerformWikibaseEditsOperation( public PerformWikibaseEditsOperation(
@JsonProperty("engineConfig") @JsonProperty("engineConfig")
@ -78,7 +85,9 @@ public class PerformWikibaseEditsOperation extends EngineDependentOperation {
@JsonProperty("summary") @JsonProperty("summary")
String summary, String summary,
@JsonProperty("maxlag") @JsonProperty("maxlag")
Integer maxlag) { Integer maxlag,
@JsonProperty("editGroupsUrlSchema")
String editGroupsUrlSchema) {
super(engineConfig); super(engineConfig);
Validate.notNull(summary, "An edit summary must be provided."); Validate.notNull(summary, "An edit summary must be provided.");
Validate.notEmpty(summary, "An edit summary must be provided."); Validate.notEmpty(summary, "An edit summary must be provided.");
@ -89,6 +98,8 @@ public class PerformWikibaseEditsOperation extends EngineDependentOperation {
maxlag = 5; maxlag = 5;
} }
this.maxlag = maxlag; this.maxlag = maxlag;
// a fallback to Wikidata for backwards compatibility is done later on
this.editGroupsUrlSchema = editGroupsUrlSchema;
} }
@Override @Override
@ -99,7 +110,12 @@ public class PerformWikibaseEditsOperation extends EngineDependentOperation {
@Override @Override
public Process createProcess(Project project, Properties options) public Process createProcess(Project project, Properties options)
throws Exception { throws Exception {
return new PerformEditsProcess(project, createEngine(project), getBriefDescription(project), summary); return new PerformEditsProcess(
project,
createEngine(project),
getBriefDescription(project),
editGroupsUrlSchema,
summary);
} }
static public class PerformWikibaseEditsChange implements Change { static public class PerformWikibaseEditsChange implements Change {
@ -158,11 +174,12 @@ public class PerformWikibaseEditsOperation extends EngineDependentOperation {
protected Project _project; protected Project _project;
protected Engine _engine; protected Engine _engine;
protected WikibaseSchema _schema; protected WikibaseSchema _schema;
protected String _editGroupsUrlSchema;
protected String _summary; protected String _summary;
protected List<String> _tags; protected List<String> _tags;
protected final long _historyEntryID; protected final long _historyEntryID;
protected PerformEditsProcess(Project project, Engine engine, String description, String summary) { protected PerformEditsProcess(Project project, Engine engine, String description, String editGroupsUrlSchema, String summary) {
super(description); super(description);
this._project = project; this._project = project;
this._engine = engine; this._engine = engine;
@ -176,6 +193,13 @@ public class PerformWikibaseEditsOperation extends EngineDependentOperation {
} }
this._tags = Arrays.asList(tag); this._tags = Arrays.asList(tag);
this._historyEntryID = HistoryEntry.allocateID(); this._historyEntryID = HistoryEntry.allocateID();
if (editGroupsUrlSchema == null &&
ApiConnection.URL_WIKIDATA_API.equals(_schema.getMediaWikiApiEndpoint())) {
// For backward compatibility, if no editGroups schema is provided
// and we edit Wikidata, then add Wikidata's editGroups schema
editGroupsUrlSchema = WIKIDATA_EDITGROUPS_URL_SCHEMA;
}
this._editGroupsUrlSchema = editGroupsUrlSchema;
} }
@Override @Override
@ -193,7 +217,7 @@ public class PerformWikibaseEditsOperation extends EngineDependentOperation {
WikibaseDataEditor wbde = new WikibaseDataEditor(connection, _schema.getSiteIri()); WikibaseDataEditor wbde = new WikibaseDataEditor(connection, _schema.getSiteIri());
String summary; String summary;
if (StringUtils.isBlank(_schema.getEditGroupsURLSchema())) { if (StringUtils.isBlank(_editGroupsUrlSchema)) {
summary = _summary; summary = _summary;
} else { } else {
// Generate batch id // Generate batch id
@ -203,7 +227,7 @@ public class PerformWikibaseEditsOperation extends EngineDependentOperation {
// from the user-supplied ones, we replace these separators by similar unicode characters to // from the user-supplied ones, we replace these separators by similar unicode characters to
// make sure they can be told apart. // make sure they can be told apart.
String summaryWithoutCommas = _summary.replaceAll(", "," ").replaceAll(": ","։ "); String summaryWithoutCommas = _summary.replaceAll(", "," ").replaceAll(": ","։ ");
summary = summaryWithoutCommas + " " + _schema.getEditGroupsURLSchema().replace("${batch_id}", batchId); summary = summaryWithoutCommas + " " + _editGroupsUrlSchema.replace("${batch_id}", batchId);
} }
// Evaluate the schema // Evaluate the schema

View File

@ -28,12 +28,12 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.openrefine.wikidata.qa.QAWarningStore; import org.openrefine.wikidata.qa.QAWarningStore;
import org.openrefine.wikidata.schema.exceptions.SkipSchemaExpressionException; import org.openrefine.wikidata.schema.exceptions.SkipSchemaExpressionException;
import org.openrefine.wikidata.updates.ItemUpdate; import org.openrefine.wikidata.updates.ItemUpdate;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.wikidata.wdtk.wikibaseapi.ApiConnection;
import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@ -67,9 +67,6 @@ public class WikibaseSchema implements OverlayModel {
@JsonProperty("mediaWikiApiEndpoint") @JsonProperty("mediaWikiApiEndpoint")
protected String mediaWikiApiEndpoint; protected String mediaWikiApiEndpoint;
@JsonIgnore
protected String editGroupsURLSchema;
/** /**
* Constructor. * Constructor.
*/ */
@ -83,12 +80,10 @@ public class WikibaseSchema implements OverlayModel {
@JsonCreator @JsonCreator
public WikibaseSchema(@JsonProperty("itemDocuments") List<WbItemDocumentExpr> exprs, public WikibaseSchema(@JsonProperty("itemDocuments") List<WbItemDocumentExpr> exprs,
@JsonProperty("siteIri") String siteIri, @JsonProperty("siteIri") String siteIri,
@JsonProperty("mediaWikiApiEndpoint") String mediaWikiApiEndpoint, @JsonProperty("mediaWikiApiEndpoint") String mediaWikiApiEndpoint) {
@JsonProperty("editGroupsURLSchema") String editGroupsURLSchema) {
this.itemDocumentExprs = exprs; this.itemDocumentExprs = exprs;
this.siteIri = siteIri; this.siteIri = siteIri;
this.mediaWikiApiEndpoint = mediaWikiApiEndpoint; this.mediaWikiApiEndpoint = mediaWikiApiEndpoint != null ? mediaWikiApiEndpoint : ApiConnection.URL_WIKIDATA_API;
this.editGroupsURLSchema = editGroupsURLSchema;
} }
/** /**
@ -112,11 +107,6 @@ public class WikibaseSchema implements OverlayModel {
return mediaWikiApiEndpoint; return mediaWikiApiEndpoint;
} }
@JsonIgnore
public String getEditGroupsURLSchema() {
return editGroupsURLSchema;
}
/** /**
* Evaluates all item documents in a particular expression context. This * Evaluates all item documents in a particular expression context. This
* specifies, among others, a row where the values of the variables will be * specifies, among others, a row where the values of the variables will be

View File

@ -3,6 +3,7 @@
"description": "Perform Wikibase edits", "description": "Perform Wikibase edits",
"summary": "test null edit", "summary": "test null edit",
"maxlag": 5, "maxlag": 5,
"editGroupsUrlSchema": "([[:toollabs:editgroups/b/OR/${batch_id}|details]])",
"engineConfig": { "engineConfig": {
"mode": "row-based", "mode": "row-based",
"facets": [] "facets": []

View File

@ -23,6 +23,7 @@ public class ManifestV1Test {
assertEquals("https://wdreconcile.toolforge.org/${lang}/api", manifest.getReconServiceEndpoint()); assertEquals("https://wdreconcile.toolforge.org/${lang}/api", manifest.getReconServiceEndpoint());
assertEquals("P2302", manifest.getConstraintsRelatedId("property_constraint_pid")); assertEquals("P2302", manifest.getConstraintsRelatedId("property_constraint_pid"));
assertEquals("Q19474404", manifest.getConstraintsRelatedId("single_value_constraint_qid")); assertEquals("Q19474404", manifest.getConstraintsRelatedId("single_value_constraint_qid"));
assertEquals("([[:toollabs:editgroups/b/OR/${batch_id}|details]])", manifest.getEditGroupsUrlSchema());
} }
@Test @Test

View File

@ -58,7 +58,7 @@ public class PerformWikibaseEditsOperationTest extends OperationTest {
@Test(expectedExceptions=IllegalArgumentException.class) @Test(expectedExceptions=IllegalArgumentException.class)
public void testConstructor() { public void testConstructor() {
new PerformWikibaseEditsOperation(EngineConfig.reconstruct("{}"), "", 5); new PerformWikibaseEditsOperation(EngineConfig.reconstruct("{}"), "", 5, "");
} }
@Test @Test

View File

@ -23,7 +23,6 @@
******************************************************************************/ ******************************************************************************/
package org.openrefine.wikidata.schema; package org.openrefine.wikidata.schema;
import org.testng.Assert;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import java.io.IOException; import java.io.IOException;
@ -48,6 +47,7 @@ import org.wikidata.wdtk.datamodel.interfaces.Statement;
import org.wikidata.wdtk.datamodel.interfaces.StatementRank; import org.wikidata.wdtk.datamodel.interfaces.StatementRank;
import org.wikidata.wdtk.datamodel.interfaces.StringValue; import org.wikidata.wdtk.datamodel.interfaces.StringValue;
import org.wikidata.wdtk.datamodel.interfaces.TimeValue; import org.wikidata.wdtk.datamodel.interfaces.TimeValue;
import org.wikidata.wdtk.wikibaseapi.ApiConnection;
import com.google.refine.browsing.Engine; import com.google.refine.browsing.Engine;
import com.google.refine.browsing.EngineConfig; import com.google.refine.browsing.EngineConfig;
@ -106,7 +106,9 @@ public class WikibaseSchemaTest extends WikidataRefineTest {
// this json file was generated by an earlier version of the software // this json file was generated by an earlier version of the software
// it contains extra "type" fields that are now ignored. // it contains extra "type" fields that are now ignored.
String serialized = TestingData.jsonFromFile("schema/roarmap.json"); String serialized = TestingData.jsonFromFile("schema/roarmap.json");
WikibaseSchema.reconstruct(serialized); WikibaseSchema schema = WikibaseSchema.reconstruct(serialized);
// Check that we fall back on Wikidata if no API endpoint was supplied
assertEquals(schema.getMediaWikiApiEndpoint(), ApiConnection.URL_WIKIDATA_API);
} }
@Test @Test