import javax.servlet.*; import javax.servlet.http.*; import java.io.*; import java.net.*; import java.util.*; import MDMSupport.*; import com.objectspace.jgl.*; public class MDMessageServlet extends HttpServlet { //Initialize global variables MDMessageSource source = new MDMessageSource(); MDMessageRepository mmr; FMSInterface fms; DBServerInterface dbm; Queue messages = new Queue(); messageRebroadcastThread messageRebroadcast; public void init(ServletConfig config) throws ServletException { try{ super.init(config); mmr = MDMessageRepository.getInstance(); dbm = (DBServerInterface)System.getProperties().get("MDM.DBServer"); fms = (FMSInterface)System.getProperties().get("MDM.FMServer"); messageRebroadcast = new messageRebroadcastThread(); messageRebroadcast.setPriority(Thread.MIN_PRIORITY); messageRebroadcast.setDaemon(true); messageRebroadcast.start(); } catch(Exception ex){ ex.printStackTrace(); } } //Process the HTTP Get request public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { PrintWriter out = res.getWriter(); try{ res.setContentType("text/plain"); out.println(getNextMessage()); } catch(Exception ex){ ex.printStackTrace(); } finally{ out.close(); } } //Process the HTTP Post request public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { ObjectInputStream ois = new ObjectInputStream(req.getInputStream()); try{ Object obj = ois.readObject(); ReceivedMDMessage rm = (ReceivedMDMessage)obj; System.out.println("MD Message Servlet: " + rm.receiver + " getting message from " + (String)rm.msg.elementAt(0)); if(rm != null){ broadcastMessage(rm); } res.setStatus(res.SC_NO_CONTENT); rm = null; } catch(Exception ex){ ex.printStackTrace(); } finally{ ois.close(); } } //return the next new message public String getNextMessage(){ return new MDMessageSink().getNextMessage(source); } //inform all currently listening clients that there is a new message public void broadcastMessage(ReceivedMDMessage rm){ try{ String receiverStatus = dbm.getStatus(rm.receiver); if(receiverStatus.equalsIgnoreCase("Online")){ mmr.add(rm.receiver, rm); System.out.println("MMS: Message rep: " + mmr); source.sendMessage(rm.receiver); messages.push(rm.receiver); } else{ fms.addMsg(rm.receiver, "OFFLINE", rm.msg); } } catch(NullPointerException ex){ try{ System.out.println("Recreating connection to FMServer"); org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(); fms = FMSInterfaceHelper.bind(orb, "FMServer"); System.getProperties().put("MDM.FMServer", fms); dbm = DBServerInterfaceHelper.bind(orb, "DBServer"); System.getProperties().put("MDM.DBServer", dbm); } catch(Exception subEx){ subEx.printStackTrace(); } } catch(ClassCastException ex){ try{ System.out.println("Recreating connection to FMServer"); org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(); fms = FMSInterfaceHelper.bind(orb, "FMServer"); System.getProperties().put("MDM.FMServer", fms); dbm = DBServerInterfaceHelper.bind(orb, "DBServer"); System.getProperties().put("MDM.DBServer", dbm); } catch(Exception subEx){ subEx.printStackTrace(); } } catch(Exception ex){ ex.printStackTrace(); } } public void broadcastSystemMessage(String message){ source.sendMessage(message); } public void destroy(){ fms = null; dbm = null; mmr.destroy(); messageRebroadcast.stopThread(); } public void handleClient(Socket client){ } //Get Servlet information public String getServletInfo() { return "MDM.ChatServlet Information"; } class messageRebroadcastThread extends Thread{ private boolean isStopPending = false; public void stopThread(){ isStopPending = true; } public void run(){ System.out.println("Message rebroadcaster started..."); while(!isStopPending){ try{ while(!messages.isEmpty()){ String message = (String)messages.pop(); sleep(5000); System.out.println("Rebroadcast " + message); broadcastSystemMessage(message); } sleep(3000); } catch(Exception ex){ ex.printStackTrace(); } } } } } class MDMessageSource extends Observable{ public void sendMessage(String message){ setChanged(); notifyObservers(message); } } class MDMessageSink implements Observer{ String message = null; synchronized public void update(Observable o, Object arg){ message = (String) arg; notify(); } synchronized public String getNextMessage(MDMessageSource source){ source.addObserver(this); while (message == null){ try{wait();}catch(Exception ignored) {} } source.deleteObserver(this); String messageCopy = message; message = null; return messageCopy; } }