From 81a18777cbb9d9bde41b1281c32a2dca498164f8 Mon Sep 17 00:00:00 2001 From: Antonin Delpeuch Date: Tue, 20 Mar 2018 16:20:00 +0000 Subject: [PATCH] Replace QS preview by visual preview of the edits --- .../wikidata/module/MOD-INF/controller.js | 1 + .../wikidata/module/langs/translation-en.json | 5 +- .../dialogs/schema-alignment-dialog.html | 7 +- .../dialogs/schema-alignment-dialog.js | 12 +- .../module/scripts/previewrenderer.js | 276 ++++++++++++++++++ .../dialogs/schema-alignment-dialog.less | 15 +- .../PreviewWikibaseSchemaCommand.java | 24 +- .../wikidata/schema/WbSnakExpr.java | 3 +- .../FullyPropertySerializingValueSnak.java | 28 ++ .../entityvalues/ReconEntityIdValue.java | 1 + .../wikidata/utils/FirstLinesExtractor.java | 60 ---- .../PreviewWikibaseSchemaCommandTest.java | 5 +- .../utils/FirstLinesExtractorTest.java | 45 --- 13 files changed, 356 insertions(+), 126 deletions(-) create mode 100644 extensions/wikidata/module/scripts/previewrenderer.js create mode 100644 extensions/wikidata/src/org/openrefine/wikidata/schema/entityvalues/FullyPropertySerializingValueSnak.java delete mode 100644 extensions/wikidata/src/org/openrefine/wikidata/utils/FirstLinesExtractor.java delete mode 100644 extensions/wikidata/tests/src/org/openrefine/wikidata/utils/FirstLinesExtractorTest.java diff --git a/extensions/wikidata/module/MOD-INF/controller.js b/extensions/wikidata/module/MOD-INF/controller.js index 1f14b8615..d138cd42d 100644 --- a/extensions/wikidata/module/MOD-INF/controller.js +++ b/extensions/wikidata/module/MOD-INF/controller.js @@ -58,6 +58,7 @@ function init() { "scripts/warningsrenderer.js", "scripts/langsuggest.js", "scripts/bettersuggest.js", + "scripts/previewrenderer.js", "scripts/dialogs/schema-alignment-dialog.js", "scripts/dialogs/manage-account-dialog.js", "scripts/dialogs/perform-edits-dialog.js", diff --git a/extensions/wikidata/module/langs/translation-en.json b/extensions/wikidata/module/langs/translation-en.json index 0bdeb0960..87fb59e14 100644 --- a/extensions/wikidata/module/langs/translation-en.json +++ b/extensions/wikidata/module/langs/translation-en.json @@ -10,9 +10,10 @@ "wikidata-schema": { "dialog-header": "Align to Wikidata", "dialog-explanation": "The Wikidata schema below specifies how your tabular data will be transformed into Wikidata edits. You can drag and drop the column names below in most input boxes: for each row, edits will be generated with the values in these columns.", + "preview-explanation": "This tab shows the first 10 edits that will be made once you upload the changes to Wikidata. You can use facets to inspect the edits on particular items.", "schema-tab-header": "Schema", "warnings-tab-header": "Issues", - "qs-preview-tab-header": "QuickStatements preview", + "edits-preview-tab-header": "Preview", "statements-header": "Statements", "terms-header": "Terms", "empty-statements": "no statements added", @@ -41,7 +42,7 @@ "geoshape-with-prefix": "filename starting with \"Data:\"", "datatype-not-supported-yet": "This datatype is not supported yet, sorry.", "invalid-schema-warning-issues": "Your schema is incomplete, fix it to see the issues.", - "invalid-schema-warning-qs": "Your schema is incomplete, fix it to see the preview.", + "invalid-schema-warning-preview": "Your schema is incomplete, fix it to see the preview.", "reset-button": "Reset", "save-button": "Save", "close-button": "Close", diff --git a/extensions/wikidata/module/scripts/dialogs/schema-alignment-dialog.html b/extensions/wikidata/module/scripts/dialogs/schema-alignment-dialog.html index 80be6b4da..ddca9f39f 100644 --- a/extensions/wikidata/module/scripts/dialogs/schema-alignment-dialog.html +++ b/extensions/wikidata/module/scripts/dialogs/schema-alignment-dialog.html @@ -5,7 +5,7 @@

@@ -23,8 +23,9 @@
- diff --git a/extensions/wikidata/module/scripts/dialogs/schema-alignment-dialog.js b/extensions/wikidata/module/scripts/dialogs/schema-alignment-dialog.js index ef7a2f7e4..8610b7f2d 100644 --- a/extensions/wikidata/module/scripts/dialogs/schema-alignment-dialog.js +++ b/extensions/wikidata/module/scripts/dialogs/schema-alignment-dialog.js @@ -115,12 +115,13 @@ SchemaAlignmentDialog._createDialog = function() { this._elmts.dialogHeader.text($.i18n._('wikidata-schema')["dialog-header"]); this._elmts.dialogExplanation.text($.i18n._('wikidata-schema')["dialog-explanation"]); + this._elmts.previewExplanation.text($.i18n._('wikidata-schema')["preview-explanation"]); this._elmts.schemaTabHeader.text($.i18n._('wikidata-schema')["schema-tab-header"]); this._elmts.warningsTabHeader.text($.i18n._('wikidata-schema')["warnings-tab-header"]); - this._elmts.qsPreviewTabHeader.text($.i18n._('wikidata-schema')["qs-preview-tab-header"]); + this._elmts.editsPreviewTabHeader.text($.i18n._('wikidata-schema')["edits-preview-tab-header"]); SchemaAlignmentDialog._plusButton($.i18n._('wikidata-schema')["add-item-button"], this._elmts.addItemButton); this._elmts.invalidSchemaWarningIssues.text($.i18n._('wikidata-schema')["invalid-schema-warning-issues"]); - this._elmts.invalidSchemaWarningQs.text($.i18n._('wikidata-schema')["invalid-schema-warning-qs"]); + this._elmts.invalidSchemaWarningPreview.text($.i18n._('wikidata-schema')["invalid-schema-warning-preview"]); this._elmts.resetButton.text($.i18n._('wikidata-schema')["reset-button"]); this._elmts.saveButton.text($.i18n._('wikidata-schema')["save-button"]); this._elmts.closeButton.text($.i18n._('wikidata-schema')["close-button"]); @@ -939,7 +940,7 @@ SchemaAlignmentDialog._removeStatement = function(statement) { SchemaAlignmentDialog.getJSON = function() { var list = new Array(); - $('.wbs-item').each(function () { + $('#schema-alignment-statements-container .wbs-item').each(function () { list.push(SchemaAlignmentDialog._itemToJSON($(this))); }); return { @@ -963,8 +964,9 @@ SchemaAlignmentDialog.preview = function(initial) { "command/wikidata/preview-wikibase-schema?" + $.param({ project: theProject.id }), { schema: JSON.stringify(schema), engine: JSON.stringify(ui.browsingEngine.getJSON()) }, function(data) { - if ("quickstatements" in data) { - $(self._previewPanes[0]).text(data.quickstatements); + if ("edits_preview" in data) { + var previewContainer = self._previewPanes[0]; + EditRenderer.renderEdits(data.edits_preview, previewContainer); } if (data.warnings) { diff --git a/extensions/wikidata/module/scripts/previewrenderer.js b/extensions/wikidata/module/scripts/previewrenderer.js new file mode 100644 index 000000000..0bc41614a --- /dev/null +++ b/extensions/wikidata/module/scripts/previewrenderer.js @@ -0,0 +1,276 @@ +/** + * renders an item update (an edit on an item) in HTML. + */ + +var EditRenderer = {}; + +// main method: takes a DOM element and a list +// of edits to render there. +EditRenderer.renderEdits = function(edits, container) { + for(var i = 0; i != edits.length; i++) { + EditRenderer._renderItem(edits[i], container); + } +} + +/**************/ +/*** ITEMS ****/ +/**************/ + +EditRenderer._renderItem = function(json, container) { + var subject = json; + var statementGroups = null; + var nameDescs = null; + if (json) { + subject = json.subject; + statementGroups = json.statementGroups; + nameDescs = json.nameDescs; + } + + var item = $('
').addClass('wbs-item').appendTo(container); + var inputContainer = $('
').addClass('wbs-item-input').appendTo(item); + EditRenderer._renderEntity(json.subject, inputContainer); + var right = $('
').addClass('wbs-item-contents').appendTo(item); + + // Terms + if ((json.labels && json.labels.length) || + (json.descriptions && json.descriptions.length) || + (json.addedAliases && json.addedAliases.length)) { + //$('').addClass('wbs-namedesc-header') + // .text($.i18n._('wikidata-schema')["terms-header"]).appendTo(right); + var termsContainer = $('
').addClass('wbs-namedesc-container') + .appendTo(right); + + for(var i = 0; i != json.labels.length; i++) { + EditRenderer._renderTerm("label", json.labels[i], termsContainer); + } + for(var i = 0; i != json.descriptions.length; i++) { + EditRenderer._renderTerm("description", json.descriptions[i], termsContainer); + } + for(var i = 0; i != json.addedAliases.length; i++) { + EditRenderer._renderTerm("alias", json.addedAliases[i], termsContainer); + } + + // Clear the float + $('
').attr('style', 'clear: right').appendTo(right); + } + + // Statements + if (json.addedStatementGroups && json.addedStatementGroups.length) { + // $('
').addClass('wbs-statements-header') + // .text($.i18n._('wikidata-schema')['statements-header']).appendTo(right); + var statementsGroupContainer = $('
').addClass('wbs-statement-group-container') + .appendTo(right); + for(var i = 0; i != json.addedStatementGroups.length; i++) { + EditRenderer._renderStatementGroup(json.addedStatementGroups[i], statementsGroupContainer); + } + } +} + +/************************** + * NAMES AND DESCRIPTIONS * + **************************/ + +EditRenderer._renderTerm = function(termType, json, container) { + var namedesc = $('
').addClass('wbs-namedesc').appendTo(container); + var type_container = $('
').addClass('wbs-namedesc-type').appendTo(namedesc); + var type_span = $('').appendTo(type_container) + .text($.i18n._('wikidata-schema')[termType]); + + var right = $('
').addClass('wbs-right').appendTo(namedesc); + var value_container = $('
').addClass('wbs-namedesc-value').appendTo(namedesc); + EditRenderer._renderValue({datavalue:json,datatype:'monolingualtext'}, value_container); +} + +/******************** + * STATEMENT GROUPS * + ********************/ + +EditRenderer._renderStatementGroup = function(json, container) { + + var statementGroup = $('
').addClass('wbs-statement-group').appendTo(container); + var inputContainer = $('
').addClass('wbs-prop-input').appendTo(statementGroup); + var right = $('
').addClass('wbs-right').appendTo(statementGroup); + EditRenderer._renderEntity(json.property, inputContainer); + + var statementContainer = $('
').addClass('wbs-statement-container').appendTo(right); + for (var i = 0; i != json.statements.length; i++) { + EditRenderer._renderStatement(json.statements[i], statementContainer); + } +} + +/************** + * STATEMENTS * + **************/ + +EditRenderer._renderStatement = function(json, container) { + + var statement = $('
').addClass('wbs-statement').appendTo(container); + var inputContainer = $('
').addClass('wbs-target-input').appendTo(statement); + EditRenderer._renderValue(json.mainsnak, inputContainer); + + // add rank + var rank = $('
').addClass('wbs-rank-selector-icon').prependTo(inputContainer); + + // add qualifiers... + var right = $('
').addClass('wbs-right').appendTo(statement); + var qualifierContainer = $('
').addClass('wbs-qualifier-container').appendTo(right); + + if (json.qualifiers) { + for (var pid in json.qualifiers) { + if (json.qualifiers.hasOwnProperty(pid)) { + var qualifiers = json.qualifiers[pid]; + for (var i = 0; i != qualifiers.length; i++) { + EditRenderer._renderSnak(qualifiers[i], qualifierContainer); + } + } + } + } + + // and references + $('
').attr('style', 'clear: right').appendTo(statement); + var referencesToggleContainer = $('
').addClass('wbs-references-toggle').appendTo(statement); + var triangle = $('
').addClass('triangle-icon').addClass('pointing-right').appendTo(referencesToggleContainer); + var referencesToggle = $('').appendTo(referencesToggleContainer); + right = $('
').addClass('wbs-right').appendTo(statement); + var referenceContainer = $('
').addClass('wbs-reference-container').appendTo(right); + referencesToggle.click(function () { + triangle.toggleClass('pointing-down'); + triangle.toggleClass('pointing-right'); + referenceContainer.toggle(100); + }); + referenceContainer.hide(); + + if (json.references) { + for (var i = 0; i != json.references.length; i++) { + EditRenderer._renderReference(json.references[i], referenceContainer); + } + } + EditRenderer._updateReferencesNumber(referenceContainer); +} + +/********************************* + * QUALIFIER AND REFERENCE SNAKS * + *********************************/ + +EditRenderer._renderSnak = function(json, container) { + + var qualifier = $('
').addClass('wbs-qualifier').appendTo(container); + var toolbar1 = $('
').addClass('wbs-toolbar').appendTo(qualifier); + var inputContainer = $('
').addClass('wbs-prop-input').appendTo(qualifier); + var right = $('
').addClass('wbs-right').appendTo(qualifier); + var statementContainer = $('
').addClass('wbs-statement-container').appendTo(right); + EditRenderer._renderEntity(json.full_property, inputContainer); + EditRenderer._renderValue(json, statementContainer); +} + +/************** + * REFERENCES * + **************/ + +EditRenderer._renderReference = function(json, container) { + var reference = $('
').addClass('wbs-reference').appendTo(container); + var referenceHeader = $('
').addClass('wbs-reference-header').appendTo(reference); + var right = $('
').addClass('wbs-right').appendTo(reference); + var qualifierContainer = $('
').addClass('wbs-qualifier-container').appendTo(right); + + for (var pid in json.snaks) { + if (json.snaks.hasOwnProperty(pid)) { + var snaks = json.snaks[pid]; + for(var i = 0; i != snaks.length; i++) { + EditRenderer._renderSnak(snaks[i], qualifierContainer); + } + } + } +} + +EditRenderer._updateReferencesNumber = function(container) { + var childrenCount = container.children().length; + var statement = container.parents('.wbs-statement'); + var a = statement.find('.wbs-references-toggle a').first(); + a.html(childrenCount+$.i18n._('wikidata-schema')["nb-references"]); +} + +/******************* + * VALUE RENDERING * + *******************/ + +EditRenderer._renderEntity = function(json, container) { + var html = WarningsRenderer._renderEntity(json); + $(html).appendTo(container); +} + +EditRenderer._renderValue = function(json, container) { + var input = $('').appendTo(container); + var mode = json.datatype; + + if (mode === "wikibase-item" || mode === "wikibase-property") { + EditRenderer._renderEntity(json.datavalue, container); + } else { + var params = { + action: 'wbformatvalue', + generate: 'text/html', + datavalue: JSON.stringify(json.datavalue), + options: '{"lang":"'+$.i18n._('core-recon')["wd-recon-lang"]+'"}', + format: 'json' + }; + if ('property' in json) { + params.property = json.property; + } else { + params.datatype = json.datatype; + } + $.get( + 'https://www.wikidata.org/w/api.php', + params, + function (data) { + if('result' in data) { + $(''+data.result+'').appendTo(container); + } + }, + 'jsonp' + ); + } + +/* +if (mode === "time") { + input.text(json.datavalue.value.time); + } else if (mode === "globe-coordinate") { + // TODO + } else if (mode === "language") { + // TODO + } else if (mode === "monolingualtext") { + input.remove(); + var inputContainerLanguage = $('
') + .addClass('wbs-monolingual-container') + .width('30%') + .appendTo(container); + var inputContainerValue = $('
') + .addClass('wbs-monolingual-container') + .width('70%') + .appendTo(container); + + EditRenderer._renderValue({datatype:"language",datavalue:json.language}, inputContainerLanguage); + EditRenderer._renderValue({datatype:"string",datavalue:{value:json.value}}, inputContainerValue); + } else if (mode === "quantity") { + input.remove(); + var inputContainerAmount = $('
') + .addClass('wbs-quantity-container') + .width('60%') + .appendTo(inputContainer); + var inputContainerUnit = $('
') + .addClass('wbs-quantity-container') + .width('40%') + .appendTo(inputContainer); + + var amountValue = null; + var unitValue = null; + + // TODO + //EditRenderer._renderValue(inputContainerAmount, "amount", amountValue, propagateValue); + // EditRenderer._renderEntity( , inputContainerUnit); + + } else { + input.text(json.datavalue.value); + } */ +} + + diff --git a/extensions/wikidata/module/styles/dialogs/schema-alignment-dialog.less b/extensions/wikidata/module/styles/dialogs/schema-alignment-dialog.less index 986719d7f..3e0583c52 100644 --- a/extensions/wikidata/module/styles/dialogs/schema-alignment-dialog.less +++ b/extensions/wikidata/module/styles/dialogs/schema-alignment-dialog.less @@ -204,6 +204,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. color: gray; } +.schema-alignment-dialog-preview .wbs-qualifier .wbs-statement-container { + display: table-cell; + vertical-align: bottom; + padding-left: 10px; + height: 20px; +} + .wbs-statement-group-container, .wbs-statement-container, .wbs-qualifier-container, .wbs-reference-container { width: 100%; display: block; @@ -228,6 +235,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .wbs-statement { background: white; + border-bottom: 1px solid #eaecf0; +} + +.wbs-statement:last-child { + border-bottom: 0; } .wbs-right { @@ -236,7 +248,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. } .wbs-statement-group .wbs-right { - width: 70%; + width: 75%; } .wbs-statement .wbs-right { @@ -450,6 +462,5 @@ div.schema-alignment-dialog-preview { padding: 10px; margin-top: 3px; white-space: pre; - font-family: monospace; font-size: 9pt; } diff --git a/extensions/wikidata/src/org/openrefine/wikidata/commands/PreviewWikibaseSchemaCommand.java b/extensions/wikidata/src/org/openrefine/wikidata/commands/PreviewWikibaseSchemaCommand.java index 0a1e3d792..53766d3d6 100644 --- a/extensions/wikidata/src/org/openrefine/wikidata/commands/PreviewWikibaseSchemaCommand.java +++ b/extensions/wikidata/src/org/openrefine/wikidata/commands/PreviewWikibaseSchemaCommand.java @@ -28,22 +28,27 @@ import java.io.IOException; import java.io.StringWriter; import java.util.List; import java.util.Properties; +import java.util.stream.Collectors; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.json.JSONArray; import org.json.JSONException; +import org.json.JSONObject; import org.json.JSONWriter; -import org.openrefine.wikidata.exporters.QuickStatementsExporter; import org.openrefine.wikidata.qa.EditInspector; import org.openrefine.wikidata.qa.QAWarning; 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 org.openrefine.wikidata.updates.scheduler.WikibaseAPIUpdateScheduler; + import static org.openrefine.wikidata.commands.CommandUtilities.respondError; +import com.fasterxml.jackson.databind.ObjectMapper; + import com.google.refine.browsing.Engine; import com.google.refine.commands.Command; import com.google.refine.model.Project; @@ -110,12 +115,17 @@ public class PreviewWikibaseSchemaCommand extends Command { writer.key("nb_warnings"); writer.value(warningStore.getNbWarnings()); - // Export to QuickStatements - QuickStatementsExporter exporter = new QuickStatementsExporter(); - exporter.translateItemList(editBatch, stringWriter); + // Dump the first 10 edits, scheduled with the default scheduler + WikibaseAPIUpdateScheduler scheduler = new WikibaseAPIUpdateScheduler(); + List firstEdits = scheduler.schedule(editBatch).stream() + .filter(e -> !e.isNull()) + .limit(10) + .collect(Collectors.toList()); + ObjectMapper mapper = new ObjectMapper(); + String firstEditsJson = mapper.writeValueAsString(firstEdits); - writer.key("quickstatements"); - writer.value(FirstLinesExtractor.extractFirstLines(stringWriter.toString(), 50)); + writer.key("edits_preview"); + writer.value(new JSONArray(firstEditsJson)); } writer.endObject(); diff --git a/extensions/wikidata/src/org/openrefine/wikidata/schema/WbSnakExpr.java b/extensions/wikidata/src/org/openrefine/wikidata/schema/WbSnakExpr.java index 371b13e35..a9b33b952 100644 --- a/extensions/wikidata/src/org/openrefine/wikidata/schema/WbSnakExpr.java +++ b/extensions/wikidata/src/org/openrefine/wikidata/schema/WbSnakExpr.java @@ -24,6 +24,7 @@ package org.openrefine.wikidata.schema; import org.jsoup.helper.Validate; +import org.openrefine.wikidata.schema.entityvalues.FullyPropertySerializingValueSnak; import org.openrefine.wikidata.schema.exceptions.SkipSchemaExpressionException; import org.wikidata.wdtk.datamodel.helpers.Datamodel; import org.wikidata.wdtk.datamodel.interfaces.PropertyIdValue; @@ -62,7 +63,7 @@ public class WbSnakExpr implements WbExpression { throws SkipSchemaExpressionException { PropertyIdValue propertyId = getProp().evaluate(ctxt); Value evaluatedValue = value.evaluate(ctxt); - return Datamodel.makeValueSnak(propertyId, evaluatedValue); + return new FullyPropertySerializingValueSnak(propertyId, evaluatedValue); } @JsonProperty("prop") diff --git a/extensions/wikidata/src/org/openrefine/wikidata/schema/entityvalues/FullyPropertySerializingValueSnak.java b/extensions/wikidata/src/org/openrefine/wikidata/schema/entityvalues/FullyPropertySerializingValueSnak.java new file mode 100644 index 000000000..7f969b7dc --- /dev/null +++ b/extensions/wikidata/src/org/openrefine/wikidata/schema/entityvalues/FullyPropertySerializingValueSnak.java @@ -0,0 +1,28 @@ +package org.openrefine.wikidata.schema.entityvalues; + +import org.wikidata.wdtk.datamodel.implementation.ValueSnakImpl; +import org.wikidata.wdtk.datamodel.interfaces.PropertyIdValue; +import org.wikidata.wdtk.datamodel.interfaces.Value; + +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * A tweaked version of {@link SnakImpl} that serializes + * the full property (not just its PID), so that we can also + * get the label for that property and display it in the UI + * without having to query the remove server. + * + * @author Antonin Delpeuch + * + */ +public class FullyPropertySerializingValueSnak extends ValueSnakImpl { + + public FullyPropertySerializingValueSnak(PropertyIdValue property, Value value) { + super(property, value); + } + + @JsonProperty("full_property") + public PropertyIdValue getFullPropertyId() { + return getPropertyId(); + } +} diff --git a/extensions/wikidata/src/org/openrefine/wikidata/schema/entityvalues/ReconEntityIdValue.java b/extensions/wikidata/src/org/openrefine/wikidata/schema/entityvalues/ReconEntityIdValue.java index 2ab8f3222..f55bc3c8c 100644 --- a/extensions/wikidata/src/org/openrefine/wikidata/schema/entityvalues/ReconEntityIdValue.java +++ b/extensions/wikidata/src/org/openrefine/wikidata/schema/entityvalues/ReconEntityIdValue.java @@ -105,6 +105,7 @@ public abstract class ReconEntityIdValue implements PrefetchedEntityIdValue { * * @return the full reconciliation metadata of the corresponding cell */ + @JsonIgnore // just to clean up a bit the json serialization public Recon getRecon() { return _recon; } diff --git a/extensions/wikidata/src/org/openrefine/wikidata/utils/FirstLinesExtractor.java b/extensions/wikidata/src/org/openrefine/wikidata/utils/FirstLinesExtractor.java deleted file mode 100644 index a6a8d356d..000000000 --- a/extensions/wikidata/src/org/openrefine/wikidata/utils/FirstLinesExtractor.java +++ /dev/null @@ -1,60 +0,0 @@ -/******************************************************************************* - * MIT License - * - * Copyright (c) 2018 Antonin Delpeuch - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - ******************************************************************************/ -package org.openrefine.wikidata.utils; - -import java.io.IOException; -import java.io.LineNumberReader; -import java.io.StringReader; -import java.io.StringWriter; - -public class FirstLinesExtractor { - - /** - * Returns the first n lines of a given string - * - * @param content - * the content, where lines are separated by '\n' - * @param nbLines - * the number of lines to extract - * @return the first lines of the string - * @throws IOException - */ - public static String extractFirstLines(String content, int nbLines) - throws IOException { - StringWriter stringWriter = new StringWriter(); - LineNumberReader reader = new LineNumberReader(new StringReader(content)); - - // Only keep the first 50 lines - reader.setLineNumber(0); - String line = reader.readLine(); - for (int i = 1; i != nbLines && line != null; i++) { - stringWriter.write(line + "\n"); - line = reader.readLine(); - } - if (reader.getLineNumber() == nbLines) { - stringWriter.write("..."); - } - return stringWriter.toString(); - } -} diff --git a/extensions/wikidata/tests/src/org/openrefine/wikidata/commands/PreviewWikibaseSchemaCommandTest.java b/extensions/wikidata/tests/src/org/openrefine/wikidata/commands/PreviewWikibaseSchemaCommandTest.java index 19fd8fb28..f042f2c48 100644 --- a/extensions/wikidata/tests/src/org/openrefine/wikidata/commands/PreviewWikibaseSchemaCommandTest.java +++ b/extensions/wikidata/tests/src/org/openrefine/wikidata/commands/PreviewWikibaseSchemaCommandTest.java @@ -31,8 +31,10 @@ import java.io.IOException; import javax.servlet.ServletException; +import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; +import org.junit.Assert; import org.openrefine.wikidata.testing.TestingData; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; @@ -56,7 +58,8 @@ public class PreviewWikibaseSchemaCommandTest extends SchemaCommandTest { command.doPost(request, response); JSONObject response = ParsingUtilities.evaluateJsonStringToObject(writer.toString()); - assertEquals(TestingData.inceptionWithNewQS, response.getString("quickstatements")); + JSONArray edits = response.getJSONArray("edits_preview"); + assertEquals(4, edits.length()); } } diff --git a/extensions/wikidata/tests/src/org/openrefine/wikidata/utils/FirstLinesExtractorTest.java b/extensions/wikidata/tests/src/org/openrefine/wikidata/utils/FirstLinesExtractorTest.java deleted file mode 100644 index 5a3fae359..000000000 --- a/extensions/wikidata/tests/src/org/openrefine/wikidata/utils/FirstLinesExtractorTest.java +++ /dev/null @@ -1,45 +0,0 @@ -/******************************************************************************* - * MIT License - * - * Copyright (c) 2018 Antonin Delpeuch - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - ******************************************************************************/ -package org.openrefine.wikidata.utils; - -import static org.junit.Assert.assertEquals; - -import java.io.IOException; - -import org.testng.annotations.Test; - -public class FirstLinesExtractorTest { - - @Test - public void testShort() - throws IOException { - assertEquals("a\nb\nc\n", FirstLinesExtractor.extractFirstLines("a\nb\nc\n", 5)); - } - - @Test - public void testLong() - throws IOException { - assertEquals("a\nb\n...", FirstLinesExtractor.extractFirstLines("a\nb\nc", 3)); - } -}