001package bradleyross.j2ee.servlets;
002import java.io.StringWriter;
003import java.io.PrintWriter;
004import java.io.IOException;
005import java.sql.Date;
006import java.util.Vector;
007import java.util.Enumeration;
008import javax.servlet.ServletConfig;
009import javax.servlet.ServletContext;
010import javax.servlet.ServletInputStream;
011import javax.servlet.ServletOutputStream;
012import javax.servlet.http.HttpServletRequest;
013import javax.servlet.http.HttpServletResponse;
014import bradleyross.library.database.DatabaseProperties;
015import bradleyross.library.helpers.GenericPrinter;
016import bradleyross.library.helpers.StringHelpers;
017/**
018 * Used by code for servlets to pass information about a specific 
019 * HTTP request.
020 * 
021 * @see bradleyross.j2ee.servlets.UploadServlet.ThisPage
022 * 
023 * @author Bradley Ross
024 *
025 */
026public class ThisPage 
027{
028        /**
029         * Request object.
030         */
031        private HttpServletRequest request = null;
032        /**
033         * Response object.
034         */
035        private HttpServletResponse response = null;
036        /**
037         * Servlet configuration.
038         */
039        protected ServletConfig config = null;
040        /**
041         * Application (context) configuration.
042         */
043        protected ServletContext context = null;
044        /**
045         * Input stream from HTTP request.
046         * @see #getInputStream()
047         */
048        protected ServletInputStream input = null;
049        /**
050         * Used to pass information on database connection.
051         * @see #setDatabase(DatabaseProperties)
052         * @see #getDatabase()
053         */
054        protected DatabaseProperties data = null;
055        /**
056         * Starting date of date range.
057         * @see #setStartDate(Date)
058         * @see #getStartDate()
059         */
060        protected Date startDate = null;
061        /**
062         * Ending date of date range.
063         * @see #setEndDate(Date)
064         * @see #getEndDate()
065         */
066        protected Date endDate = null;
067        /**
068         * PrintWriter object for response.
069         * 
070         * <p>The value is only set when the method
071         *    {@link #getWriter()} is called.</p>
072         * @see #getWriter()
073         */
074        private PrintWriter writer = null;
075        /**
076         * Used internally to store information for page.
077         * 
078         */
079        private StringWriter stringWriter = null;
080        /**
081         * This is the printer object that will be used by servlet code.  
082         * <p>The
083         *    material is passed to a StringWriter that can be cleared and
084         *    rewritten before sending the material to the response object.</p>
085         * @see #getPrinter()
086         */
087        private GenericPrinter printer = null;
088        /**
089         * Object for sending information to HTTP response
090         * as a binary stream.
091         * 
092         * @see #getOutputStream()
093         */
094        private ServletOutputStream outputStream = null;
095        /**
096         * A list of warning or error messages that will appear
097         * on the web page generated by the servlet.
098         * 
099         * <p>The text of the messages are processed by
100         *    {@link StringHelpers#escapeHTML(String) } before
101         *    being sent to the web page.  The surrounding tags
102         *    will also have to be added.</p>
103         * <p>The error page is generated by calling
104         *    {@link #errorMessage()}.</p>
105         */
106        protected Vector<String> messageList = null;
107        /**
108         * Cancel processing if set to true.
109         * 
110         * <p>The flag is set when 
111         *    {@link #errorMessage()} or {@link #sendContents() }
112         *    is called.</p>
113         */
114        protected boolean terminateRequest = false;
115        /**
116         * Get the value of terminateRequest
117         * 
118         * @see #terminateRequest
119         * @return Value of flag
120         */
121        public boolean getTerminateRequest()
122        {
123                return terminateRequest;
124        }
125        /**
126         * Clear the contents of the StringWriter object.
127         */
128        public void clearWriter()
129        {
130                stringWriter = new StringWriter();
131                printer = new GenericPrinter(stringWriter);
132        }
133        /**
134         * Obtains the PrintWriter object for sending the page contents
135         * as a character string.
136         * <p>The only public means of calling this method is to use
137         *    {@link #sendContents()}.</p>
138         * @return PrintWriter object
139         * @throws IOException if io errors
140         */
141        protected PrintWriter getWriter() throws IOException
142        {
143                if (writer == null)
144                {
145                        writer = response.getWriter();
146                }
147                return writer;
148        }
149        /**
150         * Send the contents of the StringWriter object to
151         * the response object.
152         * 
153         * @throws IOException if database appear
154         */
155        public void sendContents() throws IOException
156        {
157                getWriter().write(stringWriter.toString());
158                terminateRequest = true;
159        }
160        /**
161         * Default constructor added to allow subclassing.
162         */
163        public ThisPage()
164        { ; }
165        /**
166         * 
167         * @param requestValue request object
168         * @param responseValue response object
169         * @param configValue servlet config object
170         * @throws IOException if io errors
171         */
172        public ThisPage(HttpServletRequest requestValue, HttpServletResponse responseValue, ServletConfig configValue)
173        throws IOException
174        {
175                request = requestValue;
176                response = responseValue;
177                config = configValue;
178                context = config.getServletContext();           
179                stringWriter = new StringWriter();
180                printer = new GenericPrinter(stringWriter);
181                messageList = new Vector<String>();     
182        }
183        /**
184         * Set the object containing database connection properties.
185         * @see #data
186         * @param databaseValue Object containing database properties
187         */
188        public void setDatabase (DatabaseProperties databaseValue)
189        {
190                data = databaseValue;
191        }
192        /**
193         * Get the object containing database connection properties.
194         * @see #data
195         * @return Object containing database connection properties
196         */
197        public DatabaseProperties getDatabase()
198        {
199                return data;
200        }
201        /**
202         * Gets request object.
203         * @return Request object
204         */
205        public HttpServletRequest getRequest()
206        {
207                return request;
208        }
209        /**
210         * Gets response object.
211         * @return Response object
212         */
213        public HttpServletResponse getResponse()
214        {
215                return response;
216        }
217        /**
218         * Get servlet configuration.
219         * <p>Parameters that are specified for a single servlet belong to
220         *    this object.</p>
221         * @return Servlet configuration object
222         */
223        public ServletConfig getConfig()
224        {
225                return config;
226        }
227        /**
228         * Get application context.
229         * <p>Parameters that belong to the entire application belong to
230         *    this object.</p>
231         *    @see #context
232         * @return Application context
233         */
234        public ServletContext getContext()
235        {
236                return context;
237        }
238        /**
239         * Return the input object obtaining information from the
240         * HTTP request.
241         * 
242         * @see #input
243         * @return ServletInputStream object
244         */
245        public ServletInputStream getInputStream()
246        {
247                return input;
248        }
249        /**
250         * Obtain the output stream for sending information to the
251         * browser as a stream of bytes.  
252         * 
253         * <p>If this method is called,
254         *    the {@link #sendContents()} and {@link #errorMessage()}
255         *    messages can not be used.</p>
256         *    
257         * @return ServletOutputStream object
258         * @throws IOException if io errors
259         */
260        public ServletOutputStream getOutputStream() throws IOException
261        {
262                if (outputStream == null)
263                {
264                        outputStream = response.getOutputStream();
265                }
266                return outputStream;
267        }
268        /**
269         * Get the generic printer object.
270         * @see #printer
271         * @return GenericPrinter object
272         */
273        public GenericPrinter getPrinter()
274        {
275                if (stringWriter == null)
276                {
277                        stringWriter = new StringWriter();
278                }
279                if (printer == null)
280                {
281                        printer = new GenericPrinter(stringWriter);
282                }
283                return printer;
284        }
285        /**
286         * Returns list of messages for the error page.
287         * @return List of messages
288         */
289        public Vector<String> getMessageList()
290        {
291                return messageList;
292        }
293        /**
294         * Add a message to the list of messages for the
295         * error page.
296         * 
297         * @see #messageList
298         * @param value Message to be added
299         */
300        public void addMessage(String value)
301        {
302                messageList.add(value);
303        }
304        /**
305         * Adds a description of an exception to the list
306         * of messages for the error page.
307         * 
308         * @see #messageList
309         * 
310         * @param e Exception to be described
311         */
312        public void addException(Exception e)
313        {
314                StringWriter str = new StringWriter();
315                PrintWriter p = new PrintWriter(str);
316                p.println(e.getClass().getName() + " " + e.getMessage());
317                e.printStackTrace(p);
318                messageList.add(str.toString());
319        }
320        /**
321         * Generates an error page based on the calls to the
322         * addMessage and addException methods.
323         * 
324         * @see #addMessage(String)
325         * @see #addException(Exception)
326         * @throws IOException if io errors
327         */
328        public void errorMessage() throws IOException
329        {
330                clearWriter();
331                GenericPrinter out = getPrinter();
332                out.println("<html><head><title>Error encountered</title></head>");
333                out.println("<body><h1>Error encountered</h1>");
334                messageList.trimToSize();
335                out.print("<p>Please print this page for aid in debugging.  This page contains " +
336                        " a list of actions taken by the servlet as well as the actual error message.</p>");
337                out.println("<h2>Start of messages</h2>");
338                int size = messageList.size();
339                if (size > 0)
340                {
341                        out.println("<ul>");
342                        for (int i = 0; i < size; i++)
343                        {
344                                out.println("<li>" + StringHelpers.escapeHTML(messageList.elementAt(i)) + "</li>");
345                        }
346                        out.println("</ul>");
347                }
348                else
349                {
350                        out.println("<p>There are no messages waiting</p>");
351                }
352                out.println("<h2>List of parameters</h2>");
353                Enumeration<?> nameList = request.getParameterNames();
354                while (nameList.hasMoreElements())
355                {
356                        String name = (String) nameList.nextElement();
357                        out.println("<p>" + 
358                                        StringHelpers.escapeHTML(name + " = " + request.getParameter(name)) +"</p>");
359                }
360                out.println("</body></html>");
361                sendContents();
362                terminateRequest = true;
363                return;
364        }
365        /**
366         * Set start date of date range.
367         * @see #startDate
368         * @param value Date to be used for start of date range
369         */
370        public void setStartDate(Date value)
371        {
372                startDate = value;
373        }
374        /**
375         * Return start date for date range.
376         * @see #startDate
377         * @return Start of date range
378         */
379        public Date getStartDate()
380        {
381                return startDate;
382        }
383        /**
384         * Set end date of date range.
385         * @see #endDate
386         * @param value Date to be used for end of date range
387         */
388        public void setEndDate(Date value)
389        {
390                endDate = value;
391        }
392        /**
393         * Return end date of date range.
394         * @see #endDate
395         * @return End date of date range
396         */
397        public Date getEndDate()
398        {
399                return endDate;
400        }
401        /**
402         * Controls amount of diagnostic output.
403         * 
404         * <p>More positive values mean more diagnostic listings.</p>
405         */
406        protected int debugLevel = 0;
407        /**
408         * Gets value of debugLevel.
409         * 
410         * @see #debugLevel
411         * @return Value of debugLevel
412         */
413        public int getDebugLevel()
414        {
415                return debugLevel;
416        }
417        /**
418         * Sets value of debugLevel
419         * @see #debugLevel
420         * @param value Value to be used
421         */
422        public void setDebugLevel(int value)
423        {
424                debugLevel = value;
425        }
426        /**
427         * Indicates that the document should be displayed in the browser if 
428         * possible.
429         * 
430         * @see #mode
431         */
432        public static final int NORMAL = 0;
433        /**
434         * Indicates that the document should be downloaded to the
435         * client machine.
436         * 
437         * @see #mode
438         */
439        public static final int DOWNLOAD = 1;
440        /**
441         * Indicates the mode of operation.  The two possible values
442         * are defined by the static integer values NORMAL and DOWNLOAD.
443         */
444        protected int mode = 0;
445        /**
446         * Contains the MIME code for the document to be displayed.
447         */
448        protected String mimeType = null;
449        /** 
450         * The byte array contains the contents of the document to be displayed.
451         */
452        protected byte[] contents = null;
453        /**
454         * File name to be associated with the download.
455         */
456        protected String fileName = null;
457        /**
458         * Set the MIME code for the document.
459         * 
460         * @param value MIME code
461         */
462        public void setMimeType (String value)
463        {
464                mimeType = value;
465        }
466        /**
467         * Get the MIME code for the document.
468         * 
469         * @return MIME code
470         */
471        public String getMimeType()
472        {
473                return mimeType;
474        }
475        /**
476         * Set the filename associated with the item to be downloaded.
477         * 
478         * @param value File name
479         */
480        public void setFileName (String value)
481        {
482                fileName = value;
483        }
484        /**
485         * Get the filename associated with the item to be downloaded.
486         * @return File name
487         */
488        public String getFileName()
489        {
490                return fileName;
491        }
492        /**
493         * Get the byte array to be used to display the downloaded item.
494         * 
495         * @return Contents of downloaded item
496         */
497        public byte[] getContents()
498        {
499                return contents;
500        }
501        /**
502         * Set the byte array to be used to display the downloaded item.
503         * 
504         * @param value Contents of downloaded item
505         */
506        public void setContents(byte value[])
507        {
508                contents = value;
509        }
510        /**
511         * Set the mode of operation
512         * @param value Mode of operation
513         * @throws IOException if io errors
514         */
515        public void setMode (int value) throws IOException
516        {
517                if (mode != NORMAL && mode != DOWNLOAD)
518                {
519                        addMessage("Illegal mode of operation");
520                        throw new IOException("Illegal mode of operation");
521                }
522                mode = value;
523        }
524        /**
525         * Get the mode of operation.
526         * 
527         * @return Mode of operation
528         */
529        public int getMode ()
530        {
531                return mode;
532        }
533        /**
534         * Address to be used for redirecting servlet.
535         */
536        protected String redirectAddress = null;
537        /**
538         * Set redirectAddress.
539         * @see #redirectAddress
540         * @param value Value to be used
541         */
542        public void setRedirectAddress(String value)
543        {
544                redirectAddress = value;
545        }
546        /**
547         * Get redirectAddress.
548         * @see #redirectAddress
549         * @return Value of redirectAddress
550         */
551        public String getRedirectAddress()
552        {
553                return redirectAddress;
554        }
555}