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}