View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.myfaces.custom.schedule;
20  
21  import java.io.Serializable;
22  import java.util.Date;
23  import java.util.Iterator;
24  
25  import javax.faces.component.ActionSource;
26  import javax.faces.context.FacesContext;
27  import javax.faces.el.MethodBinding;
28  import javax.faces.event.AbortProcessingException;
29  import javax.faces.event.ActionEvent;
30  import javax.faces.event.ActionListener;
31  import javax.faces.event.FacesEvent;
32  import javax.faces.event.PhaseId;
33  
34  import org.apache.myfaces.custom.schedule.model.ScheduleDay;
35  import org.apache.myfaces.custom.schedule.model.ScheduleEntry;
36  
37  /**
38   * This class contains all 'interactive' stuff for the Schedule component, meaning
39   * actions and actionListeners.
40   * 
41   * @JSFComponent
42   * 
43   * @author Jurgen Lust
44   * @version $Revision$
45   */
46  public class UISchedule extends org.apache.myfaces.custom.schedule.UIScheduleBase implements
47          Serializable, ActionSource
48  {
49      public static final String COMPONENT_TYPE = "org.apache.myfaces.UISchedule";
50      
51      private class ScheduleActionListener implements ActionListener
52      {
53          //~ Methods ------------------------------------------------------------
54  
55          /**
56           * @see javax.faces.event.ActionListener#processAction(javax.faces.event.ActionEvent)
57           */
58          public void processAction(ActionEvent event)
59                  throws AbortProcessingException
60          {
61              UISchedule schedule = (UISchedule) event.getComponent();
62              ScheduleEntry entry = schedule.getSubmittedEntry();
63              schedule.getModel().setSelectedEntry(entry);
64              schedule.setSubmittedEntry(null);
65          }
66      }
67      
68      private static final long serialVersionUID = -8333458172939036755L;
69      private MethodBinding _action;
70      private MethodBinding _actionListener;
71      private ScheduleActionListener _scheduleListener;
72      private ScheduleEntry _submittedEntry;
73      private Date _lastClickedDateAndTime = null;
74      
75  
76      private MethodBinding _mouseListener = null;
77  
78      public UISchedule()
79      {
80          super();
81          _scheduleListener = new ScheduleActionListener();
82      }
83  
84      public void addActionListener(ActionListener listener)
85      {
86          addFacesListener(listener);
87      }
88  
89      
90      /**
91       * @see javax.faces.component.UIComponent#broadcast(javax.faces.event.FacesEvent)
92       */
93      public void broadcast(FacesEvent event) throws AbortProcessingException
94      {
95          FacesContext context = getFacesContext();
96          //invoke the mouselistener first
97          if (event instanceof ScheduleMouseEvent)
98          {
99              ScheduleMouseEvent mouseEvent = (ScheduleMouseEvent) event;
100             MethodBinding mouseListener = getMouseListener();
101 
102             if (mouseListener != null)
103             {
104                 mouseListener.invoke(context,
105                         new Object[] { mouseEvent });
106             }
107         }
108         
109         //then invoke private ScheduleActionListener for set
110         //the selected entry (if exists), so other
111         //listeners can retrieve it from getSelectedEntry.
112         if (event.isAppropriateListener(_scheduleListener))
113         {
114             event.processListener(_scheduleListener);
115         }
116 
117         //then invoke any other listeners
118         super.broadcast(event);
119 
120         if (event instanceof ActionEvent)
121         {
122             //Call registered actionListener if applies
123             MethodBinding actionListener = getActionListener();
124     
125             if (actionListener != null)
126             {
127                 actionListener.invoke(context, new Object[] { event });
128             }
129             
130             //Since UISchedule is an ActionSource component,
131             //we should call to the application actionListener
132             //when an ActionEvent happens.
133             ActionListener defaultActionListener = context.getApplication()
134                 .getActionListener();
135             if (defaultActionListener != null)
136             {
137                 defaultActionListener.processAction((ActionEvent) event);
138             }
139         }
140     }
141 
142     /**
143      * Find the entry with the given id
144      *
145      * @param id the id
146      *
147      * @return the entry
148      */
149     protected ScheduleEntry findEntry(String id)
150     {
151         if (id == null)
152         {
153             return null;
154         }
155 
156         for (Iterator dayIterator = getModel().iterator(); dayIterator
157                 .hasNext();)
158         {
159             ScheduleDay day = (ScheduleDay) dayIterator.next();
160 
161             for (Iterator iter = day.iterator(); iter.hasNext();)
162             {
163                 ScheduleEntry entry = (ScheduleEntry) iter.next();
164 
165                 if (id.equals(entry.getId()))
166                 {
167                     return entry;
168                 }
169             }
170         }
171 
172         return null;
173     }
174 
175     /**
176      * @JSFProperty
177      *   returnSignature="java.lang.String"
178      */
179     public MethodBinding getAction()
180     {
181         return _action;
182     }
183 
184     /**
185      * @JSFProperty
186      *   returnSignature="void"
187      *   methodSignature="javax.faces.event.ActionEvent"
188      */
189     public MethodBinding getActionListener()
190     {
191         return _actionListener;
192     }
193 
194     public ActionListener[] getActionListeners()
195     {
196         return (ActionListener[]) getFacesListeners(ActionListener.class);
197     }
198 
199     /**
200      * The last date and time of day that was clicked. This is set when
201      * submitOnClick is true, and the schedule is clicked by the user.
202      * 
203      * @JSFProperty
204      *   tagExcluded = "true"
205      * @return the last clicked date and time
206      */
207     public Date getLastClickedDateAndTime()
208     {
209         return _lastClickedDateAndTime;
210     }
211 
212     /**
213      * @JSFProperty
214      *   returnSignature="void"
215      *   methodSignature="org.apache.myfaces.custom.schedule.ScheduleMouseEvent"
216      *   stateHolder="true"
217      *   
218      * @return the method binding to the mouse listener method
219      */
220     public MethodBinding getMouseListener()
221     {
222         return _mouseListener;
223     }
224 
225     /**
226      * @return the submittedEntry
227      */
228     public ScheduleEntry getSubmittedEntry()
229     {
230         return _submittedEntry;
231     }
232 
233     /**
234      * @see javax.faces.component.UIComponent#queueEvent(javax.faces.event.FacesEvent)
235      */
236     public void queueEvent(FacesEvent event)
237     {
238         if (event instanceof ActionEvent || event instanceof ScheduleMouseEvent)
239         {
240             if (isImmediate())
241             {
242                 event.setPhaseId(PhaseId.APPLY_REQUEST_VALUES);
243             }
244             else
245             {
246                 event.setPhaseId(PhaseId.INVOKE_APPLICATION);
247             }
248         }
249 
250         super.queueEvent(event);
251     }
252 
253     public void removeActionListener(ActionListener listener)
254     {
255         removeFacesListener(listener);
256     }
257 
258     /**
259      * This method is invoked at the beginning of the restore view phase,
260      * resetting all mouse event variables that were left from the previous
261      * request
262      */
263     protected void resetMouseEvents()
264     {
265         this._lastClickedDateAndTime = null;
266     }
267 
268     /**
269      * @see org.apache.myfaces.custom.schedule.UIScheduleBase#restoreState(javax.faces.context.FacesContext, java.lang.Object)
270      */
271     public void restoreState(FacesContext context, Object state)
272     {
273         Object[] values = (Object[]) state;
274         super.restoreState(context, values[0]);
275         _lastClickedDateAndTime = (Date) values[1];
276         _actionListener = (MethodBinding) restoreAttachedState(context,
277                 values[2]);
278         _action = (MethodBinding) restoreAttachedState(context, values[3]);
279         _mouseListener = (MethodBinding) restoreAttachedState(context, values[4]);
280     }
281     
282     /**
283      * @see org.apache.myfaces.custom.schedule.UIScheduleBase#saveState(javax.faces.context.FacesContext)
284      */
285     public Object saveState(FacesContext context)
286     {
287         Object[] values = new Object[5];
288         values[0] = super.saveState(context);
289         values[1] = _lastClickedDateAndTime;
290         values[2] = saveAttachedState(context, _actionListener);
291         values[3] = saveAttachedState(context, _action);
292         values[4] = saveAttachedState(context, _mouseListener);
293         
294         return values;
295     }
296 
297     
298 
299     public void setAction(MethodBinding action)
300     {
301         this._action = action;
302     }
303 
304     public void setActionListener(MethodBinding actionListener)
305     {
306         this._actionListener = actionListener;
307     }
308 
309     
310     
311     /**
312      * The last date and time of day that was clicked. This is set when
313      * submitOnClick is true, and the schedule is clicked by the user.
314      * 
315      * @return the last clicked date and time
316      */
317     protected void setLastClickedDateAndTime(Date lastClickedDateAndTime)
318     {
319         this._lastClickedDateAndTime = lastClickedDateAndTime;
320     }
321 
322 
323     /**
324      * @param listener the method binding to the mouse listener method
325      */
326     public void setMouseListener(MethodBinding listener)
327     {
328         _mouseListener = listener;
329     }
330 
331     /**
332      * @param submittedEntry the submittedEntry to set
333      */
334     protected void setSubmittedEntry(ScheduleEntry submittedEntry)
335     {
336         this._submittedEntry = submittedEntry;
337     }
338     
339 }