Add quantity expressions in the backend
This commit is contained in:
parent
487547bd27
commit
1837926cb1
@ -185,6 +185,7 @@ public class QuickStatementsExporter implements WriterExporter {
|
||||
String unit = value.getUnit();
|
||||
if (!unit.startsWith(unitPrefix))
|
||||
return null; // QuickStatements only accepts Qids as units
|
||||
// TODO test this for values without bounds
|
||||
String unitID = "U"+unit.substring(unitPrefix.length());
|
||||
return String.format(
|
||||
Locale.US,
|
||||
|
@ -28,6 +28,7 @@ import com.fasterxml.jackson.annotation.JsonSubTypes.Type;
|
||||
@Type(value = WbPropConstant.class, name = "wbpropconstant"),
|
||||
@Type(value = WbLanguageConstant.class, name = "wblanguageconstant"),
|
||||
@Type(value = WbLanguageVariable.class, name = "wblanguagevariable"),
|
||||
@Type(value = WbQuantityExpr.class, name="wbquantityexpr"),
|
||||
})
|
||||
public interface WbExpression<T> {
|
||||
|
||||
|
@ -0,0 +1,71 @@
|
||||
package org.openrefine.wikidata.schema;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.openrefine.wikidata.schema.exceptions.SkipSchemaExpressionException;
|
||||
import org.wikidata.wdtk.datamodel.helpers.Datamodel;
|
||||
import org.wikidata.wdtk.datamodel.interfaces.ItemIdValue;
|
||||
import org.wikidata.wdtk.datamodel.interfaces.QuantityValue;
|
||||
import org.wikidata.wdtk.datamodel.interfaces.StringValue;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
public class WbQuantityExpr implements WbExpression<QuantityValue> {
|
||||
|
||||
private final WbExpression<? extends StringValue> amountExpr;
|
||||
private final WbExpression<? extends ItemIdValue> unitExpr;
|
||||
|
||||
/**
|
||||
* Creates an expression for a quantity, which
|
||||
* contains two sub-expressions: one for the amount (a string with
|
||||
* a particular format) and one for the unit, which is optional.
|
||||
*
|
||||
* Setting unitExpr to null will give quantities without units. Setting
|
||||
* it to a non-null value will make the unit mandatory: if the unit expression
|
||||
* fails to evaluate, the whole quantity expression will fail too.
|
||||
*/
|
||||
@JsonCreator
|
||||
public WbQuantityExpr(
|
||||
@JsonProperty("amount") WbExpression<? extends StringValue> amountExpr,
|
||||
@JsonProperty("unit") WbExpression<? extends ItemIdValue> unitExpr) {
|
||||
Validate.notNull(amountExpr);
|
||||
this.amountExpr = amountExpr;
|
||||
this.unitExpr = unitExpr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QuantityValue evaluate(ExpressionContext ctxt)
|
||||
throws SkipSchemaExpressionException {
|
||||
StringValue amount = getLanguageExpr().evaluate(ctxt);
|
||||
if (amount == null || amount.getString().isEmpty()) {
|
||||
throw new SkipSchemaExpressionException();
|
||||
}
|
||||
|
||||
BigDecimal parsedAmount = null;
|
||||
try {
|
||||
parsedAmount = new BigDecimal(amount.getString());
|
||||
} catch(NumberFormatException e) {
|
||||
throw new SkipSchemaExpressionException();
|
||||
}
|
||||
|
||||
if(getUnitExpr() != null) {
|
||||
ItemIdValue unit = getUnitExpr().evaluate(ctxt);
|
||||
return Datamodel.makeQuantityValue(parsedAmount, unit.getIri());
|
||||
}
|
||||
|
||||
return Datamodel.makeQuantityValue(parsedAmount);
|
||||
}
|
||||
|
||||
@JsonProperty("amount")
|
||||
public WbExpression<? extends StringValue> getLanguageExpr() {
|
||||
return amountExpr;
|
||||
}
|
||||
|
||||
@JsonProperty("unit")
|
||||
public WbExpression<? extends ItemIdValue> getUnitExpr() {
|
||||
return unitExpr;
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
package org.openrefine.wikidata.schema;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import org.openrefine.wikidata.qa.QAWarningStore;
|
||||
import org.openrefine.wikidata.schema.exceptions.SkipSchemaExpressionException;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Test;
|
||||
import org.wikidata.wdtk.datamodel.helpers.Datamodel;
|
||||
|
||||
import com.google.refine.model.ModelException;
|
||||
import com.google.refine.model.Project;
|
||||
import com.google.refine.model.Row;
|
||||
import com.google.refine.tests.RefineTest;
|
||||
|
||||
public class WbQuantityValueTest extends RefineTest {
|
||||
|
||||
protected Project project;
|
||||
protected Row row;
|
||||
protected ExpressionContext ctxt;
|
||||
protected QAWarningStore warningStore;
|
||||
|
||||
@BeforeMethod
|
||||
public void createProject() throws IOException, ModelException {
|
||||
project = createCSVProject("Wikidata quantity value test project",
|
||||
"column A\nrow1");
|
||||
warningStore = new QAWarningStore();
|
||||
row = project.rows.get(0);
|
||||
ctxt = new ExpressionContext("http://www.wikidata.org/entity/", 0,
|
||||
row, project.columnModel, warningStore);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithoutUnit() throws SkipSchemaExpressionException {
|
||||
WbQuantityExpr expr = new WbQuantityExpr(new WbStringConstant("4.00"), null);
|
||||
Assert.assertEquals(Datamodel.makeQuantityValue(new BigDecimal("4.00"), null, null, "1"), expr.evaluate(ctxt));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = SkipSchemaExpressionException.class)
|
||||
public void testInvalidAmountWithoutUnit() throws SkipSchemaExpressionException {
|
||||
WbQuantityExpr expr = new WbQuantityExpr(new WbStringConstant("hello"), null);
|
||||
expr.evaluate(ctxt);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithUnit() throws SkipSchemaExpressionException {
|
||||
WbItemConstant item = new WbItemConstant("Q42", "label");
|
||||
WbQuantityExpr expr = new WbQuantityExpr(new WbStringConstant("56.094"), item);
|
||||
Assert.assertEquals(Datamodel.makeQuantityValue(new BigDecimal("56.094"), null, null, "http://www.wikidata.org/entity/Q42"), expr.evaluate(ctxt));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = SkipSchemaExpressionException.class)
|
||||
public void testInvalidAmountWithUnit() throws SkipSchemaExpressionException {
|
||||
WbItemConstant item = new WbItemConstant("Q42", "label");
|
||||
WbQuantityExpr expr = new WbQuantityExpr(new WbStringConstant("invalid"), item);
|
||||
expr.evaluate(ctxt);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = SkipSchemaExpressionException.class)
|
||||
public void testInvalidUnitWithAmount() throws SkipSchemaExpressionException {
|
||||
WbItemVariable item = new WbItemVariable();
|
||||
item.setColumnName("column A");
|
||||
WbQuantityExpr expr = new WbQuantityExpr(new WbStringConstant("56.094"), item);
|
||||
expr.evaluate(ctxt);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user