private AttachedFileValue createAttachedFileValue(Date sentDate, BodyPart part) throws MessagingException, IOException { // Create attachment ValueBuilder<AttachedFileValue> attachmentBuilder = module.valueBuilderFactory().newValueBuilder(AttachedFileValue.class); AttachedFileValue prototype = attachmentBuilder.prototype(); // check contentType and fetch just the first part if necessary String contentType = ""; if (part.getContentType().indexOf(';') == -1) contentType = part.getContentType(); else contentType = part.getContentType().substring(0, part.getContentType().indexOf(';')); prototype.mimeType().set(contentType); prototype.modificationDate().set(sentDate); String fileName = part.getFileName(); prototype.name().set(fileName == null ? "Nofilename" : MimeUtility.decodeText(fileName)); prototype.size().set((long) part.getSize()); InputStream inputStream = part.getInputStream(); String id = attachmentStore.storeAttachment(Inputs.byteBuffer(inputStream, 4096)); String uri = "store:" + id; prototype.uri().set(uri); return attachmentBuilder.newInstance(); }
public void receivedEmail(ApplicationEvent event, EmailValue email) { UnitOfWork uow = module .unitOfWorkFactory() .newUnitOfWork(UsecaseBuilder.newUsecase("Receive email in conversation")); try { String references = email.headers().get().get("References"); if (hasStreamflowReference(references)) { // This is a response - handle it! List<String> refs = (List<String>) Iterables.addAll( (Collection<String>) new ArrayList<String>(), Iterables.iterable(references.split("[ \r\n\t]"))); // Hotmail handles refs a bit differently... String hotmailRefs = Iterables.first( Iterables.filter( new Specification<String>() { public boolean satisfiedBy(String item) { return item.contains(",") && item.endsWith("@Streamflow>"); } }, refs)); String lastRef = null; if (!Strings.empty(hotmailRefs)) { lastRef = hotmailRefs.split(",")[1]; } else { Collections.reverse(refs); Iterable<String> filter = Iterables.filter( new Specification<String>() { public boolean satisfiedBy(String item) { return item.endsWith("@Streamflow>"); } }, refs); lastRef = Iterables.first(filter); } if (lastRef == null) { ValueBuilder<EmailValue> builder = module .valueBuilderFactory() .newValueBuilder(EmailValue.class) .withPrototype(email); String subj = "Msg Ref missing: " + builder.prototype().subject().get(); builder.prototype().subject().set(subj.length() > 50 ? subj.substring(0, 50) : subj); systemDefaults.createCaseOnEmailFailure(builder.newInstance()); logger.error("Could not find message reference in email header:" + lastRef); uow.discard(); return; } Matcher matcher = Pattern.compile("<([^/]*)/([^@]*)@[^>]*>").matcher(lastRef); if (matcher.find()) { String conversationId = matcher.group(1); String participantId = URLDecoder.decode(matcher.group(2), "UTF-8"); if (!"".equals(conversationId) && !"".equals(participantId)) { ConversationParticipant from = uow.get(ConversationParticipant.class, participantId); Conversation conversation = uow.get(Conversation.class, conversationId); CaseEntity caze = (CaseEntity) conversation.conversationOwner().get(); String content = email.content().get(); // If we have an assignee, ensure it is a member of the conversation first if (caze.isAssigned()) { if (!conversation.isParticipant( (ConversationParticipant) caze.assignedTo().get())) conversation.addParticipant((ConversationParticipant) caze.assignedTo().get()); } // Create a new role map and fill it with relevant objects if (RoleMap.current() == null) RoleMap.newCurrentRoleMap(); RoleMap.current().set(from, ConversationParticipant.class); RoleMap.current().set(caze, CaseLoggable.Data.class); RoleMap.current().set(caze, Case.class); Message message = null; if (Translator.HTML.equalsIgnoreCase(email.contentType().get())) { message = conversation.createMessage(email.contentHtml().get(), MessageType.HTML, from); } else { message = conversation.createMessage(email.content().get(), MessageType.PLAIN, from); } // Create attachments for (AttachedFileValue attachedFileValue : email.attachments().get()) { if (!(attachedFileValue.mimeType().get().contains("text/x-vcard") || attachedFileValue.mimeType().get().contains("text/directory"))) { Attachment attachment = message.createAttachment(attachedFileValue.uri().get()); attachment.changeDescription("New Attachment"); attachment.changeName(attachedFileValue.name().get()); attachment.changeMimeType(attachedFileValue.mimeType().get()); attachment.changeModificationDate(attachedFileValue.modificationDate().get()); attachment.changeSize(attachedFileValue.size().get()); attachment.changeUri(attachedFileValue.uri().get()); } } try { if (caze.isStatus(CaseStates.CLOSED)) { RoleMap.newCurrentRoleMap(); RoleMap.current().set(caze); if (caze.assignedTo().get() != null) { RoleMap.current().set(caze.assignedTo().get()); } else { RoleMap.current() .set(uow.get(UserEntity.class, UserEntity.ADMINISTRATOR_USERNAME)); } CaseCommandsContext caseCommands = module.transientBuilderFactory().newTransient(CaseCommandsContext.class); caseCommands.reopen(); caseCommands.unassign(); RoleMap.clearCurrentRoleMap(); } } catch (Throwable e) { ValueBuilder<EmailValue> builder = module .valueBuilderFactory() .newValueBuilder(EmailValue.class) .withPrototype(email); String subj = "Create Case failed: " + builder.prototype().subject().get(); builder .prototype() .subject() .set(subj.length() > 50 ? subj.substring(0, 50) : subj); systemDefaults.createCaseOnEmailFailure(builder.newInstance()); // throw new IllegalStateException("Could not open case through new message.", e); } } } } uow.complete(); } catch (Exception ex) { ValueBuilder<EmailValue> builder = module.valueBuilderFactory().newValueBuilder(EmailValue.class).withPrototype(email); String subj = "Conversation Response Error: " + builder.prototype().subject().get(); builder.prototype().subject().set(subj.length() > 50 ? subj.substring(0, 50) : subj); StringBuilder content = new StringBuilder(); content.append("Error Message: " + ex.getMessage()); content.append("\n\rStackTrace:\n\r"); for (StackTraceElement trace : Arrays.asList(ex.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()); uow.discard(); // throw new ApplicationEventReplayException(event, ex); } }