001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package com.sun.rave.web.ui.appbase;
043:
044: import com.sun.rave.web.ui.appbase.faces.ViewHandlerImpl;
045: import java.util.ArrayList;
046: import java.util.Iterator;
047: import java.util.List;
048: import java.util.Map;
049: import javax.faces.context.FacesContext;
050: import javax.faces.component.UIViewRoot;
051: import javax.faces.event.PhaseEvent;
052: import javax.faces.event.PhaseId;
053: import javax.faces.lifecycle.Lifecycle;
054:
055: /**
056: * <p><strong>AbstractPageBean</strong> is the abstract base class for every
057: * page bean associated with a JSP page containing JavaServer Faces
058: * components. It extends {@link FacesBean}, so it inherits all of the
059: * default integration behavior found there.</p>
060: *
061: * <p>In addition to event handler methods that you create while building
062: * your application, the runtime environment will also call the following
063: * <em>lifecycle</em> related methods at appropriate points during the execution
064: * of your application:</p>
065: * <ul>
066: * <li><strong>init()</strong> - Called whenever you navigate to the
067: * corresponding JSP page, either directly (via a URL) or indirectly
068: * via page navigation from a different page. You can override this
069: * method to acquire any resources that will always be needed by this
070: * page.</li>
071: * <li><strong>preprocess()</strong> - If this request is a postback (i.e.
072: * your page is about to process an incoming form submit, this method
073: * will be called after the original component tree has been restored,
074: * but before any standard JavaServer Faces event processing is done
075: * (i.e. this is called before <em>Apply Request Values</em> phase of
076: * the request processing lifecycle). Override this method to acquire
077: * any resources that will be needed by event handlers (such as action
078: * methods, validator methods, or value change listener methods) that
079: * will be executed while executing the request processing lifecycle.</li>
080: * <li><strong>prerender()</strong> - If this page is the one that will be
081: * rendering the response, this method is called <em>after</em> any event
082: * processing, but before the actual rendering. Override this method to
083: * acquire resources that are only needed when a page is being rendered.
084: * </li>
085: * <li><strong>destroy()</strong> - Called unconditionally if
086: * <code>init()</code> was called, after completion of rendering by
087: * whichever page was actually rendered. Override this method to release
088: * any resources allocated in the <code>init()</code>,
089: * <code>preprocess()</code>, or <code>prerender()</code>
090: * methods (or in an event handler).</li>
091: * </ul>
092: *
093: * <p>For advanced users, and as a carry forward from previous versions of
094: * Sun Java Studio Creator, page bean instances are also registered
095: * automatically as a JavaServer Faces <code>PhaseListener</code>. For each
096: * lifecycle phase, there is an appropriate "before" and "after" event method,
097: * which you can override to provide phase-specific behavior. For example,
098: * if you wanted to provide some special logic that happened before or after
099: * the Update Model Values phase, you would override one of the methods:</p>
100: * <pre>
101: * public void beforeUpdateModelValues();
102: * public void afterUpdateModelValues();
103: * </pre>
104: *
105: */
106: public abstract class AbstractPageBean extends FacesBean // implements PhaseListener
107: {
108:
109: // ------------------------------------------------------------- Constructor
110:
111: /**
112: * <p>Construct a new instance of this bean.</p>
113: */
114: public AbstractPageBean() {
115:
116: /* mbohm (6450530): This work is already being done when
117: * the managed bean mechanism places this page bean
118: * in request scope. Placing it in request scope causes
119: * LifecycleListener.attributeAdded to be called, which causes
120: * LifecycleListener.fireInit to be called, which causes
121: * ViewHandlerImpl.record to be called, which appends this page bean
122: * to the PAGE_BEANS_CREATED list in the request.
123: // Register ourselves for phase events
124: Map map = FacesContext.getCurrentInstance().getExternalContext().getRequestMap();
125: List list = (List) map.get(ViewHandlerImpl.PAGE_BEANS_CREATED);
126: if (list == null) {
127: list = new ArrayList(5);
128: map.put(ViewHandlerImpl.PAGE_BEANS_CREATED, list);
129: }
130: list.add(this);
131: **/
132:
133: }
134:
135: // --------------------------------------------------- PhaseListener Methods
136:
137: /**
138: * <p>Call through to the appropriate "before event" method,
139: * depending upon the <code>PhaseId</code> in this event.</p>
140: *
141: * @param event <code>PhaseEvent</code> to be processed
142: */
143: public void beforePhase(PhaseEvent event) {
144:
145: PhaseId phaseId = event.getPhaseId();
146: if (PhaseId.RESTORE_VIEW.equals(phaseId)) {
147: beforeRestoreView();
148: } else if (PhaseId.APPLY_REQUEST_VALUES.equals(phaseId)) {
149: beforeApplyRequestValues();
150: } else if (PhaseId.PROCESS_VALIDATIONS.equals(phaseId)) {
151: beforeProcessValidations();
152: } else if (PhaseId.UPDATE_MODEL_VALUES.equals(phaseId)) {
153: beforeUpdateModelValues();
154: } else if (PhaseId.INVOKE_APPLICATION.equals(phaseId)) {
155: beforeInvokeApplication();
156: } else if (PhaseId.RENDER_RESPONSE.equals(phaseId)) {
157: if (!FacesContext.getCurrentInstance()
158: .getResponseComplete()) {
159: beforeRenderResponse();
160: }
161: }
162:
163: }
164:
165: /**
166: * <p>Call through to the appropriate "after event" method,
167: * depending upon the <code>PhaseId</code> in this event.</p>
168: *
169: * @param event <code>PhaseEvent</code> to be processed
170: */
171: public void afterPhase(PhaseEvent event) {
172:
173: PhaseId phaseId = event.getPhaseId();
174: if (PhaseId.RESTORE_VIEW.equals(phaseId)) {
175: afterRestoreView();
176: } else if (PhaseId.APPLY_REQUEST_VALUES.equals(phaseId)) {
177: afterApplyRequestValues();
178: } else if (PhaseId.PROCESS_VALIDATIONS.equals(phaseId)) {
179: afterProcessValidations();
180: } else if (PhaseId.UPDATE_MODEL_VALUES.equals(phaseId)) {
181: afterUpdateModelValues();
182: } else if (PhaseId.INVOKE_APPLICATION.equals(phaseId)) {
183: afterInvokeApplication();
184: } else if (PhaseId.RENDER_RESPONSE.equals(phaseId)) {
185: if (!FacesContext.getCurrentInstance()
186: .getResponseComplete()) {
187: afterRenderResponse();
188: }
189: }
190:
191: }
192:
193: // ---------------------------------------------------- PhaseEvent Callbacks
194:
195: // These methods are called by beforePhase() and afterPhase() as appropriate
196: // and allow subclasses to perform additional tasks at the corresponding
197: // moment in the request processing lifecycle for each request. The default
198: // implementations do nothing.
199:
200: protected void beforeRestoreView() {
201: }
202:
203: protected void afterRestoreView() {
204: }
205:
206: protected void beforeApplyRequestValues() {
207: }
208:
209: protected void afterApplyRequestValues() {
210: }
211:
212: protected void beforeProcessValidations() {
213: }
214:
215: protected void afterProcessValidations() {
216: }
217:
218: protected void beforeUpdateModelValues() {
219: }
220:
221: protected void afterUpdateModelValues() {
222: }
223:
224: protected void beforeInvokeApplication() {
225: }
226:
227: protected void afterInvokeApplication() {
228: }
229:
230: protected void beforeRenderResponse() {
231: }
232:
233: protected void afterRenderResponse() {
234: }
235:
236: // ------------------------------------------------------- Phase Processing
237:
238: /**
239: * <p>Return <code>true</code> if the current request was a post back
240: * for an existing view, rather than the creation of a new view. The
241: * result of this method may be used to conditionally execute one time
242: * setup that is only required when a page is first displayed.</p>
243: */
244: protected boolean isPostBack() {
245:
246: UIViewRoot viewRoot = getFacesContext().getViewRoot();
247: if (viewRoot == null) {
248: return true;
249: }
250: return !Boolean.TRUE.equals(viewRoot.getAttributes().get(
251: ViewHandlerImpl.CREATED_VIEW));
252:
253: }
254:
255: /**
256: * <p>Skip any remaining request processing lifecycle phases for the
257: * current request, and go immediately to <em>Render Response</em>
258: * phase. This method is typically invoked when you want to throw
259: * away input values provided by the user, instead of processing them.</p>
260: */
261: protected void renderResponse() {
262:
263: getFacesContext().renderResponse();
264:
265: }
266:
267: /**
268: * <p>Skip any remaining request processing lifecycle phases for the
269: * current request, including <em>Render Response</em> phase. This is
270: * appropriate if you have completed the response through some means
271: * other than JavaServer Faces rendering.</p>
272: */
273: protected void responseComplete() {
274:
275: getFacesContext().responseComplete();
276:
277: }
278:
279: // ------------------------------------------------------- Lifecycle Methods
280:
281: /**
282: * <p>Callback method that is called whenever a page is navigated to,
283: * either directly via a URL, or indirectly via page navigation.
284: * Override this method to acquire resources that will be needed
285: * for event handlers and lifecycle methods, whether or not this
286: * page is performing post back processing.</p>
287: *
288: * <p>The default implementation does nothing.</p>
289: */
290: public void init() {
291: ;
292: }
293:
294: /**
295: * <p>Callback method that is called after the component tree has been
296: * restored, but before any event processing takes place. This method
297: * will <strong>only</strong> be called on a "post back" request that
298: * is processing a form submit. Override this method to allocate
299: * resources that will be required in your event handlers.</p>
300: *
301: * <p>The default implementation does nothing.</p>
302: */
303: public void preprocess() {
304: ;
305: }
306:
307: /**
308: * <p>Callback method that is called just before rendering takes place.
309: * This method will <strong>only</strong> be called for the page that
310: * will actually be rendered (and not, for example, on a page that
311: * handled a post back and then navigated to a different page). Override
312: * this method to allocate resources that will be required for rendering
313: * this page.</p>
314: *
315: * <p>The default implementation does nothing.</p>
316: */
317: public void prerender() {
318: ;
319: }
320:
321: /**
322: * <p>Callback method that is called after rendering is completed for
323: * this request, if <code>init()</code> was called, regardless of whether
324: * or not this was the page that was actually rendered. Override this
325: * method to release resources acquired in the <code>init()</code>,
326: * <code>preprocess()</code>, or <code>prerender()</code> methods (or
327: * acquired during execution of an event handler).</p>
328: *
329: * <p>The default implementation does nothing.</p>
330: */
331: public void destroy() {
332: ;
333: }
334:
335: }
|