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.script.common;
020:
021: import java.util.Map;
022: import java.util.Collections;
023: import javax.servlet.ServletRequest;
024: import javax.servlet.ServletResponse;
025: import javax.servlet.ServletContext;
026: import javax.servlet.http.HttpServletRequest;
027: import javax.servlet.http.HttpServletResponse;
028: import javax.servlet.jsp.JspContext;
029: import javax.servlet.jsp.PageContext;
030: import javax.servlet.jsp.el.VariableResolver;
031:
032: import org.apache.beehive.netui.pageflow.FacesBackingBean;
033: import org.apache.beehive.netui.pageflow.GlobalApp;
034: import org.apache.beehive.netui.pageflow.PageFlowController;
035: import org.apache.beehive.netui.pageflow.PageFlowUtils;
036: import org.apache.beehive.netui.pageflow.internal.AnyBeanActionForm;
037: import org.apache.beehive.netui.pageflow.internal.InternalUtils;
038: import org.apache.beehive.netui.script.el.NetUIUpdateVariableResolver;
039: import org.apache.beehive.netui.script.el.NetUIReadVariableResolver;
040: import org.apache.beehive.netui.util.logging.Logger;
041:
042: /**
043: * Utilities for loading NetUI implicit objects into various data binding scopes such as the
044: * PageContext, ServletRequest, HttpSession, and ServletContext.
045: */
046: public final class ImplicitObjectUtil {
047:
048: private static final Logger LOGGER = Logger
049: .getInstance(ImplicitObjectUtil.class);
050:
051: private static final String PAGE_FLOW_IMPLICIT_OBJECT_KEY = "pageFlow";
052: private static final String SHARED_FLOW_IMPLICIT_OBJECT_KEY = "sharedFlow";
053: private static final String GLOBAL_APP_IMPLICIT_OBJECT_KEY = "globalApp";
054: private static final String BUNDLE_IMPLICIT_OBJECT_KEY = "bundle";
055: private static final String BACKING_IMPLICIT_OBJECT_KEY = "backing";
056: private static final String PAGE_INPUT_IMPLICIT_OBJECT_KEY = "pageInput";
057: private static final String ACTION_FORM_IMPLICIT_OBJECT_KEY = "actionForm";
058: private static final String OUTPUT_FORM_BEAN_OBJECT_KEY = "outputFormBean";
059:
060: /* do not construct */
061: private ImplicitObjectUtil() {
062: }
063:
064: /**
065: * Load the NetUI framework's implicit objects into the request.
066: * @param request the request
067: * @param response the response
068: * @param servletContext the servlet context
069: * @param currentPageFlow the current page flow
070: */
071: public static void loadImplicitObjects(HttpServletRequest request,
072: HttpServletResponse response,
073: ServletContext servletContext,
074: PageFlowController currentPageFlow) {
075: // @todo: add an interceptor chain here for putting implicit objects into the request
076: loadPageFlow(request, currentPageFlow);
077:
078: // @todo: need to move bundleMap creation to a BundleMapFactory
079: BundleMap bundleMap = new BundleMap(request, servletContext);
080: loadBundleMap(request, bundleMap);
081: }
082:
083: /**
084: * Load the given <code>form</code> into the {@link JspContext} object. Because the
085: * framework supports any bean action forms, the type of the form is {@link Object}
086: * @param jspContext the jsp context
087: * @param form the form object
088: */
089: public static void loadActionForm(JspContext jspContext, Object form) {
090: jspContext.setAttribute(ACTION_FORM_IMPLICIT_OBJECT_KEY,
091: unwrapForm(form));
092: }
093:
094: /**
095: * Remove any action form present in the {@link JspContext}.
096: * @param jspContext the jsp context
097: */
098: public static void unloadActionForm(JspContext jspContext) {
099: jspContext.removeAttribute(ACTION_FORM_IMPLICIT_OBJECT_KEY);
100: }
101:
102: /**
103: * Load Page Flow related implicit objects into the request. This method will set the
104: * Page Flow itself and any available page inputs into the request.
105: * @param request the request
106: * @param pageFlow the current page flow
107: */
108: public static void loadPageFlow(ServletRequest request,
109: PageFlowController pageFlow) {
110: if (pageFlow != null)
111: request.setAttribute(PAGE_FLOW_IMPLICIT_OBJECT_KEY,
112: pageFlow);
113:
114: Map map = InternalUtils.getPageInputMap(request);
115: request.setAttribute(PAGE_INPUT_IMPLICIT_OBJECT_KEY,
116: map != null ? map : Collections.EMPTY_MAP);
117: }
118:
119: /**
120: * Load the JSF backing bean into the request.
121: * @param request the request
122: * @param facesBackingBean the JSF backing bean
123: */
124: public static void loadFacesBackingBean(ServletRequest request,
125: FacesBackingBean facesBackingBean) {
126: if (facesBackingBean != null)
127: request.setAttribute(BACKING_IMPLICIT_OBJECT_KEY,
128: facesBackingBean);
129: }
130:
131: /**
132: * Unload the JSF backing bean from the request
133: * @param request the request
134: */
135: public static void unloadFacesBackingBean(ServletRequest request) {
136: request.removeAttribute(BACKING_IMPLICIT_OBJECT_KEY);
137: }
138:
139: /**
140: * Load the shared flow into the request.
141: * @param request the request
142: * @param sharedFlows the current shared flows
143: */
144: public static void loadSharedFlow(ServletRequest request,
145: Map/*<String, SharedFlowController>*/sharedFlows) {
146: if (sharedFlows != null)
147: request.setAttribute(SHARED_FLOW_IMPLICIT_OBJECT_KEY,
148: sharedFlows);
149: }
150:
151: /**
152: * Load the global app into the request
153: * @param request the request
154: * @param globalApp the global app
155: */
156: public static void loadGlobalApp(ServletRequest request,
157: GlobalApp globalApp) {
158: if (globalApp != null)
159: request.setAttribute(GLOBAL_APP_IMPLICIT_OBJECT_KEY,
160: globalApp);
161: }
162:
163: /**
164: * Load the resource bundle binding map into the request.
165: * @param request the request
166: * @param bundleMap the {@link java.util.Map} of resource bundles
167: */
168: public static void loadBundleMap(ServletRequest request,
169: BundleMap bundleMap) {
170: request.setAttribute(BUNDLE_IMPLICIT_OBJECT_KEY, bundleMap);
171: }
172:
173: /**
174: * Load the output form bean into the request.
175: * @param request the request
176: * @param bean the output form bean
177: */
178: public static void loadOutputFormBean(ServletRequest request,
179: Object bean) {
180: if (bean != null)
181: request.setAttribute(OUTPUT_FORM_BEAN_OBJECT_KEY, bean);
182: }
183:
184: /**
185: * If applicable, unwrap the given <code>form</code> object to its native backing object. If
186: * the type of this form is a {@link AnyBeanActionForm}, the type returned will be the
187: * native object backing the wrapper.
188: * @param form the form
189: * @return the unwrapped form
190: */
191: public static Object unwrapForm(Object form) {
192: if (LOGGER.isDebugEnabled()
193: && form instanceof AnyBeanActionForm)
194: LOGGER.debug("using form of type: "
195: + form.getClass().getName());
196:
197: if (form instanceof AnyBeanActionForm)
198: return ((AnyBeanActionForm) form).getBean();
199: else
200: return form;
201: }
202:
203: /**
204: * Get the {@link Map} of shared flow objects from the request.
205: *
206: * @param request
207: * @return the shared flows
208: */
209: public static Map/*<String, SharedFlowController>*/getSharedFlow(
210: ServletRequest request) {
211: return (Map) request
212: .getAttribute(SHARED_FLOW_IMPLICIT_OBJECT_KEY);
213: }
214:
215: /**
216: * Internal method!
217: *
218: * This method is used by the expression engine to get the current page flow. If no page flow is
219: * found, an exception will be thrown.
220: * @param request the request
221: * @param response the response
222: * @return the page flow
223: */
224: public static PageFlowController getPageFlow(
225: ServletRequest request, ServletResponse response) {
226: assert request instanceof HttpServletRequest;
227:
228: PageFlowController jpf = PageFlowUtils
229: .getCurrentPageFlow((HttpServletRequest) request);
230: if (jpf != null)
231: return jpf;
232: else {
233: String message = "There is no current Page Flow!";
234: LOGGER.error(message);
235: throw new RuntimeException(message);
236: }
237: }
238:
239: /**
240: * Internal method!
241: *
242: * This method is used by the expression engine to get the current global app. If no global app
243: * is found, an exception will be thrown.
244: * @param request the request
245: * @return the global app
246: */
247: public static GlobalApp getGlobalApp(ServletRequest request) {
248: assert request instanceof HttpServletRequest;
249: GlobalApp ga = PageFlowUtils
250: .getGlobalApp((HttpServletRequest) request);
251: if (ga == null) {
252: String message = "There is no current GlobalApp!";
253: LOGGER.error(message);
254: throw new RuntimeException(message);
255: }
256: return ga;
257: }
258:
259: /**
260: * Internal method!
261: *
262: * Create a {@link VariableResolver} that contains the implicit objects available for expression
263: * updates.
264: */
265: public static VariableResolver getUpdateVariableResolver(
266: ServletRequest request, ServletResponse response,
267: boolean isHandlingPost) {
268: Object form = ImplicitObjectUtil
269: .unwrapForm(getActionForm(request));
270: return new NetUIUpdateVariableResolver(form, request, response,
271: isHandlingPost);
272: }
273:
274: /**
275: * Internal method!
276: *
277: * Create a {@link VariableResolver} that contains the implicit objects available for expression
278: * updates.
279: */
280: public static VariableResolver getUpdateVariableResolver(
281: Object form, ServletRequest request,
282: ServletResponse response, boolean isHandlingPost) {
283: Object realForm = ImplicitObjectUtil.unwrapForm(form);
284: return new NetUIUpdateVariableResolver(realForm, request,
285: response, isHandlingPost);
286: }
287:
288: /**
289: * Internal method!
290: *
291: * Create a {@link VariableResolver} that contains the implicit objects available for
292: * expression reads.
293: *
294: * @param jspContext the jsp context
295: * @return the variable resolver
296: */
297: public static VariableResolver getReadVariableResolver(
298: JspContext jspContext) {
299: assert jspContext != null;
300:
301: /* todo: ugly ugly ugly...getting the appropriate variable resolver should be easier than this */
302: Object actionForm = getActionForm(((PageContext) jspContext)
303: .getRequest());
304:
305: NetUIReadVariableResolver netuiVariableResolver = new NetUIReadVariableResolver(
306: jspContext.getVariableResolver());
307: netuiVariableResolver.setActionForm(unwrapForm(actionForm));
308:
309: return netuiVariableResolver;
310: }
311:
312: private static Object getActionForm(ServletRequest request) {
313: return request
314: .getAttribute(org.apache.struts.taglib.html.Constants.BEAN_KEY);
315: }
316: }
|