KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > beehive > netui > tools > testrecorder > server > TestRecorderServlet


1 /*
2  * Copyright 2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  * $Header:$
17  */

18
19 package org.apache.beehive.netui.tools.testrecorder.server;
20
21 import java.io.File JavaDoc;
22 import java.io.IOException JavaDoc;
23 import java.io.Writer JavaDoc;
24 import java.io.FileReader JavaDoc;
25 import java.io.InputStream JavaDoc;
26 import java.io.InputStreamReader JavaDoc;
27 import javax.servlet.http.HttpServlet JavaDoc;
28 import javax.servlet.http.HttpServletRequest JavaDoc;
29 import javax.servlet.http.HttpServletResponse JavaDoc;
30 import javax.servlet.ServletException JavaDoc;
31 import javax.servlet.RequestDispatcher JavaDoc;
32
33 import org.apache.beehive.netui.tools.testrecorder.shared.Logger;
34 import org.apache.beehive.netui.tools.testrecorder.shared.Constants;
35 import org.apache.beehive.netui.tools.testrecorder.shared.Reporter;
36 import org.apache.beehive.netui.tools.testrecorder.shared.RecordSessionBean;
37 import org.apache.beehive.netui.tools.testrecorder.shared.RequestData;
38 import org.apache.beehive.netui.tools.testrecorder.shared.SessionXMLException;
39 import org.apache.beehive.netui.tools.testrecorder.shared.xmlbeans.XMLHelper;
40 import org.apache.beehive.netui.tools.testrecorder.shared.config.TestDefinition;
41 import org.apache.beehive.netui.tools.testrecorder.shared.config.ConfigException;
42 import org.apache.beehive.netui.tools.testrecorder.shared.config.Category;
43 import org.apache.beehive.netui.tools.testrecorder.shared.config.WebappConfig;
44 import org.apache.beehive.netui.tools.testrecorder.server.state.PlaybackSession;
45 import org.apache.beehive.netui.tools.testrecorder.server.state.RecordSession;
46 import org.apache.beehive.netui.tools.testrecorder.server.state.State;
47 import org.apache.beehive.netui.tools.testrecorder.server.state.SessionFailedException;
48
49
50 public class TestRecorderServlet extends HttpServlet JavaDoc {
51
52     private static final Logger log = Logger.getInstance( TestRecorderServlet.class );
53
54     public TestRecorderServlet() {
55     }
56
57     public void init() {
58         if ( log.isInfoEnabled() ) {
59             log.warn( "initializing ..." );
60         }
61     }
62
63     public void destroy() {
64         if ( log.isInfoEnabled() ) {
65             log.warn( "destroying ..." );
66         }
67         super.destroy();
68     }
69
70     public void doPost( HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response )
71             throws ServletException JavaDoc, IOException JavaDoc {
72         doGet( request, response );
73     }
74
75     public void doGet( HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response )
76             throws ServletException JavaDoc, IOException JavaDoc {
77         String JavaDoc mode = null;
78         try {
79             mode = request.getParameter( Constants.MODE );
80             if ( mode == null ) {
81                 // fail
82
String JavaDoc msg = "mode( " + mode + " ) may not be null.";
83                 forward( request, response, msg, Constants.ERROR_PAGE, true );
84                 return;
85             }
86             else if ( mode.equalsIgnoreCase( Constants.RECORD ) ) {
87                 doRecord( request, response );
88             }
89             else if ( mode.equalsIgnoreCase( Constants.PLAYBACK ) ) {
90                 doPlayback( request, response );
91             }
92             else if ( mode.equalsIgnoreCase( Constants.DPY_DIFF ) ) {
93                 doDiff( request, response );
94             }
95             else if ( mode.equalsIgnoreCase( Constants.DPY_DETAILS ) ) {
96                 doDetails( request, response );
97             }
98             else if ( mode.equalsIgnoreCase( Constants.DPY_LINK ) ) {
99                 doLink( request, response );
100             }
101             else if ( mode.equalsIgnoreCase( Constants.ADMIN ) ) {
102                 doAdmin( request, response );
103             }
104             else if ( mode.equalsIgnoreCase( Constants.XML_MODE ) ) {
105                 doXml( request, response );
106             }
107             else {
108                 // fail
109
String JavaDoc msg = "unknown mode( " + mode + " ).";
110                 forward( request, response, msg, Constants.ERROR_PAGE, true );
111                 return;
112             }
113         }
114         catch ( Exception JavaDoc ex ) {
115             String JavaDoc msg = "ERROR: encountered exception handling test recorder control request, mode( " + mode +
116                     ", exception( " + ex.getMessage() + " )";
117             forward( request, response, msg, Constants.ERROR_PAGE, true, ex );
118         }
119     }
120
121     public void doRecord( HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response )
122             throws ServletException JavaDoc, IOException JavaDoc, ConfigException {
123         String JavaDoc cmd = request.getParameter( Constants.CMD );
124         String JavaDoc testName = getTestName( request );
125         String JavaDoc testUser = request.getParameter( Constants.TEST_USER );
126         String JavaDoc description = request.getParameter( Constants.DESCRIPTION );
127         boolean overwrite = Boolean.valueOf( request.getParameter( Constants.OVERWRITE ) ).booleanValue();
128         if ( log.isInfoEnabled() ) {
129             log.debug( "record cmd( " + cmd + " )" );
130             log.debug( "testName( " + testName + " )" );
131         }
132         if ( log.isDebugEnabled() ) {
133             log.debug( "testUser( " + testUser + " )" );
134             log.debug( "overwrite( " + overwrite + " )" );
135             log.debug( "description( " + description + " )" );
136         }
137         if ( cmd == null ) {
138             // fail
139
String JavaDoc msg = "ERROR: unable to handle record request, '" + Constants.CMD + "' may not be null.";
140             forward( request, response, msg, Constants.ERROR_PAGE, true );
141             return;
142         }
143         if ( cmd.equalsIgnoreCase( Constants.START ) ) {
144             doRecordStart( testName, request, response, overwrite, testUser, description );
145         }
146         else if ( cmd.equalsIgnoreCase( Constants.STOP ) ) {
147             doRecordStop( request, response );
148         }
149         else {
150             // fail
151
String JavaDoc msg = "ERROR: unable to handle record request: '" + Constants.CMD + "'( " + cmd +
152                     " ) is not recognized.";
153             forward( request, response, msg, Constants.ERROR_PAGE, true );
154             return;
155         }
156     }
157
158     private void doRecordStop( HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response ) throws IOException JavaDoc,
159             ServletException JavaDoc {
160         TestRecorderFilter filter = TestRecorderFilter.instance();
161         RecordSession session = filter.getState().getRecordingSession();
162         String JavaDoc msg = "ERROR: failed stopping recording session";
163         if ( log.isDebugEnabled() ) {
164             log.debug( "STOPPING: recording session( " + session + " )" );
165         }
166         try {
167             // this may take some time, this waits for recording threads to finish
168
session = filter.getState().recordStop();
169             if ( session == null ) {
170                 // fail, not currently recording
171
msg = "ERROR: no recording session is currently started";
172                 if ( log.isWarnEnabled() ) {
173                     log.warn( msg );
174                 }
175             }
176             else {
177                 request.setAttribute( Constants.RECORD_SESSION_ATTRIBUTE, session );
178                 msg = "Recording session( " + session.getSessionName() + " ) stopped";
179                 if ( log.isInfoEnabled() ) {
180                     log.info( msg );
181                 }
182             }
183             forward( request, response, msg, Constants.RECORD_PAGE, false );
184
185         }
186         catch ( Exception JavaDoc ex ) {
187             msg = "ERROR: failed while stopping recording";
188             request.setAttribute( Constants.RECORD_SESSION_ATTRIBUTE, session );
189             forward( request, response, msg, Constants.RECORD_PAGE, true, ex );
190         }
191         if ( log.isDebugEnabled() ) {
192             log.debug( "STOPPED: recording session( " + session + " )" );
193         }
194     }
195
196     private void doRecordStart( String JavaDoc testName, HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response,
197             boolean overwrite, String JavaDoc testUser, String JavaDoc description ) throws IOException JavaDoc, ServletException JavaDoc {
198         TestDefinition test = getTest( testName );
199         if ( test == null ) {
200             test = new TestDefinition( testName, description, TestRecorderFilter.instance().getWebapp(), null );
201         }
202         if ( test.getWebapp() != TestRecorderFilter.instance().getWebapp() ) {
203             String JavaDoc msg = "ERROR: unable to start recording, the webapp of the test( " +
204                     test.getWebapp().getName() + " ) is not the same as this webapp( " +
205                     TestRecorderFilter.instance().getWebapp() + " )";
206             forward( request, response, msg, Constants.RECORD_PAGE, true );
207             return;
208         }
209         // may throw IOException or SecurityException
210
RecordSession session = null;
211         try {
212             session = getRecordSession( test, overwrite, testUser, description );
213             if ( description != null ) {
214                 test.setDescription( description );
215             }
216             TestRecorderFilter.instance().getTestDefinitions().add( test );
217         }
218         catch ( Exception JavaDoc ex ) {
219             String JavaDoc msg = "ERROR: unable to start recording, unable to obtain session, exception( " +
220                     ex.getMessage() + " )";
221             forward( request, response, msg, Constants.RECORD_PAGE, true, ex );
222             return;
223         }
224         if ( log.isDebugEnabled() ) {
225             log.debug( "attempting to start recording session( " + session + " )" );
226         }
227         TestRecorderFilter filter = TestRecorderFilter.instance();
228         boolean start = false;
229         try {
230             // may throw IOException
231
start = filter.getState().recordStart( session );
232         }
233         catch ( Exception JavaDoc ex ) {
234             String JavaDoc msg = "ERROR: failed to start recording, exception( " + ex.getMessage() + " )";
235             forward( request, response, msg, Constants.RECORD_PAGE, true, ex );
236             return;
237         }
238         if ( log.isInfoEnabled() ) {
239             log.info( "start( " + start + " )" );
240         }
241         if ( start ) {
242             String JavaDoc msg = "recording session( " + session.getSessionName() + " ) started.";
243             request.setAttribute( Constants.RECORD_SESSION_ATTRIBUTE, session );
244             if ( log.isInfoEnabled() ) {
245                 log.info( msg );
246             }
247             forward( request, response, msg, Constants.RECORD_PAGE, false );
248         }
249         else {
250             String JavaDoc msg = "ERROR: recording session( " +
251                     session.getSessionName() + " ) already started.";
252             request.setAttribute( Constants.RECORD_SESSION_ATTRIBUTE, filter.getState().getRecordingSession() );
253             forward( request, response, msg, Constants.RECORD_PAGE, true );
254         }
255     }
256
257     public void doPlayback( HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response )
258             throws ServletException JavaDoc, IOException JavaDoc, ConfigException {
259         String JavaDoc cmd = request.getParameter( Constants.CMD );
260         if ( log.isInfoEnabled() ) {
261             log.info( "playback cmd( " + cmd + " )" );
262         }
263         // any request forwards from here should skip the filter.
264
request.setAttribute( Constants.FILTER_SKIP_PARAM, Boolean.TRUE );
265         if ( cmd != null ) {
266             if ( cmd.equalsIgnoreCase( Constants.START ) ) {
267                 doPlaybackStart( request, response );
268             }
269             if ( cmd.equalsIgnoreCase( Constants.STOP ) ) {
270                 doPlaybackStop( request, response );
271             }
272         }
273         else {
274             // fail
275
String JavaDoc msg = "ERROR: playback '" + Constants.CMD + "'( " + cmd + " ) is not recognized.";
276             forward( request, response, msg, Constants.ERROR_PAGE, true );
277             return;
278         }
279         forward( request, response, Constants.RECORD_PAGE );
280     }
281
282     private void doPlaybackStop( HttpServletRequest JavaDoc request,
283             HttpServletResponse JavaDoc response ) throws IOException JavaDoc {
284         String JavaDoc testId = request.getParameter( Constants.TEST_ID_HEADER );
285         if ( log.isInfoEnabled() ) {
286             log.info( "playback stop testId( " + testId + " )" );
287         }
288         TestRecorderFilter filter = TestRecorderFilter.instance();
289         PlaybackSession session = null;
290         try {
291             // this may take some time, this waits for recording threads to finish
292
// may throw IOException
293
session = filter.getState().playbackStop( testId );
294         }
295         catch ( Exception JavaDoc ex ) {
296             String JavaDoc msg = "ERROR: unable to stop playback session for testId( " + testId + " ), exception( " +
297                     ex.getMessage() + " )";
298             request.setAttribute( Constants.MSG_ATTRIBUTE, msg );
299             response.setHeader( Constants.OUTCOME_HEADER, Constants.ERROR );
300             log.error( msg, ex );
301             if ( ex instanceof IOException JavaDoc ) {
302                 throw (IOException JavaDoc) ex;
303             }
304             else if ( ex instanceof RuntimeException JavaDoc ) {
305                 throw (RuntimeException JavaDoc) ex;
306             }
307             else {
308                 throw new RuntimeException JavaDoc( msg, ex );
309             }
310         }
311         if ( log.isInfoEnabled() ) {
312             log.info( "STOP: playback session( " + session + " )" );
313         }
314         if ( session == null ) {
315             // fail, not currently doing playback
316
String JavaDoc msg = "ERROR: no playback session exists for testId( " + testId + " )";
317             request.setAttribute( Constants.MSG_ATTRIBUTE, msg );
318             // set response headers for the client.
319
response.setHeader( Constants.OUTCOME_HEADER, Constants.ERROR );
320             response.setHeader( Constants.MSG_ATTRIBUTE, msg );
321             log.error( msg );
322         }
323         else {
324             // gen playback summary
325
// set outcome to stop or fail via resp header
326
// return playback summary as response body.
327
String JavaDoc outcome = session.getStatus();
328             String JavaDoc msg = "playback session( " + session.getSessionName() + " ) stopped with status( " + outcome +
329                     " ).";
330             request.setAttribute( Constants.MSG_ATTRIBUTE, msg );
331             request.setAttribute( Constants.PLAYBACK_SESSION_ATTRIBUTE, session );
332             if ( log.isInfoEnabled() ) {
333                 log.info( msg );
334             }
335             // set response headers for the client.
336
response.setHeader( Constants.OUTCOME_HEADER, outcome );
337             response.setHeader( Constants.MSG_ATTRIBUTE, msg );
338             response.setHeader( Constants.RESULTS_FILE_HEADER, session.getPlaybackFile().getAbsolutePath() );
339             File JavaDoc diffFile = session.getDiffFile();
340             if ( diffFile != null ) {
341                 response.setHeader( Constants.RESULTS_DIFF_HEADER, diffFile.getAbsolutePath() );
342             }
343         }
344     }
345
346     private void doPlaybackStart( HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response )
347             throws IOException JavaDoc, ConfigException {
348         String JavaDoc testName = getTestName( request );
349         TestDefinition test = getTest( testName );
350         if ( test == null ) {
351             throw new ConfigException(
352                     "ERROR: playback start failed, unable to find a test for test name( " + testName + " )" );
353         }
354         if ( log.isInfoEnabled() ) {
355             log.info( "playback start test( " + test.getName() + " )" );
356         }
357         PlaybackSession session = null;
358         try {
359             session = getPlaybackSession( test );
360         }
361         catch ( Exception JavaDoc ex ) {
362             String JavaDoc msg = "ERROR: unable to start playback, unable to obtain session, exception( " +
363                     ex.getMessage() + " )";
364             request.setAttribute( Constants.MSG_ATTRIBUTE, msg );
365             log.error( msg, ex );
366             System.err.println( "\nPLAYBACK ERROR:\n" + msg );
367             if ( ex instanceof IOException JavaDoc ) {
368                 throw (IOException JavaDoc) ex;
369             }
370             else if ( ex instanceof RuntimeException JavaDoc ) {
371                 throw (RuntimeException JavaDoc) ex;
372             }
373             else {
374                 throw new RuntimeException JavaDoc( msg, ex );
375             }
376         }
377         TestRecorderFilter filter = TestRecorderFilter.instance();
378         boolean start = false;
379         try {
380             // may throw IOException
381
start = filter.getState().playbackStart( session );
382         }
383         catch ( Exception JavaDoc ex ) {
384             String JavaDoc msg = "ERROR: failed to start playback session( " + session + " ), exception( " +
385                     ex.getMessage() + " )";
386             request.setAttribute( Constants.MSG_ATTRIBUTE, msg );
387             log.error( msg, ex );
388             System.err.println( "\nPLAYBACK ERROR:\n" + msg );
389             if ( ex instanceof IOException JavaDoc ) {
390                 throw (IOException JavaDoc) ex;
391             }
392             else if ( ex instanceof RuntimeException JavaDoc ) {
393                 throw (RuntimeException JavaDoc) ex;
394             }
395             else {
396                 throw new RuntimeException JavaDoc( msg, ex );
397             }
398         }
399         if ( log.isInfoEnabled() ) {
400             log.info( "playback start( " + start + " )" );
401         }
402         if ( start ) {
403             String JavaDoc msg = "playback session( " +
404                     session.getSessionName() + " ) started.";
405             request.setAttribute( Constants.MSG_ATTRIBUTE, msg );
406             request.setAttribute( Constants.PLAYBACK_SESSION_ATTRIBUTE, session );
407             if ( log.isInfoEnabled() ) {
408                 log.info( msg );
409             }
410             // set response headers for the client.
411
response.setHeader( Constants.OUTCOME_HEADER,
412                     Constants.PASS );
413             response.setHeader( Constants.TEST_ID_HEADER,
414                     session.getStringUID() );
415             response.setHeader( Constants.RECORD_FILE_HEADER,
416                     session.getRecordFile().getAbsolutePath() );
417         }
418         else {
419             // fail
420
String JavaDoc msg = "ERROR: failed to start playback session( " +
421                     session.getSessionName() + " )";
422             request.setAttribute( Constants.MSG_ATTRIBUTE, msg );
423             request.setAttribute( Constants.PLAYBACK_SESSION_ATTRIBUTE, session );
424             log.error( msg );
425             // set response headers for the client.
426
response.setHeader( Constants.OUTCOME_HEADER,
427                     Constants.FAIL );
428             response.setHeader( Constants.MSG_ATTRIBUTE, msg );
429         }
430     }
431
432     public void doDiff( HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response )
433             throws IOException JavaDoc, ServletException JavaDoc, ConfigException {
434         // TODO use test name constant here, similar to the rest of the commands
435
String JavaDoc sessionName = request.getParameter( Constants.FILE );
436         TestDefinition test = getTest( sessionName );
437         if ( test == null ) {
438             String JavaDoc msg = "ERROR: unable to display diff output, no test was found for name( " + sessionName +
439                     " )";
440             forward( request, response, msg, Constants.ERROR_PAGE, true );
441             return;
442         }
443         try {
444             Writer JavaDoc wrtr = response.getWriter();
445             File JavaDoc diffFile = getDiffFile( test );
446             if ( !diffFile.exists() ) {
447                 String JavaDoc msg = "ERROR: unable to display diff output, no file was found for test( " +
448                         test.getName() + " ), file( " + diffFile.getAbsolutePath() + " )";
449                 forward( request, response, msg, Constants.ERROR_PAGE, true );
450                 return;
451             }
452             // output an html page
453
wrtr.write( "<html><head><title>Test Diffs of " );
454             wrtr.write( test.getName() );
455             wrtr.write( "</title></head>\n" );
456             wrtr.write( "<body>\n" );
457             wrtr.write( "<h4>Test Diffs: " );
458             wrtr.write( test.getName() );
459             wrtr.write( "</h4>\n" );
460             wrtr.write( "<pre>" );
461             wrtr.write( Reporter.genDiffDetails( diffFile ) );
462             wrtr.write( "</pre>" );
463             wrtr.write( "</body></html>" );
464         }
465         catch ( Exception JavaDoc e ) {
466             String JavaDoc msg = "ERROR: failed to display diff file, exception( " + e.getMessage() +
467                     " ), test( " + test.getName() + " )";
468             forward( request, response, msg, Constants.ERROR_PAGE, true );
469             return;
470         }
471     }
472
473     public void doLink( HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response )
474             throws IOException JavaDoc, ServletException JavaDoc, ConfigException {
475         String JavaDoc sessionName = request.getParameter( Constants.FILE );
476         TestDefinition test = getTest( sessionName );
477         WebappConfig config = TestRecorderFilter.instance().getWebapp();
478         try {
479             if ( test == null ) {
480                 String JavaDoc msg = "No test was found for name( " + sessionName + " )";
481                 forward( request, response, msg, Constants.ERROR_PAGE, true );
482                 return;
483             }
484
485             File JavaDoc recFile = getRecordSessionFile( test );
486             if ( !recFile.exists() ) {
487                 String JavaDoc msg = "No file was found for test( " + test.getName() + " ), file( " +
488                         recFile.getAbsolutePath() + " )";
489                 forward( request, response, msg, Constants.ERROR_PAGE, true );
490                 return;
491             }
492
493             RecordSessionBean bean = null;
494             try {
495                 bean = XMLHelper.getRecordSessionBean( recFile );
496             }
497             catch ( SessionXMLException e ) {
498                 String JavaDoc msg = "Failed processing file for record session( " + test.getName() + " ), file( " +
499                         recFile.getAbsolutePath() + " )";
500                 forward( request, response, msg, Constants.ERROR_PAGE, true );
501                 return;
502             }
503             RequestData rd = bean.getRequestData( 0 );
504             if ( rd == null ) {
505                 String JavaDoc msg = "Unable to find the first request in the test ( " + test.getName() + " ), file( " +
506                         recFile.getAbsolutePath() + " )";
507                 forward( request, response, msg, Constants.ERROR_PAGE, true );
508                 return;
509             }
510             String JavaDoc host = config.getServer().getHostname();
511             if ( host.equals( "localhost" ) )
512             {
513                 host = request.getServerName();
514             }
515             response.sendRedirect( rd.getUri( host, config.getServer().getPort() ) );
516             return;
517         }
518         catch ( Exception JavaDoc e ) {
519             String JavaDoc msg = "ERROR: failed to display test details, exception( " + e.getMessage() +
520                     " ), test( " + test.getName() + " )";
521             forward( request, response, msg, Constants.ERROR_PAGE, true, e );
522         }
523     }
524
525     public void doDetails( HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response )
526             throws IOException JavaDoc, ServletException JavaDoc, ConfigException {
527         // TODO use test name constant here, similar to the rest of the commands
528
String JavaDoc sessionName = request.getParameter( Constants.FILE );
529         TestDefinition test = getTest( sessionName );
530         try {
531             if ( test == null ) {
532                 String JavaDoc msg = "No test was found for name( " + sessionName + " )";
533                 forward( request, response, msg, Constants.ERROR_PAGE, true );
534                 return;
535             }
536             Writer JavaDoc wrtr = response.getWriter();
537             File JavaDoc recFile = getRecordSessionFile( test );
538             if ( !recFile.exists() ) {
539                 String JavaDoc msg = "No file was found for test( " + test.getName() + " ), file( " +
540                         recFile.getAbsolutePath() + " )";
541                 forward( request, response, msg, Constants.ERROR_PAGE, true );
542                 return;
543             }
544             RecordSessionBean bean = null;
545             try {
546                 bean = XMLHelper.getRecordSessionBean( recFile );
547             }
548             catch ( SessionXMLException e ) {
549                 String JavaDoc msg = "Failed processing file for record session( " + test.getName() + " ), file( " +
550                         recFile.getAbsolutePath() + " )";
551                 forward( request, response, msg, Constants.ERROR_PAGE, true );
552                 return;
553             }
554             // output an html page
555
wrtr.write( "<html><head><title>Test Details of " );
556             wrtr.write( test.getName() );
557             wrtr.write( "</title></head>\n" );
558             wrtr.write( "<body>\n" );
559             wrtr.write( "<h3>Test Details: " );
560             wrtr.write( test.getName() );
561             wrtr.write( "</h3>\n" );
562             wrtr.write( Reporter.genDetails( bean ) );
563             wrtr.write( "</body></html>" );
564         }
565         catch ( Exception JavaDoc e ) {
566             String JavaDoc msg = "ERROR: failed to display test details, exception( " + e.getMessage() +
567                     " ), test( " + test.getName() + " )";
568             forward( request, response, msg, Constants.ERROR_PAGE, true, e );
569         }
570     }
571
572     private void forward( HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response, String JavaDoc msg,
573             String JavaDoc page, boolean error ) throws ServletException JavaDoc, IOException JavaDoc {
574         forward( request, response, msg, page, error, null );
575     }
576
577     private void forward( HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response, String JavaDoc msg,
578             String JavaDoc page, boolean error, Exception JavaDoc ex ) throws ServletException JavaDoc, IOException JavaDoc {
579         if ( request.getAttribute( Constants.MSG_ATTRIBUTE ) == null ) {
580             request.setAttribute( Constants.MSG_ATTRIBUTE, msg );
581         }
582         if ( error ) {
583             if ( ex != null ) {
584                 log.error( msg, ex );
585             }
586             else {
587                 log.error( msg );
588             }
589         }
590         forward( request, response, page );
591     }
592
593     private void forward( HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response, String JavaDoc page )
594             throws ServletException JavaDoc, IOException JavaDoc {
595         RequestDispatcher JavaDoc dispatcher = request.getRequestDispatcher( page );
596         dispatcher.forward( request, response );
597     }
598
599     public void doAdmin( HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response )
600             throws ServletException JavaDoc,