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

com.google.sitebricks.mail.CommandCompletion Maven / Gradle / Ivy

The newest version!
package com.google.sitebricks.mail;

import com.google.common.collect.Lists;
import com.google.common.util.concurrent.SettableFuture;
import com.google.sitebricks.mail.imap.Command;
import com.google.sitebricks.mail.imap.ExtractionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

/**
 * A generic command completion listener that aggregates incoming messages
 * until it forms a complete response to an issued command.
 *
 * @author [email protected] (Dhanji R. Prasanna)
 */
class CommandCompletion {
  private static final Logger log = LoggerFactory.getLogger(CommandCompletion.class);
  private final SettableFuture valueFuture;
  private final List value = Lists.newArrayList();
  private final Long sequence;
  private final Command command;
  private final String commandString;

  @SuppressWarnings("unchecked") // Ugly gunk needed to prevent generics from spewing everywhere
  public CommandCompletion(Command command,
                           Long sequence,
                           SettableFuture valueFuture,
                           String commandString) {
    this.commandString = commandString;
    this.valueFuture = (SettableFuture) valueFuture;
    this.sequence = sequence;
    this.command = command;
  }

  public void error(String message, Exception e) {
    StringBuilder builder = new StringBuilder();
    for (String piece : value) {
      builder.append(piece).append('\n');
    }
    log.error("Exception while processing response:\n Command: {} (seq: {})\n\n--message follows--" +
        "\n{}\n--message end--\n--context follows--\n{}\n--context end--\n\n",
        new Object[] { commandString, sequence, message, builder.toString(), e });

    // TODO Send this back to the client as an exception so it can be handled correctly.
    valueFuture.setException(new MailHandlingException(value, message, e));
  }

  public boolean complete(String message) {
    value.add(message);
    // Base case (empty/newline message).
    if (message.isEmpty()) {
      return false;
    }

    try {
     if (Command.isEndOfSequence(sequence, message.toLowerCase())) {
       // Once we see the OK message, we should process the data and return.
       valueFuture.set(command.extract(value));
       return true;
      }
    }
    catch(ExtractionException ee) {
      valueFuture.setException(ee);
      return true;
    }

    return false;
  }

  @Override public String toString() {
    return commandString;
  }
}