001// -------------------------------------------------------------------------------- 002// Copyright 2002-2025 Echo Three, LLC 003// 004// Licensed under the Apache License, Version 2.0 (the "License"); 005// you may not use this file except in compliance with the License. 006// You may obtain a copy of the License at 007// 008// http://www.apache.org/licenses/LICENSE-2.0 009// 010// Unless required by applicable law or agreed to in writing, software 011// distributed under the License is distributed on an "AS IS" BASIS, 012// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013// See the License for the specific language governing permissions and 014// limitations under the License. 015// -------------------------------------------------------------------------------- 016 017package com.echothree.model.control.forum.server.indexer; 018 019import com.echothree.model.control.core.common.MimeTypeUsageTypes; 020import com.echothree.model.control.forum.server.control.ForumControl; 021import com.echothree.model.control.index.common.IndexConstants; 022import com.echothree.model.control.index.common.IndexFieldVariations; 023import com.echothree.model.control.index.common.IndexFields; 024import com.echothree.model.control.forum.server.analyzer.ForumMessageAnalyzer; 025import com.echothree.model.control.index.server.indexer.BaseIndexer; 026import com.echothree.model.control.index.server.indexer.FieldTypes; 027import com.echothree.model.data.core.server.entity.EntityInstance; 028import com.echothree.model.data.forum.server.entity.ForumMessage; 029import com.echothree.model.data.index.server.entity.Index; 030import com.echothree.util.server.message.ExecutionErrorAccumulator; 031import com.echothree.util.server.persistence.Session; 032import org.apache.lucene.analysis.Analyzer; 033import org.apache.lucene.document.Document; 034import org.apache.lucene.document.Field; 035import org.apache.lucene.document.LongPoint; 036import org.apache.lucene.document.SortedDocValuesField; 037import org.apache.lucene.util.BytesRef; 038 039public class ForumMessageIndexer 040 extends BaseIndexer<ForumMessage> { 041 042 ForumControl forumControl = Session.getModelController(ForumControl.class); 043 044 /** Creates a new instance of ForumMessageIndexer */ 045 public ForumMessageIndexer(final ExecutionErrorAccumulator eea, final Index index) { 046 super(eea, index); 047 } 048 049 @Override 050 protected Analyzer getAnalyzer() { 051 return new ForumMessageAnalyzer(eea, language, entityType, entityAliasTypes, entityAttributes, tagScopes); 052 } 053 054 @Override 055 protected ForumMessage getEntity(final EntityInstance entityInstance) { 056 return forumControl.getForumMessageByEntityInstance(entityInstance); 057 } 058 059 @Override 060 protected Document convertToDocument(final EntityInstance entityInstance, final ForumMessage forumMessage) { 061 var forumMessageDetail = forumMessage.getLastDetail(); 062 var forumThread = forumMessageDetail.getForumThread(); 063 var forumForumThreads = forumControl.getForumForumThreadsByForumThread(forumThread); 064 var forumMessageTypePartTypes = forumControl.getForumMessageTypePartTypesByForumMessageTypeAndIncludeInIndex(forumMessageDetail.getForumMessageType()); 065 066 var document = newDocumentWithEntityInstanceFields(entityInstance, forumMessage.getPrimaryKey()); 067 068 document.add(new Field(IndexFields.forumMessageName.name(), forumMessageDetail.getForumMessageName(), FieldTypes.NOT_STORED_TOKENIZED)); 069 document.add(new Field(IndexFields.forumThreadName.name(), forumThread.getLastDetail().getForumThreadName(), FieldTypes.NOT_STORED_TOKENIZED)); 070 document.add(new LongPoint(IndexFields.postedTime.name(), forumMessageDetail.getPostedTime())); 071 072 forumMessageTypePartTypes.stream().map((forumMessageTypePartType) -> forumMessageTypePartType.getForumMessagePartType()).forEach((forumMessagePartType) -> { 073 var forumMessagePart = forumControl.getBestForumMessagePart(forumMessage, forumMessagePartType, language); 074 if (forumMessagePart != null) { 075 var mimeTypeUsageType = forumMessagePartType.getMimeTypeUsageType(); 076 077 if(mimeTypeUsageType == null) { 078 var forumMessagePartTypeName = forumMessagePartType.getForumMessagePartTypeName(); 079 var string = forumControl.getForumStringMessagePart(forumMessagePart).getString(); 080 081 document.add(new Field(forumMessagePartTypeName, string, FieldTypes.NOT_STORED_TOKENIZED)); 082 document.add(new SortedDocValuesField(forumMessagePartTypeName + IndexConstants.INDEX_FIELD_VARIATION_SEPARATOR + IndexFieldVariations.sortable.name(), 083 new BytesRef(string))); 084 } else { 085 var mimeTypeUsageTypeName = mimeTypeUsageType.getMimeTypeUsageTypeName(); 086 087 if(mimeTypeUsageTypeName.equals(MimeTypeUsageTypes.TEXT.name())) { 088 var forumClobMessagePart = forumControl.getForumClobMessagePart(forumMessagePart); 089 090 // TODO: mime type conversion to text/plain happens here 091 document.add(new Field(forumMessagePartType.getForumMessagePartTypeName(), forumClobMessagePart.getClob(), FieldTypes.NOT_STORED_TOKENIZED)); 092 } // Others are not supported at this time, DOCUMENT probably should be. 093 } 094 } 095 }); 096 097 if(forumForumThreads.size() > 0) { 098 var forumNames = new StringBuilder(); 099 100 forumForumThreads.forEach((forumForumThread) -> { 101 if(forumNames.length() > 0) { 102 forumNames.append(' '); 103 } 104 105 forumNames.append(forumForumThread.getForum().getLastDetail().getForumName()); 106 }); 107 108 document.add(new Field(IndexFields.forumNames.name(), forumNames.toString(), FieldTypes.NOT_STORED_NOT_TOKENIZED)); 109 } 110 111 return document; 112 } 113 114}