Package com.pusher.client.channel.impl

Source Code of com.pusher.client.channel.impl.PresenceChannelImpl

package com.pusher.client.channel.impl;

import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.google.gson.Gson;
import com.pusher.client.AuthorizationFailureException;
import com.pusher.client.Authorizer;
import com.pusher.client.channel.ChannelEventListener;
import com.pusher.client.channel.PresenceChannel;
import com.pusher.client.channel.PresenceChannelEventListener;
import com.pusher.client.channel.SubscriptionEventListener;
import com.pusher.client.channel.User;
import com.pusher.client.connection.impl.InternalConnection;
import com.pusher.client.util.Factory;

public class PresenceChannelImpl extends PrivateChannelImpl implements
        PresenceChannel {

    private static final String MEMBER_ADDED_EVENT = "pusher_internal:member_added";
    private static final String MEMBER_REMOVED_EVENT = "pusher_internal:member_removed";

    private final Map<String, User> idToUserMap = Collections.synchronizedMap(new LinkedHashMap<String, User>());

    private String myUserID;

    public PresenceChannelImpl(InternalConnection connection, String channelName,
            Authorizer authorizer, Factory factory) {
        super(connection, channelName, authorizer, factory);
    }

    /* PresenceChannel implementation */

    @Override
    public Set<User> getUsers() {
        return new LinkedHashSet<User>(idToUserMap.values());
    }

    @Override
    public User getMe() {
        return idToUserMap.get(myUserID);
    }

    /* Base class overrides */

    @Override
    public void onMessage(String event, String message) {

        super.onMessage(event, message);

        if (event.equals(SUBSCRIPTION_SUCCESS_EVENT)) {
            handleSubscriptionSuccessfulMessage(message);
        } else if (event.equals(MEMBER_ADDED_EVENT)) {
            handleMemberAddedEvent(message);
        } else if (event.equals(MEMBER_REMOVED_EVENT)) {
            handleMemberRemovedEvent(message);
        }
    }

    @Override
    @SuppressWarnings("rawtypes")
    public String toSubscribeMessage() {

        String authResponse = getAuthResponse();

        try {
            Map authResponseMap = new Gson().fromJson(authResponse, Map.class);
            String authKey = (String) authResponseMap.get("auth");
            Object channelData = authResponseMap.get("channel_data");

            storeMyUserId(channelData);

            Map<Object, Object> jsonObject = new LinkedHashMap<Object, Object>();
            jsonObject.put("event", "pusher:subscribe");

            Map<Object, Object> dataMap = new LinkedHashMap<Object, Object>();
            dataMap.put("channel", name);
            dataMap.put("auth", authKey);
            dataMap.put("channel_data", channelData);

            jsonObject.put("data", dataMap);

            String json = new Gson().toJson(jsonObject);

            return json;
        } catch (Exception e) {
            throw new AuthorizationFailureException(
                    "Unable to parse response from Authorizer: " + authResponse, e);
        }
    }

    @Override
    public void bind(String eventName, SubscriptionEventListener listener) {

        if ((listener instanceof PresenceChannelEventListener) == false) {
            throw new IllegalArgumentException(
                    "Only instances of PresenceChannelEventListener can be bound to a presence channel");
        }

        super.bind(eventName, listener);
    }

    @Override
    protected String[] getDisallowedNameExpressions() {
        return new String[] { "^(?!presence-).*" };
    }

    @Override
    public String toString() {
        return String.format("[Presence Channel: name=%s]", name);
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    private void handleSubscriptionSuccessfulMessage(String message) {

        // extract data from the JSON message
        Map presenceMap = extractPresenceMapFrom(message);

        List<String> ids = (List<String>) presenceMap.get("ids");
        Map<String, ?> hash = (Map<String, ?>)presenceMap.get("hash");

        // build the collection of Users
        for (String id : ids) {
            String userData = (hash.get(id) != null) ? new Gson().toJson(hash.get(id)) : null;
            User user = new User(id, userData);
            idToUserMap.put(id, user);
        }

        ChannelEventListener listener = this.getEventListener();
        if (listener != null) {
            PresenceChannelEventListener presenceListener = (PresenceChannelEventListener)listener;
            presenceListener.onUsersInformationReceived(getName(), getUsers());
        }
    }

    @SuppressWarnings("rawtypes")
    private void handleMemberAddedEvent(String message) {

        Map dataMap = extractDataMapFrom(message);
        String id = String.valueOf(dataMap.get("user_id"));
        String userData = (dataMap.get("user_info") != null) ? new Gson().toJson(dataMap.get("user_info")) : null;

        final User user = new User(id, userData);
        idToUserMap.put(id, user);

        ChannelEventListener listener = this.getEventListener();
        if (listener != null) {
            PresenceChannelEventListener presenceListener = (PresenceChannelEventListener)listener;
            presenceListener.userSubscribed(getName(), user);
        }
    }

    @SuppressWarnings("rawtypes")
    private void handleMemberRemovedEvent(String message) {

        Map dataMap = extractDataMapFrom(message);
        String id = String.valueOf(dataMap.get("user_id"));

        final User user = idToUserMap.remove(id);

        ChannelEventListener listener = this.getEventListener();
        if( listener != null ) {
            PresenceChannelEventListener presenceListener = (PresenceChannelEventListener)listener;
            presenceListener.userUnsubscribed(getName(), user);
        }
    }

    @SuppressWarnings("rawtypes")
    private static Map extractDataMapFrom(String message) {
        Gson gson = new Gson();
        Map jsonObject = gson.fromJson(message, Map.class);
        String dataString = (String) jsonObject.get("data");

        Map dataMap = gson.fromJson(dataString, Map.class);
        return dataMap;
    }

    @SuppressWarnings("rawtypes")
    private static Map extractPresenceMapFrom(String message) {

        Map dataMap = extractDataMapFrom(message);
        Map presenceMap = (Map) dataMap.get("presence");

        return presenceMap;
    }

    @SuppressWarnings("rawtypes")
    private void storeMyUserId(Object channelData) {
        Map channelDataMap = new Gson().fromJson(((String) channelData), Map.class);
        myUserID = String.valueOf(channelDataMap.get("user_id"));
    }
}
TOP

Related Classes of com.pusher.client.channel.impl.PresenceChannelImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.