//$Header: /cvsroot-fuse/mec-as2/39/mendelson/util/clientserver/ClientSessionHandler.java,v 1.1 2012/04/18 14:10:41 heller Exp $ package de.mendelson.util.clientserver; import de.mendelson.util.clientserver.messages.ClientServerMessage; import de.mendelson.util.clientserver.messages.ClientServerResponse; import de.mendelson.util.clientserver.messages.LoginState; import de.mendelson.util.clientserver.messages.ServerLogMessage; import java.util.Map; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import java.util.logging.Level; import org.apache.mina.core.service.IoHandlerAdapter; import org.apache.mina.core.session.IoSession; /* * Copyright (C) mendelson-e-commerce GmbH Berlin Germany * * This software is subject to the license agreement set forth in the license. * Please read and agree to all terms before using this software. * Other product and brand names are trademarks of their respective owners. */ /** * Client side protocol handler * @author S.Heller * @version $Revision: 1.1 $ */ public class ClientSessionHandler extends IoHandlerAdapter { /**Callback that is used for event notification*/ private final ClientSessionHandlerCallback callback; /**stores the sync requests*/ private Map<Long, BlockingQueue<ClientServerResponse>> syncMap = new ConcurrentHashMap<Long, BlockingQueue<ClientServerResponse>>(); /**Indicates if the server log messages should be displayed in the client log*/ private boolean displayServerLogMessages = true; public ClientSessionHandler(ClientSessionHandlerCallback callback) { this.callback = callback; } /**Indicates if server log messages should be displayed in the client or * simply ignored*/ public void setDisplayServerLogMessages(boolean flag) { this.displayServerLogMessages = flag; } @Override public void sessionCreated(IoSession session) throws Exception { } @Override public void sessionOpened(IoSession session) throws Exception { this.callback.connected(session.getRemoteAddress()); } @Override public void messageSent(IoSession session, Object messageObj) { } @Override public void messageReceived(IoSession session, Object messageObj) throws Exception { if (messageObj == null) { this.callback.getLogger().log(Level.WARNING, "ClientSessionHandler.messageReceived: Received null type message."); return; } if (!(messageObj instanceof ClientServerMessage)) { this.callback.getLogger().log(Level.WARNING, "ClientSessionHandler.messageReceived: Client server message type is not supported: " + messageObj.getClass().getName()); return; } ClientServerMessage message = (ClientServerMessage) messageObj; //sync response: check if there was a request for this message if (message._isSyncRequest()) { ClientServerResponse response = (ClientServerResponse) message; if (!this.syncMap.containsKey(response.getReferenceId())) { Exception unreferredSyncResponse = new Exception("The client received a unreferred sync response. Type: " + response.getClass().getName() + ", reference id: " + response.getReferenceId()); this.callback.syncRequestFailed(unreferredSyncResponse); } BlockingQueue queue = this.syncMap.get(response.getReferenceId()); queue.offer(response); } if (message instanceof LoginState) { LoginState state = (LoginState) message; if (state.getState() == LoginState.STATE_AUTHENTICATION_SUCCESS) { this.callback.loggedIn(state.getUser()); } else if (state.getState() == LoginState.STATE_AUTHENTICATION_FAILURE_PASSWORD_REQUIRED) { this.callback.loginFailureServerRequestsPassword(state.getUser().getName()); } else if (state.getState() == LoginState.STATE_INCOMPATIBLE_CLIENT) { this.callback.loginFailureIncompatibleClient(); } else if (state.getState() == LoginState.STATE_AUTHENTICATION_REQUIRED) { this.callback.loginRequestedFromServer(); } else { //STATE_AUTHENTICATION_FAILURE callback.loginFailure(state.getUser().getName()); } } else if (message instanceof ServerLogMessage) { if (this.displayServerLogMessages) { //server log messages are just passed through to the client log if requested ServerLogMessage serverMessage = (ServerLogMessage) message; this.callback.getLogger().log(serverMessage.getLevel(), serverMessage.getMessage(), serverMessage.getParameter()); } } else { this.callback.messageReceivedFromServer((ClientServerMessage) message); } } @Override public void sessionClosed(IoSession session) throws Exception { callback.disconnected(); } /** * waits a specified time for an inbound message, used for sync processing*/ public ClientServerResponse waitForSyncAnswer(Long referenceId, long timeoutInMS) throws Exception { if (!this.syncMap.containsKey(referenceId)) { Exception unreferredSyncResponse = new Exception("ClientSessionHandler.waitForSyncAnswer: " + "The message that should be waited for is unreferred." + " Reference id: " + referenceId); this.callback.syncRequestFailed(unreferredSyncResponse); } BlockingQueue<ClientServerResponse> queue = this.syncMap.get(referenceId); ClientServerResponse response = queue.poll(timeoutInMS, TimeUnit.MILLISECONDS); return (response); } public void addSyncRequest(ClientServerMessage request) { BlockingQueue<ClientServerResponse> queue = new LinkedBlockingQueue<ClientServerResponse>(1); this.syncMap.put(request.getReferenceId(), queue); } public void removeSyncRequest(ClientServerMessage request) { if (!this.syncMap.containsKey(request.getReferenceId())) { Exception unreferredSyncResponse = new Exception("ClientSessionHandler.removeSyncRequest: " + "The message to remove from the sync map does not exist. " + " Reference id: " + request.getReferenceId()); this.callback.syncRequestFailed(unreferredSyncResponse); } BlockingQueue<ClientServerMessage> queue = new LinkedBlockingQueue<ClientServerMessage>(1); this.syncMap.remove(request.getReferenceId()); } /**Inform the callback that a sync request failed*/ public void syncRequestFailed(Throwable throwable) { this.callback.syncRequestFailed(throwable); } @Override public void exceptionCaught(IoSession session, Throwable cause) { cause.printStackTrace(); } }