Package com.comphenix.protocol

Source Code of com.comphenix.protocol.MultipleLinesPrompt

package com.comphenix.protocol;

import org.bukkit.conversations.Conversation;
import org.bukkit.conversations.ConversationCanceller;
import org.bukkit.conversations.ConversationContext;
import org.bukkit.conversations.ExactMatchConversationCanceller;
import org.bukkit.conversations.Prompt;
import org.bukkit.conversations.StringPrompt;

/**
* Represents a conversation prompt that accepts a list of lines.
*
* @author Kristian
*/
class MultipleLinesPrompt extends StringPrompt {
  /**
   * Represents a canceller that determines if the multiple lines prompt is finished.
   * @author Kristian
   */
  public static interface MultipleConversationCanceller extends ConversationCanceller {
    @Override
    public boolean cancelBasedOnInput(ConversationContext context, String currentLine);

    /**
     * Determine if the current prompt is done based on the context, last
     * line and collected lines.
     *
     * @param context - current context.
     * @param currentLine - current (last) line.
     * @param lines - collected lines.
     * @param lineCount - number of lines.
     * @return TRUE if we are done, FALSE otherwise.
     */
    public boolean cancelBasedOnInput(ConversationContext context, String currentLine,
                      StringBuilder lines, int lineCount);
  }

  /**
   * A wrapper class for turning a ConversationCanceller into a MultipleConversationCanceller.
   * @author Kristian
   */
  private static class MultipleWrapper implements MultipleConversationCanceller {
    private ConversationCanceller canceller;

    public MultipleWrapper(ConversationCanceller canceller) {
      this.canceller = canceller;
    }
   
    @Override
    public boolean cancelBasedOnInput(ConversationContext context, String currentLine) {
      return canceller.cancelBasedOnInput(context, currentLine);
    }
   
    @Override
    public boolean cancelBasedOnInput(ConversationContext context, String currentLine,
                      StringBuilder lines, int lineCount) {
      return cancelBasedOnInput(context, currentLine);
    }

    @Override
    public void setConversation(Conversation conversation) {
      canceller.setConversation(conversation);
    }
   
    @Override
    public MultipleWrapper clone() {
      return new MultipleWrapper(canceller.clone());
    }
  }

  // Feels a bit like Android
  private static final String KEY = "multiple_lines_prompt";
  private static final String KEY_LAST = KEY + ".last_line";
  private static final String KEY_LINES = KEY + ".linecount";

  private final MultipleConversationCanceller endMarker;
  private final String initialPrompt;

  /**
   * Retrieve and remove the current accumulated input.
   *
   * @param context
   *            - conversation context.
   * @return The accumulated input, or NULL if not found.
   */
  public String removeAccumulatedInput(ConversationContext context) {
    Object result = context.getSessionData(KEY);

    if (result instanceof StringBuilder) {
      context.setSessionData(KEY, null);
      context.setSessionData(KEY_LINES, null);
      return ((StringBuilder) result).toString();
    } else {
      return null;
    }
  }

  /**
   * Construct a multiple lines input prompt with a specific end marker.
   * <p>
   * This is usually an empty string.
   *
   * @param endMarker - the end marker.
   */
  public MultipleLinesPrompt(String endMarker, String initialPrompt) {
    this(new ExactMatchConversationCanceller(endMarker), initialPrompt);
  }

  /**
   * Construct a multiple lines input prompt with a specific end marker implementation.
   * <p>
   * Note: Use {@link #MultipleLinesPrompt(MultipleConversationCanceller, String)} if implementing a custom canceller.
   * @param endMarker - the end marker.
   * @param initialPrompt - the initial prompt text.
   */
  public MultipleLinesPrompt(ConversationCanceller endMarker, String initialPrompt) {
    this.endMarker = new MultipleWrapper(endMarker);
    this.initialPrompt = initialPrompt;
  }
 
  /**
   * Construct a multiple lines input prompt with a specific end marker implementation.
   * @param endMarker - the end marker.
   * @param initialPrompt - the initial prompt text.
   */
  public MultipleLinesPrompt(MultipleConversationCanceller endMarker, String initialPrompt) {
    this.endMarker = endMarker;
    this.initialPrompt = initialPrompt;
  }

  @Override
  public Prompt acceptInput(ConversationContext context, String in) {
    StringBuilder result = (StringBuilder) context.getSessionData(KEY);
    Integer count = (Integer) context.getSessionData(KEY_LINES);
   
    // Handle first run
    if (result == null)
      context.setSessionData(KEY, result = new StringBuilder());
    if (count == null)
      count = 0;
   
    // Save the last line as well
    context.setSessionData(KEY_LAST, in);
    context.setSessionData(KEY_LINES, ++count);
    result.append(in + "\n");

    // And we're done
    if (endMarker.cancelBasedOnInput(context, in, result, count))
      return Prompt.END_OF_CONVERSATION;
    else
      return this;
  }

  @Override
  public String getPromptText(ConversationContext context) {
    Object last = context.getSessionData(KEY_LAST);

    if (last instanceof String)
      return (String) last;
    else
      return initialPrompt;
  }
}
TOP

Related Classes of com.comphenix.protocol.MultipleLinesPrompt

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.