diff --git a/extensions/wikidata/module/langs/translation-en.json b/extensions/wikidata/module/langs/translation-en.json index 89e3f7dc5..38809026e 100644 --- a/extensions/wikidata/module/langs/translation-en.json +++ b/extensions/wikidata/module/langs/translation-en.json @@ -41,7 +41,8 @@ "reset-button": "Reset", "save-button": "Save", "close-button": "Close", - "unsaved-changes": "There are unsaved changes. Close anyway?" + "unsaved-changes": "There are unsaved changes. Close anyway?", + "incomplete-schema-could-not-be-saved": "Your schema is incomplete so it cannot be saved yet." }, "wikidata-preview": { "new-id": "new item" diff --git a/extensions/wikidata/module/scripts/dialogs/schema-alignment-dialog.js b/extensions/wikidata/module/scripts/dialogs/schema-alignment-dialog.js index 645184a8f..d3149b203 100644 --- a/extensions/wikidata/module/scripts/dialogs/schema-alignment-dialog.js +++ b/extensions/wikidata/module/scripts/dialogs/schema-alignment-dialog.js @@ -84,7 +84,10 @@ SchemaAlignmentDialog._save = function(onDone) { self._hasUnsavedChanges = false; if (onDone) onDone(); - } + }, + onError: function(e) { + alert($.i18n._('wikidata-schema')["incomplete-schema-could-not-be-saved"]); + }, } ); }; diff --git a/extensions/wikidata/src/org/openrefine/wikidata/commands/CommandUtilities.java b/extensions/wikidata/src/org/openrefine/wikidata/commands/CommandUtilities.java new file mode 100644 index 000000000..74f1cbdfd --- /dev/null +++ b/extensions/wikidata/src/org/openrefine/wikidata/commands/CommandUtilities.java @@ -0,0 +1,32 @@ +package org.openrefine.wikidata.commands; + +import java.io.IOException; +import java.io.Writer; + +import javax.servlet.http.HttpServletResponse; + +import org.json.JSONWriter; + +public class CommandUtilities { + + /** + * Helper introduced to ease returning error messages from a response. Curiously + * this is not part of {@link Command}: the respond method uses the "status" JSON + * key instead of the "code" one required by the JS code. + * + * @param response + * @param errorMessage + * @throws IOException + */ + public static void respondError(HttpServletResponse response, String errorMessage) + throws IOException { + Writer w = response.getWriter(); + JSONWriter writer = new JSONWriter(w); + writer.object(); + writer.key("code"); writer.value("error"); + writer.key("message"); writer.value(errorMessage); + writer.endObject(); + w.flush(); + w.close(); + } +} diff --git a/extensions/wikidata/src/org/openrefine/wikidata/commands/PreviewWikibaseSchemaCommand.java b/extensions/wikidata/src/org/openrefine/wikidata/commands/PreviewWikibaseSchemaCommand.java index ca71df77a..c27b37349 100644 --- a/extensions/wikidata/src/org/openrefine/wikidata/commands/PreviewWikibaseSchemaCommand.java +++ b/extensions/wikidata/src/org/openrefine/wikidata/commands/PreviewWikibaseSchemaCommand.java @@ -42,6 +42,7 @@ import org.openrefine.wikidata.qa.QAWarningStore; import org.openrefine.wikidata.schema.WikibaseSchema; import org.openrefine.wikidata.updates.ItemUpdate; import org.openrefine.wikidata.utils.FirstLinesExtractor; +import static org.openrefine.wikidata.commands.CommandUtilities.respondError; import com.google.refine.browsing.Engine; import com.google.refine.commands.Command; @@ -66,14 +67,14 @@ public class PreviewWikibaseSchemaCommand extends Command { try { schema = WikibaseSchema.reconstruct(jsonString); } catch (JSONException e) { - respond(response, "error", "Wikibase schema could not be parsed."); + respondError(response, e.toString()); return; } } else { schema = (WikibaseSchema) project.overlayModels.get("wikibaseSchema"); } if (schema == null) { - respond(response, "error", "No Wikibase schema provided."); + respondError(response, "No schema provided."); return; } diff --git a/extensions/wikidata/src/org/openrefine/wikidata/commands/SaveWikibaseSchemaCommand.java b/extensions/wikidata/src/org/openrefine/wikidata/commands/SaveWikibaseSchemaCommand.java index 0fd70fa8e..3abf66404 100644 --- a/extensions/wikidata/src/org/openrefine/wikidata/commands/SaveWikibaseSchemaCommand.java +++ b/extensions/wikidata/src/org/openrefine/wikidata/commands/SaveWikibaseSchemaCommand.java @@ -34,6 +34,7 @@ import org.json.JSONException; import org.json.JSONObject; import org.openrefine.wikidata.operations.SaveWikibaseSchemaOperation; import org.openrefine.wikidata.schema.WikibaseSchema; +import static org.openrefine.wikidata.commands.CommandUtilities.respondError; import com.google.refine.commands.Command; import com.google.refine.model.AbstractOperation; @@ -52,7 +53,7 @@ public class SaveWikibaseSchemaCommand extends Command { String jsonString = request.getParameter("schema"); if (jsonString == null) { - respond(response, "error", "No Wikibase schema provided."); + respondError(response, "No Wikibase schema provided."); return; } @@ -65,8 +66,12 @@ public class SaveWikibaseSchemaCommand extends Command { performProcessAndRespond(request, response, project, process); } catch (JSONException e) { - respond(response, "error", "Wikibase schema could not be parsed."); + // We do not use respondException here because this is an expected + // exception which happens every time a user tries to save an incomplete + // schema - the exception should not be logged. + respondError(response, "Invalid Wikibase schema provided."); } catch (Exception e) { + // This is an unexpected exception, so we log it. respondException(response, e); } } diff --git a/extensions/wikidata/src/org/openrefine/wikidata/schema/WikibaseSchema.java b/extensions/wikidata/src/org/openrefine/wikidata/schema/WikibaseSchema.java index 4eb708037..6c5d98c45 100644 --- a/extensions/wikidata/src/org/openrefine/wikidata/schema/WikibaseSchema.java +++ b/extensions/wikidata/src/org/openrefine/wikidata/schema/WikibaseSchema.java @@ -186,7 +186,7 @@ public class WikibaseSchema implements OverlayModel { return reconstruct(o.toString()); } - static public WikibaseSchema reconstruct(String json) { + static public WikibaseSchema reconstruct(String json) throws JSONException { ObjectMapper mapper = new ObjectMapper(); try { return mapper.readValue(json, WikibaseSchema.class); diff --git a/extensions/wikidata/tests/src/org/openrefine/wikidata/commands/SaveWikibaseSchemaCommandTest.java b/extensions/wikidata/tests/src/org/openrefine/wikidata/commands/SaveWikibaseSchemaCommandTest.java index 855108db3..081e44e85 100644 --- a/extensions/wikidata/tests/src/org/openrefine/wikidata/commands/SaveWikibaseSchemaCommandTest.java +++ b/extensions/wikidata/tests/src/org/openrefine/wikidata/commands/SaveWikibaseSchemaCommandTest.java @@ -51,4 +51,15 @@ public class SaveWikibaseSchemaCommandTest extends SchemaCommandTest { assertTrue(writer.toString().contains("\"ok\"")); } + + @Test + public void testInvalidSchema() throws ServletException, IOException { + String schemaJson = "{\"itemDocuments\":[{\"statementGroups\":[{\"statements\":[]}]," + +"\"nameDescs\":[]}],\"wikibasePrefix\":\"http://www.wikidata.org/entity/\"}"; + + when(request.getParameter("schema")).thenReturn(schemaJson); + command.doPost(request, response); + + assertTrue(writer.toString().contains("\"error\"")); + } } diff --git a/extensions/wikidata/tests/src/org/openrefine/wikidata/schema/WbItemVariableTest.java b/extensions/wikidata/tests/src/org/openrefine/wikidata/schema/WbItemVariableTest.java index 1412ad613..de19a8aff 100644 --- a/extensions/wikidata/tests/src/org/openrefine/wikidata/schema/WbItemVariableTest.java +++ b/extensions/wikidata/tests/src/org/openrefine/wikidata/schema/WbItemVariableTest.java @@ -78,4 +78,6 @@ public class WbItemVariableTest extends WbVariableTest { JacksonSerializationTest.canonicalSerialization(WbExpression.class, variable, "{\"type\":\"wbitemvariable\",\"columnName\":\"column A\"}"); } + + // TODO: test with column reconciled against different identifier space } diff --git a/extensions/wikidata/tests/src/org/openrefine/wikidata/schema/WikibaseSchemaTest.java b/extensions/wikidata/tests/src/org/openrefine/wikidata/schema/WikibaseSchemaTest.java index 0e62a57f3..d78aa28b4 100644 --- a/extensions/wikidata/tests/src/org/openrefine/wikidata/schema/WikibaseSchemaTest.java +++ b/extensions/wikidata/tests/src/org/openrefine/wikidata/schema/WikibaseSchemaTest.java @@ -52,6 +52,8 @@ import org.wikidata.wdtk.datamodel.interfaces.StatementRank; import org.wikidata.wdtk.datamodel.interfaces.StringValue; import org.wikidata.wdtk.datamodel.interfaces.TimeValue; +import com.fasterxml.jackson.databind.exc.InvalidDefinitionException; + import com.google.refine.browsing.Engine; import com.google.refine.model.Project; import com.google.refine.tests.RefineTest; @@ -132,6 +134,13 @@ public class WikibaseSchemaTest extends RefineTest { expected.add(update2); assertEquals(expected, updates); } + + @Test(expectedExceptions = JSONException.class) + public void testDeserializeEmpty() throws JSONException { + String schemaJson = "{\"itemDocuments\":[{\"statementGroups\":[{\"statements\":[]}]," + +"\"nameDescs\":[]}],\"wikibasePrefix\":\"http://www.wikidata.org/entity/\"}"; + WikibaseSchema.reconstruct(schemaJson); + } @Test public void testEvaluateRespectsFacets()