Package org.speakright.sro

Source Code of org.speakright.sro.BaseSROQuestion$MyConfirmationWrapper

/**
* Copyright (c) 2007 Ian Rae
* All Rights Reserved.
* Licensed under the Eclipse Public License - v 1.0
* For more information see http://www.eclipse.org/legal/epl-v10.html
*/
package org.speakright.sro;

import static org.junit.Assert.assertEquals;

import java.io.*;

import org.speakright.core.ConfirmationWrapper;
import org.speakright.core.IConfirmationFlow;
import org.speakright.core.IExecutionContext;
import org.speakright.core.IFlow;
import org.speakright.core.SRResults;
import org.speakright.core.StringSwitch;
import org.speakright.core.flows.ChoiceFlow;
import org.speakright.core.flows.NBestConfirmerFlow;
import org.speakright.core.flows.QuestionFlow;
import org.speakright.core.render.Grammar;
import org.speakright.core.render.Prompt;
import org.speakright.core.render.PromptType;
import org.speakright.core.render.Question;

/**
* Base class for all SROs (SpeakRight Objects). SROs are re-usable "speech
* objects" for common things like dates, times, numbers, and currency.
*
* Each SRO has
* <ul>
* <li>a main prompt (m_main1Prompt)</li>
* <li>3 silence prompts (m_silence1Prompt, m_silence2Prompt, m_silence3Prompt)
* used for escalating error messages.</li>
* <li>3 noreco prompts (m_noreco1Prompt, m_noreco2Prompt, m_noreco3Prompt)
* used for escalating error messages.</li>
* <li>a subject, such as 'tickets' (used to generate prompts)</li>
* <li>an optional modelVar. If this SRO is a question then the resulting user
* input value will be stored in the model var</li>
* <li>an optional confirmation flow object for doing confirmation.</li>
* </ul>
*
* @author IanRaeLaptop
*
*/
@SuppressWarnings("serial")
public class BaseSROQuestion extends QuestionFlow {

  protected String m_prefixPrompt = "What ";

  public void set_prefixPrompt(String text) {
    m_prefixPrompt = text;
  }

  protected String m_main1Prompt = "{%prefixPrompt%}{%subject%}?";

  public void set_main1Prompt(String text) {
    m_main1Prompt = text;
  }

  // add main2, etc if needed!! I don't think they're ever used.

  protected String m_silence1Prompt = "I'm sorry I didn't hear anything. {%main1Prompt%}";

  public void set_silence1Prompt(String text) {
    m_silence1Prompt = text;
  }

  protected String m_silence2Prompt = "I still didn't hear anything. {%main1Prompt%}";

  public void set_silence2Prompt(String text) {
    m_silence2Prompt = text;
  }

  protected String m_silence3Prompt = "";

  public void set_silence3Prompt(String text) {
    m_silence3Prompt = text;
  }

  protected String m_silence4Prompt = "";

  public void set_silence4Prompt(String text) {
    m_silence4Prompt = text;
  }

  protected String m_noreco1Prompt = "I didn't get that. {%main1Prompt%}";

  public void set_noreco1Prompt(String text) {
    m_noreco1Prompt = text;
  }

  protected String m_noreco2Prompt = "I still didn't get that. {%main1Prompt%}";

  public void set_noreco2Prompt(String text) {
    m_noreco2Prompt = text;
  }

  protected String m_noreco3Prompt = "";

  public void set_noreco3Prompt(String text) {
    m_noreco3Prompt = text;
  }

  protected String m_noreco4Prompt = "";

  public void set_noreco4Prompt(String text) {
    m_noreco4Prompt = text;
  }

  protected int m_maxReExecutions = 3; // limits retries due to
                      // validate-fail. Is 1 + # of
                      // retries

  protected String m_subjectWord = "items"; // say the plural
  transient protected SROSubjectItem m_subject = null; //used in execute, can be null

  protected String m_slotName = "";

  protected String m_modelVar = ""; // optional, a model var to bind to
  protected ChoiceFlow m_cmds; //can be null. Contains commands and their sub-flows
 
  // cw stuff
  MyConfirmationWrapper m_cw;

  public BaseSROQuestion()
  {
    this("");
  }
  public BaseSROQuestion(String subject) {
    m_subjectWord = subject;
    m_quest.addGrammar(new Grammar(""));

    // initialize prompts here, but we do it again in execute
    // in case derived classes changed prompt fields like m_mainPrompt
    // dynamically
    initPrompts();
  }

  public void setModelVar(String modelVar) {
    m_modelVar = modelVar;
  }

  /**
   * Adds a command such as "cancel" or "main menu". 
   * SROs don't have any support for a separate command grammar.  Command words must be included in
   * the active grammar.  All that this method does is determine how to handle the command word when
   * it comes back in the SRResults. 
   * @param cmd  the user input string for this cmd.
   * @param flow  IFlow to be executed when the user input equals <code>choice</code>
   */
  public void addCommand(String cmd, IFlow flow)
  {
    if (m_cmds == null) {
      m_cmds = new ChoiceFlow("");
    }
    m_cmds.addChoice(cmd, flow);
  }
 
  /**
   * Add a cancel command.  The action of the cancel command is to
   * terminate this SRO.  Many applications have this pattern of dialog,
   * where the user can "enter a flight number, or say cancel".
   * @param cmd the command user input
   */
  public void addCancelCommand(String cmd)
  {
    if (m_cmds == null) {
      m_cmds = new ChoiceFlow("");
    }
    addCommand(cmd, new SROCancelCommand());
  }
 
  protected void initPrompts() {
    // load prompt set using our prompt fields
    initPrompt(PromptType.MAIN1, m_main1Prompt);
    initPrompt(PromptType.SILENCE1, m_silence1Prompt);
    initPrompt(PromptType.SILENCE2, m_silence2Prompt);
    initPrompt(PromptType.SILENCE3, m_silence3Prompt);
    initPrompt(PromptType.SILENCE4, m_silence4Prompt);
    initPrompt(PromptType.NORECO1, m_noreco1Prompt);
    initPrompt(PromptType.NORECO2, m_noreco2Prompt);
    initPrompt(PromptType.NORECO3, m_noreco3Prompt);
    initPrompt(PromptType.NORECO4, m_noreco4Prompt);
   
    initSubPrompts(m_quest);
  }
 
  protected void initSubPrompts(Question quest)
  {}

  protected void initPrompt(PromptType type, String text) {
    m_quest.add(type, text);
  }

  protected void initPrompts(IExecutionContext context) {
    if (m_subject == null) {
      m_subject = new SROSubjectItem(m_subjectWord, 2); //assume plural. derived classes can alter
    }
    initPrompts();
  }

  protected void setSubjectPlurality(int num, IExecutionContext context)
  {
    if (m_subject == null) {
      m_subject = new SROSubjectItem(m_subjectWord, num);
    }
    m_subject.setNum(num);
  }

  /**
   * A common pattern is that the main prompt changes depending on whether
   * this is the first time we've asked the question, or we're re-asking the
   * question because of validation-failure or confirmation-rejection.
   *
   * @param context
   * @param normal
   * @param validationFailed
   * @param confirmationWasRejected
   */
  protected void initMainPrompt(IExecutionContext context, String normal,
      String validationFailed, String confirmationWasRejected) {
    // load prompt set using our prompt fields
    String text = normal;
    if (context.ConfirmationWasRejected()) {
      text = confirmationWasRejected;
    } else if (context.ValidateFailed()) {
      text = validationFailed;
    }
    initPrompt(PromptType.MAIN1, text);
  }
 
 
  /**
   * Enable NBest and use an SROConfirmNBest confirmer.
   * If you want to use your own confirmer, then call setConfirmer
   * after this method.
   * The confirmer is given the name X_confirmer where X is the name
   * of this SRO.  Thus, a prompt file for an SRO named "AskTickets" could
   * override the main prompt of the NBest confirmer with the prompt id
   * "AskTickets_confirmer.main1"
   */
  @Override
  public void enableNBest(int maxNBest) {
    NBestConfirmerFlow confirmer = new NBestConfirmerFlow(m_subjectWord);
    confirmer.setName(this.name() + "_confirmer");
    setConfirmer(confirmer);
    super.enableNBest(maxNBest);
  }
  /**
   * Set a confirmer. The confirmer flow object will confirm user input (eg.
   * "Do you want Boston?")
   *
   * @param flow
   *            a confirmer object, or null to clear the confirmer
   */
  public void setConfirmer(IConfirmationFlow flow) {
    m_cw = new MyConfirmationWrapper(this, flow, this);
  }
 
  protected void setPromptCondition(Prompt prompt, String condition)
  {
    condition = condition.toLowerCase().trim();
    String[] ar = "play-once", "play-once-ever" };
   
    prompt.setConditionNone();
    int pos = StringSwitch.indexOf(ar, condition);
    switch(pos) {
    case 0:
      prompt.setConditionPlayOnce();
      break;
    case 1:
      prompt.setConditionPlayOnceEver();
      break;
    case 2:
      //log error
      break;
    }
  }

  /**
   * A hack to avoid stack overflow when ConfirmationWrapper calls
   * m_question.getNext, which in this case is this object (BaseSROQuestion).
   * So ConfirmationWrapper nows calls a virtual method doQuestionGetNext
   * which we override in MyConfirmationWrapper to call here, all so we can
   * call super.getNext. I think in Java you can only do super. from inside
   * the object.
   *
   * @param current
   *            passed to getNext
   * @param results
   *            passed to getNext
   * @return null if we're finished, else the next flow object to run.
   */
  IFlow doQuestionGetNext(IFlow current, SRResults results) {
    return super.getNext(current, results);
  }

  @Override
  public IFlow getNext(IFlow current, SRResults results) {
    if (m_cmds != null) {
      IFlow flow = m_cmds.getNext(current, results);
      if (flow != null) {
        log("COMMAND seen: " + results.m_input);
       
        if (flow instanceof SROCancelCommand) {
          log("COMMAND-CANCEL!");
          return null;
        }
        return flow;
      }
    }

    if (m_cw == null) {

      return super.getNext(current, results);
    } else {
      return m_cw.getNext(current, results); // confirmerGetNext(current,
                          // results);
    }
  }

  @Override
  public void execute(IExecutionContext context) {
    context.registerPromptFile("$sro$\\prompts.xml");
    // generate prompts here in case derived classes changed prompt fields
    // dynamically.
    initPrompts(context);
   
    if (m_modelVar.length() > 0) {
      m_quest.grammar().addBinding(m_slotName, m_modelVar);
    }

    super.execute(context);
  }
 
  @Override
  public IFlow onValidateFailed(IFlow current, SRResults results) {
    if (executionCount() <= this.m_maxReExecutions) {
      return this; // try again
    }
    return null; // give up
  }

  /*
   * Hack -- see BaseSROQuestion.doQuestionGetNext
   */
  public class MyConfirmationWrapper extends ConfirmationWrapper {

    BaseSROQuestion m_self;

    public MyConfirmationWrapper(IFlow question,
        IConfirmationFlow confirmer, BaseSROQuestion self) {
      super(question, confirmer);
      m_self = self;
    }

    @Override
    public IFlow doQuestionGetNext(IFlow current, SRResults results) {
      return m_self.doQuestionGetNext(current, results);
    }
  }
}
TOP

Related Classes of org.speakright.sro.BaseSROQuestion$MyConfirmationWrapper

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