Refactor TextSearchFacet for JSON serialization

This commit is contained in:
Antonin Delpeuch 2018-09-05 10:51:31 +01:00
parent daeb7ab6df
commit 7a3d13ef47
2 changed files with 102 additions and 46 deletions

View File

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

View File

@ -43,12 +43,13 @@ import org.testng.annotations.BeforeMethod;
import org.testng.annotations.BeforeTest; import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test; 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.RowFilter;
import com.google.refine.browsing.facets.TextSearchFacet; 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.RefineTest;
import com.google.refine.tests.util.TestUtils;
public class TextSearchFacetTests extends RefineTest { public class TextSearchFacetTests extends RefineTest {
@ -57,6 +58,20 @@ public class TextSearchFacetTests extends RefineTest {
private TextSearchFacet textfilter; private TextSearchFacet textfilter;
private RowFilter rowfilter; private RowFilter rowfilter;
private JSONObject textsearchfacet; 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 @Override
@BeforeTest @BeforeTest
@ -172,22 +187,11 @@ public class TextSearchFacetTests extends RefineTest {
public void testCaseSensitiveFilter() throws Exception { public void testCaseSensitiveFilter() throws Exception {
//Apply case-sensitive filter "A" //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 //Add the facet to the project and create a row filter
textfilter = new TextSearchFacet(); textfilter = new TextSearchFacet();
textsearchfacet = new JSONObject(filter); textsearchfacet = new JSONObject(sensitiveConfigJson);
textfilter.initializeFromJSON(project,textsearchfacet); textfilter.initializeFromJSON(project,textsearchfacet);
rowfilter = textfilter.getRowFilter(project); rowfilter = textfilter.getRowFilter(project);
@ -198,5 +202,20 @@ public class TextSearchFacetTests extends RefineTest {
Assert.assertEquals(rowfilter.filterRow(project, 2, project.rows.get(2)),false); Assert.assertEquals(rowfilter.filterRow(project, 2, project.rows.get(2)),false);
Assert.assertEquals(rowfilter.filterRow(project, 3, project.rows.get(3)),true); 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);
}
} }