001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: * $Header:$
018: */
019: package org.apache.beehive.netui.pageflow.internal;
020:
021: import org.apache.beehive.netui.pageflow.FlowController;
022: import org.apache.beehive.netui.pageflow.PreviousPageInfo;
023: import org.apache.struts.upload.MultipartRequestWrapper;
024:
025: import javax.servlet.http.HttpServletRequestWrapper;
026: import javax.servlet.http.HttpServletRequest;
027: import javax.servlet.ServletRequest;
028: import javax.servlet.ServletRequestWrapper;
029:
030: /**
031: * Request wrapper that contains request-scoped values that our runtime uses. This is faster than sticking everything
032: * into attributes on the request.
033: */
034: public final class PageFlowRequestWrapper extends
035: HttpServletRequestWrapper {
036: private static final class State {
037: public Integer forwardedRequestCount;
038: public String originalServletPath;
039: public FlowController currentFlowController;
040: public ViewRenderer viewRenderer;
041: public PreviousPageInfo previousPageInfo;
042: public boolean returningFromActionIntercept = false;
043: public String pageFlowScopedFormName;
044: public boolean processPopulateAlreadyCalled = false;
045: public boolean forwardedByButton = false;
046: public MultipartRequestWrapper multipartRequestWrapper;
047: public Throwable exceptionBeingHandled = null;
048: public boolean stayInCurrentModule = false;
049: public boolean scopedLookup = false;
050: public boolean returningFromNesting = false;
051: }
052:
053: private State _state = new State();
054:
055: public static PageFlowRequestWrapper get(
056: ServletRequest servletRequest) {
057: servletRequest = InternalUtils.unwrapMultipart(servletRequest);
058: assert servletRequest instanceof PageFlowRequestWrapper : servletRequest
059: .getClass().getName();
060: return (PageFlowRequestWrapper) servletRequest;
061: }
062:
063: /**
064: * Unwrap to find the PageFlowRequestWrapper. This method may return <code>null</code>.
065: */
066: public static PageFlowRequestWrapper unwrap(
067: ServletRequest servletRequest) {
068: servletRequest = InternalUtils.unwrapMultipart(servletRequest);
069:
070: while (!(servletRequest instanceof PageFlowRequestWrapper)) {
071: if (!(servletRequest instanceof ServletRequestWrapper))
072: return null;
073: servletRequest = ((ServletRequestWrapper) servletRequest)
074: .getRequest();
075: }
076:
077: return (PageFlowRequestWrapper) servletRequest;
078: }
079:
080: public void initFrom(PageFlowRequestWrapper wrapper) {
081: _state = wrapper._state;
082: }
083:
084: public PageFlowRequestWrapper(HttpServletRequest delegate) {
085: super (delegate);
086: }
087:
088: public boolean isForwardedRequest() {
089: return _state.forwardedRequestCount != null;
090: }
091:
092: public int getForwardedRequestCount() {
093: return _state.forwardedRequestCount != null ? _state.forwardedRequestCount
094: .intValue()
095: : 0;
096: }
097:
098: public void setForwardedRequestCount(int count) {
099: _state.forwardedRequestCount = new Integer(count);
100: }
101:
102: public String getOriginalServletPath() {
103: return _state.originalServletPath;
104: }
105:
106: public void setOriginalServletPath(String originalServletPath) {
107: _state.originalServletPath = originalServletPath;
108: }
109:
110: public FlowController getCurrentFlowController() {
111: return _state.currentFlowController;
112: }
113:
114: public void setCurrentFlowController(
115: FlowController currentFlowController) {
116: _state.currentFlowController = currentFlowController;
117: }
118:
119: public ViewRenderer getViewRenderer() {
120: return _state.viewRenderer;
121: }
122:
123: public void setViewRenderer(ViewRenderer viewRenderer) {
124: _state.viewRenderer = viewRenderer;
125: }
126:
127: public PreviousPageInfo getPreviousPageInfo(boolean remove) {
128: PreviousPageInfo retVal = _state.previousPageInfo;
129: if (remove)
130: _state.previousPageInfo = null;
131: return retVal;
132: }
133:
134: public void setPreviousPageInfo(PreviousPageInfo previousPageInfo) {
135: _state.previousPageInfo = previousPageInfo;
136: }
137:
138: public boolean isReturningFromActionIntercept() {
139: return _state.returningFromActionIntercept;
140: }
141:
142: public void setReturningFromActionIntercept(
143: boolean returningFromActionIntercept) {
144: _state.returningFromActionIntercept = returningFromActionIntercept;
145: }
146:
147: public HttpServletRequest getHttpRequest() {
148: return (HttpServletRequest) super .getRequest();
149: }
150:
151: public String getPageFlowScopedFormName() {
152: return _state.pageFlowScopedFormName;
153: }
154:
155: public void setPageFlowScopedFormName(String pageFlowScopedFormName) {
156: _state.pageFlowScopedFormName = pageFlowScopedFormName;
157: }
158:
159: public boolean isProcessPopulateAlreadyCalled() {
160: return _state.processPopulateAlreadyCalled;
161: }
162:
163: public void setProcessPopulateAlreadyCalled(
164: boolean processPopulateAlreadyCalled) {
165: _state.processPopulateAlreadyCalled = processPopulateAlreadyCalled;
166: }
167:
168: public boolean isForwardedByButton() {
169: return _state.forwardedByButton;
170: }
171:
172: public void setForwardedByButton(boolean forwardedByButton) {
173: _state.forwardedByButton = forwardedByButton;
174: }
175:
176: public MultipartRequestWrapper getMultipartRequestWrapper() {
177: return _state.multipartRequestWrapper;
178: }
179:
180: public void setMultipartRequestWrapper(
181: MultipartRequestWrapper multipartRequestWrapper) {
182: _state.multipartRequestWrapper = multipartRequestWrapper;
183: }
184:
185: public boolean isStayInCurrentModule() {
186: return _state.stayInCurrentModule;
187: }
188:
189: public void setStayInCurrentModule(boolean stayInCurrentModule) {
190: _state.stayInCurrentModule = stayInCurrentModule;
191: }
192:
193: public boolean isScopedLookup() {
194: return _state.scopedLookup;
195: }
196:
197: public void setScopedLookup(boolean scopedLookup) {
198: _state.scopedLookup = scopedLookup;
199: }
200:
201: public Throwable getExceptionBeingHandled() {
202: return _state.exceptionBeingHandled;
203: }
204:
205: public void setExceptionBeingHandled(Throwable th) {
206: _state.exceptionBeingHandled = th;
207: }
208:
209: public boolean isReturningFromNesting() {
210: return _state.returningFromNesting;
211: }
212:
213: public void setReturningFromNesting(boolean returningFromNesting) {
214: _state.returningFromNesting = returningFromNesting;
215: }
216:
217: public static PageFlowRequestWrapper wrapRequest(
218: HttpServletRequest req) {
219: if (req instanceof PageFlowRequestWrapper) {
220: return (PageFlowRequestWrapper) req;
221: }
222:
223: PageFlowRequestWrapper retVal = new PageFlowRequestWrapper(req);
224:
225: // If there's *any* PageFlowRequestWrapper up the chain of wrapped requests, we must copy values from that.
226: ServletRequest j = retVal.getRequest();
227: while (j instanceof HttpServletRequestWrapper) {
228: if (j instanceof PageFlowRequestWrapper) {
229: retVal.initFrom((PageFlowRequestWrapper) j);
230: break;
231: }
232:
233: j = ((HttpServletRequestWrapper) j).getRequest();
234: }
235:
236: return retVal;
237: }
238:
239: /**
240: * This override returns "utf-8" if the character encoding in the request is null. It works around a Struts
241: * issue (http://issues.apache.org/bugzilla/show_bug.cgi?id=29668), where CommonsMultipartRequestHandler uses
242: * the character encoding from the request, which causes problems if the encoding wasn't specified in the request
243: * (as it usually never is). This is tracked in Beehive's JIRA as
244: * http://issues.apache.org/jira/browse/BEEHIVE-803 .
245: */
246: public String getCharacterEncoding() {
247: String encoding = super .getCharacterEncoding();
248: return encoding != null ? encoding : "utf-8";
249: }
250: }
|