@SuppressWarnings("unchecked")
 private void writePartPropertiesToNode(BodyPart part, Node childNode)
     throws MessagingException, RepositoryException {
   Enumeration<Header> headers = part.getAllHeaders();
   while (headers.hasMoreElements()) {
     Header header = headers.nextElement();
     childNode.setProperty(header.getName(), header.getValue());
   }
 }
Beispiel #2
0
  // 取得邮件列表的信息
  @SuppressWarnings({"rawtypes", "unchecked"})
  public List getMailInfo(Message[] msg) throws Exception {
    List result = new ArrayList();
    Map map = null;
    Multipart mp = null;
    BodyPart part = null;
    String disp = null;
    SimpleDateFormat fmt = new SimpleDateFormat("yyyy年MM月dd日 hh:mm-ss");
    Enumeration enumMail = null;
    // 取出每个邮件的信息
    for (int i = msg.length - 1; i >= 0; i--) {
      if (!msg[i].getFolder().isOpen()) // 判断是否open
      msg[i].getFolder().open(Folder.READ_WRITE);
      map = new HashMap();
      // 读取邮件ID
      enumMail = msg[i].getAllHeaders();
      Header h = null;
      while (enumMail.hasMoreElements()) {
        h = (Header) enumMail.nextElement();
        if (h.getName().equals("Message-ID") || h.getName().equals("Message-Id")) {
          map.put("ID", h.getValue());
        }
      }
      // 读取邮件标题
      map.put("subject", msg[i].getSubject());
      // 读取发件人
      map.put("sender", MimeUtility.decodeText(msg[i].getFrom()[0].toString()));
      // 读取邮件发送日期
      map.put("senddate", fmt.format(msg[i].getSentDate()));
      // 读取邮件大小
      map.put("size", new Integer(msg[i].getSize()));
      map.put("hasAttach", "&nbsp;");
      // 判断是否有附件
      if (msg[i].isMimeType("multipart/*")) {
        mp = (Multipart) msg[i].getContent();
        // 遍历每个Miltipart对象

        for (int j = 0; j < mp.getCount(); j++) {
          part = mp.getBodyPart(j);
          disp = part.getDisposition();
          // 如果有附件
          if (disp != null && (disp.equals(Part.ATTACHMENT) || disp.equals(Part.INLINE))) {
            // 设置有附件的特征值
            map.put("hasAttach", "√");
          }
        }
      }
      result.add(map);
    }
    return result;
  }
Beispiel #3
0
 public static void writeMessage(Message message, OutputStream out) {
   try {
     Enumeration<Header> enu = message.getAllHeaders();
     while (enu.hasMoreElements()) {
       Header header = enu.nextElement();
       IO.writeText(out, header.getName() + ": " + header.getValue() + "\n", charset);
     }
     IO.writeText(out, "\n", charset);
     IO.copyData(message.getInputStream(), out);
   } catch (IOException ex) {
     throw new RuntimeException(ex);
   } catch (MessagingException ex) {
     throw new RuntimeException(ex);
   }
 }
  private MyMessage map(Message message) throws IOException, MessagingException {

    MimeMessage m = (MimeMessage) message;

    dump(m);

    Object content = m.getContent();

    log.info("================= " + m.getSubject() + " =================");
    log.info("content class: " + content.getClass());
    log.info("contentType: " + m.getContentType());

    if (content instanceof Multipart) {

      Multipart mp = (Multipart) content;
      log.info("---------------------- " + mp.getCount() + " ----------------------");
      for (int i = 0; i < mp.getCount(); i++) {

        Part part = mp.getBodyPart(i);
        String disposition = part.getDisposition();

        log.info("---------------------- >>>>> ----------------------");

        log.info("part.size: " + part.getSize());
        log.info("part.lineCount: " + part.getLineCount());
        log.info("part.description: " + part.getDescription());
        log.info("part.contentType: " + part.getContentType());
        log.info("part.fileName: " + part.getFileName());
        log.info("part.disposition: " + disposition);

        Enumeration headers = part.getAllHeaders();

        while (headers.hasMoreElements()) {
          Header header = (Header) headers.nextElement();
          log.info("part.header - " + header.getName() + " : " + header.getValue());
        }

        log.info("---------------------- <<<<< ----------------------");

        if (disposition != null) {}
      }
    }

    return new MyMessage().setSubject(m.getSubject()).setId(m.getMessageID());
  }
 /**
  * Method getHeaderNames answers a List of all of the headers in the receiver. No duplicates are
  * allowed.
  *
  * @return <code>List</code>, not null possible empty, possible unmodifiable
  * @throws SieveMailException
  */
 @SuppressWarnings("unchecked")
 public List<String> getHeaderNames() throws SieveMailException {
   List<String> results = Collections.EMPTY_LIST;
   if (mail != null) {
     try {
       results = new ArrayList<String>();
       for (final Enumeration en = mail.getAllHeaders(); en.hasMoreElements(); ) {
         final Header header = (Header) en.nextElement();
         final String name = header.getName();
         if (!results.contains(name)) {
           results.add(name);
         }
       }
     } catch (MessagingException e) {
       throw new SieveMailException(e);
     }
   }
   return results;
 }
Beispiel #6
0
 // 查找指定邮件
 @SuppressWarnings("rawtypes")
 public Message findMail(Message[] msg, String id) throws Exception {
   Enumeration enumMail = null;
   Header h = null;
   for (int i = 0; i < msg.length; i++) {
     enumMail = msg[i].getAllHeaders();
     // 查找邮件头中的Message-ID项
     while (enumMail.hasMoreElements()) {
       h = (Header) enumMail.nextElement();
       // 根据传入的message-id来查找目标邮件
       boolean messageId =
           (h.getName().equals("Message-ID")) || (h.getName().equals("Message-Id"));
       if (messageId && (h.getValue().equals(id))) {
         return msg[i];
       }
     }
   }
   return null;
 }
  /**
   * Parses the value from the given message into addresses.
   *
   * @param headerName header name, to be matched case insensitively
   * @param message <code>Message</code>, not null
   * @return <code>Address</code> array, not null possibly empty
   * @throws SieveMailException
   */
  public Address[] parseAddresses(final String headerName, final Message message)
      throws SieveMailException {
    try {
      final SieveAddressBuilder builder = new SieveAddressBuilder();

      for (Enumeration en = message.getAllHeaders(); en.hasMoreElements(); ) {
        final Header header = (Header) en.nextElement();
        final String name = header.getName();
        if (name.trim().equalsIgnoreCase(headerName)) {
          builder.addAddresses(header.getValue());
        }
      }

      return builder.getAddresses();

    } catch (MessagingException ex) {
      throw new SieveMailException(ex);
    } catch (org.apache.jsieve.parser.generated.address.ParseException ex) {
      throw new SieveMailException(ex);
    }
  }
Beispiel #8
0
  @SuppressWarnings("unchecked")
  @Test
  public void testSendMatchingMessage() throws Exception {
    String sender = "sender@localhost";
    String rcpt = "rcpt@localhost";
    String body = "Subject: test\r\n\r\nTestmail";
    SMTPClient client = new SMTPClient();
    client.connect("localhost", 2525);
    client.helo("localhost");
    client.setSender(sender);
    client.addRecipient(rcpt);

    client.sendShortMessageData(body);
    client.quit();
    client.disconnect();
    resultEndpoint.expectedMessageCount(1);
    resultEndpoint.expectedBodyReceived().body(InputStream.class);
    Exchange ex = resultEndpoint.getReceivedExchanges().get(0);
    Map<String, Object> headers = ex.getIn().getHeaders();
    assertEquals(sender, headers.get(MailEnvelopeMessage.SMTP_SENDER_ADRRESS));
    assertEquals(rcpt, headers.get(MailEnvelopeMessage.SMTP_RCPT_ADRRESS_LIST));

    // check type converter
    MimeMessage message = ex.getIn().getBody(MimeMessage.class);
    Enumeration<Header> mHeaders = message.getAllHeaders();
    Header header = null;
    while (mHeaders.hasMoreElements()) {
      header = mHeaders.nextElement();
      if (header.getName().equals("Subject")) {
        break;
      }
    }
    assertNotNull(header);
    assertEquals("Subject", header.getName());
    assertEquals(header.getValue(), "test");

    resultEndpoint.assertIsSatisfied();
  }
 @Override
 public void marshal(Exchange exchange, Object graph, OutputStream stream)
     throws NoTypeConversionAvailableException, MessagingException, IOException {
   if (multipartWithoutAttachment || headersInline || exchange.getIn().hasAttachments()) {
     ContentType contentType = getContentType(exchange);
     // remove the Content-Type header. This will be wrong afterwards...
     exchange.getOut().removeHeader(Exchange.CONTENT_TYPE);
     byte[] bodyContent = ExchangeHelper.convertToMandatoryType(exchange, byte[].class, graph);
     Session session = Session.getInstance(System.getProperties());
     MimeMessage mm = new MimeMessage(session);
     MimeMultipart mp = new MimeMultipart(multipartSubType);
     BodyPart part = new MimeBodyPart();
     writeBodyPart(bodyContent, part, contentType);
     mp.addBodyPart(part);
     for (Map.Entry<String, Attachment> entry :
         exchange.getIn().getAttachmentObjects().entrySet()) {
       String attachmentFilename = entry.getKey();
       Attachment attachment = entry.getValue();
       part = new MimeBodyPart();
       part.setDataHandler(attachment.getDataHandler());
       part.setFileName(MimeUtility.encodeText(attachmentFilename, "UTF-8", null));
       String ct = attachment.getDataHandler().getContentType();
       contentType = new ContentType(ct);
       part.setHeader(CONTENT_TYPE, ct);
       if (!contentType.match("text/*") && binaryContent) {
         part.setHeader(CONTENT_TRANSFER_ENCODING, "binary");
       }
       // Set headers to the attachment
       for (String headerName : attachment.getHeaderNames()) {
         List<String> values = attachment.getHeaderAsList(headerName);
         for (String value : values) {
           part.setHeader(headerName, value);
         }
       }
       mp.addBodyPart(part);
       exchange.getOut().removeAttachment(attachmentFilename);
     }
     mm.setContent(mp);
     // copy headers if required and if the content can be converted into
     // a String
     if (headersInline && includeHeaders != null) {
       for (Map.Entry<String, Object> entry : exchange.getIn().getHeaders().entrySet()) {
         if (includeHeaders.matcher(entry.getKey()).matches()) {
           String headerStr =
               ExchangeHelper.convertToType(exchange, String.class, entry.getValue());
           if (headerStr != null) {
             mm.setHeader(entry.getKey(), headerStr);
           }
         }
       }
     }
     mm.saveChanges();
     Enumeration<?> hl = mm.getAllHeaders();
     List<String> headers = new ArrayList<String>();
     if (!headersInline) {
       while (hl.hasMoreElements()) {
         Object ho = hl.nextElement();
         if (ho instanceof Header) {
           Header h = (Header) ho;
           exchange.getOut().setHeader(h.getName(), h.getValue());
           headers.add(h.getName());
         }
       }
       mm.saveChanges();
     }
     mm.writeTo(stream, headers.toArray(new String[0]));
   } else {
     // keep the original data
     InputStream is = ExchangeHelper.convertToMandatoryType(exchange, InputStream.class, graph);
     IOHelper.copyAndCloseInput(is, stream);
   }
 }
 @Override
 public Object unmarshal(Exchange exchange, InputStream stream)
     throws IOException, MessagingException {
   MimeBodyPart mimeMessage;
   String contentType;
   Message camelMessage;
   Object content = null;
   if (headersInline) {
     mimeMessage = new MimeBodyPart(stream);
     camelMessage = exchange.getOut();
     MessageHelper.copyHeaders(exchange.getIn(), camelMessage, true);
     contentType = mimeMessage.getHeader(CONTENT_TYPE, null);
     // write the MIME headers not generated by javamail as Camel headers
     Enumeration<?> headersEnum = mimeMessage.getNonMatchingHeaders(STANDARD_HEADERS);
     while (headersEnum.hasMoreElements()) {
       Object ho = headersEnum.nextElement();
       if (ho instanceof Header) {
         Header header = (Header) ho;
         camelMessage.setHeader(header.getName(), header.getValue());
       }
     }
   } else {
     // check if this a multipart at all. Otherwise do nothing
     contentType = exchange.getIn().getHeader(CONTENT_TYPE, String.class);
     if (contentType == null) {
       return stream;
     }
     try {
       ContentType ct = new ContentType(contentType);
       if (!ct.match("multipart/*")) {
         return stream;
       }
     } catch (ParseException e) {
       LOG.warn("Invalid Content-Type " + contentType + " ignored");
       return stream;
     }
     camelMessage = exchange.getOut();
     MessageHelper.copyHeaders(exchange.getIn(), camelMessage, true);
     ByteArrayOutputStream bos = new ByteArrayOutputStream();
     IOHelper.copyAndCloseInput(stream, bos);
     InternetHeaders headers = new InternetHeaders();
     extractHeader(CONTENT_TYPE, camelMessage, headers);
     extractHeader(MIME_VERSION, camelMessage, headers);
     mimeMessage = new MimeBodyPart(headers, bos.toByteArray());
     bos.close();
   }
   DataHandler dh;
   try {
     dh = mimeMessage.getDataHandler();
     if (dh != null) {
       content = dh.getContent();
       contentType = dh.getContentType();
     }
   } catch (MessagingException e) {
     LOG.warn("cannot parse message, no unmarshalling done");
   }
   if (content instanceof MimeMultipart) {
     MimeMultipart mp = (MimeMultipart) content;
     content = mp.getBodyPart(0);
     for (int i = 1; i < mp.getCount(); i++) {
       BodyPart bp = mp.getBodyPart(i);
       DefaultAttachment camelAttachment = new DefaultAttachment(bp.getDataHandler());
       @SuppressWarnings("unchecked")
       Enumeration<Header> headers = bp.getAllHeaders();
       while (headers.hasMoreElements()) {
         Header header = headers.nextElement();
         camelAttachment.addHeader(header.getName(), header.getValue());
       }
       camelMessage.addAttachmentObject(getAttachmentKey(bp), camelAttachment);
     }
   }
   if (content instanceof BodyPart) {
     BodyPart bp = (BodyPart) content;
     camelMessage.setBody(bp.getInputStream());
     contentType = bp.getContentType();
     if (contentType != null && !DEFAULT_CONTENT_TYPE.equals(contentType)) {
       camelMessage.setHeader(CONTENT_TYPE, contentType);
       ContentType ct = new ContentType(contentType);
       String charset = ct.getParameter("charset");
       if (charset != null) {
         camelMessage.setHeader(Exchange.CONTENT_ENCODING, MimeUtility.javaCharset(charset));
       }
     }
   } else {
     // If we find no body part, try to leave the message alone
     LOG.info("no MIME part found");
   }
   return camelMessage;
 }
Beispiel #11
0
  /**
   * Creates a Mail
   *
   * @param inboxHelper
   * @param message
   * @param mUId
   * @return
   * @throws FolderClosedException
   * @throws MessagingException
   * @throws IOException
   */
  public static RawMail createMail(Message message) throws FolderClosedException {
    try {
      // fill the message objects with messagedata
      String[] fromInfo = MailUtils.getFromInfo(message.getFrom());

      if (fromInfo[0] == null || fromInfo[0].isEmpty()) {
        fromInfo = MailUtils.getFromInfo(message.getReplyTo());
      }
      if (fromInfo[0] == null || fromInfo[0].isEmpty()) {
        String[] returnPath = message.getHeader("Return-Path");
        if (returnPath.length > 0) {
          fromInfo[0] = returnPath[0].trim();
          if (fromInfo[0].charAt(0) == '<') fromInfo[0].substring(1);
          if (fromInfo[0].charAt(fromInfo[0].length() - 1) == '>')
            fromInfo[0].substring(0, fromInfo[0].length() - 2);
        }
      }

      String mFromAddress = (fromInfo[0] != null) ? fromInfo[0] : "";
      RawMail mail = new RawMail();
      // Note: Mail ids are generated based on contents - do not set an id

      String mSubject = message.getSubject();
      mail.setSubject(mSubject);
      mail.setFrom(new EmailAddress(mFromAddress, fromInfo[1]));
      mail.setCreated(new Date());

      // Prevent evil mail servers from sending from the future
      Date now = new Date();
      Date sentDate = message.getSentDate();
      Date recDate = message.getReceivedDate();

      if (sentDate == null || now.before(sentDate)) sentDate = new Date();
      if (recDate == null || now.before(recDate)) recDate = new Date();

      mail.setSentDate(sentDate);
      mail.setRecievedDate(recDate);

      mail.setServerId(String.valueOf(message.getMessageNumber()));

      try {
        mail.setBody(MailUtils.getBody(message));
      } catch (Throwable ex) {
        System.out.println("Failed when reading mail body");
      }

      // Headers
      Enumeration<?> allHeaders = message.getAllHeaders();
      HashMap<String, String> mailHeaders = new HashMap<String, String>();
      while (allHeaders.hasMoreElements()) {
        Header header = (Header) allHeaders.nextElement();
        mailHeaders.put(header.getName(), header.getValue());
      }
      mail.setHeaders(mailHeaders);

      try {
        mail.setRecipients(MailUtils.getRecipients(Message.RecipientType.TO, message));
      } catch (Throwable ex) {
        System.out.println("Throwable during setRecipients");
      }
      try {
        mail.setRecipients(MailUtils.getRecipients(Message.RecipientType.CC, message));
      } catch (Throwable ex) {
        System.out.println("Throwable during setRecipients");
      }
      try {
        mail.setRecipients(MailUtils.getRecipients(Message.RecipientType.BCC, message));
      } catch (Throwable ex) {
        System.out.println("Throwable during setRecipients");
      }
      return mail;
    } catch (FolderClosedException ex) {
      throw ex;
    } catch (Throwable ex) {
      System.out.println("Could not read mail");
    }
    return null;
  }
  private void _sendAsyncMDN(@Nonnull final AS2Message aMsg) throws OpenAS2Exception {
    s_aLogger.info("Async MDN submitted" + aMsg.getLoggingText());
    final DispositionType aDisposition = DispositionType.createSuccess();

    try {
      final IMessageMDN aMdn = aMsg.getMDN();

      // Create a HTTP connection
      final String sUrl = aMsg.getAsyncMDNurl();
      final boolean bOutput = true;
      final boolean bInput = true;
      final boolean bUseCaches = false;
      final HttpURLConnection aConn =
          getConnection(sUrl, bOutput, bInput, bUseCaches, "POST", getSession().getHttpProxy());

      try {
        s_aLogger.info("connected to " + sUrl + aMsg.getLoggingText());

        aConn.setRequestProperty(CAS2Header.HEADER_CONNECTION, CAS2Header.DEFAULT_CONNECTION);
        aConn.setRequestProperty(CAS2Header.HEADER_USER_AGENT, CAS2Header.DEFAULT_USER_AGENT);
        // Copy all the header from mdn to the RequestProperties of conn
        final Enumeration<?> aHeaders = aMdn.getHeaders().getAllHeaders();
        while (aHeaders.hasMoreElements()) {
          final Header aHeader = (Header) aHeaders.nextElement();
          final String sHeaderValue =
              aHeader.getValue().replace('\t', ' ').replace('\n', ' ').replace('\r', ' ');
          aConn.setRequestProperty(aHeader.getName(), sHeaderValue);
        }

        // Note: closing this stream causes connection abort errors on some AS2
        // servers
        final OutputStream aMessageOS = aConn.getOutputStream();

        // Transfer the data
        final InputStream aMessageIS = aMdn.getData().getInputStream();
        final StopWatch aSW = StopWatch.createdStarted();
        final long nBytes = IOHelper.copy(aMessageIS, aMessageOS);
        aSW.stop();
        s_aLogger.info(
            "transferred " + IOHelper.getTransferRate(nBytes, aSW) + aMsg.getLoggingText());

        // Check the HTTP Response code
        final int nResponseCode = aConn.getResponseCode();
        if (nResponseCode != HttpURLConnection.HTTP_OK
            && nResponseCode != HttpURLConnection.HTTP_CREATED
            && nResponseCode != HttpURLConnection.HTTP_ACCEPTED
            && nResponseCode != HttpURLConnection.HTTP_PARTIAL
            && nResponseCode != HttpURLConnection.HTTP_NO_CONTENT) {
          s_aLogger.error(
              "sent AsyncMDN [" + aDisposition.getAsString() + "] Fail " + aMsg.getLoggingText());
          throw new HttpResponseException(sUrl, nResponseCode, aConn.getResponseMessage());
        }

        s_aLogger.info(
            "sent AsyncMDN [" + aDisposition.getAsString() + "] OK " + aMsg.getLoggingText());

        // log & store mdn into backup folder.
        try {
          getSession()
              .getMessageProcessor()
              .handle(IProcessorStorageModule.DO_STOREMDN, aMsg, null);
        } catch (final ComponentNotFoundException ex) {
          // May be
        }
      } finally {
        aConn.disconnect();
      }
    } catch (final HttpResponseException ex) {
      // Resend if the HTTP Response has an error code
      ex.terminate();
      _resend(aMsg, ex);
    } catch (final IOException ex) {
      // Resend if a network error occurs during transmission
      final OpenAS2Exception wioe = WrappedOpenAS2Exception.wrap(ex);
      wioe.addSource(OpenAS2Exception.SOURCE_MESSAGE, aMsg);
      wioe.terminate();

      _resend(aMsg, wioe);
    } catch (final Exception ex) {
      // Propagate error if it can't be handled by a resend
      throw WrappedOpenAS2Exception.wrap(ex);
    }
  }
    public void run() {
      Thread.currentThread().setContextClassLoader(getClass().getClassLoader());

      if (!circuitBreaker.isOn()) return; // Don't try - circuit breaker is off

      boolean expunge = config.configuration().deleteMailOnInboxClose().get();
      if (config.configuration().debug().get()) {
        logger.info("Checking email");
        logger.info("Delete mail on close - " + expunge);
      }

      Session session = javax.mail.Session.getInstance(props, authenticator);
      session.setDebug(config.configuration().debug().get());

      Usecase usecase = newUsecase("Receive Mail");
      UnitOfWork uow = null;
      Store store = null;
      Folder inbox = null;
      Folder archive = null;
      boolean archiveExists = false;
      List<Message> copyToArchive = new ArrayList<Message>();
      MimeMessage internalMessage = null;

      try {
        store = session.getStore(url);
        store.connect();

        inbox = store.getFolder("INBOX");
        inbox.open(Folder.READ_WRITE);

        javax.mail.Message[] messages = inbox.getMessages();
        FetchProfile fp = new FetchProfile();
        //            fp.add( "In-Reply-To" );
        inbox.fetch(messages, fp);

        // check if the archive folder is configured and exists
        if (!Strings.empty(config.configuration().archiveFolder().get())
            && config.configuration().protocol().get().startsWith("imap")) {
          archive = store.getFolder(config.configuration().archiveFolder().get());

          // if not exists - create
          if (!archive.exists()) {
            archive.create(Folder.HOLDS_MESSAGES);
            archiveExists = true;
          } else {
            archiveExists = true;
          }

          archive.open(Folder.READ_WRITE);
        }

        for (javax.mail.Message message : messages) {
          int tries = 0;
          while (tries < 3) {
            uow = module.unitOfWorkFactory().newUnitOfWork(usecase);

            ValueBuilder<EmailValue> builder =
                module.valueBuilderFactory().newValueBuilder(EmailValue.class);

            try {
              // Force a complete fetch of the message by cloning it to a internal MimeMessage
              // to avoid "javax.mail.MessagingException: Unable to load BODYSTRUCTURE" problems
              // f.ex. experienced if the message contains a windows .eml file as attachment!

              // Beware that all flag and folder operations have to be made on the original message
              // and not on the internal one!!
              internalMessage = new MimeMessage((MimeMessage) message);

              Object content = internalMessage.getContent();

              // Get email fields
              builder
                  .prototype()
                  .from()
                  .set(((InternetAddress) internalMessage.getFrom()[0]).getAddress());
              builder
                  .prototype()
                  .fromName()
                  .set(((InternetAddress) internalMessage.getFrom()[0]).getPersonal());
              builder
                  .prototype()
                  .subject()
                  .set(internalMessage.getSubject() == null ? "" : internalMessage.getSubject());

              // Get headers
              for (Header header :
                  Iterables.iterable((Enumeration<Header>) internalMessage.getAllHeaders())) {
                builder.prototype().headers().get().put(header.getName(), header.getValue());
              }

              // Get all recipients in order - TO, CC, BCC
              // and provide it to the toaddress method to pick the first possible valid adress
              builder
                  .prototype()
                  .to()
                  .set(
                      toaddress(
                          internalMessage.getAllRecipients(),
                          builder.prototype().headers().get().get("References")));

              builder.prototype().messageId().set(internalMessage.getHeader("Message-ID")[0]);

              // Get body and attachments
              String body = "";
              // set content initially so it never can become null
              builder.prototype().content().set(body);

              if (content instanceof String) {
                body = content.toString();
                builder.prototype().content().set(body);
                String contentTypeString = cleanContentType(internalMessage.getContentType());
                builder.prototype().contentType().set(contentTypeString);
                if (Translator.HTML.equalsIgnoreCase(contentTypeString)) {
                  builder.prototype().contentHtml().set(body);
                }

              } else if (content instanceof Multipart) {
                handleMultipart((Multipart) content, internalMessage, builder);
              } else if (content instanceof InputStream) {
                content = new MimeMessage(session, (InputStream) content).getContent();
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                Inputs.byteBuffer((InputStream) content, 4096).transferTo(Outputs.byteBuffer(baos));

                String data = new String(baos.toByteArray(), "UTF-8");
                // Unknown content type - abort
                // and create failure case
                String subj = "Unkonwn content type: " + internalMessage.getSubject();
                builder
                    .prototype()
                    .subject()
                    .set(subj.length() > 50 ? subj.substring(0, 50) : subj);
                builder.prototype().content().set(body);
                builder.prototype().contentType().set(internalMessage.getContentType());
                systemDefaults.createCaseOnEmailFailure(builder.newInstance());
                copyToArchive.add(message);
                if (expunge) message.setFlag(Flags.Flag.DELETED, true);

                uow.discard();
                tries = 3;
                continue;
              } else {
                // Unknown content type - abort
                // and create failure case
                String subj = "Unkonwn content type: " + internalMessage.getSubject();
                builder
                    .prototype()
                    .subject()
                    .set(subj.length() > 50 ? subj.substring(0, 50) : subj);
                builder.prototype().content().set(body);
                builder.prototype().contentType().set(internalMessage.getContentType());
                systemDefaults.createCaseOnEmailFailure(builder.newInstance());
                copyToArchive.add(message);
                if (expunge) message.setFlag(Flags.Flag.DELETED, true);

                uow.discard();
                logger.error(
                    "Could not parse emails: unknown content type " + content.getClass().getName());
                tries = 3;
                continue;
              }

              // make sure mail content fit's into statistic database - truncate on 65.500
              // characters.
              if (builder.prototype().content().get().length() > 65000) {
                builder
                    .prototype()
                    .content()
                    .set(builder.prototype().content().get().substring(0, 65000));
              }

              // try to reveal if it is a smpt error we are looking at
              // X-Failed-Recipients is returned by Gmail
              // X-FC-MachineGenerated is returned by FirstClass
              // Exchange is following RFC 6522 -  The Multipart/Report Media Type for
              // the Reporting of Mail System Administrative Messages
              boolean isSmtpErrorReport =
                  !Strings.empty(builder.prototype().headers().get().get("X-Failed-Recipients"))
                      || (!Strings.empty(
                              builder.prototype().headers().get().get("X-FC-MachineGenerated"))
                          && "true"
                              .equals(
                                  builder.prototype().headers().get().get("X-FC-MachineGenerated")))
                      || !Strings.empty(
                          new ContentType(builder.prototype().headers().get().get("Content-Type"))
                              .getParameter("report-type"));

              if (isSmtpErrorReport) {
                // This is a mail bounce due to SMTP error - create support case.
                String subj = "Undeliverable mail: " + builder.prototype().subject().get();

                builder
                    .prototype()
                    .subject()
                    .set(subj.length() > 50 ? subj.substring(0, 50) : subj);
                systemDefaults.createCaseOnEmailFailure(builder.newInstance());
                copyToArchive.add(message);
                if (expunge) message.setFlag(Flags.Flag.DELETED, true);

                uow.discard();
                logger.error("Received a mail bounce reply: " + body);
                tries = 3;
                continue;
              }

              if (builder.prototype().to().get().equals("n/a")) {
                // This is a mail has no to address - create support case.

                String subj = "No TO address: " + builder.prototype().subject().get();

                builder
                    .prototype()
                    .subject()
                    .set(subj.length() > 50 ? subj.substring(0, 50) : subj);
                systemDefaults.createCaseOnEmailFailure(builder.newInstance());
                copyToArchive.add(message);
                if (expunge) message.setFlag(Flags.Flag.DELETED, true);

                uow.discard();
                logger.error("Received a mail without TO address: " + body);
                tries = 3;
                continue;
              }

              mailReceiver.receivedEmail(null, builder.newInstance());

              try {
                logger.debug("This is try " + tries);
                uow.complete();
                tries = 3;
              } catch (ConcurrentEntityModificationException ceme) {
                if (tries < 2) {
                  logger.debug("Encountered ConcurrentEntityModificationException - try again ");
                  // discard uow and try again
                  uow.discard();
                  tries++;
                  continue;

                } else {
                  logger.debug("Rethrowing ConcurrentEntityModification.Exception");
                  tries++;
                  throw ceme;
                }
              }

              copyToArchive.add(message);
              // remove mail on success if expunge is true
              if (expunge) message.setFlag(Flags.Flag.DELETED, true);

            } catch (Throwable e) {
              String subj = "Unknown error: " + internalMessage.getSubject();
              builder.prototype().subject().set(subj.length() > 50 ? subj.substring(0, 50) : subj);

              StringBuilder content = new StringBuilder();
              content.append("Error Message: " + e.getMessage());
              content.append("\n\rStackTrace:\n\r");
              for (StackTraceElement trace : Arrays.asList(e.getStackTrace())) {
                content.append(trace.toString() + "\n\r");
              }

              builder.prototype().content().set(content.toString());
              // since we create the content of the message our self it's ok to set content type
              // always to text/plain
              builder.prototype().contentType().set("text/plain");

              // Make sure to address has some value before vi create a case!!
              if (builder.prototype().to().get() == null) {
                builder.prototype().to().set("n/a");
              }
              systemDefaults.createCaseOnEmailFailure(builder.newInstance());
              copyToArchive.add(message);
              if (expunge) message.setFlag(Flags.Flag.DELETED, true);

              uow.discard();
              logger.error("Could not parse emails", e);
              tries = 3;
            }
          }
        }

        // copy message to archive if archive exists
        if (archiveExists) {
          inbox.copyMessages(copyToArchive.toArray(new Message[0]), archive);
          archive.close(false);
        }

        inbox.close(config.configuration().deleteMailOnInboxClose().get());

        store.close();

        if (config.configuration().debug().get()) {
          logger.info("Checked email");
        }

        circuitBreaker.success();
      } catch (Throwable e) {
        logger.error("Error in mail receiver: ", e);
        circuitBreaker.throwable(e);

        try {
          if (inbox != null && inbox.isOpen()) inbox.close(false);

          if (store != null && store.isConnected()) store.close();
        } catch (Throwable e1) {
          logger.error("Could not close inbox", e1);
        }
      }
    }