// BSD License (http://lemurproject.org/galago-license)
package org.lemurproject.galago.core.retrieval.traversal;

import org.lemurproject.galago.core.retrieval.Retrieval;
import org.lemurproject.galago.core.retrieval.ann.ImplementsOperator;
import org.lemurproject.galago.core.retrieval.prf.ExpansionModel;
import org.lemurproject.galago.core.retrieval.prf.ExpansionModelFactory;
import org.lemurproject.galago.core.retrieval.query.Node;
import org.lemurproject.galago.utility.Parameters;

/**
 * The Relevance Model implemented as a traversal. Input query should look like:
 *
 * #prf( original query )
 *
 *
 * #rm:fbOrigWt=0.5:fbDocs=10:fbTerms=10( query )
 *
 * The outer node (the #rm operator) will be replaced with a #combine, and the
 * query submitted to the retrieval supplied at construction. The parameters
 * will then be applied for constructing the expansion.
 *
 * Supports more general RM
 *
 * @author irmarc, sjh, dietz
 */
@ImplementsOperator(value ="rm")
public class RelevanceModelTraversal extends Traversal {

  private final Retrieval retrieval;
  private final ExpansionModel defaultExpander;

  public RelevanceModelTraversal(Retrieval retrieval) throws Exception {
    this.retrieval = retrieval;
    
    defaultExpander = ExpansionModelFactory.create(retrieval.getGlobalParameters(), retrieval);
  }

  @Override
  public Node afterNode(Node originalNode, Parameters queryParams) throws Exception {
    
    if (originalNode.getOperator().equals("rm") == false) {
      return originalNode;
    }
    
    ExpansionModel em = defaultExpander;
    if(queryParams.containsKey("relevanceModel")){
      em = ExpansionModelFactory.create(queryParams, retrieval);
    }
    
    // strip the #rm operator
    Node newRoot = new Node("combine", originalNode.getNodeParameters(), originalNode.getInternalNodes(), originalNode.getPosition());
    Node expanded = em.expand(newRoot, queryParams);
    
    return expanded;
  }

  @Override
  public void beforeNode(Node object, Parameters queryParams) throws Exception {
  }
}

@@ -215,30 +215,167 @@
 val.
-ann.ImplementsOperator
+RequiredParameters;%0Aimport org.lemurproject.galago.core.retrieval.ann.ImplementsOperator;%0Aimport org.lemurproject.galago.core.retrieval.ann.OperatorDescription
 ;%0Aim
@@ -777,17 +777,16 @@
 0:fbTerm
-s
 =10( que
@@ -1096,21 +1096,749 @@
 ator
+  
 (value 
-=%22rm%22)
+      = %22rm%22)%0A@RequiredParameters  (parameters  = %7B%22fbDocs%22, %22fbTerm%22, %22fbOrigWeight%22, %22relevanceModel%22%7D)%0A@OperatorDescription (description = %22Relevance %5BFeedback%5D Model Operator %5Cn%22 +%0A                                    %22%5Ct%5CtExpand the original query using automatically derived terms from the %5Cn%22 +%0A                                    %22%5Ct%5Ctspecified number of feedback terms and documents based on the relevanceModel %5Cn%22 +%0A                                    %22%5Ct%5Ctused.  The default RelevanceModel3 adds derived query terms to the original %5Cn%22 +%0A                                    %22%5Ct%5Ctquery while RelevanceModel1 replaces the original query terms with the %5Cn%22 +%0A                                    %22%5Ct%5Ctexpansion terms only.%22)%0A%0A
 %0Apub

Add RequiredParameters and OperatorDescription annotations.