All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.browseengine.bobo.facets.FacetHandler Maven / Gradle / Ivy

There is a newer version: 3.1.2
Show newest version
/**
 * This software is licensed to you under the Apache License, Version 2.0 (the
 * "Apache License").
 *
 * LinkedIn's contributions are made under the Apache License. If you contribute
 * to the Software, the contributions will be deemed to have been made under the
 * Apache License, unless you expressly indicate otherwise. Please do not make any
 * contributions that would be inconsistent with the Apache License.
 *
 * You may obtain a copy of the Apache License at http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, this software
 * distributed under the Apache License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the Apache
 * License for the specific language governing permissions and limitations for the
 * software governed under the Apache License.
 *
 * © 2012 LinkedIn Corp. All Rights Reserved.  
 */

package com.browseengine.bobo.facets;

import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import com.browseengine.bobo.api.BoboIndexReader;
import com.browseengine.bobo.api.BrowseSelection;
import com.browseengine.bobo.api.BrowseSelection.ValueOperation;
import com.browseengine.bobo.api.FacetAccessible;
import com.browseengine.bobo.api.FacetSpec;
import com.browseengine.bobo.facets.filter.EmptyFilter;
import com.browseengine.bobo.facets.filter.RandomAccessAndFilter;
import com.browseengine.bobo.facets.filter.RandomAccessFilter;
import com.browseengine.bobo.facets.filter.RandomAccessNotFilter;
import com.browseengine.bobo.facets.filter.RandomAccessOrFilter;
import com.browseengine.bobo.sort.DocComparatorSource;

/**
 * FacetHandler definition
 *
 */
public abstract class FacetHandler
{
	public static class FacetDataNone implements Serializable{
		private static final long serialVersionUID = 1L;
		public static FacetDataNone instance = new FacetDataNone();
		private FacetDataNone(){}
	}
	
	protected final String _name;
	private final Set _dependsOn;
	private final Map> _dependedFacetHandlers;
	private TermCountSize _termCountSize;
	
	public static enum TermCountSize{
		small,
		medium,
		large
	}
	
	/**
	 * Constructor
	 * @param name name
	 * @param dependsOn Set of names of facet handlers this facet handler depend on for loading
	 */
	public FacetHandler(String name,Set dependsOn)
	{
		_name=name;
		_dependsOn = new HashSet();
		if (dependsOn != null)
		{
			_dependsOn.addAll(dependsOn);
		}
		_dependedFacetHandlers = new HashMap>();
		_termCountSize = TermCountSize.large;
	}
	
	public FacetHandler setTermCountSize(String termCountSize){
		setTermCountSize(TermCountSize.valueOf(termCountSize.toLowerCase()));
    return this;
	}
	
	public FacetHandler setTermCountSize(TermCountSize termCountSize){
		_termCountSize = termCountSize;
    return this;
	}
	
	public TermCountSize getTermCountSize(){
		return _termCountSize;
	}
	
	/**
	 * Constructor
	 * @param name name
	 */
	public FacetHandler(String name)
	{
		this(name,null);
	}
	
	/**
	 * Gets the name
	 * @return name
	 */
	public final String getName()
	{
		return _name;
	}
	
	/**
	 * Gets names of the facet handler this depends on
	 * @return set of facet handler names
	 */
	public final Set getDependsOn()
	{
		return _dependsOn;
	}
	
	/**
	 * Adds a list of depended facet handlers
	 * @param facetHandler depended facet handler
	 */
	public final void putDependedFacetHandler(FacetHandler facetHandler)
	{
		_dependedFacetHandlers.put(facetHandler._name, facetHandler);
	}
	
	/**
	 * Gets a depended facet handler
	 * @param name facet handler name
	 * @return facet handler instance 
	 */
	public final FacetHandler getDependedFacetHandler(String name)
	{
		return _dependedFacetHandlers.get(name);
	}
	
	/**
	 * Load information from an index reader, initialized by {@link BoboIndexReader}
	 * @param reader reader
	 * @throws IOException
	 */
	abstract public D load(BoboIndexReader reader) throws IOException;

	public FacetAccessible merge(FacetSpec fspec, List facetList)
	{
		return new CombinedFacetAccessible(fspec,facetList);
	}
	
	@SuppressWarnings("unchecked")
	public D getFacetData(BoboIndexReader reader){
		return (D)reader.getFacetData(_name);
	}
	
	public D load(BoboIndexReader reader, BoboIndexReader.WorkArea workArea) throws IOException
	{
	  return load(reader);
	}
	
	public void loadFacetData(BoboIndexReader reader, BoboIndexReader.WorkArea workArea) throws IOException
	{
	  reader.putFacetData(_name, load(reader, workArea));
	}
	
	public void loadFacetData(BoboIndexReader reader) throws IOException
	{
	  reader.putFacetData(_name, load(reader));
	}

	/**
	 * Gets a filter from a given selection
	 * @param sel selection
	 * @return a filter
	 * @throws IOException 
	 * @throws IOException
	 */
	public RandomAccessFilter buildFilter(BrowseSelection sel) throws IOException
	{
      String[] selections = sel.getValues();
      String[] notSelections = sel.getNotValues();
      Properties prop=sel.getSelectionProperties();
      
      RandomAccessFilter filter = null;
      if (selections!=null && selections.length > 0)
      {
        if (sel.getSelectionOperation() == ValueOperation.ValueOperationAnd)
        {
          filter = buildRandomAccessAndFilter(selections,prop);
          if (filter == null)
          {
            filter = EmptyFilter.getInstance();
          }
        }
        else
        {
          filter = buildRandomAccessOrFilter(selections, prop,false);
          if (filter == null)
          {
            return EmptyFilter.getInstance();
          }
        }
      }
      
      if (notSelections!=null && notSelections.length>0)
      {
        RandomAccessFilter notFilter = buildRandomAccessOrFilter(notSelections, prop, true);
        if (filter==null)
        {
          filter = notFilter;
        }
        else
        {
          RandomAccessFilter andFilter = new RandomAccessAndFilter(Arrays.asList(new RandomAccessFilter[]{filter,notFilter}));
          filter = andFilter;
        }
      }
      
      return filter;
	}
	
	abstract public RandomAccessFilter buildRandomAccessFilter(String value,Properties selectionProperty) throws IOException;
	
  public RandomAccessFilter buildRandomAccessAndFilter(String[] vals, Properties prop) throws IOException {
    ArrayList filterList = new ArrayList(vals.length);

    for (String val : vals) {
      RandomAccessFilter f = buildRandomAccessFilter(val, prop);
      if (f != null) {
        filterList.add(f);
      } else {
        return EmptyFilter.getInstance();
      }
    }

    if (filterList.size() == 1)
      return filterList.get(0);
    return new RandomAccessAndFilter(filterList);
  }
	
	public RandomAccessFilter buildRandomAccessOrFilter(String[] vals,Properties prop,boolean isNot) throws IOException
    {
      ArrayList filterList = new ArrayList(vals.length);
      
      for (String val : vals)
      {
        RandomAccessFilter f = buildRandomAccessFilter(val, prop);
        if(f != null && !(f instanceof EmptyFilter)) 
        {
          filterList.add(f);
        }
      }
      
      RandomAccessFilter finalFilter;
      if (filterList.size() == 0)
      {
        finalFilter = EmptyFilter.getInstance();
      }
      else
      {
        finalFilter = new RandomAccessOrFilter(filterList);
      }
      
      if (isNot)
      {
        finalFilter = new RandomAccessNotFilter(finalFilter);
      }
      return finalFilter;
    }
	
	/**
	 * Gets a FacetCountCollector
	 * @param sel selection
	 * @param fspec facetSpec
	 * @return a FacetCountCollector
	 */
	abstract public FacetCountCollectorSource getFacetCountCollectorSource(BrowseSelection sel, FacetSpec fspec);

  /**
   * Override this method if your facet handler have a better group mode like the SimpleFacetHandler.
   */
	public FacetCountCollectorSource getFacetCountCollectorSource(BrowseSelection sel,
                                                                FacetSpec ospec,
                                                                boolean groupMode) {
    return getFacetCountCollectorSource(sel, ospec);
  }
	
	/**
	 * Gets the field value
	 * @param id doc
	 * @param reader index reader
	 * @return array of field values
	 * @see #getFieldValue(BoboIndexReader,int)
	 */
	abstract public String[] getFieldValues(BoboIndexReader reader,int id);
	
	public int getNumItems(BoboIndexReader reader,int id){
	  throw new UnsupportedOperationException("getNumItems is not supported for this facet handler: "+getClass().getName());
	}
	
	public Object[] getRawFieldValues(BoboIndexReader reader,int id){
		return getFieldValues(reader, id);
	}
	
	/**
	 * Gets a single field value
	 * @param id doc
	 * @param reader index reader
	 * @return first field value
	 * @see #getFieldValues(BoboIndexReader,int)
	 */
	public String getFieldValue(BoboIndexReader reader,int id)
	{
		return getFieldValues(reader,id)[0];
	}
	
	/**
	 * builds a comparator to determine how sorting is done
	 * @return a sort comparator
	 */
	abstract public DocComparatorSource getDocComparatorSource();
	
	@Override
	public Object clone() throws CloneNotSupportedException
	{
		return super.clone();
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy