Package de.novanic.gwteventservice.demo.conversationapp.client.conversation.control

Source Code of de.novanic.gwteventservice.demo.conversationapp.client.conversation.control.ConversationControl

/*
* GWTEventService
* Copyright (c) 2011 and beyond, strawbill UG (haftungsbeschr�nkt)
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 3 of
* the License, or (at your option) any later version.
* Other licensing for GWTEventService may also be possible on request.
* Please view the license.txt of the project for more information.
*
* This software 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package de.novanic.gwteventservice.demo.conversationapp.client.conversation.control;

import com.google.gwt.user.client.rpc.ServiceDefTarget;
import de.novanic.eventservice.client.ClientHandler;
import de.novanic.gwteventservice.demo.conversationapp.client.conversation.ui.*;
import de.novanic.gwteventservice.demo.conversationapp.client.conversation.ui.message.MessageButtonListener;
import de.novanic.gwteventservice.demo.conversationapp.client.conversation.ui.message.MessageBoxCreator;
import de.novanic.gwteventservice.demo.conversationapp.client.conversation.ui.message.MessageBox;
import de.novanic.gwteventservice.demo.conversationapp.client.conversation.ConversationServiceAsync;
import de.novanic.gwteventservice.demo.conversationapp.client.conversation.ConversationService;
import de.novanic.gwteventservice.demo.conversationapp.client.conversation.Channel;
import de.novanic.gwteventservice.demo.conversationapp.client.conversation.event.ConversationEvent;
import de.novanic.gwteventservice.demo.conversationapp.client.conversation.event.ConversationListenerAdapter;
import de.novanic.gwteventservice.demo.conversationapp.client.conversation.event.UserUnlistenEvent;
import de.novanic.gwteventservice.demo.conversationapp.client.conversation.event.filter.ChannelEventFilter;
import de.novanic.eventservice.client.event.RemoteEventService;
import de.novanic.eventservice.client.event.RemoteEventServiceFactory;
import de.novanic.eventservice.client.event.listener.unlisten.UnlistenEvent;
import de.novanic.eventservice.client.event.listener.unlisten.UnlistenEventListenerAdapter;
import de.novanic.eventservice.client.event.domain.DomainFactory;
import de.novanic.eventservice.client.event.domain.Domain;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.logical.shared.CloseHandler;
import com.google.gwt.event.logical.shared.CloseEvent;

import java.util.List;

/**
* @author sstrohschein
*         <br>Date: 16.09.2008
*         <br>Time: 23:34:40
*/
public class ConversationControl
{
    private static final Domain CONVERSATION_DOMAIN = DomainFactory.getDomain(ConversationEvent.CONVERSATION_DOMAIN);
    private static final String GLOBAL_CHANNEL = "GlobalChannel";

    private ConversationMainPanel myConversationMainPanel;
    private ConversationServiceAsync myConversationService;
    private RemoteEventService myRemoteEventService;
    private Channel myChannel;
    private String myUser;

    public ConversationControl(ConversationMainPanel aConversationMainPanel) {
        myConversationMainPanel = aConversationMainPanel;

        myConversationService = (ConversationServiceAsync)mapService(GWT.create(ConversationService.class), "conversationport");

        final RemoteEventServiceFactory theRemoteEventHandlerFactory = RemoteEventServiceFactory.getInstance();
        myRemoteEventService = theRemoteEventHandlerFactory.getRemoteEventService();

        theRemoteEventHandlerFactory.requestClientHandler(new DefaultAsyncCallback<ClientHandler>() {
            public void onSuccess(ClientHandler aClientHandler) {
                //create an event execution service (that is only necessary when user-specific events or user-specific EventFilters
                // must dynamically changeable at the server-side).
                theRemoteEventHandlerFactory.registerClientSpecificHandler((ServiceDefTarget)myConversationService, aClientHandler);

                //custom logic for the UI control
                initUILogic();
            }
        });
    }

    private void init() {
        myRemoteEventService.addUnlistenListener(new UnlistenEventListenerAdapter() {
            public void onUnlisten(UnlistenEvent anUnlistenEvent) {
                String theUserName = ((UserUnlistenEvent)anUnlistenEvent).getUserName();
                if(myUser.equals(theUserName)) {
                    if(anUnlistenEvent.isLocal()) {
                        writeLocalSystemMessage("A connection error is occurred!");
                    } else if(anUnlistenEvent.isTimeout()) {
                        toggleLoginStateUI(myConversationMainPanel.getConversationLoginPanel(), false);
                        writeLocalSystemMessage("A server side timeout is occurred! You need to login again.");
                    }
                }
                myConversationMainPanel.getConversationChannelPanel().removeContact(theUserName);
            }
        }, new UserUnlistenEvent(myUser), new VoidAsyncCallback<Void>());

        myRemoteEventService.addListener(CONVERSATION_DOMAIN, new DefaultConversationListener(), new ChannelEventFilter(GLOBAL_CHANNEL), new DefaultAsyncCallback<Void>() {
            public void onSuccess(Void aResult) {
                final ConversationChannelPanel theChannelPanel = myConversationMainPanel.getConversationChannelPanel();

                joinChannel(GLOBAL_CHANNEL, new DefaultAsyncCallback<Channel>() {
                    public void onSuccess(Channel aResult) {
                        init(myConversationMainPanel.getConversationMessagePanel());
                        init(theChannelPanel);
                    }
                });
                requestChannelList(new DefaultAsyncCallback<List<Channel>>() {
                    public void onSuccess(List<Channel> aChannelList) {
                        fillChannelList(theChannelPanel, aChannelList);
                    }
                });
            }
        });
    }

    private void init(final ConversationMessagePanel aConversationMessagePanel) {
        aConversationMessagePanel.addSendButtonListener(new ClickHandler() {
            public void onClick(ClickEvent aClickEvent) {
                final String theMessage = aConversationMessagePanel.getMessageText();
                if(theMessage.trim().length() > 0) {
                    myConversationService.sendMessage(myUser, theMessage, new VoidAsyncCallback<Void>());
                    aConversationMessagePanel.resetMessageText();
                }
            }
        });
    }

    private void init(final ConversationChannelPanel aConversationChannelPanel) {
        aConversationChannelPanel.addAddChannelButtonListener(new ClickHandler() {
            public void onClick(ClickEvent aClickEvent) {
                final ConversationChannelCreatorDialog theConversationChannelCreatorDialog = new GWTConversationChannelCreatorDialog();
                theConversationChannelCreatorDialog.addCloseHandler(new CloseHandler<PopupPanel>() {
                    public void onClose(CloseEvent aCloseEvent) {
                        if(!theConversationChannelCreatorDialog.isCanceled()) {
                            //the new channel can be got with from the EventService and the user is joined by the server (ConversationService)
                            myConversationService.createChannel(myUser, theConversationChannelCreatorDialog.getChannelName(), new DefaultAsyncCallback<Channel>() {
                                public void onSuccess(Channel aNewChannel) {
                                    switchChannel(aNewChannel);
                                }
                            });
                        }
                    }
                });
                theConversationChannelCreatorDialog.show();
            }
        });

        aConversationChannelPanel.addChannelSelectListener(new ChannelSelectListener() {
            public void onSelect(final String aChannel) {
                if(myChannel != null && !aChannel.equals(myChannel.getName())) {
                    final MessageBox theMessageBox = MessageBoxCreator.createYesNoMessage("Join channel \"" + aChannel + "\"?");
                    theMessageBox.addButtonListener(new MessageButtonListener() {
                        public void onClick(Button aButton) {
                            switch(aButton) {
                                case YES:
                                    myConversationService.join(myUser, aChannel, new VoidAsyncCallback<Channel>());
                                default:
                                    theMessageBox.close();
                            }
                        }
                    });
                }
            }
        });
    }

    private boolean login() {
        myUser = myConversationMainPanel.getConversationLoginPanel().getNicknameText();
        if(myUser == null || myUser.trim().length() <= 0) {
            MessageBoxCreator.createOkMessage("The username is empty. Please choose a username.");
            return false;
        } else if(myConversationMainPanel.getConversationChannelPanel().getContacts().contains(myUser)) {
            MessageBoxCreator.createOkMessage("The username does already exist. Please choose another username.");
            return false;
        } else {
            init();
            return true;
        }
    }

    private boolean logout() {
        myConversationService.leave(myUser, new VoidAsyncCallback<Void>());
        myRemoteEventService.removeListeners(CONVERSATION_DOMAIN, new VoidAsyncCallback<Void>());
        myRemoteEventService.removeUnlistenListeners(new VoidAsyncCallback<Void>());
        return true;
    }

    private void toggleLoginStateUI(ConversationLoginPanel aConversationLoginPanel, boolean isLoginMode) {
        aConversationLoginPanel.toggle(!isLoginMode);
        myConversationMainPanel.getConversationMessagePanel().enable(isLoginMode);
        myConversationMainPanel.getConversationChannelPanel().enable(isLoginMode);
        myConversationMainPanel.reset();
    }

    private void joinChannel(String aChannelName, AsyncCallback<Channel> aCallback) {
        myConversationService.join(myUser, aChannelName, aCallback);
        myConversationMainPanel.getConversationChannelPanel().addContact(aChannelName, myUser);
    }

    private void initUILogic() {
        requestChannelList(new DefaultAsyncCallback<List<Channel>>() {
            public void onSuccess(List<Channel> aChannelList) {

                final ConversationLoginPanel theLoginPanel = myConversationMainPanel.getConversationLoginPanel();
                theLoginPanel.addLoginButtonListener(new ClickHandler() {
                    public void onClick(ClickEvent aClickEvent) {
                        final boolean isLoginMode = theLoginPanel.isLogin();
                        boolean isActionSuccessful;
                        if(isLoginMode) {
                            //in case of login mode
                            isActionSuccessful = login();
                        } else {
                            //in case of logout mode
                            isActionSuccessful = logout();
                        }
                        if(isActionSuccessful) {
                            toggleLoginStateUI(theLoginPanel, isLoginMode);
                            myConversationMainPanel.clearMessageHistory();
                        }
                    }
                });
            }
        });
    }

    private void requestChannelList(AsyncCallback<List<Channel>> aCallback) {
        myConversationService.getChannels(aCallback);
    }

    private void writeMessage(String aMessage) {
        writeMessage(null, aMessage);
    }

    private void writeMessage(String aUser, String aMessage) {
        String theMessage = aMessage;
        if(aUser != null) {
            theMessage = aUser + ": " + theMessage;
        }
        myConversationMainPanel.addMessageHistoryText(theMessage);
        myConversationMainPanel.getConversationMessagePanel().setFocus(true);
    }

    private void writeLocalSystemMessage(String aMessage) {
        writeMessage("SYSTEM", aMessage);
    }

    private void switchChannel(Channel aNewChannel) {
        myChannel = aNewChannel;
        myConversationMainPanel.clearMessageHistory();
    }

    private ServiceDefTarget mapService(Object aService, String aServiceMappingName) {
        String theServiceURL = GWT.getModuleBaseURL() + aServiceMappingName;
        ServiceDefTarget theServiceEndPoint = (ServiceDefTarget)aService;
        theServiceEndPoint.setServiceEntryPoint(theServiceURL);
        return theServiceEndPoint;
    }

    private void fillChannelList(ConversationChannelPanel aChannelPanel, List<Channel> aChannelList) {
        for(Channel theChannel: aChannelList) {
            final String theChannelName = theChannel.getName();
            aChannelPanel.addChannel(theChannelName);
            for(String theContact: theChannel.getContacts()) {
                aChannelPanel.addContact(theChannelName, theContact);
            }
        }
    }

    private abstract class DefaultAsyncCallback<T> implements AsyncCallback<T>
    {
        public void onFailure(Throwable aThrowable) {
            GWT.log("Error on processing conversation!", aThrowable);
        }
    }

    private class VoidAsyncCallback<T> extends DefaultAsyncCallback<T>
    {
        public void onSuccess(T aResult) {}
    }

    private class DefaultConversationListener extends ConversationListenerAdapter
    {
        public void newChannel(Channel aChannel) {
            myConversationMainPanel.getConversationChannelPanel().addChannel(aChannel.getName());
        }

        public void removedChannel(Channel aChannel) {
            myConversationMainPanel.getConversationChannelPanel().removeChannel(aChannel.getName());
        }

        public void userEntered(Channel aChannel, String aUser) {
            addUser(aChannel, aUser);
        }

        public void userLeaved(Channel aChannel, String aUser) {
            removeUser(aChannel, aUser);
        }

        public void newMessage(Channel aChannel, String aSender, String aMessage) {
            //to check the channel isn't required, because it is guaranteed by the ChannelEventFilter
            writeMessage(aSender, aMessage);
        }

        private void addUser(Channel aChannel, String aUser) {
            //switch the own channel
            if(myUser.equals(aUser)) {
                switchChannel(aChannel);
            }

            //add the contact to the channel bar
            final String theChannelName = aChannel.getName();
            myConversationMainPanel.getConversationChannelPanel().addContact(theChannelName, aUser);

            //write the entered message, if it is the current channel
            if(aChannel.equals(myChannel)) {
                writeMessage(aUser + " entered channel \"" + theChannelName + "\".");
            }
        }

        private void removeUser(Channel aChannel, String aUser) {
            //remove the contact from the channel bar
            myConversationMainPanel.getConversationChannelPanel().removeContact(aUser);

            //write the leaved message, if it is the current channel
            if(aChannel != null && aChannel.equals(myChannel)) {
                final String theChannelName = aChannel.getName();
                writeMessage(aUser + " leaved channel \"" + theChannelName + "\".");
            }
        }
    }
}
TOP

Related Classes of de.novanic.gwteventservice.demo.conversationapp.client.conversation.control.ConversationControl

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.