<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../jacoco-resources/report.css" type="text/css"/><link rel="shortcut icon" href="../jacoco-resources/report.gif" type="image/gif"/><title>MtasSolrComponentTermvector.java</title><link rel="stylesheet" href="../jacoco-resources/prettify.css" type="text/css"/><script type="text/javascript" src="../jacoco-resources/prettify.js"></script></head><body onload="window['PR_TAB_WIDTH']=4;prettyPrint()"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../jacoco-sessions.html" class="el_session">Sessions</a></span><a href="../index.html" class="el_report">MTAS</a> &gt; <a href="index.source.html" class="el_package">mtas.solr.handler.component.util</a> &gt; <span class="el_source">MtasSolrComponentTermvector.java</span></div><h1>MtasSolrComponentTermvector.java</h1><pre class="source lang-java linenums">package mtas.solr.handler.component.util;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Map.Entry;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.SimpleOrderedMap;
import org.apache.solr.handler.component.ResponseBuilder;
import org.apache.solr.handler.component.SearchComponent;
import org.apache.solr.handler.component.ShardRequest;
import org.apache.solr.handler.component.ShardResponse;

import mtas.codec.util.CodecUtil;
import mtas.codec.util.CodecComponent.ComponentField;
import mtas.codec.util.CodecComponent.ComponentFields;
import mtas.codec.util.CodecComponent.ComponentTermVector;
import mtas.codec.util.CodecComponent.SubComponentFunction;
import mtas.codec.util.collector.MtasDataCollector;
import mtas.codec.util.collector.MtasDataItemNumberComparator;
import mtas.parser.function.ParseException;
import mtas.solr.handler.component.MtasSolrSearchComponent;

/**
 * The Class MtasSolrComponentTermvector.
 */
public class MtasSolrComponentTermvector
    implements MtasSolrComponent&lt;ComponentTermVector&gt; {

  /** The Constant log. */
<span class="fc" id="L48">  private static final Log log = LogFactory</span>
<span class="fc" id="L49">      .getLog(MtasSolrComponentTermvector.class);</span>

  /** The search component. */
  MtasSolrSearchComponent searchComponent;

  /** The Constant PARAM_MTAS_TERMVECTOR. */
  public static final String PARAM_MTAS_TERMVECTOR = MtasSolrSearchComponent.PARAM_MTAS
      + &quot;.termvector&quot;;

  /** The Constant NAME_MTAS_TERMVECTOR_FIELD. */
  public static final String NAME_MTAS_TERMVECTOR_FIELD = &quot;field&quot;;

  /** The Constant NAME_MTAS_TERMVECTOR_KEY. */
  public static final String NAME_MTAS_TERMVECTOR_KEY = &quot;key&quot;;

  /** The Constant NAME_MTAS_TERMVECTOR_PREFIX. */
  public static final String NAME_MTAS_TERMVECTOR_PREFIX = &quot;prefix&quot;;

  /** The Constant NAME_MTAS_TERMVECTOR_REGEXP. */
  public static final String NAME_MTAS_TERMVECTOR_REGEXP = &quot;regexp&quot;;

  /** The Constant NAME_MTAS_TERMVECTOR_FULL. */
  public static final String NAME_MTAS_TERMVECTOR_FULL = &quot;full&quot;;

  /** The Constant NAME_MTAS_TERMVECTOR_TYPE. */
  public static final String NAME_MTAS_TERMVECTOR_TYPE = &quot;type&quot;;

  /** The Constant NAME_MTAS_TERMVECTOR_SORT_TYPE. */
  public static final String NAME_MTAS_TERMVECTOR_SORT_TYPE = &quot;sort.type&quot;;

  /** The Constant NAME_MTAS_TERMVECTOR_SORT_DIRECTION. */
  public static final String NAME_MTAS_TERMVECTOR_SORT_DIRECTION = &quot;sort.direction&quot;;

  /** The Constant NAME_MTAS_TERMVECTOR_START. */
  public static final String NAME_MTAS_TERMVECTOR_START = &quot;start&quot;;

  /** The Constant NAME_MTAS_TERMVECTOR_NUMBER. */
  public static final String NAME_MTAS_TERMVECTOR_NUMBER = &quot;number&quot;;

  /** The Constant NAME_MTAS_TERMVECTOR_NUMBER_SHARDS. */
  public static final String NAME_MTAS_TERMVECTOR_NUMBER_SHARDS = &quot;number.shards&quot;;

  /** The Constant NAME_MTAS_TERMVECTOR_FUNCTION. */
  public static final String NAME_MTAS_TERMVECTOR_FUNCTION = &quot;function&quot;;

  /** The Constant NAME_MTAS_TERMVECTOR_FUNCTION_EXPRESSION. */
  public static final String NAME_MTAS_TERMVECTOR_FUNCTION_EXPRESSION = &quot;expression&quot;;

  /** The Constant NAME_MTAS_TERMVECTOR_FUNCTION_KEY. */
  public static final String NAME_MTAS_TERMVECTOR_FUNCTION_KEY = &quot;key&quot;;

  /** The Constant NAME_MTAS_TERMVECTOR_FUNCTION_TYPE. */
  public static final String NAME_MTAS_TERMVECTOR_FUNCTION_TYPE = &quot;type&quot;;

  /** The Constant NAME_MTAS_TERMVECTOR_BOUNDARY. */
  public static final String NAME_MTAS_TERMVECTOR_BOUNDARY = &quot;boundary&quot;;

  /** The Constant NAME_MTAS_TERMVECTOR_LIST. */
  public static final String NAME_MTAS_TERMVECTOR_LIST = &quot;list&quot;;

  /** The Constant NAME_MTAS_TERMVECTOR_LIST_REGEXP. */
  public static final String NAME_MTAS_TERMVECTOR_LIST_REGEXP = &quot;listRegexp&quot;;

  /** The Constant NAME_MTAS_TERMVECTOR_IGNORE_REGEXP. */
  public static final String NAME_MTAS_TERMVECTOR_IGNORE_REGEXP = &quot;ignoreRegexp&quot;;

  /** The Constant NAME_MTAS_TERMVECTOR_IGNORE_LIST. */
  public static final String NAME_MTAS_TERMVECTOR_IGNORE_LIST = &quot;ignoreList&quot;;

  /** The Constant NAME_MTAS_TERMVECTOR_IGNORE_LIST_REGEXP. */
  public static final String NAME_MTAS_TERMVECTOR_IGNORE_LIST_REGEXP = &quot;ignoreListRegexp&quot;;

  /** The Constant SHARD_NUMBER_MULTIPLIER. */
  private static final int SHARD_NUMBER_MULTIPLIER = 2;

  /** The Constant DEFAULT_NUMBER. */
  private static final int DEFAULT_NUMBER = 10;

  /**
   * Instantiates a new mtas solr component termvector.
   *
   * @param searchComponent the search component
   */
<span class="fc" id="L132">  public MtasSolrComponentTermvector(MtasSolrSearchComponent searchComponent) {</span>
<span class="fc" id="L133">    this.searchComponent = searchComponent;</span>
<span class="fc" id="L134">  }</span>

  /*
   * (non-Javadoc)
   * 
   * @see
   * mtas.solr.handler.component.util.MtasSolrComponent#prepare(org.apache.solr.
   * handler.component.ResponseBuilder,
   * mtas.codec.util.CodecComponent.ComponentFields)
   */
  public void prepare(ResponseBuilder rb, ComponentFields mtasFields)
      throws IOException {
<span class="fc" id="L146">    Set&lt;String&gt; ids = MtasSolrResultUtil</span>
<span class="fc" id="L147">        .getIdsFromParameters(rb.req.getParams(), PARAM_MTAS_TERMVECTOR);</span>
<span class="pc bpc" id="L148" title="1 of 2 branches missed.">    if (!ids.isEmpty()) {</span>
<span class="fc" id="L149">      int tmpCounter = 0;</span>
<span class="fc" id="L150">      String[] fields = new String[ids.size()];</span>
<span class="fc" id="L151">      String[] keys = new String[ids.size()];</span>
<span class="fc" id="L152">      String[] prefixes = new String[ids.size()];</span>
<span class="fc" id="L153">      String[] regexps = new String[ids.size()];</span>
<span class="fc" id="L154">      String[] fulls = new String[ids.size()];</span>
<span class="fc" id="L155">      String[] sortTypes = new String[ids.size()];</span>
<span class="fc" id="L156">      String[] sortDirections = new String[ids.size()];</span>
<span class="fc" id="L157">      String[] types = new String[ids.size()];</span>
<span class="fc" id="L158">      String[] startValues = new String[ids.size()];</span>
<span class="fc" id="L159">      String[] numbers = new String[ids.size()];</span>
<span class="fc" id="L160">      String[] numberShards = new String[ids.size()];</span>
<span class="fc" id="L161">      String[][] functionExpressions = new String[ids.size()][];</span>
<span class="fc" id="L162">      String[][] functionKeys = new String[ids.size()][];</span>
<span class="fc" id="L163">      String[][] functionTypes = new String[ids.size()][];</span>
<span class="fc" id="L164">      String[] boundaries = new String[ids.size()];</span>
<span class="fc" id="L165">      String[] lists = new String[ids.size()];</span>
<span class="fc" id="L166">      Boolean[] listRegexps = new Boolean[ids.size()];</span>
<span class="fc" id="L167">      String[] ignoreRegexps = new String[ids.size()];</span>
<span class="fc" id="L168">      String[] ignoreLists = new String[ids.size()];</span>
<span class="fc" id="L169">      Boolean[] ignoreListRegexps = new Boolean[ids.size()];</span>
<span class="fc bfc" id="L170" title="All 2 branches covered.">      for (String id : ids) {</span>
<span class="fc" id="L171">        fields[tmpCounter] = rb.req.getParams().get(</span>
            PARAM_MTAS_TERMVECTOR + &quot;.&quot; + id + &quot;.&quot; + NAME_MTAS_TERMVECTOR_FIELD,
            null);
<span class="fc" id="L174">        keys[tmpCounter] = rb.req.getParams().get(</span>
            PARAM_MTAS_TERMVECTOR + &quot;.&quot; + id + &quot;.&quot; + NAME_MTAS_TERMVECTOR_KEY,
<span class="fc" id="L176">            String.valueOf(tmpCounter)).trim();</span>
<span class="fc" id="L177">        prefixes[tmpCounter] = rb.req.getParams().get(PARAM_MTAS_TERMVECTOR</span>
            + &quot;.&quot; + id + &quot;.&quot; + NAME_MTAS_TERMVECTOR_PREFIX, null);
<span class="fc" id="L179">        regexps[tmpCounter] = rb.req.getParams().get(PARAM_MTAS_TERMVECTOR + &quot;.&quot;</span>
            + id + &quot;.&quot; + NAME_MTAS_TERMVECTOR_REGEXP, null);
<span class="fc" id="L181">        fulls[tmpCounter] = rb.req.getParams().get(</span>
            PARAM_MTAS_TERMVECTOR + &quot;.&quot; + id + &quot;.&quot; + NAME_MTAS_TERMVECTOR_FULL,
            null);
<span class="fc" id="L184">        sortTypes[tmpCounter] = rb.req.getParams().get(PARAM_MTAS_TERMVECTOR</span>
            + &quot;.&quot; + id + &quot;.&quot; + NAME_MTAS_TERMVECTOR_SORT_TYPE, null);
<span class="fc" id="L186">        sortDirections[tmpCounter] = rb.req.getParams()</span>
<span class="fc" id="L187">            .get(PARAM_MTAS_TERMVECTOR + &quot;.&quot; + id + &quot;.&quot;</span>
                + NAME_MTAS_TERMVECTOR_SORT_DIRECTION, null);
<span class="fc" id="L189">        startValues[tmpCounter] = rb.req.getParams().get(</span>
            PARAM_MTAS_TERMVECTOR + &quot;.&quot; + id + &quot;.&quot; + NAME_MTAS_TERMVECTOR_START,
            null);
<span class="fc" id="L192">        numbers[tmpCounter] = rb.req.getParams().get(PARAM_MTAS_TERMVECTOR + &quot;.&quot;</span>
            + id + &quot;.&quot; + NAME_MTAS_TERMVECTOR_NUMBER, null);
<span class="fc" id="L194">        numberShards[tmpCounter] = rb.req.getParams().get(PARAM_MTAS_TERMVECTOR</span>
            + &quot;.&quot; + id + &quot;.&quot; + NAME_MTAS_TERMVECTOR_NUMBER_SHARDS, null);
<span class="fc" id="L196">        types[tmpCounter] = rb.req.getParams().get(</span>
            PARAM_MTAS_TERMVECTOR + &quot;.&quot; + id + &quot;.&quot; + NAME_MTAS_TERMVECTOR_TYPE,
            null);
<span class="fc" id="L199">        Set&lt;String&gt; functionIds = MtasSolrResultUtil</span>
<span class="fc" id="L200">            .getIdsFromParameters(rb.req.getParams(), PARAM_MTAS_TERMVECTOR</span>
                + &quot;.&quot; + id + &quot;.&quot; + NAME_MTAS_TERMVECTOR_FUNCTION);
<span class="fc" id="L202">        functionExpressions[tmpCounter] = new String[functionIds.size()];</span>
<span class="fc" id="L203">        functionKeys[tmpCounter] = new String[functionIds.size()];</span>
<span class="fc" id="L204">        functionTypes[tmpCounter] = new String[functionIds.size()];</span>
<span class="fc" id="L205">        int tmpSubCounter = 0;</span>
<span class="pc bpc" id="L206" title="1 of 2 branches missed.">        for (String functionId : functionIds) {</span>
<span class="nc" id="L207">          functionKeys[tmpCounter][tmpSubCounter] = rb.req.getParams()</span>
<span class="nc" id="L208">              .get(</span>
                  PARAM_MTAS_TERMVECTOR + &quot;.&quot; + id + &quot;.&quot;
                      + NAME_MTAS_TERMVECTOR_FUNCTION + &quot;.&quot; + functionId + &quot;.&quot;
                      + NAME_MTAS_TERMVECTOR_FUNCTION_KEY,
<span class="nc" id="L212">                  String.valueOf(tmpSubCounter))</span>
<span class="nc" id="L213">              .trim();</span>
<span class="nc" id="L214">          functionExpressions[tmpCounter][tmpSubCounter] = rb.req.getParams()</span>
<span class="nc" id="L215">              .get(PARAM_MTAS_TERMVECTOR + &quot;.&quot; + id + &quot;.&quot;</span>
                  + NAME_MTAS_TERMVECTOR_FUNCTION + &quot;.&quot; + functionId + &quot;.&quot;
                  + NAME_MTAS_TERMVECTOR_FUNCTION_EXPRESSION, null);
<span class="nc" id="L218">          functionTypes[tmpCounter][tmpSubCounter] = rb.req.getParams()</span>
<span class="nc" id="L219">              .get(PARAM_MTAS_TERMVECTOR + &quot;.&quot; + id + &quot;.&quot;</span>
                  + NAME_MTAS_TERMVECTOR_FUNCTION + &quot;.&quot; + functionId + &quot;.&quot;
                  + NAME_MTAS_TERMVECTOR_FUNCTION_TYPE, null);
<span class="nc" id="L222">          tmpSubCounter++;</span>
<span class="nc" id="L223">        }</span>
<span class="fc" id="L224">        boundaries[tmpCounter] = rb.req.getParams().get(PARAM_MTAS_TERMVECTOR</span>
            + &quot;.&quot; + id + &quot;.&quot; + NAME_MTAS_TERMVECTOR_BOUNDARY, null);
<span class="fc" id="L226">        lists[tmpCounter] = rb.req.getParams().get(</span>
            PARAM_MTAS_TERMVECTOR + &quot;.&quot; + id + &quot;.&quot; + NAME_MTAS_TERMVECTOR_LIST);
<span class="fc" id="L228">        listRegexps[tmpCounter] = rb.req.getParams()</span>
<span class="fc" id="L229">            .getBool(PARAM_MTAS_TERMVECTOR + &quot;.&quot; + id + &quot;.&quot;</span>
                + NAME_MTAS_TERMVECTOR_LIST_REGEXP, false);
<span class="fc" id="L231">        ignoreRegexps[tmpCounter] = rb.req.getParams().get(PARAM_MTAS_TERMVECTOR</span>
            + &quot;.&quot; + id + &quot;.&quot; + NAME_MTAS_TERMVECTOR_IGNORE_REGEXP, null);
<span class="fc" id="L233">        ignoreLists[tmpCounter] = rb.req.getParams().get(PARAM_MTAS_TERMVECTOR</span>
            + &quot;.&quot; + id + &quot;.&quot; + NAME_MTAS_TERMVECTOR_IGNORE_LIST, null);
<span class="fc" id="L235">        ignoreListRegexps[tmpCounter] = rb.req.getParams()</span>
<span class="fc" id="L236">            .getBool(PARAM_MTAS_TERMVECTOR + &quot;.&quot; + id + &quot;.&quot;</span>
                + NAME_MTAS_TERMVECTOR_IGNORE_LIST_REGEXP, false);
<span class="fc" id="L238">        tmpCounter++;</span>
<span class="fc" id="L239">      }</span>
<span class="fc" id="L240">      String uniqueKeyField = rb.req.getSchema().getUniqueKeyField().getName();</span>
<span class="fc" id="L241">      mtasFields.doTermVector = true;</span>
<span class="fc" id="L242">      rb.setNeedDocSet(true);</span>
      // init and checks
<span class="fc bfc" id="L244" title="All 2 branches covered.">      for (String field : fields) {</span>
<span class="pc bpc" id="L245" title="2 of 4 branches missed.">        if (field == null || field.isEmpty()) {</span>
<span class="nc" id="L246">          throw new IOException(&quot;no (valid) field in mtas termvector&quot;);</span>
<span class="pc bpc" id="L247" title="1 of 2 branches missed.">        } else if (!mtasFields.list.containsKey(field)) {</span>
<span class="fc" id="L248">          mtasFields.list.put(field, new ComponentField(uniqueKeyField));</span>
        }
      }
<span class="fc" id="L251">      MtasSolrResultUtil.compareAndCheck(keys, fields, NAME_MTAS_TERMVECTOR_KEY,</span>
<span class="fc" id="L252">          NAME_MTAS_TERMVECTOR_FIELD, true);</span>
<span class="fc" id="L253">      MtasSolrResultUtil.compareAndCheck(prefixes, fields,</span>
<span class="fc" id="L254">          NAME_MTAS_TERMVECTOR_PREFIX, NAME_MTAS_TERMVECTOR_FIELD, false);</span>
<span class="fc" id="L255">      MtasSolrResultUtil.compareAndCheck(regexps, fields,</span>
<span class="fc" id="L256">          NAME_MTAS_TERMVECTOR_REGEXP, NAME_MTAS_TERMVECTOR_FIELD, false);</span>
<span class="fc" id="L257">      MtasSolrResultUtil.compareAndCheck(types, fields,</span>
<span class="fc" id="L258">          NAME_MTAS_TERMVECTOR_TYPE, NAME_MTAS_TERMVECTOR_FIELD, false);</span>
<span class="fc" id="L259">      MtasSolrResultUtil.compareAndCheck(sortTypes, fields,</span>
<span class="fc" id="L260">          NAME_MTAS_TERMVECTOR_SORT_TYPE, NAME_MTAS_TERMVECTOR_FIELD, false);</span>
<span class="fc" id="L261">      MtasSolrResultUtil.compareAndCheck(sortDirections, fields,</span>
          NAME_MTAS_TERMVECTOR_SORT_DIRECTION, NAME_MTAS_TERMVECTOR_FIELD,
<span class="fc" id="L263">          false);</span>
<span class="fc" id="L264">      MtasSolrResultUtil.compareAndCheck(numbers, fields,</span>
<span class="fc" id="L265">          NAME_MTAS_TERMVECTOR_NUMBER, NAME_MTAS_TERMVECTOR_FIELD, false);</span>
<span class="fc" id="L266">      MtasSolrResultUtil.compareAndCheck(boundaries, fields,</span>
<span class="fc" id="L267">          NAME_MTAS_TERMVECTOR_BOUNDARY, NAME_MTAS_TERMVECTOR_FIELD, false);</span>
<span class="fc" id="L268">      MtasSolrResultUtil.compareAndCheck(lists, fields,</span>
<span class="fc" id="L269">          NAME_MTAS_TERMVECTOR_LIST, NAME_MTAS_TERMVECTOR_FIELD, false);</span>
<span class="fc" id="L270">      MtasSolrResultUtil.compareAndCheck(ignoreRegexps, fields,</span>
          NAME_MTAS_TERMVECTOR_IGNORE_REGEXP, NAME_MTAS_TERMVECTOR_FIELD,
<span class="fc" id="L272">          false);</span>
<span class="fc" id="L273">      MtasSolrResultUtil.compareAndCheck(ignoreLists, fields,</span>
<span class="fc" id="L274">          NAME_MTAS_TERMVECTOR_IGNORE_LIST, NAME_MTAS_TERMVECTOR_FIELD, false);</span>
<span class="fc bfc" id="L275" title="All 2 branches covered.">      for (int i = 0; i &lt; fields.length; i++) {</span>
<span class="fc bfc" id="L276" title="All 2 branches covered.">        if (!rb.req.getParams().getBool(&quot;isShard&quot;, false)) {</span>
<span class="fc" id="L277">          numberShards[i] = null;</span>
<span class="fc" id="L278">          boundaries[i] = null;</span>
        }
<span class="fc" id="L280">        String field = fields[i];</span>
<span class="pc bpc" id="L281" title="2 of 4 branches missed.">        String prefix = (prefixes[i] == null) || (prefixes[i].isEmpty()) ? null</span>
<span class="fc" id="L282">            : prefixes[i].trim();</span>
<span class="pc bpc" id="L283" title="2 of 4 branches missed.">        String key = (keys[i] == null) || (keys[i].isEmpty())</span>
<span class="pc" id="L284">            ? String.valueOf(i) + &quot;:&quot; + field + &quot;:&quot; + prefix : keys[i].trim();</span>
<span class="pc bpc" id="L285" title="1 of 4 branches missed.">        String regexp = (regexps[i] == null) || (regexps[i].isEmpty()) ? null</span>
<span class="fc" id="L286">            : regexps[i].trim();</span>
<span class="fc bfc" id="L287" title="All 4 branches covered.">        Boolean full = (fulls[i] == null) || (!fulls[i].equals(&quot;true&quot;)) ? false</span>
            : true;
<span class="pc bpc" id="L289" title="1 of 2 branches missed.">        String startValue = (startValues[i] == null)</span>
<span class="pc bnc" id="L290" title="All 2 branches missed.">            || (startValues[i].isEmpty()) ? null : startValues[i].trim();</span>
<span class="pc bpc" id="L291" title="1 of 4 branches missed.">        int listNumber = (numbers[i] == null) || (numbers[i].isEmpty())</span>
<span class="fc" id="L292">            ? DEFAULT_NUMBER : Integer.parseInt(numbers[i]);</span>
<span class="fc bfc" id="L293" title="All 2 branches covered.">        int numberFinal = (numberShards[i] == null)</span>
<span class="pc bpc" id="L294" title="1 of 2 branches missed.">            || (numberShards[i].isEmpty()) ? listNumber</span>
<span class="fc" id="L295">                : Integer.parseInt(numberShards[i]);</span>
<span class="pc bpc" id="L296" title="1 of 4 branches missed.">        String type = (types[i] == null) || (types[i].isEmpty()) ? null</span>
<span class="fc" id="L297">            : types[i].trim();</span>
<span class="pc bpc" id="L298" title="1 of 4 branches missed.">        String sortType = (sortTypes[i] == null) || (sortTypes[i].isEmpty())</span>
<span class="fc" id="L299">            ? null : sortTypes[i].trim();</span>
<span class="fc bfc" id="L300" title="All 2 branches covered.">        String sortDirection = (sortDirections[i] == null)</span>
<span class="pc bpc" id="L301" title="1 of 2 branches missed.">            || (sortDirections[i].isEmpty()) ? null : sortDirections[i].trim();</span>
<span class="fc" id="L302">        String[] functionKey = functionKeys[i];</span>
<span class="fc" id="L303">        String[] functionExpression = functionExpressions[i];</span>
<span class="fc" id="L304">        String[] functionType = functionTypes[i];</span>
<span class="fc" id="L305">        String boundary = boundaries[i];</span>
<span class="fc" id="L306">        String[] list = null;</span>
<span class="fc" id="L307">        Boolean listRegexp = listRegexps[i];</span>
<span class="fc bfc" id="L308" title="All 2 branches covered.">        if (lists[i] != null) {</span>
<span class="fc" id="L309">          ArrayList&lt;String&gt; tmpList = new ArrayList&lt;&gt;();</span>
<span class="fc" id="L310">          String[] subList = lists[i].split(&quot;(?&lt;!\\\\),&quot;);</span>
<span class="fc bfc" id="L311" title="All 2 branches covered.">          for (int j = 0; j &lt; subList.length; j++) {</span>
<span class="fc" id="L312">            tmpList.add(subList[j].replace(&quot;\\,&quot;, &quot;,&quot;).replace(&quot;\\\\&quot;, &quot;\\&quot;));</span>
          }
<span class="fc" id="L314">          list = tmpList.toArray(new String[tmpList.size()]);</span>
        }
<span class="fc" id="L316">        String ignoreRegexp = ignoreRegexps[i];</span>
<span class="fc" id="L317">        String[] ignoreList = null;</span>
<span class="fc" id="L318">        Boolean ignoreListRegexp = ignoreListRegexps[i];</span>
<span class="fc bfc" id="L319" title="All 2 branches covered.">        if (ignoreLists[i] != null) {</span>
<span class="fc" id="L320">          ArrayList&lt;String&gt; tmpList = new ArrayList&lt;&gt;();</span>
<span class="fc" id="L321">          String[] subList = ignoreLists[i].split(&quot;(?&lt;!\\\\),&quot;);</span>
<span class="fc bfc" id="L322" title="All 2 branches covered.">          for (int j = 0; j &lt; subList.length; j++) {</span>
<span class="fc" id="L323">            tmpList.add(subList[j].replace(&quot;\\,&quot;, &quot;,&quot;).replace(&quot;\\\\&quot;, &quot;\\&quot;));</span>
          }
<span class="fc" id="L325">          ignoreList = tmpList.toArray(new String[tmpList.size()]);</span>
        }

<span class="pc bpc" id="L328" title="2 of 4 branches missed.">        if (prefix == null || prefix.isEmpty()) {</span>
<span class="nc" id="L329">          throw new IOException(&quot;no (valid) prefix in mtas termvector&quot;);</span>
        } else {
          try {
<span class="fc" id="L332">            mtasFields.list.get(field).termVectorList</span>
<span class="fc" id="L333">                .add(new ComponentTermVector(key, prefix, regexp, full, type,</span>
                    sortType, sortDirection, startValue, numberFinal,
                    functionKey, functionExpression, functionType, boundary,
                    list, listRegexp, ignoreRegexp, ignoreList,
                    ignoreListRegexp));
<span class="nc" id="L338">          } catch (ParseException e) {</span>
<span class="nc" id="L339">            throw new IOException(e);</span>
<span class="fc" id="L340">          }</span>
        }
      }

    }
<span class="fc" id="L345">  }</span>

  /*
   * (non-Javadoc)
   * 
   * @see
   * mtas.solr.handler.component.util.MtasSolrComponent#modifyRequest(org.apache
   * .solr.handler.component.ResponseBuilder,
   * org.apache.solr.handler.component.SearchComponent,
   * org.apache.solr.handler.component.ShardRequest)
   */
  public void modifyRequest(ResponseBuilder rb, SearchComponent who,
      ShardRequest sreq) {
<span class="pc bpc" id="L358" title="1 of 2 branches missed.">    if (sreq.params.getBool(MtasSolrSearchComponent.PARAM_MTAS, false)) {</span>
<span class="pc bpc" id="L359" title="1 of 2 branches missed.">      if (sreq.params.getBool(PARAM_MTAS_TERMVECTOR, false)) {</span>
        // compute keys
<span class="fc" id="L361">        Set&lt;String&gt; keys = MtasSolrResultUtil</span>
<span class="fc" id="L362">            .getIdsFromParameters(rb.req.getParams(), PARAM_MTAS_TERMVECTOR);</span>
<span class="fc bfc" id="L363" title="All 2 branches covered.">        if ((sreq.purpose &amp; ShardRequest.PURPOSE_GET_TOP_IDS) != 0) {</span>
<span class="fc bfc" id="L364" title="All 2 branches covered.">          for (String key : keys) {</span>
<span class="fc" id="L365">            String oldNumber = sreq.params.get(PARAM_MTAS_TERMVECTOR + &quot;.&quot; + key</span>
                + &quot;.&quot; + NAME_MTAS_TERMVECTOR_NUMBER);
            int number;
<span class="pc bpc" id="L368" title="1 of 2 branches missed.">            if (oldNumber != null) {</span>
<span class="fc" id="L369">              int oldNumberValue = Integer.parseInt(oldNumber);</span>
<span class="fc bfc" id="L370" title="All 2 branches covered.">              number = (oldNumberValue &gt;= 0)</span>
                  ? oldNumberValue * SHARD_NUMBER_MULTIPLIER : oldNumberValue;
<span class="fc" id="L372">            } else {</span>
<span class="nc" id="L373">              number = DEFAULT_NUMBER * SHARD_NUMBER_MULTIPLIER;</span>
            }
<span class="fc" id="L375">            sreq.params.add(</span>
                PARAM_MTAS_TERMVECTOR + &quot;.&quot; + key + &quot;.&quot;
                    + NAME_MTAS_TERMVECTOR_NUMBER_SHARDS,
<span class="fc" id="L378">                String.valueOf(number));</span>
<span class="fc" id="L379">          }</span>
        } else {
<span class="fc" id="L381">          sreq.params.remove(PARAM_MTAS_TERMVECTOR);</span>
<span class="fc bfc" id="L382" title="All 2 branches covered.">          for (String key : keys) {</span>
<span class="fc" id="L383">            sreq.params.remove(PARAM_MTAS_TERMVECTOR + &quot;.&quot; + key + &quot;.&quot;</span>
                + NAME_MTAS_TERMVECTOR_FIELD);
<span class="fc" id="L385">            sreq.params.remove(PARAM_MTAS_TERMVECTOR + &quot;.&quot; + key + &quot;.&quot;</span>
                + NAME_MTAS_TERMVECTOR_KEY);
<span class="fc" id="L387">            sreq.params.remove(PARAM_MTAS_TERMVECTOR + &quot;.&quot; + key + &quot;.&quot;</span>
                + NAME_MTAS_TERMVECTOR_PREFIX);
<span class="fc" id="L389">            sreq.params.remove(PARAM_MTAS_TERMVECTOR + &quot;.&quot; + key + &quot;.&quot;</span>
                + NAME_MTAS_TERMVECTOR_REGEXP);
<span class="fc" id="L391">            sreq.params.remove(PARAM_MTAS_TERMVECTOR + &quot;.&quot; + key + &quot;.&quot;</span>
                + NAME_MTAS_TERMVECTOR_FULL);
<span class="fc" id="L393">            sreq.params.remove(PARAM_MTAS_TERMVECTOR + &quot;.&quot; + key + &quot;.&quot;</span>
                + NAME_MTAS_TERMVECTOR_SORT_TYPE);
<span class="fc" id="L395">            sreq.params.remove(PARAM_MTAS_TERMVECTOR + &quot;.&quot; + key + &quot;.&quot;</span>
                + NAME_MTAS_TERMVECTOR_SORT_DIRECTION);
<span class="fc" id="L397">            sreq.params.remove(PARAM_MTAS_TERMVECTOR + &quot;.&quot; + key + &quot;.&quot;</span>
                + NAME_MTAS_TERMVECTOR_NUMBER);
<span class="fc" id="L399">            sreq.params.remove(PARAM_MTAS_TERMVECTOR + &quot;.&quot; + key + &quot;.&quot;</span>
                + NAME_MTAS_TERMVECTOR_NUMBER_SHARDS);
<span class="fc" id="L401">            Set&lt;String&gt; functionKeys = MtasSolrResultUtil</span>
<span class="fc" id="L402">                .getIdsFromParameters(rb.req.getParams(), PARAM_MTAS_TERMVECTOR</span>
                    + &quot;.&quot; + key + &quot;.&quot; + NAME_MTAS_TERMVECTOR_FUNCTION);
<span class="pc bpc" id="L404" title="1 of 2 branches missed.">            for (String functionKey : functionKeys) {</span>
<span class="nc" id="L405">              sreq.params.remove(PARAM_MTAS_TERMVECTOR + &quot;.&quot; + key + &quot;.&quot;</span>
                  + NAME_MTAS_TERMVECTOR_FUNCTION + &quot;.&quot; + functionKey + &quot;.&quot;
                  + NAME_MTAS_TERMVECTOR_FUNCTION_EXPRESSION);
<span class="nc" id="L408">              sreq.params.remove(PARAM_MTAS_TERMVECTOR + &quot;.&quot; + key + &quot;.&quot;</span>
                  + NAME_MTAS_TERMVECTOR_FUNCTION + &quot;.&quot; + functionKey + &quot;.&quot;
                  + NAME_MTAS_TERMVECTOR_FUNCTION_KEY);
<span class="nc" id="L411">              sreq.params.remove(PARAM_MTAS_TERMVECTOR + &quot;.&quot; + key + &quot;.&quot;</span>
                  + NAME_MTAS_TERMVECTOR_FUNCTION + &quot;.&quot; + functionKey + &quot;.&quot;
                  + NAME_MTAS_TERMVECTOR_FUNCTION_TYPE);
<span class="nc" id="L414">            }</span>
<span class="fc" id="L415">            sreq.params.remove(PARAM_MTAS_TERMVECTOR + &quot;.&quot; + key + &quot;.&quot;</span>
                + NAME_MTAS_TERMVECTOR_BOUNDARY);
<span class="fc" id="L417">            sreq.params.remove(PARAM_MTAS_TERMVECTOR + &quot;.&quot; + key + &quot;.&quot;</span>
                + NAME_MTAS_TERMVECTOR_LIST);
<span class="fc" id="L419">            sreq.params.remove(PARAM_MTAS_TERMVECTOR + &quot;.&quot; + key + &quot;.&quot;</span>
                + NAME_MTAS_TERMVECTOR_LIST_REGEXP);
<span class="fc" id="L421">            sreq.params.remove(PARAM_MTAS_TERMVECTOR + &quot;.&quot; + key + &quot;.&quot;</span>
                + NAME_MTAS_TERMVECTOR_IGNORE_REGEXP);
<span class="fc" id="L423">            sreq.params.remove(PARAM_MTAS_TERMVECTOR + &quot;.&quot; + key + &quot;.&quot;</span>
                + NAME_MTAS_TERMVECTOR_IGNORE_LIST);
<span class="fc" id="L425">            sreq.params.remove(PARAM_MTAS_TERMVECTOR + &quot;.&quot; + key + &quot;.&quot;</span>
                + NAME_MTAS_TERMVECTOR_IGNORE_REGEXP);
<span class="fc" id="L427">          }</span>
        }
      }
    }
<span class="fc" id="L431">  }</span>

  /*
   * (non-Javadoc)
   * 
   * @see
   * mtas.solr.handler.component.util.MtasSolrComponent#create(mtas.codec.util.
   * CodecComponent.BasicComponent, java.lang.Boolean)
   */
  @SuppressWarnings(&quot;unchecked&quot;)
  public SimpleOrderedMap&lt;Object&gt; create(ComponentTermVector termVector,
      Boolean encode) throws IOException {
<span class="fc" id="L443">    SimpleOrderedMap&lt;Object&gt; mtasTermVectorResponse = new SimpleOrderedMap&lt;&gt;();</span>
<span class="fc" id="L444">    mtasTermVectorResponse.add(&quot;key&quot;, termVector.key);</span>

<span class="fc" id="L446">    termVector.subComponentFunction.dataCollector.close();</span>

<span class="fc" id="L448">    HashMap&lt;MtasDataCollector&lt;?, ?&gt;, HashMap&lt;String, MtasSolrMtasResult&gt;&gt; functionData = new HashMap&lt;&gt;();</span>
<span class="fc" id="L449">    HashMap&lt;String, MtasSolrMtasResult&gt; functionDataItem = new HashMap&lt;&gt;();</span>
<span class="fc" id="L450">    functionData.put(termVector.subComponentFunction.dataCollector,</span>
        functionDataItem);
<span class="pc bpc" id="L452" title="1 of 2 branches missed.">    if (termVector.functions != null) {</span>
<span class="pc bpc" id="L453" title="1 of 2 branches missed.">      for (SubComponentFunction function : termVector.functions) {</span>
<span class="nc" id="L454">        function.dataCollector.reduceToKeys(</span>
<span class="nc" id="L455">            termVector.subComponentFunction.dataCollector.getKeyList());</span>
<span class="nc" id="L456">        function.dataCollector.close();</span>
<span class="nc" id="L457">        functionDataItem.put(function.key,</span>
            new MtasSolrMtasResult(function.dataCollector,
                new String[] { function.dataType },
                new String[] { function.statsType },
                new SortedSet[] { function.statsItems }, new String[] { null },
<span class="nc" id="L462">                new String[] { null }, new Integer[] { 0 },</span>
<span class="nc" id="L463">                new Integer[] { Integer.MAX_VALUE }, null));</span>
<span class="nc" id="L464">      }</span>
    }
<span class="fc" id="L466">    MtasSolrMtasResult data = new MtasSolrMtasResult(</span>
        termVector.subComponentFunction.dataCollector,
        new String[] { termVector.subComponentFunction.dataType },
        new String[] { termVector.subComponentFunction.statsType },
        new SortedSet[] { termVector.subComponentFunction.statsItems },
        new String[] { termVector.subComponentFunction.sortType },
        new String[] { termVector.subComponentFunction.sortDirection },
<span class="fc" id="L473">        new Integer[] { 0 }, new Integer[] { termVector.number }, functionData);</span>
<span class="fc bfc" id="L474" title="All 2 branches covered.">    if (encode) {</span>
<span class="fc" id="L475">      mtasTermVectorResponse.add(&quot;_encoded_list&quot;,</span>
<span class="fc" id="L476">          MtasSolrResultUtil.encode(data));</span>
    } else {
<span class="fc" id="L478">      mtasTermVectorResponse.add(&quot;list&quot;, data);</span>
<span class="fc" id="L479">      MtasSolrResultUtil.rewrite(mtasTermVectorResponse, searchComponent);</span>
    }
<span class="fc" id="L481">    return mtasTermVectorResponse;</span>
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * mtas.solr.handler.component.util.MtasSolrComponent#finishStage(org.apache.
   * solr.handler.component.ResponseBuilder)
   */
  @SuppressWarnings(&quot;unchecked&quot;)
  public void finishStage(ResponseBuilder rb) {
<span class="pc bpc" id="L493" title="1 of 2 branches missed.">    if (rb.req.getParams().getBool(MtasSolrSearchComponent.PARAM_MTAS, false)) {</span>
<span class="fc bfc" id="L494" title="All 4 branches covered.">      if (rb.stage &gt;= ResponseBuilder.STAGE_EXECUTE_QUERY</span>
          &amp;&amp; rb.stage &lt; ResponseBuilder.STAGE_GET_FIELDS) {
<span class="fc bfc" id="L496" title="All 2 branches covered.">        for (ShardRequest sreq : rb.finished) {</span>
<span class="pc bpc" id="L497" title="1 of 2 branches missed.">          if (sreq.params.getBool(MtasSolrSearchComponent.PARAM_MTAS, false)</span>
<span class="pc bpc" id="L498" title="1 of 2 branches missed.">              &amp;&amp; sreq.params.getBool(PARAM_MTAS_TERMVECTOR, false)) {</span>
<span class="fc bfc" id="L499" title="All 2 branches covered.">            for (ShardResponse shardResponse : sreq.responses) {</span>
<span class="fc" id="L500">              NamedList&lt;Object&gt; response = shardResponse.getSolrResponse()</span>
<span class="fc" id="L501">                  .getResponse();</span>
              try {
<span class="fc" id="L503">                ArrayList&lt;NamedList&lt;Object&gt;&gt; data = (ArrayList&lt;NamedList&lt;Object&gt;&gt;) response</span>
<span class="fc" id="L504">                    .findRecursive(&quot;mtas&quot;, &quot;termvector&quot;);</span>
<span class="pc bpc" id="L505" title="1 of 2 branches missed.">                if (data != null) {</span>
<span class="fc" id="L506">                  MtasSolrResultUtil.decode(data);</span>
                }
<span class="nc" id="L508">              } catch (ClassCastException e) {</span>
<span class="nc" id="L509">                log.debug(e);</span>
                // shouldnt happen
<span class="fc" id="L511">              }</span>
<span class="fc" id="L512">            }</span>
          }
<span class="fc" id="L514">        }</span>
<span class="fc bfc" id="L515" title="All 2 branches covered.">        if (rb.stage == MtasSolrSearchComponent.STAGE_TERMVECTOR_FINISH) {</span>
<span class="pc bpc" id="L516" title="1 of 2 branches missed.">          if (rb.req.getParams().getBool(MtasSolrSearchComponent.PARAM_MTAS,</span>
              false)
<span class="pc bpc" id="L518" title="1 of 2 branches missed.">              &amp;&amp; rb.req.getParams().getBool(PARAM_MTAS_TERMVECTOR, false)) {</span>
<span class="fc" id="L519">            Set&lt;String&gt; ids = MtasSolrResultUtil.getIdsFromParameters(</span>
<span class="fc" id="L520">                rb.req.getParams(), PARAM_MTAS_TERMVECTOR);</span>
<span class="pc bpc" id="L521" title="1 of 2 branches missed.">            if (!ids.isEmpty()) {</span>
<span class="fc" id="L522">              int tmpCounter = 0;</span>
<span class="fc" id="L523">              String[] keys = new String[ids.size()];</span>
<span class="fc" id="L524">              String[] numbers = new String[ids.size()];</span>
<span class="fc bfc" id="L525" title="All 2 branches covered.">              for (String id : ids) {</span>
<span class="fc" id="L526">                keys[tmpCounter] = rb.req.getParams()</span>
<span class="fc" id="L527">                    .get(</span>
                        PARAM_MTAS_TERMVECTOR + &quot;.&quot; + id + &quot;.&quot;
                            + NAME_MTAS_TERMVECTOR_KEY,
<span class="fc" id="L530">                        String.valueOf(tmpCounter))</span>
<span class="fc" id="L531">                    .trim();</span>
<span class="fc" id="L532">                numbers[tmpCounter] = rb.req.getParams()</span>
<span class="fc" id="L533">                    .get(PARAM_MTAS_TERMVECTOR + &quot;.&quot; + id + &quot;.&quot;</span>
                        + NAME_MTAS_TERMVECTOR_NUMBER, null);
<span class="fc" id="L535">                tmpCounter++;</span>
<span class="fc" id="L536">              }</span>
              // mtas response
<span class="fc" id="L538">              NamedList&lt;Object&gt; mtasResponse = null;</span>
              try {
<span class="fc" id="L540">                mtasResponse = (NamedList&lt;Object&gt;) rb.rsp.getValues()</span>
<span class="fc" id="L541">                    .get(&quot;mtas&quot;);</span>
<span class="nc" id="L542">              } catch (ClassCastException e) {</span>
<span class="nc" id="L543">                log.debug(e);</span>
<span class="nc" id="L544">                mtasResponse = null;</span>
<span class="fc" id="L545">              }</span>
<span class="pc bpc" id="L546" title="1 of 2 branches missed.">              if (mtasResponse == null) {</span>
<span class="nc" id="L547">                mtasResponse = new SimpleOrderedMap&lt;&gt;();</span>
<span class="nc" id="L548">                rb.rsp.add(&quot;mtas&quot;, mtasResponse);</span>
              }
<span class="fc" id="L550">              Object o = mtasResponse.get(&quot;termvector&quot;);</span>
<span class="pc bpc" id="L551" title="2 of 4 branches missed.">              if (o != null &amp;&amp; o instanceof ArrayList) {</span>
<span class="fc" id="L552">                ArrayList&lt;?&gt; tvList = (ArrayList&lt;?&gt;) o;</span>
<span class="fc bfc" id="L553" title="All 2 branches covered.">                for (int i = 0; i &lt; tmpCounter; i++) {</span>
<span class="fc bfc" id="L554" title="All 2 branches covered.">                  for (int j = 0; j &lt; tvList.size(); j++) {</span>
<span class="fc" id="L555">                    NamedList&lt;Object&gt; item = (NamedList&lt;Object&gt;) tvList.get(j);</span>
                    boolean condition;
<span class="pc bpc" id="L557" title="1 of 2 branches missed.">                    condition = item != null;</span>
<span class="pc bpc" id="L558" title="1 of 2 branches missed.">                    condition &amp;= item.get(&quot;key&quot;) != null;</span>
<span class="fc" id="L559">                    condition &amp;= item.get(&quot;key&quot;) instanceof String;</span>
<span class="pc bpc" id="L560" title="1 of 2 branches missed.">                    condition &amp;= item.get(&quot;list&quot;) != null;</span>
<span class="fc" id="L561">                    condition &amp;= item.get(&quot;list&quot;) instanceof ArrayList;</span>
<span class="pc bpc" id="L562" title="1 of 2 branches missed.">                    if (condition) {</span>
<span class="fc" id="L563">                      String key = (String) item.get(&quot;key&quot;);</span>
<span class="fc" id="L564">                      ArrayList&lt;Object&gt; list = (ArrayList&lt;Object&gt;) item</span>
<span class="fc" id="L565">                          .get(&quot;list&quot;);</span>
<span class="pc bpc" id="L566" title="1 of 2 branches missed.">                      if (key.equals(keys[i])) {</span>
                        int number;
<span class="pc bpc" id="L568" title="1 of 2 branches missed.">                        if (numbers[i] != null) {</span>
<span class="fc" id="L569">                          int numberValue = Integer.parseInt(numbers[i]);</span>
<span class="fc bfc" id="L570" title="All 2 branches covered.">                          number = numberValue &gt;= 0 ? numberValue</span>
                              : Integer.MAX_VALUE;
<span class="fc" id="L572">                        } else {</span>
<span class="nc" id="L573">                          number = DEFAULT_NUMBER;</span>
                        }
<span class="fc bfc" id="L575" title="All 2 branches covered.">                        if (list.size() &gt; number) {</span>
<span class="fc" id="L576">                          item.removeAll(&quot;list&quot;);</span>
<span class="fc" id="L577">                          item.add(&quot;list&quot;, list.subList(0, number));</span>
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
<span class="fc" id="L589">  }</span>

  /*
   * (non-Javadoc)
   * 
   * @see
   * mtas.solr.handler.component.util.MtasSolrComponent#distributedProcess(org.
   * apache.solr.handler.component.ResponseBuilder,
   * mtas.codec.util.CodecComponent.ComponentFields)
   */
  @Override
  public void distributedProcess(ResponseBuilder rb, ComponentFields mtasFields)
      throws IOException {
<span class="fc bfc" id="L602" title="All 2 branches covered.">    if (rb.stage == MtasSolrSearchComponent.STAGE_TERMVECTOR_MISSING_TOP) {</span>
<span class="fc" id="L603">      distributedProcessMissingTop(rb, mtasFields);</span>
<span class="fc bfc" id="L604" title="All 2 branches covered.">    } else if (rb.stage == MtasSolrSearchComponent.STAGE_TERMVECTOR_MISSING_KEY) {</span>
<span class="fc" id="L605">      distributedProcessMissingKey(rb, mtasFields);</span>
<span class="pc bpc" id="L606" title="1 of 2 branches missed.">    } else if (rb.stage == MtasSolrSearchComponent.STAGE_TERMVECTOR_FINISH) {</span>
<span class="fc" id="L607">      distributedProcessFinish(rb, mtasFields);</span>
    }
<span class="fc" id="L609">  }</span>

  /**
   * Distributed process finish.
   *
   * @param rb the rb
   * @param mtasFields the mtas fields
   * @throws IOException Signals that an I/O exception has occurred.
   */
  private void distributedProcessFinish(ResponseBuilder rb,
      ComponentFields mtasFields) throws IOException {
    // rewrite

    Object mtasResponseRaw;
<span class="pc bpc" id="L623" title="2 of 4 branches missed.">    if ((mtasResponseRaw = rb.rsp.getValues().get(&quot;mtas&quot;)) != null</span>
        &amp;&amp; mtasResponseRaw instanceof NamedList) {
<span class="fc" id="L625">      NamedList&lt;Object&gt; mtasResponse = (NamedList&lt;Object&gt;) mtasResponseRaw;</span>
      Object mtasResponseTermvectorRaw;
<span class="pc bpc" id="L627" title="2 of 4 branches missed.">      if ((mtasResponseTermvectorRaw = mtasResponse.get(&quot;termvector&quot;)) != null</span>
          &amp;&amp; mtasResponseTermvectorRaw instanceof ArrayList) {
<span class="fc" id="L629">        MtasSolrResultUtil.rewrite(</span>
            (ArrayList&lt;Object&gt;) mtasResponseTermvectorRaw, searchComponent);
      }
    }
<span class="fc" id="L633">  }</span>

  /**
   * Distributed process missing top.
   *
   * @param rb the rb
   * @param mtasFields the mtas fields
   * @throws IOException Signals that an I/O exception has occurred.
   */
  private void distributedProcessMissingTop(ResponseBuilder rb,
      ComponentFields mtasFields) throws IOException {
    // initialise
<span class="fc" id="L645">    Map&lt;String, SortedMap&lt;String, MtasDataItemNumberComparator&gt;&gt; mergedComparatorLists = new HashMap&lt;&gt;();</span>
<span class="fc" id="L646">    Map&lt;String, MtasDataItemNumberComparator&gt; mergedComparatorBoundaryList = new HashMap&lt;&gt;();</span>
<span class="fc" id="L647">    Map&lt;String, MtasDataItemNumberComparator&gt; summedComparatorBoundaryList = new HashMap&lt;&gt;();</span>
<span class="fc" id="L648">    Map&lt;String, Map&lt;String, MtasDataItemNumberComparator&gt;&gt; comparatorBoundariesList = new HashMap&lt;&gt;();</span>
    // check all termvectors, and initialize
<span class="fc bfc" id="L650" title="All 2 branches covered.">    for (String field : mtasFields.list.keySet()) {</span>
<span class="fc" id="L651">      List&lt;ComponentTermVector&gt; tvList = mtasFields.list</span>
<span class="fc" id="L652">          .get(field).termVectorList;</span>
<span class="pc bpc" id="L653" title="1 of 2 branches missed.">      if (tvList != null) {</span>
<span class="fc bfc" id="L654" title="All 2 branches covered.">        for (ComponentTermVector tv : tvList) {</span>
<span class="fc bfc" id="L655" title="All 2 branches covered.">          if (!tv.subComponentFunction.sortType.equals(CodecUtil.SORT_TERM)) {</span>
<span class="fc" id="L656">            mergedComparatorLists.put(tv.key,</span>
                new TreeMap&lt;String, MtasDataItemNumberComparator&gt;());
          }
<span class="fc" id="L659">        }</span>
      }
<span class="fc" id="L661">    }</span>
    // compute for each termvector the mergedComparatorList and the
    // summedBoundary
<span class="fc bfc" id="L664" title="All 2 branches covered.">    for (ShardRequest sreq : rb.finished) {</span>
<span class="pc bpc" id="L665" title="1 of 2 branches missed.">      if (sreq.params.getBool(MtasSolrSearchComponent.PARAM_MTAS, false)</span>
<span class="pc bpc" id="L666" title="1 of 2 branches missed.">          &amp;&amp; sreq.params.getBool(PARAM_MTAS_TERMVECTOR, false)) {</span>
<span class="fc bfc" id="L667" title="All 2 branches covered.">        for (ShardResponse shardResponse : sreq.responses) {</span>
          SortedMap&lt;String, MtasDataItemNumberComparator&gt; mergedComparatorList;
<span class="fc" id="L669">          NamedList&lt;Object&gt; response = shardResponse.getSolrResponse()</span>
<span class="fc" id="L670">              .getResponse();</span>
          String key;
          MtasSolrMtasResult list;
          MtasDataItemNumberComparator comparatorLast;
          Map&lt;String, MtasDataItemNumberComparator&gt; comparatorList;
          try {
<span class="fc" id="L676">            List&lt;NamedList&lt;Object&gt;&gt; data = (List&lt;NamedList&lt;Object&gt;&gt;) response</span>
<span class="fc" id="L677">                .findRecursive(&quot;mtas&quot;, &quot;termvector&quot;);</span>
<span class="pc bpc" id="L678" title="1 of 2 branches missed.">            if (data != null) {</span>
<span class="fc bfc" id="L679" title="All 2 branches covered.">              for (int i = 0; i &lt; data.size(); i++) {</span>
<span class="fc" id="L680">                NamedList&lt;Object&gt; dataItem = data.get(i);</span>
                try {
<span class="fc" id="L682">                  key = (String) dataItem.get(&quot;key&quot;);</span>
<span class="fc" id="L683">                  list = (MtasSolrMtasResult) dataItem.get(&quot;list&quot;);</span>
<span class="pc bpc" id="L684" title="1 of 2 branches missed.">                  if (list != null) {</span>
<span class="fc" id="L685">                    comparatorLast = list.getResult().getLastSortValue();</span>
<span class="fc" id="L686">                    comparatorList = list.getResult().getComparatorList();</span>
<span class="pc bpc" id="L687" title="1 of 2 branches missed.">                    if (key == null) {</span>
<span class="nc" id="L688">                      dataItem.clear();</span>
<span class="pc bpc" id="L689" title="1 of 4 branches missed.">                    } else if (comparatorLast == null || comparatorList == null</span>
<span class="pc bpc" id="L690" title="1 of 2 branches missed.">                        || !mergedComparatorLists.containsKey(key)) {</span>
                      // do nothing
                    } else {
<span class="fc" id="L693">                      mergedComparatorList = mergedComparatorLists.get(key);</span>
<span class="fc bfc" id="L694" title="All 2 branches covered.">                      for (Entry&lt;String, MtasDataItemNumberComparator&gt; entry : comparatorList</span>
<span class="fc" id="L695">                          .entrySet()) {</span>
<span class="fc bfc" id="L696" title="All 2 branches covered.">                        if (mergedComparatorList.containsKey(entry.getKey())) {</span>
<span class="fc" id="L697">                          mergedComparatorList.get(entry.getKey())</span>
<span class="fc" id="L698">                              .add(entry.getValue().getValue());</span>
                        } else {
<span class="fc" id="L700">                          mergedComparatorList.put(entry.getKey(),</span>
<span class="fc" id="L701">                              entry.getValue().clone());</span>
                        }
<span class="fc" id="L703">                      }</span>
<span class="fc bfc" id="L704" title="All 2 branches covered.">                      if (!comparatorBoundariesList.containsKey(key)) {</span>
<span class="fc" id="L705">                        comparatorBoundariesList.put(key,</span>
                            new HashMap&lt;String, MtasDataItemNumberComparator&gt;());
                      }
<span class="fc" id="L708">                      comparatorBoundariesList.get(key)</span>
<span class="fc" id="L709">                          .put(shardResponse.getShardAddress(), comparatorLast);</span>
<span class="fc bfc" id="L710" title="All 2 branches covered.">                      if (summedComparatorBoundaryList.containsKey(key)) {</span>
<span class="fc" id="L711">                        summedComparatorBoundaryList.get(key)</span>
<span class="fc" id="L712">                            .add(comparatorLast.getValue());</span>
                      } else {
<span class="fc" id="L714">                        summedComparatorBoundaryList.put(key,</span>
<span class="fc" id="L715">                            comparatorLast.clone());</span>
                      }
                    }
                  } else {
<span class="nc" id="L719">                    throw new IOException(&quot;no data returned&quot;);</span>
                  }
<span class="nc" id="L721">                } catch (ClassCastException e) {</span>
<span class="nc" id="L722">                  log.debug(e);</span>
<span class="nc" id="L723">                  dataItem.clear();</span>
<span class="fc" id="L724">                }</span>
              }
            }
<span class="nc" id="L727">          } catch (ClassCastException e) {</span>
<span class="nc" id="L728">            log.debug(e);</span>
            // shouldnt happen
<span class="fc" id="L730">          }</span>
<span class="fc" id="L731">          shardResponse.getSolrResponse().setResponse(response);</span>
<span class="fc" id="L732">        }</span>
      }
<span class="fc" id="L734">    }</span>
    // compute for each relevant termvector the mergedComparatorBoundary
<span class="fc" id="L736">    HashMap&lt;String, HashMap&lt;String, HashMap&lt;String, MtasDataItemNumberComparator&gt;&gt;&gt; recomputeFieldList = new HashMap&lt;&gt;();</span>
<span class="fc bfc" id="L737" title="All 2 branches covered.">    for (String field : mtasFields.list.keySet()) {</span>
<span class="fc" id="L738">      List&lt;ComponentTermVector&gt; tvList = mtasFields.list</span>
<span class="fc" id="L739">          .get(field).termVectorList;</span>
<span class="pc bpc" id="L740" title="1 of 2 branches missed.">      if (tvList != null) {</span>
<span class="fc bfc" id="L741" title="All 2 branches covered.">        for (ComponentTermVector tv : tvList) {</span>
          SortedMap&lt;String, MtasDataItemNumberComparator&gt; mergedComparatorList;
<span class="fc bfc" id="L743" title="All 2 branches covered.">          if (mergedComparatorLists.containsKey(tv.key)) {</span>
<span class="fc" id="L744">            mergedComparatorList = mergedComparatorLists.get(tv.key);</span>
<span class="pc bpc" id="L745" title="2 of 4 branches missed.">            if (mergedComparatorList.size() &lt; tv.number || tv.number &lt;= 0) {</span>
              // do nothing
            } else {
<span class="fc" id="L748">              final int sortDirection = tv.subComponentFunction.sortDirection</span>
<span class="fc bfc" id="L749" title="All 2 branches covered.">                  .equals(CodecUtil.SORT_DESC) ? -1 : 1;</span>
<span class="fc" id="L750">              SortedSet&lt;Map.Entry&lt;String, MtasDataItemNumberComparator&gt;&gt; sortedSet = new TreeSet&lt;&gt;(</span>
                  (Map.Entry&lt;String, MtasDataItemNumberComparator&gt; e1,
<span class="fc" id="L752">                      Map.Entry&lt;String, MtasDataItemNumberComparator&gt; e2) -&gt; (e1</span>
<span class="fc bfc" id="L753" title="All 2 branches covered.">                          .getValue().compareTo(e2.getValue().getValue()) == 0)</span>
<span class="fc" id="L754">                              ? e1.getKey().compareTo(e2.getKey())</span>
<span class="fc" id="L755">                              : e1.getValue().compareTo(</span>
<span class="fc" id="L756">                                  e2.getValue().getValue()) * sortDirection);</span>
<span class="fc" id="L757">              sortedSet.addAll(mergedComparatorLists.get(tv.key).entrySet());</span>
<span class="fc" id="L758">              Optional&lt;Map.Entry&lt;String, MtasDataItemNumberComparator&gt;&gt; optionalItem = sortedSet</span>
<span class="fc" id="L759">                  .stream().skip(tv.number - 1L).findFirst();</span>
<span class="pc bpc" id="L760" title="1 of 2 branches missed.">              if (optionalItem.isPresent()) {</span>
<span class="fc" id="L761">                mergedComparatorBoundaryList.put(tv.key,</span>
<span class="fc" id="L762">                    optionalItem.get().getValue());</span>
              }
            }
          }
<span class="fc" id="L766">        }</span>
      }
<span class="fc" id="L768">      HashMap&lt;String, HashMap&lt;String, MtasDataItemNumberComparator&gt;&gt; recomputeList = new HashMap&lt;&gt;();</span>
<span class="pc bpc" id="L769" title="1 of 2 branches missed.">      if (tvList != null) {</span>
<span class="fc bfc" id="L770" title="All 2 branches covered.">        for (ComponentTermVector tv : tvList) {</span>
<span class="fc" id="L771">          String key = tv.key;</span>
<span class="fc bfc" id="L772" title="All 2 branches covered.">          if (mergedComparatorBoundaryList.containsKey(key)</span>
<span class="pc bpc" id="L773" title="1 of 2 branches missed.">              &amp;&amp; summedComparatorBoundaryList.containsKey(key)) {</span>
            // set termvector to recompute
<span class="fc" id="L775">            recomputeList.put(key,</span>
                new HashMap&lt;String, MtasDataItemNumberComparator&gt;());
            // sort
<span class="fc" id="L778">            List&lt;Entry&lt;String, MtasDataItemNumberComparator&gt;&gt; list = new LinkedList&lt;&gt;(</span>
<span class="fc" id="L779">                comparatorBoundariesList.get(key).entrySet());</span>
<span class="fc" id="L780">            Collections.sort(list,</span>
                (Entry&lt;String, MtasDataItemNumberComparator&gt; e1,
                    Entry&lt;String, MtasDataItemNumberComparator&gt; e2) -&gt; e1
<span class="fc" id="L783">                        .getValue().compareTo(e2.getValue().getValue()));</span>
<span class="fc" id="L784">            HashMap&lt;String, MtasDataItemNumberComparator&gt; sortedHashMap = new LinkedHashMap&lt;&gt;();</span>
<span class="fc" id="L785">            for (Iterator&lt;Map.Entry&lt;String, MtasDataItemNumberComparator&gt;&gt; it = list</span>
<span class="fc bfc" id="L786" title="All 2 branches covered.">                .iterator(); it.hasNext();) {</span>
<span class="fc" id="L787">              Map.Entry&lt;String, MtasDataItemNumberComparator&gt; entry = it.next();</span>
<span class="fc" id="L788">              sortedHashMap.put(entry.getKey(), entry.getValue());</span>
<span class="fc" id="L789">            }</span>

<span class="fc" id="L791">            MtasDataItemNumberComparator mainNewBoundary = mergedComparatorBoundaryList</span>
<span class="fc" id="L792">                .get(key).recomputeBoundary(sortedHashMap.size());</span>
            // System.out.println(
            // &quot;MAIN NEW BOUNDARY for '&quot; + key + &quot;' : &quot; + mainNewBoundary);

<span class="fc" id="L796">            MtasDataItemNumberComparator sum = null;</span>
<span class="fc" id="L797">            int number = 0;</span>
<span class="fc bfc" id="L798" title="All 2 branches covered.">            for (Entry&lt;String, MtasDataItemNumberComparator&gt; entry : sortedHashMap</span>
<span class="fc" id="L799">                .entrySet()) {</span>
<span class="fc" id="L800">              MtasDataItemNumberComparator newBoundary = mainNewBoundary</span>
<span class="fc" id="L801">                  .clone();</span>
<span class="fc" id="L802">              MtasDataItemNumberComparator currentBoundary = entry.getValue();</span>
<span class="fc" id="L803">              int compare = currentBoundary.compareTo(newBoundary.getValue());</span>
<span class="fc" id="L804">              if (tv.subComponentFunction.sortDirection</span>
<span class="fc bfc" id="L805" title="All 2 branches covered.">                  .equals(CodecUtil.SORT_DESC)) {</span>
<span class="fc" id="L806">                compare *= -1;</span>
              }
<span class="pc bpc" id="L808" title="1 of 2 branches missed.">              if (compare &lt; 0) {</span>
<span class="nc" id="L809">                HashMap&lt;String, MtasDataItemNumberComparator&gt; recomputeSubList = new HashMap&lt;&gt;();</span>
                // sum not null if number&gt;0, but do check
<span class="nc bnc" id="L811" title="All 4 branches missed.">                if (number &gt; 0 &amp;&amp; sum != null</span>
                    &amp;&amp; tv.subComponentFunction.sortDirection
<span class="nc bnc" id="L813" title="All 2 branches missed.">                        .equals(CodecUtil.SORT_DESC)) {</span>
<span class="nc" id="L814">                  MtasDataItemNumberComparator tmpSumBoundary = mergedComparatorBoundaryList</span>
<span class="nc" id="L815">                      .get(key);</span>
<span class="nc" id="L816">                  tmpSumBoundary.subtract(sum.getValue());</span>
<span class="nc" id="L817">                  MtasDataItemNumberComparator alternativeNewBoundary = tmpSumBoundary</span>
<span class="nc" id="L818">                      .recomputeBoundary(sortedHashMap.size() - number);</span>
<span class="nc" id="L819">                  compare = newBoundary</span>
<span class="nc" id="L820">                      .compareTo(alternativeNewBoundary.getValue());</span>
<span class="nc bnc" id="L821" title="All 2 branches missed.">                  if (compare &lt; 0) {</span>
<span class="nc" id="L822">                    newBoundary = alternativeNewBoundary;</span>
<span class="nc" id="L823">                    compare = currentBoundary.compareTo(newBoundary.getValue());</span>
<span class="nc" id="L824">                    if (tv.subComponentFunction.sortDirection</span>
<span class="nc bnc" id="L825" title="All 2 branches missed.">                        .equals(CodecUtil.SORT_DESC)) {</span>
<span class="nc" id="L826">                      compare *= -1;</span>
                    }
<span class="nc bnc" id="L828" title="All 2 branches missed.">                    if (compare &lt; 0) {</span>
<span class="nc" id="L829">                      recomputeSubList.put(entry.getKey(), newBoundary);</span>
                    }
                  } else {
<span class="nc" id="L832">                    recomputeSubList.put(entry.getKey(), newBoundary);</span>
                  }
<span class="nc" id="L834">                } else {</span>
<span class="nc" id="L835">                  recomputeSubList.put(entry.getKey(), newBoundary);</span>
                }
<span class="nc bnc" id="L837" title="All 2 branches missed.">                if (!recomputeSubList.isEmpty()) {</span>
<span class="nc bnc" id="L838" title="All 2 branches missed.">                  if (!recomputeList.containsKey(key)) {</span>
<span class="nc" id="L839">                    recomputeList.put(key, recomputeSubList);</span>
                  } else {
<span class="nc" id="L841">                    recomputeList.get(key).putAll(recomputeSubList);</span>
                  }
                }
<span class="nc" id="L844">              } else {</span>
<span class="fc" id="L845">                newBoundary = currentBoundary.clone();</span>
              }
<span class="fc bfc" id="L847" title="All 2 branches covered.">              if (sum == null) {</span>
<span class="fc" id="L848">                sum = newBoundary.clone();</span>
              } else {
<span class="fc" id="L850">                sum.add(newBoundary.getValue());</span>
              }
<span class="fc" id="L852">              number++;</span>
<span class="fc" id="L853">            }</span>
          }
<span class="fc" id="L855">        }</span>
      }
<span class="fc bfc" id="L857" title="All 2 branches covered.">      if (!recomputeList.isEmpty()) {</span>
<span class="fc" id="L858">        recomputeFieldList.put(field, recomputeList);</span>
      }
<span class="fc" id="L860">    }</span>

    // finally, recompute
<span class="fc bfc" id="L863" title="All 2 branches covered.">    if (recomputeFieldList.size() &gt; 0) {</span>

      // remove output for termvectors in recompute list and get list of shards
<span class="fc" id="L866">      HashSet&lt;String&gt; shards = new HashSet&lt;&gt;();</span>
<span class="fc bfc" id="L867" title="All 2 branches covered.">      for (ShardRequest sreq : rb.finished) {</span>
<span class="pc bpc" id="L868" title="1 of 2 branches missed.">        if (sreq.params.getBool(MtasSolrSearchComponent.PARAM_MTAS, false)</span>
<span class="pc bpc" id="L869" title="1 of 2 branches missed.">            &amp;&amp; sreq.params.getBool(PARAM_MTAS_TERMVECTOR, false)) {</span>
<span class="fc bfc" id="L870" title="All 2 branches covered.">          for (ShardResponse shardResponse : sreq.responses) {</span>
<span class="fc" id="L871">            NamedList&lt;Object&gt; response = shardResponse.getSolrResponse()</span>
<span class="fc" id="L872">                .getResponse();</span>
            String key;
            String field;
<span class="fc" id="L875">            String shardAddress = shardResponse.getShardAddress();</span>
            try {
<span class="fc" id="L877">              ArrayList&lt;NamedList&lt;Object&gt;&gt; data = (ArrayList&lt;NamedList&lt;Object&gt;&gt;) response</span>
<span class="fc" id="L878">                  .findRecursive(&quot;mtas&quot;, &quot;termvector&quot;);</span>
<span class="fc" id="L879">              shards.add(shardAddress);</span>
<span class="pc bpc" id="L880" title="1 of 2 branches missed.">              if (data != null) {</span>
<span class="fc bfc" id="L881" title="All 2 branches covered.">                for (int i = 0; i &lt; data.size(); i++) {</span>
<span class="fc" id="L882">                  NamedList&lt;Object&gt; dataItem = data.get(i);</span>
                  try {
<span class="fc" id="L884">                    key = (String) dataItem.get(&quot;key&quot;);</span>
<span class="fc" id="L885">                    field = (String) dataItem.get(&quot;field&quot;);</span>
                    boolean doClear;
<span class="pc bpc" id="L887" title="3 of 4 branches missed.">                    doClear = field != null &amp;&amp; key != null;</span>
<span class="pc bpc" id="L888" title="3 of 4 branches missed.">                    doClear = doClear ? recomputeFieldList.get(field) != null</span>
                        : false;
<span class="pc bpc" id="L890" title="1 of 2 branches missed.">                    doClear = doClear</span>
<span class="pc" id="L891">                        ? recomputeFieldList.get(field).containsKey(key)</span>
                        : false;
<span class="pc bpc" id="L893" title="1 of 2 branches missed.">                    doClear = doClear ? recomputeFieldList.get(field).get(key)</span>
<span class="pc" id="L894">                        .containsKey(shardAddress) : false;</span>
<span class="pc bpc" id="L895" title="1 of 2 branches missed.">                    if (doClear) {</span>
<span class="nc" id="L896">                      dataItem.clear();</span>
<span class="nc" id="L897">                      dataItem.add(&quot;key&quot;, key);</span>
                    }
<span class="nc" id="L899">                  } catch (ClassCastException e) {</span>
<span class="nc" id="L900">                    log.debug(e);</span>
<span class="nc" id="L901">                    dataItem.clear();</span>
<span class="fc" id="L902">                  }</span>
                }
              }
<span class="nc" id="L905">            } catch (ClassCastException e) {</span>
<span class="nc" id="L906">              log.debug(e);</span>
              // shouldnt happen
<span class="fc" id="L908">            }</span>
<span class="fc" id="L909">            shardResponse.getSolrResponse().setResponse(response);</span>
<span class="fc" id="L910">          }</span>
        }
<span class="fc" id="L912">      }</span>

      // parameter
<span class="fc" id="L915">      HashMap&lt;String, ModifiableSolrParams&gt; requestParamList = new HashMap&lt;&gt;();</span>
<span class="fc bfc" id="L916" title="All 2 branches covered.">      for (String shardAddress : shards) {</span>
<span class="fc" id="L917">        ModifiableSolrParams paramsNewRequest = new ModifiableSolrParams();</span>
<span class="fc" id="L918">        int termvectorCounter = 0;</span>
<span class="fc bfc" id="L919" title="All 2 branches covered.">        for (String field : mtasFields.list.keySet()) {</span>
<span class="fc" id="L920">          List&lt;ComponentTermVector&gt; tvList = mtasFields.list</span>
<span class="fc" id="L921">              .get(field).termVectorList;</span>
<span class="pc bpc" id="L922" title="1 of 2 branches missed.">          if (recomputeFieldList.containsKey(field)) {</span>
<span class="fc" id="L923">            HashMap&lt;String, HashMap&lt;String, MtasDataItemNumberComparator&gt;&gt; recomputeList = recomputeFieldList</span>
<span class="fc" id="L924">                .get(field);</span>
<span class="pc bpc" id="L925" title="1 of 2 branches missed.">            if (tvList != null) {</span>
<span class="fc bfc" id="L926" title="All 2 branches covered.">              for (ComponentTermVector tv : tvList) {</span>
<span class="pc bpc" id="L927" title="1 of 2 branches missed.">                if (recomputeList.containsKey(tv.key)</span>
<span class="pc bpc" id="L928" title="1 of 2 branches missed.">                    &amp;&amp; recomputeList.get(tv.key).containsKey(shardAddress)) {</span>
<span class="nc" id="L929">                  paramsNewRequest.add(</span>
                      PARAM_MTAS_TERMVECTOR + &quot;.&quot; + termvectorCounter + &quot;.&quot;
                          + NAME_MTAS_TERMVECTOR_BOUNDARY,
<span class="nc" id="L932">                      String.valueOf(recomputeList.get(tv.key).get(shardAddress)</span>
<span class="nc" id="L933">                          .getValue()));</span>
<span class="nc" id="L934">                  paramsNewRequest.add(PARAM_MTAS_TERMVECTOR + &quot;.&quot;</span>
                      + termvectorCounter + &quot;.&quot; + NAME_MTAS_TERMVECTOR_FIELD,
                      field);
<span class="nc" id="L937">                  paramsNewRequest.add(PARAM_MTAS_TERMVECTOR + &quot;.&quot;</span>
                      + termvectorCounter + &quot;.&quot; + NAME_MTAS_TERMVECTOR_PREFIX,
                      tv.prefix);
<span class="nc" id="L940">                  paramsNewRequest.add(PARAM_MTAS_TERMVECTOR + &quot;.&quot;</span>
                      + termvectorCounter + &quot;.&quot; + NAME_MTAS_TERMVECTOR_KEY,
                      tv.key);
<span class="nc" id="L943">                  paramsNewRequest.add(</span>
                      PARAM_MTAS_TERMVECTOR + &quot;.&quot; + termvectorCounter + &quot;.&quot;
                          + NAME_MTAS_TERMVECTOR_NUMBER,
<span class="nc" id="L946">                      String.valueOf(tv.number));</span>
<span class="nc bnc" id="L947" title="All 2 branches missed.">                  if (tv.subComponentFunction.sortType != null) {</span>
<span class="nc" id="L948">                    paramsNewRequest.add(</span>
                        PARAM_MTAS_TERMVECTOR + &quot;.&quot; + termvectorCounter + &quot;.&quot;
                            + NAME_MTAS_TERMVECTOR_SORT_TYPE,
                        tv.subComponentFunction.sortType);
                  }
<span class="nc bnc" id="L953" title="All 2 branches missed.">                  if (tv.subComponentFunction.sortDirection != null) {</span>
<span class="nc" id="L954">                    paramsNewRequest.add(</span>
                        PARAM_MTAS_TERMVECTOR + &quot;.&quot; + termvectorCounter + &quot;.&quot;
                            + NAME_MTAS_TERMVECTOR_SORT_DIRECTION,
                        tv.subComponentFunction.sortDirection);
                  }
<span class="nc bnc" id="L959" title="All 2 branches missed.">                  if (tv.subComponentFunction.type != null) {</span>
<span class="nc" id="L960">                    paramsNewRequest.add(</span>
                        PARAM_MTAS_TERMVECTOR + &quot;.&quot; + termvectorCounter + &quot;.&quot;
                            + NAME_MTAS_TERMVECTOR_TYPE,
                        tv.subComponentFunction.type);
                  }
<span class="nc bnc" id="L965" title="All 2 branches missed.">                  if (tv.functions != null) {</span>
<span class="nc" id="L966">                    int functionCounter = 0;</span>
<span class="nc bnc" id="L967" title="All 2 branches missed.">                    for (SubComponentFunction function : tv.functions) {</span>
<span class="nc" id="L968">                      paramsNewRequest.add(</span>
                          PARAM_MTAS_TERMVECTOR + &quot;.&quot; + termvectorCounter + &quot;.&quot;
                              + NAME_MTAS_TERMVECTOR_FUNCTION + &quot;.&quot;
                              + functionCounter + &quot;.&quot;
                              + NAME_MTAS_TERMVECTOR_FUNCTION_EXPRESSION,
                          function.expression);
<span class="nc" id="L974">                      paramsNewRequest.add(</span>
                          PARAM_MTAS_TERMVECTOR + &quot;.&quot; + termvectorCounter + &quot;.&quot;
                              + NAME_MTAS_TERMVECTOR_FUNCTION + &quot;.&quot;
                              + functionCounter + &quot;.&quot;
                              + NAME_MTAS_TERMVECTOR_FUNCTION_KEY,
                          function.key);
<span class="nc bnc" id="L980" title="All 2 branches missed.">                      if (function.type != null) {</span>
<span class="nc" id="L981">                        paramsNewRequest.add(</span>
                            PARAM_MTAS_TERMVECTOR + &quot;.&quot; + termvectorCounter
                                + &quot;.&quot; + NAME_MTAS_TERMVECTOR_FUNCTION + &quot;.&quot;
                                + functionCounter + &quot;.&quot;
                                + NAME_MTAS_TERMVECTOR_FUNCTION_TYPE,
                            function.type);
                      }
<span class="nc" id="L988">                      functionCounter++;</span>
<span class="nc" id="L989">                    }</span>
                  }
<span class="nc bnc" id="L991" title="All 2 branches missed.">                  if (tv.regexp != null) {</span>
<span class="nc" id="L992">                    paramsNewRequest.add(PARAM_MTAS_TERMVECTOR + &quot;.&quot;</span>
                        + termvectorCounter + &quot;.&quot; + NAME_MTAS_TERMVECTOR_REGEXP,
                        tv.regexp);
                  }
<span class="nc" id="L996">                  termvectorCounter++;</span>
                }
<span class="fc" id="L998">              }</span>
            }
          }
<span class="fc" id="L1001">        }</span>
<span class="pc bpc" id="L1002" title="1 of 2 branches missed.">        if (!paramsNewRequest.getParameterNames().isEmpty()) {</span>
<span class="nc" id="L1003">          requestParamList.put(shardAddress, paramsNewRequest);</span>
        }
<span class="fc" id="L1005">      }</span>

      // new requests
<span class="pc bpc" id="L1008" title="1 of 2 branches missed.">      for (Entry&lt;String, ModifiableSolrParams&gt; entry : requestParamList</span>
<span class="fc" id="L1009">          .entrySet()) {</span>
<span class="nc" id="L1010">        ShardRequest sreq = new ShardRequest();</span>
<span class="nc" id="L1011">        sreq.shards = new String[] { entry.getKey() };</span>
<span class="nc" id="L1012">        sreq.purpose = ShardRequest.PURPOSE_PRIVATE;</span>
<span class="nc" id="L1013">        sreq.params = entry.getValue();</span>
<span class="nc" id="L1014">        sreq.params.add(&quot;fq&quot;, rb.req.getParams().getParams(&quot;fq&quot;));</span>
<span class="nc" id="L1015">        sreq.params.add(&quot;q&quot;, rb.req.getParams().getParams(&quot;q&quot;));</span>
<span class="nc" id="L1016">        sreq.params.add(&quot;cache&quot;, rb.req.getParams().getParams(&quot;cache&quot;));</span>
<span class="nc" id="L1017">        sreq.params.add(&quot;rows&quot;, &quot;0&quot;);</span>
<span class="nc" id="L1018">        sreq.params.add(MtasSolrSearchComponent.PARAM_MTAS, rb.req</span>
<span class="nc" id="L1019">            .getOriginalParams().getParams(MtasSolrSearchComponent.PARAM_MTAS));</span>
<span class="nc" id="L1020">        sreq.params.add(PARAM_MTAS_TERMVECTOR,</span>
<span class="nc" id="L1021">            rb.req.getOriginalParams().getParams(PARAM_MTAS_TERMVECTOR));</span>
<span class="nc" id="L1022">        rb.addRequest(searchComponent, sreq);</span>
<span class="nc" id="L1023">      }</span>
    }

<span class="fc" id="L1026">  }</span>

  /**
   * Distributed process missing key.
   *
   * @param rb the rb
   * @param mtasFields the mtas fields
   * @throws IOException Signals that an I/O exception has occurred.
   */
  private void distributedProcessMissingKey(ResponseBuilder rb,
      ComponentFields mtasFields) throws IOException {
<span class="fc" id="L1037">    HashMap&lt;String, HashMap&lt;String, HashSet&lt;String&gt;&gt;&gt; missingTermvectorKeys = computeMissingTermvectorItemsPerShard(</span>
        rb.finished, &quot;mtas&quot;, &quot;termvector&quot;);
<span class="fc bfc" id="L1039" title="All 2 branches covered.">    for (Entry&lt;String, HashMap&lt;String, HashSet&lt;String&gt;&gt;&gt; entry : missingTermvectorKeys</span>
<span class="fc" id="L1040">        .entrySet()) {</span>
<span class="fc" id="L1041">      HashMap&lt;String, HashSet&lt;String&gt;&gt; missingTermvectorKeysShard = entry</span>
<span class="fc" id="L1042">          .getValue();</span>
<span class="fc" id="L1043">      ModifiableSolrParams paramsNewRequest = new ModifiableSolrParams();</span>
<span class="fc" id="L1044">      int termvectorCounter = 0;</span>
<span class="fc bfc" id="L1045" title="All 2 branches covered.">      for (String field : mtasFields.list.keySet()) {</span>
<span class="fc" id="L1046">        List&lt;ComponentTermVector&gt; tvList = mtasFields.list</span>
<span class="fc" id="L1047">            .get(field).termVectorList;</span>
<span class="pc bpc" id="L1048" title="1 of 2 branches missed.">        if (tvList != null) {</span>
<span class="fc bfc" id="L1049" title="All 2 branches covered.">          for (ComponentTermVector tv : tvList) {</span>
<span class="fc bfc" id="L1050" title="All 2 branches covered.">            if (!tv.full) {</span>
<span class="pc bpc" id="L1051" title="1 of 2 branches missed.">              if (missingTermvectorKeysShard.containsKey(tv.key)) {</span>
<span class="fc" id="L1052">                HashSet&lt;String&gt; list = missingTermvectorKeysShard.get(tv.key);</span>
<span class="fc bfc" id="L1053" title="All 2 branches covered.">                if (!list.isEmpty()) {</span>
<span class="fc" id="L1054">                  paramsNewRequest.add(PARAM_MTAS_TERMVECTOR + &quot;.&quot;</span>
                      + termvectorCounter + &quot;.&quot; + NAME_MTAS_TERMVECTOR_FIELD,
                      field);
<span class="fc" id="L1057">                  paramsNewRequest.add(PARAM_MTAS_TERMVECTOR + &quot;.&quot;</span>
                      + termvectorCounter + &quot;.&quot; + NAME_MTAS_TERMVECTOR_PREFIX,
                      tv.prefix);
<span class="fc" id="L1060">                  paramsNewRequest.add(PARAM_MTAS_TERMVECTOR + &quot;.&quot;</span>
                      + termvectorCounter + &quot;.&quot; + NAME_MTAS_TERMVECTOR_KEY,
                      tv.key);
<span class="pc bpc" id="L1063" title="1 of 2 branches missed.">                  if (tv.subComponentFunction.type != null) {</span>
<span class="fc" id="L1064">                    paramsNewRequest.add(</span>
                        PARAM_MTAS_TERMVECTOR + &quot;.&quot; + termvectorCounter + &quot;.&quot;
                            + NAME_MTAS_TERMVECTOR_TYPE,
                        tv.subComponentFunction.type);
                  }
<span class="pc bpc" id="L1069" title="1 of 2 branches missed.">                  if (tv.functions != null) {</span>
<span class="fc" id="L1070">                    int functionCounter = 0;</span>
<span class="pc bpc" id="L1071" title="1 of 2 branches missed.">                    for (SubComponentFunction function : tv.functions) {</span>
<span class="nc" id="L1072">                      paramsNewRequest.add(</span>
                          PARAM_MTAS_TERMVECTOR + &quot;.&quot; + termvectorCounter + &quot;.&quot;
                              + NAME_MTAS_TERMVECTOR_FUNCTION + &quot;.&quot;
                              + functionCounter + &quot;.&quot;
                              + NAME_MTAS_TERMVECTOR_FUNCTION_EXPRESSION,
                          function.expression);
<span class="nc" id="L1078">                      paramsNewRequest.add(</span>
                          PARAM_MTAS_TERMVECTOR + &quot;.&quot; + termvectorCounter + &quot;.&quot;
                              + NAME_MTAS_TERMVECTOR_FUNCTION + &quot;.&quot;
                              + functionCounter + &quot;.&quot;
                              + NAME_MTAS_TERMVECTOR_FUNCTION_KEY,
                          function.key);
<span class="nc bnc" id="L1084" title="All 2 branches missed.">                      if (function.type != null) {</span>
<span class="nc" id="L1085">                        paramsNewRequest.add(</span>
                            PARAM_MTAS_TERMVECTOR + &quot;.&quot; + termvectorCounter
                                + &quot;.&quot; + NAME_MTAS_TERMVECTOR_FUNCTION + &quot;.&quot;
                                + functionCounter + &quot;.&quot;
                                + NAME_MTAS_TERMVECTOR_FUNCTION_TYPE,
                            function.type);
                      }
<span class="nc" id="L1092">                      functionCounter++;</span>
<span class="nc" id="L1093">                    }</span>
                  }
<span class="pc bpc" id="L1095" title="1 of 2 branches missed.">                  if (tv.regexp != null) {</span>
<span class="nc" id="L1096">                    paramsNewRequest.add(PARAM_MTAS_TERMVECTOR + &quot;.&quot;</span>
                        + termvectorCounter + &quot;.&quot; + NAME_MTAS_TERMVECTOR_REGEXP,
                        tv.regexp);
                  }
<span class="pc bpc" id="L1100" title="1 of 2 branches missed.">                  if (!list.isEmpty()) {</span>
<span class="fc" id="L1101">                    StringBuilder listValue = new StringBuilder();</span>
<span class="fc" id="L1102">                    String[] listList = list.toArray(new String[list.size()]);</span>
<span class="fc bfc" id="L1103" title="All 2 branches covered.">                    for (int i = 0; i &lt; listList.length; i++) {</span>
<span class="fc bfc" id="L1104" title="All 2 branches covered.">                      if (i &gt; 0) {</span>
<span class="fc" id="L1105">                        listValue.append(&quot;,&quot;);</span>
                      }
<span class="fc" id="L1107">                      listValue.append(listList[i].replace(&quot;\\&quot;, &quot;\\\\&quot;)</span>
<span class="fc" id="L1108">                          .replace(&quot;,&quot;, &quot;\\\\&quot;));</span>
                    }
<span class="fc" id="L1110">                    paramsNewRequest.add(PARAM_MTAS_TERMVECTOR + &quot;.&quot;</span>
                        + termvectorCounter + &quot;.&quot; + NAME_MTAS_TERMVECTOR_FULL,
                        &quot;false&quot;);
<span class="fc" id="L1113">                    paramsNewRequest</span>
<span class="fc" id="L1114">                        .add(</span>
                            PARAM_MTAS_TERMVECTOR + &quot;.&quot; + termvectorCounter
                                + &quot;.&quot; + NAME_MTAS_TERMVECTOR_LIST,
<span class="fc" id="L1117">                            listValue.toString());</span>
                  }
<span class="fc" id="L1119">                  termvectorCounter++;</span>
                }
              }
            }
<span class="fc" id="L1123">          }</span>
<span class="fc bfc" id="L1124" title="All 2 branches covered.">          if (termvectorCounter &gt; 0) {</span>
<span class="fc" id="L1125">            ShardRequest nsreq = new ShardRequest();</span>
<span class="fc" id="L1126">            nsreq.shards = new String[] { entry.getKey() };</span>
<span class="fc" id="L1127">            nsreq.purpose = ShardRequest.PURPOSE_PRIVATE;</span>
<span class="fc" id="L1128">            nsreq.params = new ModifiableSolrParams();</span>
<span class="fc" id="L1129">            nsreq.params.add(&quot;fq&quot;, rb.req.getParams().getParams(&quot;fq&quot;));</span>
<span class="fc" id="L1130">            nsreq.params.add(&quot;q&quot;, rb.req.getParams().getParams(&quot;q&quot;));</span>
<span class="fc" id="L1131">            nsreq.params.add(&quot;cache&quot;, rb.req.getParams().getParams(&quot;cache&quot;));</span>
<span class="fc" id="L1132">            nsreq.params.add(&quot;rows&quot;, &quot;0&quot;);</span>
<span class="fc" id="L1133">            nsreq.params.add(MtasSolrSearchComponent.PARAM_MTAS,</span>
<span class="fc" id="L1134">                rb.req.getOriginalParams()</span>
<span class="fc" id="L1135">                    .getParams(MtasSolrSearchComponent.PARAM_MTAS));</span>
<span class="fc" id="L1136">            nsreq.params.add(PARAM_MTAS_TERMVECTOR,</span>
<span class="fc" id="L1137">                rb.req.getOriginalParams().getParams(PARAM_MTAS_TERMVECTOR));</span>
<span class="fc" id="L1138">            nsreq.params.add(paramsNewRequest);</span>
<span class="fc" id="L1139">            rb.addRequest(searchComponent, nsreq);</span>
          }
        }
<span class="fc" id="L1142">      }</span>
<span class="fc" id="L1143">    }</span>
<span class="fc" id="L1144">  }</span>

  /**
   * Compute missing termvector items per shard.
   *
   * @param requests the requests
   * @param args the args
   * @return the hash map
   * @throws IOException Signals that an I/O exception has occurred.
   */
  @SuppressWarnings(&quot;unchecked&quot;)
  private HashMap&lt;String, HashMap&lt;String, HashSet&lt;String&gt;&gt;&gt; computeMissingTermvectorItemsPerShard(
      List&lt;ShardRequest&gt; requests, String... args) throws IOException {
<span class="fc" id="L1157">    HashMap&lt;String, HashMap&lt;String, HashSet&lt;String&gt;&gt;&gt; result = new HashMap&lt;&gt;();</span>
<span class="fc" id="L1158">    HashMap&lt;String, HashMap&lt;String, HashSet&lt;String&gt;&gt;&gt; itemsPerShardSets = new HashMap&lt;&gt;();</span>
<span class="fc" id="L1159">    HashMap&lt;String, HashSet&lt;String&gt;&gt; itemSets = new HashMap&lt;&gt;();</span>
    // loop over responses different shards
<span class="fc bfc" id="L1161" title="All 2 branches covered.">    for (ShardRequest sreq : requests) {</span>
<span class="pc bpc" id="L1162" title="1 of 2 branches missed.">      if (sreq.params.getBool(MtasSolrSearchComponent.PARAM_MTAS, false)</span>
<span class="pc bpc" id="L1163" title="1 of 2 branches missed.">          &amp;&amp; sreq.params.getBool(PARAM_MTAS_TERMVECTOR, false)) {</span>
<span class="fc bfc" id="L1164" title="All 2 branches covered.">        for (ShardResponse shardResponse : sreq.responses) {</span>
<span class="fc" id="L1165">          NamedList&lt;Object&gt; response = shardResponse.getSolrResponse()</span>
<span class="fc" id="L1166">              .getResponse();</span>
          try {
            // get termvector data
<span class="fc" id="L1169">            ArrayList&lt;NamedList&lt;Object&gt;&gt; data = (ArrayList&lt;NamedList&lt;Object&gt;&gt;) response</span>
<span class="fc" id="L1170">                .findRecursive(args);</span>
<span class="pc bpc" id="L1171" title="1 of 2 branches missed.">            if (data != null) {</span>
              // loop over temvector results
<span class="fc bfc" id="L1173" title="All 2 branches covered.">              for (int i = 0; i &lt; data.size(); i++) {</span>
<span class="fc" id="L1174">                NamedList&lt;Object&gt; dataItem = data.get(i);</span>
                try {
                  // get termvector result
<span class="fc" id="L1177">                  String termvectorKey = (String) dataItem.get(&quot;key&quot;);</span>
<span class="fc" id="L1178">                  MtasSolrMtasResult list = (MtasSolrMtasResult) dataItem</span>
<span class="fc" id="L1179">                      .get(&quot;list&quot;);</span>
<span class="pc bpc" id="L1180" title="2 of 4 branches missed.">                  if (termvectorKey != null &amp;&amp; list != null) {</span>
                    // get keys
<span class="fc" id="L1182">                    Set&lt;String&gt; keyList = list.getKeyList();</span>
                    HashMap&lt;String, HashSet&lt;String&gt;&gt; itemsPerShardSet;
                    HashSet&lt;String&gt; itemSet;
<span class="fc" id="L1185">                    HashSet&lt;String&gt; tmpItemSet = new HashSet&lt;&gt;();</span>
<span class="fc bfc" id="L1186" title="All 2 branches covered.">                    if (itemsPerShardSets.containsKey(termvectorKey)) {</span>
<span class="fc" id="L1187">                      itemsPerShardSet = itemsPerShardSets.get(termvectorKey);</span>
<span class="fc" id="L1188">                      itemSet = itemSets.get(termvectorKey);</span>
                    } else {
<span class="fc" id="L1190">                      itemsPerShardSet = new HashMap&lt;&gt;();</span>
<span class="fc" id="L1191">                      itemSet = new HashSet&lt;&gt;();</span>
<span class="fc" id="L1192">                      itemsPerShardSets.put(termvectorKey, itemsPerShardSet);</span>
<span class="fc" id="L1193">                      itemSets.put(termvectorKey, itemSet);</span>
                    }
<span class="fc" id="L1195">                    itemsPerShardSet.put(shardResponse.getShardAddress(),</span>
                        tmpItemSet);
<span class="fc" id="L1197">                    tmpItemSet.addAll(keyList);</span>
<span class="fc" id="L1198">                    itemSet.addAll(keyList);</span>
                  }
<span class="nc" id="L1200">                } catch (ClassCastException e) {</span>
<span class="nc" id="L1201">                  log.debug(e);</span>
<span class="fc" id="L1202">                }</span>
              }
            }
<span class="nc" id="L1205">          } catch (ClassCastException e) {</span>
<span class="nc" id="L1206">            log.debug(e);</span>
<span class="fc" id="L1207">          }</span>
<span class="fc" id="L1208">        }</span>
      }
<span class="fc" id="L1210">    }</span>

    // construct result
<span class="fc bfc" id="L1213" title="All 2 branches covered.">    for (Entry&lt;String, HashSet&lt;String&gt;&gt; entry : itemSets.entrySet()) {</span>
<span class="fc" id="L1214">      String termvectorKey = entry.getKey();</span>
<span class="fc" id="L1215">      HashSet&lt;String&gt; termvectorKeyList = entry.getValue();</span>
<span class="pc bpc" id="L1216" title="1 of 2 branches missed.">      if (itemsPerShardSets.containsKey(termvectorKey)) {</span>
<span class="fc" id="L1217">        HashMap&lt;String, HashSet&lt;String&gt;&gt; itemsPerShardSet = itemsPerShardSets</span>
<span class="fc" id="L1218">            .get(termvectorKey);</span>
<span class="fc bfc" id="L1219" title="All 2 branches covered.">        for (Entry&lt;String, HashSet&lt;String&gt;&gt; subEntry : itemsPerShardSet</span>
<span class="fc" id="L1220">            .entrySet()) {</span>
<span class="fc" id="L1221">          String shardName = subEntry.getKey();</span>
          HashMap&lt;String, HashSet&lt;String&gt;&gt; tmpShardKeySet;
<span class="pc bpc" id="L1223" title="1 of 2 branches missed.">          if (result.containsKey(shardName)) {</span>
<span class="nc" id="L1224">            tmpShardKeySet = result.get(shardName);</span>
          } else {
<span class="fc" id="L1226">            tmpShardKeySet = new HashMap&lt;&gt;();</span>
<span class="fc" id="L1227">            result.put(shardName, tmpShardKeySet);</span>
          }
<span class="fc" id="L1229">          HashSet&lt;String&gt; tmpResult = new HashSet&lt;&gt;();</span>
<span class="fc" id="L1230">          HashSet&lt;String&gt; shardItemsSet = subEntry.getValue();</span>
<span class="fc bfc" id="L1231" title="All 2 branches covered.">          for (String termvectorKeyListItem : termvectorKeyList) {</span>
<span class="fc bfc" id="L1232" title="All 2 branches covered.">            if (!shardItemsSet.contains(termvectorKeyListItem)) {</span>
<span class="fc" id="L1233">              tmpResult.add(termvectorKeyListItem);</span>
            }
<span class="fc" id="L1235">          }</span>
<span class="fc" id="L1236">          tmpShardKeySet.put(termvectorKey, tmpResult);</span>
<span class="fc" id="L1237">        }</span>
      }
<span class="fc" id="L1239">    }</span>
<span class="fc" id="L1240">    return result;</span>
  }

}
</pre><div class="footer"><span class="right">Created with <a href="http://www.jacoco.org/jacoco">JaCoCo</a> 0.7.9.201702052155</span></div></body></html>