/* * DrakkarKeel - An Enterprise Collaborative Search Platform * * The contents of this file are subject under the terms described in the * DRAKKARKEEL_LICENSE file included in this distribution; you may not use this * file except in compliance with the License. * * 2013-2014 DrakkarKeel Platform. */ package drakkar.stern.servant.service; import drakkar.oar.Response; import drakkar.oar.Seeker; import drakkar.oar.exception.SeekerException; import drakkar.oar.exception.SessionException; import drakkar.oar.slice.client.ClientSidePrx; import static drakkar.oar.util.KeyTransaction.*; import static drakkar.oar.util.NotifyAction.*; import drakkar.oar.util.OutputMonitor; import drakkar.stern.callback.NotifyAMICallback; import drakkar.stern.controller.DataBaseController; import drakkar.stern.facade.event.FacadeListener; import drakkar.stern.tracker.cache.Count; import drakkar.stern.tracker.cache.SeekerInfo; import drakkar.stern.tracker.cache.SessionProfile; import java.io.IOException; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * The <code>Tracker</code> class is.... * Esta clase implementa todos los métodos de mensajería soportados por el * framework DrakkarKeel, además de ofrecer información sobre los mismos */ public class Messenger extends Service implements Sendable { /** * Esta variable representa el número de mensajes enviados durante la actual * sesión del servidor */ private long messagesCount = 0; /** * Constructor de la clase * * @param defaultSessionName * @param collaborativeSessions listado de sesiones * @param defaultSessionProfile */ public Messenger(String defaultSessionName, SessionProfile defaultSessionProfile, Map<String, SessionProfile> collaborativeSessions, Map<String, SessionProfile> htTempSessions) { super(defaultSessionName, defaultSessionProfile, collaborativeSessions, htTempSessions); } /** * Constructor de la clase * * @param defaultSessionName * @param defaultSessionProfile * @param collaborativeSessions listado de sesiones * @param dbController */ public Messenger(String defaultSessionName, SessionProfile defaultSessionProfile, Map<String, SessionProfile> collaborativeSessions, Map<String, SessionProfile> htTempSessions, DataBaseController dbController) { super(defaultSessionName, defaultSessionProfile, collaborativeSessions, htTempSessions, dbController); } /** * Constructor de la clase * * @param defaultSessionName * @param collaborativeSessions listado de sesiones * @param defaultSessionProfile * @param listener oyente de la aplicación servidora * @param dbController */ public Messenger(String defaultSessionName, SessionProfile defaultSessionProfile, Map<String, SessionProfile> collaborativeSessions, Map<String, SessionProfile> htTempSessions, FacadeListener listener, DataBaseController dbController) { super(defaultSessionName, defaultSessionProfile, collaborativeSessions, htTempSessions, listener, dbController); } /** * {@inheritDoc} */ public void sendMessage(String sessionName, Seeker emitter, String message) throws SessionException, SeekerException, IOException { SessionProfile recordSession = getSessionProfile(sessionName); SeekerInfo seekersRecord = recordSession.getSeekerInfo(); boolean flag = seekersRecord.record.containsKey(emitter); if (flag) { int countMembers = seekersRecord.record.size(); if (countMembers > 1) { Map<Seeker, ClientSidePrx> record = seekersRecord.record; @SuppressWarnings("unchecked") List<Seeker> receptors = new ArrayList<>(record.keySet()); receptors.remove(emitter); Response response = this.buildResponse(sessionName, emitter, message); byte[] array = response.toArray(); // se serializa el objeto response ClientSidePrx receptorPrx; for (Seeker item : receptors) { receptorPrx = record.get(item); receptorPrx.notify_async(new NotifyAMICallback(item, "sendMessage"), array); // save message to BD saveMessage(sessionName, message, emitter, item); notifySentMessage(); } // se incrementa el valor de los mensajes enviados por emisor this.updateMessagesCount(sessionName, emitter); } } else { throw new SeekerException("The seeker '" + emitter.getUser() + "' is not registered in the session '" + sessionName + "'."); } } private void notifySentMessage() { if (listener != null) { this.listener.notifySentMessage(); } } /** * {@inheritDoc} * */ public void sendMessage(final String sessionName, final Seeker emitter, final Seeker receptor, final String message) throws SessionException, SeekerException, IOException { SessionProfile recordSession = getSessionProfile(sessionName); SeekerInfo seekersRecord = recordSession.getSeekerInfo(); boolean flag = flag = seekersRecord.record.containsKey(emitter); if (flag) { // se solicita el objeto proxy correspondiente al miembro receptor, // si este devuelve un valor distinto de nulo, se realiza el envió del // mensaje y la notificación de conclusión de la operación al miembro // emisor, en caso contrario se notifica al emisor el error y se lanza // una excepción del tipo UserNotExistException. flag = seekersRecord.record.containsKey(receptor); if (flag) { Response response = this.buildResponse(sessionName, emitter, message); byte[] array = response.toArray(); // se serializa el objeto response // se notifica a cada miembro el mensaje apartir de su objeto proxy ClientSidePrx clientPrx = seekersRecord.record.get(receptor); clientPrx.notify_async(new NotifyAMICallback(receptor, "sendMessage"), array); // // se incrementa el valor de los mensajes enviados por emisor this.updateMessagesCount(sessionName, emitter); notifySentMessage(); } else { throw new SeekerException("The seeker '" + receptor.getUser() + "' is not registered in the session '" + sessionName + "'."); } } else { throw new SeekerException("The seeker '" + emitter.getUser() + "' is not registered in the session '" + sessionName + "'."); } // save message to BD saveMessage(sessionName, message, emitter, receptor); } private void saveMessage(final String sessionName, final String message, final Seeker emitter, final Seeker receptor) { Thread thread = new Thread( new Runnable() { public void run() { try { if (dbController != null && dbController.isOpen()) { dbController.saveMessage(sessionName, emitter.getUser(), message, receptor); } } catch (SQLException ex) { OutputMonitor.printStream("SQL", null); } } }); thread.start(); } /** * {@inheritDoc} */ public void sendMessage(final String sessionName, final Seeker emitter, final List<Seeker> receptors, final String message) throws SessionException, SeekerException, IOException { SessionProfile recordSession = getSessionProfile(sessionName); String notFound = null; SeekerInfo members = recordSession.getSeekerInfo(); boolean flag = members.record.containsKey(emitter); if (flag) { Response response = this.buildResponse(sessionName, emitter, message); byte[] array = response.toArray();// se serializa el objeto response ClientSidePrx clientPrx; // se notifica a cada miembro el mensaje apartir de su objeto proxy for (Seeker seeker : receptors) { // se solicita el objeto proxy correspondiente al miembro receptor clientPrx = members.record.get(seeker); if (clientPrx != null) { clientPrx.notify_async(new NotifyAMICallback(seeker, "sendMessage"), array); // save message to BD saveMessage(sessionName, message, emitter, seeker); } else { notFound.concat(seeker.getUser()).concat(", "); } } // se incrementa el valor de los mensajes enviados por emisor this.updateMessagesCount(sessionName, emitter); notifySentMessage(); } else { throw new SeekerException("The seeker '" + emitter.getUser() + "' is not registered in the session '" + sessionName + "'."); } // se comprueba si algunos de los receptores no pudo ser notificado if (notFound != null) { throw new SeekerException("The members '" + notFound + "' is not registered in the session '" + sessionName + "'."); } } private Response buildResponse(String sessionName, Seeker emitter, String message) { Map<Object, Object> hash = new HashMap<>(4); hash.put(OPERATION, NOTIFY_TEXT_MESSAGE); hash.put(SESSION_NAME, sessionName); hash.put(SEEKER_EMITTER, emitter); hash.put(MESSAGE, message); Response response = new Response(hash); return response; } /** * Este método se emplea para actualizar la relación de mensajes enviados * por los miembros de un sesión y el total general de la misma. * * @param sessionName nombre de la sesión a la que pertenece el miembro. * @param seeker miembro que ejecuta la búsqueda. */ private void updateMessagesCount(String sessionName, Seeker seeker) throws SessionException { SessionProfile recordSession = getSessionProfile(sessionName); int count = 0; //se obtiene la relación de mensajes enviados por los // miembros de la sesión. Count membMsgsCount = recordSession.getSeekersMessages(); boolean flag = !membMsgsCount.record.isEmpty(); if (flag) { try { // se obtiene e incrementa el número de mensajes del miembro count = membMsgsCount.record.get(seeker); count++; // si el miembro no se encuentra registrado, se procede // a realizar su registro al capturar la expeción. } catch (NullPointerException e) { membMsgsCount.record.put(seeker, 1); } } else { membMsgsCount.record.put(seeker, 1); } // se incrementa el valor de los mensajes enviados durante la // actual sesión del servidor. this.messagesCount++; // se incrementa el valor de los mensajes enviados por la // la sesión durante actual sesión del servidor. count = recordSession.getMessagesCount(); count++; } /** * {@inheritDoc} */ public long getMessagesCount() { return this.messagesCount; } /** * {@inheritDoc} */ public long getMessagesCount(String sessionName) throws SessionException { SessionProfile recordSession = getSessionProfile(sessionName); int count = recordSession.getMessagesCount(); return count; } /** * {@inheritDoc} */ public long getMessagesCount(String sessionName, Seeker seeker) throws SessionException, SeekerException { SessionProfile recordSession = getSessionProfile(sessionName); Count members = recordSession.getSeekersMessages(); boolean flag = members.record.containsKey(seeker); if (flag) { int count = members.record.get(seeker); return count; } else { throw new SeekerException("The seeker '" + seeker.getUser() + "' is not registered in the session '" + sessionName + "'."); } } }