diff --git a/main/src/com/google/refine/browsing/facets/TextSearchFacet.java b/main/src/com/google/refine/browsing/facets/TextSearchFacet.java index e8270d4fc..48fb1f242 100644 --- a/main/src/com/google/refine/browsing/facets/TextSearchFacet.java +++ b/main/src/com/google/refine/browsing/facets/TextSearchFacet.java @@ -53,21 +53,58 @@ 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; + } + + 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 +114,68 @@ 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"); + TextSearchFacetConfig config = new TextSearchFacetConfig(); + 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; - 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); }; }; } diff --git a/main/tests/server/src/com/google/refine/tests/browsing/facets/TextSearchFacetTests.java b/main/tests/server/src/com/google/refine/tests/browsing/facets/TextSearchFacetTests.java index 09c9ea754..24e74104f 100644 --- a/main/tests/server/src/com/google/refine/tests/browsing/facets/TextSearchFacetTests.java +++ b/main/tests/server/src/com/google/refine/tests/browsing/facets/TextSearchFacetTests.java @@ -43,12 +43,13 @@ 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 { @@ -57,6 +58,20 @@ public class TextSearchFacetTests extends RefineTest { 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 @@ -172,22 +187,11 @@ public class TextSearchFacetTests extends RefineTest { 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); + textsearchfacet = new JSONObject(sensitiveConfigJson); textfilter.initializeFromJSON(project,textsearchfacet); 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, 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); + } }