KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > barracuda > core > event > events > LongRunningEventGateway


1 /*
2  * Copyright (C) 2003 Christian Cryder [christianc@granitepeaks.com]
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * $Id: LongRunningEventGateway.java,v 1.2 2004/02/01 05:16:28 christianc Exp $
19  */

20 package org.enhydra.barracuda.core.event.events;
21
22 import java.io.*;
23 import java.util.*;
24 import java.net.*;
25 import javax.servlet.*;
26 import javax.servlet.http.*;
27
28 import org.apache.log4j.*;
29
30 import org.enhydra.barracuda.core.comp.*;
31 import org.enhydra.barracuda.core.event.*;
32 import org.enhydra.barracuda.core.event.helper.*;
33 import org.enhydra.barracuda.core.helper.servlet.*;
34 import org.enhydra.barracuda.plankton.*;
35 import org.enhydra.barracuda.plankton.data.*;
36 //import org.enhydra.barracuda.plankton.http.*;
37
import org.enhydra.barracuda.core.util.dom.*;
38 import org.enhydra.barracuda.core.util.http.*;
39 import org.enhydra.barracuda.core.event.events.xmlc.*;
40
41
42 /**
43  * Event handlers (both Controller and View) for the LongRunning events
44  */

45 public class LongRunningEventGateway extends DefaultEventGateway {
46
47     //public constants
48
protected static final Logger logger = Logger.getLogger(LongRunningEventGateway.class.getName());
49
50     //configurable through object repos assembler
51
public static Class JavaDoc DEFAULT_TEMPLATE = LongRunningHTML.class;
52     public static int DEFAULT_ETA = 180;
53     public static int DEFAULT_REFRESH_RATE = 3;
54
55     //Get_Data directives supported
56
public static final String JavaDoc CHECK_LONG_RUNNING = "CheckLongRunning"; //(BAction)
57
public static final String JavaDoc CANCEL_LONG_RUNNING = "CancelLongRunning"; //(BAction)
58
public static final String JavaDoc TIME_ETA = "TimeETA"; //(String describing ETA in hours, minutes, and secs)
59
public static final String JavaDoc TIME_ELAPSED = "TimeElapsed"; //(String describing ETA in hours, minutes, and secs)
60
public static final String JavaDoc TIME_REMAINING = "TimeRemaining"; //(String describing ETA in hours, minutes, and secs)
61
public static final String JavaDoc PERCENT_COMPLETE = "PercentComplete"; //(int)
62
public static final String JavaDoc PERCENT_REMAINING = "PercentRemaining"; //(int)
63
public static final String JavaDoc STATEMAP_VALUE = "StateMapValue"; //(String - data portion of TemplateDirective used as StateMap key)
64
public static final String JavaDoc REFRESH_RATE = "RefreshRate"; //(int - in seconds)
65

66     //req params
67
public static final String JavaDoc LRG_ID = "$lrgid"; //(String)
68

69     //this defines the various event handlers
70
private ListenerFactory baseLongRunningFactory = new DefaultListenerFactory() {public BaseEventListener getInstance() {return new BaseLongRunningHandler();} public String JavaDoc getListenerID() {return getID(BaseLongRunningHandler.class);}};
71     private ListenerFactory checkLongRunningFactory = new EventForwardingFactory(new RenderLongRunningEvent());
72     private ListenerFactory cancelLongRunningFactory = new DefaultListenerFactory() {public BaseEventListener getInstance() {return new CancelLongRunningHandler();} public String JavaDoc getListenerID() {return getID(CancelLongRunningHandler.class);}};
73     private ListenerFactory renderLongRunningFactory = new DefaultListenerFactory() {public BaseEventListener getInstance() {return new RenderLongRunningHandler();} public String JavaDoc getListenerID() {return getID(RenderLongRunningHandler.class);}};
74
75
76
77
78     /**
79      * Public constructor
80      */

81     public LongRunningEventGateway() {
82         //specify who's interested in what
83
specifyLocalEventInterests(baseLongRunningFactory, LongRunningEvent.class);
84         specifyLocalEventInterests(checkLongRunningFactory, CheckLongRunningEvent.class);
85         specifyLocalEventInterests(cancelLongRunningFactory, CancelLongRunningEvent.class);
86         specifyLocalEventInterests(renderLongRunningFactory, RenderLongRunningEvent.class);
87     }
88
89
90     //------------------------------------------------------------
91
// Model 2 - Controller Event Handlers
92
//------------------------------------------------------------
93
/**
94      * Gets invoked for both CheckLongRunningEvent and CancelLongRunningEvent.
95      * Basically just makes sure that everything needed (lrid and dresp) is
96      * available before continuing.
97      */

98     class BaseLongRunningHandler extends DefaultBaseEventListener {
99         public void handleControlEvent(ControlEventContext context) throws EventException, ServletException, IOException {
100             //get the basic objects
101
ObjectRepository session = ObjectRepository.getSessionRepository();
102             ObjectRepository lor = ObjectRepository.getLocalRepository();
103             HttpServletRequest req = (HttpServletRequest) lor.getState(ApplicationGateway.HTTP_SERVLET_REQUEST);
104             HttpServletResponse resp = (HttpServletResponse) lor.getState(ApplicationGateway.HTTP_SERVLET_RESPONSE);
105
106             //get the lrid
107
String JavaDoc lrid = req.getParameter(LRG_ID);
108             logger.info("invoking CheckLongRunningHandler, for "+LRG_ID+"="+lrid);
109
110             //if we don't have any accompanying lrid, err
111
if (lrid==null) {
112                 resp.sendError(HttpServletResponse.SC_GONE, "This event was missing a long running target ID. Please try running the report again.");
113                 return;
114             } else {
115                 lor.putState(LRG_ID, lrid);
116             }
117
118             //if there is no DeferredResponseWrapper living in the session for this lrid, err
119
DeferredResponseWrapper dresp = (DeferredResponseWrapper) session.getState(lrid);
120             if (dresp==null) {
121                 resp.sendError(HttpServletResponse.SC_GONE, "This long running response was missing from the session. The long running report has either completed or been canceled.");
122                 return;
123             } else {
124                 lor.putState(lrid, dresp);
125             }
126
127             //sit and spin until we have a LongRunning object available in the dresp
128
//(what happens is the CheckLongRunningEvent handler gets dispatched at the same time as
129
//the request to actually execute the long running task - this means we may actually be handling
130
//this request before the LongRunning object has been added to the dresp yet...so if its not
131
//there, we want to sit and spin a bit until we get it; if it doesn't show up after 5 secs, something
132
//is wrong)
133
int tryCntr = 0;
134             while (dresp.getLongRunning()==null) {
135                 try {
136                     if (++tryCntr>50) {
137                         resp.sendError(HttpServletResponse.SC_GONE, "This LongRunning object never showed up in the DeferredResponseWrapper. Aborting LongRunningHandler...");
138                         return;
139                     }
140                     Thread.currentThread().sleep(100);
141                 } catch (InterruptedException JavaDoc e) {
142                 }
143             }
144         }
145     }
146
147     /**
148      * Actually cancel the long running process
149      */

150     class CancelLongRunningHandler extends DefaultBaseEventListener {
151         public void handleControlEvent(ControlEventContext context) throws EventException, ServletException, IOException {
152
153             //get the dresp obj
154
ObjectRepository session = ObjectRepository.getSessionRepository();
155             ObjectRepository lor = ObjectRepository.getLocalRepository();
156             HttpServletRequest req = (HttpServletRequest) lor.getState(ApplicationGateway.HTTP_SERVLET_REQUEST);
157             HttpServletResponse resp = (HttpServletResponse) lor.getState(ApplicationGateway.HTTP_SERVLET_RESPONSE);
158             String JavaDoc lrid = (String JavaDoc) lor.getState(LRG_ID);
159             DeferredResponseWrapper dresp = (DeferredResponseWrapper) lor.getState(lrid);
160
161             //get the LongRunning object so we can see where to go from here
162
LongRunning lr = (LongRunning) dresp.getLongRunning();
163
164             //stop the dresp
165
dresp.interrupt();
166
167             //clean up the session
168
session.removeState(lrid+"*");
169
170             //get the redirect url. If none is specified, simply write an error response
171
resp.setContentType("text/html");
172             StringBuffer JavaDoc sb = new StringBuffer JavaDoc(500);
173             BaseEvent redirectEvent = lr.getRedirectEvent();
174             if (redirectEvent==null) {
175                 if (logger.isInfoEnabled()) logger.info("LongRunning processes cancelled, generating default description");
176                 sb.append("<html>");
177                 sb.append(" <head>");
178                 sb.append(" <title>Cancelled</title>");
179                 sb.append(" </head>");
180                 sb.append(" <body>");
181                 sb.append(" <h1>Cancelled.</h1>");
182                 sb.append(" <p>The Long Running process was cancelled.");
183                 sb.append(" </body>");
184                 sb.append("</html>");
185             
186             //...otherwise, redirect the browser
187
} else {
188                 //request the browser to redirect accordingly
189
ClientSideRedirectException re = new ClientSideRedirectException(redirectEvent);
190                 String JavaDoc rdURL = URLRewriter.encodeRedirectURL(req, resp, re.getRedirectURL());
191                 if (logger.isInfoEnabled()) logger.info("LongRunning processes cancelled, redirecting to "+rdURL);
192                 sb.append("<html>");
193                 sb.append(" <head>");
194                 sb.append(" <title>Redirecting...</title>");
195                 sb.append(" </head>");
196 // sb.append(" <body onload=\"window.top.pageFullyLoaded=true; window.top.location.replace('"+rdURL+"');\">");
197
sb.append(" <body onload=\"window.top.pageFullyLoaded=true; window.top.location.replace('"+rdURL+"');\" style=\"font-family: Georgia, Arial, Times New Roman\">");
198                 sb.append(" <p>&nbsp;<p>&nbsp;<p>&nbsp;<div style=\"text-align: center\">Cancelling request (this may take a few seconds...)</div>");
199                 sb.append(" </body>");
200                 sb.append("</html>");
201             }
202             String JavaDoc content = sb.toString();
203             Writer wr = resp.getWriter();
204             wr.write(content);
205             wr.close();
206             resp.flushBuffer();
207         }
208     }
209
210
211     //------------------------------------------------------------
212
// Model 2 - View Event Handlers
213
//------------------------------------------------------------
214
/**
215      * RenderLongRunningHandler -
216      */

217     class RenderLongRunningHandler extends BTemplateViewHandler {
218         ObjectRepository lor = ObjectRepository.getLocalRepository();
219         String JavaDoc lrid = (String JavaDoc) lor.getState(LRG_ID);
220         DeferredResponseWrapper dresp = (DeferredResponseWrapper) lor.getState(lrid);
221         LongRunning lr = (LongRunning) dresp.getLongRunning();
222
223         public Object JavaDoc getTemplateModels() {
224             List models = lr.getAdditionalModels();
225             models.add(new LocalTemplateModel());
226             return models;
227         }
228         public Class JavaDoc getTemplateClass() {
229             return lr.getTemplateClass();
230         }
231         public class LocalTemplateModel extends AbstractTemplateModel {
232
233             //register the model by name
234
public String JavaDoc getName() {return "LongRunningModel";}
235
236             //provide items by key
237
public Object JavaDoc getItem(TemplateDirective td) {
238                 String JavaDoc cmd = td.getCommand();
239                 String JavaDoc key = td.getKeyName();
240                 String JavaDoc data = td.getKeyData();
241                 Object JavaDoc item = null;
242         
243                 //get a list of all key/total vals
244
if (key.equals(CHECK_LONG_RUNNING)) {
245                     BAction baction = new BAction(new CheckLongRunningEvent());
246                     baction.setParam(LRG_ID, lrid);
247                     item = baction;
248              
249                 } else if (key.equals(CANCEL_LONG_RUNNING)) {
250                     BAction baction = new BAction(new CancelLongRunningEvent());
251                     baction.setParam(LRG_ID, lrid);
252                     item = baction;
253
254                 } else if (key.equals(TIME_ETA)) {
255                     item = StringUtil.getElapsedStr((long) (lr.getETA()*1000), Calendar.SECOND);
256
257                 } else if (key.equals(TIME_ELAPSED)) {
258                     item = StringUtil.getElapsedStr((long) (lr.getElapsed()*1000), Calendar.SECOND);
259
260                 } else if (key.equals(TIME_REMAINING)) {
261                     int remaining = lr.getETA() - lr.getElapsed();
262                     if (remaining<1) remaining = 1;
263                     item = StringUtil.getElapsedStr((long) (remaining*1000), Calendar.SECOND);
264
265                 } else if (key.equals(PERCENT_COMPLETE)) {
266                     item = lr.getPercentComplete()+"%";
267                     
268                 } else if (key.equals(PERCENT_REMAINING)) {
269                     item = (100 - lr.getPercentComplete())+"%";
270                     
271                 } else if (key.equals(REFRESH_RATE)) {
272                     item = ""+lr.getRefreshRate();
273                     
274                 } else if (key.equals(STATEMAP_VALUE)) {
275                     Object JavaDoc val = lr.getStateMap().getState(data);
276                     item = (val!=null ? val : "[Undefined Statemap Key: "+data+"]");
277                     
278                 } else {
279                     item = super.getItem(td);
280                 }
281                 
282                 //return item
283
return item;
284             }
285         }
286     }
287 }
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
Popular Tags