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.search; 018 019import com.echothree.model.control.core.common.ComponentVendors; 020import com.echothree.model.control.core.common.EntityTypes; 021import com.echothree.model.control.forum.common.ForumConstants; 022import com.echothree.model.control.forum.server.analyzer.ForumMessageAnalyzer; 023import com.echothree.model.control.forum.server.control.ForumControl; 024import com.echothree.model.control.index.common.IndexConstants; 025import com.echothree.model.control.index.common.IndexFieldVariations; 026import com.echothree.model.control.index.common.IndexFields; 027import com.echothree.model.control.index.common.IndexTypes; 028import com.echothree.model.control.index.server.analyzer.BasicAnalyzer; 029import com.echothree.model.control.search.common.SearchSortDirections; 030import com.echothree.model.control.search.common.SearchSortOrders; 031import com.echothree.model.control.search.server.search.BaseSearchEvaluator; 032import com.echothree.model.control.search.server.search.EntityInstancePKHolder; 033import com.echothree.model.data.core.server.factory.EntityInstanceFactory; 034import com.echothree.model.data.forum.server.entity.Forum; 035import com.echothree.model.data.forum.server.entity.ForumMessageType; 036import com.echothree.model.data.party.server.entity.Language; 037import com.echothree.model.data.search.server.entity.SearchDefaultOperator; 038import com.echothree.model.data.search.server.entity.SearchSortDirection; 039import com.echothree.model.data.search.server.entity.SearchSortOrder; 040import com.echothree.model.data.search.server.entity.SearchType; 041import com.echothree.model.data.search.server.entity.SearchUseType; 042import com.echothree.model.data.user.server.entity.UserVisit; 043import com.echothree.util.server.message.ExecutionErrorAccumulator; 044import com.echothree.util.server.persistence.Session; 045import org.apache.lucene.search.SortField; 046 047public class ForumMessageSearchEvaluator 048 extends BaseSearchEvaluator { 049 050 private Forum forum; 051 private ForumMessageType forumMessageType; 052 private boolean includeFutureForumThreads; 053 054 /** Creates a new instance of ForumMessageSearchEvaluator */ 055 public ForumMessageSearchEvaluator(UserVisit userVisit, Language language, SearchType searchType, SearchDefaultOperator searchDefaultOperator, SearchSortOrder searchSortOrder, 056 SearchSortDirection searchSortDirection, SearchUseType searchUseType, Forum forum, ForumMessageType forumMessageType) { 057 super(userVisit, searchDefaultOperator, searchType, searchSortOrder, searchSortDirection, searchUseType, ComponentVendors.ECHO_THREE.name(), 058 EntityTypes.ForumMessage.name(), IndexTypes.FORUM_MESSAGE.name(), language, null); 059 060 this.forum = forum; 061 this.forumMessageType = forumMessageType; 062 063 var forumControl = Session.getModelController(ForumControl.class); 064 var indexDefaultForumMessageTypePartType = forumControl.getIndexDefaultForumMessageTypePartType(forumMessageType); 065 066 setField(indexDefaultForumMessageTypePartType.getForumMessagePartType().getForumMessagePartTypeName()); 067 } 068 069 public EntityInstancePKHolder getEntityInstancePKHolderByForum(Forum forum) { 070 EntityInstancePKHolder entityInstancePKHolder; 071 var ps = EntityInstanceFactory.getInstance().prepareStatement( 072 "SELECT _PK_ " + 073 "FROM componentvendors, componentvendordetails, entitytypes, entitytypedetails, entityinstances, forummessages, forummessagedetails, forumforumthreads " + 074 "WHERE frmmsg_activedetailid = frmmsgdt_forummessagedetailid " + 075 "AND frmmsgdt_frmthrd_forumthreadid = frmfrmthrd_frmthrd_forumthreadid AND frmfrmthrd_thrutime = ? " + 076 "AND frmfrmthrd_frm_forumid = ? " + 077 "AND cvnd_activedetailid = cvndd_componentvendordetailid AND cvndd_componentvendorname = ? " + 078 "AND ent_activedetailid = entdt_entitytypedetailid " + 079 "AND cvnd_componentvendorid = entdt_cvnd_componentvendorid " + 080 "AND entdt_entitytypename = ? " + 081 "AND ent_entitytypeid = eni_ent_entitytypeid AND frmmsg_forummessageid = eni_entityuniqueid " + 082 (includeFutureForumThreads ? "" : "AND frmmsgdt_postedtime <= ?")); 083 084 if(includeFutureForumThreads) { 085 entityInstancePKHolder = getEntityInstancePKHolderFromQuery(ps, 086 Session.MAX_TIME, forum, ComponentVendors.ECHO_THREE.name(), EntityTypes.ForumMessage.name()); 087 } else { 088 entityInstancePKHolder = getEntityInstancePKHolderFromQuery(ps, 089 Session.MAX_TIME, forum, ComponentVendors.ECHO_THREE.name(), EntityTypes.ForumMessage.name(), session.START_TIME); 090 } 091 092 return entityInstancePKHolder; 093 } 094 095 public EntityInstancePKHolder getEntityInstancePKHolderByForumMessageType(ForumMessageType forumMessageType) { 096 EntityInstancePKHolder entityInstancePKHolder; 097 var ps = EntityInstanceFactory.getInstance().prepareStatement( 098 "SELECT _PK_ " + 099 "FROM componentvendors, componentvendordetails, entitytypes, entitytypedetails, entityinstances, forummessages, forummessagedetails " + 100 "WHERE frmmsg_activedetailid = frmmsgdt_forummessagedetailid " + 101 "AND frmmsgdt_frmmsgtyp_forummessagetypeid = ? " + 102 "AND cvnd_activedetailid = cvndd_componentvendordetailid AND cvndd_componentvendorname = ? " + 103 "AND ent_activedetailid = entdt_entitytypedetailid " + 104 "AND cvnd_componentvendorid = entdt_cvnd_componentvendorid " + 105 "AND entdt_entitytypename = ? " + 106 "AND ent_entitytypeid = eni_ent_entitytypeid AND frmmsg_forummessageid = eni_entityuniqueid " + 107 (includeFutureForumThreads ? "" : "AND frmmsgdt_postedtime <= ?")); 108 109 if(includeFutureForumThreads) { 110 entityInstancePKHolder = getEntityInstancePKHolderFromQuery(ps, 111 forumMessageType, ComponentVendors.ECHO_THREE.name(), EntityTypes.ForumMessage.name()); 112 } else { 113 entityInstancePKHolder = getEntityInstancePKHolderFromQuery(ps, 114 forumMessageType, ComponentVendors.ECHO_THREE.name(), EntityTypes.ForumMessage.name(), session.START_TIME); 115 } 116 117 return entityInstancePKHolder; 118 } 119 120 /** 121 * Returns the includeFutureForumThreads. 122 * @return the includeFutureForumThreads 123 */ 124 public boolean isIncludeFutureForumThreads() { 125 return includeFutureForumThreads; 126 } 127 128 /** 129 * Sets the includeFutureForumThreads. 130 * @param includeFutureForumThreads the includeFutureForumThreads to set 131 */ 132 public void setIncludeFutureForumThreads(boolean includeFutureForumThreads) { 133 this.includeFutureForumThreads = includeFutureForumThreads; 134 } 135 136 @Override 137 public SortField[] getSortFields(String searchSortOrderName) { 138 SortField[] sortFields = null; 139 var reverse = searchSortDirection.getLastDetail().getSearchSortDirectionName().equals(SearchSortDirections.DESCENDING.name()); 140 141 if(searchSortOrderName.equals(SearchSortOrders.SCORE.name())) { 142 sortFields = new SortField[]{ 143 new SortField(null, SortField.Type.SCORE, reverse), 144 new SortField(ForumConstants.ForumMessagePartType_TITLE + IndexConstants.INDEX_FIELD_VARIATION_SEPARATOR + IndexFieldVariations.sortable.name(), SortField.Type.STRING, reverse) 145 }; 146 } else if(searchSortOrderName.equals(SearchSortOrders.TITLE.name())) { 147 sortFields = new SortField[]{new SortField(ForumConstants.ForumMessagePartType_TITLE + IndexConstants.INDEX_FIELD_VARIATION_SEPARATOR + IndexFieldVariations.sortable.name(), SortField.Type.STRING, reverse)}; 148 } else if(searchSortOrderName.equals(SearchSortOrders.POSTED_TIME.name())) { 149 sortFields = new SortField[]{new SortField(IndexFields.postedTime.name(), SortField.Type.LONG, reverse)}; 150 } else if(searchSortOrderName.equals(SearchSortOrders.CREATED_TIME.name())) { 151 sortFields = new SortField[]{new SortField(IndexFields.createdTime.name(), SortField.Type.LONG, reverse)}; 152 } else if(searchSortOrderName.equals(SearchSortOrders.MODIFIED_TIME.name())) { 153 sortFields = new SortField[]{new SortField(IndexFields.modifiedTime.name(), SortField.Type.LONG, reverse)}; 154 } 155 156 return sortFields; 157 } 158 159 @Override 160 public BasicAnalyzer getAnalyzer(final ExecutionErrorAccumulator eea, final Language language) { 161 return new ForumMessageAnalyzer(eea, language, entityType); 162 } 163 164 @Override 165 protected EntityInstancePKHolder executeSearch(final ExecutionErrorAccumulator eea) { 166 var resultSet = super.executeSearch(eea); 167 168 if(resultSet == null || resultSet.size() > 0) { 169 if(q != null) { 170 if(resultSet == null || resultSet.size() > 0) { 171 var entityInstancePKHolder = executeQuery(eea); 172 173 if(resultSet == null) { 174 resultSet = entityInstancePKHolder; 175 } else { 176 resultSet.retainAll(entityInstancePKHolder); 177 } 178 } 179 } 180 } 181 182 if(resultSet == null || resultSet.size() > 0) { 183 if(forum != null) { 184 var entityInstancePKHolder = getEntityInstancePKHolderByForum(forum); 185 186 if(resultSet == null) { 187 resultSet = entityInstancePKHolder; 188 } else { 189 resultSet.retainAll(entityInstancePKHolder); 190 } 191 } 192 } 193 194 if(resultSet == null || resultSet.size() > 0) { 195 if(forumMessageType != null) { 196 var entityInstancePKHolder = getEntityInstancePKHolderByForumMessageType(forumMessageType); 197 198 if(resultSet == null) { 199 resultSet = entityInstancePKHolder; 200 } else { 201 resultSet.retainAll(entityInstancePKHolder); 202 } 203 } 204 } 205 206 return resultSet; 207 } 208 209}