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
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        public void sendContents() throws IOException
154        {
155                getWriter().write(stringWriter.toString());
156                terminateRequest = true;
157        }
158        /**
159         * Default constructor added to allow subclassing.
160         */
161        public ThisPage()
162        { ; }
163        public ThisPage(HttpServletRequest requestValue, HttpServletResponse responseValue, ServletConfig configValue)
164        throws IOException
165        {
166                request = requestValue;
167                response = responseValue;
168                config = configValue;
169                context = config.getServletContext();           
170                stringWriter = new StringWriter();
171                printer = new GenericPrinter(stringWriter);
172                messageList = new Vector<String>();       
173        }
174        /**
175         * Set the object containing database connection properties.
176         * @see #data
177         * @param databaseValue Object containing database properties
178         */
179        public void setDatabase (DatabaseProperties databaseValue)
180        {
181                data = databaseValue;
182        }
183        /**
184         * Get the object containing database connection properties.
185         * @see #data
186         * @return Object containing database connection properties
187         */
188        public DatabaseProperties getDatabase()
189        {
190                return data;
191        }
192        /**
193         * Gets request object.
194         * @return Request object
195         */
196        public HttpServletRequest getRequest()
197        {
198                return request;
199        }
200        /**
201         * Gets response object.
202         * @return Response object
203         */
204        public HttpServletResponse getResponse()
205        {
206                return response;
207        }
208        /**
209         * Get servlet configuration.
210         * <p>Parameters that are specified for a single servlet belong to
211         *    this object.</p>
212         * @return Servlet configuration object
213         */
214        public ServletConfig getConfig()
215        {
216                return config;
217        }
218        /**
219         * Get application context.
220         * <p>Parameters that belong to the entire application belong to
221         *    this object.</p>
222         *    @see #context
223         * @return Application context
224         */
225        public ServletContext getContext()
226        {
227                return context;
228        }
229        /**
230         * Return the input object obtaining information from the
231         * HTTP request.
232         * 
233         * @see #input
234         * @return ServletInputStream object
235         */
236        public ServletInputStream getInputStream()
237        {
238                return input;
239        }
240        /**
241         * Obtain the output stream for sending information to the
242         * browser as a stream of bytes.  
243         * 
244         * <p>If this method is called,
245         *    the {@link #sendContents()} and {@link #errorMessage()}
246         *    messages can not be used.</p>
247         *    
248         * @return ServletOutputStream object
249         * @throws IOException
250         */
251        public ServletOutputStream getOutputStream() throws IOException
252        {
253                if (outputStream == null)
254                {
255                        outputStream = response.getOutputStream();
256                }
257                return outputStream;
258        }
259        /**
260         * Get the generic printer object.
261         * @see #printer
262         * @return GenericPrinter object
263         */
264        public GenericPrinter getPrinter()
265        {
266                if (stringWriter == null)
267                {
268                        stringWriter = new StringWriter();
269                }
270                if (printer == null)
271                {
272                        printer = new GenericPrinter(stringWriter);
273                }
274                return printer;
275        }
276        /**
277         * Returns list of messages for the error page.
278         * @return List of messages
279         */
280        public Vector<String> getMessageList()
281        {
282                return messageList;
283        }
284        /**
285         * Add a message to the list of messages for the
286         * error page.
287         * 
288         * @see #messageList
289         * @param value Message to be added
290         */
291        public void addMessage(String value)
292        {
293                messageList.add(value);
294        }
295        /**
296         * Adds a description of an exception to the list
297         * of messages for the error page.
298         * 
299         * @see #messageList
300         * 
301         * @param e Exception to be described
302         */
303        public void addException(Exception e)
304        {
305                StringWriter str = new StringWriter();
306                PrintWriter p = new PrintWriter(str);
307                p.println(e.getClass().getName() + " " + e.getMessage());
308                e.printStackTrace(p);
309                messageList.add(str.toString());
310        }
311        /**
312         * Generates an error page based on the calls to the
313         * addMessage and addException methods.
314         * 
315         * @see #addMessage(String)
316         * @see #addException(Exception)
317         * @throws IOException
318         */
319        public void errorMessage() throws IOException
320        {
321                clearWriter();
322                GenericPrinter out = getPrinter();
323                out.println("<html><head><title>Error encountered</title></head>");
324                out.println("<body><h1>Error encountered</h1>");
325                messageList.trimToSize();
326                out.print("<p>Please print this page for aid in debugging.  This page contains " +
327                        " a list of actions taken by the servlet as well as the actual error message.</p>");
328                out.println("<h2>Start of messages</h2>");
329                int size = messageList.size();
330                if (size > 0)
331                {
332                        out.println("<ul>");
333                        for (int i = 0; i < size; i++)
334                        {
335                                out.println("<li>" + StringHelpers.escapeHTML(messageList.elementAt(i)) + "</li>");
336                        }
337                        out.println("</ul>");
338                }
339                else
340                {
341                        out.println("<p>There are no messages waiting</p>");
342                }
343                out.println("<h2>List of parameters</h2>");
344                Enumeration<?> nameList = request.getParameterNames();
345                while (nameList.hasMoreElements())
346                {
347                        String name = (String) nameList.nextElement();
348                        out.println("<p>" + 
349                                        StringHelpers.escapeHTML(name + " = " + request.getParameter(name)) +"</p>");
350                }
351                out.println("</body></html>");
352                sendContents();
353                terminateRequest = true;
354                return;
355        }
356        /**
357         * Set start date of date range.
358         * @see #startDate
359         * @param value Date to be used for start of date range
360         */
361        public void setStartDate(Date value)
362        {
363                startDate = value;
364        }
365        /**
366         * Return start date for date range.
367         * @see #startDate
368         * @return Start of date range
369         */
370        public Date getStartDate()
371        {
372                return startDate;
373        }
374        /**
375         * Set end date of date range.
376         * @see #endDate
377         * @param value Date to be used for end of date range
378         */
379        public void setEndDate(Date value)
380        {
381                endDate = value;
382        }
383        /**
384         * Return end date of date range.
385         * @see #endDate
386         * @return End date of date range
387         */
388        public Date getEndDate()
389        {
390                return endDate;
391        }
392        /**
393         * Controls amount of diagnostic output.
394         * 
395         * <p>More positive values mean more diagnostic listings.</p>
396         */
397        protected int debugLevel = 0;
398        /**
399         * Gets value of debugLevel.
400         * 
401         * @see #debugLevel
402         * @return Value of debugLevel
403         */
404        public int getDebugLevel()
405        {
406                return debugLevel;
407        }
408        /**
409         * Sets value of debugLevel
410         * @see #debugLevel
411         * @param value Value to be used
412         */
413        public void setDebugLevel(int value)
414        {
415                debugLevel = value;
416        }
417        /**
418         * Indicates that the document should be displayed in the browser if 
419         * possible.
420         * 
421         * @see #mode
422         */
423        public static final int NORMAL = 0;
424        /**
425         * Indicates that the document should be downloaded to the
426         * client machine.
427         * 
428         * @see #mode
429         */
430        public static final int DOWNLOAD = 1;
431        /**
432         * Indicates the mode of operation.  The two possible values
433         * are defined by the static integer values NORMAL and DOWNLOAD.
434         */
435        protected int mode = 0;
436        /**
437         * Contains the MIME code for the document to be displayed.
438         */
439        protected String mimeType = null;
440        /** 
441         * The byte array contains the contents of the document to be displayed.
442         */
443        protected byte[] contents = null;
444        /**
445         * File name to be associated with the download.
446         */
447        protected String fileName = null;
448        /**
449         * Set the MIME code for the document.
450         * 
451         * @param value MIME code
452         */
453        public void setMimeType (String value)
454        {
455                mimeType = value;
456        }
457        /**
458         * Get the MIME code for the document.
459         * 
460         * @return MIME code
461         */
462        public String getMimeType()
463        {
464                return mimeType;
465        }
466        /**
467         * Set the filename associated with the item to be downloaded.
468         * 
469         * @param value File name
470         */
471        public void setFileName (String value)
472        {
473                fileName = value;
474        }
475        /**
476         * Get the filename associated with the item to be downloaded.
477         * @return File name
478         */
479        public String getFileName()
480        {
481                return fileName;
482        }
483        /**
484         * Get the byte array to be used to display the downloaded item.
485         * 
486         * @return Contents of downloaded item
487         */
488        public byte[] getContents()
489        {
490                return contents;
491        }
492        /**
493         * Set the byte array to be used to display the downloaded item.
494         * 
495         * @param value Contents of downloaded item
496         */
497        public void setContents(byte value[])
498        {
499                contents = value;
500        }
501        /**
502         * Set the mode of operation
503         * @param value Mode of operation
504         * @throws IOException
505         */
506        public void setMode (int value) throws IOException
507        {
508                if (mode != NORMAL && mode != DOWNLOAD)
509                {
510                        addMessage("Illegal mode of operation");
511                        throw new IOException("Illegal mode of operation");
512                }
513                mode = value;
514        }
515        /**
516         * Get the mode of operation.
517         * 
518         * @return Mode of operation
519         */
520        public int getMode ()
521        {
522                return mode;
523        }
524        /**
525         * Address to be used for redirecting servlet.
526         */
527        protected String redirectAddress = null;
528        /**
529         * Set redirectAddress.
530         * @see #redirectAddress
531         * @param value Value to be used
532         */
533        public void setRedirectAddress(String value)
534        {
535                redirectAddress = value;
536        }
537        /**
538         * Get redirectAddress.
539         * @see #redirectAddress
540         * @return Value of redirectAddress
541         */
542        public String getRedirectAddress()
543        {
544                return redirectAddress;
545        }
546}