Refactoring and adding more functions.

git-svn-id: http://google-refine.googlecode.com/svn/trunk@14 7d457c2a-affb-35e4-300a-418c747d4874
This commit is contained in:
David Huynh 2010-01-31 23:15:50 +00:00
parent e24d40c3da
commit 8b22eb594f
29 changed files with 227 additions and 173 deletions

View File

@ -21,14 +21,14 @@ public class ConjunctiveFilteredRows implements FilteredRows {
boolean ok = true;
for (RowFilter rowFilter : _rowFilters) {
if (!rowFilter.filterRow(row)) {
if (!rowFilter.filterRow(project, i, row)) {
ok = false;
break;
}
}
if (ok) {
visitor.visit(i, row);
visitor.visit(project, i, row);
}
}
}

View File

@ -1,4 +1,4 @@
package com.metaweb.gridlock.browsing.accessors;
package com.metaweb.gridlock.browsing;
import java.util.Properties;

View File

@ -1,8 +1,9 @@
package com.metaweb.gridlock.browsing;
import com.metaweb.gridlock.model.Project;
import com.metaweb.gridlock.model.Row;
public interface RowVisitor {
public boolean visit(int rowIndex, Row row);
public boolean visit(Project project, int rowIndex, Row row);
}

View File

@ -1,7 +0,0 @@
package com.metaweb.gridlock.browsing.accessors;
import com.metaweb.gridlock.model.Cell;
public interface CellAccessor {
public Object[] get(Cell cell, boolean decorated);
}

View File

@ -1,19 +0,0 @@
package com.metaweb.gridlock.browsing.accessors;
import com.metaweb.gridlock.model.Cell;
public class ReconFeatureCellAccessor implements CellAccessor {
final protected String _name;
public ReconFeatureCellAccessor(String name) {
_name = name;
}
@Override
public Object[] get(Cell cell, boolean decorated) {
if (cell.recon != null) {
return new Object[] { cell.recon.features.get(_name) };
}
return null;
}
}

View File

@ -1,15 +0,0 @@
package com.metaweb.gridlock.browsing.accessors;
import com.metaweb.gridlock.model.Cell;
import com.metaweb.gridlock.model.ReconCandidate;
public class ReconTypeAccessor implements CellAccessor {
@Override
public Object[] get(Cell cell, boolean decorated) {
if (cell.recon != null && cell.recon.candidates.size() > 0) {
ReconCandidate c = cell.recon.candidates.get(0);
return c.typeIDs;
}
return null;
}
}

View File

@ -1,13 +0,0 @@
package com.metaweb.gridlock.browsing.accessors;
import com.metaweb.gridlock.model.Cell;
public class ValueCellAccessor implements CellAccessor {
@Override
public Object[] get(Cell cell, boolean decorated) {
if (cell.value != null) {
return new Object[] { cell.value };
}
return null;
}
}

View File

@ -1,53 +0,0 @@
package com.metaweb.gridlock.browsing.facets;
import java.util.HashMap;
import java.util.Map;
import com.metaweb.gridlock.browsing.RowVisitor;
import com.metaweb.gridlock.browsing.accessors.CellAccessor;
import com.metaweb.gridlock.browsing.accessors.DecoratedValue;
import com.metaweb.gridlock.model.Cell;
import com.metaweb.gridlock.model.Row;
public class CellAccessorNominalRowGrouper implements RowVisitor {
final protected CellAccessor _accessor;
final protected int _cellIndex;
final public Map<Object, NominalFacetChoice> choices = new HashMap<Object, NominalFacetChoice>();
public CellAccessorNominalRowGrouper(CellAccessor accessor, int cellIndex) {
_accessor = accessor;
_cellIndex = cellIndex;
}
@Override
public boolean visit(int rowIndex, Row row) {
if (_cellIndex < row.cells.size()) {
Cell cell = row.cells.get(_cellIndex);
if (cell != null) {
Object[] values = _accessor.get(cell, true);
if (values != null && values.length > 0) {
for (Object value : values) {
if (value != null) {
DecoratedValue dValue =
value instanceof DecoratedValue ?
(DecoratedValue) value :
new DecoratedValue(value, value.toString());
Object v = dValue.value;
if (choices.containsKey(v)) {
choices.get(v).count++;
} else {
NominalFacetChoice choice = new NominalFacetChoice(dValue);
choice.count = 1;
choices.put(v, choice);
}
}
}
}
}
}
return false;
}
}

View File

@ -4,10 +4,11 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import com.metaweb.gridlock.browsing.DecoratedValue;
import com.metaweb.gridlock.browsing.RowVisitor;
import com.metaweb.gridlock.browsing.accessors.DecoratedValue;
import com.metaweb.gridlock.expr.Evaluable;
import com.metaweb.gridlock.model.Cell;
import com.metaweb.gridlock.model.Project;
import com.metaweb.gridlock.model.Row;
public class ExpressionNominalRowGrouper implements RowVisitor {
@ -22,13 +23,14 @@ public class ExpressionNominalRowGrouper implements RowVisitor {
}
@Override
public boolean visit(int rowIndex, Row row) {
public boolean visit(Project project, int rowIndex, Row row) {
if (_cellIndex < row.cells.size()) {
Cell cell = row.cells.get(_cellIndex);
if (cell != null) {
Properties bindings = new Properties();
bindings.put("this", cell);
bindings.put("project", project);
bindings.put("cell", cell);
bindings.put("value", cell.value);
Object value = _evaluable.evaluate(bindings);

View File

@ -9,8 +9,8 @@ import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import com.metaweb.gridlock.browsing.DecoratedValue;
import com.metaweb.gridlock.browsing.FilteredRows;
import com.metaweb.gridlock.browsing.accessors.DecoratedValue;
import com.metaweb.gridlock.browsing.filters.ExpressionEqualRowFilter;
import com.metaweb.gridlock.browsing.filters.RowFilter;
import com.metaweb.gridlock.expr.Evaluable;

View File

@ -5,7 +5,7 @@ import java.util.Properties;
import org.json.JSONException;
import org.json.JSONObject;
import com.metaweb.gridlock.browsing.accessors.DecoratedValue;
import com.metaweb.gridlock.browsing.DecoratedValue;
public class NominalFacetChoice {
final public DecoratedValue decoratedValue;

View File

@ -1,37 +0,0 @@
package com.metaweb.gridlock.browsing.filters;
import com.metaweb.gridlock.browsing.accessors.CellAccessor;
import com.metaweb.gridlock.model.Cell;
import com.metaweb.gridlock.model.Row;
public class CellAccessorEqualRowFilter implements RowFilter {
final protected CellAccessor _accessor;
final protected int _cellIndex;
final protected Object[] _matches;
public CellAccessorEqualRowFilter(CellAccessor accessor, int cellIndex, Object[] matches) {
_accessor = accessor;
_cellIndex = cellIndex;
_matches = matches;
}
@Override
public boolean filterRow(Row row) {
if (_cellIndex < row.cells.size()) {
Cell cell = row.cells.get(_cellIndex);
if (cell != null) {
Object[] values = _accessor.get(cell, false);
if (values != null && values.length > 0) {
for (Object v : values) {
for (Object match : _matches) {
if (match.equals(v)) {
return true;
}
}
}
}
}
}
return false;
}
}

View File

@ -4,6 +4,7 @@ import java.util.Properties;
import com.metaweb.gridlock.expr.Evaluable;
import com.metaweb.gridlock.model.Cell;
import com.metaweb.gridlock.model.Project;
import com.metaweb.gridlock.model.Row;
public class ExpressionEqualRowFilter implements RowFilter {
@ -18,13 +19,13 @@ public class ExpressionEqualRowFilter implements RowFilter {
}
@Override
public boolean filterRow(Row row) {
public boolean filterRow(Project project, int rowIndex, Row row) {
if (_cellIndex < row.cells.size()) {
Cell cell = row.cells.get(_cellIndex);
if (cell != null) {
Properties bindings = new Properties();
bindings.put("this", cell);
bindings.put("cell", cell);
bindings.put("value", cell.value);
Object value = _evaluable.evaluate(bindings);

View File

@ -1,7 +1,8 @@
package com.metaweb.gridlock.browsing.filters;
import com.metaweb.gridlock.model.Project;
import com.metaweb.gridlock.model.Row;
public interface RowFilter {
public boolean filterRow(Row row);
public boolean filterRow(Project project, int rowIndex, Row row);
}

View File

@ -44,6 +44,8 @@ public class DoTextTransformCommand extends Command {
Evaluable eval = new Parser(expression).getExpression();
//System.out.println("--- " + eval.toString());
Properties bindings = new Properties();
bindings.put("project", project);
List<CellChange> cellChanges = new ArrayList<CellChange>(project.rows.size());
for (int r = 0; r < project.rows.size(); r++) {
@ -54,7 +56,7 @@ public class DoTextTransformCommand extends Command {
continue;
}
bindings.put("this", cell);
bindings.put("cell", cell);
bindings.put("value", cell.value);
Cell newCell = new Cell();

View File

@ -87,7 +87,7 @@ public class GetRowsCommand extends Command {
}
@Override
public boolean visit(int rowIndex, Row row) {
public boolean visit(Project project, int rowIndex, Row row) {
boolean r = false;
if (total >= start && total < start + limit) {

View File

@ -15,7 +15,7 @@ public class FieldAccessorExpr implements Evaluable {
public Object evaluate(Properties bindings) {
Object o = _inner.evaluate(bindings);
if (o != null && o instanceof HasFields) {
return ((HasFields) o).getField(_fieldName);
return ((HasFields) o).getField(_fieldName, bindings);
}
return null;
}

View File

@ -1,5 +1,7 @@
package com.metaweb.gridlock.expr;
import java.util.Properties;
public interface HasFields {
public Object getField(String name);
public Object getField(String name, Properties bindings);
}

View File

@ -8,7 +8,12 @@ import java.util.Map;
import com.metaweb.gridlock.expr.Scanner.NumberToken;
import com.metaweb.gridlock.expr.Scanner.Token;
import com.metaweb.gridlock.expr.Scanner.TokenType;
import com.metaweb.gridlock.expr.functions.And;
import com.metaweb.gridlock.expr.functions.Get;
import com.metaweb.gridlock.expr.functions.IsNotNull;
import com.metaweb.gridlock.expr.functions.IsNull;
import com.metaweb.gridlock.expr.functions.Not;
import com.metaweb.gridlock.expr.functions.Or;
import com.metaweb.gridlock.expr.functions.Replace;
import com.metaweb.gridlock.expr.functions.Slice;
import com.metaweb.gridlock.expr.functions.Split;
@ -26,11 +31,18 @@ public class Parser {
functionTable.put("toUppercase", new ToUppercase());
functionTable.put("toLowercase", new ToLowercase());
functionTable.put("toTitlecase", new ToTitlecase());
functionTable.put("get", new Get());
functionTable.put("slice", new Slice());
functionTable.put("substring", new Slice());
functionTable.put("get", new Get());
functionTable.put("replace", new Replace());
functionTable.put("split", new Split());
functionTable.put("and", new And());
functionTable.put("or", new Or());
functionTable.put("not", new Not());
functionTable.put("isNull", new IsNull());
functionTable.put("isNotNull", new IsNotNull());
}
public Parser(String s) throws Exception {

View File

@ -0,0 +1,18 @@
package com.metaweb.gridlock.expr.functions;
import java.util.Properties;
import com.metaweb.gridlock.expr.Function;
public class And implements Function {
@Override
public Object call(Properties bindings, Object[] args) {
for (Object o : args) {
if (!Not.objectToBoolean(o)) {
return false;
}
}
return true;
}
}

View File

@ -0,0 +1,14 @@
package com.metaweb.gridlock.expr.functions;
import java.util.Properties;
import com.metaweb.gridlock.expr.Function;
public class IsNotNull implements Function {
@Override
public Object call(Properties bindings, Object[] args) {
return args.length > 0 && args[0] != null;
}
}

View File

@ -0,0 +1,14 @@
package com.metaweb.gridlock.expr.functions;
import java.util.Properties;
import com.metaweb.gridlock.expr.Function;
public class IsNull implements Function {
@Override
public Object call(Properties bindings, Object[] args) {
return args.length == 0 || args[0] == null;
}
}

View File

@ -0,0 +1,21 @@
package com.metaweb.gridlock.expr.functions;
import java.util.Properties;
import com.metaweb.gridlock.expr.Function;
public class Not implements Function {
@Override
public Object call(Properties bindings, Object[] args) {
if (args.length > 0) {
return !objectToBoolean(args[0]);
}
return true;
}
public static boolean objectToBoolean(Object o) {
return o == null ? false : (
(o instanceof Boolean) ? ((Boolean) o).booleanValue() : Boolean.parseBoolean(o.toString()));
}
}

View File

@ -0,0 +1,18 @@
package com.metaweb.gridlock.expr.functions;
import java.util.Properties;
import com.metaweb.gridlock.expr.Function;
public class Or implements Function {
@Override
public Object call(Properties bindings, Object[] args) {
for (Object o : args) {
if (Not.objectToBoolean(o)) {
return true;
}
}
return false;
}
}

View File

@ -26,9 +26,11 @@ public class Cell implements Serializable, HasFields {
}
@Override
public Object getField(String name) {
public Object getField(String name, Properties bindings) {
if ("value".equals(name)) {
return value;
} else if ("recon".equals(name)) {
return recon;
}
return null;
}

View File

@ -4,6 +4,7 @@ import java.io.Serializable;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.json.JSONException;
@ -14,6 +15,8 @@ public class ColumnModel implements Serializable {
public List<Column> columns = new LinkedList<Column>();
transient protected Map<String, Column> _nameToColumn;
public JSONObject getJSON(Properties options) throws JSONException {
JSONObject o = new JSONObject();
@ -25,4 +28,13 @@ public class ColumnModel implements Serializable {
return o;
}
public Column getColumnByName(String name) {
if (_nameToColumn == null) {
for (Column column : columns) {
_nameToColumn.put(column.headerLabel, column);
}
}
return _nameToColumn.get(name);
}
}

View File

@ -10,7 +10,9 @@ import java.util.Properties;
import org.json.JSONException;
import org.json.JSONObject;
public class Recon implements Serializable {
import com.metaweb.gridlock.expr.HasFields;
public class Recon implements Serializable, HasFields {
private static final long serialVersionUID = 8906257833709315762L;
static public enum Judgment {
@ -22,18 +24,45 @@ public class Recon implements Serializable {
public Map<String, Object> features = new HashMap<String, Object>();
public List<ReconCandidate> candidates = new LinkedList<ReconCandidate>();
public Judgment judgment = Judgment.None;
public ReconCandidate match = null;
public JSONObject getJSON(Properties options) throws JSONException {
JSONObject o = new JSONObject();
if (judgment == Judgment.None) {
o.put("j", "none");
} else if (judgment == Judgment.Approve) {
o.put("j", "approve");
} else if (judgment == Judgment.New) {
o.put("j", "new");
}
o.put("j", judgmentToString());
return o;
}
@Override
public Object getField(String name, Properties bindings) {
if ("best".equals(name)) {
return candidates.size() > 0 ? candidates.get(0) : null;
} else if ("judgment".equals(name) || "judgement".equals(name)) {
return judgmentToString();
} else if ("approved".equals(name)) {
return judgment == Judgment.Approve;
} else if ("new".equals(name)) {
return judgment == Judgment.New;
} else if ("match".equals(name)) {
return match;
}
return null;
}
protected String judgmentToString() {
if (judgment == Judgment.Approve) {
return "approve";
} else if (judgment == Judgment.New) {
return "new";
} else {
return "none";
}
}
public class Features implements HasFields {
@Override
public Object getField(String name, Properties bindings) {
return features.get(name);
}
}
}

View File

@ -6,13 +6,16 @@ import java.util.Properties;
import org.json.JSONException;
import org.json.JSONObject;
public class ReconCandidate implements Serializable {
import com.metaweb.gridlock.expr.HasFields;
public class ReconCandidate implements Serializable, HasFields {
private static final long serialVersionUID = -8013997214978715606L;
public String topicID;
public String topicGUID;
public String topicName;
public String[] typeIDs;
public double score;
public JSONObject getJSON(Properties options) throws JSONException {
JSONObject o = new JSONObject();
@ -21,7 +24,24 @@ public class ReconCandidate implements Serializable {
o.put("guid", topicGUID);
o.put("name", topicName);
o.put("types", typeIDs);
o.put("score", score);
return o;
}
@Override
public Object getField(String name, Properties bindings) {
if ("id".equals(name)) {
return topicName;
} else if ("guid".equals(name)) {
return topicGUID;
} else if ("name".equals(name)) {
return topicName;
} else if ("type".equals(name)) {
return typeIDs;
} else if ("score".equals(name)) {
return score;
}
return null;
}
}

View File

@ -8,7 +8,9 @@ import java.util.Properties;
import org.json.JSONException;
import org.json.JSONObject;
public class Row implements Serializable {
import com.metaweb.gridlock.expr.HasFields;
public class Row implements Serializable, HasFields {
private static final long serialVersionUID = -689264211730915507L;
public boolean flagged;
@ -32,4 +34,31 @@ public class Row implements Serializable {
return o;
}
@Override
public Object getField(String name, Properties bindings) {
if ("flagged".equals(name)) {
return flagged;
} else if ("starred".equals(name)) {
return starred;
} else if ("cells".equals(name)) {
return new Cells();
}
return null;
}
public class Cells implements HasFields {
private Cells() {};
@Override
public Object getField(String name, Properties bindings) {
Project project = (Project) bindings.get("project");
Column column = project.columnModel.getColumnByName(name);
if (column != null) {
return cells.get(column.cellIndex);
}
return null;
}
}
}