com.rivetlogic.portlet.whiteboard.atmosphere.WhiteboardHandler.java Source code

Java tutorial

Introduction

Here is the source code for com.rivetlogic.portlet.whiteboard.atmosphere.WhiteboardHandler.java

Source

/**
 * Copyright (C) 2005-2014 Rivet Logic Corporation.
 * 
 * This program 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; version 3 of the License.
 * 
 * This program 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
 * this program; if not, write to the Free Software Foundation, Inc., 51
 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

package com.rivetlogic.portlet.whiteboard.atmosphere;

import com.liferay.portal.kernel.cache.MultiVMPoolUtil;
import com.liferay.portal.kernel.cache.PortalCache;
import com.liferay.portal.kernel.json.JSONException;
import com.liferay.portal.kernel.json.JSONFactoryUtil;
import com.liferay.portal.kernel.json.JSONObject;
import com.liferay.portal.kernel.language.LanguageUtil;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.util.LocaleUtil;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.model.User;
import com.liferay.portal.model.UserConstants;
import com.liferay.portal.service.UserLocalServiceUtil;
import com.liferay.portal.util.PortalUtil;

import java.io.IOException;
import java.net.URLDecoder;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ConcurrentSkipListMap;

import org.atmosphere.client.TrackMessageSizeInterceptor;
import org.atmosphere.config.service.AtmosphereHandlerService;
import org.atmosphere.config.service.Singleton;
import org.atmosphere.cpr.AtmosphereResource;
import org.atmosphere.cpr.AtmosphereResourceEvent;
import org.atmosphere.handler.AtmosphereHandlerAdapter;
import org.atmosphere.interceptor.AtmosphereResourceLifecycleInterceptor;
import org.atmosphere.interceptor.BroadcastOnPostAtmosphereInterceptor;
import org.atmosphere.interceptor.SuspendTrackerInterceptor;
import org.atmosphere.util.SimpleBroadcaster;

@Singleton

@AtmosphereHandlerService(path = "/", supportSession = true, interceptors = {
        AtmosphereResourceLifecycleInterceptor.class, TrackMessageSizeInterceptor.class,
        BroadcastOnPostAtmosphereInterceptor.class,
        SuspendTrackerInterceptor.class }, broadcaster = SimpleBroadcaster.class)

public class WhiteboardHandler extends AtmosphereHandlerAdapter {

    public static final String CACHE_NAME = WhiteboardHandler.class.getName();
    private static final String ENCODING = "UTF-8";
    private static final String DUMP_MESSAGE = "dump";
    private static final Log LOG = LogFactoryUtil.getLog(WhiteboardHandler.class);
    @SuppressWarnings("rawtypes")
    private static PortalCache portalCache = MultiVMPoolUtil.getCache(CACHE_NAME);

    @SuppressWarnings("unchecked")
    private ConcurrentMap<String, UserData> getLoggedUsersMap() {

        Object object = portalCache.get(WhiteboardHandlerUtil.LOGGED_USERS_MAP_KEY);
        ConcurrentMap<String, UserData> loggedUserMap = (ConcurrentMap<String, UserData>) object;
        if (null == loggedUserMap) {
            loggedUserMap = new ConcurrentSkipListMap<String, UserData>();
            portalCache.put(WhiteboardHandlerUtil.LOGGED_USERS_MAP_KEY, loggedUserMap);
        }
        return loggedUserMap;
    }

    @SuppressWarnings("unchecked")
    private ConcurrentMap<String, JSONObject> getWhiteBoardDump() {
        Object object = portalCache.get(WhiteboardHandlerUtil.WHITEBOARD_DUMP_KEY);
        ConcurrentMap<String, JSONObject> whiteBoardDump = (ConcurrentMap<String, JSONObject>) object;
        if (null == whiteBoardDump) {
            whiteBoardDump = new ConcurrentSkipListMap<String, JSONObject>();
            portalCache.put(WhiteboardHandlerUtil.WHITEBOARD_DUMP_KEY, whiteBoardDump);
        }
        return whiteBoardDump;
    }

    @Override
    public void onRequest(AtmosphereResource resource) throws IOException {

        ConcurrentMap<String, UserData> loggedUserMap = getLoggedUsersMap();

        String userName = StringPool.BLANK;
        String userImagePath = StringPool.BLANK;

        // user joined
        String sessionId = resource.session().getId();
        if (loggedUserMap.get(sessionId) == null) {

            try {

                String baseImagePath = URLDecoder
                        .decode(resource.getRequest().getParameter(WhiteboardHandlerUtil.BASE_IMAGEPATH), ENCODING);
                LOG.debug("base image path " + baseImagePath);

                User user = PortalUtil.getUser(resource.getRequest());
                long companyId = PortalUtil.getCompanyId(resource.getRequest());

                if (user == null || user.isDefaultUser()) {
                    LOG.debug("This is guest user");
                    user = UserLocalServiceUtil.getDefaultUser(companyId);
                    userName = LanguageUtil.get(LocaleUtil.getDefault(),
                            WhiteboardHandlerUtil.GUEST_USER_NAME_LABEL);
                } else {
                    userName = user.getFullName();
                }

                userImagePath = UserConstants.getPortraitURL(baseImagePath, user.isMale(), user.getPortraitId());

                LOG.debug(String.format("User full name: %s, User image path: %s", userName, userImagePath));
            } catch (Exception e) {
                LOG.error(e.getMessage());
            }

            loggedUserMap.put(resource.session().getId(), new UserData(userName, userImagePath));

            /* listens to disconnection event */
            resource.addEventListener(new WhiteBoardResourceEventListener(loggedUserMap, sessionId));
        }
    }

    @Override
    public void onStateChange(AtmosphereResourceEvent event) throws IOException {

        ConcurrentMap<String, UserData> loggedUserMap = getLoggedUsersMap();
        ConcurrentMap<String, JSONObject> whiteBoardDump = getWhiteBoardDump();

        /* messages broadcasting */
        if (event.isSuspended()) {
            String message = event.getMessage() == null ? StringPool.BLANK : event.getMessage().toString();

            if (!message.equals(StringPool.BLANK)) {

                try {
                    JSONObject jsonMessage = JSONFactoryUtil.createJSONObject(message);
                    /* verify if user is signing in */
                    if (WhiteboardHandlerUtil.LOGIN.equals(jsonMessage.getString(WhiteboardHandlerUtil.TYPE))) {
                        JSONObject usersLoggedMessage = WhiteboardHandlerUtil
                                .generateLoggedUsersJSON(loggedUserMap);
                        /* adds whiteboard dump to the message */
                        usersLoggedMessage.put(DUMP_MESSAGE,
                                WhiteboardHandlerUtil.loadWhiteboardDump(whiteBoardDump));
                        event.getResource().getBroadcaster().broadcast(usersLoggedMessage);
                    } else {
                        /* just broadcast the message */
                        LOG.debug("Broadcasting = " + message);
                        /* adds whiteboard updates to the dump */
                        WhiteboardHandlerUtil.persistWhiteboardDump(whiteBoardDump, jsonMessage);
                        event.getResource().write(message);
                    }
                } catch (JSONException e) {
                    LOG.debug("JSON parse failed");
                }
            }
        }
    }
}