1 package org.apache.turbine.services.rundata;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 import java.io.IOException;
20 import java.io.PrintWriter;
21
22 import java.util.ArrayList;
23 import java.util.HashMap;
24 import java.util.List;
25 import java.util.Locale;
26 import java.util.Map;
27
28 import javax.servlet.ServletConfig;
29 import javax.servlet.ServletContext;
30 import javax.servlet.http.HttpServletRequest;
31 import javax.servlet.http.HttpServletResponse;
32 import javax.servlet.http.HttpSession;
33
34 import org.apache.commons.lang.StringUtils;
35
36 import org.apache.commons.logging.Log;
37 import org.apache.commons.logging.LogFactory;
38
39 import org.apache.ecs.Document;
40 import org.apache.ecs.Element;
41 import org.apache.ecs.StringElement;
42
43 import org.apache.turbine.Turbine;
44 import org.apache.turbine.TurbineConstants;
45 import org.apache.turbine.om.security.User;
46 import org.apache.turbine.services.mimetype.TurbineMimeTypes;
47 import org.apache.turbine.services.template.TurbineTemplate;
48 import org.apache.turbine.util.FormMessages;
49 import org.apache.turbine.util.ServerData;
50 import org.apache.turbine.util.SystemError;
51 import org.apache.turbine.util.parser.CookieParser;
52 import org.apache.turbine.util.parser.ParameterParser;
53 import org.apache.turbine.util.pool.Recyclable;
54 import org.apache.turbine.util.pool.RecyclableSupport;
55 import org.apache.turbine.util.security.AccessControlList;
56 import org.apache.turbine.util.template.TemplateInfo;
57
58 /***
59 * DefaultTurbineRunData is the default implementation of the
60 * TurbineRunData interface, which is distributed by the Turbine
61 * RunData service, if another implementation is not defined in
62 * the default or specified RunData configuration.
63 * TurbineRunData is an extension to RunData, which
64 * is an interface to run-rime information that is passed
65 * within Turbine. This provides the threading mechanism for the
66 * entire system because multiple requests can potentially come in
67 * at the same time. Thus, there is only one RunData implementation
68 * for each request that is being serviced.
69 *
70 * <p>DefaultTurbineRunData implements the Recyclable interface making
71 * it possible to pool its instances for recycling.
72 *
73 * @author <a href="mailto:ilkka.priha@simsoft.fi">Ilkka Priha</a>
74 * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
75 * @author <a href="mailto:bhoeneis@ee.ethz.ch">Bernie Hoeneisen</a>
76 * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
77 * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
78 * @author <a href="mailto:quintonm@bellsouth.net">Quinton McCombs</a>
79 * @version $Id: DefaultTurbineRunData.java,v 1.16.2.2 2004/05/20 03:06:51 seade Exp $
80 */
81 public class DefaultTurbineRunData
82 extends RecyclableSupport
83 implements TurbineRunData, Recyclable
84 {
85 /*** The default locale. */
86 private static Locale defaultLocale = null;
87
88 /*** The default charset. */
89 private static String defaultCharSet = null;
90
91 /*** A reference to the GET/POST data parser. */
92 private ParameterParser parameters;
93
94 /*** A reference to a cookie parser. */
95 public CookieParser cookies;
96
97 /*** The servlet request interface. */
98 private HttpServletRequest req;
99
100 /*** The servlet response interface. */
101 private HttpServletResponse res;
102
103 /*** The servlet configuration. */
104 private ServletConfig config;
105
106 /***
107 * The servlet context information.
108 * Note that this is from the "Turbine" Servlet context.
109 */
110 private ServletContext servletContext;
111
112 /*** The access control list. */
113 private AccessControlList acl;
114
115 /*** Determines if there is information in the document or not. */
116 private boolean pageSet;
117
118 /*** This creates an ECS Document. */
119 private Document page;
120
121 /*** Cached action name to execute for this request. */
122 private String action;
123
124 /*** This is the layout that the page will use to render the screen. */
125 private String layout;
126
127 /*** Cached screen name to execute for this request. */
128 private String screen;
129
130 /*** The character encoding of template files. */
131 private String templateEncoding;
132
133 /*** Information used by a Template system (such as Velocity/JSP). */
134 private TemplateInfo templateInfo;
135
136 /*** This is where output messages from actions should go. */
137 private StringElement message;
138
139 /***
140 * This is a dedicated message class where output messages from
141 * actions should go.
142 */
143 private FormMessages messages;
144
145 /*** The user object. */
146 private User user;
147
148 /*** This is what will build the <title></title> of the document. */
149 private String title;
150
151 /*** Determines if there is information in the outputstream or not. */
152 private boolean outSet;
153
154 /***
155 * Cache the output stream because it can be used in many
156 * different places.
157 */
158 private PrintWriter out;
159
160 /*** The locale. */
161 private Locale locale;
162
163 /*** The HTTP charset. */
164 private String charSet;
165
166 /*** The HTTP content type to return. */
167 private String contentType = "text/html";
168
169 /*** If this is set, also set the status code to 302. */
170 private String redirectURI;
171
172 /*** The HTTP status code to return. */
173 private int statusCode = HttpServletResponse.SC_OK;
174
175 /*** This is a List to hold critical system errors. */
176 private List errors = new ArrayList();
177
178 /*** JNDI Contexts. */
179 private Map jndiContexts;
180
181 /*** Holds ServerData (basic properties) about this RunData object. */
182 private ServerData serverData;
183
184 /*** @see #getRemoteAddr() */
185 private String remoteAddr;
186
187 /*** @see #getRemoteHost() */
188 private String remoteHost;
189
190 /*** @see #getUserAgent() */
191 private String userAgent;
192
193 /*** A holder for stack trace. */
194 private String stackTrace;
195
196 /*** A holder ofr stack trace exception. */
197 private Throwable stackTraceException;
198
199 /***
200 * Put things here and they will be shown on the default Error
201 * screen. This is great for debugging variable values when an
202 * exception is thrown.
203 */
204 private Map debugVariables = new HashMap();
205
206 /*** Logging */
207 private static Log log = LogFactory.getLog(DefaultTurbineRunData.class);
208
209 /***
210 * Attempts to get the User object from the session. If it does
211 * not exist, it returns null.
212 *
213 * @param session An HttpSession.
214 * @return A User.
215 */
216 public static User getUserFromSession(HttpSession session)
217 {
218 try
219 {
220 return (User) session.getAttribute(User.SESSION_KEY);
221 }
222 catch (ClassCastException e)
223 {
224 return null;
225 }
226 }
227
228 /***
229 * Allows one to invalidate the user in a session.
230 *
231 * @param session An HttpSession.
232 * @return True if user was invalidated.
233 */
234 public static boolean removeUserFromSession(HttpSession session)
235 {
236 try
237 {
238 session.removeAttribute(User.SESSION_KEY);
239 }
240 catch (Exception e)
241 {
242 return false;
243 }
244 return true;
245 }
246
247 /***
248 * Gets the default locale defined by properties named
249 * "locale.default.lang" and "locale.default.country".
250 *
251 * This changed from earlier Turbine versions that you can
252 * rely on getDefaultLocale() to never return null.
253 *
254 * @return A Locale object.
255 */
256 protected static Locale getDefaultLocale()
257 {
258 if (defaultLocale == null)
259 {
260
261 String lang = Turbine.getConfiguration()
262 .getString(TurbineConstants.LOCALE_DEFAULT_LANGUAGE_KEY,
263 TurbineConstants.LOCALE_DEFAULT_LANGUAGE_DEFAULT);
264
265 String country = Turbine.getConfiguration()
266 .getString(TurbineConstants.LOCALE_DEFAULT_COUNTRY_KEY,
267 TurbineConstants.LOCALE_DEFAULT_COUNTRY_DEFAULT);
268
269
270
271 defaultLocale = new Locale(lang, country);
272 }
273 return defaultLocale;
274 }
275
276 /***
277 * Gets the default charset defined by a property named
278 * "locale.default.charset" or by the specified locale.
279 * If the specified locale is null, the default locale is applied.
280 *
281 * @return the name of the default charset or null.
282 */
283 protected String getDefaultCharSet()
284 {
285 log.debug("getDefaultCharSet()");
286
287 if (defaultCharSet == null)
288 {
289
290 defaultCharSet = Turbine.getConfiguration()
291 .getString(TurbineConstants.LOCALE_DEFAULT_CHARSET_KEY,
292 TurbineConstants.LOCALE_DEFAULT_CHARSET_DEFAULT);
293 log.debug("defaultCharSet = " + defaultCharSet + " (From Properties)");
294 }
295
296 String charset = defaultCharSet;
297
298 if (StringUtils.isEmpty(charset))
299 {
300 log.debug("charset is empty!");
301
302 Locale locale = this.locale;
303 if (locale == null)
304 {
305 locale = getDefaultLocale();
306 log.debug("Locale was null, is now " + locale + " (from getDefaultLocale())");
307 }
308
309 log.debug("Locale is " + locale);
310
311 if (!locale.equals(Locale.US))
312 {
313 log.debug("We have US Locale!");
314 charset = TurbineMimeTypes.getCharSet(locale);
315
316 log.debug("Charset now " + charset);
317 }
318 }
319
320 log.debug("Returning default Charset of " + charset);
321 return charset;
322 }
323
324 /***
325 * Constructs a run data object.
326 */
327 public DefaultTurbineRunData()
328 {
329 super();
330 }
331
332 /***
333 * Recycles a run data object.
334 */
335 public void recycle()
336 {
337 super.recycle();
338 }
339
340 /***
341 * Disposes a run data object.
342 */
343 public void dispose()
344 {
345 parameters = null;
346 cookies = null;
347 req = null;
348 res = null;
349 config = null;
350 servletContext = null;
351 acl = null;
352 pageSet = false;
353 page = null;
354 action = null;
355 layout = null;
356 screen = null;
357 templateEncoding = null;
358 templateInfo = null;
359 message = null;
360 messages = null;
361 user = null;
362 title = null;
363 outSet = false;
364 out = null;
365 locale = null;
366 charSet = null;
367 contentType = "text/html";
368 redirectURI = null;
369 statusCode = HttpServletResponse.SC_OK;
370 errors.clear();
371 jndiContexts = null;
372 serverData = null;
373 remoteAddr = null;
374 remoteHost = null;
375 userAgent = null;
376 stackTrace = null;
377 stackTraceException = null;
378 debugVariables.clear();
379
380 super.dispose();
381 }
382
383
384
385
386
387 /***
388 * Gets the parameters.
389 *
390 * @return a parameter parser.
391 */
392 public ParameterParser getParameters()
393 {
394
395 if ((this.parameters != null) &&
396 (this.parameters.getRequest() != this.req))
397 {
398 this.parameters.setRequest(this.req);
399 }
400 return this.parameters;
401 }
402
403 /***
404 * Gets the cookies.
405 *
406 * @return a cookie parser.
407 */
408 public CookieParser getCookies()
409 {
410
411 if ((this.cookies != null) &&
412 (this.cookies.getRequest() != getRequest()))
413 {
414
415
416
417
418
419
420
421 this.cookies.setRunData(this);
422 }
423 return this.cookies;
424 }
425
426 /***
427 * Gets the servlet request.
428 *
429 * @return the request.
430 */
431 public HttpServletRequest getRequest()
432 {
433 return this.req;
434 }
435
436 /***
437 * Gets the servlet response.
438 *
439 * @return the response.
440 */
441 public HttpServletResponse getResponse()
442 {
443 return this.res;
444 }
445
446 /***
447 * Gets the servlet session information.
448 *
449 * @return the session.
450 */
451 public HttpSession getSession()
452 {
453 return getRequest().getSession();
454 }
455
456 /***
457 * Gets the servlet configuration used during servlet init.
458 *
459 * @return the configuration.
460 */
461 public ServletConfig getServletConfig()
462 {
463 return this.config;
464 }
465
466 /***
467 * Gets the servlet context used during servlet init.
468 *
469 * @return the context.
470 */
471 public ServletContext getServletContext()
472 {
473 return this.servletContext;
474 }
475
476 /***
477 * Gets the access control list.
478 *
479 * @return the access control list.
480 */
481 public AccessControlList getACL()
482 {
483 return acl;
484 }
485
486 /***
487 * Sets the access control list.
488 *
489 * @param acl an access control list.
490 */
491 public void setACL(AccessControlList acl)
492 {
493 this.acl = acl;
494 }
495
496 /***
497 * Checks to see if the page is set.
498 *
499 * @return true if the page is set.
500 * @deprecated no replacement planned, ECS is no longer a requirement
501 */
502 public boolean isPageSet()
503 {
504 return pageSet;
505 }
506
507 /***
508 * Gets the page.
509 *
510 * @return a document.
511 * @deprecated no replacement planned, ECS is no longer a requirement
512 */
513 public Document getPage()
514 {
515 pageSet = true;
516 if (this.page == null)
517 this.page = new Document();
518 return this.page;
519 }
520
521 /***
522 * Whether or not an action has been defined.
523 *
524 * @return true if an action has been defined.
525 */
526 public boolean hasAction()
527 {
528 return (StringUtils.isNotEmpty(this.action)
529 && !this.action.equalsIgnoreCase("null"));
530 }
531
532 /***
533 * Gets the action. It returns an empty string if null so
534 * that it is easy to do conditionals on it based on the
535 * equalsIgnoreCase() method.
536 *
537 * @return a string, "" if null.
538 */
539 public String getAction()
540 {
541 return (hasAction() ? this.action : "");
542 }
543
544 /***
545 * Sets the action for the request.
546 *
547 * @param action a atring.
548 */
549 public void setAction(String action)
550 {
551 this.action = action;
552 }
553
554 /***
555 * If the Layout has not been defined by the screen then set the
556 * layout to be "DefaultLayout". The screen object can also
557 * override this method to provide intelligent determination of
558 * the Layout to execute. You can also define that logic here as
559 * well if you want it to apply on a global scale. For example,
560 * if you wanted to allow someone to define layout "preferences"
561 * where they could dynamicially change the layout for the entire
562 * site.
563 *
564 * @return a string.
565 */
566
567 public String getLayout()
568 {
569 if (this.layout == null)
570 {
571
572
573
574
575
576 layout = TurbineTemplate.getDefaultLayoutName(this);
577
578 if (layout == null)
579 {
580 layout = "DefaultLayout";
581 }
582 }
583
584 return this.layout;
585 }
586
587 /***
588 * Set the layout for the request.
589 *
590 * @param layout a string.
591 */
592 public void setLayout(String layout)
593 {
594 this.layout = layout;
595 }
596
597 /***
598 * Convenience method for a template info that
599 * returns the layout template being used.
600 *
601 * @return a string.
602 */
603 public String getLayoutTemplate()
604 {
605 return getTemplateInfo().getLayoutTemplate();
606 }
607
608 /***
609 * Modifies the layout template for the screen. This convenience
610 * method allows for a layout to be modified from within a
611 * template. For example;
612 *
613 * $data.setLayoutTemplate("NewLayout.vm")
614 *
615 * @param layout a layout template.
616 */
617 public void setLayoutTemplate(String layout)
618 {
619 getTemplateInfo().setLayoutTemplate(layout);
620 }
621
622 /***
623 * Whether or not a screen has been defined.
624 *
625 * @return true if a screen has been defined.
626 */
627 public boolean hasScreen()
628 {
629 return StringUtils.isNotEmpty(this.screen);
630 }
631
632 /***
633 * Gets the screen to execute.
634 *
635 * @return a string.
636 */
637 public String getScreen()
638 {
639 return (hasScreen() ? this.screen : "");
640 }
641
642 /***
643 * Sets the screen for the request.
644 *
645 * @param screen a string.
646 */
647 public void setScreen(String screen)
648 {
649 this.screen = screen;
650 }
651
652 /***
653 * Convenience method for a template info that
654 * returns the name of the template being used.
655 *
656 * @return a string.
657 */
658 public String getScreenTemplate()
659 {
660 return getTemplateInfo().getScreenTemplate();
661 }
662
663 /***
664 * Sets the screen template for the request. For
665 * example;
666 *
667 * $data.setScreenTemplate("NewScreen.vm")
668 *
669 * @param screen a screen template.
670 */
671 public void setScreenTemplate(String screen)
672 {
673 getTemplateInfo().setScreenTemplate(screen);
674 }
675
676 /***
677 * Gets the character encoding to use for reading template files.
678 *
679 * @return the template encoding or null if not specified.
680 */
681 public String getTemplateEncoding()
682 {
683 return templateEncoding;
684 }
685
686 /***
687 * Sets the character encoding to use for reading template files.
688 *
689 * @param encoding the template encoding.
690 */
691 public void setTemplateEncoding(String encoding)
692 {
693 templateEncoding = encoding;
694 }
695
696 /***
697 * Gets the template info. Creates a new one if needed.
698 *
699 * @return a template info.
700 */
701 public TemplateInfo getTemplateInfo()
702 {
703 if (templateInfo == null)
704 {
705 templateInfo = new TemplateInfo(this);
706 }
707 return templateInfo;
708 }
709
710 /***
711 * Whether or not a message has been defined.
712 *
713 * @return true if a message has been defined.
714 */
715 public boolean hasMessage()
716 {
717 return (this.message != null)
718 && StringUtils.isNotEmpty(this.message.toString());
719 }
720
721 /***
722 * Gets the results of an action or another message
723 * to be displayed as a string.
724 *
725 * @return a string.
726 */
727 public String getMessage()
728 {
729 return (this.message == null ? null : this.message.toString());
730 }
731
732 /***
733 * Sets the message for the request as a string.
734 *
735 * @param msg a string.
736 */
737 public void setMessage(String msg)
738 {
739 this.message = new StringElement(msg);
740 }
741
742 /***
743 * Adds the string to message. If message has prior messages from
744 * other actions or screens, this method can be used to chain them.
745 *
746 * @param msg a string.
747 */
748 public void addMessage(String msg)
749 {
750 addMessage(new StringElement(msg));
751 }
752
753 /***
754 * Gets the results of an action or another message
755 * to be displayed as an ECS string element.
756 *
757 * @return a string element.
758 */
759 public StringElement getMessageAsHTML()
760 {
761 return this.message;
762 }
763
764 /***
765 * Sets the message for the request as an ECS element.
766 *
767 * @param msg an element.
768 */
769 public void setMessage(Element msg)
770 {
771 this.message = new StringElement(msg);
772 }
773
774 /***
775 * Adds the ECS element to message. If message has prior messages from
776 * other actions or screens, this method can be used to chain them.
777 *
778 * @param msg an element.
779 */
780 public void addMessage(Element msg)
781 {
782 if (msg != null)
783 {
784 if (message != null)
785 {
786 message.addElement(msg);
787 }
788 else
789 {
790 message = new StringElement(msg);
791 }
792 }
793 }
794
795 /***
796 * Unsets the message for the request.
797 */
798 public void unsetMessage()
799 {
800 this.message = null;
801 }
802
803 /***
804 * Gets a FormMessages object where all the messages to the
805 * user should be stored.
806 *
807 * @return a FormMessages.
808 */
809 public FormMessages getMessages()
810 {
811 if (this.messages == null)
812 {
813 this.messages = new FormMessages();
814 }
815 return this.messages;
816 }
817
818 /***
819 * Sets the FormMessages object for the request.
820 *
821 * @param msgs A FormMessages.
822 */
823 public void setMessages(FormMessages msgs)
824 {
825 this.messages = msgs;
826 }
827
828 /***
829 * Gets the title of the page.
830 *
831 * @return a string.
832 */
833 public String getTitle()
834 {
835 return (this.title == null ? "" : this.title);
836 }
837
838 /***
839 * Sets the title of the page.
840 *
841 * @param title a string.
842 */
843 public void setTitle(String title)
844 {
845 this.title = title;
846 }
847
848 /***
849 * Checks if a user exists in this session.
850 *
851 * @return true if a user exists in this session.
852 */
853 public boolean userExists()
854 {
855 user = getUserFromSession();
856 return (user != null);
857 }
858
859 /***
860 * Gets the user.
861 *
862 * @return a user.
863 */
864 public User getUser()
865 {
866 return this.user;
867 }
868
869 /***
870 * Sets the user.
871 *
872 * @param user a user.
873 */
874 public void setUser(User user)
875 {
876 log.debug("user set: " + user.getName());
877 this.user = user;
878 }
879
880 /***
881 * Attempts to get the user from the session. If it does
882 * not exist, it returns null.
883 *
884 * @return a user.
885 */
886 public User getUserFromSession()
887 {
888 return getUserFromSession(getSession());
889 }
890
891 /***
892 * Allows one to invalidate the user in the default session.
893 *
894 * @return true if user was invalidated.
895 */
896 public boolean removeUserFromSession()
897 {
898 return removeUserFromSession(getSession());
899 }
900
901 /***
902 * Checks to see if out is set.
903 *
904 * @return true if out is set.
905 * @deprecated no replacement planned, response writer will not be cached
906 */
907 public boolean isOutSet()
908 {
909 return outSet;
910 }
911
912 /***
913 * Gets the print writer. First time calling this
914 * will set the print writer via the response.
915 *
916 * @return a print writer.
917 * @throws IOException
918 * @deprecated no replacement planned, response writer will not be cached
919 */
920 public PrintWriter getOut()
921 throws IOException
922 {
923
924 if (this.out == null)
925 {
926 setOut(res.getWriter());
927 }
928 pageSet = false;
929 outSet = true;
930 return this.out;
931 }
932
933 /***
934 * Declares that output will be direct to the response stream,
935 * even though getOut() may never be called. Useful for response
936 * mechanisms that may call res.getWriter() themselves
937 * (such as JSP.)
938 */
939 public void declareDirectResponse()
940 {
941 outSet = true;
942 pageSet = false;
943 }
944
945 /***
946 * Gets the locale. If it has not already been defined with
947 * setLocale(), then properties named "locale.default.lang"
948 * and "locale.default.country" are checked from the Resource
949 * Service and the corresponding locale is returned. If these
950 * properties are undefined, JVM's default locale is returned.
951 *
952 * @return the locale.
953 */
954 public Locale getLocale()
955 {
956 Locale locale = this.locale;
957 if (locale == null)
958 {
959 locale = getDefaultLocale();
960 }
961 return locale;
962 }
963
964 /***
965 * Sets the locale.
966 *
967 * @param locale the new locale.
968 */
969 public void setLocale(Locale locale)
970 {
971 this.locale = locale;
972 }
973
974 /***
975 * Gets the charset. If it has not already been defined with
976 * setCharSet(), then a property named "locale.default.charset"
977 * is checked from the Resource Service and returned. If this
978 * property is undefined, the default charset of the locale
979 * is returned. If the locale is undefined, null is returned.
980 *
981 * @return the name of the charset or null.
982 */
983 public String getCharSet()
984 {
985 log.debug("getCharSet()");
986
987 if (StringUtils.isEmpty(charSet))
988 {
989 log.debug("Charset was null!");
990 return getDefaultCharSet();
991 }
992 else
993 {
994 return charSet;
995 }
996 }
997
998 /***
999 * Sets the charset.
1000 *
1001 * @param charSet the name of the new charset.
1002 */
1003 public void setCharSet(String charSet)
1004 {
1005 log.debug("setCharSet(" + charSet + ")");
1006 this.charSet = charSet;
1007 }
1008
1009 /***
1010 * Gets the HTTP content type to return. If a charset
1011 * has been specified, it is included in the content type.
1012 * If the charset has not been specified and the main type
1013 * of the content type is "text", the default charset is
1014 * included. If the default charset is undefined, but the
1015 * default locale is defined and it is not the US locale,
1016 * a locale specific charset is included.
1017 *
1018 * @return the content type or an empty string.
1019 */
1020 public String getContentType()
1021 {
1022 if (StringUtils.isNotEmpty(contentType))
1023 {
1024 if (StringUtils.isEmpty(charSet))
1025 {
1026 if (contentType.startsWith("text/"))
1027 {
1028 return contentType + "; charset=" + getDefaultCharSet();
1029 }
1030 }
1031 else
1032 {
1033 return contentType + "; charset=" + charSet;
1034 }
1035 }
1036
1037 return "";
1038 }
1039
1040 /***
1041 * Sets the HTTP content type to return.
1042 *
1043 * @param contentType a string.
1044 */
1045 public void setContentType(String contentType)
1046 {
1047 this.contentType = contentType;
1048 }
1049
1050 /***
1051 * Gets the redirect URI. If this is set, also make sure to set
1052 * the status code to 302.
1053 *
1054 * @return a string, "" if null.
1055 */
1056 public String getRedirectURI()
1057 {
1058 return (this.redirectURI == null ? "" : redirectURI);
1059 }
1060
1061 /***
1062 * Sets the redirect uri. If this is set, also make sure to set
1063 * the status code to 302.
1064 *
1065 * @param ruri a string.
1066 */
1067 public void setRedirectURI(String ruri)
1068 {
1069 this.redirectURI = ruri;
1070 }
1071
1072 /***
1073 * Gets the HTTP status code to return.
1074 *
1075 * @return the status.
1076 */
1077 public int getStatusCode()
1078 {
1079 return statusCode;
1080 }
1081
1082 /***
1083 * Sets the HTTP status code to return.
1084 *
1085 * @param statusCode the status.
1086 */
1087 public void setStatusCode(int statusCode)
1088 {
1089 this.statusCode = statusCode;
1090 }
1091
1092 /***
1093 * Gets an array of system errors.
1094 *
1095 * @return a SystemError[].
1096 */
1097 public SystemError[] getSystemErrors()
1098 {
1099 SystemError[] result = new SystemError[errors.size()];
1100 errors.toArray(result);
1101 return result;
1102 }
1103
1104 /***
1105 * Adds a critical system error.
1106 *
1107 * @param err a system error.
1108 */
1109 public void setSystemError(SystemError err)
1110 {
1111 this.errors.add(err);
1112 }
1113
1114 /***
1115 * Gets JNDI Contexts.
1116 *
1117 * @return a hashtable.
1118 */
1119 public Map getJNDIContexts()
1120 {
1121 if (jndiContexts == null)
1122 jndiContexts = new HashMap();
1123 return jndiContexts;
1124 }
1125
1126 /***
1127 * Sets JNDI Contexts.
1128 *
1129 * @param contexts a hashtable.
1130 */
1131 public void setJNDIContexts(Map contexts)
1132 {
1133 this.jndiContexts = contexts;
1134 }
1135
1136 /***
1137 * Gets the cached server scheme.
1138 *
1139 * @return a string.
1140 */
1141 public String getServerScheme()
1142 {
1143 return getServerData().getServerScheme();
1144 }
1145
1146 /***
1147 * Gets the cached server name.
1148 *
1149 * @return a string.
1150 */
1151 public String getServerName()
1152 {
1153 return getServerData().getServerName();
1154 }
1155
1156 /***
1157 * Gets the cached server port.
1158 *
1159 * @return an int.
1160 */
1161 public int getServerPort()
1162 {
1163 return getServerData().getServerPort();
1164 }
1165
1166 /***
1167 * Gets the cached context path.
1168 *
1169 * @return a string.
1170 */
1171 public String getContextPath()
1172 {
1173 return getServerData().getContextPath();
1174 }
1175
1176 /***
1177 * Gets the cached script name.
1178 *
1179 * @return a string.
1180 */
1181 public String getScriptName()
1182 {
1183 return getServerData().getScriptName();
1184 }
1185
1186 /***
1187 * Gets the server data ofy the request.
1188 *
1189 * @return server data.
1190 */
1191 public ServerData getServerData()
1192 {
1193 return this.serverData;
1194 }
1195
1196 /***
1197 * Gets the IP address of the client that sent the request.
1198 *
1199 * @return a string.
1200 */
1201 public String getRemoteAddr()
1202 {
1203 if (this.remoteAddr == null)
1204 {
1205 this.remoteAddr = this.getRequest().getRemoteAddr();
1206 }
1207
1208 return this.remoteAddr;
1209 }
1210
1211 /***
1212 * Gets the qualified name of the client that sent the request.
1213 *
1214 * @return a string.
1215 */
1216 public String getRemoteHost()
1217 {
1218 if (this.remoteHost == null)
1219 {
1220 this.remoteHost = this.getRequest().getRemoteHost();
1221 }
1222
1223 return this.remoteHost;
1224 }
1225
1226 /***
1227 * Get the user agent for the request. The semantics here
1228 * are muddled because RunData caches the value after the
1229 * first invocation. This is different e.g. from getCharSet().
1230 *
1231 * @return a string.
1232 */
1233 public String getUserAgent()
1234 {
1235 if (StringUtils.isEmpty(userAgent))
1236 {
1237 userAgent = this.getRequest().getHeader("User-Agent");
1238 }
1239
1240 return userAgent;
1241 }
1242
1243 /***
1244 * Pulls a user object from the session and increments the access
1245 * counter and sets the last access date for the object.
1246 */
1247 public void populate()
1248 {
1249 user = getUserFromSession();
1250
1251 if (user != null)
1252 {
1253 user.setLastAccessDate();
1254 user.incrementAccessCounter();
1255 user.incrementAccessCounterForSession();
1256 }
1257 }
1258
1259 /***
1260 * Saves a user object into the session.
1261 */
1262 public void save()
1263 {
1264 getSession().setAttribute(User.SESSION_KEY, user);
1265 }
1266
1267 /***
1268 * Gets the stack trace if set.
1269 *
1270 * @return the stack trace.
1271 */
1272 public String getStackTrace()
1273 {
1274 return stackTrace;
1275 }
1276
1277 /***
1278 * Gets the stack trace exception if set.
1279 *
1280 * @return the stack exception.
1281 */
1282 public Throwable getStackTraceException()
1283 {
1284 return stackTraceException;
1285 }
1286
1287 /***
1288 * Sets the stack trace.
1289 *
1290 * @param trace the stack trace.
1291 * @param exp the exception.
1292 */
1293 public void setStackTrace(String trace, Throwable exp)
1294 {
1295 stackTrace = trace;
1296 stackTraceException = exp;
1297 }
1298
1299 /***
1300 * Gets a Map of debug variables.
1301 *
1302 * @return a Map of debug variables.
1303 * @deprecated use {@link #getDebugVariables} instead
1304 */
1305 public Map getVarDebug()
1306 {
1307 return debugVariables;
1308 }
1309
1310 /***
1311 * Sets a name/value pair in an internal Map that is accessible from the
1312 * Error screen. This is a good way to get debugging information
1313 * when an exception is thrown.
1314 *
1315 * @param name name of the variable
1316 * @param value value of the variable.
1317 */
1318 public void setDebugVariable(String name, Object value)
1319 {
1320 this.debugVariables.put(name, value);
1321 }
1322
1323 /***
1324 * Gets a Map of debug variables.
1325 *
1326 * @return a Map of debug variables.
1327 */
1328 public Map getDebugVariables()
1329 {
1330 return this.debugVariables;
1331 }
1332
1333
1334
1335
1336
1337 /***
1338 * Gets the parameter parser without parsing the parameters.
1339 *
1340 * @return the parameter parser.
1341 */
1342 public ParameterParser getParameterParser()
1343 {
1344 return parameters;
1345 }
1346
1347 /***
1348 * Sets the parameter parser.
1349 *
1350 * @param parser a parameter parser.
1351 */
1352 public void setParameterParser(ParameterParser parser)
1353 {
1354 parameters = parser;
1355 }
1356
1357 /***
1358 * Gets the cookie parser without parsing the cookies.
1359 *
1360 * @return the cookie parser.
1361 */
1362 public CookieParser getCookieParser()
1363 {
1364 return cookies;
1365 }
1366
1367 /***
1368 * Sets the cookie parser.
1369 *
1370 * @param parser a cookie parser.
1371 */
1372 public void setCookieParser(CookieParser parser)
1373 {
1374 cookies = parser;
1375 }
1376
1377 /***
1378 * Sets the servlet request.
1379 *
1380 * @param req a request.
1381 */
1382 public void setRequest(HttpServletRequest req)
1383 {
1384 this.req = req;
1385 }
1386
1387 /***
1388 * Sets the servlet response.
1389 *
1390 * @param res a response.
1391 */
1392 public void setResponse(HttpServletResponse res)
1393 {
1394 this.res = res;
1395 }
1396
1397 /***
1398 * Sets the servlet session information.
1399 *
1400 * @param sess a session.
1401 * @deprecated No replacement. This method no longer does anything.
1402 */
1403 public void setSession(HttpSession sess)
1404 {
1405 }
1406
1407 /***
1408 * Sets the servlet configuration used during servlet init.
1409 *
1410 * @param config a configuration.
1411 */
1412 public void setServletConfig(ServletConfig config)
1413 {
1414 this.config = config;
1415 if (config == null)
1416 {
1417 this.servletContext = null;
1418 }
1419 else
1420 {
1421 this.servletContext = config.getServletContext();
1422 }
1423 }
1424
1425 /***
1426 * Sets the server data of the request.
1427 *
1428 * @param serverData server data.
1429 */
1430 public void setServerData(ServerData serverData)
1431 {
1432 this.serverData = serverData;
1433 }
1434
1435
1436
1437
1438
1439 /***
1440 * Sets the print writer.
1441 *
1442 * @param out a print writer.
1443 * @deprecated no replacement planned, response writer will not be cached
1444 */
1445 protected void setOut(PrintWriter out)
1446 {
1447 this.out = out;
1448 }
1449
1450 /***
1451 * Sets the cached server scheme that is stored in the server data.
1452 *
1453 * @param serverScheme a string.
1454 */
1455 protected void setServerScheme(String serverScheme)
1456 {
1457 getServerData().setServerScheme(serverScheme);
1458 }
1459
1460 /***
1461 * Sets the cached server same that is stored in the server data.
1462 *
1463 * @param serverName a string.
1464 */
1465 protected void setServerName(String serverName)
1466 {
1467 getServerData().setServerName(serverName);
1468 }
1469
1470 /***
1471 * Sets the cached server port that is stored in the server data.
1472 *
1473 * @param port an int.
1474 */
1475 protected void setServerPort(int port)
1476 {
1477 getServerData().setServerPort(port);
1478 }
1479
1480 /***
1481 * Sets the cached context path that is stored in the server data.
1482 *
1483 * @param contextPath a string.
1484 */
1485 protected void setContextPath(String contextPath)
1486 {
1487 getServerData().setContextPath(contextPath);
1488 }
1489
1490 /***
1491 * Sets the cached script name that is stored in the server data.
1492 *
1493 * @param scriptName a string.
1494 */
1495 protected void setScriptName(String scriptName)
1496 {
1497 getServerData().setScriptName(scriptName);
1498 }
1499 }