PageRenderTime 91ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/src/main/java/cn/javaeye/lonlysky/lforum/service/SearchManager.java

http://fishkang.googlecode.com/
Java | 469 lines | 358 code | 53 blank | 58 comment | 69 complexity | a43bb87b8131ad03c936059a39f2f8d2 MD5 | raw file
Possible License(s): Apache-2.0, LGPL-2.1
  1. package cn.javaeye.lonlysky.lforum.service;
  2. import java.util.ArrayList;
  3. import java.util.Calendar;
  4. import java.util.List;
  5. import java.util.Map;
  6. import java.util.regex.Matcher;
  7. import java.util.regex.Pattern;
  8. import org.hibernate.ObjectNotFoundException;
  9. import org.hibernate.SessionFactory;
  10. import org.slf4j.Logger;
  11. import org.slf4j.LoggerFactory;
  12. import org.springframework.beans.factory.annotation.Autowired;
  13. import org.springframework.stereotype.Service;
  14. import org.springframework.transaction.annotation.Transactional;
  15. import org.springside.modules.orm.hibernate.SimpleHibernateTemplate;
  16. import cn.javaeye.lonlysky.lforum.comm.LForumRequest;
  17. import cn.javaeye.lonlysky.lforum.comm.utils.Utils;
  18. import cn.javaeye.lonlysky.lforum.entity.forum.Searchcaches;
  19. import cn.javaeye.lonlysky.lforum.entity.forum.Usergroups;
  20. import cn.javaeye.lonlysky.lforum.entity.forum.Users;
  21. import cn.javaeye.lonlysky.lforum.entity.global.SearchType;
  22. /**
  23. * ?????
  24. *
  25. * @author fishkang
  26. *
  27. */
  28. @Service
  29. @Transactional
  30. public class SearchManager {
  31. private static final Logger logger = LoggerFactory.getLogger(SearchManager.class);
  32. private SimpleHibernateTemplate<Searchcaches, Integer> searchcacheDAO;
  33. @Autowired
  34. public void setSessionFactory(SessionFactory sessionFactory) {
  35. searchcacheDAO = new SimpleHibernateTemplate<Searchcaches, Integer>(sessionFactory, Searchcaches.class);
  36. }
  37. private Pattern regexForumTopics = Pattern.compile("<ForumTopics>([\\s\\S]+?)</ForumTopics>");
  38. /**
  39. * ?????????????
  40. */
  41. public void deleteExpriedSearchCache() {
  42. Calendar calendar = Calendar.getInstance();
  43. calendar.add(Calendar.MINUTE, -30);
  44. int result = searchcacheDAO.createQuery("delete from Searchcaches where expiration<?",
  45. Utils.dateFormat(calendar.getTime(), Utils.FULL_DATEFORMAT)).executeUpdate();
  46. if (logger.isDebugEnabled()) {
  47. logger.debug("??????????????{}", result);
  48. }
  49. }
  50. private StringBuilder getSearchByPosterResult(List<Object[]> objList) {
  51. StringBuilder strTids = new StringBuilder("<ForumTopics>");
  52. if (objList != null) {
  53. for (Object[] objects : objList) {
  54. strTids.append(objects[0] + ",");
  55. }
  56. }
  57. if (strTids.toString().endsWith(",")) {
  58. strTids.setLength(strTids.length() - 1);
  59. }
  60. strTids.append("</ForumTopics>");
  61. if (logger.isDebugEnabled()) {
  62. logger.debug("???????????" + strTids.toString());
  63. }
  64. return strTids;
  65. }
  66. /**
  67. * ??????????
  68. * @param userid ??id
  69. * @param usergroupid ???id
  70. * @param keyword ???
  71. * @param posterid ???id
  72. * @param type ????
  73. * @param searchforumid ????id
  74. * @param keywordtype ?????
  75. * @param searchtime ????
  76. * @param searchtimetype ??????
  77. * @param resultorder ??????
  78. * @param resultordertype ??????
  79. * @return ???????searchid, ????-1
  80. */
  81. @SuppressWarnings("unchecked")
  82. public int search(int userid, int usergroupid, String keyword, int posterid, String type, String searchforumid,
  83. int keywordtype, int searchtime, int searchtimetype, int resultorder, int resultordertype) {
  84. // ??30???????????
  85. deleteExpriedSearchCache();
  86. String hql = "";
  87. StringBuilder strTids = new StringBuilder();
  88. SearchType searchType = SearchType.TopicTitle;
  89. switch (keywordtype) {
  90. case 0:
  91. searchType = SearchType.PostTitle;
  92. if (type.equals("digest")) {
  93. searchType = SearchType.DigestTopic;
  94. }
  95. break;
  96. case 1:
  97. searchType = SearchType.PostContent;
  98. break;
  99. case 8:
  100. searchType = SearchType.ByPoster;
  101. break;
  102. }
  103. if (searchType == SearchType.DigestTopic) {
  104. hql = getSearchTopicTitleHQL(posterid, searchforumid, resultorder, resultordertype, 1, keyword);
  105. } else if (searchType == SearchType.TopicTitle || searchType == SearchType.PostTitle) {
  106. hql = getSearchTopicTitleHQL(posterid, searchforumid, resultorder, resultordertype, 0, keyword);
  107. } else if (searchType == SearchType.PostContent) {
  108. hql = getSearchPostContentHQL(posterid, searchforumid, resultorder, resultordertype, searchtime,
  109. searchtimetype, new StringBuilder(keyword));
  110. } else if (searchType == SearchType.ByPoster) {
  111. hql = getSearchByPosterHQL(posterid);
  112. } else {
  113. hql = getSearchTopicTitleHQL(posterid, searchforumid, resultorder, resultordertype, 0, keyword);
  114. }
  115. if (hql.equals("")) {
  116. return -1;
  117. }
  118. int searchid = Utils.null2Int(searchcacheDAO.createQuery(
  119. "select searchid from Searchcaches where searchstring=? and usergroups.groupid=?", hql, usergroupid)
  120. .setMaxResults(1).uniqueResult());
  121. if (searchid > -1) {
  122. return searchid;
  123. }
  124. List objList = searchcacheDAO.find(hql);
  125. int rowcount = 0;
  126. if (objList != null) {
  127. if (searchType == SearchType.ByPoster) {
  128. strTids = getSearchByPosterResult(objList);
  129. Searchcaches cacheinfo = new Searchcaches();
  130. cacheinfo.setKeywords(keyword);
  131. cacheinfo.setSearchstring(hql);
  132. cacheinfo.setPostdatetime(Utils.getNowTime());
  133. cacheinfo.setTopics(rowcount);
  134. cacheinfo.setTids(strTids.toString());
  135. Users users = new Users();
  136. users.setUid(userid);
  137. cacheinfo.setUsers(users);
  138. Usergroups usergroups = new Usergroups();
  139. usergroups.setGroupid(usergroupid);
  140. cacheinfo.setUsergroups(usergroups);
  141. cacheinfo.setIp(LForumRequest.getIp());
  142. cacheinfo.setExpiration(Utils.getNowTime());
  143. return createSearchCache(cacheinfo);
  144. } else {
  145. strTids.append("<ForumTopics>");
  146. }
  147. for (Object objects : objList) {
  148. if (objects instanceof Object[]) {
  149. Object[] obj = (Object[]) objects;
  150. strTids.append(obj[0]);
  151. } else {
  152. strTids.append(objects);
  153. }
  154. strTids.append(",");
  155. rowcount++;
  156. }
  157. if (rowcount > 0) {
  158. strTids.deleteCharAt(strTids.length() - 1);
  159. strTids.append("</ForumTopics>");
  160. Searchcaches cacheinfo = new Searchcaches();
  161. cacheinfo.setKeywords(keyword);
  162. cacheinfo.setSearchstring(hql);
  163. cacheinfo.setPostdatetime(Utils.getNowTime());
  164. cacheinfo.setTopics(rowcount);
  165. cacheinfo.setTids(strTids.toString());
  166. Users users = new Users();
  167. users.setUid(userid);
  168. cacheinfo.setUsers(users);
  169. Usergroups usergroups = new Usergroups();
  170. usergroups.setGroupid(usergroupid);
  171. cacheinfo.setUsergroups(usergroups);
  172. cacheinfo.setIp(LForumRequest.getIp());
  173. cacheinfo.setExpiration(Utils.getNowTime());
  174. return createSearchCache(cacheinfo);
  175. }
  176. }
  177. return -1;
  178. }
  179. /**
  180. * ??????
  181. * @param cacheinfo ??????
  182. * @return ??????
  183. */
  184. public int createSearchCache(Searchcaches cacheinfo) {
  185. searchcacheDAO.save(cacheinfo);
  186. return cacheinfo.getSearchid();
  187. }
  188. private String getSearchByPosterHQL(int posterid) {
  189. if (posterid > 0) {
  190. String hql = "select distinct topics.tid, 'forum' as datafrom from Posts where users.uid=" + posterid
  191. + " and topics.tid not in (select tid from Topics where usersByPosterid.uid=" + posterid
  192. + " and displayorder<0)";
  193. return hql;
  194. }
  195. return "";
  196. }
  197. private String getSearchPostContentHQL(int posterid, String searchforumid, int resultorder, int resultordertype,
  198. int searchtime, int searchtimetype, StringBuilder strKeyWord) {
  199. StringBuilder strHQL = new StringBuilder();
  200. String orderfield = "lastpost";
  201. switch (resultorder) {
  202. case 1:
  203. orderfield = "tid";
  204. break;
  205. case 2:
  206. orderfield = "replies";
  207. break;
  208. case 3:
  209. orderfield = "views";
  210. break;
  211. default:
  212. orderfield = "lastpost";
  213. break;
  214. }
  215. strHQL.append("select distinct topics.tid,topics." + orderfield
  216. + " from Posts where topics.displayorder>=0 and ");
  217. if (!searchforumid.equals("")) {
  218. strHQL.append("forums.fid in (");
  219. strHQL.append(searchforumid);
  220. strHQL.append(") and ");
  221. }
  222. if (posterid != -1) {
  223. strHQL.append("users.uid=");
  224. strHQL.append(posterid);
  225. strHQL.append(" and ");
  226. }
  227. if (searchtime != 0) {
  228. strHQL.append("postdatetime");
  229. if (searchtimetype == 1) {
  230. strHQL.append("<'");
  231. } else {
  232. strHQL.append(">'");
  233. }
  234. Calendar calendar = Calendar.getInstance();
  235. calendar.add(Calendar.DAY_OF_MONTH, searchtime);
  236. strHQL.append(Utils.dateFormat(calendar.getTime(), Utils.SHORT_DATEFORMAT) + " 00:00:00");
  237. strHQL.append("'and ");
  238. }
  239. String[] keywordlist = strKeyWord.toString().split(" ");
  240. strKeyWord = new StringBuilder();
  241. for (int i = 0; i < keywordlist.length; i++) {
  242. strKeyWord.append(" or ");
  243. strKeyWord.append("message like '%");
  244. strKeyWord.append(keywordlist[i]);
  245. strKeyWord.append("%' ");
  246. }
  247. strHQL.append(strKeyWord.toString().substring(3));
  248. strHQL.append("order by topics.");
  249. switch (resultorder) {
  250. case 1:
  251. strHQL.append("tid");
  252. break;
  253. case 2:
  254. strHQL.append("replies");
  255. break;
  256. case 3:
  257. strHQL.append("views");
  258. break;
  259. default:
  260. strHQL.append("lastpost");
  261. break;
  262. }
  263. if (resultordertype == 1) {
  264. strHQL.append(" asc");
  265. } else {
  266. strHQL.append(" desc");
  267. }
  268. return strHQL.toString();
  269. }
  270. /**
  271. * ???????????HQL??
  272. * @param posterid
  273. * @param searchforumid
  274. * @param resultorder
  275. * @param resultordertype
  276. * @param digest
  277. * @param keyword
  278. * @return
  279. */
  280. private String getSearchTopicTitleHQL(int posterid, String searchforumid, int resultorder, int resultordertype,
  281. int digest, String keyword) {
  282. keyword = keyword.replaceAll("--|;|'|\"", "");
  283. // ??????
  284. keyword.replace("'", "''");
  285. StringBuilder strKeyWord = new StringBuilder(keyword);
  286. StringBuilder strHQL = new StringBuilder();
  287. strHQL.append("select tid from Topics where displayorder>=0");
  288. if (posterid > 0) {
  289. strHQL.append(" and posterid=");
  290. strHQL.append(posterid);
  291. }
  292. if (digest > 0) {
  293. strHQL.append(" and digest>0 ");
  294. }
  295. if (!searchforumid.equals("")) {
  296. strHQL.append(" and forums.fid in (");
  297. strHQL.append(searchforumid);
  298. strHQL.append(")");
  299. }
  300. String[] keywordlist = strKeyWord.toString().split(" ");
  301. strKeyWord = new StringBuilder();
  302. if (keyword.length() > 0) {
  303. strKeyWord.append(" and (1=0 ");
  304. for (int i = 0; i < keywordlist.length; i++) {
  305. strKeyWord.append(" or title ");
  306. strKeyWord.append("like '%");
  307. strKeyWord.append(keywordlist[i]);
  308. strKeyWord.append("%' ");
  309. }
  310. strKeyWord.append(")");
  311. }
  312. strHQL.append(strKeyWord.toString());
  313. strHQL.append(" order by ");
  314. switch (resultorder) {
  315. case 1:
  316. strHQL.append("tid");
  317. break;
  318. case 2:
  319. strHQL.append("replies");
  320. break;
  321. case 3:
  322. strHQL.append("views");
  323. break;
  324. default:
  325. strHQL.append("postdatetime");
  326. break;
  327. }
  328. if (resultordertype == 1) {
  329. strHQL.append(" asc");
  330. } else {
  331. strHQL.append(" desc");
  332. }
  333. return strHQL.toString();
  334. }
  335. /**
  336. * ???????????
  337. * @param searchid ?????searchid
  338. * @param pagesize ??????
  339. * @param pageindex ????
  340. * @param topiccountmap ?????
  341. * @param type ????
  342. * @return ???????
  343. */
  344. @SuppressWarnings("unchecked")
  345. public List getSearchCacheList(int searchid, int pagesize, int pageindex, Map<Integer, Integer> topiccountmap,
  346. String type) {
  347. if (logger.isDebugEnabled()) {
  348. logger.debug("???????,ID?{},TYPE?{}", searchid, type);
  349. }
  350. topiccountmap.put(0, 0);
  351. String cachedidlist;
  352. try {
  353. Searchcaches caches = searchcacheDAO.get(searchid);
  354. cachedidlist = caches.getTids();
  355. } catch (ObjectNotFoundException e) {
  356. return new ArrayList();
  357. }
  358. Matcher m;
  359. m = regexForumTopics.matcher(cachedidlist);
  360. if (m.find()) {
  361. String tids = getCurrentPageTids(m.group(1), topiccountmap, pagesize, pageindex);
  362. if (tids.equals("")) {
  363. return new ArrayList();
  364. }
  365. if (type.equals("digest")) {
  366. return searchcacheDAO
  367. .createQuery(
  368. "select tid, title, poster, usersByPosterid.uid, postdatetime, replies, views, lastpost,lastposter,usersByLastposterid.uid, forums.fid,forums.name from Topics as topic where tid in("
  369. + tids + ")").setMaxResults(pagesize).list();
  370. }
  371. if (type.equals("post")) {
  372. return searchcacheDAO
  373. .createQuery(
  374. "select topics.tid, title, poster, users.uid, postdatetime,lastedit, rate, ratetimes,topics.usersByLastposterid.uid forums.fid,forums.name from Posts as post where pid in("
  375. + tids + ")").setMaxResults(pagesize).list();
  376. } else {
  377. return searchcacheDAO
  378. .createQuery(
  379. "select tid, title, poster, usersByPosterid.uid, postdatetime, replies, views, lastpost,lastposter,usersByLastposterid.uid, forums.fid,forums.name from Topics as topic where tid in("
  380. + tids + ")").setMaxResults(pagesize).list();
  381. }
  382. }
  383. return new ArrayList();
  384. }
  385. /**
  386. * ??????Tid??
  387. * @param tids ??Tid??
  388. * @param topiccountmap
  389. * @param pagesize
  390. * @param pageindex
  391. * @return
  392. */
  393. private String getCurrentPageTids(String tids, Map<Integer, Integer> topiccountmap, int pagesize, int pageindex) {
  394. String[] tid = tids.split(",");
  395. topiccountmap.put(0, tid.length);
  396. int pagecount = tid.length % pagesize == 0 ? tid.length / pagesize : tid.length / pagesize + 1;
  397. if (pagecount < 1) {
  398. pagecount = 1;
  399. }
  400. if (pageindex > pagecount) {
  401. pageindex = pagecount;
  402. }
  403. int startindex = pagesize * (pageindex - 1);
  404. StringBuilder strTids = new StringBuilder();
  405. for (int i = startindex; i < tid.length; i++) {
  406. if (i > startindex + pagesize) {
  407. break;
  408. } else {
  409. strTids.append(tid[i]);
  410. strTids.append(",");
  411. }
  412. }
  413. strTids.deleteCharAt(strTids.length() - 1);
  414. return strTids.toString();
  415. }
  416. }