Package edu.mit.simile.backstage.model.ui.facets

Source Code of edu.mit.simile.backstage.model.ui.facets.ListFacet$FacetChoice

package edu.mit.simile.backstage.model.ui.facets;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.mozilla.javascript.Scriptable;
import org.openrdf.model.Literal;
import org.openrdf.model.URI;
import org.openrdf.model.Value;
import org.openrdf.model.impl.LiteralImpl;
import org.openrdf.model.impl.URIImpl;
import org.openrdf.query.BindingSet;
import org.openrdf.query.QueryEvaluationException;
import org.openrdf.query.TupleQuery;
import org.openrdf.query.TupleQueryResult;
import org.openrdf.query.algebra.Compare;
import org.openrdf.query.algebra.Count;
import org.openrdf.query.algebra.GroupElem;
import org.openrdf.query.algebra.Or;
import org.openrdf.query.algebra.Order;
import org.openrdf.query.algebra.OrderElem;
import org.openrdf.query.algebra.Projection;
import org.openrdf.query.algebra.ProjectionElem;
import org.openrdf.query.algebra.ProjectionElemList;
import org.openrdf.query.algebra.ValueExpr;
import org.openrdf.query.algebra.Var;
import org.openrdf.query.algebra.Compare.CompareOp;
import org.openrdf.query.parser.ParsedTupleQuery;
import org.openrdf.repository.sail.SailRepositoryConnection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import edu.mit.simile.backstage.model.BackChannel;
import edu.mit.simile.backstage.model.Context;
import edu.mit.simile.backstage.model.TupleQueryBuilder;
import edu.mit.simile.backstage.model.data.CacheableQuery;
import edu.mit.simile.backstage.model.data.Database;
import edu.mit.simile.backstage.model.data.Expression;
import edu.mit.simile.backstage.model.data.ExpressionException;
import edu.mit.simile.backstage.model.data.ExpressionResult;
import edu.mit.simile.backstage.util.DefaultScriptableObject;
import edu.mit.simile.backstage.util.Group2;
import edu.mit.simile.backstage.util.MyTupleQuery;
import edu.mit.simile.backstage.util.ScriptableArrayBuilder;
import edu.mit.simile.backstage.util.Utilities;

public class ListFacet extends Facet {
    protected static Logger _logger = LoggerFactory.getLogger("backstage.facets.list-facet");
   
    protected Expression    _expression;
    protected String        _sortMode = "value";
    protected String        _sortDirection = "forward";
   
    protected Set<String>   _selection = new HashSet<String>();
    protected boolean       _selectMissing;
   
    protected TupleQueryBuilder _builder;
    protected Var               _itemVar;
    protected Var               _valueVar;
    protected Var               _countVar;
    protected String            _valueType;
   
    public ListFacet(Context context, String id) {
        super(context, id);
    }

    @Override
    public void configure(Scriptable config, BackChannel backChannel) {
        super.configure(config, backChannel);
        _expression = Expression.construct((Scriptable) config.get("expression", config));
       
        Utilities.getScriptableArrayElements(
            (Scriptable) config.get("selection", config), _selection);
       
        _sortMode = (String) config.get("sortMode", config);
        _sortDirection = (String) config.get("sortDirection", config);
       
        _collection.addFacet(this, backChannel);
    }

    @Override
    public boolean hasRestrictions() {
        return _selection.size() > 0 || _selectMissing;
    }

    @Override
    public void restrict(TupleQueryBuilder builder, Var itemVar) throws ExpressionException {
        if (!hasRestrictions()) {
            return;
        }
       
        ExpressionResult result = _expression.computeOutputOnItem(
            _context.getDatabase(),
            builder,
            itemVar
        );
       
        if (!(result.valueExpr instanceof Var)) {
            throw new ExpressionException("Facet expression does not evaluate to a Var");
        }
       
        ValueExpr input = result.valueExpr;
        ValueExpr condition = null;
       
        if (_selectMissing) {
            // what do we do???
        }
        for (String v : _selection) {
            condition = createRestrictionClause(builder, v, result.valueType, input, condition);
        }
        builder.addCondition(condition);
    }

    @Override
    public void update(TupleQueryBuilder queryBuilder, Var itemVar, BackChannel backChannel) throws ExpressionException {
        _builder = queryBuilder;
        _itemVar = itemVar;
       
        ExpressionResult result = _expression.computeOutputOnItem(
            _context.getDatabase(),
            _builder,
            _itemVar
        );
       
        if (!(result.valueExpr instanceof Var)) {
            throw new ExpressionException("Facet expression does not evaluate to a Var");
        }
       
        _valueVar = (Var) result.valueExpr;
        _valueType = result.valueType;
        _countVar = _builder.makeVar("count");
       
        backChannel.addComponentChangingState(this);
    }
   
    @Override
    public void applyRestrictions(Scriptable restrictions, BackChannel backChannel) throws ExpressionException {
        _selection.clear();
        Utilities.getScriptableArrayElements(
            (Scriptable) restrictions.get("selection", restrictions),
            _selection
        );
       
        _selectMissing = ((Boolean) restrictions.get("selectMissing", restrictions)).booleanValue();
       
        _collection.onFacetUpdated(this, backChannel);
    }
   
    @Override
    public void clearRestrictions(BackChannel backChannel) throws ExpressionException {
        _selection.clear();
        _selectMissing = false;
       
        _collection.onFacetUpdated(this, backChannel);
    }
   
    @SuppressWarnings("unchecked")
  @Override
    public Scriptable getComponentState() {
        DefaultScriptableObject result = new DefaultScriptableObject();
       
        ScriptableArrayBuilder facetChoicesWithSelection = new ScriptableArrayBuilder();
        int selectionCount = 0;
       
      List<FacetChoice> facetChoices = (List<FacetChoice>)
        _context.getDatabase().cacheAndRun(getCacheableQueryKey(), new ListFacetCacheableQuery());
      if (facetChoices != null) {
          for (FacetChoice fc : facetChoices) {
              DefaultScriptableObject valueO = new DefaultScriptableObject();
              boolean selected = _selection.contains(fc._valueString);
             
              valueO.put("value", valueO, fc._valueString);
              valueO.put("count", valueO, fc._count);
              valueO.put("label", valueO, fc._label);
              valueO.put("selected", valueO, selected);
             
              facetChoicesWithSelection.add(valueO);
             
              if (selected) {
                selectionCount++;
              }
          }
      }
     
        result.put("values", result, facetChoicesWithSelection.toArray());
        result.put("selectionCount", result, selectionCount);
       
        return result;
    }
   
    protected ValueExpr createRestrictionClause(
        TupleQueryBuilder builder,
        String valueAsString,
        String valueType,
        ValueExpr input,
        ValueExpr previousClauses
    ) {
        Value value = stringToValue(valueAsString);
        Compare compare = new Compare(input, builder.makeVar("v", value), CompareOp.EQ);
       
        return previousClauses == null ? compare : new Or(previousClauses, compare);
    }
   
    protected String valueToString(Value value) {
      if (value instanceof Literal) {
        return "l" + ((Literal) value).getLabel();
      }
     
      return "r" + ((URI) value).stringValue();
    }
   
    protected Value stringToValue(String s) {
      if (s.length() == 0) {
        return null;
      } else if (s.charAt(0) == 'r') {
        return new URIImpl(s.substring(1));
      } else {
        return new LiteralImpl(s.substring(1));
      }
    }
   
    protected String getCacheableQueryKey() {
      return "ListFacet-expression:" + _expression.toString() + ":" + _builder.getStringSerialization();
    }
   
    protected class ListFacetCacheableQuery extends CacheableQuery {

    @Override
    protected Object internalRun() {
          Database database = _context.getDatabase();
          try {
              SailRepositoryConnection connection = (SailRepositoryConnection)
                  database.getRepository().getConnection();
             
              try {
                  Group2 group = new Group2(_builder.makeFilterTupleExpr());
                  group.addGroupElement(new GroupElem(_countVar.getName(), new Count(_itemVar)));
                  group.addGroupBindingName(_valueVar.getName());
                 
                  ProjectionElemList projectionElements = new ProjectionElemList();
                  projectionElements.addElement(new ProjectionElem(_valueVar.getName()));
                  projectionElements.addElement(new ProjectionElem(_countVar.getName()));
                 
                  Projection projection = new Projection(group, projectionElements);
                  Order order = "value".equals(_sortMode) ?
                      new Order(projection, new OrderElem(_valueVar, "forward".equals(_sortDirection))) :
                      new Order(projection, new OrderElem(_countVar, !"forward".equals(_sortDirection)));
                 
                  TupleQuery query = new MyTupleQuery(new ParsedTupleQuery(order), connection);
                  TupleQueryResult queryResult = query.evaluate();
                  try {
                    return createComponentState(queryResult);
                  } finally {
                      queryResult.close();
                  }
              } finally {
                  connection.close();
              }
          } catch (Exception e) {
              _logger.error("Error querying to compute list facet", e);
          }
          return null;
    }
    }
   
    protected List<FacetChoice> createComponentState(TupleQueryResult queryResult) throws QueryEvaluationException {
        List<FacetChoice> facetChoices = new ArrayList<FacetChoice>();
        Database database = _context.getDatabase();
       
        while (queryResult.hasNext()) {
            BindingSet bindingSet = queryResult.next();
           
            Value value = bindingSet.getValue(_valueVar.getName());
            Value count = bindingSet.getValue(_countVar.getName());
           
            String s = valueToString(value);
            int c = Integer.parseInt(count.stringValue());
           
            FacetChoice fc = new FacetChoice();
            fc._value = value;
            fc._valueString = s;
            fc._count = c;
            fc._label = database.valueToLabel(value);
            facetChoices.add(fc);
        }
      return facetChoices;
    }
   
    static protected class FacetChoice {
      public Value  _value;
      public String  _valueString;
      public String  _label;
      public int    _count;
    }
}
TOP

Related Classes of edu.mit.simile.backstage.model.ui.facets.ListFacet$FacetChoice

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.