1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.module.blossom.support;
35
36 import java.io.IOException;
37 import java.util.ArrayList;
38 import java.util.List;
39
40 import javax.servlet.RequestDispatcher;
41 import javax.servlet.ServletException;
42 import javax.servlet.ServletRequest;
43 import javax.servlet.ServletResponse;
44 import javax.servlet.http.HttpServletRequest;
45 import javax.servlet.http.HttpServletRequestWrapper;
46
47 import org.springframework.web.util.WebUtils;
48
49
50
51
52
53
54
55 public class ForwardRequestWrapper extends SpecialAttributeRequestWrapper {
56
57 private static final String FORWARD_ATTRIBUTES_COMMON_PREFIX = "javax.servlet.forward.";
58 private static final String[] FORWARD_ATTRIBUTE_NAMES = new String[]{
59 WebUtils.FORWARD_REQUEST_URI_ATTRIBUTE,
60 WebUtils.FORWARD_CONTEXT_PATH_ATTRIBUTE,
61 WebUtils.FORWARD_SERVLET_PATH_ATTRIBUTE,
62 WebUtils.FORWARD_PATH_INFO_ATTRIBUTE,
63 WebUtils.FORWARD_QUERY_STRING_ATTRIBUTE};
64
65 private final List<Object> previousChainState = new ArrayList<Object>(48);
66 private boolean overridePathElements = true;
67 private final String requestUri;
68 private final String contextPath;
69 private final String servletPath;
70 private final String pathInfo;
71
72 public ForwardRequestWrapper(HttpServletRequest request, String requestUri, String contextPath, String servletPath, String pathInfo) {
73 super(request);
74 this.requestUri = requestUri;
75 this.contextPath = contextPath;
76 this.servletPath = servletPath;
77 this.pathInfo = pathInfo;
78 if (request.getAttribute(WebUtils.FORWARD_REQUEST_URI_ATTRIBUTE) == null) {
79 setOverriddenAttributes(
80 FORWARD_ATTRIBUTES_COMMON_PREFIX,
81 FORWARD_ATTRIBUTE_NAMES,
82 new Object[]{
83 request.getRequestURI(),
84 request.getContextPath(),
85 request.getServletPath(),
86 request.getPathInfo(),
87 request.getQueryString()}
88 );
89 } else {
90 super.setEnabled(false);
91 }
92
93
94
95 ServletRequest wrapper = request;
96 while (wrapper instanceof HttpServletRequestWrapper) {
97 if (wrapper instanceof IncludeRequestWrapper) {
98 IncludeRequestWrapper includeRequestWrapper = (IncludeRequestWrapper) wrapper;
99 previousChainState.add(includeRequestWrapper);
100 previousChainState.add(includeRequestWrapper.isEnabled());
101 includeRequestWrapper.setEnabled(false);
102 } else if (wrapper instanceof ForwardRequestWrapper) {
103 ForwardRequestWrapper forwardRequestWrapper = (ForwardRequestWrapper) wrapper;
104 previousChainState.add(forwardRequestWrapper);
105 previousChainState.add(forwardRequestWrapper.isOverridePathElements());
106 previousChainState.add(forwardRequestWrapper.isEnabled());
107 forwardRequestWrapper.setOverridePathElements(false);
108 forwardRequestWrapper.setEnabled(false);
109 }
110 wrapper = ((HttpServletRequestWrapper) wrapper).getRequest();
111 }
112 }
113
114 public void restore() {
115 for (int i = 0; i < previousChainState.size(); ) {
116 Object wrapper = previousChainState.get(i++);
117 if (wrapper instanceof IncludeRequestWrapper) {
118 IncludeRequestWrapper includeRequestWrapper = (IncludeRequestWrapper) wrapper;
119 includeRequestWrapper.setEnabled((Boolean) previousChainState.get(i++));
120 } else {
121 ForwardRequestWrapper forwardRequestWrapper = (ForwardRequestWrapper) wrapper;
122 forwardRequestWrapper.setOverridePathElements((Boolean) previousChainState.get(i++));
123 forwardRequestWrapper.setEnabled((Boolean) previousChainState.get(i++));
124 }
125 }
126 }
127
128 public boolean isOverridePathElements() {
129 return overridePathElements;
130 }
131
132 public void setOverridePathElements(boolean overridePathElements) {
133 this.overridePathElements = overridePathElements;
134 }
135
136 @Override
137 public String getRequestURI() {
138 if (overridePathElements) {
139 return requestUri;
140 }
141 return super.getRequestURI();
142 }
143
144 @Override
145 public String getServletPath() {
146 if (overridePathElements) {
147 return servletPath;
148 }
149 return super.getServletPath();
150 }
151
152 @Override
153 public String getContextPath() {
154 if (overridePathElements) {
155 return contextPath;
156 }
157 return super.getContextPath();
158 }
159
160 @Override
161 public String getPathInfo() {
162 if (overridePathElements) {
163 return pathInfo;
164 }
165 return super.getPathInfo();
166 }
167
168 @Override
169 public RequestDispatcher getRequestDispatcher(final String path) {
170
171 if (!overridePathElements) {
172 return super.getRequestDispatcher(path);
173 }
174
175 final RequestDispatcher dispatcher = super.getRequestDispatcher(path);
176
177 return new RequestDispatcher() {
178
179 @Override
180 public void forward(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
181 boolean previousValue = overridePathElements;
182 overridePathElements = false;
183 try {
184 dispatcher.forward(servletRequest, servletResponse);
185 } finally {
186 overridePathElements = previousValue;
187 }
188 }
189
190 @Override
191 public void include(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
192 dispatcher.include(servletRequest, servletResponse);
193 }
194 };
195 }
196 }