Merge pull request #1729 from OpenRefine/json-engineconfig

Store engine configuration in dedicated class
This commit is contained in:
Antonin Delpeuch 2018-09-16 18:51:41 +01:00 committed by GitHub
commit d421fd7fbf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
75 changed files with 1320 additions and 608 deletions

View File

@ -25,9 +25,9 @@ package org.openrefine.wikidata.commands;
import javax.servlet.http.HttpServletRequest;
import org.json.JSONObject;
import org.openrefine.wikidata.operations.PerformWikibaseEditsOperation;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.commands.EngineDependentCommand;
import com.google.refine.model.AbstractOperation;
import com.google.refine.model.Project;
@ -35,7 +35,7 @@ import com.google.refine.model.Project;
public class PerformWikibaseEditsCommand extends EngineDependentCommand {
@Override
protected AbstractOperation createOperation(Project project, HttpServletRequest request, JSONObject engineConfig)
protected AbstractOperation createOperation(Project project, HttpServletRequest request, EngineConfig engineConfig)
throws Exception {
String summary = request.getParameter("summary");
return new PerformWikibaseEditsOperation(engineConfig, summary);

View File

@ -49,6 +49,7 @@ import org.wikidata.wdtk.wikibaseapi.WikibaseDataFetcher;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.refine.browsing.Engine;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.history.Change;
import com.google.refine.history.HistoryEntry;
import com.google.refine.model.AbstractOperation;
@ -65,7 +66,7 @@ public class PerformWikibaseEditsOperation extends EngineDependentOperation {
private String summary;
public PerformWikibaseEditsOperation(JSONObject engineConfig, String summary) {
public PerformWikibaseEditsOperation(EngineConfig engineConfig, String summary) {
super(engineConfig);
Validate.notNull(summary, "An edit summary must be provided.");
Validate.notEmpty(summary, "An edit summary must be provided.");
@ -79,7 +80,8 @@ public class PerformWikibaseEditsOperation extends EngineDependentOperation {
if (obj.has("summary")) {
summary = obj.getString("summary");
}
return new PerformWikibaseEditsOperation(engineConfig, summary);
return new PerformWikibaseEditsOperation(
EngineConfig.reconstruct(engineConfig), summary);
}
@Override
@ -93,7 +95,7 @@ public class PerformWikibaseEditsOperation extends EngineDependentOperation {
writer.key("summary");
writer.value(summary);
writer.key("engineConfig");
writer.value(getEngineConfig());
getEngineConfig().write(writer, options);
writer.endObject();
}

View File

@ -32,6 +32,7 @@ import org.openrefine.wikidata.testing.TestingData;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.history.Change;
import com.google.refine.model.AbstractOperation;
import com.google.refine.model.Recon;
@ -58,7 +59,7 @@ public class PerformWikibaseEditsOperationTest extends OperationTest {
@Test(expectedExceptions=IllegalArgumentException.class)
public void testConstructor() {
new PerformWikibaseEditsOperation(new JSONObject("{}"), "");
new PerformWikibaseEditsOperation(EngineConfig.reconstruct(new JSONObject("{}")), "");
}
@Test

View File

@ -55,6 +55,7 @@ import org.wikidata.wdtk.datamodel.interfaces.TimeValue;
import com.fasterxml.jackson.databind.exc.InvalidDefinitionException;
import com.google.refine.browsing.Engine;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.model.Project;
import com.google.refine.tests.RefineTest;
import com.google.refine.util.ParsingUtilities;
@ -149,12 +150,21 @@ public class WikibaseSchemaTest extends RefineTest {
JSONObject serialized = TestingData.jsonFromFile("data/schema/inception.json");
WikibaseSchema schema = WikibaseSchema.reconstruct(serialized);
Engine engine = new Engine(project);
JSONObject engineConfig = new JSONObject("{\n" + " \"mode\": \"row-based\",\n" + " \"facets\": [\n"
+ " {\n" + " \"mode\": \"text\",\n" + " \"invert\": false,\n"
+ " \"caseSensitive\": false,\n" + " \"query\": \"www\",\n"
+ " \"name\": \"reference\",\n" + " \"type\": \"text\",\n"
+ " \"columnName\": \"reference\"\n" + " }\n" + " ]\n" + " }");
engine.initializeFromJSON(engineConfig);
EngineConfig engineConfig = EngineConfig.reconstruct(new JSONObject("{\n"
+ " \"mode\": \"row-based\",\n"
+ " \"facets\": [\n"
+ " {\n"
+ " \"mode\": \"text\",\n"
+ " \"invert\": false,\n"
+ " \"caseSensitive\": false,\n"
+ " \"query\": \"www\",\n"
+ " \"name\": \"reference\",\n"
+ " \"type\": \"text\",\n"
+ " \"columnName\": \"reference\"\n"
+ " }\n"
+ " ]\n"
+ " }"));
engine.initializeFromConfig(engineConfig);
List<ItemUpdate> updates = schema.evaluate(project, engine);
List<ItemUpdate> expected = new ArrayList<>();
ItemUpdate update1 = new ItemUpdateBuilder(qid1).addStatement(statement1).build();

View File

@ -33,22 +33,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.refine.browsing;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import java.util.stream.Collectors;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONWriter;
import com.google.refine.Jsonizable;
import com.google.refine.browsing.facets.Facet;
import com.google.refine.browsing.facets.ListFacet;
import com.google.refine.browsing.facets.RangeFacet;
import com.google.refine.browsing.facets.ScatterplotFacet;
import com.google.refine.browsing.facets.TextSearchFacet;
import com.google.refine.browsing.facets.TimeRangeFacet;
import com.google.refine.browsing.util.ConjunctiveFilteredRecords;
import com.google.refine.browsing.util.ConjunctiveFilteredRows;
import com.google.refine.browsing.util.FilteredRecordsAsFilteredRows;
@ -71,7 +67,7 @@ public class Engine implements Jsonizable {
protected Project _project;
protected List<Facet> _facets = new LinkedList<Facet>();
protected Mode _mode = Mode.RowBased;
protected EngineConfig _config = new EngineConfig(Collections.emptyList(), Mode.RowBased);
static public String modeToString(Mode mode) {
return mode == Mode.RowBased ? MODE_ROW_BASED : MODE_RECORD_BASED;
@ -85,10 +81,10 @@ public class Engine implements Jsonizable {
}
public Mode getMode() {
return _mode;
return _config.getMode();
}
public void setMode(Mode mode) {
_mode = mode;
_config = new EngineConfig(_config.getFacetConfigs(), mode);
}
public FilteredRows getAllRows() {
@ -117,9 +113,9 @@ public class Engine implements Jsonizable {
}
public FilteredRows getFilteredRows(Facet except) {
if (_mode == Mode.RecordBased) {
if (_config.getMode().equals(Mode.RecordBased)) {
return new FilteredRecordsAsFilteredRows(getFilteredRecords(except));
} else if (_mode == Mode.RowBased) {
} else if (_config.getMode().equals(Mode.RowBased)) {
ConjunctiveFilteredRows cfr = new ConjunctiveFilteredRows();
for (Facet facet : _facets) {
if (facet != except) {
@ -157,7 +153,7 @@ public class Engine implements Jsonizable {
}
public FilteredRecords getFilteredRecords(Facet except) {
if (_mode == Mode.RecordBased) {
if (_config.getMode().equals(Mode.RecordBased)) {
ConjunctiveFilteredRecords cfr = new ConjunctiveFilteredRecords();
for (Facet facet : _facets) {
if (facet != except) {
@ -172,57 +168,27 @@ public class Engine implements Jsonizable {
throw new InternalError("This method should not be called when the engine is not in record mode.");
}
@Deprecated
public void initializeFromJSON(JSONObject o) throws JSONException {
if (o == null) {
return;
}
if (o.has("facets") && !o.isNull("facets")) {
JSONArray a = o.getJSONArray("facets");
int length = a.length();
for (int i = 0; i < length; i++) {
JSONObject fo = a.getJSONObject(i);
String type = fo.has("type") ? fo.getString("type") : "list";
Facet facet = null;
if ("list".equals(type)) {
facet = new ListFacet();
} else if ("range".equals(type)) {
facet = new RangeFacet();
} else if ("timerange".equals(type)) {
facet = new TimeRangeFacet();
} else if ("scatterplot".equals(type)) {
facet = new ScatterplotFacet();
} else if ("text".equals(type)) {
facet = new TextSearchFacet();
}
if (facet != null) {
facet.initializeFromJSON(_project, fo);
_facets.add(facet);
}
}
}
// for backward compatibility
if (o.has(INCLUDE_DEPENDENT) && !o.isNull(INCLUDE_DEPENDENT)) {
_mode = o.getBoolean(INCLUDE_DEPENDENT) ? Mode.RecordBased : Mode.RowBased;
}
if (o.has(MODE) && !o.isNull(MODE)) {
_mode = MODE_ROW_BASED.equals(o.getString(MODE)) ? Mode.RowBased : Mode.RecordBased;
}
EngineConfig config = EngineConfig.reconstruct(o);
initializeFromConfig(config);
}
public void initializeFromConfig(EngineConfig config) {
_config = config;
_facets = config.getFacetConfigs().stream()
.map(c -> c.apply(_project))
.collect(Collectors.toList());
}
public void computeFacets() throws JSONException {
if (_mode == Mode.RowBased) {
if (_config.getMode().equals(Mode.RowBased)) {
for (Facet facet : _facets) {
FilteredRows filteredRows = getFilteredRows(facet);
facet.computeChoices(_project, filteredRows);
}
} else if (_mode == Mode.RecordBased) {
} else if (_config.getMode().equals(Mode.RecordBased)) {
for (Facet facet : _facets) {
FilteredRecords filteredRecords = getFilteredRecords(facet);
@ -244,7 +210,7 @@ public class Engine implements Jsonizable {
facet.write(writer, options);
}
writer.endArray();
writer.key(MODE); writer.value(_mode == Mode.RowBased ? MODE_ROW_BASED : MODE_RECORD_BASED);
writer.key(MODE); writer.value(_config.getMode().equals(Mode.RowBased) ? MODE_ROW_BASED : MODE_RECORD_BASED);
writer.endObject();
}
}

View File

@ -0,0 +1,102 @@
package com.google.refine.browsing;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONWriter;
import com.google.refine.Jsonizable;
import com.google.refine.browsing.Engine.Mode;
import com.google.refine.browsing.facets.FacetConfig;
import com.google.refine.browsing.facets.ListFacet.ListFacetConfig;
import com.google.refine.browsing.facets.RangeFacet.RangeFacetConfig;
import com.google.refine.browsing.facets.ScatterplotFacet.ScatterplotFacetConfig;
import com.google.refine.browsing.facets.TextSearchFacet.TextSearchFacetConfig;
import com.google.refine.browsing.facets.TimeRangeFacet.TimeRangeFacetConfig;
public class EngineConfig implements Jsonizable {
protected final List<FacetConfig> _facets;
protected final Mode _mode;
public EngineConfig(List<FacetConfig> facets, Mode mode) {
_facets = facets;
_mode = mode;
}
public Mode getMode() {
return _mode;
}
public List<FacetConfig> getFacetConfigs() {
return _facets;
}
public static EngineConfig reconstruct(JSONObject o) {
if (o == null) {
return new EngineConfig(Collections.emptyList(), Mode.RowBased);
}
List<FacetConfig> facets = new LinkedList<>();
if (o.has("facets") && !o.isNull("facets")) {
JSONArray a = o.getJSONArray("facets");
int length = a.length();
for (int i = 0; i < length; i++) {
JSONObject fo = a.getJSONObject(i);
String type = fo.has("type") ? fo.getString("type") : "list";
FacetConfig facet = null;
if ("list".equals(type)) {
facet = new ListFacetConfig();
} else if ("range".equals(type)) {
facet = new RangeFacetConfig();
} else if ("timerange".equals(type)) {
facet = new TimeRangeFacetConfig();
} else if ("scatterplot".equals(type)) {
facet = new ScatterplotFacetConfig();
} else if ("text".equals(type)) {
facet = new TextSearchFacetConfig();
}
if (facet != null) {
facet.initializeFromJSON(fo);
facets.add(facet);
}
}
}
Mode mode = Mode.RowBased;
// for backward compatibility
if (o.has(Engine.INCLUDE_DEPENDENT) && !o.isNull(Engine.INCLUDE_DEPENDENT)) {
mode = o.getBoolean(Engine.INCLUDE_DEPENDENT) ? Mode.RecordBased : Mode.RowBased;
}
if (o.has(Engine.MODE) && !o.isNull(Engine.MODE)) {
mode = Engine.MODE_ROW_BASED.equals(o.getString(Engine.MODE)) ? Mode.RowBased : Mode.RecordBased;
}
return new EngineConfig(facets, mode);
}
@Override
public void write(JSONWriter writer, Properties options)
throws JSONException {
writer.object();
writer.key("facets");
writer.array();
for (FacetConfig facet : _facets) {
facet.write(writer, options);
}
writer.endArray();
writer.key(Engine.MODE); writer.value(_mode == Mode.RowBased ? Engine.MODE_ROW_BASED : Engine.MODE_RECORD_BASED);
writer.endObject();
}
}

View File

@ -33,9 +33,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.refine.browsing.facets;
import org.json.JSONException;
import org.json.JSONObject;
import com.google.refine.Jsonizable;
import com.google.refine.browsing.FilteredRecords;
import com.google.refine.browsing.FilteredRows;
@ -54,6 +51,4 @@ public interface Facet extends Jsonizable {
public void computeChoices(Project project, FilteredRows filteredRows);
public void computeChoices(Project project, FilteredRecords filteredRecords);
public void initializeFromJSON(Project project, JSONObject o) throws JSONException;
}

View File

@ -0,0 +1,31 @@
package com.google.refine.browsing.facets;
import org.json.JSONObject;
import com.google.refine.Jsonizable;
import com.google.refine.model.Project;
/**
* Represents the configuration of a facet, as stored
* in the engine configuration and in the JSON serialization
* of operations. It does not contain the actual values displayed by
* the facet.
*
* @author antonin
*
*/
public interface FacetConfig extends Jsonizable {
/**
* Reads the facet configuration from a JSON object (will be removed once we migrate to Jackson)
* @param fo
*/
public void initializeFromJSON(JSONObject fo);
/**
* Instantiates the given facet on a particular project.
* @param project
* @return a computed facet on the given project.
*/
public Facet apply(Project project);
}

View File

@ -63,18 +63,80 @@ public class ListFacet implements Facet {
/*
* Configuration
*/
protected String _name;
protected String _expression;
protected String _columnName;
protected boolean _invert;
public static class ListFacetConfig implements FacetConfig {
public String name;
public String expression;
public String columnName;
public boolean invert;
// If true, then facet won't show the blank and error choices
public boolean omitBlank;
public boolean omitError;
public List<DecoratedValue> selection = new LinkedList<>();
public boolean selectBlank;
public boolean selectError;
@Override
public void write(JSONWriter writer, Properties options)
throws JSONException {
writer.object();
writer.key("type"); writer.value("list");
writer.key("name"); writer.value(name);
writer.key("expression"); writer.value(expression);
writer.key("columnName"); writer.value(columnName);
writer.key("invert"); writer.value(invert);
writer.key("selection"); writer.array();
for (DecoratedValue choice : selection) {
writer.object();
writer.key("v");
choice.write(writer, options);
writer.endObject();
}
writer.endArray();
writer.key("omitBlank"); writer.value(omitBlank);
writer.key("selectBlank"); writer.value(selectBlank);
writer.key("omitError"); writer.value(omitError);
writer.key("selectError"); writer.value(selectError);
writer.endObject();
}
@Override
public void initializeFromJSON(JSONObject o) {
name = o.getString("name");
expression = o.getString("expression");
columnName = o.getString("columnName");
invert = o.has("invert") && o.getBoolean("invert");
JSONArray a = o.getJSONArray("selection");
int length = a.length();
for (int i = 0; i < length; i++) {
JSONObject oc = a.getJSONObject(i);
JSONObject ocv = oc.getJSONObject("v");
DecoratedValue decoratedValue = new DecoratedValue(
ocv.get("v"), ocv.getString("l"));
selection.add(decoratedValue);
}
omitBlank = JSONUtilities.getBoolean(o, "omitBlank", false);
omitError = JSONUtilities.getBoolean(o, "omitError", false);
selectBlank = JSONUtilities.getBoolean(o, "selectBlank", false);
selectError = JSONUtilities.getBoolean(o, "selectError", false);
}
@Override
public Facet apply(Project project) {
ListFacet facet = new ListFacet();
facet.initializeFromConfig(this, project);
return facet;
}
}
// If true, then facet won't show the blank and error choices
protected boolean _omitBlank;
protected boolean _omitError;
protected List<NominalFacetChoice> _selection = new LinkedList<NominalFacetChoice>();
protected boolean _selectBlank;
protected boolean _selectError;
ListFacetConfig _config = new ListFacetConfig();
/*
* Derived configuration
@ -98,10 +160,10 @@ public class ListFacet implements Facet {
throws JSONException {
writer.object();
writer.key("name"); writer.value(_name);
writer.key("expression"); writer.value(_expression);
writer.key("columnName"); writer.value(_columnName);
writer.key("invert"); writer.value(_invert);
writer.key("name"); writer.value(_config.name);
writer.key("expression"); writer.value(_config.expression);
writer.key("columnName"); writer.value(_config.columnName);
writer.key("invert"); writer.value(_config.invert);
if (_errorMessage != null) {
writer.key("error"); writer.value(_errorMessage);
@ -115,17 +177,17 @@ public class ListFacet implements Facet {
}
writer.endArray();
if (!_omitBlank && (_selectBlank || _blankCount > 0)) {
if (!_config.omitBlank && (_config.selectBlank || _blankCount > 0)) {
writer.key("blankChoice");
writer.object();
writer.key("s"); writer.value(_selectBlank);
writer.key("s"); writer.value(_config.selectBlank);
writer.key("c"); writer.value(_blankCount);
writer.endObject();
}
if (!_omitError && (_selectError || _errorCount > 0)) {
if (!_config.omitError && (_config.selectError || _errorCount > 0)) {
writer.key("errorChoice");
writer.object();
writer.key("s"); writer.value(_selectError);
writer.key("s"); writer.value(_config.selectError);
writer.key("c"); writer.value(_errorCount);
writer.endObject();
}
@ -150,54 +212,25 @@ public class ListFacet implements Facet {
}
return 2000;
}
@Override
public void initializeFromJSON(Project project, JSONObject o) throws JSONException {
_name = o.getString("name");
_expression = o.getString("expression");
_columnName = o.getString("columnName");
_invert = o.has("invert") && o.getBoolean("invert");
if (_columnName.length() > 0) {
Column column = project.columnModel.getColumnByName(_columnName);
public void initializeFromConfig(ListFacetConfig config, Project project) {
_config = config;
if (_config.columnName.length() > 0) {
Column column = project.columnModel.getColumnByName(_config.columnName);
if (column != null) {
_cellIndex = column.getCellIndex();
} else {
_errorMessage = "No column named " + _columnName;
_errorMessage = "No column named " + _config.columnName;
}
} else {
_cellIndex = -1;
}
try {
_eval = MetaParser.parse(_expression);
_eval = MetaParser.parse(_config.expression);
} catch (ParsingException e) {
_errorMessage = e.getMessage();
}
_selection.clear();
JSONArray a = o.getJSONArray("selection");
int length = a.length();
for (int i = 0; i < length; i++) {
JSONObject oc = a.getJSONObject(i);
JSONObject ocv = oc.getJSONObject("v");
DecoratedValue decoratedValue = new DecoratedValue(
ocv.get("v"), ocv.getString("l"));
NominalFacetChoice nominalFacetChoice = new NominalFacetChoice(decoratedValue);
nominalFacetChoice.selected = true;
_selection.add(nominalFacetChoice);
}
_omitBlank = JSONUtilities.getBoolean(o, "omitBlank", false);
_omitError = JSONUtilities.getBoolean(o, "omitError", false);
_selectBlank = JSONUtilities.getBoolean(o, "selectBlank", false);
_selectError = JSONUtilities.getBoolean(o, "selectError", false);
}
@Override
@ -205,23 +238,23 @@ public class ListFacet implements Facet {
return
_eval == null ||
_errorMessage != null ||
(_selection.size() == 0 && !_selectBlank && !_selectError) ?
(_config.selection.size() == 0 && !_config.selectBlank && !_config.selectError) ?
null :
new ExpressionEqualRowFilter(
_eval,
_columnName,
_config.columnName,
_cellIndex,
createMatches(),
_selectBlank,
_selectError,
_invert);
_config.selectBlank,
_config.selectError,
_config.invert);
}
@Override
public RecordFilter getRecordFilter(Project project) {
RowFilter rowFilter = getRowFilter(project);
return rowFilter == null ? null :
(_invert ?
(_config.invert ?
new AllRowsRecordFilter(rowFilter) :
new AnyRowRecordFilter(rowFilter));
}
@ -230,7 +263,7 @@ public class ListFacet implements Facet {
public void computeChoices(Project project, FilteredRows filteredRows) {
if (_eval != null && _errorMessage == null) {
ExpressionNominalValueGrouper grouper =
new ExpressionNominalValueGrouper(_eval, _columnName, _cellIndex);
new ExpressionNominalValueGrouper(_eval, _config.columnName, _cellIndex);
filteredRows.accept(project, grouper);
@ -242,7 +275,7 @@ public class ListFacet implements Facet {
public void computeChoices(Project project, FilteredRecords filteredRecords) {
if (_eval != null && _errorMessage == null) {
ExpressionNominalValueGrouper grouper =
new ExpressionNominalValueGrouper(_eval, _columnName, _cellIndex);
new ExpressionNominalValueGrouper(_eval, _config.columnName, _cellIndex);
filteredRecords.accept(project, grouper);
@ -254,8 +287,8 @@ public class ListFacet implements Facet {
_choices.clear();
_choices.addAll(grouper.choices.values());
for (NominalFacetChoice choice : _selection) {
String valueString = choice.decoratedValue.value.toString();
for (DecoratedValue decoratedValue : _config.selection) {
String valueString = decoratedValue.value.toString();
if (grouper.choices.containsKey(valueString)) {
grouper.choices.get(valueString).selected = true;
@ -270,6 +303,7 @@ public class ListFacet implements Facet {
* won't be able to detect the "bicycle" choice, so we need to inject
* that choice into the choice list ourselves.
*/
NominalFacetChoice choice = new NominalFacetChoice(decoratedValue);
choice.count = 0;
_choices.add(choice);
}
@ -280,9 +314,9 @@ public class ListFacet implements Facet {
}
protected Object[] createMatches() {
Object[] a = new Object[_selection.size()];
Object[] a = new Object[_config.selection.size()];
for (int i = 0; i < a.length; i++) {
a[i] = _selection.get(i).decoratedValue.value;
a[i] = _config.selection.get(i).value;
}
return a;
}

View File

@ -62,17 +62,68 @@ public class RangeFacet implements Facet {
/*
* Configuration, from the client side
*/
protected String _name; // name of facet
protected String _expression; // expression to compute numeric value(s) per row
protected String _columnName; // column to base expression on, if any
protected double _from; // the numeric selection
protected double _to;
protected boolean _selectNumeric; // whether the numeric selection applies, default true
protected boolean _selectNonNumeric;
protected boolean _selectBlank;
protected boolean _selectError;
public static class RangeFacetConfig implements FacetConfig {
protected String _name; // name of facet
protected String _expression; // expression to compute numeric value(s) per row
protected String _columnName; // column to base expression on, if any
protected double _from; // the numeric selection
protected double _to;
protected boolean _selectNumeric; // whether the numeric selection applies, default true
protected boolean _selectNonNumeric;
protected boolean _selectBlank;
protected boolean _selectError;
protected boolean _selected; // false if we're certain that all rows will match
// and there isn't any filtering to do
@Override
public void write(JSONWriter writer, Properties options)
throws JSONException {
writer.object();
writer.key("type"); writer.value("range");
writer.key("name"); writer.value(_name);
writer.key("expression"); writer.value(_expression);
writer.key("columnName"); writer.value(_columnName);
writer.key(FROM); writer.value(_from);
writer.key(TO); writer.value(_to);
writer.key("selectNumeric"); writer.value(_selectNumeric);
writer.key("selectNonNumeric"); writer.value(_selectNonNumeric);
writer.key("selectError"); writer.value(_selectError);
writer.key("selectBlank"); writer.value(_selectBlank);
writer.endObject();
}
@Override
public void initializeFromJSON(JSONObject o) {
_name = o.getString("name");
_expression = o.getString("expression");
_columnName = o.getString("columnName");
if (o.has(FROM) || o.has(TO)) {
_from = o.has(FROM) ? o.getDouble(FROM) : 0;
_to = o.has(TO) ? o.getDouble(TO) : 0;
_selected = true;
}
_selectNumeric = JSONUtilities.getBoolean(o, "selectNumeric", true);
_selectNonNumeric = JSONUtilities.getBoolean(o, "selectNonNumeric", true);
_selectBlank = JSONUtilities.getBoolean(o, "selectBlank", true);
_selectError = JSONUtilities.getBoolean(o, "selectError", true);
if (!_selectNumeric || !_selectNonNumeric || !_selectBlank || !_selectError) {
_selected = true;
}
}
@Override
public RangeFacet apply(Project project) {
RangeFacet facet = new RangeFacet();
facet.initializeFromConfig(this, project);
return facet;
}
}
RangeFacetConfig _config = new RangeFacetConfig();
/*
* Derived configuration data
@ -80,8 +131,6 @@ public class RangeFacet implements Facet {
protected int _cellIndex;
protected Evaluable _eval;
protected String _errorMessage;
protected boolean _selected; // false if we're certain that all rows will match
// and there isn't any filtering to do
/*
* Computed data, to return to the client side
@ -115,9 +164,9 @@ public class RangeFacet implements Facet {
throws JSONException {
writer.object();
writer.key("name"); writer.value(_name);
writer.key("expression"); writer.value(_expression);
writer.key("columnName"); writer.value(_columnName);
writer.key("name"); writer.value(_config._name);
writer.key("expression"); writer.value(_config._expression);
writer.key("columnName"); writer.value(_config._columnName);
if (_errorMessage != null) {
writer.key("error"); writer.value(_errorMessage);
@ -139,8 +188,8 @@ public class RangeFacet implements Facet {
}
writer.endArray();
writer.key(FROM); writer.value(_from);
writer.key(TO); writer.value(_to);
writer.key(FROM); writer.value(_config._from);
writer.key(TO); writer.value(_config._to);
} else {
writer.key("error"); writer.value("No numeric value present.");
}
@ -157,55 +206,37 @@ public class RangeFacet implements Facet {
}
writer.endObject();
}
@Override
public void initializeFromJSON(Project project, JSONObject o) throws JSONException {
_name = o.getString("name");
_expression = o.getString("expression");
_columnName = o.getString("columnName");
public void initializeFromConfig(RangeFacetConfig config, Project project) {
_config = config;
if (_columnName.length() > 0) {
Column column = project.columnModel.getColumnByName(_columnName);
if (_config._columnName.length() > 0) {
Column column = project.columnModel.getColumnByName(_config._columnName);
if (column != null) {
_cellIndex = column.getCellIndex();
} else {
_errorMessage = "No column named " + _columnName;
_errorMessage = "No column named " + _config._columnName;
}
} else {
_cellIndex = -1;
}
try {
_eval = MetaParser.parse(_expression);
_eval = MetaParser.parse(_config._expression);
} catch (ParsingException e) {
_errorMessage = e.getMessage();
}
if (o.has(FROM) || o.has(TO)) {
_from = o.has(FROM) ? o.getDouble(FROM) : _min;
_to = o.has(TO) ? o.getDouble(TO) : _max;
_selected = true;
}
_selectNumeric = JSONUtilities.getBoolean(o, "selectNumeric", true);
_selectNonNumeric = JSONUtilities.getBoolean(o, "selectNonNumeric", true);
_selectBlank = JSONUtilities.getBoolean(o, "selectBlank", true);
_selectError = JSONUtilities.getBoolean(o, "selectError", true);
if (!_selectNumeric || !_selectNonNumeric || !_selectBlank || !_selectError) {
_selected = true;
}
}
@Override
public RowFilter getRowFilter(Project project) {
if (_eval != null && _errorMessage == null && _selected) {
if (_eval != null && _errorMessage == null && _config._selected) {
return new ExpressionNumberComparisonRowFilter(
getRowEvaluable(project), _selectNumeric, _selectNonNumeric, _selectBlank, _selectError) {
getRowEvaluable(project), _config._selectNumeric, _config._selectNonNumeric, _config._selectBlank, _config._selectError) {
@Override
protected boolean checkValue(double d) {
return d >= _from && d < _to;
return d >= _config._from && d < _config._to;
};
};
} else {
@ -225,7 +256,7 @@ public class RangeFacet implements Facet {
RowEvaluable rowEvaluable = getRowEvaluable(project);
Column column = project.columnModel.getColumnByCellIndex(_cellIndex);
String key = "numeric-bin:row-based:" + _expression;
String key = "numeric-bin:row-based:" + _config._expression;
NumericBinIndex index = (NumericBinIndex) column.getPrecompute(key);
if (index == null) {
index = new NumericBinRowIndex(project, rowEvaluable);
@ -248,7 +279,7 @@ public class RangeFacet implements Facet {
RowEvaluable rowEvaluable = getRowEvaluable(project);
Column column = project.columnModel.getColumnByCellIndex(_cellIndex);
String key = "numeric-bin:record-based:" + _expression;
String key = "numeric-bin:record-based:" + _config._expression;
NumericBinIndex index = (NumericBinIndex) column.getPrecompute(key);
if (index == null) {
index = new NumericBinRecordIndex(project, rowEvaluable);
@ -267,7 +298,7 @@ public class RangeFacet implements Facet {
}
protected RowEvaluable getRowEvaluable(Project project) {
return new ExpressionBasedRowEvaluable(_columnName, _cellIndex, _eval);
return new ExpressionBasedRowEvaluable(_config._columnName, _cellIndex, _eval);
}
protected void retrieveDataFromBaseBinIndex(NumericBinIndex index) {
@ -281,12 +312,12 @@ public class RangeFacet implements Facet {
_baseBlankCount = index.getBlankRowCount();
_baseErrorCount = index.getErrorRowCount();
if (_selected) {
_from = Math.max(_from, _min);
_to = Math.min(_to, _max);
if (_config._selected) {
_config._from = Math.max(_config._from, _min);
_config._to = Math.min(_config._to, _max);
} else {
_from = _min;
_to = _max;
_config._from = _min;
_config._to = _max;
}
}

View File

@ -79,30 +79,122 @@ public class ScatterplotFacet implements Facet {
/*
* Configuration, from the client side
*/
protected String name; // name of facet
protected String expression_x; // expression to compute the x numeric value(s) per row
protected String expression_y; // expression to compute the y numeric value(s) per row
protected String columnName_x; // column to base the x expression on, if any
protected String columnName_y; // column to base the y expression on, if any
public static class ScatterplotFacetConfig implements FacetConfig {
protected String name; // name of facet
protected int size;
protected int dim_x;
protected int dim_y;
protected int rotation;
protected double l;
protected double dot;
protected String image;
protected String expression_x; // expression to compute the x numeric value(s) per row
protected String expression_y; // expression to compute the y numeric value(s) per row
protected String columnName_x; // column to base the x expression on, if any
protected String columnName_y; // column to base the y expression on, if any
protected int size;
protected int dim_x;
protected int dim_y;
protected String rotation_str;
protected int rotation;
protected String color_str;
protected Color color;
protected double l;
protected double dot;
protected double from_x; // the numeric selection for the x axis, from 0 to 1
protected double to_x;
protected double from_y; // the numeric selection for the y axis, from 0 to 1
protected double to_y;
protected String color_str;
protected Color color;
protected double from_x; // the numeric selection for the x axis, from 0 to 1
protected double to_x;
protected double from_y; // the numeric selection for the y axis, from 0 to 1
protected double to_y;
protected boolean selected; // false if we're certain that all rows will match
// and there isn't any filtering to do
@Override
public void write(JSONWriter writer, Properties options)
throws JSONException {
writer.object();
writer.key("type"); writer.value("scatterplot");
writer.key(NAME); writer.value(name);
writer.key(X_COLUMN_NAME); writer.value(columnName_x);
writer.key(X_EXPRESSION); writer.value(expression_x);
writer.key(Y_COLUMN_NAME); writer.value(columnName_y);
writer.key(Y_EXPRESSION); writer.value(expression_y);
writer.key(SIZE); writer.value(size);
writer.key(DOT); writer.value(dot);
if(!rotation_str.isEmpty()) {
writer.key(ROTATION); writer.value(rotation_str);
}
writer.key(DIM_X); writer.value(dim_x == LIN ? "lin" : "log");
writer.key(DIM_Y); writer.value(dim_y == LIN ? "lin" : "log");
if(!"000000".equals(color_str)) {
writer.key(COLOR); writer.value(color_str);
}
writer.key(FROM_X); writer.value(from_x);
writer.key(TO_X); writer.value(to_x);
writer.key(FROM_Y); writer.value(from_y);
writer.key(TO_Y); writer.value(to_y);
writer.endObject();
}
@Override
public ScatterplotFacet apply(Project project) {
ScatterplotFacet facet = new ScatterplotFacet();
facet.initializeFromConfig(this, project);
return facet;
}
@Override
public void initializeFromJSON(JSONObject o) {
name = o.getString(NAME);
l = size = (o.has(SIZE)) ? o.getInt(SIZE) : 100;
dot = (o.has(DOT)) ? o.getInt(DOT) : 0.5d;
dim_x = (o.has(DIM_X)) ? getAxisDim(o.getString(DIM_X)) : LIN;
if (o.has(FROM_X) && o.has(TO_X)) {
from_x = o.getDouble(FROM_X);
to_x = o.getDouble(TO_X);
selected = true;
} else {
from_x = 0;
to_x = 1;
}
dim_y = (o.has(DIM_Y)) ? getAxisDim(o.getString(DIM_Y)) : LIN;
if (o.has(FROM_Y) && o.has(TO_Y)) {
from_y = o.getDouble(FROM_Y);
to_y = o.getDouble(TO_Y);
selected = true;
} else {
from_y = 0;
to_y = 1;
}
rotation_str = (o.has(ROTATION) ? o.getString(ROTATION) : "");
rotation = getRotation(rotation_str);
color_str = (o.has(COLOR)) ? o.getString(COLOR) : "000000";
color = new Color(Integer.parseInt(color_str,16));
columnName_x = o.getString(X_COLUMN_NAME);
expression_x = o.getString(X_EXPRESSION);
columnName_y = o.getString(Y_COLUMN_NAME);
expression_y = o.getString(Y_EXPRESSION);
}
public static int getRotation(String rotation) {
rotation = rotation.toLowerCase();
if ("cw".equals(rotation) || "right".equals(rotation)) {
return ScatterplotFacet.ROTATE_CW;
} else if ("ccw".equals(rotation) || "left".equals(rotation)) {
return ScatterplotFacet.ROTATE_CCW;
} else {
return NO_ROTATION;
}
}
}
ScatterplotFacetConfig config;
/*
* Derived configuration data
@ -120,8 +212,8 @@ public class ScatterplotFacet implements Facet {
protected double max_y;
protected AffineTransform t;
protected boolean selected; // false if we're certain that all rows will match
// and there isn't any filtering to do
protected String image;
public static final String NAME = "name";
public static final String IMAGE = "image";
@ -168,17 +260,17 @@ public class ScatterplotFacet implements Facet {
writer.object();
writer.key(NAME); writer.value(name);
writer.key(X_COLUMN_NAME); writer.value(columnName_x);
writer.key(X_EXPRESSION); writer.value(expression_x);
writer.key(Y_COLUMN_NAME); writer.value(columnName_y);
writer.key(Y_EXPRESSION); writer.value(expression_y);
writer.key(SIZE); writer.value(size);
writer.key(DOT); writer.value(dot);
writer.key(ROTATION); writer.value(rotation);
writer.key(DIM_X); writer.value(dim_x);
writer.key(DIM_Y); writer.value(dim_y);
writer.key(COLOR); writer.value(color_str);
writer.key(NAME); writer.value(config.name);
writer.key(X_COLUMN_NAME); writer.value(config.columnName_x);
writer.key(X_EXPRESSION); writer.value(config.expression_x);
writer.key(Y_COLUMN_NAME); writer.value(config.columnName_y);
writer.key(Y_EXPRESSION); writer.value(config.expression_y);
writer.key(SIZE); writer.value(config.size);
writer.key(DOT); writer.value(config.dot);
writer.key(ROTATION); writer.value(config.rotation);
writer.key(DIM_X); writer.value(config.dim_x);
writer.key(DIM_Y); writer.value(config.dim_y);
writer.key(COLOR); writer.value(config.color_str);
if (IMAGE_URI) {
writer.key(IMAGE); writer.value(image);
@ -188,8 +280,8 @@ public class ScatterplotFacet implements Facet {
writer.key(ERROR_X); writer.value(errorMessage_x);
} else {
if (!Double.isInfinite(min_x) && !Double.isInfinite(max_x)) {
writer.key(FROM_X); writer.value(from_x);
writer.key(TO_X); writer.value(to_x);
writer.key(FROM_X); writer.value(config.from_x);
writer.key(TO_X); writer.value(config.to_x);
}
}
@ -197,90 +289,57 @@ public class ScatterplotFacet implements Facet {
writer.key(ERROR_Y); writer.value(errorMessage_y);
} else {
if (!Double.isInfinite(min_y) && !Double.isInfinite(max_y)) {
writer.key(FROM_Y); writer.value(from_y);
writer.key(TO_Y); writer.value(to_y);
writer.key(FROM_Y); writer.value(config.from_y);
writer.key(TO_Y); writer.value(config.to_y);
}
}
writer.endObject();
}
@Override
public void initializeFromJSON(Project project, JSONObject o) throws JSONException {
name = o.getString(NAME);
l = size = (o.has(SIZE)) ? o.getInt(SIZE) : 100;
dot = (o.has(DOT)) ? o.getInt(DOT) : 0.5d;
public void initializeFromConfig(ScatterplotFacetConfig configuration, Project project) {
config = configuration;
dim_x = (o.has(DIM_X)) ? getAxisDim(o.getString(DIM_X)) : LIN;
if (o.has(FROM_X) && o.has(TO_X)) {
from_x = o.getDouble(FROM_X);
to_x = o.getDouble(TO_X);
selected = true;
} else {
from_x = 0;
to_x = 1;
}
t = createRotationMatrix(config.rotation, config.l);
dim_y = (o.has(DIM_Y)) ? getAxisDim(o.getString(DIM_Y)) : LIN;
if (o.has(FROM_Y) && o.has(TO_Y)) {
from_y = o.getDouble(FROM_Y);
to_y = o.getDouble(TO_Y);
selected = true;
} else {
from_y = 0;
to_y = 1;
}
rotation = (o.has(ROTATION)) ? getRotation(o.getString(ROTATION)) : NO_ROTATION;
t = createRotationMatrix(rotation, l);
color_str = (o.has(COLOR)) ? o.getString(COLOR) : "000000";
color = new Color(Integer.parseInt(color_str,16));
columnName_x = o.getString(X_COLUMN_NAME);
expression_x = o.getString(X_EXPRESSION);
if (columnName_x.length() > 0) {
Column x_column = project.columnModel.getColumnByName(columnName_x);
if (config.columnName_x.length() > 0) {
Column x_column = project.columnModel.getColumnByName(config.columnName_x);
if (x_column != null) {
columnIndex_x = x_column.getCellIndex();
NumericBinIndex index_x = ScatterplotFacet.getBinIndex(project, x_column, eval_x, expression_x);
NumericBinIndex index_x = ScatterplotFacet.getBinIndex(project, x_column, eval_x, config.expression_x);
min_x = index_x.getMin();
max_x = index_x.getMax();
} else {
errorMessage_x = "No column named " + columnName_x;
errorMessage_x = "No column named " + config.columnName_x;
}
} else {
columnIndex_x = -1;
}
try {
eval_x = MetaParser.parse(expression_x);
eval_x = MetaParser.parse(config.expression_x);
} catch (ParsingException e) {
errorMessage_x = e.getMessage();
}
columnName_y = o.getString(Y_COLUMN_NAME);
expression_y = o.getString(Y_EXPRESSION);
if (columnName_y.length() > 0) {
Column y_column = project.columnModel.getColumnByName(columnName_y);
if (config.columnName_y.length() > 0) {
Column y_column = project.columnModel.getColumnByName(config.columnName_y);
if (y_column != null) {
columnIndex_y = y_column.getCellIndex();
NumericBinIndex index_y = ScatterplotFacet.getBinIndex(project, y_column, eval_y, expression_y);
NumericBinIndex index_y = ScatterplotFacet.getBinIndex(project, y_column, eval_y, config.expression_y);
min_y = index_y.getMin();
max_y = index_y.getMax();
} else {
errorMessage_y = "No column named " + columnName_y;
errorMessage_y = "No column named " + config.columnName_y;
}
} else {
columnIndex_y = -1;
}
try {
eval_y = MetaParser.parse(expression_y);
eval_y = MetaParser.parse(config.expression_y);
} catch (ParsingException e) {
errorMessage_y = e.getMessage();
}
@ -289,22 +348,22 @@ public class ScatterplotFacet implements Facet {
@Override
public RowFilter getRowFilter(Project project) {
if (selected &&
if (config.selected &&
eval_x != null && errorMessage_x == null &&
eval_y != null && errorMessage_y == null)
{
return new DualExpressionsNumberComparisonRowFilter(
eval_x, columnName_x, columnIndex_x, eval_y, columnName_y, columnIndex_y) {
eval_x, config.columnName_x, columnIndex_x, eval_y, config.columnName_y, columnIndex_y) {
double from_x_pixels = from_x * l;
double to_x_pixels = to_x * l;
double from_y_pixels = from_y * l;
double to_y_pixels = to_y * l;
double from_x_pixels = config.from_x * config.l;
double to_x_pixels = config.to_x * config.l;
double from_y_pixels = config.from_y * config.l;
double to_y_pixels = config.to_y * config.l;
@Override
protected boolean checkValues(double x, double y) {
Point2D.Double p = new Point2D.Double(x,y);
p = translateCoordinates(p, min_x, max_x, min_y, max_y, dim_x, dim_y, l, t);
p = translateCoordinates(p, min_x, max_x, min_y, max_y, config.dim_x, config.dim_y, config.l, t);
return p.x >= from_x_pixels && p.x <= to_x_pixels && p.y >= from_y_pixels && p.y <= to_y_pixels;
};
};
@ -323,10 +382,10 @@ public class ScatterplotFacet implements Facet {
public void computeChoices(Project project, FilteredRows filteredRows) {
if (eval_x != null && eval_y != null && errorMessage_x == null && errorMessage_y == null) {
Column column_x = project.columnModel.getColumnByCellIndex(columnIndex_x);
NumericBinIndex index_x = getBinIndex(project, column_x, eval_x, expression_x, "row-based");
NumericBinIndex index_x = getBinIndex(project, column_x, eval_x, config.expression_x, "row-based");
Column column_y = project.columnModel.getColumnByCellIndex(columnIndex_y);
NumericBinIndex index_y = getBinIndex(project, column_y, eval_y, expression_y, "row-based");
NumericBinIndex index_y = getBinIndex(project, column_y, eval_y, config.expression_y, "row-based");
retrieveDataFromBinIndices(index_x, index_y);
@ -334,7 +393,7 @@ public class ScatterplotFacet implements Facet {
if (index_x.isNumeric() && index_y.isNumeric()) {
ScatterplotDrawingRowVisitor drawer = new ScatterplotDrawingRowVisitor(
columnIndex_x, columnIndex_y, min_x, max_x, min_y, max_y,
size, dim_x, dim_y, rotation, dot, color
config.size, config.dim_x, config.dim_y, config.rotation, config.dot, config.color
);
filteredRows.accept(project, drawer);
@ -354,10 +413,10 @@ public class ScatterplotFacet implements Facet {
public void computeChoices(Project project, FilteredRecords filteredRecords) {
if (eval_x != null && eval_y != null && errorMessage_x == null && errorMessage_y == null) {
Column column_x = project.columnModel.getColumnByCellIndex(columnIndex_x);
NumericBinIndex index_x = getBinIndex(project, column_x, eval_x, expression_x, "record-based");
NumericBinIndex index_x = getBinIndex(project, column_x, eval_x, config.expression_x, "record-based");
Column column_y = project.columnModel.getColumnByCellIndex(columnIndex_y);
NumericBinIndex index_y = getBinIndex(project, column_y, eval_y, expression_y, "record-based");
NumericBinIndex index_y = getBinIndex(project, column_y, eval_y, config.expression_y, "record-based");
retrieveDataFromBinIndices(index_x, index_y);
@ -365,7 +424,7 @@ public class ScatterplotFacet implements Facet {
if (index_x.isNumeric() && index_y.isNumeric()) {
ScatterplotDrawingRowVisitor drawer = new ScatterplotDrawingRowVisitor(
columnIndex_x, columnIndex_y, min_x, max_x, min_y, max_y,
size, dim_x, dim_y, rotation, dot, color
config.size, config.dim_x, config.dim_y, config.rotation, config.dot, config.color
);
filteredRecords.accept(project, drawer);
@ -401,17 +460,7 @@ public class ScatterplotFacet implements Facet {
public static int getAxisDim(String type) {
return ("log".equals(type.toLowerCase())) ? LOG : LIN;
}
public static int getRotation(String rotation) {
rotation = rotation.toLowerCase();
if ("cw".equals(rotation) || "right".equals(rotation)) {
return ScatterplotFacet.ROTATE_CW;
} else if ("ccw".equals(rotation) || "left".equals(rotation)) {
return ScatterplotFacet.ROTATE_CCW;
} else {
return NO_ROTATION;
}
}
public static NumericBinIndex getBinIndex(Project project, Column column, Evaluable eval, String expression) {
return getBinIndex(project, column, eval, expression, "row-based");

View File

@ -53,21 +53,59 @@ import com.google.refine.model.Project;
import com.google.refine.util.PatternSyntaxExceptionParser;
public class TextSearchFacet implements Facet {
/*
* Configuration
*/
protected String _name;
protected String _columnName;
protected String _query;
protected String _mode;
protected boolean _caseSensitive;
protected boolean _invert;
public static class TextSearchFacetConfig implements FacetConfig {
protected String _name;
protected String _columnName;
protected String _query = null;
protected String _mode;
protected boolean _caseSensitive;
protected boolean _invert;
@Override
public void write(JSONWriter writer, Properties options)
throws JSONException {
writer.object();
writer.key("name"); writer.value(_name);
writer.key("columnName"); writer.value(_columnName);
writer.key("query"); writer.value(_query);
writer.key("mode"); writer.value(_mode);
writer.key("caseSensitive"); writer.value(_caseSensitive);
writer.key("invert"); writer.value(_invert);
writer.key("type"); writer.value("text");
writer.endObject();
}
@Override
public TextSearchFacet apply(Project project) {
TextSearchFacet facet = new TextSearchFacet();
facet.initializeFromConfig(this, project);
return facet;
}
@Override
public void initializeFromJSON(JSONObject o) {
_name = o.getString("name");
_columnName = o.getString("columnName");
_mode = o.getString("mode");
_caseSensitive = o.getBoolean("caseSensitive");
if (!o.isNull("query")) {
_query = o.getString("query");
}
_invert = o.has("invert") && o.getBoolean("invert");
}
}
TextSearchFacetConfig _config = new TextSearchFacetConfig();
/*
* Derived configuration
*/
protected int _cellIndex;
protected Pattern _pattern;
protected String _query; // normalized version of the query from the config
public TextSearchFacet() {
}
@ -77,68 +115,61 @@ public class TextSearchFacet implements Facet {
throws JSONException {
writer.object();
writer.key("name"); writer.value(_name);
writer.key("columnName"); writer.value(_columnName);
writer.key("query"); writer.value(_query);
writer.key("mode"); writer.value(_mode);
writer.key("caseSensitive"); writer.value(_caseSensitive);
writer.key("invert"); writer.value(_invert);
writer.key("name"); writer.value(_config._name);
writer.key("columnName"); writer.value(_config._columnName);
writer.key("query"); writer.value(_config._query);
writer.key("mode"); writer.value(_config._mode);
writer.key("caseSensitive"); writer.value(_config._caseSensitive);
writer.key("invert"); writer.value(_config._invert);
writer.endObject();
}
@Override
public void initializeFromJSON(Project project, JSONObject o) throws JSONException {
_name = o.getString("name");
_columnName = o.getString("columnName");
public void initializeFromConfig(TextSearchFacetConfig config, Project project) {
_config = config;
Column column = project.columnModel.getColumnByName(_columnName);
Column column = project.columnModel.getColumnByName(_config._columnName);
_cellIndex = column != null ? column.getCellIndex() : -1;
if (!o.isNull("query")) {
_query = o.getString("query");
}
_mode = o.getString("mode");
_caseSensitive = o.getBoolean("caseSensitive");
_query = _config._query;
if (_query != null) {
if ("regex".equals(_mode)) {
if ("regex".equals(_config._mode)) {
try {
_pattern = Pattern.compile(
_query,
_caseSensitive ? 0 : Pattern.CASE_INSENSITIVE);
_config._caseSensitive ? 0 : Pattern.CASE_INSENSITIVE);
} catch (java.util.regex.PatternSyntaxException e) {
PatternSyntaxExceptionParser err = new PatternSyntaxExceptionParser(e);
throw new JSONException(err.getUserMessage());
}
} else if (!_caseSensitive) {
} else if (!_config._caseSensitive) {
_query = _query.toLowerCase();
}
}
_invert = o.has("invert") && o.getBoolean("invert");
}
@Override
public RowFilter getRowFilter(Project project) {
if (_query == null || _query.length() == 0 || _cellIndex < 0) {
return null;
} else if ("regex".equals(_mode) && _pattern == null) {
} else if ("regex".equals(_config._mode) && _pattern == null) {
return null;
}
Evaluable eval = new VariableExpr("value");
if ("regex".equals(_mode)) {
return new ExpressionStringComparisonRowFilter(eval, _invert, _columnName, _cellIndex) {
if ("regex".equals(_config._mode)) {
return new ExpressionStringComparisonRowFilter(eval, _config._invert, _config._columnName, _cellIndex) {
@Override
protected boolean checkValue(String s) {
return _pattern.matcher(s).find();
};
};
} else {
return new ExpressionStringComparisonRowFilter(eval, _invert, _columnName, _cellIndex) {
return new ExpressionStringComparisonRowFilter(eval, _config._invert, _config._columnName, _cellIndex) {
@Override
protected boolean checkValue(String s) {
return (_caseSensitive ? s : s.toLowerCase()).contains(_query);
return (_config._caseSensitive ? s : s.toLowerCase()).contains(_query);
};
};
}

View File

@ -41,37 +41,129 @@ import org.json.JSONWriter;
import com.google.refine.browsing.FilteredRecords;
import com.google.refine.browsing.FilteredRows;
import com.google.refine.browsing.RecordFilter;
import com.google.refine.browsing.RowFilter;
import com.google.refine.browsing.filters.AnyRowRecordFilter;
import com.google.refine.browsing.filters.ExpressionTimeComparisonRowFilter;
import com.google.refine.browsing.util.ExpressionBasedRowEvaluable;
import com.google.refine.browsing.util.ExpressionTimeValueBinner;
import com.google.refine.browsing.util.RowEvaluable;
import com.google.refine.browsing.util.TimeBinIndex;
import com.google.refine.browsing.util.TimeBinRecordIndex;
import com.google.refine.browsing.util.TimeBinRowIndex;
import com.google.refine.expr.Evaluable;
import com.google.refine.expr.MetaParser;
import com.google.refine.expr.ParsingException;
import com.google.refine.model.Column;
import com.google.refine.model.Project;
import com.google.refine.util.JSONUtilities;
public class TimeRangeFacet extends RangeFacet {
protected boolean _selectTime; // whether the time selection applies, default true
protected boolean _selectNonTime;
public class TimeRangeFacet implements Facet {
/*
* Configuration, from the client side
*/
public static class TimeRangeFacetConfig implements FacetConfig {
protected String _name; // name of facet
protected String _expression; // expression to compute numeric value(s) per row
protected String _columnName; // column to base expression on, if any
protected double _from; // the numeric selection
protected double _to;
protected boolean _selectTime; // whether the time selection applies, default true
protected boolean _selectNonTime;
protected boolean _selectBlank;
protected boolean _selectError;
protected boolean _selected; // false if we're certain that all rows will match
// and there isn't any filtering to do
@Override
public void write(JSONWriter writer, Properties options)
throws JSONException {
writer.object();
writer.key("type"); writer.value("timerange");
writer.key("name"); writer.value(_name);
writer.key("expression"); writer.value(_expression);
writer.key("columnName"); writer.value(_columnName);
writer.key("selectTime"); writer.value(_selectTime);
writer.key("selectNonTime"); writer.value(_selectNonTime);
writer.key("selectBlank"); writer.value(_selectBlank);
writer.key("selectError"); writer.value(_selectError);
writer.key(FROM); writer.value((long)_from);
writer.key(TO); writer.value((long)_to);
writer.endObject();
}
@Override
public void initializeFromJSON(JSONObject o) throws JSONException {
_name = o.getString("name");
_expression = o.getString("expression");
_columnName = o.getString("columnName");
if (o.has(FROM) || o.has(TO)) {
_from = o.has(FROM) ? o.getDouble(FROM) : 0;
_to = o.has(TO) ? o.getDouble(TO) : 0;
_selected = true;
}
_selectTime = JSONUtilities.getBoolean(o, "selectTime", true);
_selectNonTime = JSONUtilities.getBoolean(o, "selectNonTime", true);
_selectBlank = JSONUtilities.getBoolean(o, "selectBlank", true);
_selectError = JSONUtilities.getBoolean(o, "selectError", true);
if (!_selectTime || !_selectNonTime || !_selectBlank || !_selectError) {
_selected = true;
}
}
@Override
public TimeRangeFacet apply(Project project) {
TimeRangeFacet facet = new TimeRangeFacet();
facet.initializeFromConfig(this, project);
return facet;
}
}
protected TimeRangeFacetConfig _config;
/*
* Derived configuration data
*/
protected int _cellIndex;
protected Evaluable _eval;
protected String _errorMessage;
protected double _min;
protected double _max;
protected double _step;
protected int[] _baseBins;
protected int[] _bins;
/*
* Computed data
*/
protected int _baseTimeCount;
protected int _baseNonTimeCount;
protected int _baseBlankCount;
protected int _baseErrorCount;
protected int _timeCount;
protected int _nonTimeCount;
protected int _blankCount;
protected int _errorCount;
protected static final String MIN = "min";
protected static final String MAX = "max";
protected static final String TO = "to";
protected static final String FROM = "from";
@Override
public void write(JSONWriter writer, Properties options) throws JSONException {
writer.object();
writer.key("name"); writer.value(_name);
writer.key("expression"); writer.value(_expression);
writer.key("columnName"); writer.value(_columnName);
writer.key("name"); writer.value(_config._name);
writer.key("expression"); writer.value(_config._expression);
writer.key("columnName"); writer.value(_config._columnName);
if (_errorMessage != null) {
writer.key("error"); writer.value(_errorMessage);
@ -93,8 +185,8 @@ public class TimeRangeFacet extends RangeFacet {
}
writer.endArray();
writer.key(FROM); writer.value(_from);
writer.key(TO); writer.value(_to);
writer.key(FROM); writer.value(_config._from);
writer.key(TO); writer.value(_config._to);
}
writer.key("baseTimeCount"); writer.value(_baseTimeCount);
@ -109,55 +201,36 @@ public class TimeRangeFacet extends RangeFacet {
}
writer.endObject();
}
@Override
public void initializeFromJSON(Project project, JSONObject o) throws JSONException {
_name = o.getString("name");
_expression = o.getString("expression");
_columnName = o.getString("columnName");
if (_columnName.length() > 0) {
Column column = project.columnModel.getColumnByName(_columnName);
public void initializeFromConfig(TimeRangeFacetConfig config, Project project) {
_config = config;
if (_config._columnName.length() > 0) {
Column column = project.columnModel.getColumnByName(_config._columnName);
if (column != null) {
_cellIndex = column.getCellIndex();
} else {
_errorMessage = "No column named " + _columnName;
_errorMessage = "No column named " + _config._columnName;
}
} else {
_cellIndex = -1;
}
try {
_eval = MetaParser.parse(_expression);
_eval = MetaParser.parse(_config._expression);
} catch (ParsingException e) {
_errorMessage = e.getMessage();
}
if (o.has(FROM) || o.has(TO)) {
_from = o.has(FROM) ? o.getDouble(FROM) : _min;
_to = o.has(TO) ? o.getDouble(TO) : _max;
_selected = true;
}
_selectTime = JSONUtilities.getBoolean(o, "selectTime", true);
_selectNonTime = JSONUtilities.getBoolean(o, "selectNonTime", true);
_selectBlank = JSONUtilities.getBoolean(o, "selectBlank", true);
_selectError = JSONUtilities.getBoolean(o, "selectError", true);
if (!_selectTime || !_selectNonTime || !_selectBlank || !_selectError) {
_selected = true;
}
}
@Override
public RowFilter getRowFilter(Project project) {
if (_eval != null && _errorMessage == null && _selected) {
if (_eval != null && _errorMessage == null && _config._selected) {
return new ExpressionTimeComparisonRowFilter(
getRowEvaluable(project), _selectTime, _selectNonTime, _selectBlank, _selectError) {
getRowEvaluable(project), _config._selectTime, _config._selectNonTime, _config._selectBlank, _config._selectError) {
@Override
protected boolean checkValue(long t) {
return t >= _from && t <= _to;
return t >= _config._from && t <= _config._to;
};
};
} else {
@ -171,7 +244,7 @@ public class TimeRangeFacet extends RangeFacet {
RowEvaluable rowEvaluable = getRowEvaluable(project);
Column column = project.columnModel.getColumnByCellIndex(_cellIndex);
String key = "time-bin:row-based:" + _expression;
String key = "time-bin:row-based:" + _config._expression;
TimeBinIndex index = (TimeBinIndex) column.getPrecompute(key);
if (index == null) {
index = new TimeBinRowIndex(project, rowEvaluable);
@ -193,7 +266,7 @@ public class TimeRangeFacet extends RangeFacet {
RowEvaluable rowEvaluable = getRowEvaluable(project);
Column column = project.columnModel.getColumnByCellIndex(_cellIndex);
String key = "time-bin:record-based:" + _expression;
String key = "time-bin:record-based:" + _config._expression;
TimeBinIndex index = (TimeBinIndex) column.getPrecompute(key);
if (index == null) {
index = new TimeBinRecordIndex(project, rowEvaluable);
@ -221,12 +294,12 @@ public class TimeRangeFacet extends RangeFacet {
_baseBlankCount = index.getBlankRowCount();
_baseErrorCount = index.getErrorRowCount();
if (_selected) {
_from = Math.max(_from, _min);
_to = Math.min(_to, _max);
if (_config._selected) {
_config._from = Math.max(_config._from, _min);
_config._to = Math.min(_config._to, _max);
} else {
_from = _min;
_to = _max;
_config._from = _min;
_config._to = _max;
}
}
@ -237,4 +310,14 @@ public class TimeRangeFacet extends RangeFacet {
_blankCount = binner.blankCount;
_errorCount = binner.errorCount;
}
@Override
public RecordFilter getRecordFilter(Project project) {
RowFilter rowFilter = getRowFilter(project);
return rowFilter == null ? null : new AnyRowRecordFilter(rowFilter);
}
protected RowEvaluable getRowEvaluable(Project project) {
return new ExpressionBasedRowEvaluable(_config._columnName, _cellIndex, _eval);
}
}

View File

@ -54,6 +54,7 @@ import com.google.refine.Jsonizable;
import com.google.refine.ProjectManager;
import com.google.refine.RefineServlet;
import com.google.refine.browsing.Engine;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.history.HistoryEntry;
import com.google.refine.model.Project;
import com.google.refine.model.metadata.ProjectMetadata;
@ -115,7 +116,7 @@ public abstract class Command {
* @return
* @throws JSONException
*/
static protected JSONObject getEngineConfig(HttpServletRequest request)
static protected EngineConfig getEngineConfig(HttpServletRequest request)
throws JSONException {
if (request == null) {
throw new IllegalArgumentException("parameter 'request' should not be null");
@ -123,7 +124,8 @@ public abstract class Command {
String json = request.getParameter("engine");
try{
return (json == null) ? null : ParsingUtilities.evaluateJsonStringToObject(json);
return (json == null) ? null :
EngineConfig.reconstruct(ParsingUtilities.evaluateJsonStringToObject(json));
} catch (JSONException e){
logger.debug( json + " could not be parsed to JSON");
return null;
@ -149,9 +151,9 @@ public abstract class Command {
}
Engine engine = new Engine(project);
JSONObject o = getEngineConfig(request);
if (o != null) {
engine.initializeFromJSON(o);
EngineConfig c = getEngineConfig(request);
if (c != null) {
engine.initializeFromConfig(c);
}
return engine;
}

View File

@ -40,8 +40,7 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.json.JSONObject;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.model.AbstractOperation;
import com.google.refine.model.Project;
import com.google.refine.process.Process;
@ -85,5 +84,5 @@ abstract public class EngineDependentCommand extends Command {
}
abstract protected AbstractOperation createOperation(
Project project, HttpServletRequest request, JSONObject engineConfig) throws Exception;
Project project, HttpServletRequest request, EngineConfig engineConfig) throws Exception;
}

View File

@ -53,6 +53,7 @@ import com.google.refine.browsing.Engine;
import com.google.refine.browsing.FilteredRows;
import com.google.refine.browsing.facets.ScatterplotDrawingRowVisitor;
import com.google.refine.browsing.facets.ScatterplotFacet;
import com.google.refine.browsing.facets.ScatterplotFacet.ScatterplotFacetConfig;
import com.google.refine.browsing.util.NumericBinIndex;
import com.google.refine.commands.Command;
import com.google.refine.expr.Evaluable;
@ -114,7 +115,7 @@ public class GetScatterplotCommand extends Command {
int dim_x = (o.has(ScatterplotFacet.DIM_X)) ? ScatterplotFacet.getAxisDim(o.getString(ScatterplotFacet.DIM_X)) : ScatterplotFacet.LIN;
int dim_y = (o.has(ScatterplotFacet.DIM_Y)) ? ScatterplotFacet.getAxisDim(o.getString(ScatterplotFacet.DIM_Y)) : ScatterplotFacet.LIN;
int rotation = (o.has(ScatterplotFacet.ROTATION)) ? ScatterplotFacet.getRotation(o.getString(ScatterplotFacet.ROTATION)) : ScatterplotFacet.NO_ROTATION;
int rotation = (o.has(ScatterplotFacet.ROTATION)) ? ScatterplotFacetConfig.getRotation(o.getString(ScatterplotFacet.ROTATION)) : ScatterplotFacet.NO_ROTATION;
String color_str = (o.has(ScatterplotFacet.COLOR)) ? o.getString(ScatterplotFacet.COLOR) : "000000";
Color color = new Color(Integer.parseInt(color_str,16));

View File

@ -35,8 +35,7 @@ package com.google.refine.commands.cell;
import javax.servlet.http.HttpServletRequest;
import org.json.JSONObject;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.commands.EngineDependentCommand;
import com.google.refine.model.AbstractOperation;
import com.google.refine.model.Project;
@ -45,7 +44,7 @@ import com.google.refine.operations.cell.BlankDownOperation;
public class BlankDownCommand extends EngineDependentCommand {
@Override
protected AbstractOperation createOperation(Project project,
HttpServletRequest request, JSONObject engineConfig) throws Exception {
HttpServletRequest request, EngineConfig engineConfig) throws Exception {
String columnName = request.getParameter("columnName");

View File

@ -35,8 +35,7 @@ package com.google.refine.commands.cell;
import javax.servlet.http.HttpServletRequest;
import org.json.JSONObject;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.commands.EngineDependentCommand;
import com.google.refine.model.AbstractOperation;
import com.google.refine.model.Project;
@ -45,7 +44,7 @@ import com.google.refine.operations.cell.FillDownOperation;
public class FillDownCommand extends EngineDependentCommand {
@Override
protected AbstractOperation createOperation(Project project,
HttpServletRequest request, JSONObject engineConfig) throws Exception {
HttpServletRequest request, EngineConfig engineConfig) throws Exception {
String columnName = request.getParameter("columnName");

View File

@ -35,8 +35,7 @@ package com.google.refine.commands.cell;
import javax.servlet.http.HttpServletRequest;
import org.json.JSONObject;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.commands.EngineDependentCommand;
import com.google.refine.model.AbstractOperation;
import com.google.refine.model.Project;
@ -46,7 +45,7 @@ import com.google.refine.util.ParsingUtilities;
public class MassEditCommand extends EngineDependentCommand {
@Override
protected AbstractOperation createOperation(Project project,
HttpServletRequest request, JSONObject engineConfig) throws Exception {
HttpServletRequest request, EngineConfig engineConfig) throws Exception {
String columnName = request.getParameter("columnName");
String expression = request.getParameter("expression");

View File

@ -35,8 +35,7 @@ package com.google.refine.commands.cell;
import javax.servlet.http.HttpServletRequest;
import org.json.JSONObject;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.commands.EngineDependentCommand;
import com.google.refine.model.AbstractOperation;
import com.google.refine.model.Project;
@ -45,7 +44,7 @@ import com.google.refine.operations.cell.TextTransformOperation;
public class TextTransformCommand extends EngineDependentCommand {
@Override
protected AbstractOperation createOperation(Project project,
HttpServletRequest request, JSONObject engineConfig) throws Exception {
HttpServletRequest request, EngineConfig engineConfig) throws Exception {
String columnName = request.getParameter("columnName");
String expression = request.getParameter("expression");

View File

@ -35,9 +35,9 @@ package com.google.refine.commands.column;
import javax.servlet.http.HttpServletRequest;
import org.json.JSONObject;
import org.json.JSONArray;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.commands.EngineDependentCommand;
import com.google.refine.model.AbstractOperation;
import com.google.refine.model.Project;
@ -47,7 +47,7 @@ import com.google.refine.operations.column.ColumnAdditionByFetchingURLsOperation
public class AddColumnByFetchingURLsCommand extends EngineDependentCommand {
@Override
protected AbstractOperation createOperation(Project project,
HttpServletRequest request, JSONObject engineConfig) throws Exception {
HttpServletRequest request, EngineConfig engineConfig) throws Exception {
String baseColumnName = request.getParameter("baseColumnName");
String urlExpression = request.getParameter("urlExpression");

View File

@ -35,8 +35,7 @@ package com.google.refine.commands.column;
import javax.servlet.http.HttpServletRequest;
import org.json.JSONObject;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.commands.EngineDependentCommand;
import com.google.refine.model.AbstractOperation;
import com.google.refine.model.Project;
@ -46,7 +45,7 @@ import com.google.refine.operations.column.ColumnAdditionOperation;
public class AddColumnCommand extends EngineDependentCommand {
@Override
protected AbstractOperation createOperation(Project project,
HttpServletRequest request, JSONObject engineConfig) throws Exception {
HttpServletRequest request, EngineConfig engineConfig) throws Exception {
String baseColumnName = request.getParameter("baseColumnName");
String expression = request.getParameter("expression");

View File

@ -35,8 +35,7 @@ package com.google.refine.commands.column;
import javax.servlet.http.HttpServletRequest;
import org.json.JSONObject;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.commands.EngineDependentCommand;
import com.google.refine.model.AbstractOperation;
import com.google.refine.model.Project;
@ -48,7 +47,7 @@ public class ReorderColumnsCommand extends EngineDependentCommand {
@Override
protected AbstractOperation createOperation(Project project,
HttpServletRequest request, JSONObject engineConfig) throws Exception {
HttpServletRequest request, EngineConfig engineConfig) throws Exception {
String columnNames = request.getParameter("columnNames");
return new ColumnReorderOperation(

View File

@ -36,8 +36,8 @@ package com.google.refine.commands.column;
import javax.servlet.http.HttpServletRequest;
import org.json.JSONArray;
import org.json.JSONObject;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.commands.EngineDependentCommand;
import com.google.refine.model.AbstractOperation;
import com.google.refine.model.Project;
@ -47,7 +47,7 @@ import com.google.refine.util.ParsingUtilities;
public class SplitColumnCommand extends EngineDependentCommand {
@Override
protected AbstractOperation createOperation(Project project,
HttpServletRequest request, JSONObject engineConfig) throws Exception {
HttpServletRequest request, EngineConfig engineConfig) throws Exception {
String columnName = request.getParameter("columnName");
boolean guessCellType = Boolean.parseBoolean(request.getParameter("guessCellType"));

View File

@ -37,6 +37,7 @@ import javax.servlet.http.HttpServletRequest;
import org.json.JSONObject;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.commands.EngineDependentCommand;
import com.google.refine.operations.recon.ExtendDataOperation;
import com.google.refine.model.AbstractOperation;
@ -46,7 +47,7 @@ import com.google.refine.util.ParsingUtilities;
public class ExtendDataCommand extends EngineDependentCommand {
@Override
protected AbstractOperation createOperation(Project project,
HttpServletRequest request, JSONObject engineConfig) throws Exception {
HttpServletRequest request, EngineConfig engineConfig) throws Exception {
String baseColumnName = request.getParameter("baseColumnName");
int columnInsertIndex = Integer.parseInt(request.getParameter("columnInsertIndex"));

View File

@ -35,8 +35,7 @@ package com.google.refine.commands.recon;
import javax.servlet.http.HttpServletRequest;
import org.json.JSONObject;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.commands.EngineDependentCommand;
import com.google.refine.model.AbstractOperation;
import com.google.refine.model.Project;
@ -46,7 +45,7 @@ public class ReconClearSimilarCellsCommand extends EngineDependentCommand {
@Override
protected AbstractOperation createOperation(
Project project, HttpServletRequest request, JSONObject engineConfig) throws Exception {
Project project, HttpServletRequest request, EngineConfig engineConfig) throws Exception {
String columnName = request.getParameter("columnName");
String similarValue = request.getParameter("similarValue");

View File

@ -35,8 +35,7 @@ package com.google.refine.commands.recon;
import javax.servlet.http.HttpServletRequest;
import org.json.JSONObject;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.commands.EngineDependentCommand;
import com.google.refine.model.AbstractOperation;
import com.google.refine.model.Project;
@ -45,7 +44,7 @@ import com.google.refine.operations.recon.ReconCopyAcrossColumnsOperation;
public class ReconCopyAcrossColumnsCommand extends EngineDependentCommand {
@Override
protected AbstractOperation createOperation(Project project,
HttpServletRequest request, JSONObject engineConfig) throws Exception {
HttpServletRequest request, EngineConfig engineConfig) throws Exception {
String fromColumnName = request.getParameter("fromColumnName");
String[] toColumnNames = request.getParameterValues("toColumnName[]");

View File

@ -35,8 +35,7 @@ package com.google.refine.commands.recon;
import javax.servlet.http.HttpServletRequest;
import org.json.JSONObject;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.commands.EngineDependentCommand;
import com.google.refine.model.AbstractOperation;
import com.google.refine.model.Project;
@ -45,7 +44,7 @@ import com.google.refine.operations.recon.ReconDiscardJudgmentsOperation;
public class ReconDiscardJudgmentsCommand extends EngineDependentCommand {
@Override
protected AbstractOperation createOperation(Project project,
HttpServletRequest request, JSONObject engineConfig) throws Exception {
HttpServletRequest request, EngineConfig engineConfig) throws Exception {
String columnName = request.getParameter("columnName");
boolean clearData = Boolean.parseBoolean(request.getParameter("clearData"));

View File

@ -35,8 +35,7 @@ package com.google.refine.commands.recon;
import javax.servlet.http.HttpServletRequest;
import org.json.JSONObject;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.commands.EngineDependentCommand;
import com.google.refine.model.AbstractOperation;
import com.google.refine.model.Project;
@ -49,7 +48,7 @@ public class ReconJudgeSimilarCellsCommand extends EngineDependentCommand {
@Override
protected AbstractOperation createOperation(
Project project, HttpServletRequest request, JSONObject engineConfig) throws Exception {
Project project, HttpServletRequest request, EngineConfig engineConfig) throws Exception {
String columnName = request.getParameter("columnName");
String similarValue = request.getParameter("similarValue");

View File

@ -35,8 +35,7 @@ package com.google.refine.commands.recon;
import javax.servlet.http.HttpServletRequest;
import org.json.JSONObject;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.commands.EngineDependentCommand;
import com.google.refine.model.AbstractOperation;
import com.google.refine.model.Project;
@ -46,7 +45,7 @@ public class ReconMarkNewTopicsCommand extends EngineDependentCommand {
@Override
protected AbstractOperation createOperation(Project project,
HttpServletRequest request, JSONObject engineConfig) throws Exception {
HttpServletRequest request, EngineConfig engineConfig) throws Exception {
return new ReconMarkNewTopicsOperation(
engineConfig,

View File

@ -35,8 +35,7 @@ package com.google.refine.commands.recon;
import javax.servlet.http.HttpServletRequest;
import org.json.JSONObject;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.commands.EngineDependentCommand;
import com.google.refine.model.AbstractOperation;
import com.google.refine.model.Project;
@ -46,7 +45,7 @@ public class ReconMatchBestCandidatesCommand extends EngineDependentCommand {
@Override
protected AbstractOperation createOperation(Project project,
HttpServletRequest request, JSONObject engineConfig) throws Exception {
HttpServletRequest request, EngineConfig engineConfig) throws Exception {
String columnName = request.getParameter("columnName");

View File

@ -35,8 +35,7 @@ package com.google.refine.commands.recon;
import javax.servlet.http.HttpServletRequest;
import org.json.JSONObject;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.commands.EngineDependentCommand;
import com.google.refine.model.AbstractOperation;
import com.google.refine.model.Project;
@ -47,7 +46,7 @@ public class ReconMatchSpecificTopicCommand extends EngineDependentCommand {
@Override
protected AbstractOperation createOperation(Project project,
HttpServletRequest request, JSONObject engineConfig) throws Exception {
HttpServletRequest request, EngineConfig engineConfig) throws Exception {
String columnName = request.getParameter("columnName");
ReconCandidate match = new ReconCandidate(

View File

@ -38,6 +38,7 @@ import javax.servlet.http.HttpServletRequest;
import org.json.JSONObject;
import org.json.JSONTokener;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.commands.EngineDependentCommand;
import com.google.refine.model.AbstractOperation;
import com.google.refine.model.Project;
@ -48,7 +49,7 @@ public class ReconcileCommand extends EngineDependentCommand {
@Override
protected AbstractOperation createOperation(Project project,
HttpServletRequest request, JSONObject engineConfig) throws Exception {
HttpServletRequest request, EngineConfig engineConfig) throws Exception {
String columnName = request.getParameter("columnName");
String configString = request.getParameter("config");

View File

@ -35,8 +35,7 @@ package com.google.refine.commands.row;
import javax.servlet.http.HttpServletRequest;
import org.json.JSONObject;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.commands.EngineDependentCommand;
import com.google.refine.model.AbstractOperation;
import com.google.refine.model.Project;
@ -47,7 +46,7 @@ public class AnnotateRowsCommand extends EngineDependentCommand {
@Override
protected AbstractOperation createOperation(Project project,
HttpServletRequest request, JSONObject engineConfig) throws Exception {
HttpServletRequest request, EngineConfig engineConfig) throws Exception {
String starredString = request.getParameter("starred");
if (starredString != null) {

View File

@ -35,8 +35,7 @@ package com.google.refine.commands.row;
import javax.servlet.http.HttpServletRequest;
import org.json.JSONObject;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.commands.EngineDependentCommand;
import com.google.refine.model.AbstractOperation;
import com.google.refine.model.Project;
@ -46,7 +45,7 @@ public class RemoveRowsCommand extends EngineDependentCommand {
@Override
protected AbstractOperation createOperation(Project project,
HttpServletRequest request, JSONObject engineConfig) throws Exception {
HttpServletRequest request, EngineConfig engineConfig) throws Exception {
return new RowRemovalOperation(engineConfig);
}

View File

@ -39,6 +39,7 @@ import org.json.JSONException;
import org.json.JSONObject;
import com.google.refine.browsing.Engine;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.commands.EngineDependentCommand;
import com.google.refine.model.AbstractOperation;
import com.google.refine.model.Project;
@ -49,7 +50,7 @@ public class ReorderRowsCommand extends EngineDependentCommand {
@Override
protected AbstractOperation createOperation(Project project,
HttpServletRequest request, JSONObject engineConfig) throws Exception {
HttpServletRequest request, EngineConfig engineConfig) throws Exception {
String mode = request.getParameter("mode");
JSONObject sorting = null;

View File

@ -36,9 +36,8 @@ package com.google.refine.operations;
import java.util.ArrayList;
import java.util.List;
import org.json.JSONObject;
import com.google.refine.browsing.Engine;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.browsing.FilteredRows;
import com.google.refine.browsing.RowVisitor;
import com.google.refine.history.Change;
@ -53,7 +52,7 @@ abstract public class EngineDependentMassCellOperation extends EngineDependentOp
final protected boolean _updateRowContextDependencies;
protected EngineDependentMassCellOperation(
JSONObject engineConfig, String columnName, boolean updateRowContextDependencies) {
EngineConfig engineConfig, String columnName, boolean updateRowContextDependencies) {
super(engineConfig);
_columnName = columnName;
_updateRowContextDependencies = updateRowContextDependencies;

View File

@ -33,39 +33,26 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.refine.operations;
import org.json.JSONException;
import org.json.JSONObject;
import com.google.refine.browsing.Engine;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.model.AbstractOperation;
import com.google.refine.model.Project;
import com.google.refine.util.ParsingUtilities;
abstract public class EngineDependentOperation extends AbstractOperation {
final private String _engineConfigString;
transient protected JSONObject _engineConfig;
transient protected EngineConfig _engineConfig;
protected EngineDependentOperation(JSONObject engineConfig) {
protected EngineDependentOperation(EngineConfig engineConfig) {
_engineConfig = engineConfig;
_engineConfigString = engineConfig == null || engineConfig.length() == 0
? null : engineConfig.toString();
}
protected Engine createEngine(Project project) throws Exception {
Engine engine = new Engine(project);
engine.initializeFromJSON(getEngineConfig());
engine.initializeFromConfig(getEngineConfig());
return engine;
}
protected JSONObject getEngineConfig() {
if (_engineConfig == null && _engineConfigString != null) {
try {
_engineConfig = ParsingUtilities.evaluateJsonStringToObject(_engineConfigString);
} catch (JSONException e) {
// ignore
}
}
protected EngineConfig getEngineConfig() {
return _engineConfig;
}
}

View File

@ -41,6 +41,7 @@ import org.json.JSONObject;
import org.json.JSONWriter;
import com.google.refine.browsing.Engine.Mode;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.browsing.RowVisitor;
import com.google.refine.expr.ExpressionUtils;
import com.google.refine.model.AbstractOperation;
@ -58,13 +59,13 @@ public class BlankDownOperation extends EngineDependentMassCellOperation {
JSONObject engineConfig = obj.getJSONObject("engineConfig");
return new BlankDownOperation(
engineConfig,
EngineConfig.reconstruct(engineConfig),
obj.getString("columnName")
);
}
public BlankDownOperation(
JSONObject engineConfig,
EngineConfig engineConfig,
String columnName
) {
super(engineConfig, columnName, true);
@ -77,7 +78,7 @@ public class BlankDownOperation extends EngineDependentMassCellOperation {
writer.object();
writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass()));
writer.key("description"); writer.value(getBriefDescription(null));
writer.key("engineConfig"); writer.value(getEngineConfig());
writer.key("engineConfig"); getEngineConfig().write(writer, options);
writer.key("columnName"); writer.value(_columnName);
writer.endObject();
}

View File

@ -42,6 +42,7 @@ import org.json.JSONWriter;
import com.google.refine.browsing.Engine;
import com.google.refine.browsing.Engine.Mode;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.browsing.RowVisitor;
import com.google.refine.expr.ExpressionUtils;
import com.google.refine.model.AbstractOperation;
@ -59,13 +60,13 @@ public class FillDownOperation extends EngineDependentMassCellOperation {
JSONObject engineConfig = obj.getJSONObject("engineConfig");
return new FillDownOperation(
engineConfig,
EngineConfig.reconstruct(engineConfig),
obj.getString("columnName")
);
}
public FillDownOperation(
JSONObject engineConfig,
EngineConfig engineConfig,
String columnName
) {
super(engineConfig, columnName, true);
@ -78,7 +79,7 @@ public class FillDownOperation extends EngineDependentMassCellOperation {
writer.object();
writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass()));
writer.key("description"); writer.value(getBriefDescription(null));
writer.key("engineConfig"); writer.value(getEngineConfig());
writer.key("engineConfig"); getEngineConfig().write(writer, options);
writer.key("columnName"); writer.value(_columnName);
writer.endObject();
}

View File

@ -46,6 +46,7 @@ import org.json.JSONObject;
import org.json.JSONWriter;
import com.google.refine.Jsonizable;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.browsing.RowVisitor;
import com.google.refine.expr.Evaluable;
import com.google.refine.expr.ExpressionUtils;
@ -101,7 +102,7 @@ public class MassEditOperation extends EngineDependentMassCellOperation {
obj.getJSONObject("engineConfig") : null;
return new MassEditOperation(
engineConfig,
EngineConfig.reconstruct(engineConfig),
obj.getString("columnName"),
obj.getString("expression"),
reconstructEdits(obj.getJSONArray("edits"))
@ -145,7 +146,7 @@ public class MassEditOperation extends EngineDependentMassCellOperation {
return edits;
}
public MassEditOperation(JSONObject engineConfig, String columnName, String expression, List<Edit> edits) {
public MassEditOperation(EngineConfig engineConfig, String columnName, String expression, List<Edit> edits) {
super(engineConfig, columnName, true);
_expression = expression;
_edits = edits;
@ -158,7 +159,7 @@ public class MassEditOperation extends EngineDependentMassCellOperation {
writer.object();
writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass()));
writer.key("description"); writer.value(getBriefDescription(null));
writer.key("engineConfig"); writer.value(getEngineConfig());
writer.key("engineConfig"); getEngineConfig().write(writer, options);
writer.key("columnName"); writer.value(_columnName);
writer.key("expression"); writer.value(_expression);
writer.key("edits");

View File

@ -41,6 +41,7 @@ import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONWriter;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.browsing.RowVisitor;
import com.google.refine.expr.Evaluable;
import com.google.refine.expr.ExpressionUtils;
@ -66,7 +67,7 @@ public class TextTransformOperation extends EngineDependentMassCellOperation {
JSONObject engineConfig = obj.getJSONObject("engineConfig");
return new TextTransformOperation(
engineConfig,
EngineConfig.reconstruct(engineConfig),
obj.getString("columnName"),
obj.getString("expression"),
stringToOnError(obj.getString("onError")),
@ -95,7 +96,7 @@ public class TextTransformOperation extends EngineDependentMassCellOperation {
}
public TextTransformOperation(
JSONObject engineConfig,
EngineConfig engineConfig,
String columnName,
String expression,
OnError onError,
@ -116,7 +117,7 @@ public class TextTransformOperation extends EngineDependentMassCellOperation {
writer.object();
writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass()));
writer.key("description"); writer.value(getBriefDescription(null));
writer.key("engineConfig"); writer.value(getEngineConfig());
writer.key("engineConfig"); getEngineConfig().write(writer, options);
writer.key("columnName"); writer.value(_columnName);
writer.key("expression"); writer.value(_expression);
writer.key("onError"); writer.value(onErrorToString(_onError));

View File

@ -42,18 +42,20 @@ import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.ExecutionException;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONArray;
import org.json.JSONWriter;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.refine.browsing.Engine;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.browsing.FilteredRows;
import com.google.refine.browsing.RowVisitor;
import com.google.refine.expr.EvalError;
@ -69,8 +71,6 @@ import com.google.refine.model.Project;
import com.google.refine.model.Row;
import com.google.refine.model.changes.CellAtRow;
import com.google.refine.model.changes.ColumnAdditionChange;
import com.google.refine.commands.HttpHeadersSupport;
import com.google.refine.commands.HttpHeadersSupport.HttpHeaderInfo;
import com.google.refine.operations.EngineDependentOperation;
import com.google.refine.operations.OnError;
import com.google.refine.operations.OperationRegistry;
@ -78,9 +78,6 @@ import com.google.refine.operations.cell.TextTransformOperation;
import com.google.refine.process.LongRunningProcess;
import com.google.refine.process.Process;
import com.google.refine.util.ParsingUtilities;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.LoadingCache;
import com.google.common.cache.CacheLoader;
public class ColumnAdditionByFetchingURLsOperation extends EngineDependentOperation {
@ -98,7 +95,7 @@ public class ColumnAdditionByFetchingURLsOperation extends EngineDependentOperat
JSONObject engineConfig = obj.getJSONObject("engineConfig");
return new ColumnAdditionByFetchingURLsOperation(
engineConfig,
EngineConfig.reconstruct(engineConfig),
obj.getString("baseColumnName"),
obj.getString("urlExpression"),
TextTransformOperation.stringToOnError(obj.getString("onError")),
@ -111,7 +108,7 @@ public class ColumnAdditionByFetchingURLsOperation extends EngineDependentOperat
}
public ColumnAdditionByFetchingURLsOperation(
JSONObject engineConfig,
EngineConfig engineConfig,
String baseColumnName,
String urlExpression,
OnError onError,
@ -142,7 +139,7 @@ public class ColumnAdditionByFetchingURLsOperation extends EngineDependentOperat
writer.object();
writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass()));
writer.key("description"); writer.value(getBriefDescription(null));
writer.key("engineConfig"); writer.value(getEngineConfig());
writer.key("engineConfig"); getEngineConfig().write(writer, options);
writer.key("newColumnName"); writer.value(_newColumnName);
writer.key("columnInsertIndex"); writer.value(_columnInsertIndex);
writer.key("baseColumnName"); writer.value(_baseColumnName);
@ -173,7 +170,7 @@ public class ColumnAdditionByFetchingURLsOperation extends EngineDependentOperat
@Override
public Process createProcess(Project project, Properties options) throws Exception {
Engine engine = createEngine(project);
engine.initializeFromJSON(_engineConfig);
engine.initializeFromConfig(_engineConfig);
Evaluable eval = MetaParser.parse(_urlExpression);

View File

@ -43,6 +43,7 @@ import org.json.JSONObject;
import org.json.JSONWriter;
import com.google.refine.browsing.Engine;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.browsing.FilteredRows;
import com.google.refine.browsing.RowVisitor;
import com.google.refine.expr.Evaluable;
@ -75,7 +76,7 @@ public class ColumnAdditionOperation extends EngineDependentOperation {
JSONObject engineConfig = obj.getJSONObject("engineConfig");
return new ColumnAdditionOperation(
engineConfig,
EngineConfig.reconstruct(engineConfig),
obj.getString("baseColumnName"),
obj.getString("expression"),
TextTransformOperation.stringToOnError(obj.getString("onError")),
@ -85,7 +86,7 @@ public class ColumnAdditionOperation extends EngineDependentOperation {
}
public ColumnAdditionOperation(
JSONObject engineConfig,
EngineConfig engineConfig,
String baseColumnName,
String expression,
OnError onError,
@ -109,7 +110,7 @@ public class ColumnAdditionOperation extends EngineDependentOperation {
writer.object();
writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass()));
writer.key("description"); writer.value(getBriefDescription(null));
writer.key("engineConfig"); writer.value(getEngineConfig());
writer.key("engineConfig"); getEngineConfig().write(writer, options);
writer.key("newColumnName"); writer.value(_newColumnName);
writer.key("columnInsertIndex"); writer.value(_columnInsertIndex);
writer.key("baseColumnName"); writer.value(_baseColumnName);

View File

@ -45,6 +45,7 @@ import org.json.JSONObject;
import org.json.JSONWriter;
import com.google.refine.browsing.Engine;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.browsing.FilteredRows;
import com.google.refine.browsing.RowVisitor;
import com.google.refine.expr.ExpressionUtils;
@ -78,7 +79,7 @@ public class ColumnSplitOperation extends EngineDependentOperation {
if ("separator".equals(mode)) {
return new ColumnSplitOperation(
engineConfig,
EngineConfig.reconstruct(engineConfig),
obj.getString("columnName"),
obj.getBoolean("guessCellType"),
obj.getBoolean("removeOriginalColumn"),
@ -88,7 +89,7 @@ public class ColumnSplitOperation extends EngineDependentOperation {
);
} else {
return new ColumnSplitOperation(
engineConfig,
EngineConfig.reconstruct(engineConfig),
obj.getString("columnName"),
obj.getBoolean("guessCellType"),
obj.getBoolean("removeOriginalColumn"),
@ -98,7 +99,7 @@ public class ColumnSplitOperation extends EngineDependentOperation {
}
public ColumnSplitOperation(
JSONObject engineConfig,
EngineConfig engineConfig,
String columnName,
boolean guessCellType,
boolean removeOriginalColumn,
@ -121,7 +122,7 @@ public class ColumnSplitOperation extends EngineDependentOperation {
}
public ColumnSplitOperation(
JSONObject engineConfig,
EngineConfig engineConfig,
String columnName,
boolean guessCellType,
boolean removeOriginalColumn,
@ -148,7 +149,7 @@ public class ColumnSplitOperation extends EngineDependentOperation {
writer.object();
writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass()));
writer.key("description"); writer.value(getBriefDescription(null));
writer.key("engineConfig"); writer.value(getEngineConfig());
writer.key("engineConfig"); getEngineConfig().write(writer, options);
writer.key("columnName"); writer.value(_columnName);
writer.key("guessCellType"); writer.value(_guessCellType);
writer.key("removeOriginalColumn"); writer.value(_removeOriginalColumn);

View File

@ -41,18 +41,14 @@ import java.util.Map;
import java.util.Properties;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONWriter;
import com.google.refine.browsing.Engine;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.browsing.FilteredRows;
import com.google.refine.browsing.RowVisitor;
import com.google.refine.model.changes.DataExtensionChange;
import com.google.refine.model.recon.ReconciledDataExtensionJob;
import com.google.refine.model.recon.ReconciledDataExtensionJob.ColumnInfo;
import com.google.refine.model.recon.ReconciledDataExtensionJob.DataExtension;
import com.google.refine.history.HistoryEntry;
import com.google.refine.model.AbstractOperation;
import com.google.refine.model.Cell;
@ -62,6 +58,10 @@ import com.google.refine.model.ReconCandidate;
import com.google.refine.model.ReconType;
import com.google.refine.model.Row;
import com.google.refine.model.changes.CellAtRow;
import com.google.refine.model.changes.DataExtensionChange;
import com.google.refine.model.recon.ReconciledDataExtensionJob;
import com.google.refine.model.recon.ReconciledDataExtensionJob.ColumnInfo;
import com.google.refine.model.recon.ReconciledDataExtensionJob.DataExtension;
import com.google.refine.operations.EngineDependentOperation;
import com.google.refine.operations.OperationRegistry;
import com.google.refine.process.LongRunningProcess;
@ -79,7 +79,7 @@ public class ExtendDataOperation extends EngineDependentOperation {
JSONObject engineConfig = obj.getJSONObject("engineConfig");
return new ExtendDataOperation(
engineConfig,
EngineConfig.reconstruct(engineConfig),
obj.getString("baseColumnName"),
obj.getString("endpoint"),
obj.getString("identifierSpace"),
@ -90,7 +90,7 @@ public class ExtendDataOperation extends EngineDependentOperation {
}
public ExtendDataOperation(
JSONObject engineConfig,
EngineConfig engineConfig,
String baseColumnName,
String endpoint,
String identifierSpace,
@ -115,7 +115,7 @@ public class ExtendDataOperation extends EngineDependentOperation {
writer.object();
writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass()));
writer.key("description"); writer.value(getBriefDescription(null));
writer.key("engineConfig"); writer.value(getEngineConfig());
writer.key("engineConfig"); getEngineConfig().write(writer, options);
writer.key("columnInsertIndex"); writer.value(_columnInsertIndex);
writer.key("baseColumnName"); writer.value(_baseColumnName);
writer.key("endpoint"); writer.value(_endpoint);
@ -148,14 +148,14 @@ public class ExtendDataOperation extends EngineDependentOperation {
public class ExtendDataProcess extends LongRunningProcess implements Runnable {
final protected Project _project;
final protected JSONObject _engineConfig;
final protected EngineConfig _engineConfig;
final protected long _historyEntryID;
protected int _cellIndex;
protected ReconciledDataExtensionJob _job;
public ExtendDataProcess(
Project project,
JSONObject engineConfig,
EngineConfig engineConfig,
String description
) throws JSONException {
super(description);
@ -186,7 +186,7 @@ public class ExtendDataOperation extends EngineDependentOperation {
protected void populateRowsWithMatches(List<Integer> rowIndices) throws Exception {
Engine engine = new Engine(_project);
engine.initializeFromJSON(_engineConfig);
engine.initializeFromConfig(_engineConfig);
Column column = _project.columnModel.getColumnByName(_baseColumnName);
if (column == null) {

View File

@ -40,6 +40,7 @@ import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONWriter;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.browsing.RowVisitor;
import com.google.refine.history.Change;
import com.google.refine.model.AbstractOperation;
@ -58,14 +59,14 @@ public class ReconClearSimilarCellsOperation extends EngineDependentMassCellOper
static public AbstractOperation reconstruct(Project project, JSONObject obj) throws Exception {
JSONObject engineConfig = obj.getJSONObject("engineConfig");
return new ReconClearSimilarCellsOperation(
engineConfig,
EngineConfig.reconstruct(engineConfig),
obj.getString("columnName"),
obj.getString("similarValue")
);
}
public ReconClearSimilarCellsOperation(
JSONObject engineConfig,
EngineConfig engineConfig,
String columnName,
String similarValue
) {
@ -80,7 +81,7 @@ public class ReconClearSimilarCellsOperation extends EngineDependentMassCellOper
writer.object();
writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass()));
writer.key("description"); writer.value(getBriefDescription(null));
writer.key("engineConfig"); writer.value(getEngineConfig());
writer.key("engineConfig"); getEngineConfig().write(writer, options);
writer.key("columnName"); writer.value(_columnName);
writer.key("similarValue"); writer.value(_similarValue);

View File

@ -47,6 +47,7 @@ import org.json.JSONObject;
import org.json.JSONWriter;
import com.google.refine.browsing.Engine;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.browsing.FilteredRows;
import com.google.refine.browsing.RowVisitor;
import com.google.refine.history.HistoryEntry;
@ -72,7 +73,7 @@ public class ReconCopyAcrossColumnsOperation extends EngineDependentOperation {
static public AbstractOperation reconstruct(Project project, JSONObject obj) throws Exception {
JSONObject engineConfig = obj.getJSONObject("engineConfig");
return new ReconCopyAcrossColumnsOperation(
engineConfig,
EngineConfig.reconstruct(engineConfig),
obj.getString("fromColumnName"),
JSONUtilities.getStringArray(obj, "toColumnNames"),
JSONUtilities.getStringArray(obj, "judgments"),
@ -81,7 +82,7 @@ public class ReconCopyAcrossColumnsOperation extends EngineDependentOperation {
}
public ReconCopyAcrossColumnsOperation(
JSONObject engineConfig,
EngineConfig engineConfig,
String fromColumnName,
String[] toColumnNames,
String[] judgments,
@ -100,7 +101,7 @@ public class ReconCopyAcrossColumnsOperation extends EngineDependentOperation {
writer.object();
writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass()));
writer.key("description"); writer.value(getBriefDescription(null));
writer.key("engineConfig"); writer.value(getEngineConfig());
writer.key("engineConfig"); getEngineConfig().write(writer, options);
writer.key("fromColumnName"); writer.value(_fromColumnName);
writer.key("toColumnNames");
writer.array();

View File

@ -42,6 +42,7 @@ import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONWriter;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.browsing.RowVisitor;
import com.google.refine.history.Change;
import com.google.refine.model.AbstractOperation;
@ -62,13 +63,13 @@ public class ReconDiscardJudgmentsOperation extends EngineDependentMassCellOpera
static public AbstractOperation reconstruct(Project project, JSONObject obj) throws Exception {
JSONObject engineConfig = obj.getJSONObject("engineConfig");
return new ReconDiscardJudgmentsOperation(
engineConfig,
EngineConfig.reconstruct(engineConfig),
obj.getString("columnName"),
obj.has("clearData") && obj.getBoolean("clearData")
);
}
public ReconDiscardJudgmentsOperation(JSONObject engineConfig, String columnName, boolean clearData) {
public ReconDiscardJudgmentsOperation(EngineConfig engineConfig, String columnName, boolean clearData) {
super(engineConfig, columnName, false);
_clearData = clearData;
}
@ -80,7 +81,7 @@ public class ReconDiscardJudgmentsOperation extends EngineDependentMassCellOpera
writer.object();
writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass()));
writer.key("description"); writer.value(getBriefDescription(null));
writer.key("engineConfig"); writer.value(getEngineConfig());
writer.key("engineConfig"); getEngineConfig().write(writer, options);
writer.key("columnName"); writer.value(_columnName);
writer.key("clearData"); writer.value(_clearData);
writer.endObject();

View File

@ -43,6 +43,7 @@ import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONWriter;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.browsing.RowVisitor;
import com.google.refine.expr.ExpressionUtils;
import com.google.refine.history.Change;
@ -93,7 +94,7 @@ public class ReconJudgeSimilarCellsOperation extends EngineDependentMassCellOper
}
return new ReconJudgeSimilarCellsOperation(
engineConfig,
EngineConfig.reconstruct(engineConfig),
obj.getString("columnName"),
obj.getString("similarValue"),
judgment,
@ -103,7 +104,7 @@ public class ReconJudgeSimilarCellsOperation extends EngineDependentMassCellOper
}
public ReconJudgeSimilarCellsOperation(
JSONObject engineConfig,
EngineConfig engineConfig,
String columnName,
String similarValue,
Judgment judgment,
@ -124,7 +125,7 @@ public class ReconJudgeSimilarCellsOperation extends EngineDependentMassCellOper
writer.object();
writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass()));
writer.key("description"); writer.value(getBriefDescription(null));
writer.key("engineConfig"); writer.value(getEngineConfig());
writer.key("engineConfig"); getEngineConfig().write(writer, options);
writer.key("columnName"); writer.value(_columnName);
writer.key("similarValue"); writer.value(_similarValue);
writer.key("judgment"); writer.value(Recon.judgmentToString(_judgment));

View File

@ -42,6 +42,7 @@ import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONWriter;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.browsing.RowVisitor;
import com.google.refine.history.Change;
import com.google.refine.model.AbstractOperation;
@ -64,13 +65,13 @@ public class ReconMarkNewTopicsOperation extends EngineDependentMassCellOperatio
JSONObject engineConfig = obj.getJSONObject("engineConfig");
return new ReconMarkNewTopicsOperation(
engineConfig,
EngineConfig.reconstruct(engineConfig),
obj.getString("columnName"),
obj.has("shareNewTopics") ? obj.getBoolean("shareNewTopics") : false
);
}
public ReconMarkNewTopicsOperation(JSONObject engineConfig, String columnName, boolean shareNewTopics) {
public ReconMarkNewTopicsOperation(EngineConfig engineConfig, String columnName, boolean shareNewTopics) {
super(engineConfig, columnName, false);
_shareNewTopics = shareNewTopics;
}
@ -82,7 +83,7 @@ public class ReconMarkNewTopicsOperation extends EngineDependentMassCellOperatio
writer.object();
writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass()));
writer.key("description"); writer.value(getBriefDescription(null));
writer.key("engineConfig"); writer.value(getEngineConfig());
writer.key("engineConfig"); getEngineConfig().write(writer, options);
writer.key("columnName"); writer.value(_columnName);
writer.key("shareNewTopics"); writer.value(_shareNewTopics);
writer.endObject();

View File

@ -42,6 +42,7 @@ import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONWriter;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.browsing.RowVisitor;
import com.google.refine.history.Change;
import com.google.refine.model.AbstractOperation;
@ -63,12 +64,12 @@ public class ReconMatchBestCandidatesOperation extends EngineDependentMassCellOp
String columnName = obj.getString("columnName");
return new ReconMatchBestCandidatesOperation(
engineConfig,
EngineConfig.reconstruct(engineConfig),
columnName
);
}
public ReconMatchBestCandidatesOperation(JSONObject engineConfig, String columnName) {
public ReconMatchBestCandidatesOperation(EngineConfig engineConfig, String columnName) {
super(engineConfig, columnName, false);
}
@ -79,7 +80,7 @@ public class ReconMatchBestCandidatesOperation extends EngineDependentMassCellOp
writer.object();
writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass()));
writer.key("description"); writer.value(getBriefDescription(null));
writer.key("engineConfig"); writer.value(getEngineConfig());
writer.key("engineConfig"); getEngineConfig().write(writer, options);
writer.key("columnName"); writer.value(_columnName);
writer.endObject();
}

View File

@ -43,6 +43,7 @@ import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONWriter;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.browsing.RowVisitor;
import com.google.refine.history.Change;
import com.google.refine.model.AbstractOperation;
@ -75,7 +76,7 @@ public class ReconMatchSpecificTopicOperation extends EngineDependentMassCellOpe
}
return new ReconMatchSpecificTopicOperation(
engineConfig,
EngineConfig.reconstruct(engineConfig),
obj.getString("columnName"),
new ReconCandidate(
match.getString("id"),
@ -89,7 +90,7 @@ public class ReconMatchSpecificTopicOperation extends EngineDependentMassCellOpe
}
public ReconMatchSpecificTopicOperation(
JSONObject engineConfig,
EngineConfig engineConfig,
String columnName,
ReconCandidate match,
String identifierSpace,
@ -108,7 +109,7 @@ public class ReconMatchSpecificTopicOperation extends EngineDependentMassCellOpe
writer.object();
writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass()));
writer.key("description"); writer.value(getBriefDescription(null));
writer.key("engineConfig"); writer.value(getEngineConfig());
writer.key("engineConfig"); getEngineConfig().write(writer, options);
writer.key("columnName"); writer.value(_columnName);
writer.key("match");
writer.object();

View File

@ -46,6 +46,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.refine.browsing.Engine;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.browsing.FilteredRows;
import com.google.refine.browsing.RowVisitor;
import com.google.refine.expr.ExpressionUtils;
@ -77,14 +78,14 @@ public class ReconOperation extends EngineDependentOperation {
JSONObject engineConfig = obj.getJSONObject("engineConfig");
return new ReconOperation(
engineConfig,
EngineConfig.reconstruct(engineConfig),
obj.getString("columnName"),
ReconConfig.reconstruct(obj.getJSONObject("config"))
);
}
public ReconOperation(
JSONObject engineConfig,
EngineConfig engineConfig,
String columnName,
ReconConfig reconConfig
) {
@ -116,7 +117,7 @@ public class ReconOperation extends EngineDependentOperation {
writer.key("description"); writer.value(getBriefDescription(null));
writer.key("columnName"); writer.value(_columnName);
writer.key("config"); _reconConfig.write(writer, options);
writer.key("engineConfig"); writer.value(getEngineConfig());
writer.key("engineConfig"); getEngineConfig().write(writer, options);
writer.endObject();
}
@ -140,15 +141,15 @@ public class ReconOperation extends EngineDependentOperation {
}
public class ReconProcess extends LongRunningProcess implements Runnable {
final protected Project _project;
final protected JSONObject _engineConfig;
final protected long _historyEntryID;
protected List<ReconEntry> _entries;
protected int _cellIndex;
final protected Project _project;
final protected EngineConfig _engineConfig;
final protected long _historyEntryID;
protected List<ReconEntry> _entries;
protected int _cellIndex;
public ReconProcess(
Project project,
JSONObject engineConfig,
EngineConfig engineConfig,
String description
) {
super(description);
@ -208,7 +209,7 @@ public class ReconOperation extends EngineDependentOperation {
protected void populateEntries() throws Exception {
Engine engine = new Engine(_project);
engine.initializeFromJSON(_engineConfig);
engine.initializeFromConfig(_engineConfig);
Column column = _project.columnModel.getColumnByName(_columnName);
if (column == null) {

View File

@ -42,6 +42,7 @@ import org.json.JSONObject;
import org.json.JSONWriter;
import com.google.refine.browsing.Engine;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.browsing.FilteredRows;
import com.google.refine.browsing.RowVisitor;
import com.google.refine.history.Change;
@ -62,12 +63,12 @@ public class RowFlagOperation extends EngineDependentOperation {
boolean flagged = obj.getBoolean("flagged");
return new RowFlagOperation(
engineConfig,
EngineConfig.reconstruct(engineConfig),
flagged
);
}
public RowFlagOperation(JSONObject engineConfig, boolean flagged) {
public RowFlagOperation(EngineConfig engineConfig, boolean flagged) {
super(engineConfig);
_flagged = flagged;
}
@ -79,7 +80,7 @@ public class RowFlagOperation extends EngineDependentOperation {
writer.object();
writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass()));
writer.key("description"); writer.value(getBriefDescription(null));
writer.key("engineConfig"); writer.value(getEngineConfig());
writer.key("engineConfig"); getEngineConfig().write(writer, options);
writer.key("flagged"); writer.value(_flagged);
writer.endObject();
}

View File

@ -42,6 +42,7 @@ import org.json.JSONObject;
import org.json.JSONWriter;
import com.google.refine.browsing.Engine;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.browsing.FilteredRows;
import com.google.refine.browsing.RowVisitor;
import com.google.refine.history.HistoryEntry;
@ -57,11 +58,11 @@ public class RowRemovalOperation extends EngineDependentOperation {
JSONObject engineConfig = obj.getJSONObject("engineConfig");
return new RowRemovalOperation(
engineConfig
EngineConfig.reconstruct(engineConfig)
);
}
public RowRemovalOperation(JSONObject engineConfig) {
public RowRemovalOperation(EngineConfig engineConfig) {
super(engineConfig);
}
@ -72,7 +73,7 @@ public class RowRemovalOperation extends EngineDependentOperation {
writer.object();
writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass()));
writer.key("description"); writer.value(getBriefDescription(null));
writer.key("engineConfig"); writer.value(getEngineConfig());
writer.key("engineConfig"); getEngineConfig().write(writer, options);
writer.endObject();
}

View File

@ -42,6 +42,7 @@ import org.json.JSONObject;
import org.json.JSONWriter;
import com.google.refine.browsing.Engine;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.browsing.FilteredRows;
import com.google.refine.browsing.RowVisitor;
import com.google.refine.history.Change;
@ -62,12 +63,12 @@ public class RowStarOperation extends EngineDependentOperation {
boolean starred = obj.getBoolean("starred");
return new RowStarOperation(
engineConfig,
EngineConfig.reconstruct(engineConfig),
starred
);
}
public RowStarOperation(JSONObject engineConfig, boolean starred) {
public RowStarOperation(EngineConfig engineConfig, boolean starred) {
super(engineConfig);
_starred = starred;
}
@ -79,7 +80,7 @@ public class RowStarOperation extends EngineDependentOperation {
writer.object();
writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass()));
writer.key("description"); writer.value(getBriefDescription(null));
writer.key("engineConfig"); writer.value(getEngineConfig());
writer.key("engineConfig"); getEngineConfig().write(writer, options);
writer.key("starred"); writer.value(_starred);
writer.endObject();
}

View File

@ -7,7 +7,7 @@ import com.google.refine.tests.util.TestUtils;
public class EvalErrorTests {
@Test
public void serializeEvalError() {
EvalError e = new EvalError("this is a critical error");
EvalError e = new EvalError("This is a critical error");
TestUtils.isSerializedTo(e, "{\"type\":\"error\",\"message\":\"This is a critical error\"}");
}
}

View File

@ -7,8 +7,6 @@ import com.google.refine.browsing.Engine;
import com.google.refine.model.Project;
import com.google.refine.tests.util.TestUtils;
// TODO Engine and engine config should be separated
// create an EngineConfig class that can be used in operations directly (to avoid manipulating JSONObject)
public class EngineTests {
@Test

View File

@ -0,0 +1,62 @@
package com.google.refine.tests.browsing.facets;
import org.json.JSONObject;
import org.testng.Assert;
import org.testng.annotations.Test;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.browsing.Engine.Mode;
import com.google.refine.tests.util.TestUtils;
public class EngineConfigTests {
public static String engineConfigJson =
"{\n"
+ " \"mode\": \"row-based\",\n"
+ " \"facets\": [\n"
+ " {\n"
+ " \"mode\": \"text\",\n"
+ " \"invert\": false,\n"
+ " \"caseSensitive\": false,\n"
+ " \"query\": \"www\",\n"
+ " \"name\": \"reference\",\n"
+ " \"type\": \"text\",\n"
+ " \"columnName\": \"reference\"\n"
+ " }\n"
+ " ]\n"
+ " }";
public static String engineConfigRecordModeJson =
"{"
+ " \"mode\":\"record-based\","
+ " \"facets\":[]"
+ "}";
public static String noFacetProvided = "{\"mode\":\"row-based\"}";
@Test
public void serializeEngineConfig() {
EngineConfig ec = EngineConfig.reconstruct(new JSONObject(engineConfigJson));
TestUtils.isSerializedTo(ec, engineConfigJson);
}
@Test
public void serializeEngineConfigRecordMode() {
EngineConfig ec = EngineConfig.reconstruct(new JSONObject(engineConfigRecordModeJson));
TestUtils.isSerializedTo(ec, engineConfigRecordModeJson);
}
@Test
public void reconstructNullEngineConfig() {
EngineConfig ec = EngineConfig.reconstruct(null);
Assert.assertEquals(ec.getMode(), Mode.RowBased);
Assert.assertTrue(ec.getFacetConfigs().isEmpty());
}
@Test
public void reconstructNoFacetsProvided() {
EngineConfig ec = EngineConfig.reconstruct(new JSONObject(noFacetProvided));
Assert.assertEquals(ec.getMode(), Mode.RowBased);
Assert.assertTrue(ec.getFacetConfigs().isEmpty());
}
}

View File

@ -0,0 +1,80 @@
package com.google.refine.tests.browsing.facets;
import org.json.JSONObject;
import org.testng.annotations.Test;
import com.google.refine.browsing.Engine;
import com.google.refine.browsing.facets.Facet;
import com.google.refine.browsing.facets.ListFacet.ListFacetConfig;
import com.google.refine.model.Project;
import com.google.refine.tests.RefineTest;
import com.google.refine.tests.util.TestUtils;
public class ListFacetTests extends RefineTest {
private static String jsonConfig = "{"
+ "\"type\":\"list\","
+ "\"name\":\"facet A\","
+ "\"columnName\":\"Column A\","
+ "\"expression\":\"value+\\\"bar\\\"\","
+ "\"omitBlank\":false,"
+ "\"omitError\":false,"
+ "\"selection\":[{\"v\":{\"v\":\"foobar\",\"l\":\"true\"}}],"
+ "\"selectBlank\":false,"
+ "\"selectError\":false,"
+ "\"invert\":false"
+ "}";
private static String jsonFacetError = "{"
+ "\"name\":\"facet A\","
+ "\"expression\":\"value+\\\"bar\\\"\","
+ "\"columnName\":\"Column A\","
+ "\"invert\":false,"
+ "\"error\":\"No column named Column A\"}\" are not equal as JSON strings.\n" +
"}";
private static String jsonFacet = "{"
+ "\"name\":\"facet A\","
+ "\"expression\":\"value+\\\"bar\\\"\","
+ "\"columnName\":\"Column A\","
+ "\"invert\":false,"
+ "\"choices\":["
+ " {\"v\":{\"v\":\"foobar\",\"l\":\"foobar\"},\"c\":1,\"s\":true},"
+ " {\"v\":{\"v\":\"barbar\",\"l\":\"barbar\"},\"c\":1,\"s\":false}"
+ "]}";
@Test
public void serializeListFacetConfig() {
ListFacetConfig facetConfig = new ListFacetConfig();
facetConfig.initializeFromJSON(new JSONObject(jsonConfig));
TestUtils.isSerializedTo(facetConfig, jsonConfig);
}
@Test
public void serializeListFacet() {
Project project = createCSVProject("Column A\n" +
"foo\n" +
"bar\n");
Engine engine = new Engine(project);
ListFacetConfig facetConfig = new ListFacetConfig();
facetConfig.initializeFromJSON(new JSONObject(jsonConfig));
Facet facet = facetConfig.apply(project);
facet.computeChoices(project, engine.getAllFilteredRows());
TestUtils.isSerializedTo(facet, jsonFacet);
}
@Test
public void serializeListFacetWithError() {
Project project = createCSVProject("other column\n" +
"foo\n" +
"bar\n");
ListFacetConfig facetConfig = new ListFacetConfig();
facetConfig.initializeFromJSON(new JSONObject(jsonConfig));
Facet facet = facetConfig.apply(project);
TestUtils.isSerializedTo(facet, jsonFacetError);
}
}

View File

@ -0,0 +1,72 @@
package com.google.refine.tests.browsing.facets;
import org.json.JSONObject;
import org.testng.annotations.Test;
import com.google.refine.browsing.Engine;
import com.google.refine.browsing.facets.RangeFacet;
import com.google.refine.browsing.facets.RangeFacet.RangeFacetConfig;
import com.google.refine.model.Cell;
import com.google.refine.model.Project;
import com.google.refine.tests.RefineTest;
import com.google.refine.tests.util.TestUtils;
public class RangeFacetTests extends RefineTest {
public static String configJson = "{\n" +
" \"selectNumeric\": true,\n" +
" \"expression\": \"value\",\n" +
" \"selectBlank\": true,\n" +
" \"selectNonNumeric\": true,\n" +
" \"selectError\": true,\n" +
" \"name\": \"my column\",\n" +
" \"from\": -30,\n" +
" \"to\": 90,\n" +
" \"type\": \"range\",\n" +
" \"columnName\": \"my column\"\n" +
" }";
public static String facetJson = "{"
+ "\"name\":\"my column\","
+ "\"expression\":\"value\","
+ "\"columnName\":\"my column\","
+ "\"min\":-50,"
+ "\"max\":90,"
+ "\"step\":10,"
+ "\"bins\":[1,0,0,0,0,1,0,0,0,0,0,0,0,1],"
+ "\"baseBins\":[1,0,0,0,0,1,0,0,0,0,0,0,0,1],"
+ "\"from\":-30,"
+ "\"to\":90,"
+ "\"baseNumericCount\":3,"
+ "\"baseNonNumericCount\":1,"
+ "\"baseBlankCount\":0,"
+ "\"baseErrorCount\":0,"
+ "\"numericCount\":3,"
+ "\"nonNumericCount\":1,"
+ "\"blankCount\":0,"
+ "\"errorCount\":0}";
@Test
public void serializeRangeFacetConfig() {
RangeFacetConfig config = new RangeFacetConfig();
config.initializeFromJSON(new JSONObject(configJson));
TestUtils.isSerializedTo(config, configJson);
}
@Test
public void serializeRangeFacet() {
Project project = createCSVProject("my column\n"
+ "89.2\n"
+ "-45.9\n"
+ "blah\n"
+ "0.4\n");
project.rows.get(0).cells.set(0, new Cell(89.2, null));
project.rows.get(1).cells.set(0, new Cell(-45.9, null));
project.rows.get(3).cells.set(0, new Cell(0.4, null));
Engine engine = new Engine(project);
RangeFacetConfig config = new RangeFacetConfig();
config.initializeFromJSON(new JSONObject(configJson));
RangeFacet facet = config.apply(project);
facet.computeChoices(project, engine.getAllFilteredRows());
TestUtils.isSerializedTo(facet, facetJson);
}
}

View File

@ -0,0 +1,80 @@
package com.google.refine.tests.browsing.facets;
import org.json.JSONObject;
import org.testng.annotations.Test;
import com.google.refine.browsing.Engine;
import com.google.refine.browsing.facets.ScatterplotFacet;
import com.google.refine.browsing.facets.ScatterplotFacet.ScatterplotFacetConfig;
import com.google.refine.model.Cell;
import com.google.refine.model.Project;
import com.google.refine.tests.RefineTest;
import com.google.refine.tests.util.TestUtils;
public class ScatterplotFacetTests extends RefineTest {
public static String configJson = "{\n" +
" \"to_x\": 1,\n" +
" \"to_y\": 1,\n" +
" \"dot\": 1,\n" +
" \"from_x\": 0.21333333333333335,\n" +
" \"l\": 150,\n" +
" \"type\": \"scatterplot\",\n" +
" \"from_y\": 0.26666666666666666,\n" +
" \"dim_y\": \"lin\",\n" +
" \"ex\": \"value\",\n" +
" \"dim_x\": \"lin\",\n" +
" \"ey\": \"value\",\n" +
" \"cx\": \"my column\",\n" +
" \"cy\": \"e\",\n" +
" \"name\": \"my column (x) vs. e (y)\"\n" +
" }";
public static String facetJson = "{"
+ "\"name\":\"my column (x) vs. e (y)\","
+ "\"cx\":\"my column\","
+ "\"ex\":\"value\","
+ "\"cy\":\"e\","
+ "\"ey\":\"value\","
+ "\"l\":150,"
+ "\"dot\":1,"
+ "\"r\":0,"
+ "\"dim_x\":0,"
+ "\"dim_y\":0,"
+ "\"color\":\"000000\","
+ "\"from_x\":0.21333333333333335,"
+ "\"to_x\":1,"
+ "\"from_y\":0.26666666666666666,"
+ "\"to_y\":1"
+ "}";
@Test
public void serializeScatterplotFacetConfig() {
ScatterplotFacetConfig config = new ScatterplotFacetConfig();
config.initializeFromJSON(new JSONObject(configJson));
TestUtils.isSerializedTo(config, configJson);
}
@Test
public void serializeScatterplotFacet() {
Project project = createCSVProject("my column,e\n"
+ "89.2,89.2\n" +
"-45.9,-45.9\n" +
"blah,blah\n" +
"0.4,0.4\n");
Engine engine = new Engine(project);
project.rows.get(0).cells.set(0, new Cell(89.2, null));
project.rows.get(0).cells.set(1, new Cell(89.2, null));
project.rows.get(1).cells.set(0, new Cell(-45.9, null));
project.rows.get(1).cells.set(1, new Cell(-45.9, null));
project.rows.get(3).cells.set(0, new Cell(0.4, null));
project.rows.get(3).cells.set(1, new Cell(0.4, null));
ScatterplotFacetConfig config = new ScatterplotFacetConfig();
config.initializeFromJSON(new JSONObject(configJson));
ScatterplotFacet facet = config.apply(project);
facet.computeChoices(project, engine.getAllFilteredRows());
TestUtils.isSerializedTo(facet, facetJson);
}
}

View File

@ -43,20 +43,35 @@ import org.testng.annotations.BeforeMethod;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import com.google.refine.model.ModelException;
import com.google.refine.model.Project;
import com.google.refine.model.metadata.ProjectMetadata;
import com.google.refine.browsing.RowFilter;
import com.google.refine.browsing.facets.TextSearchFacet;
import com.google.refine.browsing.facets.TextSearchFacet.TextSearchFacetConfig;
import com.google.refine.model.ModelException;
import com.google.refine.model.Project;
import com.google.refine.tests.RefineTest;
import com.google.refine.tests.util.TestUtils;
public class TextSearchFacetTests extends RefineTest {
// dependencies
private Project project;
private TextSearchFacetConfig textfilterconfig;
private TextSearchFacet textfilter;
private RowFilter rowfilter;
private JSONObject textsearchfacet;
private String sensitiveConfigJson = "{\"type\":\"text\","
+ "\"name\":\"Value\","
+ "\"columnName\":\"Value\","
+ "\"mode\":\"text\","
+ "\"caseSensitive\":true,"
+ "\"invert\":false,"
+ "\"query\":\"A\"}";
private String sensitiveFacetJson = "{\"name\":\"Value\","
+ "\"columnName\":\"Value\","
+ "\"query\":\"A\","
+ "\"mode\":\"text\","
+ "\"caseSensitive\":true,"
+ "\"invert\":false}";
@Override
@BeforeTest
@ -74,6 +89,14 @@ public class TextSearchFacetTests extends RefineTest {
+ "Abc\n");
}
private void configureFilter(String filter) {
//Add the facet to the project and create a row filter
textfilterconfig = new TextSearchFacetConfig();
textfilterconfig.initializeFromJSON(new JSONObject(filter));
textfilter = textfilterconfig.apply(project);
rowfilter = textfilter.getRowFilter(project);
}
/**
* Test to demonstrate the intended behaviour of the function
*/
@ -95,11 +118,7 @@ public class TextSearchFacetTests extends RefineTest {
+ "\"invert\":false,"
+ "\"query\":\"a\"}";
//Add the facet to the project and create a row filter
textfilter = new TextSearchFacet();
textsearchfacet = new JSONObject(filter);
textfilter.initializeFromJSON(project,textsearchfacet);
rowfilter = textfilter.getRowFilter(project);
configureFilter(filter);
//Check each row in the project against the filter
Assert.assertEquals(rowfilter.filterRow(project, 0, project.rows.get(0)),true);
@ -125,11 +144,7 @@ public class TextSearchFacetTests extends RefineTest {
+ "\"invert\":true,"
+ "\"query\":\"a\"}";
//Add the facet to the project and create a row filter
textfilter = new TextSearchFacet();
textsearchfacet = new JSONObject(filter);
textfilter.initializeFromJSON(project,textsearchfacet);
rowfilter = textfilter.getRowFilter(project);
configureFilter(filter);
//Check each row in the project against the filter
Assert.assertEquals(rowfilter.filterRow(project, 0, project.rows.get(0)),false);
@ -155,11 +170,7 @@ public class TextSearchFacetTests extends RefineTest {
+ "\"invert\":false,"
+ "\"query\":\"[bc]\"}";
//Add the facet to the project and create a row filter
textfilter = new TextSearchFacet();
textsearchfacet = new JSONObject(filter);
textfilter.initializeFromJSON(project,textsearchfacet);
rowfilter = textfilter.getRowFilter(project);
configureFilter(filter);
//Check each row in the project against the filter
Assert.assertEquals(rowfilter.filterRow(project, 0, project.rows.get(0)),false);
@ -171,25 +182,8 @@ public class TextSearchFacetTests extends RefineTest {
@Test
public void testCaseSensitiveFilter() throws Exception {
//Apply case-sensitive filter "A"
//Column: "Value"
//Filter Query: "A"
//Mode: "text"
//Case sensitive: True
//Invert: False
String filter = "{\"type\":\"text\","
+ "\"name\":\"Value\","
+ "\"columnName\":\"Value\","
+ "\"mode\":\"text\","
+ "\"caseSensitive\":true,"
+ "\"invert\":false,"
+ "\"query\":\"A\"}";
//Add the facet to the project and create a row filter
textfilter = new TextSearchFacet();
textsearchfacet = new JSONObject(filter);
textfilter.initializeFromJSON(project,textsearchfacet);
rowfilter = textfilter.getRowFilter(project);
configureFilter(sensitiveConfigJson);
//Check each row in the project against the filter
//Expect to retrieve one row containing "Abc"
@ -198,5 +192,20 @@ public class TextSearchFacetTests extends RefineTest {
Assert.assertEquals(rowfilter.filterRow(project, 2, project.rows.get(2)),false);
Assert.assertEquals(rowfilter.filterRow(project, 3, project.rows.get(3)),true);
}
@Test
public void serializeTextSearchFacetConfig() {
TextSearchFacetConfig config = new TextSearchFacetConfig();
config.initializeFromJSON(new JSONObject(sensitiveConfigJson));
TestUtils.isSerializedTo(config, sensitiveConfigJson);
}
@Test
public void serializeTextSearchFacet() {
TextSearchFacetConfig config = new TextSearchFacetConfig();
config.initializeFromJSON(new JSONObject(sensitiveConfigJson));
TextSearchFacet facet = config.apply(project);
TestUtils.isSerializedTo(facet, sensitiveFacetJson);
}
}

View File

@ -0,0 +1,77 @@
package com.google.refine.tests.browsing.facets;
import java.time.OffsetDateTime;
import org.json.JSONObject;
import org.testng.annotations.Test;
import com.google.refine.browsing.Engine;
import com.google.refine.browsing.facets.TimeRangeFacet;
import com.google.refine.browsing.facets.TimeRangeFacet.TimeRangeFacetConfig;
import com.google.refine.model.Cell;
import com.google.refine.model.Project;
import com.google.refine.tests.RefineTest;
import com.google.refine.tests.util.TestUtils;
public class TimeRangeFacetTests extends RefineTest {
public static String facetJson = "{"
+ "\"name\":\"my column\","
+ "\"expression\":\"value\","
+ "\"columnName\":\"my column\","
+ "\"min\":1.199329445E12,"
+ "\"max\":1.51496695E12,"
+ "\"step\":3.1556952E10,"
+ "\"bins\":[1,0,0,0,1,0,0,0,0,0,1],"
+ "\"baseBins\":[1,0,0,0,1,0,0,0,0,0,1],"
+ "\"from\":1.262443349E12,"
+ "\"to\":1.51496695E12,"
+ "\"baseTimeCount\":3,"
+ "\"baseNonTimeCount\":1,"
+ "\"baseBlankCount\":0,"
+ "\"baseErrorCount\":0,"
+ "\"timeCount\":3,"
+ "\"nonTimeCount\":1,"
+ "\"blankCount\":0,"
+ "\"errorCount\":0}";
public static String configJson = "{\n" +
" \"selectNonTime\": true,\n" +
" \"expression\": \"value\",\n" +
" \"selectBlank\": true,\n" +
" \"selectError\": true,\n" +
" \"selectTime\": true,\n" +
" \"name\": \"my column\",\n" +
" \"from\": 1262443349000,\n" +
" \"to\": 1514966950000,\n" +
" \"type\": \"timerange\",\n" +
" \"columnName\": \"my column\"\n" +
" }";
@Test
public void serializeTimeRangeFacetConfig() {
TimeRangeFacetConfig config = new TimeRangeFacetConfig();
config.initializeFromJSON(new JSONObject(configJson));
TestUtils.isSerializedTo(config, configJson);
}
@Test
public void serializeTimeRangeFacet() {
Project project = createCSVProject("my column\n"
+ "placeholder\n"
+ "nontime\n"
+ "placeholder\n"
+ "placeholder\n");
project.rows.get(0).cells.set(0, new Cell(OffsetDateTime.parse("2018-01-03T08:09:10Z"), null));
project.rows.get(2).cells.set(0, new Cell(OffsetDateTime.parse("2008-01-03T03:04:05Z"), null));
project.rows.get(3).cells.set(0, new Cell(OffsetDateTime.parse("2012-04-05T02:00:01Z"), null));
Engine engine = new Engine(project);
TimeRangeFacetConfig config = new TimeRangeFacetConfig();
config.initializeFromJSON(new JSONObject(configJson));
TimeRangeFacet facet = config.apply(project);
facet.computeChoices(project, engine.getAllFilteredRows());
TestUtils.isSerializedTo(facet, facetJson);
}
}

View File

@ -40,6 +40,7 @@ import org.json.JSONException;
import org.json.JSONObject;
import com.google.refine.browsing.Engine;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.commands.Command;
import com.google.refine.model.Project;
@ -53,7 +54,7 @@ public class CommandStub extends Command {
return getProject(request);
}
public JSONObject wrapGetEngineConfig(HttpServletRequest request)
public EngineConfig wrapGetEngineConfig(HttpServletRequest request)
throws JSONException {
return getEngineConfig(request);
}

View File

@ -52,6 +52,8 @@ import org.testng.annotations.Test;
import com.google.refine.ProjectManager;
import com.google.refine.browsing.Engine;
import com.google.refine.browsing.Engine.Mode;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.model.Project;
import com.google.refine.tests.RefineTest;
@ -151,11 +153,11 @@ public class CommandTests extends RefineTest {
@Test
public void getEngineConfigRegressionTest() {
when(request.getParameter("engine")).thenReturn("{\"hello\":\"world\"}");
JSONObject o = null;
when(request.getParameter("engine")).thenReturn("{\"mode\":\"row-based\"}");
EngineConfig o = null;
try {
o = SUT.wrapGetEngineConfig(request);
Assert.assertEquals("world", o.getString("hello"));
Assert.assertEquals(Mode.RowBased, o.getMode());
} catch (JSONException e) {
Assert.fail();
} catch (Exception e) {

View File

@ -45,6 +45,7 @@ import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import com.google.refine.browsing.Engine;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.browsing.RowVisitor;
import com.google.refine.expr.functions.FacetCount;
import com.google.refine.grel.Function;
@ -72,7 +73,7 @@ public class CacheTests extends RefineTest {
// dependencies
Project project;
Properties options;
JSONObject engine_config;
EngineConfig engine_config;
Engine engine;
Properties bindings;
@ -81,8 +82,8 @@ public class CacheTests extends RefineTest {
project = createProjectWithColumns("CacheTests", "Column A");
engine = new Engine(project);
engine_config = new JSONObject(ENGINE_JSON_DUPLICATES);
engine.initializeFromJSON(engine_config);
engine_config = EngineConfig.reconstruct(new JSONObject(ENGINE_JSON_DUPLICATES));
engine.initializeFromConfig(engine_config);
engine.setMode(Engine.Mode.RowBased);
bindings = new Properties();

View File

@ -11,6 +11,7 @@ import org.testng.annotations.BeforeSuite;
import org.testng.annotations.Test;
import com.google.refine.ProjectManager;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.model.AbstractOperation;
import com.google.refine.model.Project;
import com.google.refine.operations.OperationRegistry;
@ -56,7 +57,7 @@ public class BlankDownTests extends RefineTest {
@Test
public void testBlankDownRecords() throws Exception {
AbstractOperation op = new BlankDownOperation(
new JSONObject("{\"mode\":\"record-based\",\"facets\":[]}"),
EngineConfig.reconstruct(new JSONObject("{\"mode\":\"record-based\",\"facets\":[]}")),
"second");
Process process = op.createProcess(project, new Properties());
process.performImmediate();
@ -70,7 +71,7 @@ public class BlankDownTests extends RefineTest {
@Test
public void testBlankDownRows() throws Exception {
AbstractOperation op = new BlankDownOperation(
new JSONObject("{\"mode\":\"row-based\",\"facets\":[]}"),
EngineConfig.reconstruct(new JSONObject("{\"mode\":\"row-based\",\"facets\":[]}")),
"second");
Process process = op.createProcess(project, new Properties());
process.performImmediate();

View File

@ -11,6 +11,7 @@ import org.testng.annotations.BeforeSuite;
import org.testng.annotations.Test;
import com.google.refine.ProjectManager;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.model.AbstractOperation;
import com.google.refine.model.Project;
import com.google.refine.operations.OperationRegistry;
@ -55,7 +56,7 @@ public class FillDownTests extends RefineTest {
@Test
public void testFillDownRecordKey() throws Exception {
AbstractOperation op = new FillDownOperation(
new JSONObject("{\"mode\":\"record-based\",\"facets\":[]}"),
EngineConfig.reconstruct(new JSONObject("{\"mode\":\"record-based\",\"facets\":[]}")),
"key");
Process process = op.createProcess(project, new Properties());
process.performImmediate();
@ -71,7 +72,7 @@ public class FillDownTests extends RefineTest {
@Test
public void testFillDownRecords() throws Exception {
AbstractOperation op = new FillDownOperation(
new JSONObject("{\"mode\":\"record-based\",\"facets\":[]}"),
EngineConfig.reconstruct(new JSONObject("{\"mode\":\"record-based\",\"facets\":[]}")),
"second");
Process process = op.createProcess(project, new Properties());
process.performImmediate();
@ -87,7 +88,7 @@ public class FillDownTests extends RefineTest {
@Test
public void testFillDownRows() throws Exception {
AbstractOperation op = new FillDownOperation(
new JSONObject("{\"mode\":\"row-based\",\"facets\":[]}"),
EngineConfig.reconstruct(new JSONObject("{\"mode\":\"row-based\",\"facets\":[]}")),
"second");
Process process = op.createProcess(project, new Properties());
process.performImmediate();

View File

@ -46,6 +46,7 @@ import org.testng.annotations.BeforeMethod;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.expr.ExpressionUtils;
import com.google.refine.model.Cell;
import com.google.refine.model.ModelException;
@ -63,7 +64,7 @@ import com.google.refine.tests.util.TestUtils;
public class ColumnAdditionByFetchingURLsOperationTests extends RefineTest {
static final String ENGINE_JSON_URLS = "{\"mode\":\"row-based\"}}";
static final String ENGINE_JSON_URLS = "{\"mode\":\"row-based\"}";
@Override
@BeforeTest
@ -75,7 +76,7 @@ public class ColumnAdditionByFetchingURLsOperationTests extends RefineTest {
// dependencies
private Project project;
private Properties options;
private JSONObject engine_config;
private EngineConfig engine_config = EngineConfig.reconstruct(new JSONObject(ENGINE_JSON_URLS));
@BeforeMethod
public void SetUp() throws JSONException, IOException, ModelException {

View File

@ -50,6 +50,7 @@ import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import com.google.refine.browsing.Engine;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.model.Cell;
import com.google.refine.model.ModelException;
import com.google.refine.model.Project;
@ -81,7 +82,7 @@ public class ExtendDataOperationTests extends RefineTest {
// dependencies
Project project;
Properties options;
JSONObject engine_config;
EngineConfig engine_config;
Engine engine;
@BeforeMethod
@ -91,8 +92,8 @@ public class ExtendDataOperationTests extends RefineTest {
options = mock(Properties.class);
engine = new Engine(project);
engine_config = new JSONObject(ENGINE_JSON_URLS);
engine.initializeFromJSON(engine_config);
engine_config = EngineConfig.reconstruct(new JSONObject(ENGINE_JSON_URLS));
engine.initializeFromConfig(engine_config);
engine.setMode(Engine.Mode.RowBased);
Row row = new Row(2);

View File

@ -21,7 +21,7 @@ public class ReconCopyAcrossColumnsOperationTests extends RefineTest {
public void serializeReconCopyAcrossColumnsOperation() throws Exception {
String json = "{\"op\":\"core/recon-copy-across-columns\","
+ "\"description\":\"Copy recon judgments from column source column to firstsecond\","
+ "\"engineConfig\":{\"mode\":\"row-based\"},"
+ "\"engineConfig\":{\"mode\":\"row-based\",\"facets\":[]},"
+ "\"fromColumnName\":\"source column\","
+ "\"toColumnNames\":[\"first\",\"second\"],"
+ "\"judgments\":[\"matched\",\"new\"],"

View File

@ -11,6 +11,7 @@ import org.slf4j.LoggerFactory;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import com.google.refine.browsing.EngineConfig;
import com.google.refine.model.AbstractOperation;
import com.google.refine.model.Cell;
import com.google.refine.model.Column;
@ -26,7 +27,7 @@ import com.google.refine.tests.util.TestUtils;
public class ReconJudgeSimilarCellsTests extends RefineTest {
static final JSONObject ENGINE_CONFIG = new JSONObject("{\"mode\":\"row-based\"}}");
static final EngineConfig ENGINE_CONFIG = EngineConfig.reconstruct(new JSONObject("{\"mode\":\"row-based\"}}"));
@Override
@BeforeTest
@ -45,7 +46,7 @@ public class ReconJudgeSimilarCellsTests extends RefineTest {
null, true);
TestUtils.isSerializedTo(op, "{\"op\":\"core/recon-judge-similar-cells\","
+ "\"description\":\"Mark to create one single new item for all cells containing \\\"foo\\\" in column A\","
+ "\"engineConfig\":{\"mode\":\"row-based\"},"
+ "\"engineConfig\":{\"mode\":\"row-based\",\"facets\":[]},"
+ "\"columnName\":\"A\","
+ "\"similarValue\":\"foo\","
+ "\"judgment\":\"new\","

View File

@ -21,7 +21,7 @@ public class ReconMarkNewTopicsOperationTests extends RefineTest {
public void serializeReconMarkNewTopicsOperation() throws Exception {
String json = "{"
+ "\"op\":\"core/recon-mark-new-topics\","
+ "\"engineConfig\":{\"mode\":\"row-based\"},"
+ "\"engineConfig\":{\"mode\":\"row-based\",\"facets\":[]},"
+ "\"columnName\":\"my column\","
+ "\"shareNewTopics\":true,"
+ "\"description\":\"Mark to create new items for cells in column my column, one item for each group of similar cells\""