Server-side scaffolding for faceted browsing.

git-svn-id: http://google-refine.googlecode.com/svn/trunk@9 7d457c2a-affb-35e4-300a-418c747d4874
This commit is contained in:
David Huynh 2010-01-27 07:52:05 +00:00
parent 73ecc8f5d2
commit 6889d0e58a
14 changed files with 318 additions and 0 deletions

View File

@ -0,0 +1,33 @@
package com.metaweb.gridlock.browsing;
import java.util.LinkedList;
import java.util.List;
import com.metaweb.gridlock.browsing.filters.RowFilter;
import com.metaweb.gridlock.model.Project;
import com.metaweb.gridlock.model.Row;
public class ConjunctiveFilteredRows implements FilteredRows {
final protected List<RowFilter> _rowFilters = new LinkedList<RowFilter>();
public void add(RowFilter rowFilter) {
_rowFilters.add(rowFilter);
}
@Override
public void accept(Project project, RowVisitor visitor) {
for (Row row : project.rows) {
boolean ok = true;
for (RowFilter rowFilter : _rowFilters) {
if (!rowFilter.filterRow(row)) {
ok = false;
break;
}
}
if (ok) {
visitor.visit(row);
}
}
}
}

View File

@ -0,0 +1,71 @@
package com.metaweb.gridlock.browsing;
import java.util.ArrayList;
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 com.metaweb.gridlock.browsing.facets.Facet;
import com.metaweb.gridlock.browsing.facets.ListFacet;
public class Engine {
protected List<Facet> facets = new LinkedList<Facet>();
public FilteredRows getAllFilteredRows() {
return getFilteredRows(null);
}
public FilteredRows getFilteredRows(Facet except) {
ConjunctiveFilteredRows cfr = new ConjunctiveFilteredRows();
for (Facet facet : facets) {
if (facet != except) {
cfr.add(facet.getRowFilter());
}
}
return cfr;
}
public JSONObject getJSON(Properties options) throws JSONException {
JSONObject o = new JSONObject();
List<JSONObject> a = new ArrayList<JSONObject>(facets.size());
for (Facet facet : facets) {
a.add(facet.getJSON(options));
}
o.put("facets", a);
return o;
}
public void initializeFromJSON(JSONObject o) throws JSONException {
JSONArray a = o.getJSONArray("facets");
int length = a.length();
for (int i = 0; i < length; i++) {
JSONObject fo = a.getJSONObject(i);
String type = fo.getString("type");
Facet facet = null;
if ("list".equals(type)) {
facet = new ListFacet();
}
if (facet != null) {
facet.initializeFromJSON(fo);
facets.add(facet);
}
}
}
public void computeFacets() throws JSONException {
for (Facet facet : facets) {
FilteredRows filteredRows = getFilteredRows(facet);
facet.computeChoices(filteredRows);
}
}
}

View File

@ -0,0 +1,7 @@
package com.metaweb.gridlock.browsing;
import com.metaweb.gridlock.model.Project;
public interface FilteredRows {
public void accept(Project project, RowVisitor visitor);
}

View File

@ -0,0 +1,8 @@
package com.metaweb.gridlock.browsing;
import com.metaweb.gridlock.model.Row;
public interface RowVisitor {
public void visit(Row row);
}

View File

@ -0,0 +1,7 @@
package com.metaweb.gridlock.browsing.accessors;
import com.metaweb.gridlock.model.Cell;
public interface CellAccessor {
public Object[] get(Cell cell);
}

View File

@ -0,0 +1,19 @@
package com.metaweb.gridlock.browsing.accessors;
import com.metaweb.gridlock.model.Cell;
public class ReconFeatureCellAccessor implements CellAccessor {
final protected String _name;
public ReconFeatureCellAccessor(String name) {
_name = name;
}
@Override
public Object[] get(Cell cell) {
if (cell.recon != null) {
return new Object[] { cell.recon.features.get(_name) };
}
return null;
}
}

View File

@ -0,0 +1,15 @@
package com.metaweb.gridlock.browsing.accessors;
import com.metaweb.gridlock.model.Cell;
import com.metaweb.gridlock.model.ReconCandidate;
public class ReconTypeAccessor implements CellAccessor {
@Override
public Object[] get(Cell cell) {
if (cell.recon != null && cell.recon.candidates.size() > 0) {
ReconCandidate c = cell.recon.candidates.get(0);
return c.typeIDs;
}
return null;
}
}

View File

@ -0,0 +1,13 @@
package com.metaweb.gridlock.browsing.accessors;
import com.metaweb.gridlock.model.Cell;
public class ValueCellAccessor implements CellAccessor {
@Override
public Object[] get(Cell cell) {
if (cell.value != null) {
return new Object[] { cell.value };
}
return null;
}
}

View File

@ -0,0 +1,46 @@
package com.metaweb.gridlock.browsing.facets;
import java.util.HashMap;
import java.util.Map;
import com.metaweb.gridlock.browsing.RowVisitor;
import com.metaweb.gridlock.browsing.accessors.CellAccessor;
import com.metaweb.gridlock.model.Cell;
import com.metaweb.gridlock.model.Row;
public class CellAccessorNominalRowGrouper implements RowVisitor {
final protected CellAccessor _accessor;
final protected int _cellIndex;
final public Map<Object, NominalFacetChoice> groups = new HashMap<Object, NominalFacetChoice>();
public CellAccessorNominalRowGrouper(CellAccessor accessor, int cellIndex) {
_accessor = accessor;
_cellIndex = cellIndex;
}
@Override
public void visit(Row row) {
if (_cellIndex < row.cells.size()) {
Cell cell = row.cells.get(_cellIndex);
if (cell != null) {
Object[] values = _accessor.get(cell);
if (values != null && values.length > 0) {
for (Object v : values) {
if (v != null) {
if (groups.containsKey(v)) {
groups.get(v).count++;
} else {
NominalFacetChoice group = new NominalFacetChoice();
group.value = v;
group.count = 1;
groups.put(v, group);
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,19 @@
package com.metaweb.gridlock.browsing.facets;
import java.util.Properties;
import org.json.JSONException;
import org.json.JSONObject;
import com.metaweb.gridlock.browsing.FilteredRows;
import com.metaweb.gridlock.browsing.filters.RowFilter;
public interface Facet {
public RowFilter getRowFilter();
public void computeChoices(FilteredRows filteredRows);
public JSONObject getJSON(Properties options) throws JSONException;
public void initializeFromJSON(JSONObject o) throws JSONException;
}

View File

@ -0,0 +1,30 @@
package com.metaweb.gridlock.browsing.facets;
import java.util.Properties;
import org.json.JSONException;
import org.json.JSONObject;
import com.metaweb.gridlock.browsing.filters.RowFilter;
public class ListFacet implements Facet {
@Override
public JSONObject getJSON(Properties options) throws JSONException {
// TODO Auto-generated method stub
return null;
}
@Override
public RowFilter getRowFilter() {
// TODO Auto-generated method stub
return null;
}
@Override
public void initializeFromJSON(JSONObject o) throws JSONException {
// TODO Auto-generated method stub
}
}

View File

@ -0,0 +1,6 @@
package com.metaweb.gridlock.browsing.facets;
public class NominalFacetChoice {
public Object value;
public int count;
}

View File

@ -0,0 +1,37 @@
package com.metaweb.gridlock.browsing.filters;
import com.metaweb.gridlock.browsing.accessors.CellAccessor;
import com.metaweb.gridlock.model.Cell;
import com.metaweb.gridlock.model.Row;
public class CellAccessorEqualRowFilter implements RowFilter {
final protected CellAccessor _accessor;
final protected int _cellIndex;
final protected Object[] _matches;
public CellAccessorEqualRowFilter(CellAccessor accessor, int cellIndex, Object[] matches) {
_accessor = accessor;
_cellIndex = cellIndex;
_matches = matches;
}
@Override
public boolean filterRow(Row row) {
if (_cellIndex < row.cells.size()) {
Cell cell = row.cells.get(_cellIndex);
if (cell != null) {
Object[] values = _accessor.get(cell);
if (values != null && values.length > 0) {
for (Object v : values) {
for (Object match : _matches) {
if (match.equals(v)) {
return true;
}
}
}
}
}
}
return false;
}
}

View File

@ -0,0 +1,7 @@
package com.metaweb.gridlock.browsing.filters;
import com.metaweb.gridlock.model.Row;
public interface RowFilter {
public boolean filterRow(Row row);
}