Made various GEL functions and the forEach control work with java.util.List and java.util.Collection in addition to just Object[].
Added field columnNames to row object. Added 1-bounded numeric log facet. git-svn-id: http://google-refine.googlecode.com/svn/trunk@328 7d457c2a-affb-35e4-300a-418c747d4874
This commit is contained in:
parent
6fba7d1e7f
commit
a43b2a72c1
@ -2,7 +2,9 @@ package com.metaweb.gridworks.expr;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import com.metaweb.gridworks.model.Cell;
|
||||
@ -86,4 +88,14 @@ public class ExpressionUtils {
|
||||
(Serializable) v :
|
||||
new EvalError(v.getClass().getSimpleName() + " value not storable");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
static public List<Object> toObjectList(Object v) {
|
||||
return (List<Object>) v;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
static public Collection<Object> toObjectCollection(Object v) {
|
||||
return (Collection<Object>) v;
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,12 @@
|
||||
package com.metaweb.gridworks.expr.functions;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONWriter;
|
||||
|
||||
import com.metaweb.gridworks.expr.ExpressionUtils;
|
||||
import com.metaweb.gridworks.expr.HasFields;
|
||||
import com.metaweb.gridworks.gel.Function;
|
||||
|
||||
@ -23,31 +25,41 @@ public class Get implements Function {
|
||||
}
|
||||
} else {
|
||||
if (from instanceof Number && (to == null || to instanceof Number)) {
|
||||
if (v.getClass().isArray()) {
|
||||
Object[] a = (Object[]) v;
|
||||
if (v.getClass().isArray() || v instanceof List<?>) {
|
||||
int length = v.getClass().isArray() ?
|
||||
((Object[]) v).length :
|
||||
ExpressionUtils.toObjectList(v).size();
|
||||
|
||||
int start = ((Number) from).intValue();
|
||||
if (start < 0) {
|
||||
start = a.length + start;
|
||||
start = length + start;
|
||||
}
|
||||
start = Math.min(a.length, Math.max(0, start));
|
||||
start = Math.min(length, Math.max(0, start));
|
||||
|
||||
if (to == null) {
|
||||
return start < a.length ? a[start] : null;
|
||||
return start >= length ? null :
|
||||
(v.getClass().isArray() ?
|
||||
((Object[]) v)[start] :
|
||||
ExpressionUtils.toObjectList(v).get(start));
|
||||
} else {
|
||||
int end = to != null && to instanceof Number ?
|
||||
((Number) to).intValue() : a.length;
|
||||
((Number) to).intValue() : length;
|
||||
|
||||
if (end < 0) {
|
||||
end = a.length + end;
|
||||
end = length + end;
|
||||
}
|
||||
end = Math.min(a.length, Math.max(start, end));
|
||||
end = Math.min(length, Math.max(start, end));
|
||||
|
||||
if (end > start) {
|
||||
Object[] a2 = new Object[end - start];
|
||||
|
||||
System.arraycopy(a, start, a2, 0, end - start);
|
||||
|
||||
return a2;
|
||||
if (v.getClass().isArray()) {
|
||||
Object[] a2 = new Object[end - start];
|
||||
|
||||
System.arraycopy((Object[]) v, start, a2, 0, end - start);
|
||||
|
||||
return a2;
|
||||
} else {
|
||||
return ExpressionUtils.toObjectList(v).subList(start, end);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.metaweb.gridworks.expr.functions;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.json.JSONException;
|
||||
@ -19,6 +20,8 @@ public class Length implements Function {
|
||||
if (v.getClass().isArray()) {
|
||||
Object[] a = (Object[]) v;
|
||||
return a.length;
|
||||
} else if (v instanceof Collection<?>) {
|
||||
return ((Collection<?>) v).size();
|
||||
} else {
|
||||
String s = (v instanceof String ? (String) v : v.toString());
|
||||
return s.length();
|
||||
|
@ -1,10 +1,12 @@
|
||||
package com.metaweb.gridworks.expr.functions;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONWriter;
|
||||
|
||||
import com.metaweb.gridworks.expr.ExpressionUtils;
|
||||
import com.metaweb.gridworks.gel.Function;
|
||||
|
||||
public class Slice implements Function {
|
||||
@ -16,26 +18,34 @@ public class Slice implements Function {
|
||||
Object to = args.length == 3 ? args[2] : null;
|
||||
|
||||
if (v != null && from != null && from instanceof Number && (to == null || to instanceof Number)) {
|
||||
if (v.getClass().isArray()) {
|
||||
Object[] a = (Object[]) v;
|
||||
if (v.getClass().isArray() || v instanceof List<?>) {
|
||||
int length = v.getClass().isArray() ?
|
||||
((Object[]) v).length :
|
||||
ExpressionUtils.toObjectList(v).size();
|
||||
|
||||
int start = ((Number) from).intValue();
|
||||
int end = to != null && to instanceof Number ?
|
||||
((Number) to).intValue() : a.length;
|
||||
((Number) to).intValue() : length;
|
||||
|
||||
if (start < 0) {
|
||||
start = a.length + start;
|
||||
start = length + start;
|
||||
}
|
||||
start = Math.min(a.length, Math.max(0, start));
|
||||
start = Math.min(length, Math.max(0, start));
|
||||
|
||||
if (end < 0) {
|
||||
end = a.length + end;
|
||||
end = length + end;
|
||||
}
|
||||
end = Math.min(a.length, Math.max(start, end));
|
||||
end = Math.min(length, Math.max(start, end));
|
||||
|
||||
Object[] a2 = new Object[end - start];
|
||||
System.arraycopy(a, start, a2, 0, end - start);
|
||||
|
||||
return a2;
|
||||
if (v.getClass().isArray()) {
|
||||
Object[] a2 = new Object[end - start];
|
||||
|
||||
System.arraycopy((Object[]) v, start, a2, 0, end - start);
|
||||
|
||||
return a2;
|
||||
} else {
|
||||
return ExpressionUtils.toObjectList(v).subList(start, end);
|
||||
}
|
||||
} else {
|
||||
String s = (v instanceof String ? (String) v : v.toString());
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.metaweb.gridworks.expr.functions;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.json.JSONException;
|
||||
@ -23,7 +24,7 @@ public class Type implements Function {
|
||||
return "date";
|
||||
} else if (v instanceof Number) {
|
||||
return "number";
|
||||
} else if (v.getClass().isArray()) {
|
||||
} else if (v.getClass().isArray() || v instanceof List<?>) {
|
||||
return "array";
|
||||
} else {
|
||||
return v.getClass().getName();
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.metaweb.gridworks.expr.functions.arrays;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.json.JSONException;
|
||||
@ -16,20 +17,30 @@ public class Join implements Function {
|
||||
Object v = args[0];
|
||||
Object s = args[1];
|
||||
|
||||
if (v != null && v.getClass().isArray() &&
|
||||
if (v != null && (v.getClass().isArray() || v instanceof List<?>) &&
|
||||
s != null && s instanceof String) {
|
||||
|
||||
Object[] a = (Object[]) v;
|
||||
String separator = (String) s;
|
||||
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for (Object o : a) {
|
||||
if (o != null) {
|
||||
if (sb.length() > 0) {
|
||||
sb.append(separator);
|
||||
}
|
||||
sb.append(o.toString());
|
||||
}
|
||||
if (v.getClass().isArray()) {
|
||||
for (Object o : (Object[]) v) {
|
||||
if (o != null) {
|
||||
if (sb.length() > 0) {
|
||||
sb.append(separator);
|
||||
}
|
||||
sb.append(o.toString());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (Object o : (List<Object>) v) {
|
||||
if (o != null) {
|
||||
if (sb.length() > 0) {
|
||||
sb.append(separator);
|
||||
}
|
||||
sb.append(o.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
|
@ -1,11 +1,13 @@
|
||||
package com.metaweb.gridworks.expr.functions.arrays;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONWriter;
|
||||
|
||||
import com.metaweb.gridworks.expr.EvalError;
|
||||
import com.metaweb.gridworks.expr.ExpressionUtils;
|
||||
import com.metaweb.gridworks.gel.ControlFunctionRegistry;
|
||||
import com.metaweb.gridworks.gel.Function;
|
||||
|
||||
@ -15,14 +17,23 @@ public class Reverse implements Function {
|
||||
if (args.length == 1) {
|
||||
Object v = args[0];
|
||||
|
||||
if (v != null && v.getClass().isArray()) {
|
||||
Object[] a = (Object[]) v;
|
||||
Object[] r = new Object[a.length];
|
||||
|
||||
for (int i = 0; i < a.length; i++) {
|
||||
r[i] = a[r.length - i - 1];
|
||||
if (v != null && (v.getClass().isArray() || v instanceof List<?>)) {
|
||||
int length = v.getClass().isArray() ?
|
||||
((Object[]) v).length :
|
||||
ExpressionUtils.toObjectList(v).size();
|
||||
|
||||
Object[] r = new Object[length];
|
||||
if (v.getClass().isArray()) {
|
||||
Object[] a = (Object[]) v;
|
||||
for (int i = 0; i < length; i++) {
|
||||
r[i] = a[r.length - i - 1];
|
||||
}
|
||||
} else {
|
||||
List<Object> a = ExpressionUtils.toObjectList(v);
|
||||
for (int i = 0; i < length; i++) {
|
||||
r[i] = a.get(r.length - i - 1);
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
package com.metaweb.gridworks.expr.functions.arrays;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.json.JSONException;
|
||||
@ -12,18 +14,25 @@ import com.metaweb.gridworks.gel.Function;
|
||||
|
||||
public class Sort implements Function {
|
||||
|
||||
public Object call(Properties bindings, Object[] args) {
|
||||
@SuppressWarnings("unchecked")
|
||||
public Object call(Properties bindings, Object[] args) {
|
||||
if (args.length == 1) {
|
||||
Object v = args[0];
|
||||
|
||||
|
||||
if (v != null && v.getClass().isArray()) {
|
||||
Object[] a = (Object[]) v;
|
||||
Object[] r = a.clone();
|
||||
|
||||
Arrays.sort(r, 0, r.length);
|
||||
|
||||
return r;
|
||||
if (v != null) {
|
||||
if (v.getClass().isArray()) {
|
||||
Object[] a = (Object[]) v;
|
||||
Object[] r = a.clone();
|
||||
|
||||
Arrays.sort(r, 0, r.length);
|
||||
|
||||
return r;
|
||||
} else if (v instanceof List<?>) {
|
||||
List<? extends Comparable> a = (List<? extends Comparable>) v;
|
||||
Collections.sort(a);
|
||||
|
||||
return a;
|
||||
}
|
||||
}
|
||||
}
|
||||
return new EvalError(ControlFunctionRegistry.getFunctionName(this) + " expects an array");
|
||||
|
@ -0,0 +1,59 @@
|
||||
package com.metaweb.gridworks.expr.functions.math;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONWriter;
|
||||
|
||||
import com.metaweb.gridworks.expr.EvalError;
|
||||
import com.metaweb.gridworks.expr.ExpressionUtils;
|
||||
import com.metaweb.gridworks.gel.ControlFunctionRegistry;
|
||||
import com.metaweb.gridworks.gel.Function;
|
||||
|
||||
public class Sum implements Function {
|
||||
|
||||
public Object call(Properties bindings, Object[] args) {
|
||||
if (args.length == 1) {
|
||||
Object v = args[0];
|
||||
|
||||
if (v != null && (v.getClass().isArray() || v instanceof List<?>)) {
|
||||
int length = v.getClass().isArray() ?
|
||||
((Object[]) v).length :
|
||||
ExpressionUtils.toObjectList(v).size();
|
||||
|
||||
double total = 0;
|
||||
|
||||
if (v.getClass().isArray()) {
|
||||
Object[] a = (Object[]) v;
|
||||
for (int i = 0; i < length; i++) {
|
||||
Object n = a[length - i - 1];
|
||||
if (n instanceof Number) {
|
||||
total += ((Number) n).doubleValue();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
List<Object> a = ExpressionUtils.toObjectList(v);
|
||||
for (int i = 0; i < length; i++) {
|
||||
Object n = a.get(length - i - 1);
|
||||
if (n instanceof Number) {
|
||||
total += ((Number) n).doubleValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
}
|
||||
return new EvalError(ControlFunctionRegistry.getFunctionName(this) + " expects an array of numbers");
|
||||
}
|
||||
|
||||
public void write(JSONWriter writer, Properties options)
|
||||
throws JSONException {
|
||||
|
||||
writer.object();
|
||||
writer.key("description"); writer.value("Sums numbers in array a");
|
||||
writer.key("params"); writer.value("array a");
|
||||
writer.key("returns"); writer.value("number");
|
||||
writer.endObject();
|
||||
}
|
||||
}
|
@ -30,6 +30,7 @@ import com.metaweb.gridworks.expr.functions.math.Min;
|
||||
import com.metaweb.gridworks.expr.functions.math.Mod;
|
||||
import com.metaweb.gridworks.expr.functions.math.Pow;
|
||||
import com.metaweb.gridworks.expr.functions.math.Round;
|
||||
import com.metaweb.gridworks.expr.functions.math.Sum;
|
||||
import com.metaweb.gridworks.expr.functions.strings.Contains;
|
||||
import com.metaweb.gridworks.expr.functions.strings.Diff;
|
||||
import com.metaweb.gridworks.expr.functions.strings.EndsWith;
|
||||
@ -161,6 +162,7 @@ public class ControlFunctionRegistry {
|
||||
registerFunction("ln", new Ln());
|
||||
registerFunction("pow", new Pow());
|
||||
registerFunction("exp", new Exp());
|
||||
registerFunction("sum", new Sum());
|
||||
|
||||
registerFunction("and", new And());
|
||||
registerFunction("or", new Or());
|
||||
|
@ -1,6 +1,8 @@
|
||||
package com.metaweb.gridworks.gel.controls;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
@ -28,7 +30,7 @@ public class ForEach implements Control {
|
||||
Object o = args[0].evaluate(bindings);
|
||||
if (ExpressionUtils.isError(o)) {
|
||||
return o;
|
||||
} else if (o == null || !o.getClass().isArray()) {
|
||||
} else if (o == null || (!o.getClass().isArray() && !(o instanceof Iterable<?>))) {
|
||||
return new EvalError("First argument to forEach is not an array");
|
||||
}
|
||||
|
||||
@ -36,17 +38,36 @@ public class ForEach implements Control {
|
||||
|
||||
Object oldValue = bindings.get(name);
|
||||
try {
|
||||
Object[] values = (Object[]) o;
|
||||
|
||||
List<Object> results = new ArrayList<Object>(values.length);
|
||||
for (Object v : values) {
|
||||
bindings.put(name, v);
|
||||
|
||||
Object r = args[2].evaluate(bindings);
|
||||
|
||||
results.add(r);
|
||||
}
|
||||
List<Object> results = null;
|
||||
|
||||
if (o.getClass().isArray()) {
|
||||
Object[] values = (Object[]) o;
|
||||
|
||||
results = new ArrayList<Object>(values.length);
|
||||
for (Object v : values) {
|
||||
bindings.put(name, v);
|
||||
|
||||
Object r = args[2].evaluate(bindings);
|
||||
|
||||
results.add(r);
|
||||
}
|
||||
} else {
|
||||
results = o instanceof Collection<?> ?
|
||||
new ArrayList<Object>(ExpressionUtils.toObjectCollection(o).size()) :
|
||||
new ArrayList<Object>();
|
||||
|
||||
Iterator<Object> i = ExpressionUtils.toObjectCollection(o).iterator();
|
||||
while (i.hasNext()) {
|
||||
Object v = i.next();
|
||||
|
||||
bindings.put(name, v);
|
||||
|
||||
Object r = args[2].evaluate(bindings);
|
||||
|
||||
results.add(r);
|
||||
}
|
||||
}
|
||||
|
||||
return results.toArray();
|
||||
} finally {
|
||||
if (oldValue != null) {
|
||||
|
@ -3,6 +3,7 @@ package com.metaweb.gridworks.model;
|
||||
import java.io.IOException;
|
||||
import java.io.LineNumberReader;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
@ -26,6 +27,7 @@ public class ColumnModel implements Jsonizable {
|
||||
transient protected Map<String, Column> _nameToColumn;
|
||||
transient protected Map<Integer, Column> _cellIndexToColumn;
|
||||
transient protected List<ColumnGroup> _rootColumnGroups;
|
||||
transient protected List<String> _columnNames;
|
||||
|
||||
public ColumnModel() {
|
||||
internalInitialize();
|
||||
@ -63,6 +65,10 @@ public class ColumnModel implements Jsonizable {
|
||||
public Column getColumnByCellIndex(int cellIndex) {
|
||||
return _cellIndexToColumn.get(cellIndex);
|
||||
}
|
||||
|
||||
public List<String> getColumnNames() {
|
||||
return _columnNames;
|
||||
}
|
||||
|
||||
public void write(JSONWriter writer, Properties options)
|
||||
throws JSONException {
|
||||
@ -171,10 +177,12 @@ public class ColumnModel implements Jsonizable {
|
||||
protected void generateMaps() {
|
||||
_nameToColumn = new HashMap<String, Column>();
|
||||
_cellIndexToColumn = new HashMap<Integer, Column>();
|
||||
_columnNames = new ArrayList<String>();
|
||||
|
||||
for (Column column : columns) {
|
||||
_nameToColumn.put(column.getName(), column);
|
||||
_cellIndexToColumn.put(column.getCellIndex(), column);
|
||||
_columnNames.add(column.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -52,6 +52,10 @@ public class Row implements HasFields, Jsonizable {
|
||||
contextRows.get(0) : rowIndex;
|
||||
|
||||
return new Record(recordRowIndex, rowIndex);
|
||||
} else if ("columnNames".equals(name)) {
|
||||
Project project = (Project) bindings.get("project");
|
||||
|
||||
return project.columnModel.getColumnNames();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -133,6 +133,21 @@ DataTableColumnHeaderUI.prototype._createMenuForColumnHeader = function(elmt) {
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
label: "1-bounded Numeric Log Facet",
|
||||
click: function() {
|
||||
ui.browsingEngine.addFacet(
|
||||
"range",
|
||||
{
|
||||
"name" : self._column.name + ": log(max(1, value))",
|
||||
"columnName" : self._column.name,
|
||||
"expression" : "log(max(1, value))",
|
||||
"mode" : "range"
|
||||
}
|
||||
);
|
||||
}
|
||||
},
|
||||
{},
|
||||
{
|
||||
label: "Text Length Facet",
|
||||
click: function() {
|
||||
|
Loading…
Reference in New Issue
Block a user