webim.controller.WebimController.java Source code

Java tutorial

Introduction

Here is the source code for webim.controller.WebimController.java

Source

/*
 * 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;
    }

}