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