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 * Configuration
*/ */
protected String _name; public static class ListFacetConfig implements FacetConfig {
protected String _expression; public String name;
protected String _columnName; public String expression;
protected boolean _invert; 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<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;
}
}
// If true, then facet won't show the blank and error choices ListFacetConfig _config = new ListFacetConfig();
protected boolean _omitBlank;
protected boolean _omitError;
protected List<NominalFacetChoice> _selection = new LinkedList<NominalFacetChoice>();
protected boolean _selectBlank;
protected boolean _selectError;
/* /*
* Derived configuration * Derived configuration
@ -98,10 +153,10 @@ public class ListFacet implements Facet {
throws JSONException { throws JSONException {
writer.object(); writer.object();
writer.key("name"); writer.value(_name); writer.key("name"); writer.value(_config.name);
writer.key("expression"); writer.value(_expression); writer.key("expression"); writer.value(_config.expression);
writer.key("columnName"); writer.value(_columnName); writer.key("columnName"); writer.value(_config.columnName);
writer.key("invert"); writer.value(_invert); writer.key("invert"); writer.value(_config.invert);
if (_errorMessage != null) { if (_errorMessage != null) {
writer.key("error"); writer.value(_errorMessage); writer.key("error"); writer.value(_errorMessage);
@ -115,17 +170,17 @@ public class ListFacet implements Facet {
} }
writer.endArray(); writer.endArray();
if (!_omitBlank && (_selectBlank || _blankCount > 0)) { if (!_config.omitBlank && (_config.selectBlank || _blankCount > 0)) {
writer.key("blankChoice"); writer.key("blankChoice");
writer.object(); writer.object();
writer.key("s"); writer.value(_selectBlank); writer.key("s"); writer.value(_config.selectBlank);
writer.key("c"); writer.value(_blankCount); writer.key("c"); writer.value(_blankCount);
writer.endObject(); writer.endObject();
} }
if (!_omitError && (_selectError || _errorCount > 0)) { if (!_config.omitError && (_config.selectError || _errorCount > 0)) {
writer.key("errorChoice"); writer.key("errorChoice");
writer.object(); writer.object();
writer.key("s"); writer.value(_selectError); writer.key("s"); writer.value(_config.selectError);
writer.key("c"); writer.value(_errorCount); writer.key("c"); writer.value(_errorCount);
writer.endObject(); writer.endObject();
} }
@ -153,51 +208,28 @@ public class ListFacet implements Facet {
@Override @Override
public void initializeFromJSON(Project project, JSONObject o) throws JSONException { public void initializeFromJSON(Project project, JSONObject o) throws JSONException {
_name = o.getString("name"); ListFacetConfig config = new ListFacetConfig();
_expression = o.getString("expression"); config.initializeFromJSON(o);
_columnName = o.getString("columnName"); initializeFromConfig(config, project);
_invert = o.has("invert") && o.getBoolean("invert"); }
if (_columnName.length() > 0) { public void initializeFromConfig(ListFacetConfig config, Project project) {
Column column = project.columnModel.getColumnByName(_columnName); if (_config.columnName.length() > 0) {
Column column = project.columnModel.getColumnByName(_config.columnName);
if (column != null) { if (column != null) {
_cellIndex = column.getCellIndex(); _cellIndex = column.getCellIndex();
} else { } else {
_errorMessage = "No column named " + _columnName; _errorMessage = "No column named " + _config.columnName;
} }
} else { } else {
_cellIndex = -1; _cellIndex = -1;
} }
try { try {
_eval = MetaParser.parse(_expression); _eval = MetaParser.parse(_config.expression);
} catch (ParsingException e) { } catch (ParsingException e) {
_errorMessage = e.getMessage(); _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 @Override
@ -205,23 +237,23 @@ public class ListFacet implements Facet {
return return
_eval == null || _eval == null ||
_errorMessage != null || _errorMessage != null ||
(_selection.size() == 0 && !_selectBlank && !_selectError) ? (_config.selection.size() == 0 && !_config.selectBlank && !_config.selectError) ?
null : null :
new ExpressionEqualRowFilter( new ExpressionEqualRowFilter(
_eval, _eval,
_columnName, _config.columnName,
_cellIndex, _cellIndex,
createMatches(), createMatches(),
_selectBlank, _config.selectBlank,
_selectError, _config.selectError,
_invert); _config.invert);
} }
@Override @Override
public RecordFilter getRecordFilter(Project project) { public RecordFilter getRecordFilter(Project project) {
RowFilter rowFilter = getRowFilter(project); RowFilter rowFilter = getRowFilter(project);
return rowFilter == null ? null : return rowFilter == null ? null :
(_invert ? (_config.invert ?
new AllRowsRecordFilter(rowFilter) : new AllRowsRecordFilter(rowFilter) :
new AnyRowRecordFilter(rowFilter)); new AnyRowRecordFilter(rowFilter));
} }
@ -230,7 +262,7 @@ public class ListFacet implements Facet {
public void computeChoices(Project project, FilteredRows filteredRows) { public void computeChoices(Project project, FilteredRows filteredRows) {
if (_eval != null && _errorMessage == null) { if (_eval != null && _errorMessage == null) {
ExpressionNominalValueGrouper grouper = ExpressionNominalValueGrouper grouper =
new ExpressionNominalValueGrouper(_eval, _columnName, _cellIndex); new ExpressionNominalValueGrouper(_eval, _config.columnName, _cellIndex);
filteredRows.accept(project, grouper); filteredRows.accept(project, grouper);
@ -242,7 +274,7 @@ public class ListFacet implements Facet {
public void computeChoices(Project project, FilteredRecords filteredRecords) { public void computeChoices(Project project, FilteredRecords filteredRecords) {
if (_eval != null && _errorMessage == null) { if (_eval != null && _errorMessage == null) {
ExpressionNominalValueGrouper grouper = ExpressionNominalValueGrouper grouper =
new ExpressionNominalValueGrouper(_eval, _columnName, _cellIndex); new ExpressionNominalValueGrouper(_eval, _config.columnName, _cellIndex);
filteredRecords.accept(project, grouper); filteredRecords.accept(project, grouper);
@ -254,7 +286,7 @@ public class ListFacet implements Facet {
_choices.clear(); _choices.clear();
_choices.addAll(grouper.choices.values()); _choices.addAll(grouper.choices.values());
for (NominalFacetChoice choice : _selection) { for (NominalFacetChoice choice : _config.selection) {
String valueString = choice.decoratedValue.value.toString(); String valueString = choice.decoratedValue.value.toString();
if (grouper.choices.containsKey(valueString)) { if (grouper.choices.containsKey(valueString)) {
@ -280,9 +312,9 @@ public class ListFacet implements Facet {
} }
protected Object[] createMatches() { protected Object[] createMatches() {
Object[] a = new Object[_selection.size()]; Object[] a = new Object[_config.selection.size()];
for (int i = 0; i < a.length; i++) { 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; return a;
} }