Java tutorial
/* This file is part of OpenMyEWB. OpenMyEWB is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OpenMyEWB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenMyEWB. If not, see <http://www.gnu.org/licenses/>. OpenMyEWB is Copyright 2005-2009 Nicolas Kruchten (nicolas@kruchten.com), Francis Kung, Engineers Without Borders Canada, Michael Trauttmansdorff, Jon Fishbein, David Kadish */ package ca.myewb.controllers.home; import java.math.BigInteger; import java.net.URLDecoder; import java.net.URLEncoder; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.Vector; import org.apache.velocity.context.Context; import org.hibernate.Hibernate; import org.hibernate.Query; import ca.myewb.frame.Controller; import ca.myewb.frame.Permissions; import ca.myewb.frame.PostParamWrapper; import ca.myewb.frame.RedirectionException; import ca.myewb.frame.forms.SearchForm; import ca.myewb.model.EventModel; import ca.myewb.model.GroupModel; import ca.myewb.model.PostModel; import ca.myewb.model.WhiteboardModel; public class Search extends Controller { private String[] types = { "Posts", "Events", "Whiteboards" }; public void handle(Context ctx) throws Exception { if ((requestParams.get("Body") != null) && !requestParams.get("Body").equals("")) { throw new RedirectionException(path + "/home/Search/" + encode(requestParams)); } urlParams.processParams(new String[] { "filter", "pagenum" }, new String[] { "", "1" }); HashMap<String, String> terms = decode(urlParams.get("filter")); if (terms.get("Body").equals("")) { ctx.put("noterms", true); } else { ctx.put("noterms", false); int pagesize = 30; int start = 1; try { start = new Integer(urlParams.get("pagenum")).intValue(); } catch (Exception e) { start = 1; } if (start < 1) { start = 1; } int pageStart = (start - 1) * pagesize; int numSearchables = numMatchingSearchables(terms); ctx.put("searchables", matchingSearchables(terms, pageStart, pagesize)); int numPages = (numSearchables / pagesize); if ((numSearchables % pagesize) != 0) { numPages++; } ctx.put("pageNum", new Integer(start)); ctx.put("pageSize", new Integer(pagesize)); ctx.put("numPages", new Integer(numPages)); ctx.put("filterParam", urlParams.get("filter")); ctx.put("numSearchables", new Integer(numSearchables)); } ctx.put("form", new SearchForm(path + "/home/Search/", terms)); } private List matchingSearchables(HashMap<String, String> terms, int pageStart, int pagesize) { String sql = "select parentPost, parentEvent, parentWhiteboard " + getCommonQueryPart(terms) + " limit :start, :limit"; Query query = hibernateSession.createSQLQuery(sql).addScalar("parentPost", Hibernate.INTEGER) .addScalar("parentEvent", Hibernate.INTEGER).addScalar("parentWhiteboard", Hibernate.INTEGER) .setString("terms", terms.get("Body")).setInteger("start", pageStart).setInteger("limit", pagesize); if (!terms.get("Since").equals("")) query.setString("since", terms.get("Since")); List searchableIDs = query.list(); Vector<Object> searchables = new Vector<Object>(); for (Object temp : searchableIDs) { Object[] idArray = (Object[]) temp; Integer parentPostId = (Integer) idArray[0]; Integer parentEventId = (Integer) idArray[1]; Integer parentWhiteboardId = (Integer) idArray[2]; if (parentPostId != null) { searchables.add(hibernateSession.load(PostModel.class, parentPostId)); } else if (parentEventId != null) { searchables.add(hibernateSession.load(EventModel.class, parentEventId)); } else if (parentWhiteboardId != null) { searchables.add(hibernateSession.load(WhiteboardModel.class, parentWhiteboardId)); } } return searchables; } private String getCommonQueryPart(HashMap<String, String> terms) { String sql = " from searchables where match(body) against (:terms) "; if (!currentUser.isAdmin()) { sql += " AND (groupid IN ("; Iterator<GroupModel> groups = Permissions.visibleGroups(currentUser, true, false).iterator(); sql += groups.next().getId(); while (groups.hasNext()) { sql += ", " + groups.next().getId(); } sql += ")) "; } if (!terms.get("Posts").equals("on")) sql += " and parentPost is null "; if (!terms.get("Events").equals("on")) sql += " and parentEvent is null "; if (!terms.get("Whiteboards").equals("on")) sql += " and parentWhiteboard is null "; if (!terms.get("Since").equals("")) sql += " and date >= :since "; return sql; } private int numMatchingSearchables(HashMap<String, String> terms) { String sql = "select count(*) " + getCommonQueryPart(terms); Query query = hibernateSession.createSQLQuery(sql).setString("terms", terms.get("Body")); if (!terms.get("Since").equals("")) query.setString("since", terms.get("Since")); return ((BigInteger) query.uniqueResult()).intValue(); } public HashMap<String, String> decode(String searchTerm) throws Exception { HashMap<String, String> lines = new HashMap<String, String>(); lines.put("Body", ""); lines.put("Since", ""); lines.put("Mask", "111"); String[] keys = searchTerm.split("&"); for (int i = 0; i < keys.length; i++) { String line = keys[i]; String[] keyValue = line.split("="); lines.put(keyValue[0], keyValue.length > 1 ? URLDecoder.decode(keyValue[1], "UTF-8") : ""); } String mask = lines.remove("Mask"); if (mask.equals("000")) mask = "111"; for (int i = 0; i < types.length; i++) { if (mask.charAt(i) == '1') lines.put(types[i], "on"); else lines.put(types[i], ""); } return lines; } private String encode(PostParamWrapper requestParams) throws Exception { String bodyTerm = requestParams.get("Body") != null ? URLEncoder.encode(requestParams.get("Body").replaceAll("/", " "), "UTF-8") : ""; String sinceTerm = requestParams.get("Since") != null ? URLEncoder.encode(requestParams.get("Since"), "UTF-8") : ""; String mask = ""; for (String type : types) { if (requestParams.get(type) != null && requestParams.get(type).equals("on")) mask += "1"; else mask += "0"; } return "Body=" + bodyTerm + "&Since=" + sinceTerm + "&Mask=" + mask; } public Set<String> invisibleGroups() { Set<String> s = new HashSet<String>(); s.add("Org"); return s; } public String displayName() { return "Search"; } }