Introduce FacetConfig interface and refactor ListFacet accordingly

This commit is contained in:
Antonin Delpeuch 2018-09-04 09:33:30 +01:00
parent f6bbb64c98
commit bc81beb933
2 changed files with 118 additions and 62 deletions

View File

@ -0,0 +1,24 @@
package com.google.refine.browsing.facets;
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 {
/**
* 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,73 @@ 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
protected boolean _omitBlank;
protected boolean _omitError;
public boolean omitBlank;
public boolean omitError;
protected List<NominalFacetChoice> _selection = new LinkedList<NominalFacetChoice>();
protected boolean _selectBlank;
protected boolean _selectError;
public List<NominalFacetChoice> selection = new LinkedList<NominalFacetChoice>();
public boolean selectBlank;
public boolean selectError;
@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("invert"); writer.value(invert);
writer.key("selection"); writer.array();
for (NominalFacetChoice choice : selection) {
choice.write(writer, options);
}
writer.endArray();
}
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"));
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
public Facet apply(Project project) {
ListFacet facet = new ListFacet();
facet.initializeFromConfig(this, project);
return facet;
}
}
ListFacetConfig _config = new ListFacetConfig();
/*
* Derived configuration
@ -98,10 +153,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 +170,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();
}
@ -153,51 +208,28 @@ public class ListFacet implements Facet {
@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");
ListFacetConfig config = new ListFacetConfig();
config.initializeFromJSON(o);
initializeFromConfig(config, project);
}
if (_columnName.length() > 0) {
Column column = project.columnModel.getColumnByName(_columnName);
public void initializeFromConfig(ListFacetConfig config, Project project) {
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 +237,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 +262,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 +274,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,7 +286,7 @@ public class ListFacet implements Facet {
_choices.clear();
_choices.addAll(grouper.choices.values());
for (NominalFacetChoice choice : _selection) {
for (NominalFacetChoice choice : _config.selection) {
String valueString = choice.decoratedValue.value.toString();
if (grouper.choices.containsKey(valueString)) {
@ -280,9 +312,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).decoratedValue.value;
}
return a;
}