2009/05/20 - Apache Shale has been retired.

For more information, please explore the Attic.

View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to you under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.shale.dialog.base;
19  
20  import java.util.ArrayList;
21  import java.util.List;
22  
23  import javax.faces.context.FacesContext;
24  import javax.servlet.http.HttpSessionBindingEvent;
25  import javax.servlet.http.HttpSessionBindingListener;
26  
27  import org.apache.shale.dialog.Constants;
28  import org.apache.shale.dialog.DialogContext;
29  import org.apache.shale.dialog.DialogContextManager;
30  import org.apache.shale.dialog.DialogContextManagerListener;
31  import org.apache.shale.dialog.DialogLifecycleListener;
32  
33  /***
34   * <p>Abstract base class for {@link DialogContextManager} implementations.
35   * Provides listener registration and event firing convenience methods.
36   * Subclasses are expected to be serializable.</p>
37   *
38   * @since 1.0.4
39   */
40  public abstract class AbstractDialogContextManager
41    implements DialogContextManager, HttpSessionBindingListener {
42      
43  
44      // ------------------------------------------------------ Instance Variables
45  
46  
47      /***
48       * <p><code>List</code> of registered {@link DialogContextManagerListener}
49       * instances.</p>
50       */
51      private List listeners = new ArrayList();
52  
53  
54      // -------------------------------------- HttpSessionBindingListener Methods
55  
56  
57      /***
58       * <p>Handle an instance of this class being bound into an HttpSession.</p>
59       *
60       * @param event HttpSessionBindingEvent to be handled
61       */
62      public void valueBound(HttpSessionBindingEvent event) {
63  
64          DialogLifecycleListener listener = lifecycleListener();
65          if (listener != null) {
66              listener.onInit(this);
67          }
68  
69      }
70  
71  
72      /***
73       * <p>Handle an instance of this class being unbound from an HttpSession.</p>
74       *
75       * @param event HttpSessionBindingEvent to be handled
76       */
77      public void valueUnbound(HttpSessionBindingEvent event) {
78  
79          DialogLifecycleListener listener = lifecycleListener();
80          if (listener != null) {
81              listener.onDestroy(this);
82          }
83  
84      }
85  
86  
87      // ------------------------------------------------- Default Implementations
88  
89  
90      /***
91       * <p>Return the currently active {@link DialogContext} instance for the
92       * current request, if there is one; otherwise, return <code>null</code>.</p>
93       *
94       * @param context <code>FacesContext</code> for the current request
95       *
96       * @since 1.1.0
97       */
98      public DialogContext getActiveDialogContext(FacesContext context) {
99  
100         DialogContext dcontext = (DialogContext)
101           context.getExternalContext().getRequestMap().get(Constants.CONTEXT_BEAN);
102         if ((dcontext != null) && dcontext.isActive()) {
103             return dcontext;
104         } else {
105             return null;
106         }
107 
108     }
109 
110 
111     // --------------------------------------------------- Listener Registration
112 
113 
114     /***
115      * <p>Register a new {@link DialogContextManagerListener} instance.</p>
116      *
117      * @param listener The new listener instance to be registered
118      */
119     public void addDialogContextManagerListener(DialogContextManagerListener listener) {
120 
121         if (listener == null) {
122             throw new IllegalArgumentException("Cannot register null DialogContextManagerListener");
123         }
124 
125         synchronized (listeners) {
126             if (listeners.contains(listener)) {
127                 throw new IllegalArgumentException("DialogContextManagerListener already registered");
128             }
129             listener.setDialogContextManager(this); // attach self reference
130             listeners.add(listener);
131         }
132 
133     }
134 
135 
136     /***
137      * <p>Return the set of currently registered {@link DialogContextManagerListener}s.
138      * If there are no registered listeners, a zero-length array is returned.</p>
139      */
140     public DialogContextManagerListener[] getDialogContextManagerListeners() {
141 
142         synchronized (listeners) {
143             return (DialogContextManagerListener[])
144               listeners.toArray(new DialogContextManagerListener[listeners.size()]);
145         }
146 
147     }
148 
149 
150     /***
151      * <p>Deregister an existing {@link DialogContextManagerListener} instance.</p>
152      *
153      * @param listener The existing listener to be deregistered
154      */
155     public void removeDialogContextManagerListener(DialogContextManagerListener listener) {
156 
157         if (listener == null) {
158             throw new IllegalArgumentException("Cannot remove null DialogContextManagerListener");
159         }
160 
161         boolean removed;
162         synchronized (listeners) {
163             removed = listeners.remove(listener);
164         }
165         if (removed) {
166             listener.setDialogContextManager(null); // detach self reference
167         }
168 
169 
170     }
171 
172 
173     // ---------------------------------------------------- Event Firing Methods
174 
175 
176     /***
177      * <p>Fire an <code>onCreate()</code> event to all registered listeners.</p>
178      *
179      * @param context The {@link DialogContext} instance that has been created
180      */
181     protected void fireOnCreate(DialogContext context) {
182 
183         DialogContextManagerListener[] listeners =
184           getDialogContextManagerListeners();
185         for (int i = 0; i < listeners.length; i++) {
186             listeners[i].onCreate(context);
187         }
188 
189     }
190 
191 
192     /***
193      * <p>Fire an <code>onRemove()</code> event to all registered listeners.</p>
194      *
195      * @param context The {@link DialogContext} instance that has been removed
196      */
197     protected void fireOnRemove(DialogContext context) {
198 
199         DialogContextManagerListener[] listeners =
200           getDialogContextManagerListeners();
201         for (int i = 0; i < listeners.length; i++) {
202             listeners[i].onRemove(context);
203         }
204 
205     }
206 
207 
208     // --------------------------------------------------------- Private Methods
209 
210 
211     /***
212      * <p>Return the {@link DialogLifecycleListener} for this application
213      * (if any); otherwise, return <code>null</code>.</p>
214      */
215     private DialogLifecycleListener lifecycleListener() {
216 
217         FacesContext context = FacesContext.getCurrentInstance();
218         if (context == null) {
219             return null;
220         }
221         Object result =
222           context.getApplication().getVariableResolver().
223           resolveVariable(context, Constants.LIFECYCLE_ATTR);
224         if ((result != null) && (result instanceof DialogLifecycleListener)) {
225             return (DialogLifecycleListener) result;
226         } else {
227             return null;
228         }
229 
230     }
231 
232 
233 }