Package com.browseengine.bobo.api

Source Code of com.browseengine.bobo.api.BoboSubBrowser

package com.browseengine.bobo.api;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.log4j.Logger;
import org.apache.lucene.index.AtomicReaderContext;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.Collector;
import org.apache.lucene.search.Filter;
import org.apache.lucene.search.MatchAllDocsQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.Weight;

import com.browseengine.bobo.facets.CombinedFacetAccessible;
import com.browseengine.bobo.facets.FacetCountCollector;
import com.browseengine.bobo.facets.FacetHandler;
import com.browseengine.bobo.facets.FacetHandlerInitializerParam;
import com.browseengine.bobo.facets.RuntimeFacetHandler;
import com.browseengine.bobo.facets.RuntimeFacetHandlerFactory;
import com.browseengine.bobo.facets.filter.AndFilter;
import com.browseengine.bobo.facets.filter.RandomAccessFilter;
import com.browseengine.bobo.search.BoboSearcher;
import com.browseengine.bobo.search.FacetHitCollector;
import com.browseengine.bobo.sort.SortCollector;

/**
* This class implements the browsing functionality.
*/
public class BoboSubBrowser extends BoboSearcher implements Browsable {
  private static Logger logger = Logger.getLogger(BoboSubBrowser.class);

  private final BoboSegmentReader _reader;
  private final Map<String, RuntimeFacetHandlerFactory<?, ?>> _runtimeFacetHandlerFactoryMap;
  private final HashMap<String, FacetHandler<?>> _runtimeFacetHandlerMap;
  private HashMap<String, FacetHandler<?>> _allFacetHandlerMap;
  private ArrayList<RuntimeFacetHandler<?>> _runtimeFacetHandlers = null;

  @Override
  public IndexReader getIndexReader() {
    return _reader;
  }

  public BoboSubBrowser(AtomicReaderContext ctx) {
    super(ctx);
    _reader = (BoboSegmentReader) ctx.reader();
    _runtimeFacetHandlerMap = new HashMap<String, FacetHandler<?>>();
    _runtimeFacetHandlerFactoryMap = _reader.getRuntimeFacetHandlerFactoryMap();
    _allFacetHandlerMap = null;
  }

  private boolean isNoQueryNoFilter(BrowseRequest req) {
    Query q = req.getQuery();
    Filter filter = req.getFilter();
    return ((q == null || q instanceof MatchAllDocsQuery) && filter == null && !_reader
        .hasDeletions());
  }

  @Override
  public Object[] getRawFieldVal(int docid, String fieldname) throws IOException {
    FacetHandler<?> facetHandler = getFacetHandler(fieldname);
    if (facetHandler == null) {
      return getFieldVal(docid, fieldname);
    } else {
      return facetHandler.getRawFieldValues(_reader, docid);
    }
  }

  /**
   * Sets runtime facet handler. If has the same name as a preload handler, for the
   * duration of this browser, this one will be used.
   *
   * @param facetHandler
   *          Runtime facet handler
   */
  @Override
  public void setFacetHandler(FacetHandler<?> facetHandler) throws IOException {
    Set<String> dependsOn = facetHandler.getDependsOn();
    if (dependsOn.size() > 0) {
      Iterator<String> iter = dependsOn.iterator();
      while (iter.hasNext()) {
        String fn = iter.next();
        FacetHandler<?> f = _runtimeFacetHandlerMap.get(fn);
        if (f == null) {
          f = _reader.getFacetHandler(fn);
        }
        if (f == null) {
          throw new IOException("depended on facet handler: " + fn + ", but is not found");
        }
        facetHandler.putDependedFacetHandler(f);
      }
    }
    facetHandler.loadFacetData(_reader);
    _runtimeFacetHandlerMap.put(facetHandler.getName(), facetHandler);
  }

  /**
   * Gets a defined facet handler
   *
   * @param name
   *          facet name
   * @return a facet handler
   */
  @Override
  public FacetHandler<?> getFacetHandler(String name) {
    return getFacetHandlerMap().get(name);
  }

  @Override
  public Map<String, FacetHandler<?>> getFacetHandlerMap() {
    if (_allFacetHandlerMap == null) {
      _allFacetHandlerMap = new HashMap<String, FacetHandler<?>>(_reader.getFacetHandlerMap());
    }
    _allFacetHandlerMap.putAll(_runtimeFacetHandlerMap);
    return _allFacetHandlerMap;
  }

  /**
   * Gets a set of facet names
   *
   * @return set of facet names
   */
  @Override
  public Set<String> getFacetNames() {
    Map<String, FacetHandler<?>> map = getFacetHandlerMap();
    return map.keySet();
  }

  @SuppressWarnings("unchecked")
  @Override
  public void browse(BrowseRequest req, Weight w, Collector collector,
      Map<String, FacetAccessible> facetMap, int start) throws BrowseException {

    if (_reader == null) {
      return;
    }
    // initialize all RuntimeFacetHandlers with data supplied by user at run-time.
    _runtimeFacetHandlers = new ArrayList<RuntimeFacetHandler<?>>(
        _runtimeFacetHandlerFactoryMap.size());

    Set<String> runtimeFacetNames = _runtimeFacetHandlerFactoryMap.keySet();
    for (String facetName : runtimeFacetNames) {
      FacetHandler<?> sfacetHandler = this.getFacetHandler(facetName);
      if (sfacetHandler != null) {
        logger.warn("attempting to reset facetHandler: " + sfacetHandler);
        continue;
      }
      RuntimeFacetHandlerFactory<FacetHandlerInitializerParam, ?> factory = (RuntimeFacetHandlerFactory<FacetHandlerInitializerParam, ?>) _runtimeFacetHandlerFactoryMap
          .get(facetName);

      try {

        FacetHandlerInitializerParam data = req.getFacethandlerData(facetName);
        if (data == null) data = FacetHandlerInitializerParam.EMPTY_PARAM;
        if (data != FacetHandlerInitializerParam.EMPTY_PARAM || !factory.isLoadLazily()) {
          RuntimeFacetHandler<?> facetHandler = factory.get(data);
          if (facetHandler != null) {
            _runtimeFacetHandlers.add(facetHandler); // add to a list so we close them after search
            this.setFacetHandler(facetHandler);
          }
        }
      } catch (IOException e) {
        throw new BrowseException("error trying to set FacetHandler : " + facetName + ":"
            + e.getMessage(), e);
      }
    }
    // done initialize all RuntimeFacetHandlers with data supplied by user at run-time.

    Set<String> fields = getFacetNames();

    LinkedList<Filter> preFilterList = new LinkedList<Filter>();
    List<FacetHitCollector> facetHitCollectorList = new LinkedList<FacetHitCollector>();

    Filter baseFilter = req.getFilter();
    if (baseFilter != null) {
      preFilterList.add(baseFilter);
    }

    int selCount = req.getSelectionCount();
    boolean isNoQueryNoFilter = isNoQueryNoFilter(req);

    boolean isDefaultSearch = isNoQueryNoFilter && selCount == 0;
    try {

      for (String name : fields) {
        BrowseSelection sel = req.getSelection(name);
        FacetSpec ospec = req.getFacetSpec(name);

        FacetHandler<?> handler = getFacetHandler(name);

        if (handler == null) {
          logger.error("facet handler: " + name + " is not defined, ignored.");
          continue;
        }

        FacetHitCollector facetHitCollector = null;

        RandomAccessFilter filter = null;
        if (sel != null) {
          filter = handler.buildFilter(sel);
        }

        if (ospec == null) {
          if (filter != null) {
            preFilterList.add(filter);
          }
        } else {
          FacetSpec fspec = ospec;

          facetHitCollector = new FacetHitCollector();
          facetHitCollector.facetHandler = handler;

          if (isDefaultSearch) {
            facetHitCollector._collectAllSource = handler.getFacetCountCollectorSource(sel, fspec);
          } else {
            facetHitCollector._facetCountCollectorSource = handler.getFacetCountCollectorSource(
              sel, fspec);
            if (ospec.isExpandSelection()) {
              if (isNoQueryNoFilter && sel != null && selCount == 1) {
                facetHitCollector._collectAllSource = handler.getFacetCountCollectorSource(sel,
                  fspec);
                if (filter != null) {
                  preFilterList.add(filter);
                }
              } else {
                if (filter != null) {
                  facetHitCollector._filter = filter;
                }
              }
            } else {
              if (filter != null) {
                preFilterList.add(filter);
              }
            }
          }
        }
        if (facetHitCollector != null) {
          facetHitCollectorList.add(facetHitCollector);
        }
      }

      Filter finalFilter = null;
      if (preFilterList.size() > 0) {
        if (preFilterList.size() == 1) {
          finalFilter = preFilterList.getFirst();
        } else {
          finalFilter = new AndFilter(preFilterList);
        }
      }

      setFacetHitCollectorList(facetHitCollectorList);

      try {
        search(w, finalFilter, collector, start, req.getMapReduceWrapper());
      } finally {
        for (FacetHitCollector facetCollector : facetHitCollectorList) {
          String name = facetCollector.facetHandler.getName();
          LinkedList<FacetCountCollector> resultcollector = null;
          resultcollector = facetCollector._countCollectorList;
          if (resultcollector == null || resultcollector.size() == 0) {
            resultcollector = facetCollector._collectAllCollectorList;
          }
          if (resultcollector != null) {
            FacetSpec fspec = req.getFacetSpec(name);
            assert fspec != null;
            if (resultcollector.size() == 1) {
              facetMap.put(name, resultcollector.get(0));
            } else {
              ArrayList<FacetAccessible> finalList = new ArrayList<FacetAccessible>(
                  resultcollector.size());
              for (FacetCountCollector fc : resultcollector) {
                finalList.add(fc);
              }
              CombinedFacetAccessible combinedCollector = new CombinedFacetAccessible(fspec,
                  finalList);
              facetMap.put(name, combinedCollector);
            }
          }
        }
      }
    } catch (IOException ioe) {
      throw new BrowseException(ioe.getMessage(), ioe);
    }
  }

  @Override
  public SortCollector getSortCollector(SortField[] sort, Query q, int offset, int count,
      boolean fetchStoredFields, Set<String> termVectorsToFetch, String[] groupBy, int maxPerGroup,
      boolean collectDocIdCache) {
    return SortCollector.buildSortCollector(this, q, sort, offset, count, fetchStoredFields,
      termVectorsToFetch, groupBy, maxPerGroup, collectDocIdCache);
  }

  /**
   * browses the index.
   *
   * @param req
   *          browse request
   * @return browse result
   */
  @Override
  public BrowseResult browse(BrowseRequest req) {
    throw new UnsupportedOperationException();
  }

  public Map<String, FacetHandler<?>> getRuntimeFacetHandlerMap() {
    return _runtimeFacetHandlerMap;
  }

  @Override
  public int numDocs() {
    return _reader.numDocs();
  }

  /**
   * Returns the field data for a given doc.
   *
   * @param docid
   *          doc
   * @param fieldname
   *          name of the field
   * @return field data
   */
  @Override
  public String[] getFieldVal(int docid, final String fieldname) throws IOException {
    FacetHandler<?> facetHandler = getFacetHandler(fieldname);
    if (facetHandler != null) {
      return facetHandler.getFieldValues(_reader, docid);
    } else {
      logger.warn("facet handler: " + fieldname + " not defined, looking at stored field.");
      return _reader.getStoredFieldValue(docid, fieldname);
    }
  }

  @Override
  public void doClose() throws IOException {
    if (_runtimeFacetHandlers != null) {
      for (RuntimeFacetHandler<?> handler : _runtimeFacetHandlers) {
        handler.close();
      }
    }
    if (_reader != null) {
      _reader.clearRuntimeFacetData();
      _reader.clearRuntimeFacetHandler();
    }
  }
}
TOP

Related Classes of com.browseengine.bobo.api.BoboSubBrowser

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.