package drakkar.stern.servant; import drakkar.oar.Response; import drakkar.oar.Seeker; import drakkar.oar.TermSuggest; import drakkar.oar.exception.NotificationException; import drakkar.oar.exception.QueryNotExistException; import drakkar.oar.exception.ScoreOutOfBoundsException; import drakkar.oar.exception.SessionException; import drakkar.oar.facade.event.FacadeDesktopEvent; import drakkar.oar.slice.client.ClientSidePrx; import static drakkar.oar.util.KeyMessage.*; import static drakkar.oar.util.KeyTransaction.*; import static drakkar.oar.util.NotifyAction.*; import drakkar.oar.util.OutputMonitor; import drakkar.oar.util.SeekerAction; import static drakkar.oar.util.SeekerAction.*; import drakkar.mast.RetrievalManager; import drakkar.stern.ResponseSessionFactory; import drakkar.stern.ResponseSuggestFactory; import drakkar.stern.SternAppSetting; import drakkar.stern.callback.NotifyAMICallback; import drakkar.stern.controller.DataBaseController; import drakkar.stern.evaluation.Evaluable; import drakkar.stern.evaluation.Referee; import drakkar.stern.facade.event.FacadeListener; import drakkar.stern.servant.service.ImplicitRecomendation; import drakkar.stern.servant.service.Messenger; import drakkar.stern.servant.service.Notifiable; import drakkar.stern.servant.service.Perceptionable; import drakkar.stern.servant.service.Recommendable; import drakkar.stern.servant.service.Recommender; import drakkar.stern.servant.service.SearchableInServerSide; import drakkar.stern.servant.service.SearcherServer; import drakkar.stern.servant.service.Sendable; import drakkar.stern.servant.service.SessionManager; import drakkar.stern.servant.service.Suggestable; import drakkar.stern.servant.service.SynchronousAwareness; import drakkar.stern.servant.service.Trackable; import drakkar.stern.servant.service.Tracker; import drakkar.stern.tracker.cache.CommentDocuments; import drakkar.stern.tracker.cache.CommentDocuments.CommentDocs; import drakkar.stern.tracker.cache.CommentDocuments.Comments; import drakkar.stern.tracker.cache.CommentDocuments.CommentsData; import drakkar.stern.tracker.cache.SeekerInfo; import drakkar.stern.tracker.cache.SeekerRecommendResults; import drakkar.stern.tracker.cache.SeekerSearchResults; import drakkar.stern.tracker.cache.SelectedDocuments; import drakkar.stern.tracker.cache.SelectedDocuments.Evaluation; import drakkar.stern.tracker.cache.SelectedDocuments.RelevanceDocs; import drakkar.stern.tracker.cache.SelectedDocuments.SelectedData; import drakkar.stern.tracker.cache.SessionProfile; import drakkar.stern.tracker.cache.ViewedDocuments; import drakkar.stern.tracker.cache.ViewedDocuments.ViewedData; import drakkar.stern.tracker.cache.ViewedDocuments.ViewedResults; import java.io.IOException; import java.sql.Connection; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; /** * Esta clase controla todas las operaciones soportadas por el servidor */ public abstract class Servant extends SessionManager implements Notifiable, Sendable, Recommendable, SearchableInServerSide, Evaluable, Trackable, Perceptionable, Suggestable { //@TODO revisar los cambios ahora de Document por MetaDocument. también en SearchEngineManager //@TODO Por el momento no crear nuevas sesiones con el mismo nombre que anteriores finalizadas. protected UUID uuid; protected Connection cxn; protected String sessionUUID = null; /** * Esta variable representa el valor máximo de la puntuación que puede recibir * documento por el miembro que lo evalúa. */ protected byte maxScore = 10; /** * Esta variable representa el valor de la puntuación, que permite determinar * si un documento es relevante o no. */ protected byte relevScore = 6; protected Messenger messenger; protected Recommender recommend; protected SearcherServer searcher; protected Referee evaluator; protected Tracker tracker; protected SynchronousAwareness awareness; protected ImplicitRecomendation impRecomend; public Servant(RetrievalManager retrievalManager) { super(retrievalManager); this.listener = null; String session = getCommunicationSessionName(); updateServer(SeekerAction.UPDATE_SESSIONS, SeekerAction.INCREMENT, session); this.messenger = new Messenger(session, defaultSessionProfile, collaborativeSessions, htTempSessions); this.recommend = new Recommender(session, defaultSessionProfile, collaborativeSessions, htTempSessions); this.searcher = new SearcherServer(session, defaultSessionProfile, collaborativeSessions, htTempSessions, this.retrievalManager); this.evaluator = new Referee(session, defaultSessionProfile, collaborativeSessions, htTempSessions); this.tracker = new Tracker(session, defaultSessionProfile, collaborativeSessions, htTempSessions); this.awareness = new SynchronousAwareness(session, defaultSessionProfile, collaborativeSessions, htTempSessions); this.impRecomend = new ImplicitRecomendation(session, defaultSessionProfile, collaborativeSessions, htTempSessions); } public Servant(RetrievalManager retrievalManager, SternAppSetting setting) { super(retrievalManager, setting); this.listener = null; // this.htTempSessions = new Map<String, SessionProfile>(); String session = setting.getSessionName(); updateServer(SeekerAction.UPDATE_SESSIONS, SeekerAction.INCREMENT, session); this.messenger = new Messenger(session, defaultSessionProfile, collaborativeSessions, htTempSessions); this.recommend = new Recommender(session, defaultSessionProfile, collaborativeSessions, htTempSessions); this.searcher = new SearcherServer(session, defaultSessionProfile, collaborativeSessions, htTempSessions, this.retrievalManager); this.evaluator = new Referee(session, defaultSessionProfile, collaborativeSessions, htTempSessions); this.tracker = new Tracker(session, defaultSessionProfile, collaborativeSessions, htTempSessions); this.awareness = new SynchronousAwareness(session, defaultSessionProfile, collaborativeSessions, htTempSessions); this.impRecomend = new ImplicitRecomendation(session, defaultSessionProfile, collaborativeSessions, htTempSessions); } public Servant(RetrievalManager retrievalManager, DataBaseController dbController) { super(retrievalManager, dbController); this.listener = null; String session = getCommunicationSessionName(); // this.htTempSessions = new Map<String, SessionProfile>(); updateServer(SeekerAction.UPDATE_SESSIONS, SeekerAction.INCREMENT, session); this.messenger = new Messenger(session, defaultSessionProfile, collaborativeSessions, htTempSessions); this.recommend = new Recommender(session, defaultSessionProfile, collaborativeSessions, htTempSessions); this.searcher = new SearcherServer(session, defaultSessionProfile, collaborativeSessions, htTempSessions, this.retrievalManager); this.evaluator = new Referee(session, defaultSessionProfile, collaborativeSessions, htTempSessions); this.tracker = new Tracker(session, defaultSessionProfile, collaborativeSessions, htTempSessions); this.awareness = new SynchronousAwareness(session, defaultSessionProfile, collaborativeSessions, htTempSessions); this.impRecomend = new ImplicitRecomendation(session, defaultSessionProfile, collaborativeSessions, htTempSessions); } public Servant(RetrievalManager retrievalManager, FacadeListener listener, DataBaseController dbController) { super(retrievalManager, listener, dbController); this.listener = listener; // this.htTempSessions = new Map<String, SessionProfile>(); String session = getCommunicationSessionName(); this.updateServer(SeekerAction.UPDATE_SESSIONS, SeekerAction.INCREMENT, session); this.messenger = new Messenger(session, defaultSessionProfile, collaborativeSessions, htTempSessions, this.listener, dbController); this.recommend = new Recommender(session, defaultSessionProfile, collaborativeSessions, htTempSessions, this.listener, dbController); this.searcher = new SearcherServer(session, defaultSessionProfile, collaborativeSessions, htTempSessions, this.retrievalManager, this.listener, dbController); this.evaluator = new Referee(session, defaultSessionProfile, collaborativeSessions, htTempSessions, this.listener, dbController); this.tracker = new Tracker(session, defaultSessionProfile, collaborativeSessions, htTempSessions, this.listener, dbController); this.awareness = new SynchronousAwareness(session, defaultSessionProfile, collaborativeSessions, htTempSessions, this.listener, dbController); this.impRecomend = new ImplicitRecomendation(session, defaultSessionProfile, collaborativeSessions, htTempSessions, this.listener, dbController); } public Servant(RetrievalManager retrievalManager, FacadeListener listener, DataBaseController dbController, SternAppSetting setting) { super(retrievalManager, listener, dbController, setting); this.listener = listener; // this.htTempSessions = new Map<String, SessionProfile>(); String sessionName = setting.getSessionName(); this.updateServer(SeekerAction.UPDATE_SESSIONS, SeekerAction.INCREMENT, sessionName); this.messenger = new Messenger(sessionName, defaultSessionProfile, collaborativeSessions, htTempSessions, this.listener, dbController); this.recommend = new Recommender(sessionName, defaultSessionProfile, collaborativeSessions, htTempSessions, this.listener, dbController); this.searcher = new SearcherServer(sessionName, defaultSessionProfile, collaborativeSessions, htTempSessions, this.retrievalManager, this.listener, dbController); this.evaluator = new Referee(sessionName, defaultSessionProfile, collaborativeSessions, htTempSessions, this.listener, dbController); this.tracker = new Tracker(sessionName, defaultSessionProfile, collaborativeSessions, htTempSessions, this.listener, dbController); this.awareness = new SynchronousAwareness(sessionName, defaultSessionProfile, collaborativeSessions, htTempSessions, this.listener, dbController); this.impRecomend = new ImplicitRecomendation(sessionName, defaultSessionProfile, collaborativeSessions, htTempSessions, this.listener, dbController); } /** * */ public static String tableName = "derbyDBMensajes"; /** * Este método reemplaza el objeto Connection. * * @param cxn nuevo objeto Connection. */ public abstract void setConnection(Connection cxn); /** * Este método reemplaza el uuid de la sesión. * * @param sessionUUID nuevo uuid de la sesión. */ public abstract void setSessionUUID(String sessionUUID); /** * Este método reemplaza el objeto UUID de la clase. * * @param uuid nuevo UUID */ public abstract void setUUIDClass(UUID uuid); /** * {@inheritDoc} */ public synchronized void notifyDocumentViewed(final String sessionName, Seeker seeker, String query, int searchable, int docIndex, final String uri) throws SessionException, NotificationException { SessionProfile recordSession = getSessionProfile(sessionName); SeekerInfo members = recordSession.getSeekerInfo(); boolean flag = members.record.containsKey(seeker); if (flag) { // se comprueba que la sesión y el miembro que emite la notifcación // cuenten con registros de resultados de búsqueda, en caso contrario // se lanza una excepción del tipo NotificationException. SeekerSearchResults searches = recordSession.getSeekerSearchResults(); flag = !searches.record.isEmpty(); if (flag) { // se obtiene la relación de los resultados de búquedas de los // miembros de la sesión. flag = searches.record.containsKey(seeker); if (flag) { ViewedDocuments viewedDocuments = recordSession.getViewedDocuments(); ViewedData viewedData; ViewedResults viewedResults; // de existir registros flag = !viewedDocuments.record.isEmpty(); if (flag) { // se obtienen el registro que almacena los documentos revisados // por los miembros de esta sesión. List<Integer> docs; // si el miembro cuenta con revisiones previas de documentos flag = viewedDocuments.record.containsKey(seeker); if (flag) { // se obtienen los documentos revisados por el miembro viewedData = viewedDocuments.record.get(seeker); flag = viewedData.values.containsKey(query); if (flag) { viewedResults = viewedData.values.get(query); docs = viewedResults.results.get(searchable); if (docs == null) { docs = new ArrayList<>(); docs.add(docIndex); viewedResults.results.put(searchable, docs); } else { flag = viewedResults.isViewed(searchable, docIndex); if (!flag) { docs.add(docIndex); } } } else { // si no existe el registro de documentos revisados // para esa consulta, se procede su registro. viewedResults = viewedDocuments.new ViewedResults(searchable, docIndex); viewedData.values.put(query, viewedResults); } } else { // en caso de que el miembro no halla revisado aún ningún // documento de los resultados de la búsqueda, se efectúa // el registro del mismo en las estructuras correspondientes. viewedData = viewedDocuments.new ViewedData(); viewedResults = viewedDocuments.new ViewedResults(searchable, docIndex); viewedData.values.put(query, viewedResults); // se adiciona la nueva revisión del miembro en la // hash de registro de revisiones. viewedDocuments.record.put(seeker, viewedData); } } else { // en caso de que no exista aún un registro de documentos // revisados, se efectúa la inicialización del mismo en // las estructuras correspondientes. viewedData = viewedDocuments.new ViewedData(); viewedResults = viewedDocuments.new ViewedResults(searchable, docIndex); viewedData.values.put(query, viewedResults); // se adiciona la nueva revisión del miembro en la // hash de registro de revisiones. viewedDocuments.record.put(seeker, viewedData); } //update estado de los documentos a true a partir del URI final DataBaseController control = this.dbController; Thread thread = new Thread(new Runnable() { public void run() { if (control.isOpen()) { try { control.setReviewDocument(sessionName, uri); } catch (SQLException ex) { OutputMonitor.printStream("SQL", ex); } } } }); thread.start(); } else { throw new NotificationException("The seeker '" + seeker.getUser() + "'doesn't have previous results of search"); } } else { throw new NotificationException("The session '" + sessionName + "'doesn't have previous results of search"); } } else { throw new NotificationException("The session '" + sessionName + " or the seeker '" + seeker.getUser() + "' is not supported this notification "); } } /** * {@inheritDoc} * */ public synchronized void notifyDocumentEvaluated(final String sessionName, final Seeker seeker, final String query, int searchable, int docIndex, String uri, byte score, int source) throws SessionException, NotificationException, ScoreOutOfBoundsException, IOException { final SessionProfile sessionProfile = getSessionProfile(sessionName); switch (source) { case LOCAL_SEARCH_RESULT: localEvaluation(sessionProfile, seeker, query, searchable, docIndex, score, uri); break; case RECOMMEND_SEARCH_RESULT: recommendEvaluation(sessionProfile, seeker, query, searchable, docIndex, score); break; case TRACK_SEARCH_RESULT: try { collabEvaluation(sessionProfile, seeker, query, searchable, docIndex, score, uri); } catch (SQLException ex) { throw new NotificationException(ex.getMessage()); } break; default: throw new NotificationException("El origen de la evaluación no es válido."); } if (score >= this.relevScore) { Thread t = new Thread(new Runnable() { public void run() { try { String defaultSession = defaultSessionProfile.getProperties().getSessionName(); if (sessionName.equals(defaultSession)) { if (sessionProfile.isActiveTermsSuggest(seeker)) { List<TermSuggest> termsList = retrievalManager.getTermsSuggest(query); if (!termsList.isEmpty()) { ClientSidePrx prx = sessionProfile.getSeekerInfo().record.get(seeker); Response rsp = ResponseSuggestFactory.getResponse(sessionName, query, termsList); prx.notify_async(new NotifyAMICallback(seeker), rsp.toArray()); } }//TODO responder si no está activo } else if (sessionProfile.isTermsSuggest()) { List<TermSuggest> termsList1 = retrievalManager.getTermsSuggest(query); if (!termsList1.isEmpty()) { int members = sessionProfile.getSeekerInfo().record.size(); int terms = termsList1.size(); ClientSidePrx prx; Response rsp; List<TermSuggest> temp; if (members == 1) { rsp = ResponseSuggestFactory.getResponse(sessionName, query, termsList1); prx = sessionProfile.getSeekerInfo().record.get(seeker); prx.notify_async(new NotifyAMICallback(seeker), rsp.toArray()); } else { Set<Seeker> list = sessionProfile.getSeekerInfo().record.keySet(); List<Seeker> seekerList = new ArrayList<>(list); if (members > terms) { for (int i = 0; i < terms; i++) { temp = new ArrayList<>(1); temp.add(termsList1.get(i)); rsp = ResponseSuggestFactory.getResponse(sessionName, query, temp); prx = sessionProfile.getSeekerInfo().record.get(seekerList.get(i)); prx.notify_async(new NotifyAMICallback(seeker), rsp.toArray()); } } else { int quantity = terms / members; int index = 0; for (int i = 0; i < (members - 1); i++) { temp = new ArrayList<>(termsList1.subList(index, index + quantity)); rsp = ResponseSuggestFactory.getResponse(sessionName, query, temp); prx = sessionProfile.getSeekerInfo().record.get(seekerList.get(i)); prx.notify_async(new NotifyAMICallback(seeker), rsp.toArray()); index += quantity; } // se notifica al último miembro de la sesión temp = new ArrayList<>(termsList1.subList(index, terms)); rsp = ResponseSuggestFactory.getResponse(sessionName, query, temp); prx = sessionProfile.getSeekerInfo().record.get(seekerList.get(members - 1)); prx.notify_async(new NotifyAMICallback(seeker), rsp.toArray()); } } } } } catch (IOException ex) { OutputMonitor.printStream("Notify terms suggest to seeker: " + seeker.getUser(), ex); } } }); t.start(); } } private void localEvaluation(SessionProfile sessionProfile, Seeker seeker, String query, int searchable, int docIndex, byte relevance, String uri) throws SessionException, NotificationException, ScoreOutOfBoundsException, IOException { SeekerInfo members = sessionProfile.getSeekerInfo(); String sessionName = sessionProfile.getProperties().getSessionName(); if (relevance > this.maxScore && relevance < 1) { throw new ScoreOutOfBoundsException("The assigned score finds out of the range of values possible < 0 - " + this.maxScore + " >."); } if (members.record.containsKey(seeker)) { // se comprueba que la sesión y el miembro que emite la notifcación // cuenten con registros de resultados de búsqueda, en caso contrario // se lanza una excepción del tipo NotificationException. SeekerSearchResults searches = sessionProfile.getSeekerSearchResults(); boolean flag = !searches.record.isEmpty(); if (flag) { // se obtiene la relación de los resultados de búquedas de los // miembros de la sesión. flag = searches.record.containsKey(seeker); if (flag) { registerEvaluation(sessionProfile, query, searchable, docIndex, relevance, seeker); //Guardar BD if (this.dbController.isOpen()) { try { String sessionSave; if (sessionName.equals("")) { sessionSave = getCommunicationSessionName(); } else { sessionSave = sessionName; } this.dbController.saveEvaluation(sessionSave, "", (int) relevance, seeker.getUser(), uri); } catch (SQLException ex) { OutputMonitor.printStream("SQL", ex); } } else { throw new NotificationException("No existe una conexión con la BD del servidor."); } } else { throw new NotificationException("The seeker '" + seeker.getUser() + "'doesn't have previous results of search"); } } else { throw new NotificationException("The session '" + sessionProfile.getProperties().getSessionName() + " doesn't have previous results of search"); } } else { throw new NotificationException("The session '" + sessionProfile.getProperties().getSessionName() + " or the seeker '" + seeker.getUser() + "' is not supported this notification "); } } private void recommendEvaluation(SessionProfile sessionProfile, Seeker seeker, String query, int searchable, int docIndex, byte relevance) throws SessionException, NotificationException, ScoreOutOfBoundsException { SeekerInfo members = sessionProfile.getSeekerInfo(); if (relevance > this.maxScore && relevance < 1) { throw new ScoreOutOfBoundsException("The assigned score finds out of the range of values possible < 0 - " + this.maxScore + " >."); } if (members.record.containsKey(seeker)) { // se comprueba que la sesión y el miembro que emite la notifcación // cuenten con registros de resultados de búsqueda, en caso contrario // se lanza una excepción del tipo NotificationException. SeekerRecommendResults recommendations = sessionProfile.getSeekerRecommendResults(); boolean flag = !recommendations.record.isEmpty(); if (flag) { // se obtiene la relación de los resultados de búquedas de los // miembros de la sesión. flag = recommendations.record.containsKey(seeker); if (flag) { registerEvaluation(sessionProfile, query, searchable, docIndex, relevance, seeker); } else { throw new NotificationException("The seeker '" + seeker.getUser() + "'doesn't have previous results of recommendations"); } } else { throw new NotificationException("The session '" + sessionProfile.getProperties().getSessionName() + "'doesn't have previous results of recommendation"); } } else { throw new NotificationException("The session '" + sessionProfile.getProperties().getSessionName() + " or the seeker '" + seeker.getUser() + "' is not supported this notification "); } } private void collabEvaluation(SessionProfile sessionProfile, Seeker seeker, String query, int searchable, int docIndex, byte relevance, String uri) throws SessionException, NotificationException, ScoreOutOfBoundsException, SQLException { String sessionName = sessionProfile.getProperties().getSessionName(); SeekerInfo members = sessionProfile.getSeekerInfo(); if (relevance > this.maxScore && relevance < 1) { throw new ScoreOutOfBoundsException("The assigned score finds out of the range of values possible < 0 - " + this.maxScore + " >."); } if (members.record.containsKey(seeker)) { registerEvaluation(sessionProfile, query, searchable, docIndex, relevance, seeker); if (this.dbController.isOpen()) { this.dbController.saveEvaluation(sessionName, "", (int) relevance, seeker.getUser(), uri); } else { throw new NotificationException("No existe una conexión con la BD del servidor."); } } else { throw new NotificationException("The session '" + sessionProfile.getProperties().getSessionName() + " or the seeker '" + seeker.getUser() + "' is not supported this notification "); } } private void registerEvaluation(SessionProfile sessionProfile, String query, int searchable, int docIndex, byte relevance, Seeker seeker) throws NotificationException { SelectedDocuments selectedDocuments = sessionProfile.getSelectedDocuments(); Evaluation eval; SelectedData selectedData; RelevanceDocs relevanceDocs; // de existir registros boolean flag = !selectedDocuments.record.isEmpty(); if (flag) { // se obtienen el registro que almacena los documentos revisados // por los miembros de esta sesión. // si el miembro cuenta con revisiones previas de documentos flag = selectedDocuments.record.containsKey(seeker); if (flag) { // se obtiene la relación de los documentos evavluados // por el miembro eval = selectedDocuments.record.get(seeker); flag = eval.evaluation.containsKey(query); if (flag) { // se obtiene el la instancia del objeto Evaluation, // que almacena las evaluaciones de documentos // realizadas por el miembro para la query. selectedData = eval.evaluation.get(query); // se adiciona la evaluación del nuevo documento si // ya no ha sido evaluado, en caso contrario se lanza // una excepción del tipo AlreadyRegisteredException // y se notifica al cliente el error. relevanceDocs = selectedData.values.get(searchable); if (relevanceDocs == null) { // si no existe evaluaciones para el searchable relevanceDocs = selectedDocuments.new RelevanceDocs(docIndex, relevance); selectedData.values.put(searchable, relevanceDocs); } else { flag = relevanceDocs.values.containsKey(docIndex); if (flag) { byte scoreTemp = relevanceDocs.values.get(docIndex); scoreTemp = relevance; } else { relevanceDocs.values.put(docIndex, relevance); } } } else { // de no existir evaluaciones para la consulta se // se procede a efectuar su registro en las estructuras // correspondientes. selectedData = selectedDocuments.new SelectedData(); relevanceDocs = selectedDocuments.new RelevanceDocs(docIndex, relevance); selectedData.values.put(searchable, relevanceDocs); eval.evaluation.put(query, selectedData); } } else { // en caso de que el miembro cuenta con evaluaciones // previas de documentos, se procede a efectuar su // registro en las estructuras correspondientes. eval = selectedDocuments.new Evaluation(); selectedData = selectedDocuments.new SelectedData(); relevanceDocs = selectedDocuments.new RelevanceDocs(docIndex, relevance); selectedData.values.put(searchable, relevanceDocs); eval.evaluation.put(query, selectedData); selectedDocuments.record.put(seeker, eval);// se agrega al registro de evaluaciones del usuario } } else { // en caso de que no exista aún un registro de documentos // evaluados para la sesión, se procede a efectuar su // registro en las estructuras correspondientes eval = selectedDocuments.new Evaluation(); selectedData = selectedDocuments.new SelectedData(); relevanceDocs = selectedDocuments.new RelevanceDocs(docIndex, relevance); selectedData.values.put(searchable, relevanceDocs); eval.evaluation.put(query, selectedData); selectedDocuments.record.put(seeker, eval); } } /** * {@inheritDoc} */ public void notifyDocumentCommented(String sessionName, Seeker seeker, String query, int searchable, int docIndex, String uri, String comment, int source) throws SessionException, NotificationException { SessionProfile sessionProfile = getSessionProfile(sessionName); switch (source) { case LOCAL_SEARCH_RESULT: this.localComments(sessionProfile, seeker, query, searchable, docIndex, comment, uri); break; case RECOMMEND_SEARCH_RESULT: this.registerComments(sessionProfile, query, searchable, docIndex, comment, seeker); break; case TRACK_SEARCH_RESULT: try { this.collabComments(sessionProfile, seeker, query, searchable, docIndex, comment, uri); } catch (SQLException ex) { throw new NotificationException(ex.getMessage()); } break; } } private void localComments(SessionProfile recordSession, Seeker seeker, String query, int searchable, int docIndex, String comments, String uri) throws SessionException, NotificationException { String sessionName = recordSession.getProperties().getSessionName(); SeekerInfo members = recordSession.getSeekerInfo(); // se comprueba que el miembro que emite la notificación sea miembro // de la sesión, en caso contrario se lanza una excepción del tipo // UserNotExistException. boolean flag = members.record.containsKey(seeker); if (flag) { // se obtiene la relación de los resultados de búquedas de los // miembros de la sesión. SeekerSearchResults searches = recordSession.getSeekerSearchResults(); // se comprueba que la sesión y el miembro que emite la notifcación // cuenten con registros de resultados de búsqueda, en caso contrario // se lanza una excepción del tipo NotificationException. flag = !searches.record.isEmpty(); if (flag) { flag = searches.record.containsKey(seeker); if (flag) { registerComments(recordSession, query, searchable, docIndex, comments, seeker); //Guardar BD if (this.dbController.isOpen()) { try { //nota: verificar la sesion String sessionSave; if (sessionName.equals("")) { sessionSave = getCommunicationSessionName(); } else { sessionSave = sessionName; } this.dbController.updateEvaluationComment(sessionSave, seeker, uri, comments); } catch (SQLException ex) { OutputMonitor.printStream("SQL", ex); } } else { throw new NotificationException("No existe una conexión con la BD del servidor."); } } else { throw new NotificationException("The seeker '" + seeker.getUser() + "'doesn't have previous results of search"); } } else { throw new NotificationException("The session '" + sessionName + "'doesn't have previous results of search"); } } } private void recommendComments(SessionProfile sessionProfile, Seeker seeker, String query, int searchable, int docIndex, String comments) throws SessionException, NotificationException { SeekerInfo members = sessionProfile.getSeekerInfo(); String sessionName = sessionProfile.getProperties().getSessionName(); if (members.record.containsKey(seeker)) { // se comprueba que la sesión y el miembro que emite la notifcación // cuenten con registros de resultados de búsqueda, en caso contrario // se lanza una excepción del tipo NotificationException. SeekerRecommendResults recommendations = sessionProfile.getSeekerRecommendResults(); boolean flag = !recommendations.record.isEmpty(); if (flag) { // se obtiene la relación de los resultados de búquedas de los // miembros de la sesión. flag = recommendations.record.containsKey(seeker); if (flag) { registerComments(sessionProfile, query, searchable, docIndex, comments, seeker); } else { throw new NotificationException("The seeker '" + seeker.getUser() + "'doesn't have previous results of recommendations"); } } else { throw new NotificationException("The session '" + sessionName + "'doesn't have previous results of recommendation"); } } else { throw new NotificationException("The session '" + sessionName + " or the seeker '" + seeker.getUser() + "' is not supported this notification "); } } private void collabComments(SessionProfile sessionProfile, Seeker seeker, String query, int searchable, int docIndex, String comments, String uri) throws SessionException, NotificationException, SQLException { String sessionName = sessionProfile.getProperties().getSessionName(); SeekerInfo members = sessionProfile.getSeekerInfo(); if (members.record.containsKey(seeker)) { registerComments(sessionProfile, query, searchable, docIndex, comments, seeker); if (this.dbController.isOpen()) { dbController.updateEvaluationComment(sessionName, seeker, uri, comments); } else { throw new NotificationException("No existe una conexión con la BD del servidor."); } } else { throw new NotificationException("The session '" + sessionName + " or the seeker '" + seeker.getUser() + "' is not supported this notification "); } } private void registerComments(SessionProfile sessionProfile, String query, int searchable, int docIndex, String comment, Seeker seeker) throws NotificationException { CommentDocuments seekerComments = sessionProfile.getSeekerComments(); Comments comments; CommentsData commentsData; CommentDocs commentDocs; String commentTemp; // de existir registros para la sesión boolean flag = !seekerComments.record.isEmpty(); if (flag) { // se obtienen el registro que almacena los documentos revisados // por los miembros de esta sesión. // si el miembro cuenta con revisiones previas de documentos if (seekerComments.record.containsKey(seeker)) { // se obtiene la relación de los documentos evavluados // por el miembro comments = seekerComments.record.get(seeker); if (comments.record.containsKey(query)) { // se obtiene el la instancia del objeto Comment, // quien almacena la lista de los comentarios realizados // por el miembro a cada uno de los documentos. commentsData = comments.record.get(query); if (commentsData.values.containsKey(searchable)) { commentDocs = commentsData.values.get(searchable); if (commentDocs.values.containsKey(docIndex)) { commentTemp = commentDocs.values.get(docIndex); // se adiciona el nuevo comentario del documento commentTemp = comment; } else { // se adiciona el nuevo comentario del documento commentDocs.values.put(docIndex, comment); } } else { commentDocs = seekerComments.new CommentDocs(docIndex, comment); commentsData.values.put(searchable, commentDocs); } } else { commentsData = seekerComments.new CommentsData(); commentDocs = seekerComments.new CommentDocs(docIndex, comment); commentsData.values.put(searchable, commentDocs); comments.record.put(query, commentsData); } } else { // en caso de que el miembro no halla comentado aún ningún // documento de los resultados de la búsqueda, se efectúa // el registro del mismo en las estructuras correspondientes. comments = seekerComments.new Comments(); commentsData = seekerComments.new CommentsData(); commentDocs = seekerComments.new CommentDocs(docIndex, comment); commentsData.values.put(searchable, commentDocs); comments.record.put(query, commentsData); // se adiciona la nueva comentario del miembro en la // hash de registro de comentarios. seekerComments.record.put(seeker, comments); } } else { // en caso de que no exista aún un registro de documentos // evaluados por la sesión, se efectúa la inicialización // del mismo en las estructuras correspondientes. comments = seekerComments.new Comments(); commentsData = seekerComments.new CommentsData(); commentDocs = seekerComments.new CommentDocs(docIndex, comment); commentsData.values.put(searchable, commentDocs); comments.record.put(query, commentsData); // se adiciona la nueva comentario del miembro en la // hash de registro de comentarios. seekerComments.record.put(seeker, comments); } } /** * * @param sessionName * @param query * @param docs * @return * @throws SessionException * @throws QueryNotExistException */ public double evaluatePrecision(String sessionName, String query, List<String> docs) throws SessionException, QueryNotExistException { return this.evaluator.evaluatePrecision(sessionName, query, docs); } /** * * @param sessionName * @param query * @param docs * @return * @throws QueryNotExistException * @throws SessionException */ public double evaluateRecall(String sessionName, String query, List<String> docs) throws QueryNotExistException, SessionException { return this.evaluator.evaluateRecall(sessionName, query, docs); } /** * * @param session * @return * @throws SessionException */ public double evaluateEoI(String session) throws SessionException { int membersCount = this.getSeekersCount(session); long recsCount = this.recommend.getRecommendationsCount(session); long msgsCount = this.messenger.getMessagesCount(session); long timeMs = this.evaluator.getDurationSessionTime(session); return this.evaluator.evaluateEoI(membersCount, recsCount, msgsCount, timeMs); } /** * Este método ejecuta todas las operaciones del experimento y guarda los resultados * en un fichero .xls. * * @param sessions nombres de las sessiones * @param searchableArray * @throws SessionException */ public void evaluateAll(String[] sessions, int[] searchableArray) throws SessionException { int membersCount; long recsCount, msgsCount, timeMs; for (String session : sessions) { membersCount = this.getSeekersCount(session); recsCount = this.recommend.getRecommendationsCount(session); msgsCount = this.messenger.getMessagesCount(session); timeMs = this.evaluator.getDurationSessionTime(session); this.evaluator.evaluateAll(sessions, searchableArray, membersCount, recsCount, msgsCount, timeMs); } } /** * Notifica los buscadores que están disponibles en el servidor */ public void notifyAvailableSearchers() { List<String> searchPrinciples; Response response, response1; byte[] array = null, array1 = null; try { String[] searchers = retrievalManager.getAvailableSearchers(); Map<Object, Object> hash = new HashMap<>(2); hash.put(OPERATION, NOTIFY_AVAILABLE_SEARCHERS); hash.put(SEARCHERS, searchers); response = new Response(hash); array = response.toArray(); ClientSidePrx seekerPrx; List<Seeker> seekersChairman = new ArrayList<>(); boolean flag = collaborativeSessions.isEmpty(); if (!flag) { searchPrinciples = retrievalManager.getSearchPrinciples(RetrievalManager.COLLABORATIVE_SEARCH); response1 = ResponseSessionFactory.getResponse(searchPrinciples); array1 = response1.toArray(); Collection<SessionProfile> sessions = collaborativeSessions.values(); for (SessionProfile sessionProfile : sessions) { Seeker chairman = sessionProfile.getTempChairman(); if (chairman == null) { chairman = sessionProfile.getChairman().getSeeker(); seekerPrx = sessionProfile.getChairman().getClientSidePrx(); seekerPrx.notify_async(new NotifyAMICallback(chairman, "notifyAvailableSearchers"), array); seekerPrx.notify_async(new NotifyAMICallback(chairman, "notifyAvailableSearcPrinciples"), array1); } else { seekerPrx = sessionProfile.getSeekerInfo().record.get(chairman); seekerPrx.notify_async(new NotifyAMICallback(chairman, "notifyAvailableSearchers"), array); seekerPrx.notify_async(new NotifyAMICallback(chairman, "notifyAvailableSearcPrinciples"), array1); } seekersChairman.add(chairman); } } searchPrinciples = retrievalManager.getSearchPrinciples(RetrievalManager.INDIVIDUAL_SEARCH); response1 = ResponseSessionFactory.getResponse(searchPrinciples); array1 = response1.toArray(); Map<Seeker, ClientSidePrx> record = defaultSessionProfile.getSeekerInfo().record; @SuppressWarnings("unchecked") List<Seeker> seekerList = new ArrayList<>(record.keySet()); seekerList.removeAll(seekersChairman); for (Seeker seeker : seekerList) { seekerPrx = record.get(seeker); seekerPrx.notify_async(new NotifyAMICallback(seeker, "notifyAvailableSearchers"), array); seekerPrx.notify_async(new NotifyAMICallback(seeker, "notifyAvailableSearcPrinciples"), array1); } } catch (IOException ex) { this.notifyListener(ERROR_MESSAGE, "Error al notificar los buscadores disponibles."); OutputMonitor.printStream(" En la notificación los buscadores disponibles.", ex); } } public void notifyAvailableSVNRepositories() { String[] repositories = retrievalManager.getAvailableSVNRepositories(); Map<Object, Object> hash = new HashMap<>(2); hash.put(OPERATION, NOTIFY_AVAILABLE_SVN_REPOSITORIES); hash.put(SVN_REPOSITORIES_NAMES, repositories); Response response = new Response(hash); byte[] array = null; try { array = response.toArray(); Map<Seeker, ClientSidePrx> record = defaultSessionProfile.getSeekerInfo().record; Set<Seeker> seekers = record.keySet(); ClientSidePrx seekerPrx; for (Seeker seeker : seekers) { seekerPrx = record.get(seeker); seekerPrx.notify_async(new NotifyAMICallback(seeker, "notifySVNRepositories"), array); } } catch (IOException ex) { this.notifyListener(ERROR_MESSAGE, "Error al notificar los repositorios disponibles."); OutputMonitor.printStream("IO", ex); } } /** * Notifica al servidor de algún error que ocurra * * @param messageType * @param message */ public void notifyListener(int messageType, String message) { if (listener != null) { Response rs = new Response(); rs.put(OPERATION, NOTIFY_TEXT_MESSAGE); rs.put(MESSAGE_TYPE, messageType); rs.put(MESSAGE, message); FacadeDesktopEvent evt = new FacadeDesktopEvent(this, rs); listener.notify(evt); } } }