diff --git a/src/main/java/com/metaweb/gridworks/browsing/facets/ExpressionNominalRowGrouper.java b/src/main/java/com/metaweb/gridworks/browsing/facets/ExpressionNominalRowGrouper.java index a1370821f..71f88c3a4 100644 --- a/src/main/java/com/metaweb/gridworks/browsing/facets/ExpressionNominalRowGrouper.java +++ b/src/main/java/com/metaweb/gridworks/browsing/facets/ExpressionNominalRowGrouper.java @@ -27,7 +27,7 @@ public class ExpressionNominalRowGrouper implements RowVisitor { Cell cell = row.getCell(_cellIndex); Properties bindings = ExpressionUtils.createBindings(project); - ExpressionUtils.bind(bindings, row, cell); + ExpressionUtils.bind(bindings, row, rowIndex, cell); Object value = _evaluable.evaluate(bindings); if (value != null) { diff --git a/src/main/java/com/metaweb/gridworks/browsing/facets/ExpressionNumericRowBinner.java b/src/main/java/com/metaweb/gridworks/browsing/facets/ExpressionNumericRowBinner.java index 14e4c723d..e43f9cc12 100644 --- a/src/main/java/com/metaweb/gridworks/browsing/facets/ExpressionNumericRowBinner.java +++ b/src/main/java/com/metaweb/gridworks/browsing/facets/ExpressionNumericRowBinner.java @@ -27,7 +27,7 @@ public class ExpressionNumericRowBinner implements RowVisitor { Cell cell = row.getCell(_cellIndex); Properties bindings = ExpressionUtils.createBindings(project); - ExpressionUtils.bind(bindings, row, cell); + ExpressionUtils.bind(bindings, row, rowIndex, cell); Object value = _evaluable.evaluate(bindings); if (value != null) { diff --git a/src/main/java/com/metaweb/gridworks/browsing/facets/NumericBinIndex.java b/src/main/java/com/metaweb/gridworks/browsing/facets/NumericBinIndex.java index ded39d418..1aa2ab595 100644 --- a/src/main/java/com/metaweb/gridworks/browsing/facets/NumericBinIndex.java +++ b/src/main/java/com/metaweb/gridworks/browsing/facets/NumericBinIndex.java @@ -27,7 +27,7 @@ public class NumericBinIndex { Row row = project.rows.get(i); Cell cell = row.getCell(cellIndex); - ExpressionUtils.bind(bindings, row, cell); + ExpressionUtils.bind(bindings, row, i, cell); Object value = eval.evaluate(bindings); if (value != null) { diff --git a/src/main/java/com/metaweb/gridworks/browsing/filters/ExpressionEqualRowFilter.java b/src/main/java/com/metaweb/gridworks/browsing/filters/ExpressionEqualRowFilter.java index 420c9c561..db55d091e 100644 --- a/src/main/java/com/metaweb/gridworks/browsing/filters/ExpressionEqualRowFilter.java +++ b/src/main/java/com/metaweb/gridworks/browsing/filters/ExpressionEqualRowFilter.java @@ -22,7 +22,7 @@ public class ExpressionEqualRowFilter implements RowFilter { public boolean filterRow(Project project, int rowIndex, Row row) { Cell cell = row.getCell(_cellIndex); Properties bindings = ExpressionUtils.createBindings(project); - ExpressionUtils.bind(bindings, row, cell); + ExpressionUtils.bind(bindings, row, rowIndex, cell); Object value = _evaluable.evaluate(bindings); if (value != null) { diff --git a/src/main/java/com/metaweb/gridworks/browsing/filters/ExpressionNumberComparisonRowFilter.java b/src/main/java/com/metaweb/gridworks/browsing/filters/ExpressionNumberComparisonRowFilter.java index 97049adb2..017ebffed 100644 --- a/src/main/java/com/metaweb/gridworks/browsing/filters/ExpressionNumberComparisonRowFilter.java +++ b/src/main/java/com/metaweb/gridworks/browsing/filters/ExpressionNumberComparisonRowFilter.java @@ -21,7 +21,7 @@ abstract public class ExpressionNumberComparisonRowFilter implements RowFilter { Cell cell = row.getCell(_cellIndex); Properties bindings = ExpressionUtils.createBindings(project); - ExpressionUtils.bind(bindings, row, cell); + ExpressionUtils.bind(bindings, row, rowIndex, cell); Object value = _evaluable.evaluate(bindings); if (value != null) { diff --git a/src/main/java/com/metaweb/gridworks/browsing/filters/ExpressionStringComparisonRowFilter.java b/src/main/java/com/metaweb/gridworks/browsing/filters/ExpressionStringComparisonRowFilter.java index e0f97368e..8ab7279f6 100644 --- a/src/main/java/com/metaweb/gridworks/browsing/filters/ExpressionStringComparisonRowFilter.java +++ b/src/main/java/com/metaweb/gridworks/browsing/filters/ExpressionStringComparisonRowFilter.java @@ -20,7 +20,7 @@ abstract public class ExpressionStringComparisonRowFilter implements RowFilter { public boolean filterRow(Project project, int rowIndex, Row row) { Cell cell = row.getCell(_cellIndex); Properties bindings = ExpressionUtils.createBindings(project); - ExpressionUtils.bind(bindings, row, cell); + ExpressionUtils.bind(bindings, row, rowIndex, cell); Object value = _evaluable.evaluate(bindings); if (value != null) { diff --git a/src/main/java/com/metaweb/gridworks/commands/util/PreviewExpressionCommand.java b/src/main/java/com/metaweb/gridworks/commands/util/PreviewExpressionCommand.java index ca8c11bb2..33687d8b2 100644 --- a/src/main/java/com/metaweb/gridworks/commands/util/PreviewExpressionCommand.java +++ b/src/main/java/com/metaweb/gridworks/commands/util/PreviewExpressionCommand.java @@ -59,7 +59,7 @@ public class PreviewExpressionCommand extends Command { Row row = project.rows.get(rowIndex); Cell cell = row.getCell(cellIndex); - ExpressionUtils.bind(bindings, row, cell); + ExpressionUtils.bind(bindings, row, rowIndex, cell); try { result = eval.evaluate(bindings); diff --git a/src/main/java/com/metaweb/gridworks/expr/ExpressionUtils.java b/src/main/java/com/metaweb/gridworks/expr/ExpressionUtils.java index 773ebf57b..9d66fec7f 100644 --- a/src/main/java/com/metaweb/gridworks/expr/ExpressionUtils.java +++ b/src/main/java/com/metaweb/gridworks/expr/ExpressionUtils.java @@ -18,8 +18,9 @@ public class ExpressionUtils { return bindings; } - static public void bind(Properties bindings, Row row, Cell cell) { + static public void bind(Properties bindings, Row row, int rowIndex, Cell cell) { bindings.put("row", row); + bindings.put("rowIndex", rowIndex); bindings.put("cells", row.getField("cells", bindings)); if (cell == null) { diff --git a/src/main/java/com/metaweb/gridworks/expr/Parser.java b/src/main/java/com/metaweb/gridworks/expr/Parser.java index 0d4ebc163..63a7787fa 100644 --- a/src/main/java/com/metaweb/gridworks/expr/Parser.java +++ b/src/main/java/com/metaweb/gridworks/expr/Parser.java @@ -13,7 +13,9 @@ import com.metaweb.gridworks.expr.controls.ForNonBlank; import com.metaweb.gridworks.expr.controls.If; import com.metaweb.gridworks.expr.controls.With; import com.metaweb.gridworks.expr.functions.And; +import com.metaweb.gridworks.expr.functions.Ceil; import com.metaweb.gridworks.expr.functions.EndsWith; +import com.metaweb.gridworks.expr.functions.Floor; import com.metaweb.gridworks.expr.functions.Get; import com.metaweb.gridworks.expr.functions.IndexOf; import com.metaweb.gridworks.expr.functions.IsBlank; @@ -23,13 +25,17 @@ import com.metaweb.gridworks.expr.functions.IsNull; import com.metaweb.gridworks.expr.functions.Join; import com.metaweb.gridworks.expr.functions.LastIndexOf; import com.metaweb.gridworks.expr.functions.Length; +import com.metaweb.gridworks.expr.functions.Mod; import com.metaweb.gridworks.expr.functions.Not; import com.metaweb.gridworks.expr.functions.Or; import com.metaweb.gridworks.expr.functions.Replace; +import com.metaweb.gridworks.expr.functions.Round; import com.metaweb.gridworks.expr.functions.Slice; import com.metaweb.gridworks.expr.functions.Split; import com.metaweb.gridworks.expr.functions.StartsWith; import com.metaweb.gridworks.expr.functions.ToLowercase; +import com.metaweb.gridworks.expr.functions.ToNumber; +import com.metaweb.gridworks.expr.functions.ToString; import com.metaweb.gridworks.expr.functions.ToTitlecase; import com.metaweb.gridworks.expr.functions.ToUppercase; @@ -42,6 +48,9 @@ public class Parser { static public Map controlTable = new HashMap(); static { + functionTable.put("toString", new ToString()); + functionTable.put("toNumber", new ToNumber()); + functionTable.put("toUppercase", new ToUppercase()); functionTable.put("toLowercase", new ToLowercase()); functionTable.put("toTitlecase", new ToTitlecase()); @@ -59,6 +68,11 @@ public class Parser { functionTable.put("endsWith", new EndsWith()); functionTable.put("join", new Join()); + functionTable.put("round", new Round()); + functionTable.put("floor", new Floor()); + functionTable.put("ceil", new Ceil()); + functionTable.put("mod", new Mod()); + functionTable.put("and", new And()); functionTable.put("or", new Or()); functionTable.put("not", new Not()); diff --git a/src/main/java/com/metaweb/gridworks/expr/functions/Ceil.java b/src/main/java/com/metaweb/gridworks/expr/functions/Ceil.java new file mode 100644 index 000000000..4f9c5704b --- /dev/null +++ b/src/main/java/com/metaweb/gridworks/expr/functions/Ceil.java @@ -0,0 +1,16 @@ +package com.metaweb.gridworks.expr.functions; + +import java.util.Properties; + +import com.metaweb.gridworks.expr.Function; + +public class Ceil implements Function { + + public Object call(Properties bindings, Object[] args) { + if (args.length == 1 && args[0] instanceof Number) { + return (long) Math.ceil(((Number) args[0]).doubleValue()); + } + return null; + } + +} diff --git a/src/main/java/com/metaweb/gridworks/expr/functions/Floor.java b/src/main/java/com/metaweb/gridworks/expr/functions/Floor.java new file mode 100644 index 000000000..b70ee2be9 --- /dev/null +++ b/src/main/java/com/metaweb/gridworks/expr/functions/Floor.java @@ -0,0 +1,16 @@ +package com.metaweb.gridworks.expr.functions; + +import java.util.Properties; + +import com.metaweb.gridworks.expr.Function; + +public class Floor implements Function { + + public Object call(Properties bindings, Object[] args) { + if (args.length == 1 && args[0] instanceof Number) { + return (long) Math.floor(((Number) args[0]).doubleValue()); + } + return null; + } + +} diff --git a/src/main/java/com/metaweb/gridworks/expr/functions/Mod.java b/src/main/java/com/metaweb/gridworks/expr/functions/Mod.java new file mode 100644 index 000000000..e8c84ee23 --- /dev/null +++ b/src/main/java/com/metaweb/gridworks/expr/functions/Mod.java @@ -0,0 +1,19 @@ +package com.metaweb.gridworks.expr.functions; + +import java.util.Properties; + +import com.metaweb.gridworks.expr.Function; + +public class Mod implements Function { + + public Object call(Properties bindings, Object[] args) { + if (args.length == 2 && args[0] instanceof Number && args[1] instanceof Number) { + int a = ((Number) args[0]).intValue(); + int b = ((Number) args[0]).intValue(); + + return a % b; + } + return null; + } + +} diff --git a/src/main/java/com/metaweb/gridworks/expr/functions/Round.java b/src/main/java/com/metaweb/gridworks/expr/functions/Round.java new file mode 100644 index 000000000..d32d99723 --- /dev/null +++ b/src/main/java/com/metaweb/gridworks/expr/functions/Round.java @@ -0,0 +1,16 @@ +package com.metaweb.gridworks.expr.functions; + +import java.util.Properties; + +import com.metaweb.gridworks.expr.Function; + +public class Round implements Function { + + public Object call(Properties bindings, Object[] args) { + if (args.length == 1 && args[0] instanceof Number) { + return ((Number) args[0]).longValue(); + } + return null; + } + +} diff --git a/src/main/java/com/metaweb/gridworks/expr/functions/ToNumber.java b/src/main/java/com/metaweb/gridworks/expr/functions/ToNumber.java new file mode 100644 index 000000000..038a67cb8 --- /dev/null +++ b/src/main/java/com/metaweb/gridworks/expr/functions/ToNumber.java @@ -0,0 +1,16 @@ +package com.metaweb.gridworks.expr.functions; + +import java.util.Properties; + +import com.metaweb.gridworks.expr.Function; + +public class ToNumber implements Function { + + public Object call(Properties bindings, Object[] args) { + if (args.length == 1) { + return args[0] instanceof Number ? args[0] : Double.parseDouble(args[0].toString()); + } + return null; + } + +} diff --git a/src/main/java/com/metaweb/gridworks/expr/functions/ToString.java b/src/main/java/com/metaweb/gridworks/expr/functions/ToString.java new file mode 100644 index 000000000..8ab021267 --- /dev/null +++ b/src/main/java/com/metaweb/gridworks/expr/functions/ToString.java @@ -0,0 +1,16 @@ +package com.metaweb.gridworks.expr.functions; + +import java.util.Properties; + +import com.metaweb.gridworks.expr.Function; + +public class ToString implements Function { + + public Object call(Properties bindings, Object[] args) { + if (args.length == 1) { + return args[0] instanceof String ? args[0] : args[0].toString(); + } + return null; + } + +} diff --git a/src/main/java/com/metaweb/gridworks/model/Row.java b/src/main/java/com/metaweb/gridworks/model/Row.java index 458db850c..39154c90f 100644 --- a/src/main/java/com/metaweb/gridworks/model/Row.java +++ b/src/main/java/com/metaweb/gridworks/model/Row.java @@ -42,6 +42,8 @@ public class Row implements Serializable, HasFields, Jsonizable { return starred; } else if ("cells".equals(name)) { return new Cells(); + } else if ("index".equals(name)) { + return bindings.get("rowIndex"); } return null; } diff --git a/src/main/java/com/metaweb/gridworks/operations/ColumnAdditionOperation.java b/src/main/java/com/metaweb/gridworks/operations/ColumnAdditionOperation.java index 249fae70f..760f0b83f 100644 --- a/src/main/java/com/metaweb/gridworks/operations/ColumnAdditionOperation.java +++ b/src/main/java/com/metaweb/gridworks/operations/ColumnAdditionOperation.java @@ -133,7 +133,7 @@ public class ColumnAdditionOperation extends EngineDependentOperation { public boolean visit(Project project, int rowIndex, Row row, boolean contextual) { Cell cell = row.getCell(cellIndex); - ExpressionUtils.bind(bindings, row, cell); + ExpressionUtils.bind(bindings, row, rowIndex, cell); Object v = eval.evaluate(bindings); if (v != null) { diff --git a/src/main/java/com/metaweb/gridworks/operations/TextTransformOperation.java b/src/main/java/com/metaweb/gridworks/operations/TextTransformOperation.java index 33befb4ac..17568401b 100644 --- a/src/main/java/com/metaweb/gridworks/operations/TextTransformOperation.java +++ b/src/main/java/com/metaweb/gridworks/operations/TextTransformOperation.java @@ -84,7 +84,7 @@ public class TextTransformOperation extends EngineDependentMassCellOperation { public boolean visit(Project project, int rowIndex, Row row, boolean contextual) { Cell cell = row.getCell(cellIndex); - ExpressionUtils.bind(bindings, row, cell); + ExpressionUtils.bind(bindings, row, rowIndex, cell); Object v = eval.evaluate(bindings); if ((cell != null && cell.value != null) || v != null) {