/sitebricks-mail/src/main/java/com/google/sitebricks/mail/CommandCompletion.java

http://github.com/dhanji/sitebricks · Java · 75 lines · 56 code · 10 blank · 9 comment · 3 complexity · 2e9fe164ffd5a71ab27e531ae414871d MD5 · raw file

  1. package com.google.sitebricks.mail;
  2. import com.google.common.collect.Lists;
  3. import com.google.common.util.concurrent.SettableFuture;
  4. import com.google.sitebricks.mail.imap.Command;
  5. import com.google.sitebricks.mail.imap.ExtractionException;
  6. import org.slf4j.Logger;
  7. import org.slf4j.LoggerFactory;
  8. import java.util.List;
  9. /**
  10. * A generic command completion listener that aggregates incoming messages
  11. * until it forms a complete response to an issued command.
  12. *
  13. * @author dhanji@gmail.com (Dhanji R. Prasanna)
  14. */
  15. class CommandCompletion {
  16. private static final Logger log = LoggerFactory.getLogger(CommandCompletion.class);
  17. private final SettableFuture<Object> valueFuture;
  18. private final List<String> value = Lists.newArrayList();
  19. private final Long sequence;
  20. private final Command command;
  21. private final String commandString;
  22. @SuppressWarnings("unchecked") // Ugly gunk needed to prevent generics from spewing everywhere
  23. public CommandCompletion(Command command,
  24. Long sequence,
  25. SettableFuture<?> valueFuture,
  26. String commandString) {
  27. this.commandString = commandString;
  28. this.valueFuture = (SettableFuture<Object>) valueFuture;
  29. this.sequence = sequence;
  30. this.command = command;
  31. }
  32. public void error(String message, Exception e) {
  33. StringBuilder builder = new StringBuilder();
  34. for (String piece : value) {
  35. builder.append(piece).append('\n');
  36. }
  37. log.error("Exception while processing response:\n Command: {} (seq: {})\n\n--message follows--" +
  38. "\n{}\n--message end--\n--context follows--\n{}\n--context end--\n\n",
  39. new Object[] { commandString, sequence, message, builder.toString(), e });
  40. // TODO Send this back to the client as an exception so it can be handled correctly.
  41. valueFuture.setException(new MailHandlingException(value, message, e));
  42. }
  43. public boolean complete(String message) {
  44. value.add(message);
  45. // Base case (empty/newline message).
  46. if (message.isEmpty()) {
  47. return false;
  48. }
  49. try {
  50. if (Command.isEndOfSequence(sequence, message.toLowerCase())) {
  51. // Once we see the OK message, we should process the data and return.
  52. valueFuture.set(command.extract(value));
  53. return true;
  54. }
  55. }
  56. catch(ExtractionException ee) {
  57. valueFuture.setException(ee);
  58. return true;
  59. }
  60. return false;
  61. }
  62. @Override public String toString() {
  63. return commandString;
  64. }
  65. }