KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > chat > presentation > ContentsPresentation


1 /**
2  * Andy John
3  * 2/99
4  * chat room
5  * andy@enhydra.org
6  * www.enhydra.org
7  *
8  * This is a "by hand" presentation object (Enhydra Jolt was not used).
9  * This is because there is so much java code and so little static HTML that
10  * it is easier to write it by hand.
11  * This page and the Discussion business object are the core of the
12  * "on hold push" algorithm (see the Discussion object). The browser has
13  * asked for a snapshot. They may have sent in a state id. If so, then they
14  * already have something on their screen, and they are really asking for
15  * something new. This state id (or 0 if none was sent), is passed on to
16  * the Discussion object when we ask for a snapshot. It uses it to (maybe)
17  * block (not return) until there is some new state (a message has been
18  * added or deleted from the list).
19  * The browser also probably specified a time limit it is willing to wait.
20  * The browser will time out before TCP/IP will, so we use a one minute
21  * timeout. If the browser times out, it breaks the reload cycle, and the
22  * user stops seeing messages.
23  * Becuase the call to the Discussion object might block for up to a
24  * minute, there may be several threads waiting around in this object.
25  */

26
27 package chat.presentation;
28
29 import java.util.Vector JavaDoc;
30 import com.lutris.appserver.server.httpPresentation.*;
31 import chat.ChatApplication;
32 import chat.spec.*;
33
34 /**
35  * Because this page has alot more code than html content, and because
36  * so much of the page is generated in Java anyway, I chose to write this
37  * presentation object by hand, ranther than using Jolt.
38  */

39 public class ContentsPresentation implements HttpPresentation {
40
41     /*
42      * How long can we make the browsers wait till they time out.
43      * This is a conservative guess (one minute).
44      */

45     private static final int refreshWait = 60;
46
47     /*
48      * This is used with the "unique" query string parameter. It is a
49      * psued-hack to make every page look unique. Otherwise sometimes the
50      * browser will think that a request looks like an old one and try
51      * to slip you results from the cache. By using the counter, each
52      * request is guarenteed to look unique. The actual value is not
53      * used by the program.
54      */

55     private static long counter = 0;
56
57
58     /**
59      * The main body of a presentation object. See the class comments above.
60      */

61     public void run(HttpPresentationComms comms) throws Exception JavaDoc {
62         // Try to get the current state, default to zero.
63
long state = 0;
64         try {
65             String JavaDoc stateStr = comms.request.getParameter("state");
66             if (stateStr != null)
67                 state = Long.parseLong(stateStr);
68         } catch (Exception JavaDoc e) {
69         }
70         // Try to get the wait timeout. Default to zero.
71
long wait = 0;
72         try {
73             String JavaDoc waitStr = comms.request.getParameter("wait");
74             if (waitStr != null)
75                 wait = Long.parseLong(waitStr);
76         } catch (Exception JavaDoc e) {
77         }
78         /*
79          * Get a snapshot! This may take up to wait seconds.
80          */

81      
82            DiscussionManager discussionManager = DiscussionManagerFactory.getDiscussionManager("chat.business.DiscussionManagerImpl");
83    
84    
85    
86
87   
88       
89       
90         /*
91          * Start writing out the page.
92          */

93         ChatApplication myApp = (ChatApplication) comms.application;
94
95         comms.response.setContentType("text/html");
96         comms.response.setHeader("Expires", "Tue, 01 Jan 1980 1:00:00 GMT");
97         comms.response.setHeader("Pragma", "no-cache");
98         HttpPresentationOutputStream out = comms.response.getOutputStream();
99
100         out.println("<HTML>");
101         out.println("<HEAD></HEAD>");
102         out.println("<BODY onload=\"loadOn();\" BGCOLOR=" + myApp.getBgColor() +">");
103         out.println("<h3><center><font color=purple>" +
104                     myApp.getRoomName() +
105                     "</font></center></h3>");
106
107 /*
108  * Catch Null pointer exception ( we canot make a instances of classes from business layer when we run chat_pres )
109  * We need to allow chat_pres to be functional , so if the requested url is /chat_pres/..... the response
110  * will be default HTML page
111  */

112    
113  try{
114         Snapshot snap = discussionManager.getContents(state, wait);
115       
116         if ((snap.getContents() == null) || (snap.getContents().size() == 0)) {
117             out.println("<center><i><br><br><br><font color=purple><b>" +
118                         "There are currently no messages." +
119                         "</b></font></i></center>\n");
120         } else {
121             for (int i=snap.getContents().size()-1; i>=0; i--) {
122                 /*
123                  * I used to display the messages in the "normal" order,
124                  * but ran into browser incompatabilites with scrolling,
125                  * named anchors, meta refresh tags etc...
126                  * This way it works on all browsers (which is a good
127                  * thing for a demo).
128                  */

129                 
130             Message msg = (Message) snap.getContents().elementAt(i);
131                                  
132                 if (msg == null)
133                     continue;
134                 out.print("<b>");
135                 if ((msg.getHtmlName() == null) || (msg.getHtmlName().length() == 0))
136                      out.print("<i>Anonymous</i>");
137                 else
138                      out.print(msg.getHtmlName());
139                 out.print(":</b> ");
140                 if (msg.getHtmlChunks().size() > 1)
141                     out.print("<br>\n&nbsp;&nbsp;&nbsp;&nbsp;");
142                 for (int j=0; j<((Vector JavaDoc)msg.getHtmlChunks()).size(); j++) {
143                     if (j != 0)
144                         out.print("&nbsp;&nbsp;&nbsp;&nbsp;");
145                     out.print((String JavaDoc) ((Vector JavaDoc)msg.getHtmlChunks()).elementAt(j));
146                     out.println("<br>");
147                 }
148             }
149         }
150   
151         
152         /*
153          * A key part of the "on hold push" algorithm is that the client
154          * asks for a new snapshot as soon as it is done processing the
155          * current snapshot. This synamic Javascript triggers the browser to
156          * reload, passing on the current state id.
157          * I used to use a refresh HTTP header, but IE has problems with
158          * that when you add a query string.
159          */

160         
161         out.println("<SCRIPT TYPE=\"text/javascript\" LANGUAGE=\"JavaScript\" id=\"RealScript\">\n"
162                 + "<!--\n"
163                 + " function loadOn() {\n"
164                 + " window.location.href = \"ContentsPresentation.po?state=" + snap.getState() + "&wait=" + refreshWait + "&uniqe=" + counter +"\"\n"
165                 + " }\n"
166                 + "//-->\n"
167                 + "</SCRIPT>");
168    
169   }catch(NullPointerException JavaDoc e){}
170         /*
171          * Close out the page.
172          */

173         out.println("</BODY>");
174         out.println("</HTML>");
175     }
176
177 }
178
179
Popular Tags