/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package uk.ac.cam.echo.TouchClient; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import javafx.application.Platform; import uk.ac.cam.echo.client.ClientApi; import uk.ac.cam.echo.data.Conference; import uk.ac.cam.echo.data.Conversation; import uk.ac.cam.echo.data.Message; import uk.ac.cam.echo.data.User; import uk.ac.cam.echo.data.async.Handler; import uk.ac.cam.echo.data.async.Subscription; /** *the class that connects to the server will eventually implement the ClientApi * * @author Philip */ public class ServerConnection implements Runnable{ private int CONVREPLACEDELAY = 60000; private final TouchClient mTC; private GUIController mGUI; private ClientApi mAPI; private List<Conversation> mConversations; private Conference mConfrence; private List<Subscription> mSub; @SuppressWarnings("LeakingThisInConstructor") public ServerConnection(TouchClient tc){ mTC = tc; mTC.regesterServerConnection(this); } @Override public void run() { mConversations = Collections.synchronizedList(new ArrayList<Conversation>()); mSub = Collections.synchronizedList(new ArrayList<Subscription>()); //tries to get the GUI repetedly untill the gui has been initalized while (true){ try { mGUI = mTC.getGUI(); } catch (NotInstantiatedYetException ex) { continue; } break; } //some code to get the url/ip to connect to the server defalut local host String url = "http://127.0.0.1"; boolean retry = true; while (retry){ try { url = mTC.getConfrenceURL(); } catch (NotInstantiatedYetException ex) { try { url = mTC.getConfrenceIP(); } catch (NotInstantiatedYetException ex1) { continue; } } retry = false; } //the connection to the server try{ mAPI = new ClientApi(url); }catch (Exception e){log(e);} retry = true; while(retry){ try { mConfrence = configureConference(); } catch (NotInstantiatedYetException ex) { continue; } catch (ConfrenceNotFoundException ex) { //TODO handel this error better mTC.exit(1,"the confrence has not been foud"); } retry=false; } Collection<Conversation> conversations = null; try{ conversations = mAPI.conferenceResource.mostActiveRecently(mConfrence.getId(), 600000, 5); }catch (Exception e){log(e);} final Conversation conversation1; final Conversation conversation2; final Conversation conversation3; final Conversation conversation4; final Conversation conversation5; //gets the first conversations and if there are not enugh it replaces them with placeholders Iterator it = conversations.iterator(); if (it.hasNext()){ conversation1 = (Conversation)it.next(); if (it.hasNext()){ conversation2 = (Conversation)it.next(); if (it.hasNext()){ conversation3 = (Conversation)it.next(); if (it.hasNext()){ conversation4 = (Conversation)it.next(); if (it.hasNext()){ conversation5 = (Conversation)it.next(); }else{ conversation5 = new ConversationPlaceHolder(-5,"Not connected yet"); } }else{ conversation4 = new ConversationPlaceHolder(-4,"Not connected yet"); conversation5 = new ConversationPlaceHolder(-5,"Not connected yet"); } }else{ conversation3 = new ConversationPlaceHolder(-3,"Not connected yet"); conversation4 = new ConversationPlaceHolder(-4,"Not connected yet"); conversation5 = new ConversationPlaceHolder(-5,"Not connected yet"); } }else{ conversation2 = new ConversationPlaceHolder(-2,"Not connected yet"); conversation3 = new ConversationPlaceHolder(-3,"Not connected yet"); conversation4 = new ConversationPlaceHolder(-4,"Not connected yet"); conversation5 = new ConversationPlaceHolder(-5,"Not connected yet"); } }else{ conversation1 = new ConversationPlaceHolder(-1,"Not connected yet"); conversation2 = new ConversationPlaceHolder(-2,"Not connected yet"); conversation3 = new ConversationPlaceHolder(-3,"Not connected yet"); conversation4 = new ConversationPlaceHolder(-4,"Not connected yet"); conversation5 = new ConversationPlaceHolder(-5,"Not connected yet"); } Platform.runLater(new Runnable() { @Override public void run() { mGUI.initConversations(conversation1.getName(), conversation1.getId(), conversation2.getName(), conversation2.getId(), conversation3.getName(), conversation3.getId(), conversation4.getName(), conversation4.getId(), conversation5.getName(), conversation5.getId()); } }); while (mGUI.getIsMapEmpty()){} Logger.getGlobal().log(Level.INFO, new Boolean(mGUI.getIsMapEmpty()).toString()); synchronized (mConversations){ synchronized (mSub){ mConversations.add(conversation1); mConversations.add(conversation2); mConversations.add(conversation3); mConversations.add(conversation4); mConversations.add(conversation5); for (Conversation c: mConversations){ if (c.getId()>=0){ mSub.add(listenToConversation(c)); }else{ mSub.add(new Subscription() { @Override public void unsubscribe() { return; } }); } } } } replaceConversations(); Logger.getGlobal().log(Level.INFO, "the server ("+url+") is connected"); } private Conference configureConference() throws NotInstantiatedYetException, ConfrenceNotFoundException { try { List<Conference> conferences = mAPI.conferenceResource.getAll(); for (Conference c : conferences){ if (mTC.getConfrenceID() == c.getId()){ return c; } } throw new ConfrenceNotFoundException(); }catch (Exception e){ throw new ConfrenceNotFoundException(); } } private Subscription listenToConversation(final Conversation c) { displayPreviousMessages(c); Handler<Message> handler = new Handler<Message>(){ @Override public void handle(final Message t) { final long id = c.getId(); synchronized (mConversations){ Platform.runLater(new Runnable() { @Override public void run() { try{ mGUI.displayMessage(t, id); mGUI.scrollToEnd(id); } catch (NoMessageListException ex) { System.err.println(id); System.err.println(mGUI.getMap()); Logger.getGlobal().log (Level.SEVERE, "message from conversation "+id+" could not be displayed ", ex); } } }); } } }; try{ return mAPI.conversationResource.listenToMessages(c.getId()).subscribe(handler); } catch (Exception e){log(e);} return null; } void kill() { Runtime.getRuntime().exit(1); } private void displayPreviousMessages(final Conversation c) { if (c.getId()<0){return;} List<Message> list = (List)c.getMessages(50); if (list.isEmpty()){ synchronized (mConversations){ Platform.runLater(new Runnable(){ @Override public void run() { try { mGUI.displayMessage(new Message() { @Override public long getId() {return -1;} @Override public long getTimeStamp() {return System.currentTimeMillis();} @Override public User getSender() {return null;} @Override public String getSenderName() {return "local";} @Override public void setSenderName(String senderName) {return;} @Override public void setSender(User user) {return;} @Override public Conversation getConversation() {return c;} @Override public void setConversation(Conversation conversation) {} @Override public String getContents() { return "you have connected to "+c.getName(); } @Override public void setContents(String contents) { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } @Override public void delete() { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } @Override public void save() { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } }, c.getId()); } catch (NoMessageListException ex) { Logger.getGlobal().log(Level.SEVERE, null, ex); } } }); } } for (final Message msg: list){ Platform.runLater(new Runnable() { @Override public void run() { try{ mGUI.displayMessage(msg, c.getId()); } catch (NoMessageListException ex) { Logger.getGlobal().log (Level.SEVERE, "message from conversation "+c.getId()+" could not be displayed the map contains " +mGUI.getMap().toString(), ex); } mGUI.scrollToEnd(c.getId()); } }); } } private void replaceConversations() { (new Thread(new Runnable(){ @Override @SuppressWarnings("SleepWhileInLoop") public void run() { while (true){ try { Thread.sleep(CONVREPLACEDELAY); } catch (InterruptedException ex) { Logger.getGlobal().log(Level.SEVERE, null, ex); } List<Conversation> conv = null; try { conv = mAPI.conferenceResource.mostUsers(mTC.getConfrenceID(), 10); } catch (Exception ex) { log(ex); } for (int c = 0; c<mConversations.size(); c++){ if (!isContainedIn(conv,mConversations.get(c))){ for (int c2 = 0; c2<conv.size(); c2++){ //the conversation to be replaced Conversation currentConversation = mConversations.get(c); //the conversation to replace Conversation newConversation = conv.get(c2); //new lists List<Conversation> newmConversations = new ArrayList(); List<Subscription> newmSub = new ArrayList(); //unsubscribe to old subscription mSub.get(c).unsubscribe(); //replace conversation in mConversations for (int i = 0; i < c; i++){newmConversations.add(mConversations.get(i));} newmConversations.add(newConversation); for (int i = c+1;i<mConversations.size();i++){newmConversations.add(mConversations.get(i));} //map the conversation to the correct GUI pane try{ mGUI.replaceConversation(currentConversation.getId(), newConversation.getName(), newConversation.getId()); } catch (NoMessageListException ex) { Logger.getGlobal().log(Level.SEVERE, "there has been an issue while replacing conversation "+mConversations.get(c).getName(), ex); } catch (NotCurrentConversationException ex) { Logger.getGlobal().log(Level.SEVERE, null, ex); break; } catch (ConversationAlredyDisplayedException ex) { continue;//this ocurs if the replacement conversation is alredy on screen } //replace subscription in mSub for (int i = 0; i < c; i++){newmSub.add(mSub.get(i));} newmSub.add(listenToConversation(newConversation)); for (int i = c+1;i<mSub.size();i++){newmSub.add(mSub.get(i));} //set mSub and mConversation synchronized (mConversations){ synchronized (mSub){ mSub.clear(); mConversations.clear(); mSub.addAll(newmSub); mConversations.addAll(newmConversations); } } break; } } } } } private boolean isContainedIn(List<Conversation> conv, Conversation val) { for (Conversation c: conv){ if (c.getId()==val.getId()){return true;} } return false; } })).start(); } public ConvStats getStats(long conversationID) { if (conversationID<0){return new ConvStats(0,0,0,0.5);} try{ Conversation c = mAPI.conversationResource.get(conversationID); return new ConvStats(mAPI.conferenceResource.userCount(mConfrence.getId(), conversationID), mAPI.conferenceResource.contributingUsers(mConfrence.getId(), conversationID, false), mAPI.conferenceResource.messageCount(mConfrence.getId(), conversationID), mAPI.conferenceResource.maleToFemaleRatio(mConfrence.getId(),conversationID)); } catch (Exception e){log(e);} return new ConvStats(0,0,0,0.5); } public ConfrenceStats getGlobalStats() { try{ return new ConfrenceStats(mAPI.conferenceResource.getConversations(mConfrence.getId())); }catch (Exception e){log(e);} return null; } double getNumberOfMessages(Long val2) { try{ for (Conversation c:mAPI.conferenceResource.getConversations(mConfrence.getId())){ if (c.getId()==val2){ return c.getMessages().size(); } } }catch (Exception e){log(e);} return 0; } Number getActivity() { try{ return mAPI.conferenceResource.activity(mConfrence.getId(), (1000*60*5)); }catch (Exception e){log(e);} return Integer.valueOf(0); } List<User> getUsers(long id) { try{ for (Conversation c: mAPI.conferenceResource.getConversations(mConfrence.getId())){ if (c.getId()==id){return (List<User>)c.getUsers();} } }catch (Exception e){log(e);} return new ArrayList<User>(); } private void log(Exception e) { Logger.getGlobal().log(Level.SEVERE, "There has been an issue with the server", e); mTC.exit(5, "The connection to the server has failed"); } public String getConfrenceName() { return mConfrence.getName(); } /** * * @param conversationID the id of the conversation * @param timeStamp the last timestamp to check from * @return a List of the tags */ public Map<String,Long> getTags(long conversationID, long timeStamp) { while (mAPI==null){} System.err.println("here 1"); if (conversationID < 0){ System.err.println(conversationID); return null; } System.err.println("here 2"); try{ System.err.println(mAPI.conferenceResource.getKeywords(mConfrence.getId(), conversationID, timeStamp)==null ? "is null":"not null"); return mAPI.conferenceResource.getKeywords(mConfrence.getId(), conversationID, timeStamp); } catch (Exception e){ Logger.getGlobal().log(Level.SEVERE, "faild to get the tags for the conversation tag clouds", e); } return null; } }