1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.apache.struts2.dispatcher.ng;
22
23 import org.apache.struts2.dispatcher.Dispatcher;
24 import org.apache.struts2.dispatcher.mapper.ActionMapping;
25 import org.apache.struts2.dispatcher.mapper.ActionMapper;
26 import org.apache.struts2.StrutsException;
27
28 import javax.servlet.ServletException;
29 import javax.servlet.ServletContext;
30 import javax.servlet.http.HttpServletRequest;
31 import javax.servlet.http.HttpServletResponse;
32
33 import com.opensymphony.xwork2.ActionContext;
34 import com.opensymphony.xwork2.util.ValueStack;
35 import com.opensymphony.xwork2.util.ValueStackFactory;
36 import com.opensymphony.xwork2.util.logging.Logger;
37 import com.opensymphony.xwork2.util.logging.LoggerFactory;
38
39 import java.io.IOException;
40 import java.util.HashMap;
41
42 /***
43 * Contains preparation operations for a request before execution
44 */
45 public class PrepareOperations {
46
47 private ServletContext servletContext;
48 private Dispatcher dispatcher;
49 private static final String STRUTS_ACTION_MAPPING_KEY = "struts.actionMapping";
50 public static final String CLEANUP_RECURSION_COUNTER = "__cleanup_recursion_counter";
51 private Logger log = LoggerFactory.getLogger(PrepareOperations.class);
52
53 public PrepareOperations(ServletContext servletContext, Dispatcher dispatcher) {
54 this.dispatcher = dispatcher;
55 this.servletContext = servletContext;
56 }
57
58 /***
59 * Creates the action context and initializes the thread local
60 */
61 public ActionContext createActionContext(HttpServletRequest request, HttpServletResponse response) {
62 ActionContext ctx;
63 Integer counter = 1;
64 Integer oldCounter = (Integer) request.getAttribute(CLEANUP_RECURSION_COUNTER);
65 if (oldCounter != null) {
66 counter = oldCounter + 1;
67 }
68
69 ActionContext oldContext = ActionContext.getContext();
70 if (oldContext != null) {
71
72 ctx = new ActionContext(new HashMap<String, Object>(oldContext.getContextMap()));
73 } else {
74 ValueStack stack = dispatcher.getContainer().getInstance(ValueStackFactory.class).createValueStack();
75 stack.getContext().putAll(dispatcher.createContextMap(request, response, null, servletContext));
76 ctx = new ActionContext(stack.getContext());
77 }
78 request.setAttribute(CLEANUP_RECURSION_COUNTER, counter);
79 ActionContext.setContext(ctx);
80 return ctx;
81 }
82
83 /***
84 * Cleans up a request of thread locals
85 */
86 public void cleanupRequest(HttpServletRequest request) {
87 Integer counterVal = (Integer) request.getAttribute(CLEANUP_RECURSION_COUNTER);
88 if (counterVal != null) {
89 counterVal -= 1;
90 request.setAttribute(CLEANUP_RECURSION_COUNTER, counterVal);
91 if (counterVal > 0 ) {
92 if (log.isDebugEnabled()) {
93 log.debug("skipping cleanup counter="+counterVal);
94 }
95 return;
96 }
97 }
98
99
100 ActionContext.setContext(null);
101 Dispatcher.setInstance(null);
102 }
103
104 /***
105 * Assigns the dispatcher to the dispatcher thread local
106 */
107 public void assignDispatcherToThread() {
108 Dispatcher.setInstance(dispatcher);
109 }
110
111 /***
112 * Sets the request encoding and locale on the response
113 */
114 public void setEncodingAndLocale(HttpServletRequest request, HttpServletResponse response) {
115 dispatcher.prepare(request, response);
116 }
117
118 /***
119 * Wraps the request with the Struts wrapper that handles multipart requests better
120 * @return The new request, if there is one
121 * @throws ServletException
122 */
123 public HttpServletRequest wrapRequest(HttpServletRequest oldRequest) throws ServletException {
124 HttpServletRequest request = oldRequest;
125 try {
126
127
128 request = dispatcher.wrapRequest(request, servletContext);
129 } catch (IOException e) {
130 String message = "Could not wrap servlet request with MultipartRequestWrapper!";
131 throw new ServletException(message, e);
132 }
133 return request;
134 }
135
136 /***
137 * Finds and optionally creates an {@link ActionMapping}. It first looks in the current request to see if one
138 * has already been found, otherwise, it creates it and stores it in the request. No mapping will be created in the
139 * case of static resource requests or unidentifiable requests for other servlets, for example.
140 */
141 public ActionMapping findActionMapping(HttpServletRequest request, HttpServletResponse response) {
142 ActionMapping mapping = (ActionMapping) request.getAttribute(STRUTS_ACTION_MAPPING_KEY);
143 if (mapping == null) {
144 try {
145 mapping = dispatcher.getContainer().getInstance(ActionMapper.class).getMapping(request, dispatcher.getConfigurationManager());
146 if (mapping != null) {
147 request.setAttribute(STRUTS_ACTION_MAPPING_KEY, mapping);
148 }
149 } catch (Exception ex) {
150 dispatcher.sendError(request, response, servletContext, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ex);
151 }
152 }
153
154 return mapping;
155 }
156
157 /***
158 * Cleans up the dispatcher instance
159 */
160 public void cleanupDispatcher() {
161 if (dispatcher == null) {
162 throw new StrutsException("something is seriously wrong, Dispatcher is not initialized (null) ");
163 } else {
164 try {
165 dispatcher.cleanup();
166 } finally {
167 ActionContext.setContext(null);
168 }
169 }
170 }
171 }