KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > jforum > dao > generic > GenericSearchDAO


1 /*
2  * Copyright (c) Rafael Steil
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms,
6  * with or without modification, are permitted provided
7  * that the following conditions are met:
8  *
9  * 1) Redistributions of source code must retain the above
10  * copyright notice, this list of conditions and the
11  * following disclaimer.
12  * 2) Redistributions in binary form must reproduce the
13  * above copyright notice, this list of conditions and
14  * the following disclaimer in the documentation and/or
15  * other materials provided with the distribution.
16  * 3) Neither the name of "Rafael Steil" nor
17  * the names of its contributors may be used to endorse
18  * or promote products derived from this software without
19  * specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
22  * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
23  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
24  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
27  * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES
30  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
32  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
34  * IN CONTRACT, STRICT LIABILITY, OR TORT
35  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
36  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
37  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
38  *
39  * This file creation date: 25/02/2004 - 19:32:42
40  * The JForum Project
41  * http://www.jforum.net
42  */

43 package net.jforum.dao.generic;
44
45 import java.sql.PreparedStatement JavaDoc;
46 import java.sql.ResultSet JavaDoc;
47 import java.sql.Timestamp JavaDoc;
48 import java.util.ArrayList JavaDoc;
49 import java.util.HashMap JavaDoc;
50 import java.util.HashSet JavaDoc;
51 import java.util.Iterator JavaDoc;
52 import java.util.List JavaDoc;
53 import java.util.Map JavaDoc;
54 import java.util.Set JavaDoc;
55
56 import net.jforum.JForumExecutionContext;
57 import net.jforum.SessionFacade;
58 import net.jforum.dao.SearchData;
59 import net.jforum.util.preferences.ConfigKeys;
60 import net.jforum.util.preferences.SystemGlobals;
61
62 import org.apache.log4j.Logger;
63
64 /**
65  * @author Rafael Steil
66  * @version $Id: GenericSearchDAO.java,v 1.15 2006/02/21 16:19:11 rafaelsteil Exp $
67  */

68 public class GenericSearchDAO implements net.jforum.dao.SearchDAO
69 {
70     private static final Logger log = Logger.getLogger(GenericSearchDAO.class);
71     
72     /**
73      * @see net.jforum.dao.SearchDAO#search(net.jforum.dao.SearchData)
74      */

75     public List JavaDoc search(SearchData sd) throws Exception JavaDoc
76     {
77         List JavaDoc l = new ArrayList JavaDoc();
78
79         // Check for the search cache
80
if (!sd.getSearchStarted()) {
81             if (sd.getTime() == null) {
82                 this.topicsByKeyword(sd);
83             }
84             else {
85                 this.topicsByTime(sd);
86             }
87         }
88
89         String JavaDoc sql = SystemGlobals.getSql("SearchModel.searchBase");
90         StringBuffer JavaDoc criterias = new StringBuffer JavaDoc(512);
91
92         if (sd.getForumId() != 0) {
93             criterias.append(" AND t.forum_id = " + sd.getForumId());
94         }
95         
96         if (sd.getCategoryId() != 0) {
97             sql = sql.replaceAll(":table_category:", ", jforum_forums f");
98
99             criterias.append(" AND f.categories_id = "+ sd.getCategoryId());
100             criterias.append(" AND t.forum_id = f.forum_id");
101         }
102         else {
103             sql = sql.replaceAll(":table_category:", "");
104         }
105         
106         if (sd.getOrderByField() == null || sd.getOrderByField().equals("")) {
107             sd.setOrderByField("p.post_time");
108         }
109         
110         // Prepare the query
111
sql = sql.replaceAll(":orderByField:", sd.getOrderByField());
112         sql = sql.replaceAll(":orderBy:", sd.getOrderBy());
113         sql = sql.replaceAll(":criterias:", criterias.toString());
114         
115         PreparedStatement JavaDoc p = JForumExecutionContext.getConnection().prepareStatement(sql);
116         p.setString(1, SessionFacade.getUserSession().getSessionId());
117
118         return new GenericTopicDAO().fillTopicsData(p);
119     }
120     
121     // Find topics by time
122
private void topicsByTime(SearchData sd) throws Exception JavaDoc
123     {
124         PreparedStatement JavaDoc p = JForumExecutionContext.getConnection().prepareStatement(SystemGlobals.getSql("SearchModel.searchByTime"));
125         p.setString(1, SessionFacade.getUserSession().getSessionId());
126         p.setTimestamp(2, new Timestamp JavaDoc(sd.getTime().getTime()));
127         p.executeUpdate();
128         p.close();
129         
130         this.selectTopicData();
131     }
132     
133     // Given a set of keywords, find the topics
134
private void topicsByKeyword(SearchData sd) throws Exception JavaDoc
135     {
136         boolean isLike = "like".equals(SystemGlobals.getValue(ConfigKeys.SEARCH_WORD_MATCHING).trim());
137         
138         String JavaDoc sql = isLike
139             ? SystemGlobals.getSql("SearchModel.searchByLikeWord")
140             : SystemGlobals.getSql("SearchModel.searchByWord");
141         
142         PreparedStatement JavaDoc p = JForumExecutionContext.getConnection().prepareStatement(sql);
143
144         Map JavaDoc eachWordMap = new HashMap JavaDoc();
145         
146         int maxWordSize = SystemGlobals.getIntValue(ConfigKeys.SEARCH_MAX_WORD_SIZE);
147
148         // Get the post ids to which the words are associated to
149
for (int i = 0; i < sd.getKeywords().length; i++) {
150             String JavaDoc word = sd.getKeywords()[i].toLowerCase();
151             
152             if (word.length() > maxWordSize) {
153                 //truncate the word
154
word = word.substring(0, maxWordSize);
155             }
156             
157             if (isLike) {
158                 p.setString(1, "%" + word + "%");
159             }
160             else {
161                 p.setString(1, word);
162             }
163             
164             Set JavaDoc postsIds = new HashSet JavaDoc();
165             ResultSet JavaDoc rs = p.executeQuery();
166             
167             while (rs.next()) {
168                 postsIds.add(new Integer JavaDoc(rs.getInt("post_id")));
169             }
170             
171             if (postsIds.size() > 0) {
172                 eachWordMap.put(sd.getKeywords()[i], postsIds);
173             }
174         }
175         
176         p.close();
177         
178         // [wordName] = { each, post, id }
179

180         // If seach type is OR, then get all words
181
// If it is AND, then we want only the ids common to all words
182
Set JavaDoc postsIds = null;
183         
184         if (sd.getUseAllWords()) {
185             for (Iterator JavaDoc iter = eachWordMap.values().iterator(); iter.hasNext(); ) {
186                 if (postsIds == null) {
187                     postsIds = new HashSet JavaDoc(eachWordMap.values().size());
188                     postsIds.addAll((HashSet JavaDoc)iter.next());
189                 }
190                 else {
191                     postsIds.retainAll((HashSet JavaDoc)iter.next());
192                 }
193             }
194         }
195         else {
196             postsIds = new HashSet JavaDoc();
197             
198             for (Iterator JavaDoc iter = eachWordMap.values().iterator(); iter.hasNext(); ) {
199                 postsIds.addAll((HashSet JavaDoc)iter.next());
200             }
201         }
202         
203         if (postsIds == null || postsIds.size() == 0) {
204             return;
205         }
206         
207         // Time to get ready to search for the topics ids
208
StringBuffer JavaDoc sb = new StringBuffer JavaDoc(1024);
209         for (Iterator JavaDoc iter = postsIds.iterator(); iter.hasNext(); ) {
210             sb.append(iter.next()).append(",");
211         }
212         sb.delete(sb.length() - 1, sb.length());
213
214         // Search for the ids, inserting them in the helper table
215
sql = SystemGlobals.getSql("SearchModel.insertTopicsIds");
216         sql = sql.replaceAll(":posts:", sb.toString());
217         
218         p = JForumExecutionContext.getConnection().prepareStatement(sql);
219         p.setString(1, SessionFacade.getUserSession().getSessionId());
220         
221         p.executeUpdate();
222         
223         // Now that we have the topics ids, it's time to make a copy from the
224
// topics table, to make the search faster
225
this.selectTopicData();
226         
227         p.close();
228     }
229     
230     private void selectTopicData() throws Exception JavaDoc
231     {
232         PreparedStatement JavaDoc p = JForumExecutionContext.getConnection().prepareStatement(SystemGlobals.getSql("SearchModel.selectTopicData"));
233         p.setString(1, SessionFacade.getUserSession().getSessionId());
234         p.setString(2, SessionFacade.getUserSession().getSessionId());
235         p.executeUpdate();
236         
237         p.close();
238     }
239     
240
241     /**
242      * @see net.jforum.dao.SearchDAO#cleanSearch()
243      */

244     public void cleanSearch() throws Exception JavaDoc
245     {
246         PreparedStatement JavaDoc p = JForumExecutionContext.getConnection().prepareStatement(SystemGlobals.getSql("SearchModel.cleanSearchTopics"));
247         p.setString(1, SessionFacade.getUserSession().getSessionId());
248         p.executeUpdate();
249         p.close();
250         
251         p = JForumExecutionContext.getConnection().prepareStatement(SystemGlobals.getSql("SearchModel.cleanSearchResults"));
252         p.setString(1, SessionFacade.getUserSession().getSessionId());
253         p.executeUpdate();
254         p.close();
255     }
256 }
257
Popular Tags