Java tutorial
/* * WebimController.java * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package webim.controller; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.json.JSONObject; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.servlet.ModelAndView; import webim.WebimConfig; import webim.client.WebimClient; import webim.client.WebimCluster; import webim.model.WebimEndpoint; import webim.model.WebimMember; import webim.model.WebimRoom; import webim.model.WebimHistory; import webim.model.WebimMenu; import webim.model.WebimMessage; import webim.model.WebimNotification; import webim.model.WebimPresence; import webim.model.WebimStatus; import webim.service.WebimModel; import webim.service.WebimPlugin; import webim.service.WebimVisitorManager; @Controller() @RequestMapping("/Webim") public class WebimController { public static final String SUCCESS = "ok"; @Resource(name = "webimConfig") private WebimConfig config; @Resource(name = "webimModel") private WebimModel model; @Resource(name = "webimPlugin") private WebimPlugin plugin; @Resource(name = "webimCluster") private WebimCluster cluster; @Resource(name = "webimVisitorManager") private WebimVisitorManager visitorManager; public WebimController() { } /** * ?Webim * * @param request * HTTP * @return Webim() */ private WebimEndpoint currentEndpoint(HttpServletRequest request, HttpServletResponse response) throws Exception { WebimEndpoint ep = this.plugin.endpoint(request); if (ep == null && config.getBoolean("enable_visitor")) { ep = this.visitorManager.endpoint(request, response); } return ep; } /** * ?Webim * * @param ticket * * @return ?Webim */ private WebimClient client(HttpServletRequest request, HttpServletResponse response, String ticket) throws Exception { return client(currentEndpoint(request, response), request, ticket); } /** * ??endpoint?ticketWebimClient * * @param ep * ?endpoint * @param ticket * ticket * @return WebimClient */ private WebimClient client(WebimEndpoint ep, HttpServletRequest request, String ticket) { WebimClient client = new WebimClient(ep, (String) this.config.get("domain"), (String) this.config.get("apikey"), cluster); client.setTicket(ticket); return client; } @RequestMapping("/boot") public ModelAndView boot(HttpServletRequest request, HttpServletResponse response) throws Exception { // System.out.println(message); WebimEndpoint endpoint = currentEndpoint(request, response); response.setHeader("Cache-Control", "no-cache"); Map<String, Object> data = new HashMap<String, Object>(); String[] keys = new String[] { "version", "theme", "local", "emot", "opacity", "enable_room", "enable_discussion", "enable_chatlink", "enable_chatbtn", "enable_shortcut", "enable_noti", "enable_menu", "show_unavailable", "upload" }; for (String key : keys) { data.put(key, this.config.get(key)); } // System.out.println(request.getContextPath()); data.put("context_path", request.getContextPath()); data.put("is_login", "1"); data.put("is_visitor", this.visitorManager.isVid(endpoint.getId())); data.put("login_options", ""); data.put("jsonp", this.config.getBoolean("jsonp")); data.put("setting", this.model.getSetting(endpoint.getId())); return new ModelAndView("Webim/boot", data); } @RequestMapping(value = "/chatbox", method = RequestMethod.GET) public ModelAndView chatbox(HttpServletRequest request, HttpServletResponse response) throws Exception { Map<String, Object> data = new HashMap<String, Object>(); WebimEndpoint endpoint = currentEndpoint(request, response); String uid = request.getParameter("uid"); List<WebimEndpoint> buddies = plugin.buddiesByIds(endpoint.getId(), new String[] { uid }); data.put("uid", uid); data.put("context_path", request.getContextPath()); if (buddies.size() > 0) { WebimEndpoint buddy = buddies.get(0); data.put("nick", buddy.getNick()); data.put("avatar", buddy.getAvatar()); return new ModelAndView("Webim/chatbox", data); } return new ModelAndView("Webim/notfound", data); } @RequestMapping(value = "/online", method = RequestMethod.POST) @ResponseBody public Map<String, Object> online(HttpServletRequest request, HttpServletResponse response) throws Exception { System.out.println("online....."); WebimEndpoint endpoint = currentEndpoint(request, response); String uid = endpoint.getId(); String show = request.getParameter("show"); if (show != null) { endpoint.setShow(show); } Map<String, Object> data = new HashMap<String, Object>(); List<WebimEndpoint> buddies = this.plugin.buddies(uid); //pending buddies ids that need to read buddy Set<String> pendingIds = new HashSet<String>(); String chatlinkIds = request.getParameter("chatlink_ids"); if (chatlinkIds != null) { for (String id : chatlinkIds.split(",")) { pendingIds.add(id); } ; } List<WebimHistory> offlineHistories = this.model.offlineHistories(uid, 100); for (WebimHistory h : offlineHistories) { pendingIds.add(h.getFrom()); } pendingIds.removeAll(buddyIds(buddies)); if (pendingIds.size() > 0) { buddies.addAll(this.plugin.buddiesByIds(uid, pendingIds.toArray(new String[pendingIds.size()]))); } List<WebimRoom> rooms = this.plugin.rooms(uid); rooms.addAll(this.model.rooms(uid)); // Forward Online to IM Server WebimClient client = this.client(endpoint, request, ""); Set<String> buddyIds = buddyIds(buddies); Set<String> roomIds = roomIds(rooms); try { data = client.online(buddyIds, roomIds); System.out.println(data.toString()); // Online Buddies Map<String, WebimEndpoint> buddyMap = new HashMap<String, WebimEndpoint>(); for (WebimEndpoint e : buddies) { buddyMap.put(e.getId(), e); } @SuppressWarnings("unchecked") Map<String, String> presences = (Map<String, String>) data.get("presences"); Iterator<String> it = presences.keySet().iterator(); while (it.hasNext()) { String key = it.next(); WebimEndpoint buddy = buddyMap.get(key); show = presences.get(key); if (!show.equals("invisible")) { buddy.setPresence("online"); buddy.setShow(show); } } Collection<WebimEndpoint> rtBuddies; if (this.config.getBoolean("show_unavailable")) { rtBuddies = buddyMap.values(); } else { rtBuddies = new ArrayList<WebimEndpoint>(); for (WebimEndpoint e : buddyMap.values()) { if (e.getPresence() == "online") rtBuddies.add(e); } } // need test this.model.offlineHistoriesReaded(uid); //data.remove("presences"); data.put("buddies", rtBuddies.toArray()); data.put("rooms", rooms.toArray()); data.put("new_messages", offlineHistories.toArray()); data.put("server_time", System.currentTimeMillis()); // TODO: / data.put("user", endpoint); } catch (Exception e) { e.printStackTrace(); data.put("success", false); data.put("error_msg", "IM Server is not found"); } return data; } @RequestMapping(value = "/offline", method = RequestMethod.POST) @ResponseBody public String offline(HttpServletRequest request, HttpServletResponse response) throws Exception { String ticket = request.getParameter("ticket"); WebimClient c = this.client(request, response, ticket); c.offline(); return SUCCESS; } @RequestMapping(value = "/refresh", method = RequestMethod.POST) @ResponseBody public String refresh(HttpServletRequest request, HttpServletResponse response) throws Exception { String ticket = request.getParameter("ticket"); WebimClient c = this.client(request, response, ticket); c.offline(); return SUCCESS; } @RequestMapping(value = "/message", method = RequestMethod.POST) @ResponseBody public Map<String, String> message(HttpServletRequest request, HttpServletResponse response) throws Exception { request.setCharacterEncoding("UTF-8"); Map<String, String> rtData = new HashMap<String, String>(); WebimEndpoint endpoint = currentEndpoint(request, response); String uid = endpoint.getId(); String ticket = request.getParameter("ticket"); String type = request.getParameter("type"); if (type == null) type = "chat"; String offline = request.getParameter("offline"); String to = request.getParameter("to"); String body = request.getParameter("body"); String style = request.getParameter("style"); if (style == null) style = ""; if (!this.model.isBuddy(uid, to)) { this.model.addBuddy(uid, to); } if (!plugin.checkCensor(body)) { rtData.put("status", "error"); rtData.put("message", "?????"); return rtData; } if (plugin.isRobotSupport() && plugin.isFromRobot(to)) { WebimClient c = this.client(endpoint, request, null); WebimMessage requestMsg = new WebimMessage(to, c.getEndpoint().getNick(), body, style, System.currentTimeMillis()); this.model.insertHistory(uid, requestMsg); String answer = plugin.getRobot().answer(body); WebimMessage answermsg = new WebimMessage(uid, plugin.getRobot().getNick(), answer, "", System.currentTimeMillis()); c.push(to, answermsg); this.model.insertHistory(to, answermsg); } else { WebimClient c = this.client(endpoint, request, ticket); WebimMessage msg = new WebimMessage(to, c.getEndpoint().getNick(), body, style, System.currentTimeMillis()); msg.setType(type); msg.setOffline("true".equals(offline) ? true : false); c.publish(msg); if (body != null && !body.startsWith("webim-event:")) { this.model.insertHistory(uid, msg); } } rtData.put("status", "ok"); return rtData; } @RequestMapping(value = "/presence", method = RequestMethod.POST) @ResponseBody public String presence(HttpServletRequest request, HttpServletResponse response) throws Exception { String ticket = request.getParameter("ticket"); String show = request.getParameter("show"); String status = request.getParameter("status"); if (status == null) status = ""; WebimClient c = this.client(request, response, ticket); c.publish(new WebimPresence(show, status)); return SUCCESS; } @RequestMapping(value = "/status", method = RequestMethod.POST) @ResponseBody public String status(HttpServletRequest request, HttpServletResponse response) throws Exception { String ticket = request.getParameter("ticket"); String to = request.getParameter("to"); String show = request.getParameter("show"); String status = request.getParameter("status"); if (status == null) status = ""; WebimClient c = this.client(request, response, ticket); c.publish(new WebimStatus(to, show, status)); return SUCCESS; } @RequestMapping(value = "/buddies", method = RequestMethod.GET) @ResponseBody public List<WebimEndpoint> buddies(HttpServletRequest request, HttpServletResponse response) throws Exception { WebimEndpoint endpoint = currentEndpoint(request, response); String ticket = request.getParameter("ticket"); String[] ids = request.getParameter("ids").split(","); // user id list List<String> uids = new ArrayList<String>(); // visitor id list List<String> vids = new ArrayList<String>(); for (String id : ids) { if (this.visitorManager.isVid(id)) { vids.add(id); } else { uids.add(id); } } // read buddies from user service List<WebimEndpoint> buddies = plugin.buddiesByIds(endpoint.getId(), uids.toArray(new String[uids.size()])); //TODO: read visitors from 'webim_visitors' table buddies.addAll(model.visitors(vids.toArray(new String[vids.size()]))); Set<String> buddyIds = buddyIds(buddies); // feed presence JSONObject presences = this.client(request, response, ticket).presences(buddyIds); for (WebimEndpoint buddy : buddies) { String id = buddy.getId(); if (presences.has(id)) { String show = presences.getString(id); if (!"invisible".equals(show)) { buddy.setPresence("online"); buddy.setShow(show); } } } return buddies; } @RequestMapping(value = "/search", method = RequestMethod.GET) @ResponseBody public List<WebimEndpoint> search(HttpServletRequest request, HttpServletResponse response) throws Exception { String nick = request.getParameter("nick"); List<WebimEndpoint> buddies = plugin.search(nick); return buddies; } @RequestMapping(value = "/history", method = RequestMethod.GET) @ResponseBody public List<WebimHistory> history(HttpServletRequest request, HttpServletResponse response) throws Exception { WebimEndpoint endpoint = currentEndpoint(request, response); String with = request.getParameter("id"); String type = request.getParameter("type"); if (plugin.isRobotSupport() && with.equals(plugin.getRobot().getId())) { //String[] askList = plugin.getRobot().getAskList(); //TODO: ??, //??,? } return this.model.histories(endpoint.getId(), with, type, 50); } @RequestMapping(value = "/history/clear", method = RequestMethod.POST) @ResponseBody public String clearHistory(HttpServletRequest request, HttpServletResponse response) throws Exception { WebimEndpoint endpoint = currentEndpoint(request, response); String with = request.getParameter("id"); this.model.clearHistories(endpoint.getId(), with); return SUCCESS; } @RequestMapping("/history/download") // @ResponseBody public ModelAndView downloadHistory(HttpServletRequest request, HttpServletResponse response) throws Exception { WebimEndpoint endpoint = currentEndpoint(request, response); String with = request.getParameter("id"); String type = request.getParameter("type"); response.setHeader("Content-Type", "text/html; charset=utf-8"); response.setHeader("Content-Disposition", "attachment; filename=\"histories.html\""); List<WebimHistory> histories = this.model.histories(endpoint.getId(), with, type, 1000); return new ModelAndView("Webim/download_history", "histories", histories); } @RequestMapping(value = "/room/invite", method = RequestMethod.POST) @ResponseBody public WebimRoom inviteRoom(HttpServletRequest request, HttpServletResponse response) throws Exception { WebimEndpoint endpoint = currentEndpoint(request, response); String uid = endpoint.getId(); String roomId = request.getParameter("id"); String nick = request.getParameter("nick"); String ticket = request.getParameter("ticket"); WebimClient c = this.client(request, response, ticket); WebimRoom room = this.model.findRoom(roomId); if (room != null) { room = this.model.createRoom(uid, roomId, nick); } this.model.joinRoom(roomId, uid, c.getEndpoint().getNick()); String[] memberIds = request.getParameter("members").split(","); List<WebimEndpoint> members = this.plugin.buddiesByIds(uid, memberIds); this.model.inviteRoom(roomId, members); // send invite message to members for (WebimEndpoint m : members) { String body = "webim-event:invite|,|" + roomId + "|,|" + nick; c.publish(new WebimMessage(m.getId(), c.getEndpoint().getNick(), body, "", System.currentTimeMillis())); } c.join(roomId); return room; } @RequestMapping(value = "/room/join", method = RequestMethod.POST) @ResponseBody public WebimRoom joinRoom(HttpServletRequest request, HttpServletResponse response) throws Exception { // String uid = this.currentUid(); String id = request.getParameter("id"); // String nick = request.getParameter("nick"); String ticket = request.getParameter("ticket"); WebimRoom room = this.plugin.findRoom(id); if (room == null) { room = this.model.findRoom(id); } // TODO: write database if (room != null) { this.client(request, response, ticket).join(id); } return room; } @RequestMapping(value = "/room/members", method = RequestMethod.GET) @ResponseBody public List<WebimMember> roomMembers(HttpServletRequest request, HttpServletResponse response) throws Exception { String roomId = request.getParameter("id"); String ticket = request.getParameter("ticket"); WebimRoom room = this.plugin.findRoom(roomId); List<WebimMember> members = null; if (room != null) { members = this.plugin.members(roomId); } else { room = this.model.findRoom(roomId); if (room != null) { members = this.model.members(roomId); } } if (room == null) return null; JSONObject presences = this.client(request, response, ticket).members(roomId); for (WebimMember member : members) { String mid = member.getId(); if (presences.has(mid)) { String show = presences.getString(mid); if (!"invisible".equals(show)) { member.setPresence("online"); member.setShow(presences.getString(mid)); } } } return members; } @RequestMapping(value = "/room/leave", method = RequestMethod.POST) @ResponseBody public String leaveRoom(HttpServletRequest request, HttpServletResponse response) throws Exception { WebimEndpoint endpoint = currentEndpoint(request, response); String room = request.getParameter("id"); String ticket = request.getParameter("ticket"); this.model.leaveRoom(room, endpoint.getId()); WebimClient c = this.client(endpoint, request, ticket); c.leave(room); return SUCCESS; } @RequestMapping(value = "/room/block", method = RequestMethod.POST) @ResponseBody public String blockRoom(HttpServletRequest request, HttpServletResponse response) throws Exception { WebimEndpoint endpoint = currentEndpoint(request, response); String room = request.getParameter("id"); this.model.blockRoom(room, endpoint.getId()); return SUCCESS; } @RequestMapping(value = "/room/unblock", method = RequestMethod.POST) @ResponseBody public String unblockRoom(HttpServletRequest request, HttpServletResponse response) throws Exception { WebimEndpoint endpoint = currentEndpoint(request, response); String room = request.getParameter("id"); this.model.unblockRoom(room, endpoint.getId()); return SUCCESS; } @RequestMapping("/upload") @ResponseBody public ModelAndView upload(HttpServletRequest request, HttpServletResponse response) { // TODO: return new ModelAndView("Webim/upload"); } @RequestMapping(value = "/setting", method = RequestMethod.POST) @ResponseBody public String setting(HttpServletRequest request, HttpServletResponse response) throws Exception { WebimEndpoint endpoint = currentEndpoint(request, response); String data = request.getParameter("data"); this.model.saveSetting(endpoint.getId(), data); return SUCCESS; } @RequestMapping(value = "/notifications", method = RequestMethod.GET) @ResponseBody public List<WebimNotification> notifications(HttpServletRequest request, HttpServletResponse response) throws Exception { WebimEndpoint endpoint = currentEndpoint(request, response); return this.plugin.notifications(endpoint.getId()); } @RequestMapping(value = "/menu", method = RequestMethod.GET) @ResponseBody public Collection<WebimMenu> menu(HttpServletRequest request, HttpServletResponse response) throws Exception { WebimEndpoint endpoint = currentEndpoint(request, response); return this.plugin.menu(endpoint.getId()); } private Set<String> buddyIds(List<WebimEndpoint> buddies) { Set<String> ids = new HashSet<String>(); for (WebimEndpoint b : buddies) { ids.add(b.getId()); } return ids; } private Set<String> roomIds(List<WebimRoom> rooms) { Set<String> ids = new HashSet<String>(); for (WebimRoom g : rooms) { ids.add(g.getId()); } return ids; } }