in mailbox/lucene/src/main/java/org/apache/james/mailbox/lucene/search/LuceneIndexableDocument.java [129:210]
public Document createMessageDocument(MailboxMessage message, MailboxSession session, MimePart mimePartExtracted) {
Document doc = new Document();
doc.add(new StringField(USERS, session.getUser().asString().toUpperCase(Locale.US), Field.Store.YES));
doc.add(new StringField(MAILBOX_ID_FIELD, message.getMailboxId().serialize().toUpperCase(Locale.US), Field.Store.YES));
doc.add(new NumericDocValuesField(UID_FIELD, message.getUid().asLong()));
doc.add(new LongPoint(UID_FIELD, message.getUid().asLong()));
doc.add(new StoredField(UID_FIELD, message.getUid().asLong()));
doc.add(new StringField(HAS_ATTACHMENT_FIELD, Boolean.toString(MessageAttachmentMetadata.hasNonInlinedAttachment(message.getAttachments())), Field.Store.YES));
doc.add(new LongPoint(SIZE_FIELD, message.getFullContentOctets()));
doc.add(new NumericDocValuesField(SIZE_FIELD, message.getFullContentOctets()));
// create a unique key for the document which can be used later on updates to find the document
doc.add(new StringField(ID_FIELD, message.getMailboxId().serialize().toUpperCase(Locale.US) + "-" + message.getUid().asLong(), Field.Store.YES));
Optional.ofNullable(SearchUtil.getSerializedMessageIdIfSupportedByUnderlyingStorageOrNull(message))
.ifPresent(serializedMessageId -> doc.add(new StringField(MESSAGE_ID_FIELD, serializedMessageId, Field.Store.YES)));
Optional.ofNullable(SearchUtil.getSerializedThreadIdIfSupportedByUnderlyingStorageOrNull(message))
.ifPresent(serializedThreadId -> doc.add(new StringField(THREAD_ID_FIELD, serializedThreadId, Field.Store.YES)));
HeaderCollection headerCollection = mimePartExtracted.getHeaderCollection();
// index date fields
indexInternalDateFields(message.getInternalDate(), doc);
message.getSaveDate().ifPresent(saveDate -> indexSaveDateFields(saveDate, doc));
headerCollection.getSentDate()
.map(zonedDateTime -> Date.from(zonedDateTime.toInstant()))
.or(() -> Optional.ofNullable(message.getInternalDate()))
.ifPresent(sentDate -> indexSentDateFields(sentDate, doc));
// index header
headerCollection.getHeaders()
.forEach(header -> {
String headerName = uppercase(header.getHeaderName());
String headerValue = uppercase(header.getValue());
doc.add(new TextField(HEADERS_FIELD, String.format("%s: %s", headerName, headerValue), Field.Store.NO));
doc.add(new TextField(PREFIX_HEADER_FIELD + headerName, headerValue, Field.Store.NO));
switch (headerName) {
case "TO":
doc.add(new TextField(TO_FIELD, headerValue, Field.Store.NO));
doc.add(new SortedSetDocValuesField(FIRST_TO_MAILBOX_NAME_FIELD, new BytesRef(SearchUtil.getMailboxAddress(header.getValue()))));
break;
case "FROM":
doc.add(new TextField(FROM_FIELD, headerValue, Field.Store.NO));
doc.add(new SortedSetDocValuesField(FIRST_FROM_MAILBOX_NAME_FIELD, new BytesRef(SearchUtil.getMailboxAddress(header.getValue()))));
break;
case "CC":
doc.add(new TextField(CC_FIELD, headerValue, Field.Store.NO));
doc.add(new SortedSetDocValuesField(FIRST_CC_MAILBOX_NAME_FIELD, new BytesRef(SearchUtil.getMailboxAddress(header.getValue()))));
break;
case "BCC":
doc.add(new TextField(BCC_FIELD, headerValue, Field.Store.NO));
break;
case "SUBJECT":
doc.add(new StringField(SUBJECT_FIELD, header.getValue(), Field.Store.YES));
doc.add(new StringField(BASE_SUBJECT_FIELD, headerValue, Field.Store.NO));
doc.add(new SortedSetDocValuesField(BASE_SUBJECT_FIELD, new BytesRef(SearchUtil.getBaseSubject(headerValue))));
break;
default:
break;
}
});
doc.add(new TextField(FROM_FIELD, uppercase(EMailers.from(headerCollection.getFromAddressSet()).serialize()), Field.Store.YES));
doc.add(new TextField(TO_FIELD, uppercase(EMailers.from(headerCollection.getToAddressSet()).serialize()), Field.Store.YES));
doc.add(new TextField(CC_FIELD, uppercase(EMailers.from(headerCollection.getCcAddressSet()).serialize()), Field.Store.YES));
doc.add(new TextField(BCC_FIELD, uppercase(EMailers.from(headerCollection.getBccAddressSet()).serialize()), Field.Store.YES));
// index body
Optional<String> bodyText = mimePartExtracted.locateFirstTextBody().map(SearchUtil::removeGreaterThanCharactersAtBeginningOfLine);
Optional<String> bodyHtml = mimePartExtracted.locateFirstHtmlBody();
bodyText.or(() -> bodyHtml)
.ifPresent(bodyContent -> doc.add(new TextField(BODY_FIELD, bodyContent, Field.Store.YES)));
// index attachment
mimePartExtracted.getAttachmentsStream().forEach(attachmentFields -> {
attachmentFields.getTextualBody().ifPresent(textualBody -> doc.add(new TextField(ATTACHMENT_TEXT_CONTENT_FIELD, textualBody, Field.Store.YES)));
attachmentFields.getFileName().ifPresent(fileName -> doc.add(new StringField(ATTACHMENT_FILE_NAME_FIELD, uppercase(fileName), Field.Store.YES)));
});
return doc;
}