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 import org.apache.struts2.RequestUtils;
28
29 import javax.servlet.ServletException;
30 import javax.servlet.ServletContext;
31 import javax.servlet.http.HttpServletRequest;
32 import javax.servlet.http.HttpServletResponse;
33
34 import com.opensymphony.xwork2.ActionContext;
35 import com.opensymphony.xwork2.util.ValueStack;
36 import com.opensymphony.xwork2.util.ValueStackFactory;
37 import com.opensymphony.xwork2.util.logging.Logger;
38 import com.opensymphony.xwork2.util.logging.LoggerFactory;
39
40 import java.io.IOException;
41 import java.util.HashMap;
42 import java.util.List;
43 import java.util.regex.Pattern;
44
45 /***
46 * Contains preparation operations for a request before execution
47 */
48 public class PrepareOperations {
49
50 private ServletContext servletContext;
51 private Dispatcher dispatcher;
52 private static final String STRUTS_ACTION_MAPPING_KEY = "struts.actionMapping";
53 public static final String CLEANUP_RECURSION_COUNTER = "__cleanup_recursion_counter";
54 private Logger log = LoggerFactory.getLogger(PrepareOperations.class);
55
56 public PrepareOperations(ServletContext servletContext, Dispatcher dispatcher) {
57 this.dispatcher = dispatcher;
58 this.servletContext = servletContext;
59 }
60
61 /***
62 * Creates the action context and initializes the thread local
63 */
64 public ActionContext createActionContext(HttpServletRequest request, HttpServletResponse response) {
65 ActionContext ctx;
66 Integer counter = 1;
67 Integer oldCounter = (Integer) request.getAttribute(CLEANUP_RECURSION_COUNTER);
68 if (oldCounter != null) {
69 counter = oldCounter + 1;
70 }
71
72 ActionContext oldContext = ActionContext.getContext();
73 if (oldContext != null) {
74
75 ctx = new ActionContext(new HashMap<String, Object>(oldContext.getContextMap()));
76 } else {
77 ValueStack stack = dispatcher.getContainer().getInstance(ValueStackFactory.class).createValueStack();
78 stack.getContext().putAll(dispatcher.createContextMap(request, response, null, servletContext));
79 ctx = new ActionContext(stack.getContext());
80 }
81 request.setAttribute(CLEANUP_RECURSION_COUNTER, counter);
82 ActionContext.setContext(ctx);
83 return ctx;
84 }
85
86 /***
87 * Cleans up a request of thread locals
88 */
89 public void cleanupRequest(HttpServletRequest request) {
90 Integer counterVal = (Integer) request.getAttribute(CLEANUP_RECURSION_COUNTER);
91 if (counterVal != null) {
92 counterVal -= 1;
93 request.setAttribute(CLEANUP_RECURSION_COUNTER, counterVal);
94 if (counterVal > 0 ) {
95 if (log.isDebugEnabled()) {
96 log.debug("skipping cleanup counter="+counterVal);
97 }
98 return;
99 }
100 }
101
102
103 ActionContext.setContext(null);
104 Dispatcher.setInstance(null);
105 }
106
107 /***
108 * Assigns the dispatcher to the dispatcher thread local
109 */
110 public void assignDispatcherToThread() {
111 Dispatcher.setInstance(dispatcher);
112 }
113
114 /***
115 * Sets the request encoding and locale on the response
116 */
117 public void setEncodingAndLocale(HttpServletRequest request, HttpServletResponse response) {
118 dispatcher.prepare(request, response);
119 }
120
121 /***
122 * Wraps the request with the Struts wrapper that handles multipart requests better
123 * @return The new request, if there is one
124 * @throws ServletException
125 */
126 public HttpServletRequest wrapRequest(HttpServletRequest oldRequest) throws ServletException {
127 HttpServletRequest request = oldRequest;
128 try {
129
130
131 request = dispatcher.wrapRequest(request, servletContext);
132 } catch (IOException e) {
133 String message = "Could not wrap servlet request with MultipartRequestWrapper!";
134 throw new ServletException(message, e);
135 }
136 return request;
137 }
138
139 /***
140 * Finds and optionally creates an {@link ActionMapping}. It first looks in the current request to see if one
141 * has already been found, otherwise, it creates it and stores it in the request. No mapping will be created in the
142 * case of static resource requests or unidentifiable requests for other servlets, for example.
143 */
144 public ActionMapping findActionMapping(HttpServletRequest request, HttpServletResponse response) {
145 return findActionMapping(request, response, false);
146 }
147
148 /***
149 * Finds and optionally creates an {@link ActionMapping}. if forceLookup is false, it first looks in the current request to see if one
150 * has already been found, otherwise, it creates it and stores it in the request. No mapping will be created in the
151 * case of static resource requests or unidentifiable requests for other servlets, for example.
152 * @param forceLookup if true, the action mapping will be looked up from the ActionMapper instance, ignoring if there is one
153 * in the request or not
154 */
155 public ActionMapping findActionMapping(HttpServletRequest request, HttpServletResponse response, boolean forceLookup) {
156 ActionMapping mapping = (ActionMapping) request.getAttribute(STRUTS_ACTION_MAPPING_KEY);
157 if (mapping == null || forceLookup) {
158 try {
159 mapping = dispatcher.getContainer().getInstance(ActionMapper.class).getMapping(request, dispatcher.getConfigurationManager());
160 if (mapping != null) {
161 request.setAttribute(STRUTS_ACTION_MAPPING_KEY, mapping);
162 }
163 } catch (Exception ex) {
164 dispatcher.sendError(request, response, servletContext, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ex);
165 }
166 }
167
168 return mapping;
169 }
170
171 /***
172 * Cleans up the dispatcher instance
173 */
174 public void cleanupDispatcher() {
175 if (dispatcher == null) {
176 throw new StrutsException("something is seriously wrong, Dispatcher is not initialized (null) ");
177 } else {
178 try {
179 dispatcher.cleanup();
180 } finally {
181 ActionContext.setContext(null);
182 }
183 }
184 }
185
186 /***
187 * Check whether the request matches a list of exclude patterns.
188 *
189 * @param request The request to check patterns against
190 * @param excludedPatterns list of patterns for exclusion
191 *
192 * @return <tt>true</tt> if the request URI matches one of the given patterns
193 */
194 public boolean isUrlExcluded( HttpServletRequest request, List<Pattern> excludedPatterns ) {
195 if (excludedPatterns != null) {
196 String uri = getUri(request);
197 for ( Pattern pattern : excludedPatterns ) {
198 if (pattern.matcher(uri).matches()) {
199 return true;
200 }
201 }
202 }
203 return false;
204 }
205
206 /***
207 * Gets the uri from the request
208 *
209 * @param request The request
210 *
211 * @return The uri
212 */
213 private String getUri( HttpServletRequest request ) {
214
215 String uri = (String) request.getAttribute("javax.servlet.include.servlet_path");
216 if (uri != null) {
217 return uri;
218 }
219
220 uri = RequestUtils.getServletPath(request);
221 if (uri != null && !"".equals(uri)) {
222 return uri;
223 }
224
225 uri = request.getRequestURI();
226 return uri.substring(request.getContextPath().length());
227 }
228
229 }